mirror of
https://github.com/debauchee/barrier.git
synced 2026-02-12 22:55:53 +08:00
Compare commits
128 Commits
v1.9.1-sta
...
v1.10.2-rc
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2d9b2c29e6 | ||
|
|
79fb9e2c59 | ||
|
|
70ba53caf4 | ||
|
|
667d79263d | ||
|
|
8dcb63d3c0 | ||
|
|
baa913b1ac | ||
|
|
27404ff2b9 | ||
|
|
55dd155e56 | ||
|
|
751fcffc87 | ||
|
|
7fb4805521 | ||
|
|
0ef70ac2b2 | ||
|
|
6c6e2b6bd3 | ||
|
|
207247b7ef | ||
|
|
7f4ca77444 | ||
|
|
fe6cc4b849 | ||
|
|
e29ee68ff9 | ||
|
|
6f17cb9a31 | ||
|
|
eb620097c0 | ||
|
|
8b9722df25 | ||
|
|
de7c5ce6b7 | ||
|
|
a56abf68dd | ||
|
|
9bccfb89cc | ||
|
|
6870af8eb7 | ||
|
|
2713b95af7 | ||
|
|
b3cb57243a | ||
|
|
82d5733c09 | ||
|
|
2bbfe450ae | ||
|
|
e3633d8a7b | ||
|
|
85c359693a | ||
|
|
2118c6647c | ||
|
|
0e7fef7ceb | ||
|
|
9373bdaf01 | ||
|
|
e0e8651490 | ||
|
|
4cf1ab8a25 | ||
|
|
934824433d | ||
|
|
aad0ac25d1 | ||
|
|
87d8fc1e14 | ||
|
|
3bae5f3cc6 | ||
|
|
8d2ca0b36f | ||
|
|
aae43304c3 | ||
|
|
53d5c89851 | ||
|
|
c0452f0e61 | ||
|
|
d2d2a5e1d9 | ||
|
|
918571b6e2 | ||
|
|
21655a1c7a | ||
|
|
acecfef949 | ||
|
|
80efcfa495 | ||
|
|
566e2db202 | ||
|
|
25c2e360d3 | ||
|
|
8ef2e7edbc | ||
|
|
aca2605cb8 | ||
|
|
026b1f0de1 | ||
|
|
568a008037 | ||
|
|
3523d6e254 | ||
|
|
d9ec2f3ed3 | ||
|
|
b5c0f5c47e | ||
|
|
fc6cc78738 | ||
|
|
65e9045981 | ||
|
|
8dc868a206 | ||
|
|
e555d5d651 | ||
|
|
7aa0553b57 | ||
|
|
6d57630746 | ||
|
|
0ae87852e5 | ||
|
|
85a8080339 | ||
|
|
2b79608c44 | ||
|
|
683039c9cc | ||
|
|
fd0cb228ee | ||
|
|
2cde78ff54 | ||
|
|
5f3dce8379 | ||
|
|
555090c7d2 | ||
|
|
0e0c701b61 | ||
|
|
60c0df5984 | ||
|
|
89cc8a8daa | ||
|
|
46a5166fba | ||
|
|
183403ceb7 | ||
|
|
f9b83f9516 | ||
|
|
a830861522 | ||
|
|
420718101d | ||
|
|
0f2306c9ac | ||
|
|
1b0ab12c91 | ||
|
|
9b4d14e085 | ||
|
|
21edf3e7f4 | ||
|
|
e4b5a21616 | ||
|
|
491bb2de00 | ||
|
|
57a9a0fe27 | ||
|
|
1c4eb74204 | ||
|
|
d95af84528 | ||
|
|
11be6ef3d4 | ||
|
|
8e56fbce1f | ||
|
|
eebd9b1eb2 | ||
|
|
71953b5af8 | ||
|
|
458d8e4778 | ||
|
|
b396b1092d | ||
|
|
4e59954d94 | ||
|
|
6e77d9c42a | ||
|
|
6c5c55a564 | ||
|
|
c3a4fe7f2b | ||
|
|
14343fa7e1 | ||
|
|
953e829562 | ||
|
|
7c29d8e704 | ||
|
|
3cb7a5c101 | ||
|
|
88bf4b2e47 | ||
|
|
8054bc51a5 | ||
|
|
3c133380f8 | ||
|
|
36c81480d7 | ||
|
|
dfcac4e90b | ||
|
|
358641e58e | ||
|
|
828ad24820 | ||
|
|
8af215364f | ||
|
|
01109e0499 | ||
|
|
7e7760668a | ||
|
|
682fe1cfa3 | ||
|
|
1c90f858ea | ||
|
|
284fd80c5f | ||
|
|
1852f7477c | ||
|
|
6ccd4d71b8 | ||
|
|
84dfeec2ed | ||
|
|
535627c871 | ||
|
|
46a5b7f9ae | ||
|
|
7da1d4f9cc | ||
|
|
c9082e0cf2 | ||
|
|
ea8d24c908 | ||
|
|
a155ca951c | ||
|
|
5015f9da11 | ||
|
|
f07b765a24 | ||
|
|
87e1912842 | ||
|
|
e170bd87a8 | ||
|
|
f0852871b1 |
62
.cirrus.yml
Normal file
62
.cirrus.yml
Normal file
@@ -0,0 +1,62 @@
|
||||
gcp_credentials: ENCRYPTED[d3110e2399b82e1d2adb6f9294917064a448a4d102c42c5023815723841db4ff7aa1d0df64a44281ed25b3adbeb08eff]
|
||||
|
||||
windows_task:
|
||||
gce_instance:
|
||||
image_project: buildcluster-237411
|
||||
image_name: windows2019-vs2017-ramdisk
|
||||
platform: windows
|
||||
zone: us-central1-a
|
||||
type: n1-highcpu-16
|
||||
disk: 32
|
||||
use_ssd: true
|
||||
|
||||
env:
|
||||
BONJOUR_SDK_HOME: C:\Program Files\Bonjour SDK\
|
||||
CMAKE_PREFIX_PATH: C:\Qt\5.9.5\msvc2017_64
|
||||
CIRRUS_WORKING_DIR: D:\
|
||||
|
||||
build_script:
|
||||
- .\CI\Windows\build.bat
|
||||
|
||||
ubuntu1604_task:
|
||||
use_compute_credits: true
|
||||
container:
|
||||
dockerfile: CI/ubuntu1604.Dockerfile
|
||||
build_script:
|
||||
- pwd; ls -la
|
||||
- chmod +x ./CI/build.sh
|
||||
- ./CI/build.sh
|
||||
|
||||
ubuntu1804_task:
|
||||
use_compute_credits: true
|
||||
container:
|
||||
dockerfile: CI/ubuntu1804.Dockerfile
|
||||
build_script:
|
||||
- pwd; ls -la
|
||||
- chmod +x ./CI/build.sh
|
||||
- ./CI/build.sh
|
||||
|
||||
ubuntu1904_task:
|
||||
use_compute_credits: true
|
||||
container:
|
||||
dockerfile: CI/ubuntu1904.Dockerfile
|
||||
build_script:
|
||||
- pwd; ls -la
|
||||
- chmod +x ./CI/build.sh
|
||||
- ./CI/build.sh
|
||||
|
||||
macos_task:
|
||||
use_compute_credits: true
|
||||
osx_instance:
|
||||
image: mojave-xcode-10.2
|
||||
|
||||
env:
|
||||
PATH: /usr/local/opt/qt/bin:$PATH
|
||||
|
||||
install_script:
|
||||
- brew install qt
|
||||
build_script:
|
||||
- mkdir build
|
||||
- cd build
|
||||
- cmake -DCMAKE_OSX_DEPLOYMENT_TARGET=10.10 -DCMAKE_OSX_ARCHITECTURES=x86_64 -DCMAKE_BUILD_TYPE=$CMAKE_BUILD_TYPE -DCMAKE_CONFIGURATION_TYPES=$CMAKE_BUILD_TYPE ..
|
||||
- make
|
||||
@@ -2,6 +2,6 @@
|
||||
# Synergy build parameters
|
||||
#
|
||||
SYNERGY_VERSION_MAJOR = 1
|
||||
SYNERGY_VERSION_MINOR = 9
|
||||
SYNERGY_VERSION_PATCH = 1
|
||||
SYNERGY_VERSION_STAGE = stable
|
||||
SYNERGY_VERSION_MINOR = 10
|
||||
SYNERGY_VERSION_PATCH = 2
|
||||
SYNERGY_VERSION_STAGE = snapshot
|
||||
|
||||
56
CI/MacOS/qtifwsilent.qs
Normal file
56
CI/MacOS/qtifwsilent.qs
Normal file
@@ -0,0 +1,56 @@
|
||||
function Controller() {
|
||||
installer.autoRejectMessageBoxes();
|
||||
installer.installationFinished.connect(function() {
|
||||
gui.clickButton(buttons.NextButton);
|
||||
})
|
||||
}
|
||||
|
||||
Controller.prototype.WelcomePageCallback = function() {
|
||||
gui.clickButton(buttons.NextButton, 3000);
|
||||
}
|
||||
|
||||
Controller.prototype.CredentialsPageCallback = function() {
|
||||
gui.clickButton(buttons.NextButton);
|
||||
}
|
||||
|
||||
Controller.prototype.IntroductionPageCallback = function() {
|
||||
gui.clickButton(buttons.NextButton);
|
||||
}
|
||||
|
||||
Controller.prototype.TargetDirectoryPageCallback = function()
|
||||
{
|
||||
gui.currentPageWidget().TargetDirectoryLineEdit.setText(installer.value("HomeDir") + "/Qt");
|
||||
gui.clickButton(buttons.NextButton);
|
||||
}
|
||||
|
||||
Controller.prototype.ComponentSelectionPageCallback = function() {
|
||||
var widget = gui.currentPageWidget();
|
||||
|
||||
widget.deselectAll();
|
||||
|
||||
widget.selectComponent("qt.595.clang_64")
|
||||
|
||||
gui.clickButton(buttons.NextButton);
|
||||
}
|
||||
|
||||
Controller.prototype.LicenseAgreementPageCallback = function() {
|
||||
gui.currentPageWidget().AcceptLicenseRadioButton.setChecked(true);
|
||||
gui.clickButton(buttons.NextButton);
|
||||
}
|
||||
|
||||
Controller.prototype.StartMenuDirectoryPageCallback = function() {
|
||||
gui.clickButton(buttons.NextButton);
|
||||
}
|
||||
|
||||
Controller.prototype.ReadyForInstallationPageCallback = function()
|
||||
{
|
||||
gui.clickButton(buttons.NextButton);
|
||||
}
|
||||
|
||||
Controller.prototype.FinishedPageCallback = function() {
|
||||
var checkBoxForm = gui.currentPageWidget().LaunchQtCreatorCheckBoxForm
|
||||
if (checkBoxForm && checkBoxForm.launchQtCreatorCheckBox) {
|
||||
checkBoxForm.launchQtCreatorCheckBox.checked = false;
|
||||
}
|
||||
gui.clickButton(buttons.FinishButton);
|
||||
}
|
||||
6
CI/Windows/build.bat
Normal file
6
CI/Windows/build.bat
Normal file
@@ -0,0 +1,6 @@
|
||||
SET VS_INSTALL_PATH=C:\"Program Files (x86)"\"Microsoft Visual Studio"\2019\Community\
|
||||
call %VS_INSTALL_PATH%Common7\Tools\VsDevCmd.bat
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -G "Visual Studio 15 2017 Win64" -DCMAKE_BUILD_TYPE=Debug ..
|
||||
msbuild synergy-core.sln /p:Platform="x64" /p:Configuration=Debug /m
|
||||
54
CI/Windows/qtifwsilent.qs
Normal file
54
CI/Windows/qtifwsilent.qs
Normal file
@@ -0,0 +1,54 @@
|
||||
function Controller() {
|
||||
installer.autoRejectMessageBoxes();
|
||||
installer.installationFinished.connect(function() {
|
||||
gui.clickButton(buttons.NextButton);
|
||||
})
|
||||
}
|
||||
|
||||
Controller.prototype.WelcomePageCallback = function() {
|
||||
gui.clickButton(buttons.NextButton, 3000);
|
||||
}
|
||||
|
||||
Controller.prototype.CredentialsPageCallback = function() {
|
||||
gui.clickButton(buttons.NextButton);
|
||||
}
|
||||
|
||||
Controller.prototype.IntroductionPageCallback = function() {
|
||||
gui.clickButton(buttons.NextButton);
|
||||
}
|
||||
|
||||
Controller.prototype.TargetDirectoryPageCallback = function() {
|
||||
gui.currentPageWidget().TargetDirectoryLineEdit.setText(installer.environmentVariable("QT_INSTALL_DIR"));
|
||||
gui.clickButton(buttons.NextButton);
|
||||
}
|
||||
|
||||
Controller.prototype.ComponentSelectionPageCallback = function() {
|
||||
var widget = gui.currentPageWidget();
|
||||
widget.deselectAll();
|
||||
widget.selectComponent("qt.595.win32_msvc2015");
|
||||
widget.selectComponent("qt.595.win64_msvc2015_64");
|
||||
widget.selectComponent("qt.595.qtscript");
|
||||
widget.selectComponent("qt.tools.vcredist_msvc2015_x86");
|
||||
widget.selectComponent("qt.tools.vcredist_msvc2015_x64");
|
||||
gui.clickButton(buttons.NextButton);
|
||||
}
|
||||
|
||||
Controller.prototype.LicenseAgreementPageCallback = function() {
|
||||
gui.currentPageWidget().AcceptLicenseRadioButton.setChecked(true);
|
||||
gui.clickButton(buttons.NextButton);
|
||||
}
|
||||
|
||||
Controller.prototype.StartMenuDirectoryPageCallback = function() {
|
||||
gui.clickButton(buttons.NextButton);
|
||||
}
|
||||
|
||||
Controller.prototype.ReadyForInstallationPageCallback = function() {
|
||||
gui.clickButton(buttons.NextButton);
|
||||
}
|
||||
|
||||
Controller.prototype.FinishedPageCallback = function() {
|
||||
var checkBoxForm = gui.currentPageWidget().LaunchQtCreatorCheckBoxForm;
|
||||
if (checkBoxForm && checkBoxForm.launchQtCreatorCheckBox)
|
||||
checkBoxForm.launchQtCreatorCheckBox.checked = false;
|
||||
gui.clickButton(buttons.FinishButton);
|
||||
}
|
||||
6
CI/build.sh
Normal file
6
CI/build.sh
Normal file
@@ -0,0 +1,6 @@
|
||||
pwd
|
||||
ls -la
|
||||
mkdir build
|
||||
cd build
|
||||
cmake ..
|
||||
make
|
||||
12
CI/package.sh
Normal file
12
CI/package.sh
Normal file
@@ -0,0 +1,12 @@
|
||||
cd ${CIRRUS_WORKING_DIR}
|
||||
|
||||
source ./build/version
|
||||
|
||||
SYNERGY_VERSION="$SYNERGY_VERSION_MAJOR.$SYNERGY_VERSION_MINOR.$SYNERGY_VERSION_PATCH"
|
||||
SYNERGY_REVISION=`git rev-parse --short=8 HEAD`
|
||||
SYNERGY_DEB_VERSION="${SYNERGY_VERSION}.${SYNERGY_VERSION_STAGE}~b${BUILD_NUMBER}+${SYNERGY_REVISION}"
|
||||
|
||||
dch --create --package "synergy" --controlmaint --distribution unstable --newversion $SYNERGY_DEB_VERSION "Initial release"
|
||||
|
||||
export DEB_BUILD_OPTIONS="parallel=4"
|
||||
debuild --preserve-envvar SYNERGY_* --preserve-envvar GIT_COMMIT --preserve-envvar BUILD_NUMBER
|
||||
24
CI/ubuntu1604.Dockerfile
Normal file
24
CI/ubuntu1604.Dockerfile
Normal file
@@ -0,0 +1,24 @@
|
||||
#
|
||||
# Ubuntu Dockerfile
|
||||
#
|
||||
# https://github.com/dockerfile/ubuntu
|
||||
#
|
||||
|
||||
# Pull base image.
|
||||
FROM ubuntu:16.04
|
||||
|
||||
# Install.
|
||||
RUN \
|
||||
sed -i 's/# \(.*multiverse$\)/\1/g' /etc/apt/sources.list && \
|
||||
apt-get update && \
|
||||
apt-get install -y git cmake qtbase5-dev build-essential libx11-dev libxtst-dev libgl1-mesa-dev libssl-dev libavahi-compat-libdnssd-dev && \
|
||||
apt-get install -y debhelper devscripts
|
||||
|
||||
# Set environment variables.
|
||||
ENV HOME /root
|
||||
|
||||
# Define working directory.
|
||||
WORKDIR /root
|
||||
|
||||
# Define default command.
|
||||
CMD ["bash"]
|
||||
24
CI/ubuntu1804.Dockerfile
Normal file
24
CI/ubuntu1804.Dockerfile
Normal file
@@ -0,0 +1,24 @@
|
||||
#
|
||||
# Ubuntu Dockerfile
|
||||
#
|
||||
# https://github.com/dockerfile/ubuntu
|
||||
#
|
||||
|
||||
# Pull base image.
|
||||
FROM ubuntu:18.04
|
||||
|
||||
# Install.
|
||||
RUN \
|
||||
sed -i 's/# \(.*multiverse$\)/\1/g' /etc/apt/sources.list && \
|
||||
apt-get update && \
|
||||
apt-get install -y git cmake qtbase5-dev build-essential libx11-dev libxtst-dev libgl1-mesa-dev libssl-dev libavahi-compat-libdnssd-dev && \
|
||||
apt-get install -y debhelper devscripts
|
||||
|
||||
# Set environment variables.
|
||||
ENV HOME /root
|
||||
|
||||
# Define working directory.
|
||||
WORKDIR /root
|
||||
|
||||
# Define default command.
|
||||
CMD ["bash"]
|
||||
24
CI/ubuntu1904.Dockerfile
Normal file
24
CI/ubuntu1904.Dockerfile
Normal file
@@ -0,0 +1,24 @@
|
||||
#
|
||||
# Ubuntu Dockerfile
|
||||
#
|
||||
# https://github.com/dockerfile/ubuntu
|
||||
#
|
||||
|
||||
# Pull base image.
|
||||
FROM ubuntu:19.04
|
||||
|
||||
# Install.
|
||||
RUN \
|
||||
sed -i 's/# \(.*multiverse$\)/\1/g' /etc/apt/sources.list && \
|
||||
apt-get update && \
|
||||
apt-get install -y git cmake qtbase5-dev build-essential libx11-dev libxtst-dev libgl1-mesa-dev libssl-dev libavahi-compat-libdnssd-dev && \
|
||||
apt-get install -y debhelper devscripts
|
||||
|
||||
# Set environment variables.
|
||||
ENV HOME /root
|
||||
|
||||
# Define working directory.
|
||||
WORKDIR /root
|
||||
|
||||
# Define default command.
|
||||
CMD ["bash"]
|
||||
@@ -15,12 +15,18 @@
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
cmake_minimum_required (VERSION 3.4)
|
||||
project (synergy C CXX)
|
||||
project (synergy-core C CXX)
|
||||
|
||||
option (SYNERGY_BUILD_LEGACY_GUI "Build the legacy GUI" ON)
|
||||
option (SYNERGY_BUILD_LEGACY_SERVICE "Build the legacy service (synergyd)" ON)
|
||||
option (SYNERGY_BUILD_LEGACY_INSTALLER "Build the legacy installer" ON)
|
||||
|
||||
if (DEFINED ENV{SYNERGY_ENTERPRISE})
|
||||
option (SYNERGY_ENTERPRISE "Build Enterprise" ON)
|
||||
else()
|
||||
option (SYNERGY_ENTERPRISE "Build Enterprise" OFF)
|
||||
endif()
|
||||
|
||||
set (CMAKE_CXX_STANDARD 14)
|
||||
set (CMAKE_CXX_EXTENSIONS OFF)
|
||||
set (CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
@@ -130,13 +136,6 @@ if (UNIX)
|
||||
message (FATAL_ERROR "Missing library: pthread")
|
||||
endif()
|
||||
|
||||
# curl is used on both Linux and Mac
|
||||
find_package (CURL)
|
||||
if (CURL_FOUND)
|
||||
list (APPEND libs curl)
|
||||
else()
|
||||
message (FATAL_ERROR "Missing library: curl")
|
||||
endif()
|
||||
|
||||
if (APPLE)
|
||||
set (CMAKE_CXX_FLAGS "--sysroot ${CMAKE_OSX_SYSROOT} ${CMAKE_CXX_FLAGS} -DGTEST_USE_OWN_TR1_TUPLE=1")
|
||||
@@ -337,6 +336,23 @@ macro (configure_files srcDir destDir)
|
||||
endforeach (templateFile)
|
||||
endmacro (configure_files)
|
||||
|
||||
macro(generate_versionfile)
|
||||
if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin" OR ${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
FILE(WRITE ${CMAKE_BINARY_DIR}/version
|
||||
"export SYNERGY_VERSION_MAJOR=\"${SYNERGY_VERSION_MAJOR}\"\n"
|
||||
"export SYNERGY_VERSION_MINOR=\"${SYNERGY_VERSION_MINOR}\"\n"
|
||||
"export SYNERGY_VERSION_PATCH=\"${SYNERGY_VERSION_PATCH}\"\n"
|
||||
"export SYNERGY_VERSION_STAGE=\"${SYNERGY_VERSION_STAGE}\"\n")
|
||||
elseif(${CMAKE_SYSTEM_NAME} MATCHES "Windows")
|
||||
FILE(WRITE ${CMAKE_BINARY_DIR}/version
|
||||
"$env:SYNERGY_VERSION_MAJOR=\"${SYNERGY_VERSION_MAJOR}\"\n"
|
||||
"$env:SYNERGY_VERSION_MINOR=\"${SYNERGY_VERSION_MINOR}\"\n"
|
||||
"$env:SYNERGY_VERSION_PATCH=\"${SYNERGY_VERSION_PATCH}\"\n"
|
||||
"$env:SYNERGY_VERSION_STAGE=\"${SYNERGY_VERSION_STAGE}\"\n")
|
||||
endif()
|
||||
endmacro(generate_versionfile)
|
||||
|
||||
|
||||
if (${SYNERGY_BUILD_LEGACY_INSTALLER})
|
||||
#
|
||||
# macOS app Bundle
|
||||
@@ -347,7 +363,8 @@ if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
set (SYNERGY_BUNDLE_DIR ${CMAKE_BINARY_DIR}/bundle)
|
||||
set (SYNERGY_BUNDLE_APP_DIR ${SYNERGY_BUNDLE_DIR}/Synergy.app)
|
||||
set (SYNERGY_BUNDLE_BINARY_DIR ${SYNERGY_BUNDLE_APP_DIR}/Contents/MacOS)
|
||||
|
||||
|
||||
generate_versionfile()
|
||||
configure_files (${SYNERGY_BUNDLE_SOURCE_DIR} ${SYNERGY_BUNDLE_DIR})
|
||||
endif()
|
||||
|
||||
@@ -357,6 +374,7 @@ endif()
|
||||
if (${CMAKE_SYSTEM_NAME} MATCHES "Windows")
|
||||
message (STATUS "Configuring the v1 installer")
|
||||
configure_files (${CMAKE_CURRENT_SOURCE_DIR}/dist/wix ${CMAKE_BINARY_DIR}/installer)
|
||||
generate_versionfile()
|
||||
endif()
|
||||
|
||||
#
|
||||
@@ -370,6 +388,7 @@ if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
else()
|
||||
install(FILES res/synergy.desktop DESTINATION share/applications)
|
||||
endif()
|
||||
generate_versionfile()
|
||||
endif()
|
||||
|
||||
else()
|
||||
|
||||
@@ -1,371 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE QtCreatorProject>
|
||||
<!-- Written by QtCreator 4.2.1, 2018-03-20T15:31:49. -->
|
||||
<qtcreator>
|
||||
<data>
|
||||
<variable>EnvironmentId</variable>
|
||||
<value type="QByteArray">{d2097749-f678-439b-ab23-75844ed126ff}</value>
|
||||
</data>
|
||||
<data>
|
||||
<variable>ProjectExplorer.Project.ActiveTarget</variable>
|
||||
<value type="int">0</value>
|
||||
</data>
|
||||
<data>
|
||||
<variable>ProjectExplorer.Project.EditorSettings</variable>
|
||||
<valuemap type="QVariantMap">
|
||||
<value type="bool" key="EditorConfiguration.AutoIndent">true</value>
|
||||
<value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</value>
|
||||
<value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value>
|
||||
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
|
||||
<value type="QString" key="language">Cpp</value>
|
||||
<valuemap type="QVariantMap" key="value">
|
||||
<value type="QByteArray" key="CurrentPreferences">CppGlobal</value>
|
||||
</valuemap>
|
||||
</valuemap>
|
||||
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1">
|
||||
<value type="QString" key="language">QmlJS</value>
|
||||
<valuemap type="QVariantMap" key="value">
|
||||
<value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value>
|
||||
</valuemap>
|
||||
</valuemap>
|
||||
<value type="int" key="EditorConfiguration.CodeStyle.Count">2</value>
|
||||
<value type="QByteArray" key="EditorConfiguration.Codec">UTF-8</value>
|
||||
<value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
|
||||
<value type="int" key="EditorConfiguration.IndentSize">4</value>
|
||||
<value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value>
|
||||
<value type="int" key="EditorConfiguration.MarginColumn">80</value>
|
||||
<value type="bool" key="EditorConfiguration.MouseHiding">true</value>
|
||||
<value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
|
||||
<value type="int" key="EditorConfiguration.PaddingMode">1</value>
|
||||
<value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
|
||||
<value type="bool" key="EditorConfiguration.ShowMargin">false</value>
|
||||
<value type="int" key="EditorConfiguration.SmartBackspaceBehavior">0</value>
|
||||
<value type="bool" key="EditorConfiguration.SmartSelectionChanging">true</value>
|
||||
<value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
|
||||
<value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
|
||||
<value type="int" key="EditorConfiguration.TabSize">8</value>
|
||||
<value type="bool" key="EditorConfiguration.UseGlobal">true</value>
|
||||
<value type="int" key="EditorConfiguration.Utf8BomBehavior">1</value>
|
||||
<value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
|
||||
<value type="bool" key="EditorConfiguration.cleanIndentation">true</value>
|
||||
<value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
|
||||
<value type="bool" key="EditorConfiguration.inEntireDocument">false</value>
|
||||
</valuemap>
|
||||
</data>
|
||||
<data>
|
||||
<variable>ProjectExplorer.Project.PluginSettings</variable>
|
||||
<valuemap type="QVariantMap"/>
|
||||
</data>
|
||||
<data>
|
||||
<variable>ProjectExplorer.Project.Target.0</variable>
|
||||
<valuemap type="QVariantMap">
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop Qt 5.8.0 MSVC2015_64bit</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop Qt 5.8.0 MSVC2015_64bit</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">qt.58.win64_msvc2015_64_kit</value>
|
||||
<value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
|
||||
<value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
|
||||
<value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
|
||||
<valuelist type="QVariantList" key="CMake.Configuration"/>
|
||||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">C:/Projects/build-synergy-core-Desktop_Qt_5_8_0_MSVC2015_64bit-Default</value>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||
<value type="QString" key="CMakeProjectManager.MakeStep.AdditionalArguments"></value>
|
||||
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
|
||||
<value type="QString"></value>
|
||||
</valuelist>
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
|
||||
</valuemap>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||
<value type="QString" key="CMakeProjectManager.MakeStep.AdditionalArguments"></value>
|
||||
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
|
||||
<value type="QString">clean</value>
|
||||
</valuelist>
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
|
||||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
|
||||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Default</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Default</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.CMakeBuildConfiguration</value>
|
||||
</valuemap>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.1">
|
||||
<valuelist type="QVariantList" key="CMake.Configuration">
|
||||
<value type="QString">CMAKE_BUILD_TYPE:STRING=Debug</value>
|
||||
</valuelist>
|
||||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">C:/Projects/build-synergy-core-Desktop_Qt_5_8_0_MSVC2015_64bit-Debug</value>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||
<value type="QString" key="CMakeProjectManager.MakeStep.AdditionalArguments"></value>
|
||||
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
|
||||
<value type="QString"></value>
|
||||
</valuelist>
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
|
||||
</valuemap>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||
<value type="QString" key="CMakeProjectManager.MakeStep.AdditionalArguments"></value>
|
||||
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
|
||||
<value type="QString">clean</value>
|
||||
</valuelist>
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
|
||||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
|
||||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Debug</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Debug</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.CMakeBuildConfiguration</value>
|
||||
</valuemap>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.2">
|
||||
<valuelist type="QVariantList" key="CMake.Configuration">
|
||||
<value type="QString">CMAKE_BUILD_TYPE:STRING=Release</value>
|
||||
</valuelist>
|
||||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">C:/Projects/build-synergy-core-Desktop_Qt_5_8_0_MSVC2015_64bit-Release</value>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||
<value type="QString" key="CMakeProjectManager.MakeStep.AdditionalArguments"></value>
|
||||
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
|
||||
<value type="QString"></value>
|
||||
</valuelist>
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
|
||||
</valuemap>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||
<value type="QString" key="CMakeProjectManager.MakeStep.AdditionalArguments"></value>
|
||||
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
|
||||
<value type="QString">clean</value>
|
||||
</valuelist>
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
|
||||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
|
||||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Release</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Release</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.CMakeBuildConfiguration</value>
|
||||
</valuemap>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.3">
|
||||
<valuelist type="QVariantList" key="CMake.Configuration">
|
||||
<value type="QString">CMAKE_BUILD_TYPE:STRING=RelWithDebInfo</value>
|
||||
</valuelist>
|
||||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">C:/Projects/build-synergy-core-Desktop_Qt_5_8_0_MSVC2015_64bit-Release with Debug Information</value>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||
<value type="QString" key="CMakeProjectManager.MakeStep.AdditionalArguments"></value>
|
||||
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
|
||||
<value type="QString"></value>
|
||||
</valuelist>
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
|
||||
</valuemap>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||
<value type="QString" key="CMakeProjectManager.MakeStep.AdditionalArguments"></value>
|
||||
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
|
||||
<value type="QString">clean</value>
|
||||
</valuelist>
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
|
||||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
|
||||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Release with Debug Information</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Release with Debug Information</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.CMakeBuildConfiguration</value>
|
||||
</valuemap>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.4">
|
||||
<valuelist type="QVariantList" key="CMake.Configuration">
|
||||
<value type="QString">CMAKE_BUILD_TYPE:STRING=MinSizeRel</value>
|
||||
</valuelist>
|
||||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">C:/Projects/build-synergy-core-Desktop_Qt_5_8_0_MSVC2015_64bit-Minimum Size Release</value>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||
<value type="QString" key="CMakeProjectManager.MakeStep.AdditionalArguments"></value>
|
||||
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
|
||||
<value type="QString"></value>
|
||||
</valuelist>
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
|
||||
</valuemap>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||
<value type="QString" key="CMakeProjectManager.MakeStep.AdditionalArguments"></value>
|
||||
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
|
||||
<value type="QString">clean</value>
|
||||
</valuelist>
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Make</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
|
||||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
|
||||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Minimum Size Release</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Minimum Size Release</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.CMakeBuildConfiguration</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">5</value>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy locally</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.PluginSettings"/>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
|
||||
<value type="bool" key="Analyzer.QmlProfiler.AggregateTraces">false</value>
|
||||
<value type="bool" key="Analyzer.QmlProfiler.FlushEnabled">false</value>
|
||||
<value type="uint" key="Analyzer.QmlProfiler.FlushInterval">1000</value>
|
||||
<value type="QString" key="Analyzer.QmlProfiler.LastTraceFile"></value>
|
||||
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
|
||||
<valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/>
|
||||
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value>
|
||||
<value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value>
|
||||
<value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">true</value>
|
||||
<value type="int" key="Analyzer.Valgrind.LeakCheckOnFinish">1</value>
|
||||
<value type="int" key="Analyzer.Valgrind.NumCallers">25</value>
|
||||
<valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/>
|
||||
<value type="int" key="Analyzer.Valgrind.SelfModifyingCodeDetection">1</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.ShowReachable">false</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value>
|
||||
<value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value>
|
||||
<valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds">
|
||||
<value type="int">0</value>
|
||||
<value type="int">1</value>
|
||||
<value type="int">2</value>
|
||||
<value type="int">3</value>
|
||||
<value type="int">4</value>
|
||||
<value type="int">5</value>
|
||||
<value type="int">6</value>
|
||||
<value type="int">7</value>
|
||||
<value type="int">8</value>
|
||||
<value type="int">9</value>
|
||||
<value type="int">10</value>
|
||||
<value type="int">11</value>
|
||||
<value type="int">12</value>
|
||||
<value type="int">13</value>
|
||||
<value type="int">14</value>
|
||||
</valuelist>
|
||||
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
|
||||
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
|
||||
<value type="QString" key="ProjectExplorer.CustomExecutableRunConfiguration.Arguments"></value>
|
||||
<value type="QString" key="ProjectExplorer.CustomExecutableRunConfiguration.Executable"></value>
|
||||
<value type="QString" key="ProjectExplorer.CustomExecutableRunConfiguration.WorkingDirectory">%{buildDir}</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Custom Executable</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName"></value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.CustomExecutableRunConfiguration</value>
|
||||
<value type="uint" key="RunConfiguration.QmlDebugServerPort">3768</value>
|
||||
<value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
|
||||
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
|
||||
<value type="bool" key="RunConfiguration.UseMultiProcess">false</value>
|
||||
<value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
|
||||
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
|
||||
</valuemap>
|
||||
</data>
|
||||
<data>
|
||||
<variable>ProjectExplorer.Project.TargetCount</variable>
|
||||
<value type="int">1</value>
|
||||
</data>
|
||||
<data>
|
||||
<variable>ProjectExplorer.Project.Updater.FileVersion</variable>
|
||||
<value type="int">18</value>
|
||||
</data>
|
||||
<data>
|
||||
<variable>Version</variable>
|
||||
<value type="int">18</value>
|
||||
</data>
|
||||
</qtcreator>
|
||||
99
ChangeLog
99
ChangeLog
@@ -1,21 +1,91 @@
|
||||
v1.9.0-rc3
|
||||
============
|
||||
Bug #4132 - Laggy mouse cursor on macOS clients
|
||||
v1.10.2-rc2
|
||||
==============
|
||||
|
||||
v1.9.0-rc2
|
||||
===========
|
||||
Bug #5901 - Stored serial key corrupted on macOS
|
||||
Bug #5757 - Failure to build against OpenSSL v1.1.0
|
||||
Bug fixes:
|
||||
- #6495 Event queue memory leak in server cleanup
|
||||
- #6471 Unable to stop core retry loop in config app
|
||||
- #6460 TLS memory leak on Linux server when using client
|
||||
- #6407 Enterprise config app shows auto-config elements
|
||||
- #6403 Mouse cursor movement drifts over time
|
||||
- #6392 Hostname alert shows unnecessarily on every open
|
||||
- #6373 Compile fails on BSD Unix with dl error
|
||||
|
||||
v1.9.0-rc1
|
||||
==========
|
||||
Bug #5467 - Failing to automatically download and install Bonjour
|
||||
Enhancement #5389 - Ported GUI to Qt 5
|
||||
Enhancement #4978 - Windows: Added support for Visual Studio 2015
|
||||
Enhancement #5398 - Windows: Updated OpenSSL dependency to 1.0.2k
|
||||
Enhancements:
|
||||
- #6485 Readme for master branch with download help
|
||||
- #6475 Change master branch to current version
|
||||
- #6470 CI solution with on-demand containers
|
||||
- #6397 Remember last server used in Auto Config
|
||||
- #6375 Support for Qt 5.11 framework on Windows
|
||||
|
||||
v1.10.1-stable
|
||||
==============
|
||||
|
||||
Bug fixes:
|
||||
- #6339 Windows validating install step freezes
|
||||
- #6374 Windows background service crashes randomly
|
||||
- #6376 Undeclared identifier compile error in VS2017
|
||||
|
||||
Enhancements:
|
||||
- #6372 Forced use of TLS 1.2 without fallback method
|
||||
- #6338 Auto config checkbox on settings screen
|
||||
- #6384 Removal of GPL screen on Windows installer
|
||||
- #6383 Extend foreground mode for Windows daemon
|
||||
- #6382 Code comment for MSVC debugger logging
|
||||
- #6380 Compile without warnings using VS2017
|
||||
|
||||
v1.10.0-stable
|
||||
==============
|
||||
|
||||
Bug fixes:
|
||||
- #6347 Log to file defaults to unwritable location
|
||||
- #6345 Losing GUI config when restarting the OS
|
||||
- #4991 Oversized Bonjour protocol name could conflict
|
||||
|
||||
Enhancements:
|
||||
- #6348 Use different hard coded Qt path for CI
|
||||
- #6346 CLI argument to control screen lock feature
|
||||
- #6344 Customizable size limit on clipboard sharing
|
||||
- #6332 Decouple version from CI build properties
|
||||
- #6319 Bonjour auto-config disabled by default
|
||||
- #6318 Hide TIS/TSM error on config app log
|
||||
- #6312 Removal of redundant CURL library
|
||||
- #6306 Show version number in config app title
|
||||
- #6305 Support for Raspbian in package config
|
||||
- #6301 Combine enterprise and community codebases
|
||||
|
||||
v1.9.1-stable
|
||||
=============
|
||||
|
||||
Bug fix:
|
||||
- #5964 Can't click after sleep on Mac client
|
||||
|
||||
Enhancements:
|
||||
- #6310 More robust macOS screen shape detection
|
||||
- #6309 Update OpenSSL to v1.0.2o for better security
|
||||
|
||||
v1.9.0-stable
|
||||
=============
|
||||
|
||||
Bug fixes:
|
||||
- #6251 Service hangs after GUI is opened
|
||||
- #5844 Icon causes Linux package manager to fail
|
||||
- #4132 Laggy mouse cursor on macOS clients
|
||||
|
||||
Enhancements:
|
||||
- #6116 Quieter quartz event log entry on Mac
|
||||
- #6037 Solve defects reported by PVS Studio
|
||||
- #6014 Code sign binaries on Windows
|
||||
- #6012 Jenkins integration for Ubuntu
|
||||
- #5836 Jenkins integration for macOS
|
||||
- #5834 Jenkins integration for Fedora
|
||||
- #5390 Allow tests to be skipped during build
|
||||
- #5389 Qt 5 library support for config app
|
||||
- #5019 Raspbian armhf support for Raspberry Pi
|
||||
- #4978 Visual Studio 2015 support on Windows 10
|
||||
- #4154 IPv6 support for Windows and Linux
|
||||
|
||||
v1.8.8-stable
|
||||
==========
|
||||
=============
|
||||
Bug #5196 - Some keys on Korean and Japanese keyboards have the same keycode
|
||||
Bug #5578 - Pressing Hangul key results in alt+'a'
|
||||
Bug #5785 - Can't switch screens when cursor is in a corner
|
||||
@@ -423,4 +493,3 @@ Feature #3119: Mac OS X secondary screen
|
||||
Task #2905: Unit tests: Clipboard classes
|
||||
Task #3072: Downgrade Linux build machines
|
||||
Task #3090: CXWindowsKeyState integ test args wrong
|
||||
|
||||
|
||||
@@ -3,37 +3,30 @@ cmake_minimum_required (VERSION 3.4)
|
||||
#
|
||||
# Synergy Version
|
||||
#
|
||||
if (NOT DEFINED SYNERGY_VERSION_MAJOR)
|
||||
if (DEFINED ENV{SYNERGY_VERSION_MAJOR})
|
||||
set (SYNERGY_VERSION_MAJOR $ENV{SYNERGY_VERSION_MAJOR})
|
||||
else()
|
||||
set (SYNERGY_VERSION_MAJOR 1)
|
||||
endif()
|
||||
|
||||
set (SYNERGY_VERSION_MAJOR 1)
|
||||
set (SYNERGY_VERSION_MINOR 10)
|
||||
set (SYNERGY_VERSION_PATCH 2)
|
||||
set (SYNERGY_VERSION_STAGE "rc2")
|
||||
|
||||
#
|
||||
# Version from CI
|
||||
#
|
||||
|
||||
if (DEFINED ENV{SYNERGY_VERSION_MAJOR})
|
||||
set (SYNERGY_VERSION_MAJOR $ENV{SYNERGY_VERSION_MAJOR})
|
||||
endif()
|
||||
|
||||
if (NOT DEFINED SYNERGY_VERSION_MINOR)
|
||||
if (DEFINED ENV{SYNERGY_VERSION_MINOR})
|
||||
set (SYNERGY_VERSION_MINOR $ENV{SYNERGY_VERSION_MINOR})
|
||||
else()
|
||||
set (SYNERGY_VERSION_MINOR 9)
|
||||
endif()
|
||||
if (DEFINED ENV{SYNERGY_VERSION_MINOR})
|
||||
set (SYNERGY_VERSION_MINOR $ENV{SYNERGY_VERSION_MINOR})
|
||||
endif()
|
||||
|
||||
if (NOT DEFINED SYNERGY_VERSION_PATCH)
|
||||
if (DEFINED ENV{SYNERGY_VERSION_PATCH})
|
||||
set (SYNERGY_VERSION_PATCH $ENV{SYNERGY_VERSION_PATCH})
|
||||
else()
|
||||
set (SYNERGY_VERSION_PATCH 0)
|
||||
message (WARNING "Synergy version wasn't set. Set to ${SYNERGY_VERSION_MAJOR}.${SYNERGY_VERSION_MINOR}.${SYNERGY_VERSION_PATCH}")
|
||||
endif()
|
||||
if (DEFINED ENV{SYNERGY_VERSION_PATCH})
|
||||
set (SYNERGY_VERSION_PATCH $ENV{SYNERGY_VERSION_PATCH})
|
||||
endif()
|
||||
|
||||
if (NOT DEFINED SYNERGY_VERSION_STAGE)
|
||||
if (DEFINED ENV{SYNERGY_VERSION_STAGE})
|
||||
set (SYNERGY_VERSION_STAGE $ENV{SYNERGY_VERSION_STAGE})
|
||||
else()
|
||||
set (SYNERGY_VERSION_STAGE "snapshot")
|
||||
endif()
|
||||
if (DEFINED ENV{SYNERGY_VERSION_STAGE})
|
||||
set (SYNERGY_VERSION_STAGE $ENV{SYNERGY_VERSION_STAGE})
|
||||
endif()
|
||||
|
||||
if (NOT DEFINED SYNERGY_REVISION)
|
||||
@@ -88,3 +81,6 @@ if (SYNERGY_DEVELOPER_MODE)
|
||||
add_definitions (-DSYNERGY_DEVELOPER_MODE=1)
|
||||
endif()
|
||||
|
||||
if (SYNERGY_ENTERPRISE)
|
||||
add_definitions (-DSYNERGY_ENTERPRISE=1)
|
||||
endif()
|
||||
|
||||
2
debian/control
vendored
2
debian/control
vendored
@@ -6,7 +6,7 @@ Homepage: https://www.symless.com/
|
||||
Maintainer: Symless <engineering@symless.com>
|
||||
|
||||
Package: synergy
|
||||
Architecture: amd64
|
||||
Architecture: any
|
||||
Section: utils
|
||||
Priority: optional
|
||||
Depends: ${shlibs:Depends},
|
||||
|
||||
6
dist/wix/Include.wxi.in
vendored
6
dist/wix/Include.wxi.in
vendored
@@ -2,7 +2,7 @@
|
||||
<Include>
|
||||
<?define Name="Synergy" ?>
|
||||
<?define Version="@SYNERGY_VERSION@" ?>
|
||||
<?define QtVersion="5.9.4" ?> <!-- TODO: Configure this externally //-->
|
||||
<?define QtVersion="5.9.5" ?> <!-- TODO: Configure this externally //-->
|
||||
<?define Author="Symless Ltd" ?>
|
||||
<?define BinPath="@CMAKE_RUNTIME_OUTPUT_DIRECTORY@/$(var.Configuration)" ?>
|
||||
<?define ResPath="@CMAKE_CURRENT_SOURCE_DIR@/res" ?>
|
||||
@@ -11,12 +11,12 @@
|
||||
<?define ProgramFilesFolder="ProgramFiles64Folder" ?>
|
||||
<?define PlatformSimpleName="64-bit" ?>
|
||||
<?define UpgradeGuid="E8A4FA54-14B9-4FD1-8E00-7BC46555FDA0" ?>
|
||||
<?define QtPath="C:\Qt\$(var.QtVersion)\msvc2015_64" ?>
|
||||
<?define QtPath="C:\Qt\Qt$(var.QtVersion)\$(var.QtVersion)\msvc2015_64" ?>
|
||||
<?else ?>
|
||||
<?define ProgramFilesFolder="ProgramFilesFolder" ?>
|
||||
<?define PlatformSimpleName="32-bit" ?>
|
||||
<?define UpgradeGuid="BE0B9FD8-45E2-4A8E-A0D8-1F774D074A78" ?>
|
||||
<?define QtPath="C:\Qt\$(var.QtVersion)\msvc2015" ?>
|
||||
<?define QtPath="C:\Qt\Qt$(var.QtVersion)\$(var.QtVersion)\msvc2015" ?>
|
||||
<?endif ?>
|
||||
<?define QtBinPath="$(var.QtPath)\bin" ?>
|
||||
<?define QtPlatformPath="$(var.QtPath)\plugins\platforms" ?>
|
||||
|
||||
27
dist/wix/Product.wxs
vendored
27
dist/wix/Product.wxs
vendored
@@ -22,20 +22,30 @@
|
||||
</Feature>
|
||||
<DirectoryRef Id="TARGETDIR">
|
||||
<Component Guid="7CF3564D-1F8E-4D3D-9781-E1EE22D5BD67" Id="RegistryEntries">
|
||||
<RegistryKey ForceCreateOnInstall="yes" ForceDeleteOnUninstall="yes" Key="Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers" Root="HKLM">
|
||||
<RegistryKey Id="synergys" ForceCreateOnInstall="yes" ForceDeleteOnUninstall="yes" Key="Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers" Root="HKLM">
|
||||
<RegistryValue Name="[INSTALLFOLDER]synergys.exe" Type="string" Value="~ HIGHDPIAWARE WIN7RTM"/>
|
||||
</RegistryKey>
|
||||
|
||||
<RegistryKey Id="synergyc" Root="HKLM"
|
||||
Key="Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers"
|
||||
Action="createAndRemoveOnUninstall">
|
||||
<RegistryValue Type="string" Name="[INSTALLFOLDER]synergyc.exe" Value="~ HIGHDPIAWARE WIN7RTM"/>
|
||||
</RegistryKey>
|
||||
|
||||
<RegistryKey Id="synergy" Root="HKLM"
|
||||
Key="Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers"
|
||||
Action="createAndRemoveOnUninstall">
|
||||
<RegistryValue Type="string" Name="[INSTALLFOLDER]synergy.exe" Value="~ HIGHDPIAWARE WIN7RTM"/>
|
||||
</RegistryKey>
|
||||
<!-- Windows 8 and later only -->
|
||||
<Condition><![CDATA[Installed OR (VersionNT >= 602)]]></Condition>
|
||||
</Component>
|
||||
</DirectoryRef>
|
||||
<Icon Id="synergy.ico" SourceFile="$(var.ResPath)/synergy.ico"/>
|
||||
<WixVariable Id="WixUILicenseRtf" Value="$(var.ResPath)\License.rtf"/>
|
||||
<WixVariable Id="WixUIBannerBmp" Value="$(var.ResPath)\banner.bmp"/>
|
||||
<WixVariable Id="WixUIDialogBmp" Value="$(var.ResPath)\dialog.bmp"/>
|
||||
<Property Id="ARPPRODUCTICON" Value="synergy.ico"/>
|
||||
<Property Id="WIXUI_INSTALLDIR" Value="INSTALLFOLDER"/>
|
||||
<Property Id="MSIRESTARTMANAGERCONTROL" Value="Disable"/>
|
||||
<Property Id="LEGACY_UNINSTALL_EXISTS">
|
||||
<RegistrySearch Id="LegacyRegistrySearch" Key="SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\Synergy" Name="UninstallString" Root="HKLM" Type="file" Win64="no">
|
||||
<FileSearch Id="LegacyFileSearch" Name="uninstall.exe"/>
|
||||
@@ -45,6 +55,17 @@
|
||||
</Condition>
|
||||
<CustomAction ExeCommand="" FileKey="GuiProgram" Id="StartGui" Return="asyncNoWait"/>
|
||||
<UI>
|
||||
<UIRef Id="WixUI_InstallDir" />
|
||||
<Publish Dialog="WelcomeDlg"
|
||||
Control="Next"
|
||||
Event="NewDialog"
|
||||
Value="InstallDirDlg"
|
||||
Order="2">1</Publish>
|
||||
<Publish Dialog="InstallDirDlg"
|
||||
Control="Back"
|
||||
Event="NewDialog"
|
||||
Value="WelcomeDlg"
|
||||
Order="2">1</Publish>
|
||||
<Publish Control="Finish" Dialog="ExitDialog" Event="DoAction" Value="StartGui">NOT Installed</Publish>
|
||||
</UI>
|
||||
</Product>
|
||||
|
||||
@@ -8,6 +8,14 @@ set (CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
|
||||
file (GLOB LEGACY_GUI_SOURCE_FILES src/*.cpp src/*.h)
|
||||
file (GLOB LEGACY_GUI_UI_FILES src/*.ui)
|
||||
file (GLOB LEGACY_ACTIVATION_FILES src/*Activation* src/*License*)
|
||||
file (GLOB LEGACY_ZEROCONF_FILES src/Zeroconf*)
|
||||
|
||||
if (SYNERGY_ENTERPRISE)
|
||||
list (REMOVE_ITEM LEGACY_GUI_SOURCE_FILES ${LEGACY_ACTIVATION_FILES})
|
||||
list (REMOVE_ITEM LEGACY_GUI_UI_FILES ${LEGACY_ACTIVATION_FILES})
|
||||
list (REMOVE_ITEM LEGACY_GUI_SOURCE_FILES ${LEGACY_ZEROCONF_FILES})
|
||||
endif ()
|
||||
|
||||
if (WIN32)
|
||||
set (LEGACY_GUI_RC_FILES res/win/Synergy.rc)
|
||||
@@ -23,28 +31,32 @@ add_executable (synergy WIN32
|
||||
include_directories (./src)
|
||||
target_link_libraries (synergy shared)
|
||||
|
||||
if (NOT SYNERGY_ENTERPRISE)
|
||||
if (WIN32)
|
||||
include_directories ($ENV{BONJOUR_SDK_HOME}/Include)
|
||||
if (CMAKE_SIZEOF_VOID_P EQUAL 8)
|
||||
find_library (DNSSD_LIB dnssd.lib
|
||||
find_library (DNSSD_LIB dnssd.lib
|
||||
HINTS ENV BONJOUR_SDK_HOME
|
||||
PATH_SUFFIXES "Lib/x64")
|
||||
else()
|
||||
find_library (DNSSD_LIB dnssd.lib
|
||||
find_library (DNSSD_LIB dnssd.lib
|
||||
HINTS ENV BONJOUR_SDK_HOME
|
||||
PATH_SUFFIXES "Lib/Win32")
|
||||
endif()
|
||||
|
||||
|
||||
elseif (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
target_link_libraries (synergy dns_sd)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
qt5_use_modules (synergy Core Widgets Network)
|
||||
target_compile_definitions (synergy PRIVATE -DSYNERGY_VERSION_STAGE="${SYNERGY_VERSION_STAGE}")
|
||||
target_compile_definitions (synergy PRIVATE -DSYNERGY_REVISION="${SYNERGY_REVISION}")
|
||||
|
||||
if (WIN32)
|
||||
if (NOT SYNERGY_ENTERPRISE)
|
||||
target_link_libraries (synergy ${DNSSD_LIB})
|
||||
endif ()
|
||||
set_target_properties (synergy PROPERTIES LINK_FLAGS "/NODEFAULTLIB:LIBCMT")
|
||||
endif()
|
||||
|
||||
|
||||
@@ -54,5 +54,6 @@
|
||||
<file>image/spinning-wheel.gif</file>
|
||||
<file>icons/16x16/padlock.png</file>
|
||||
<file>icons/16x16/synergy-transfering.png</file>
|
||||
<file>icons/16x16/auto-config.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
||||
BIN
src/gui/res/icons/16x16/auto-config.png
Normal file
BIN
src/gui/res/icons/16x16/auto-config.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 610 B |
@@ -25,6 +25,7 @@
|
||||
|
||||
#include <QtCore>
|
||||
#include <QtGui>
|
||||
#include <QButtonGroup>
|
||||
|
||||
ActionDialog::ActionDialog(QWidget* parent, ServerConfig& config, Hotkey& hotkey, Action& action) :
|
||||
QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint),
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
#include "ui_ActivationDialog.h"
|
||||
#include "CancelActivationDialog.h"
|
||||
#include "AppConfig.h"
|
||||
#include "WebClient.h"
|
||||
#include <shared/EditionType.h>
|
||||
#include "ActivationNotifier.h"
|
||||
#include "MainWindow.h"
|
||||
|
||||
@@ -40,21 +40,10 @@ void ActivationNotifier::setUpdateInfo(QString const& fromVersion,
|
||||
|
||||
void ActivationNotifier::notify()
|
||||
{
|
||||
CoreInterface coreInterface;
|
||||
try {
|
||||
coreInterface.notifyActivation(m_Identity);
|
||||
}
|
||||
catch (...) {
|
||||
// catch all exceptions and fails silently
|
||||
}
|
||||
// TODO: use something other than CURL
|
||||
}
|
||||
|
||||
void ActivationNotifier::notifyUpdate()
|
||||
{
|
||||
try {
|
||||
CoreInterface coreInterface;
|
||||
coreInterface.notifyUpdate(m_fromVersion, m_toVersion,
|
||||
m_serialKey);
|
||||
} catch (...) {
|
||||
}
|
||||
// TODO: use something other than CURL
|
||||
}
|
||||
|
||||
@@ -38,9 +38,6 @@ const ElevateMode defaultElevateMode = ElevateAsNeeded;
|
||||
|
||||
static const char* logLevelNames[] =
|
||||
{
|
||||
"ERROR",
|
||||
"WARNING",
|
||||
"NOTE",
|
||||
"INFO",
|
||||
"DEBUG",
|
||||
"DEBUG1",
|
||||
@@ -57,10 +54,10 @@ AppConfig::AppConfig(QSettings* settings) :
|
||||
m_ProcessMode(DEFAULT_PROCESS_MODE),
|
||||
m_AutoConfig(true),
|
||||
m_ElevateMode(defaultElevateMode),
|
||||
m_AutoConfigPrompted(false),
|
||||
m_CryptoEnabled(false),
|
||||
m_AutoHide(false),
|
||||
m_LastExpiringWarningTime(0)
|
||||
m_LastExpiringWarningTime(0),
|
||||
m_AutoConfigServer()
|
||||
{
|
||||
Q_ASSERT(m_pSettings);
|
||||
|
||||
@@ -86,13 +83,8 @@ const QString &AppConfig::logFilename() const { return m_LogFilename; }
|
||||
|
||||
QString AppConfig::synergyLogDir() const
|
||||
{
|
||||
#if defined(Q_OS_WIN)
|
||||
// on windows, we want to log to program files
|
||||
return synergyProgramDir() + "log/";
|
||||
#else
|
||||
// on unix, we'll log to the standard log dir
|
||||
return "/var/log/";
|
||||
#endif
|
||||
// by default log to home dir
|
||||
return QDir::home().absolutePath() + "/";
|
||||
}
|
||||
|
||||
QString AppConfig::synergyProgramDir() const
|
||||
@@ -135,27 +127,36 @@ const QString &AppConfig::language() const { return m_Language; }
|
||||
|
||||
bool AppConfig::startedBefore() const { return m_StartedBefore; }
|
||||
|
||||
bool AppConfig::autoConfig() const { return m_AutoConfig; }
|
||||
bool AppConfig::autoConfig() const {
|
||||
#ifndef SYNERGY_ENTERPRISE
|
||||
return m_AutoConfig;
|
||||
#else
|
||||
// always disable auto config for enterprise edition.
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
QString AppConfig::autoConfigServer() const { return m_AutoConfigServer; }
|
||||
|
||||
void AppConfig::loadSettings()
|
||||
{
|
||||
m_ScreenName = settings().value("screenName", QHostInfo::localHostName()).toString();
|
||||
m_Port = settings().value("port", 24800).toInt();
|
||||
m_Interface = settings().value("interface").toString();
|
||||
m_LogLevel = settings().value("logLevel", 3).toInt(); // level 3: INFO
|
||||
m_LogLevel = settings().value("logLevel2", 0).toInt(); // level 0: INFO
|
||||
m_LogToFile = settings().value("logToFile", false).toBool();
|
||||
m_LogFilename = settings().value("logFilename", synergyLogDir() + "synergy.log").toString();
|
||||
m_WizardLastRun = settings().value("wizardLastRun", 0).toInt();
|
||||
m_Language = settings().value("language", QLocale::system().name()).toString();
|
||||
m_StartedBefore = settings().value("startedBefore", false).toBool();
|
||||
m_AutoConfig = settings().value("autoConfig", true).toBool();
|
||||
m_AutoConfig = settings().value("autoConfig", false).toBool();
|
||||
m_AutoConfigServer = settings().value("autoConfigServer", "").toString();
|
||||
QVariant elevateMode = settings().value("elevateModeEnum");
|
||||
if (!elevateMode.isValid()) {
|
||||
elevateMode = settings().value ("elevateMode",
|
||||
QVariant(static_cast<int>(defaultElevateMode)));
|
||||
}
|
||||
m_ElevateMode = static_cast<ElevateMode>(elevateMode.toInt());
|
||||
m_AutoConfigPrompted = settings().value("autoConfigPrompted", false).toBool();
|
||||
m_Edition = static_cast<Edition>(settings().value("edition", kUnregistered).toInt());
|
||||
m_ActivateEmail = settings().value("activateEmail", "").toString();
|
||||
m_CryptoEnabled = settings().value("cryptoEnabled", true).toBool();
|
||||
@@ -171,18 +172,18 @@ void AppConfig::saveSettings()
|
||||
settings().setValue("screenName", m_ScreenName);
|
||||
settings().setValue("port", m_Port);
|
||||
settings().setValue("interface", m_Interface);
|
||||
settings().setValue("logLevel", m_LogLevel);
|
||||
settings().setValue("logLevel2", m_LogLevel);
|
||||
settings().setValue("logToFile", m_LogToFile);
|
||||
settings().setValue("logFilename", m_LogFilename);
|
||||
settings().setValue("wizardLastRun", kWizardVersion);
|
||||
settings().setValue("language", m_Language);
|
||||
settings().setValue("startedBefore", m_StartedBefore);
|
||||
settings().setValue("autoConfig", m_AutoConfig);
|
||||
settings().setValue("autoConfigServer", m_AutoConfigServer);
|
||||
// Refer to enum ElevateMode declaration for insight in to why this
|
||||
// flag is mapped this way
|
||||
settings().setValue("elevateMode", m_ElevateMode == ElevateAlways);
|
||||
settings().setValue("elevateModeEnum", static_cast<int>(m_ElevateMode));
|
||||
settings().setValue("autoConfigPrompted", m_AutoConfigPrompted);
|
||||
settings().setValue("edition", m_Edition);
|
||||
settings().setValue("cryptoEnabled", m_CryptoEnabled);
|
||||
settings().setValue("autoHide", m_AutoHide);
|
||||
@@ -193,6 +194,7 @@ void AppConfig::saveSettings()
|
||||
settings().sync();
|
||||
}
|
||||
|
||||
#ifndef SYNERGY_ENTERPRISE
|
||||
bool AppConfig::activationHasRun() const
|
||||
{
|
||||
return m_ActivationHasRun;
|
||||
@@ -203,6 +205,7 @@ AppConfig& AppConfig::activationHasRun(bool value)
|
||||
m_ActivationHasRun = value;
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
QString AppConfig::lastVersion() const
|
||||
{
|
||||
@@ -240,13 +243,12 @@ void AppConfig::setAutoConfig(bool autoConfig)
|
||||
m_AutoConfig = autoConfig;
|
||||
}
|
||||
|
||||
bool AppConfig::autoConfigPrompted() { return m_AutoConfigPrompted; }
|
||||
|
||||
void AppConfig::setAutoConfigPrompted(bool prompted)
|
||||
void AppConfig::setAutoConfigServer(QString autoConfigServer)
|
||||
{
|
||||
m_AutoConfigPrompted = prompted;
|
||||
m_AutoConfigServer = autoConfigServer;
|
||||
}
|
||||
|
||||
#ifndef SYNERGY_ENTERPRISE
|
||||
void AppConfig::setEdition(Edition e) {
|
||||
m_Edition = e;
|
||||
}
|
||||
@@ -269,6 +271,7 @@ QString AppConfig::serialKey() { return m_Serialkey; }
|
||||
int AppConfig::lastExpiringWarningTime() const { return m_LastExpiringWarningTime; }
|
||||
|
||||
void AppConfig::setLastExpiringWarningTime(int t) { m_LastExpiringWarningTime = t; }
|
||||
#endif
|
||||
|
||||
QString AppConfig::synergysName() const { return m_SynergysName; }
|
||||
|
||||
@@ -285,7 +288,11 @@ void AppConfig::setCryptoEnabled(bool e) {
|
||||
}
|
||||
|
||||
bool AppConfig::getCryptoEnabled() const {
|
||||
return (edition() == kPro) && m_CryptoEnabled;
|
||||
return
|
||||
#ifndef SYNERGY_ENTERPRISE
|
||||
(edition() == kPro) &&
|
||||
#endif
|
||||
m_CryptoEnabled;
|
||||
}
|
||||
|
||||
void AppConfig::setAutoHide(bool b) { m_AutoHide = b; }
|
||||
|
||||
@@ -77,8 +77,9 @@ class AppConfig: public QObject
|
||||
bool startedBefore() const;
|
||||
bool autoConfig() const;
|
||||
void setAutoConfig(bool autoConfig);
|
||||
bool autoConfigPrompted();
|
||||
void setAutoConfigPrompted(bool prompted);
|
||||
QString autoConfigServer() const;
|
||||
void setAutoConfigServer(QString autoConfigServer);
|
||||
#ifndef SYNERGY_ENTERPRISE
|
||||
void setEdition(Edition);
|
||||
Edition edition() const;
|
||||
QString setSerialKey(QString serial);
|
||||
@@ -86,6 +87,7 @@ class AppConfig: public QObject
|
||||
QString serialKey();
|
||||
int lastExpiringWarningTime() const;
|
||||
void setLastExpiringWarningTime(int t);
|
||||
#endif
|
||||
|
||||
QString synergysName() const;
|
||||
QString synergycName() const;
|
||||
@@ -101,9 +103,10 @@ class AppConfig: public QObject
|
||||
|
||||
void setAutoHide(bool b);
|
||||
bool getAutoHide();
|
||||
|
||||
#ifndef SYNERGY_ENTERPRISE
|
||||
bool activationHasRun() const;
|
||||
AppConfig& activationHasRun(bool value);
|
||||
#endif
|
||||
|
||||
QString lastVersion() const;
|
||||
|
||||
@@ -137,8 +140,8 @@ protected:
|
||||
QString m_Language;
|
||||
bool m_StartedBefore;
|
||||
bool m_AutoConfig;
|
||||
QString m_AutoConfigServer;
|
||||
ElevateMode m_ElevateMode;
|
||||
bool m_AutoConfigPrompted;
|
||||
Edition m_Edition;
|
||||
QString m_ActivateEmail;
|
||||
bool m_CryptoEnabled;
|
||||
|
||||
203
src/gui/src/BonjourWindows.cpp
Normal file
203
src/gui/src/BonjourWindows.cpp
Normal file
@@ -0,0 +1,203 @@
|
||||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2012-2018 Symless Ltd.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* found in the file LICENSE that should have accompanied this file.
|
||||
*
|
||||
* This package is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "BonjourWindows.h"
|
||||
|
||||
#if defined(Q_OS_WIN)
|
||||
|
||||
#include "MainWindow.h"
|
||||
#include "SettingsDialog.h"
|
||||
#include "DataDownloader.h"
|
||||
#include "QUtility.h"
|
||||
#include "CommandProcess.h"
|
||||
|
||||
#include <QUrl>
|
||||
#include <QThread>
|
||||
#include <QDir>
|
||||
#include <QStandardPaths>
|
||||
#include <QMessageBox>
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <Windows.h>
|
||||
|
||||
BonjourWindows::BonjourWindows(
|
||||
SettingsDialog* settingsDialog,
|
||||
MainWindow* mainWindow,
|
||||
AppConfig& appConfig) :
|
||||
m_pSettingsDialog(settingsDialog),
|
||||
m_pMainWindow(mainWindow),
|
||||
m_pBonjourInstall(nullptr),
|
||||
m_pDownloadMessageBox(nullptr),
|
||||
m_pDataDownloader(nullptr),
|
||||
m_appConfig(appConfig)
|
||||
{
|
||||
}
|
||||
|
||||
BonjourWindows::~BonjourWindows()
|
||||
{
|
||||
if (m_pBonjourInstall != nullptr) {
|
||||
delete m_pBonjourInstall;
|
||||
}
|
||||
|
||||
if (m_pDownloadMessageBox != nullptr) {
|
||||
delete m_pDownloadMessageBox;
|
||||
}
|
||||
|
||||
if (m_pDataDownloader != nullptr) {
|
||||
delete m_pDataDownloader;
|
||||
}
|
||||
}
|
||||
|
||||
void BonjourWindows::downloadAndInstall()
|
||||
{
|
||||
QUrl url;
|
||||
int arch = getProcessorArch();
|
||||
if (arch == kProcessorArchWin32) {
|
||||
url.setUrl(bonjourBaseUrl + bonjourFilename32);
|
||||
m_pMainWindow->appendLogInfo("downloading bonjour (32-bit)");
|
||||
}
|
||||
else if (arch == kProcessorArchWin64) {
|
||||
url.setUrl(bonjourBaseUrl + bonjourFilename64);
|
||||
m_pMainWindow->appendLogInfo("downloading bonjour (64-bit)");
|
||||
}
|
||||
else {
|
||||
QMessageBox::critical(
|
||||
m_pSettingsDialog, tr("Synergy Auto Config"),
|
||||
tr("Failed to detect system architecture."));
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_pDataDownloader == nullptr) {
|
||||
m_pDataDownloader = new DataDownloader(this);
|
||||
connect(m_pDataDownloader, SIGNAL(isComplete()), SLOT(downloadFinished()));
|
||||
}
|
||||
|
||||
m_pDataDownloader->download(url);
|
||||
|
||||
if (m_pDownloadMessageBox != nullptr) {
|
||||
delete m_pDownloadMessageBox;
|
||||
m_pDownloadMessageBox = nullptr;
|
||||
}
|
||||
|
||||
m_pDownloadMessageBox = new QMessageBox(m_pSettingsDialog);
|
||||
m_pDownloadMessageBox->setWindowTitle("Synergy Auto Config");
|
||||
m_pDownloadMessageBox->setIcon(QMessageBox::Information);
|
||||
m_pDownloadMessageBox->setText("Installing Bonjour, please wait...");
|
||||
QAbstractButton* cancel = m_pDownloadMessageBox->addButton(
|
||||
tr("Cancel"), QMessageBox::RejectRole);
|
||||
|
||||
m_pDownloadMessageBox->exec();
|
||||
|
||||
if (cancel == m_pDownloadMessageBox->clickedButton()) {
|
||||
m_pDataDownloader->cancel();
|
||||
}
|
||||
}
|
||||
|
||||
void BonjourWindows::downloadFinished()
|
||||
{
|
||||
m_pMainWindow->appendLogInfo("bonjour downloaded");
|
||||
install();
|
||||
}
|
||||
|
||||
void BonjourWindows::install()
|
||||
{
|
||||
m_pMainWindow->appendLogInfo("installing bonjour");
|
||||
|
||||
QString tempLocation = QStandardPaths::writableLocation(QStandardPaths::TempLocation);
|
||||
|
||||
QString filename = tempLocation;
|
||||
filename.append("\\").append(bonjourTargetFilename);
|
||||
QFile file(filename);
|
||||
if (!file.open(QIODevice::WriteOnly)) {
|
||||
m_pDownloadMessageBox->hide();
|
||||
|
||||
QMessageBox::warning(
|
||||
m_pSettingsDialog, "Synergy",
|
||||
tr("Failed to download Bonjour installer to location: %1")
|
||||
.arg(tempLocation));
|
||||
return;
|
||||
}
|
||||
|
||||
file.write(m_pDataDownloader->data());
|
||||
file.close();
|
||||
|
||||
QStringList arguments;
|
||||
arguments.append("/i");
|
||||
QString winFilename = QDir::toNativeSeparators(filename);
|
||||
arguments.append(winFilename);
|
||||
arguments.append("/passive");
|
||||
|
||||
if (m_pBonjourInstall != nullptr) {
|
||||
delete m_pBonjourInstall;
|
||||
m_pBonjourInstall = nullptr;
|
||||
}
|
||||
|
||||
m_pBonjourInstall = new CommandProcess("msiexec", arguments);
|
||||
|
||||
QThread* thread = new QThread;
|
||||
connect(m_pBonjourInstall, SIGNAL(finished()), this, SLOT(installFinished()));
|
||||
connect(m_pBonjourInstall, SIGNAL(finished()), thread, SLOT(quit()));
|
||||
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
|
||||
|
||||
m_pBonjourInstall->moveToThread(thread);
|
||||
thread->start();
|
||||
|
||||
QMetaObject::invokeMethod(m_pBonjourInstall, "run", Qt::QueuedConnection);
|
||||
|
||||
m_pDownloadMessageBox->hide();
|
||||
}
|
||||
|
||||
bool BonjourWindows::isRunning() const
|
||||
{
|
||||
QString name = "Bonjour Service";
|
||||
|
||||
SC_HANDLE hSCManager;
|
||||
hSCManager = OpenSCManager(nullptr, nullptr, SC_MANAGER_CONNECT);
|
||||
|
||||
if (hSCManager == nullptr) {
|
||||
m_pMainWindow->appendLogError(
|
||||
QString("failed to open a service controller manager, error: %1").arg(GetLastError()));
|
||||
return false;
|
||||
}
|
||||
|
||||
auto array = name.toLocal8Bit();
|
||||
SC_HANDLE hService = OpenService(hSCManager, array.data(), SERVICE_QUERY_STATUS);
|
||||
|
||||
if (hService == nullptr) {
|
||||
m_pMainWindow->appendLogDebug(
|
||||
QString("failed to open service: %1").arg(name));
|
||||
return false;
|
||||
}
|
||||
|
||||
SERVICE_STATUS status;
|
||||
if (QueryServiceStatus(hService, &status)) {
|
||||
if (status.dwCurrentState == SERVICE_RUNNING) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void BonjourWindows::installFinished()
|
||||
{
|
||||
m_pMainWindow->appendLogInfo("bonjour installed");
|
||||
m_appConfig.setAutoConfig(true);
|
||||
m_pSettingsDialog->allowAutoConfig();
|
||||
}
|
||||
|
||||
#endif // Q_OS_WIN
|
||||
65
src/gui/src/BonjourWindows.h
Normal file
65
src/gui/src/BonjourWindows.h
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2012-2018 Symless Ltd.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* found in the file LICENSE that should have accompanied this file.
|
||||
*
|
||||
* This package is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QtCore/QObject>
|
||||
|
||||
#if defined(Q_OS_WIN)
|
||||
|
||||
#include <QMessageBox>
|
||||
|
||||
static QString bonjourBaseUrl = "http://binaries.symless.com/bonjour/";
|
||||
static const char bonjourFilename32[] = "Bonjour.msi";
|
||||
static const char bonjourFilename64[] = "Bonjour64.msi";
|
||||
static const char bonjourTargetFilename[] = "Bonjour.msi";
|
||||
|
||||
class SettingsDialog;
|
||||
class MainWindow;
|
||||
class CommandProcess;
|
||||
class DataDownloader;
|
||||
class AppConfig;
|
||||
|
||||
class BonjourWindows : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
BonjourWindows(SettingsDialog* settingsDialog, MainWindow* mainWindow, AppConfig& appConfig);
|
||||
virtual ~BonjourWindows();
|
||||
|
||||
public:
|
||||
void downloadAndInstall();
|
||||
bool isRunning() const;
|
||||
|
||||
protected slots:
|
||||
void downloadFinished();
|
||||
void installFinished();
|
||||
|
||||
private:
|
||||
void install();
|
||||
|
||||
private:
|
||||
SettingsDialog* m_pSettingsDialog;
|
||||
MainWindow* m_pMainWindow;
|
||||
CommandProcess* m_pBonjourInstall;
|
||||
QMessageBox* m_pDownloadMessageBox;
|
||||
DataDownloader* m_pDataDownloader;
|
||||
AppConfig& m_appConfig;
|
||||
};
|
||||
|
||||
#endif // Q_OS_WIN
|
||||
@@ -62,29 +62,6 @@ QString CoreInterface::getSerialKeyFilePath()
|
||||
return filename;
|
||||
}
|
||||
|
||||
QString CoreInterface::notifyUpdate (QString const& fromVersion,
|
||||
QString const& toVersion,
|
||||
QString const& serialKey) {
|
||||
QStringList args("--notify-update");
|
||||
QString input(fromVersion + ":" + toVersion + ":" + serialKey);
|
||||
input.append("\n");
|
||||
return run(args, input);
|
||||
}
|
||||
|
||||
QString CoreInterface::notifyActivation(const QString& identity)
|
||||
{
|
||||
QStringList args("--notify-activation");
|
||||
|
||||
QString input(identity + ":" + hash(getFirstMacAddress()));
|
||||
QString os= getOSInformation();
|
||||
if (!os.isEmpty()) {
|
||||
input.append(":").append(os);
|
||||
}
|
||||
input.append("\n");
|
||||
|
||||
return run(args, input);
|
||||
}
|
||||
|
||||
QString CoreInterface::run(const QStringList& args, const QString& input)
|
||||
{
|
||||
QString program(
|
||||
|
||||
@@ -28,9 +28,5 @@ public:
|
||||
QString getInstalledDir();
|
||||
QString getArch();
|
||||
QString getSerialKeyFilePath();
|
||||
QString notifyActivation(const QString& identity);
|
||||
QString notifyUpdate (QString const& fromVersion,
|
||||
QString const& toVersion,
|
||||
QString const& serialKey);
|
||||
QString run(const QStringList& args, const QString& input = "");
|
||||
};
|
||||
|
||||
@@ -34,6 +34,7 @@ void DataDownloader::complete(QNetworkReply* reply)
|
||||
{
|
||||
m_Data = reply->readAll();
|
||||
reply->deleteLater();
|
||||
m_pReply = nullptr;
|
||||
|
||||
if (!m_Data.isEmpty()) {
|
||||
m_IsFinished = true;
|
||||
@@ -48,7 +49,9 @@ QByteArray DataDownloader::data() const
|
||||
|
||||
void DataDownloader::cancel()
|
||||
{
|
||||
m_pReply->abort();
|
||||
if (m_pReply != nullptr) {
|
||||
m_pReply->abort();
|
||||
}
|
||||
}
|
||||
|
||||
void DataDownloader::download(QUrl url)
|
||||
|
||||
@@ -106,7 +106,7 @@ void IpcClient::sendCommand(const QString& command, ElevateMode const elevate)
|
||||
|
||||
std::string stdStringCommand = command.toStdString();
|
||||
const char* charCommand = stdStringCommand.c_str();
|
||||
int length = strlen(charCommand);
|
||||
int length = static_cast<int>(strlen(charCommand));
|
||||
|
||||
char lenBuf[4];
|
||||
intToBytes(length, lenBuf, 4);
|
||||
|
||||
@@ -134,11 +134,11 @@ void LicenseManager::skipActivation()
|
||||
QString
|
||||
LicenseManager::getEditionName(Edition const edition, bool trial)
|
||||
{
|
||||
std::string name ("Synergy");
|
||||
std::string name ("Synergy 1");
|
||||
switch (edition) {
|
||||
case kUnregistered:
|
||||
name += " (UNREGISTERED)";
|
||||
return QString::fromUtf8 (name.c_str(), name.size());
|
||||
return QString::fromUtf8 (name.c_str(), static_cast<int>(name.size()));
|
||||
case kBasic:
|
||||
name += " Basic";
|
||||
break;
|
||||
@@ -148,7 +148,7 @@ LicenseManager::getEditionName(Edition const edition, bool trial)
|
||||
if (trial) {
|
||||
name += " (Trial)";
|
||||
}
|
||||
return QString::fromUtf8 (name.c_str(), name.size());
|
||||
return QString::fromUtf8 (name.c_str(), static_cast<int>(name.size()));
|
||||
}
|
||||
|
||||
void LicenseManager::notifyActivation(QString identity)
|
||||
|
||||
@@ -27,7 +27,6 @@
|
||||
#include "ServerConfigDialog.h"
|
||||
#include "SettingsDialog.h"
|
||||
#include "ActivationDialog.h"
|
||||
#include "ZeroconfService.h"
|
||||
#include "DataDownloader.h"
|
||||
#include "CommandProcess.h"
|
||||
#include "LicenseManager.h"
|
||||
@@ -35,6 +34,7 @@
|
||||
#include "QUtility.h"
|
||||
#include "ProcessorArch.h"
|
||||
#include "SslCertificate.h"
|
||||
#include "Zeroconf.h"
|
||||
|
||||
#include <QtCore>
|
||||
#include <QtGui>
|
||||
@@ -51,36 +51,42 @@
|
||||
#include <ApplicationServices/ApplicationServices.h>
|
||||
#endif
|
||||
|
||||
#if defined(Q_OS_WIN)
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <Windows.h>
|
||||
#endif
|
||||
|
||||
#if defined(Q_OS_WIN)
|
||||
static const char synergyConfigName[] = "synergy.sgc";
|
||||
static const QString synergyConfigFilter(QObject::tr("Synergy Configurations (*.sgc);;All files (*.*)"));
|
||||
static QString bonjourBaseUrl = "http://binaries.symless.com/bonjour/";
|
||||
static const char bonjourFilename32[] = "Bonjour.msi";
|
||||
static const char bonjourFilename64[] = "Bonjour64.msi";
|
||||
static const char bonjourTargetFilename[] = "Bonjour.msi";
|
||||
#else
|
||||
static const char synergyConfigName[] = "synergy.conf";
|
||||
static const QString synergyConfigFilter(QObject::tr("Synergy Configurations (*.conf);;All files (*.*)"));
|
||||
#endif
|
||||
|
||||
static const char* tlsVersion = "TLS 1.2";
|
||||
static const char* tlsCheckString = "network encryption protocol: TLSv1.2";
|
||||
|
||||
static const int debugLogLevel = 1;
|
||||
|
||||
static const char* synergyIconFiles[] =
|
||||
{
|
||||
":/res/icons/16x16/synergy-disconnected.png",
|
||||
":/res/icons/16x16/synergy-disconnected.png",
|
||||
":/res/icons/16x16/synergy-connected.png",
|
||||
":/res/icons/16x16/synergy-transfering.png"
|
||||
":/res/icons/16x16/synergy-disconnected.png", //synergyDisconnected
|
||||
":/res/icons/16x16/synergy-disconnected.png", //synergyConnecting
|
||||
":/res/icons/16x16/synergy-connected.png", //synergyConnected
|
||||
":/res/icons/16x16/synergy-transfering.png", //synergyListening
|
||||
":/res/icons/16x16/synergy-disconnected.png" //synergyPendingRetry
|
||||
};
|
||||
|
||||
MainWindow::MainWindow(QSettings& settings, AppConfig& appConfig,
|
||||
LicenseManager& licenseManager) :
|
||||
#ifdef SYNERGY_ENTERPRISE
|
||||
MainWindow::MainWindow (QSettings& settings, AppConfig& appConfig)
|
||||
#else
|
||||
MainWindow::MainWindow (QSettings& settings, AppConfig& appConfig,
|
||||
LicenseManager& licenseManager)
|
||||
#endif
|
||||
:
|
||||
#ifndef SYNERGY_ENTERPRISE
|
||||
m_LicenseManager(&licenseManager),
|
||||
m_ActivationDialogRunning(false),
|
||||
#endif
|
||||
m_pZeroconf(nullptr),
|
||||
m_Settings(settings),
|
||||
m_AppConfig(&appConfig),
|
||||
m_LicenseManager(&licenseManager),
|
||||
m_pSynergy(NULL),
|
||||
m_SynergyState(synergyDisconnected),
|
||||
m_ServerConfig(&m_Settings, 5, 3, m_AppConfig->screenName(), this),
|
||||
@@ -93,17 +99,15 @@ MainWindow::MainWindow(QSettings& settings, AppConfig& appConfig,
|
||||
m_pMenuEdit(NULL),
|
||||
m_pMenuWindow(NULL),
|
||||
m_pMenuHelp(NULL),
|
||||
m_pZeroconfService(NULL),
|
||||
m_pDataDownloader(NULL),
|
||||
m_DownloadMessageBox(NULL),
|
||||
m_pCancelButton(NULL),
|
||||
m_SuppressAutoConfigWarning(false),
|
||||
m_BonjourInstall(NULL),
|
||||
m_SuppressEmptyServerWarning(false),
|
||||
m_ExpectedRunningState(kStopped),
|
||||
m_pSslCertificate(NULL),
|
||||
m_ActivationDialogRunning(false)
|
||||
m_SecureSocket(false)
|
||||
{
|
||||
#ifndef SYNERGY_ENTERPRISE
|
||||
m_pZeroconf = new Zeroconf(this);
|
||||
#endif
|
||||
|
||||
setupUi(this);
|
||||
|
||||
createMenuBar();
|
||||
@@ -132,17 +136,14 @@ MainWindow::MainWindow(QSettings& settings, AppConfig& appConfig,
|
||||
setMinimumSize(size());
|
||||
#endif
|
||||
|
||||
m_SuppressAutoConfigWarning = true;
|
||||
m_pCheckBoxAutoConfig->setChecked(appConfig.autoConfig());
|
||||
m_SuppressAutoConfigWarning = false;
|
||||
|
||||
m_pComboServerList->hide();
|
||||
m_pLabelPadlock->hide();
|
||||
m_trialWidget->hide();
|
||||
|
||||
// hide padlock icon
|
||||
secureSocket(false);
|
||||
|
||||
connect (this, SIGNAL(windowShown()),
|
||||
this, SLOT(on_windowShown()), Qt::QueuedConnection);
|
||||
|
||||
#ifndef SYNERGY_ENTERPRISE
|
||||
connect (m_LicenseManager, SIGNAL(editionChanged(Edition)),
|
||||
this, SLOT(setEdition(Edition)), Qt::QueuedConnection);
|
||||
|
||||
@@ -151,20 +152,39 @@ MainWindow::MainWindow(QSettings& settings, AppConfig& appConfig,
|
||||
|
||||
connect (m_LicenseManager, SIGNAL(endTrial(bool)),
|
||||
this, SLOT(endTrial(bool)), Qt::QueuedConnection);
|
||||
#endif
|
||||
|
||||
connect (m_AppConfig, SIGNAL(sslToggled(bool)),
|
||||
this, SLOT(sslToggled(bool)), Qt::QueuedConnection);
|
||||
|
||||
#ifdef SYNERGY_ENTERPRISE
|
||||
setWindowTitle ("Synergy 1 Enterprise");
|
||||
#else
|
||||
setWindowTitle (m_LicenseManager->activeEditionName());
|
||||
m_LicenseManager->refresh();
|
||||
#endif
|
||||
|
||||
QString lastVersion = m_AppConfig->lastVersion();
|
||||
QString currentVersion = m_VersionChecker.getVersion();
|
||||
if (lastVersion != currentVersion) {
|
||||
m_AppConfig->setLastVersion (currentVersion);
|
||||
m_AppConfig->saveSettings();
|
||||
#ifndef SYNERGY_ENTERPRISE
|
||||
m_LicenseManager->notifyUpdate (lastVersion, currentVersion);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef SYNERGY_ENTERPRISE
|
||||
m_pActivate->setVisible(false);
|
||||
#endif
|
||||
|
||||
#ifndef SYNERGY_ENTERPRISE
|
||||
updateZeroconfService();
|
||||
|
||||
addZeroconfServer(m_AppConfig->autoConfigServer());
|
||||
#endif
|
||||
|
||||
updateAutoConfigWidgets();
|
||||
}
|
||||
|
||||
MainWindow::~MainWindow()
|
||||
@@ -174,18 +194,12 @@ MainWindow::~MainWindow()
|
||||
stopDesktop();
|
||||
}
|
||||
|
||||
#ifndef SYNERGY_ENTERPRISE
|
||||
delete m_pZeroconf;
|
||||
#endif
|
||||
|
||||
saveSettings();
|
||||
|
||||
delete m_pZeroconfService;
|
||||
|
||||
if (m_DownloadMessageBox != NULL) {
|
||||
delete m_DownloadMessageBox;
|
||||
}
|
||||
|
||||
if (m_BonjourInstall != NULL) {
|
||||
delete m_BonjourInstall;
|
||||
}
|
||||
|
||||
delete m_pSslCertificate;
|
||||
}
|
||||
|
||||
@@ -199,17 +213,11 @@ void MainWindow::open()
|
||||
|
||||
m_VersionChecker.checkLatest();
|
||||
|
||||
if (!appConfig().autoConfigPrompted()) {
|
||||
promptAutoConfig();
|
||||
}
|
||||
|
||||
// only start if user has previously started. this stops the gui from
|
||||
// auto hiding before the user has configured synergy (which of course
|
||||
// confuses first time users, who think synergy has crashed).
|
||||
if (appConfig().startedBefore() && appConfig().processMode() == Desktop) {
|
||||
m_SuppressEmptyServerWarning = true;
|
||||
startSynergy();
|
||||
m_SuppressEmptyServerWarning = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -406,7 +414,7 @@ void MainWindow::appendLogInfo(const QString& text)
|
||||
}
|
||||
|
||||
void MainWindow::appendLogDebug(const QString& text) {
|
||||
if (appConfig().logLevel() >= 4) {
|
||||
if (appConfig().logLevel() >= debugLogLevel) {
|
||||
appendLogRaw(getTimeStamp() + " DEBUG: " + text);
|
||||
}
|
||||
}
|
||||
@@ -420,6 +428,13 @@ void MainWindow::appendLogRaw(const QString& text)
|
||||
{
|
||||
foreach(QString line, text.split(QRegExp("\r|\n|\r\n"))) {
|
||||
if (!line.isEmpty()) {
|
||||
|
||||
// HACK: macOS 10.13.4+ spamming error lines in logs making them
|
||||
// impossible to read and debug; giving users a red herring.
|
||||
if (line.contains("calling TIS/TSM in non-main thread environment")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
m_pLogOutput->append(line);
|
||||
updateFromLogLine(line);
|
||||
}
|
||||
@@ -428,18 +443,21 @@ void MainWindow::appendLogRaw(const QString& text)
|
||||
|
||||
void MainWindow::updateFromLogLine(const QString &line)
|
||||
{
|
||||
// TODO: this code makes Andrew cry
|
||||
// TODO: This shouldn't be updating from log needs a better way of doing this
|
||||
checkConnected(line);
|
||||
checkFingerprint(line);
|
||||
checkSecureSocket(line);
|
||||
|
||||
#ifndef SYNERGY_ENTERPRISE
|
||||
checkLicense(line);
|
||||
#endif
|
||||
}
|
||||
|
||||
void MainWindow::checkConnected(const QString& line)
|
||||
{
|
||||
// TODO: implement ipc connection state messages to replace this hack.
|
||||
if (line.contains("started server") ||
|
||||
line.contains("connected to server") ||
|
||||
line.contains("watchdog status: ok"))
|
||||
if (line.contains("connected to server") ||
|
||||
line.contains("accepted client connection"))
|
||||
{
|
||||
setSynergyState(synergyConnected);
|
||||
|
||||
@@ -454,8 +472,21 @@ void MainWindow::checkConnected(const QString& line)
|
||||
appConfig().saveSettings();
|
||||
}
|
||||
}
|
||||
else if (line.contains("started server"))
|
||||
{
|
||||
setSynergyState(synergyListening);
|
||||
}
|
||||
else if (line.contains("disconnected from server") || line.contains("process exited"))
|
||||
{
|
||||
setSynergyState(synergyDisconnected);
|
||||
}
|
||||
else if (line.contains("connecting to"))
|
||||
{
|
||||
setSynergyState(synergyConnecting);
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef SYNERGY_ENTERPRISE
|
||||
void MainWindow::checkLicense(const QString &line)
|
||||
{
|
||||
if (line.contains("trial has expired")) {
|
||||
@@ -463,6 +494,7 @@ void MainWindow::checkLicense(const QString &line)
|
||||
raiseActivationDialog();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void MainWindow::checkFingerprint(const QString& line)
|
||||
{
|
||||
@@ -485,11 +517,10 @@ void MainWindow::checkFingerprint(const QString& line)
|
||||
QMessageBox::StandardButton fingerprintReply =
|
||||
QMessageBox::information(
|
||||
this, tr("Security question"),
|
||||
tr("Do you trust this fingerprint?\n\n"
|
||||
tr("You are connecting to a server. Here is it's fingerprint:\n\n"
|
||||
"%1\n\n"
|
||||
"This is a server fingerprint. You should compare this "
|
||||
"fingerprint to the one on your server's screen. If the "
|
||||
"two don't match exactly, then it's probably not the server "
|
||||
"Compare this fingerprint to the one on your server's screen."
|
||||
"If the two don't match exactly, then it's probably not the server "
|
||||
"you're expecting (it could be a malicious user).\n\n"
|
||||
"To automatically trust this fingerprint for future "
|
||||
"connections, click Yes. To reject this fingerprint and "
|
||||
@@ -507,6 +538,15 @@ void MainWindow::checkFingerprint(const QString& line)
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::checkSecureSocket(const QString& line)
|
||||
{
|
||||
// obviously not very secure, since this can be tricked by injecting something
|
||||
// into the log. however, since we don't have IPC between core and GUI... patches welcome.
|
||||
if (line.contains(tlsCheckString)) {
|
||||
secureSocket(true);
|
||||
}
|
||||
}
|
||||
|
||||
bool MainWindow::autoHide()
|
||||
{
|
||||
if ((appConfig().processMode() == Desktop) &&
|
||||
@@ -532,8 +572,9 @@ void MainWindow::restartSynergy()
|
||||
|
||||
void MainWindow::proofreadInfo()
|
||||
{
|
||||
#ifndef SYNERGY_ENTERPRISE
|
||||
setEdition(m_AppConfig->edition()); // Why is this here?
|
||||
|
||||
#endif
|
||||
int oldState = m_SynergyState;
|
||||
m_SynergyState = synergyDisconnected;
|
||||
setSynergyState((qSynergyState)oldState);
|
||||
@@ -552,6 +593,7 @@ void MainWindow::clearLog()
|
||||
|
||||
void MainWindow::startSynergy()
|
||||
{
|
||||
#ifndef SYNERGY_ENTERPRISE
|
||||
SerialKey serialKey = m_LicenseManager->serialKey();
|
||||
time_t currentTime = ::time(0);
|
||||
if (serialKey.isExpired(currentTime)) {
|
||||
@@ -559,7 +601,7 @@ void MainWindow::startSynergy()
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
bool desktopMode = appConfig().processMode() == Desktop;
|
||||
bool serviceMode = appConfig().processMode() == Service;
|
||||
|
||||
@@ -671,6 +713,16 @@ void MainWindow::startSynergy()
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::retryStart()
|
||||
{
|
||||
//This function is only called after a failed start
|
||||
//Only start synergy if the current state is pending retry
|
||||
if (m_SynergyState == synergyPendingRetry)
|
||||
{
|
||||
startSynergy();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MainWindow::sslToggled (bool enabled)
|
||||
{
|
||||
@@ -704,27 +756,47 @@ bool MainWindow::clientArgs(QStringList& args, QString& app)
|
||||
args << "--log" << appConfig().logFilenameCmd();
|
||||
}
|
||||
|
||||
#ifndef SYNERGY_ENTERPRISE
|
||||
// check auto config first, if it is disabled or no server detected,
|
||||
// use line edit host name if it is not empty
|
||||
if (m_pCheckBoxAutoConfig->isChecked()) {
|
||||
if (appConfig().autoConfig()) {
|
||||
if (m_pComboServerList->count() != 0) {
|
||||
QString serverIp = m_pComboServerList->currentText();
|
||||
args << serverIp + ":" + QString::number(appConfig().port());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_pLineEditHostname->text().isEmpty()) {
|
||||
show();
|
||||
if (!m_SuppressEmptyServerWarning) {
|
||||
QMessageBox::warning(this, tr("Hostname is empty"),
|
||||
tr("Please fill in a hostname for the synergy client to connect to."));
|
||||
else {
|
||||
show();
|
||||
QMessageBox::warning(
|
||||
this, tr("No server selected"),
|
||||
tr("No auto config server was selected, try manual mode instead."));
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (m_pLineEditHostname->text().isEmpty())
|
||||
{
|
||||
#ifndef SYNERGY_ENTERPRISE
|
||||
//check if autoconfig mode is enabled
|
||||
if (!appConfig().autoConfig())
|
||||
{
|
||||
#endif
|
||||
show();
|
||||
QMessageBox::warning(
|
||||
this, tr("Hostname is empty"),
|
||||
tr("Please fill in a hostname for the synergy client to connect to."));
|
||||
return false;
|
||||
|
||||
#ifndef SYNERGY_ENTERPRISE
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
args << m_pLineEditHostname->text() + ":" + QString::number(appConfig().port());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -804,9 +876,11 @@ bool MainWindow::serverArgs(QStringList& args, QString& app)
|
||||
#endif
|
||||
args << "-c" << configFilename << "--address" << address();
|
||||
|
||||
#ifndef SYNERGY_ENTERPRISE
|
||||
if (!appConfig().serialKey().isEmpty()) {
|
||||
args << "--serial-key" << appConfig().serialKey();
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -872,7 +946,9 @@ void MainWindow::synergyFinished(int exitCode, QProcess::ExitStatus)
|
||||
}
|
||||
|
||||
if (m_ExpectedRunningState == kStarted) {
|
||||
QTimer::singleShot(1000, this, SLOT(startSynergy()));
|
||||
|
||||
setSynergyState(synergyPendingRetry);
|
||||
QTimer::singleShot(1000, this, SLOT(retryStart()));
|
||||
appendLogInfo(QString("detected process not running, auto restarting"));
|
||||
}
|
||||
else {
|
||||
@@ -882,10 +958,17 @@ void MainWindow::synergyFinished(int exitCode, QProcess::ExitStatus)
|
||||
|
||||
void MainWindow::setSynergyState(qSynergyState state)
|
||||
{
|
||||
// always assume connection is not secure when connection changes
|
||||
// to anything except connected. the only way the padlock shows is
|
||||
// when the correct TLS version string is detected.
|
||||
if (state != synergyConnected) {
|
||||
secureSocket(false);
|
||||
}
|
||||
|
||||
if (synergyState() == state)
|
||||
return;
|
||||
|
||||
if (state == synergyConnected || state == synergyConnecting)
|
||||
if ((state == synergyConnected) || (state == synergyConnecting) || (state == synergyListening) || (state == synergyPendingRetry))
|
||||
{
|
||||
disconnect (m_pButtonToggleStart, SIGNAL(clicked()), m_pActionStartSynergy, SLOT(trigger()));
|
||||
connect (m_pButtonToggleStart, SIGNAL(clicked()), m_pActionStopSynergy, SLOT(trigger()));
|
||||
@@ -900,37 +983,40 @@ void MainWindow::setSynergyState(qSynergyState state)
|
||||
m_pButtonApply->setEnabled(false);
|
||||
}
|
||||
|
||||
bool connected = false;
|
||||
if (state == synergyConnected || state == synergyTransfering) {
|
||||
connected = true;
|
||||
bool running = false;
|
||||
if (state == synergyConnected || state == synergyListening) {
|
||||
running = true;
|
||||
}
|
||||
|
||||
m_pActionStartSynergy->setEnabled(!connected);
|
||||
m_pActionStopSynergy->setEnabled(connected);
|
||||
m_pActionStartSynergy->setEnabled(!running);
|
||||
m_pActionStopSynergy->setEnabled(running);
|
||||
|
||||
switch (state)
|
||||
{
|
||||
case synergyConnected: {
|
||||
if (m_AppConfig->getCryptoEnabled()) {
|
||||
m_pLabelPadlock->show();
|
||||
case synergyListening: {
|
||||
if (synergyType() == synergyServer) {
|
||||
setStatus(tr("Synergy is waiting for clients").arg(tlsVersion));
|
||||
}
|
||||
else {
|
||||
m_pLabelPadlock->hide();
|
||||
}
|
||||
|
||||
setStatus(tr("Synergy is running."));
|
||||
|
||||
break;
|
||||
}
|
||||
case synergyConnected: {
|
||||
if (m_SecureSocket) {
|
||||
setStatus(tr("Synergy is connected (with %1)").arg(tlsVersion));
|
||||
}
|
||||
else {
|
||||
setStatus(tr("Synergy is running (without %1)").arg(tlsVersion));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case synergyConnecting:
|
||||
m_pLabelPadlock->hide();
|
||||
setStatus(tr("Synergy is starting."));
|
||||
setStatus(tr("Synergy is starting..."));
|
||||
break;
|
||||
case synergyPendingRetry:
|
||||
setStatus(tr("There was an error, retrying..."));
|
||||
break;
|
||||
case synergyDisconnected:
|
||||
m_pLabelPadlock->hide();
|
||||
setStatus(tr("Synergy is not running."));
|
||||
break;
|
||||
case synergyTransfering:
|
||||
setStatus(tr("Synergy is not running"));
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1024,39 +1110,23 @@ void MainWindow::changeEvent(QEvent* event)
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::updateZeroconfService()
|
||||
void MainWindow::addZeroconfServer(const QString name)
|
||||
{
|
||||
QMutexLocker locker(&m_UpdateZeroconfMutex);
|
||||
|
||||
if (isBonjourRunning()) {
|
||||
if (!m_AppConfig->wizardShouldRun()) {
|
||||
if (m_pZeroconfService) {
|
||||
delete m_pZeroconfService;
|
||||
m_pZeroconfService = NULL;
|
||||
}
|
||||
|
||||
if (m_AppConfig->autoConfig() || synergyType() == synergyServer) {
|
||||
m_pZeroconfService = new ZeroconfService(this);
|
||||
}
|
||||
}
|
||||
// don't add yourself to the server list.
|
||||
if (getIPAddresses().contains(name)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::serverDetected(const QString name)
|
||||
{
|
||||
if (m_pComboServerList->findText(name) == -1) {
|
||||
// Note: the first added item triggers startSynergy
|
||||
m_pComboServerList->addItem(name);
|
||||
}
|
||||
|
||||
if (m_pComboServerList->count() > 1) {
|
||||
m_pComboServerList->show();
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::setEdition(Edition edition)
|
||||
{
|
||||
#ifndef SYNERGY_ENTERPRISE
|
||||
setWindowTitle(m_LicenseManager->getEditionName (edition));
|
||||
#endif
|
||||
if (m_AppConfig->getCryptoEnabled()) {
|
||||
m_pSslCertificate = new SslCertificate(this);
|
||||
m_pSslCertificate->generateCertificate();
|
||||
@@ -1065,6 +1135,7 @@ void MainWindow::setEdition(Edition edition)
|
||||
saveSettings();
|
||||
}
|
||||
|
||||
#ifndef SYNERGY_ENTERPRISE
|
||||
void MainWindow::beginTrial(bool isExpiring)
|
||||
{
|
||||
//Hack
|
||||
@@ -1115,6 +1186,7 @@ void MainWindow::endTrial(bool isExpired)
|
||||
}
|
||||
setWindowTitle (m_LicenseManager->activeEditionName());
|
||||
}
|
||||
#endif
|
||||
|
||||
void MainWindow::updateLocalFingerprint()
|
||||
{
|
||||
@@ -1129,26 +1201,26 @@ void MainWindow::updateLocalFingerprint()
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef SYNERGY_ENTERPRISE
|
||||
LicenseManager&
|
||||
MainWindow::licenseManager() const
|
||||
{
|
||||
return *m_LicenseManager;
|
||||
}
|
||||
#endif
|
||||
|
||||
void MainWindow::on_m_pGroupClient_toggled(bool on)
|
||||
{
|
||||
m_pGroupServer->setChecked(!on);
|
||||
if (on) {
|
||||
updateZeroconfService();
|
||||
}
|
||||
|
||||
// only call in either client or server toggle, but not both
|
||||
// since the toggle functions call eachother indirectly.
|
||||
updateZeroconfService();
|
||||
}
|
||||
|
||||
void MainWindow::on_m_pGroupServer_toggled(bool on)
|
||||
{
|
||||
m_pGroupClient->setChecked(!on);
|
||||
if (on) {
|
||||
updateZeroconfService();
|
||||
}
|
||||
}
|
||||
|
||||
bool MainWindow::on_m_pButtonBrowseConfigFile_clicked()
|
||||
@@ -1183,9 +1255,55 @@ void MainWindow::on_m_pActionAbout_triggered()
|
||||
dlg.exec();
|
||||
}
|
||||
|
||||
void MainWindow::updateZeroconfService()
|
||||
{
|
||||
#ifndef SYNERGY_ENTERPRISE
|
||||
|
||||
// reset the server list in case one has gone away.
|
||||
// it'll be re-added after the zeroconf service restarts.
|
||||
m_pComboServerList->clear();
|
||||
|
||||
if (m_pZeroconf != nullptr) {
|
||||
if (appConfig().autoConfig()) {
|
||||
m_pZeroconf->startService();
|
||||
}
|
||||
else {
|
||||
m_pZeroconf->stopService();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void MainWindow::updateAutoConfigWidgets()
|
||||
{
|
||||
if (appConfig().autoConfig()) {
|
||||
m_pLabelAutoDetected->show();
|
||||
m_pComboServerList->show();
|
||||
|
||||
m_pLabelServerName->hide();
|
||||
m_pLineEditHostname->hide();
|
||||
|
||||
m_pWidgetAutoConfig->hide();
|
||||
}
|
||||
else {
|
||||
m_pLabelServerName->show();
|
||||
m_pLineEditHostname->show();
|
||||
|
||||
m_pLabelAutoDetected->hide();
|
||||
m_pComboServerList->hide();
|
||||
|
||||
#ifndef SYNERGY_ENTERPRISE
|
||||
m_pWidgetAutoConfig->show();
|
||||
#else
|
||||
m_pWidgetAutoConfig->hide();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::on_m_pActionSettings_triggered()
|
||||
{
|
||||
ProcessMode lastProcessMode = appConfig().processMode();
|
||||
bool lastAutoConfig = appConfig().autoConfig();
|
||||
|
||||
SettingsDialog dlg(this, appConfig());
|
||||
dlg.exec();
|
||||
@@ -1194,38 +1312,45 @@ void MainWindow::on_m_pActionSettings_triggered()
|
||||
{
|
||||
onModeChanged(true, true);
|
||||
}
|
||||
|
||||
if (lastAutoConfig != appConfig().autoConfig()) {
|
||||
updateAutoConfigWidgets();
|
||||
updateZeroconfService();
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::autoAddScreen(const QString name)
|
||||
{
|
||||
if (!m_ServerConfig.ignoreAutoConfigClient()) {
|
||||
if (m_ActivationDialogRunning) {
|
||||
// TODO: refactor this code
|
||||
// add this screen to the pending list and check this list until
|
||||
// users finish activation dialog
|
||||
m_PendingClientNames.append(name);
|
||||
return;
|
||||
}
|
||||
if (m_ServerConfig.ignoreAutoConfigClient()) {
|
||||
appendLogDebug(QString("ignoring zeroconf screen: %1").arg(name));
|
||||
return;
|
||||
}
|
||||
|
||||
int r = m_ServerConfig.autoAddScreen(name);
|
||||
if (r != kAutoAddScreenOk) {
|
||||
switch (r) {
|
||||
case kAutoAddScreenManualServer:
|
||||
showConfigureServer(
|
||||
tr("Please add the server (%1) to the grid.")
|
||||
.arg(appConfig().screenName()));
|
||||
break;
|
||||
#ifndef SYNERGY_ENTERPRISE
|
||||
if (m_ActivationDialogRunning) {
|
||||
// TODO: refactor this code
|
||||
// add this screen to the pending list and check this list until
|
||||
// users finish activation dialog
|
||||
m_PendingClientNames.append(name);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
case kAutoAddScreenManualClient:
|
||||
showConfigureServer(
|
||||
tr("Please drag the new client screen (%1) "
|
||||
"to the desired position on the grid.")
|
||||
.arg(name));
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
restartSynergy();
|
||||
int r = m_ServerConfig.autoAddScreen(name);
|
||||
if (r != kAutoAddScreenOk) {
|
||||
switch (r) {
|
||||
case kAutoAddScreenManualServer:
|
||||
showConfigureServer(
|
||||
tr("Please add the server (%1) to the grid.")
|
||||
.arg(appConfig().screenName()));
|
||||
break;
|
||||
|
||||
case kAutoAddScreenManualClient:
|
||||
showConfigureServer(
|
||||
tr("Please drag the new client screen (%1) "
|
||||
"to the desired position on the grid.")
|
||||
.arg(name));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1244,7 +1369,9 @@ void MainWindow::on_m_pButtonConfigureServer_clicked()
|
||||
|
||||
void MainWindow::on_m_pActivate_triggered()
|
||||
{
|
||||
#ifndef SYNERGY_ENTERPRISE
|
||||
raiseActivationDialog();
|
||||
#endif
|
||||
}
|
||||
|
||||
void MainWindow::on_m_pButtonApply_clicked()
|
||||
@@ -1252,210 +1379,7 @@ void MainWindow::on_m_pButtonApply_clicked()
|
||||
restartSynergy();
|
||||
}
|
||||
|
||||
#if defined(Q_OS_WIN)
|
||||
bool MainWindow::isServiceRunning(QString name)
|
||||
{
|
||||
SC_HANDLE hSCManager;
|
||||
hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
|
||||
if (hSCManager == NULL) {
|
||||
appendLogError("failed to open a service controller manager, error: " +
|
||||
GetLastError());
|
||||
return false;
|
||||
}
|
||||
|
||||
auto array = name.toLocal8Bit();
|
||||
SC_HANDLE hService = OpenService(hSCManager, array.data(), SERVICE_QUERY_STATUS);
|
||||
|
||||
if (hService == NULL) {
|
||||
appendLogDebug("failed to open service: " + name);
|
||||
return false;
|
||||
}
|
||||
|
||||
SERVICE_STATUS status;
|
||||
if (QueryServiceStatus(hService, &status)) {
|
||||
if (status.dwCurrentState == SERVICE_RUNNING) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
#else
|
||||
bool MainWindow::isServiceRunning()
|
||||
{
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
bool MainWindow::isBonjourRunning()
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
#if defined(Q_OS_WIN)
|
||||
result = isServiceRunning("Bonjour Service");
|
||||
#else
|
||||
result = true;
|
||||
#endif
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void MainWindow::downloadBonjour()
|
||||
{
|
||||
#if defined(Q_OS_WIN)
|
||||
QUrl url;
|
||||
int arch = getProcessorArch();
|
||||
if (arch == kProcessorArchWin32) {
|
||||
url.setUrl(bonjourBaseUrl + bonjourFilename32);
|
||||
appendLogInfo("downloading 32-bit Bonjour");
|
||||
}
|
||||
else if (arch == kProcessorArchWin64) {
|
||||
url.setUrl(bonjourBaseUrl + bonjourFilename64);
|
||||
appendLogInfo("downloading 64-bit Bonjour");
|
||||
}
|
||||
else {
|
||||
QMessageBox::critical(
|
||||
this, tr("Synergy"),
|
||||
tr("Failed to detect system architecture."));
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_pDataDownloader == NULL) {
|
||||
m_pDataDownloader = new DataDownloader(this);
|
||||
connect(m_pDataDownloader, SIGNAL(isComplete()), SLOT(installBonjour()));
|
||||
}
|
||||
|
||||
m_pDataDownloader->download(url);
|
||||
|
||||
if (m_DownloadMessageBox == NULL) {
|
||||
m_DownloadMessageBox = new QMessageBox(this);
|
||||
m_DownloadMessageBox->setWindowTitle("Synergy");
|
||||
m_DownloadMessageBox->setIcon(QMessageBox::Information);
|
||||
m_DownloadMessageBox->setText("Installing Bonjour, please wait...");
|
||||
m_DownloadMessageBox->setStandardButtons(0);
|
||||
m_pCancelButton = m_DownloadMessageBox->addButton(
|
||||
tr("Cancel"), QMessageBox::RejectRole);
|
||||
}
|
||||
|
||||
m_DownloadMessageBox->exec();
|
||||
|
||||
if (m_DownloadMessageBox->clickedButton() == m_pCancelButton) {
|
||||
m_pDataDownloader->cancel();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void MainWindow::installBonjour()
|
||||
{
|
||||
#if defined(Q_OS_WIN)
|
||||
#if QT_VERSION >= 0x050000
|
||||
QString tempLocation = QStandardPaths::writableLocation(QStandardPaths::TempLocation);
|
||||
#else
|
||||
QString tempLocation = QDesktopServices::storageLocation(
|
||||
QDesktopServices::TempLocation);
|
||||
#endif
|
||||
QString filename = tempLocation;
|
||||
filename.append("\\").append(bonjourTargetFilename);
|
||||
QFile file(filename);
|
||||
if (!file.open(QIODevice::WriteOnly)) {
|
||||
m_DownloadMessageBox->hide();
|
||||
|
||||
QMessageBox::warning(
|
||||
this, "Synergy",
|
||||
tr("Failed to download Bonjour installer to location: %1")
|
||||
.arg(tempLocation));
|
||||
return;
|
||||
}
|
||||
|
||||
file.write(m_pDataDownloader->data());
|
||||
file.close();
|
||||
|
||||
QStringList arguments;
|
||||
arguments.append("/i");
|
||||
QString winFilename = QDir::toNativeSeparators(filename);
|
||||
arguments.append(winFilename);
|
||||
arguments.append("/passive");
|
||||
if (m_BonjourInstall == NULL) {
|
||||
m_BonjourInstall = new CommandProcess("msiexec", arguments);
|
||||
}
|
||||
|
||||
QThread* thread = new QThread;
|
||||
connect(m_BonjourInstall, SIGNAL(finished()), this,
|
||||
SLOT(bonjourInstallFinished()));
|
||||
connect(m_BonjourInstall, SIGNAL(finished()), thread, SLOT(quit()));
|
||||
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
|
||||
|
||||
m_BonjourInstall->moveToThread(thread);
|
||||
thread->start();
|
||||
|
||||
QMetaObject::invokeMethod(m_BonjourInstall, "run", Qt::QueuedConnection);
|
||||
|
||||
m_DownloadMessageBox->hide();
|
||||
#endif
|
||||
}
|
||||
|
||||
void MainWindow::promptAutoConfig()
|
||||
{
|
||||
if (!isBonjourRunning()) {
|
||||
int r = QMessageBox::question(
|
||||
this, tr("Synergy"),
|
||||
tr("Do you want to enable auto config and install Bonjour?\n\n"
|
||||
"This feature helps you establish the connection."),
|
||||
QMessageBox::Yes | QMessageBox::No);
|
||||
|
||||
if (r == QMessageBox::Yes) {
|
||||
m_AppConfig->setAutoConfig(true);
|
||||
downloadBonjour();
|
||||
}
|
||||
else {
|
||||
m_AppConfig->setAutoConfig(false);
|
||||
m_pCheckBoxAutoConfig->setChecked(false);
|
||||
}
|
||||
}
|
||||
|
||||
m_AppConfig->setAutoConfigPrompted(true);
|
||||
}
|
||||
|
||||
void MainWindow::on_m_pComboServerList_currentIndexChanged(QString )
|
||||
{
|
||||
if (m_pComboServerList->count() != 0) {
|
||||
restartSynergy();
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::on_m_pCheckBoxAutoConfig_toggled(bool checked)
|
||||
{
|
||||
if (!isBonjourRunning() && checked) {
|
||||
if (!m_SuppressAutoConfigWarning) {
|
||||
int r = QMessageBox::information(
|
||||
this, tr("Synergy"),
|
||||
tr("Auto config feature requires Bonjour.\n\n"
|
||||
"Do you want to install Bonjour?"),
|
||||
QMessageBox::Yes | QMessageBox::No);
|
||||
|
||||
if (r == QMessageBox::Yes) {
|
||||
downloadBonjour();
|
||||
}
|
||||
}
|
||||
|
||||
m_pCheckBoxAutoConfig->setChecked(false);
|
||||
return;
|
||||
}
|
||||
|
||||
m_pLineEditHostname->setDisabled(checked);
|
||||
appConfig().setAutoConfig(checked);
|
||||
updateZeroconfService();
|
||||
|
||||
if (!checked) {
|
||||
m_pComboServerList->clear();
|
||||
m_pComboServerList->hide();
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::bonjourInstallFinished()
|
||||
{
|
||||
appendLogInfo("Bonjour install finished");
|
||||
|
||||
m_pCheckBoxAutoConfig->setChecked(true);
|
||||
}
|
||||
|
||||
#ifndef SYNERGY_ENTERPRISE
|
||||
int MainWindow::raiseActivationDialog()
|
||||
{
|
||||
if (m_ActivationDialogRunning) {
|
||||
@@ -1474,20 +1398,20 @@ int MainWindow::raiseActivationDialog()
|
||||
|
||||
m_PendingClientNames.clear();
|
||||
}
|
||||
if (result == QDialog::Accepted) {
|
||||
restartSynergy();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
void MainWindow::on_windowShown()
|
||||
{
|
||||
#ifndef SYNERGY_ENTERPRISE
|
||||
time_t currentTime = ::time(0);
|
||||
if (!m_AppConfig->activationHasRun()
|
||||
&& ((m_AppConfig->edition() == kUnregistered) ||
|
||||
(m_LicenseManager->serialKey().isExpired(currentTime)))) {
|
||||
raiseActivationDialog();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
QString MainWindow::getProfileRootForArg()
|
||||
@@ -1504,3 +1428,25 @@ QString MainWindow::getProfileRootForArg()
|
||||
|
||||
return QString("\"%1\"").arg(dir);
|
||||
}
|
||||
|
||||
void MainWindow::secureSocket(bool secureSocket)
|
||||
{
|
||||
m_SecureSocket = secureSocket;
|
||||
if (secureSocket) {
|
||||
m_pLabelPadlock->show();
|
||||
}
|
||||
else {
|
||||
m_pLabelPadlock->hide();
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::on_m_pLabelAutoConfig_linkActivated(const QString &)
|
||||
{
|
||||
m_pActionSettings->trigger();
|
||||
}
|
||||
|
||||
void MainWindow::on_m_pComboServerList_currentIndexChanged(const QString &server)
|
||||
{
|
||||
appConfig().setAutoConfigServer(server);
|
||||
appConfig().saveSettings();
|
||||
}
|
||||
|
||||
@@ -16,9 +16,7 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#if !defined(MAINWINDOW__H)
|
||||
|
||||
#define MAINWINDOW__H
|
||||
#pragma once
|
||||
|
||||
#include <QMainWindow>
|
||||
#include <QSystemTrayIcon>
|
||||
@@ -54,11 +52,11 @@ class QAbstractButton;
|
||||
class LogDialog;
|
||||
class QSynergyApplication;
|
||||
class SetupWizard;
|
||||
class ZeroconfService;
|
||||
class DataDownloader;
|
||||
class CommandProcess;
|
||||
class SslCertificate;
|
||||
class LicenseManager;
|
||||
class Zeroconf;
|
||||
|
||||
class MainWindow : public QMainWindow, public Ui::MainWindowBase
|
||||
{
|
||||
@@ -75,7 +73,8 @@ class MainWindow : public QMainWindow, public Ui::MainWindowBase
|
||||
synergyDisconnected,
|
||||
synergyConnecting,
|
||||
synergyConnected,
|
||||
synergyTransfering
|
||||
synergyListening,
|
||||
synergyPendingRetry
|
||||
};
|
||||
|
||||
enum qSynergyType
|
||||
@@ -95,8 +94,12 @@ class MainWindow : public QMainWindow, public Ui::MainWindowBase
|
||||
};
|
||||
|
||||
public:
|
||||
#ifdef SYNERGY_ENTERPRISE
|
||||
MainWindow(QSettings& settings, AppConfig& appConfig);
|
||||
#else
|
||||
MainWindow(QSettings& settings, AppConfig& appConfig,
|
||||
LicenseManager& licenseManager);
|
||||
#endif
|
||||
~MainWindow();
|
||||
|
||||
public:
|
||||
@@ -115,22 +118,28 @@ class MainWindow : public QMainWindow, public Ui::MainWindowBase
|
||||
void showConfigureServer(const QString& message);
|
||||
void showConfigureServer() { showConfigureServer(""); }
|
||||
void autoAddScreen(const QString name);
|
||||
void updateZeroconfService();
|
||||
void serverDetected(const QString name);
|
||||
void addZeroconfServer(const QString name);
|
||||
void updateLocalFingerprint();
|
||||
Zeroconf& zeroconf() { return *m_pZeroconf; }
|
||||
#ifndef SYNERGY_ENTERPRISE
|
||||
LicenseManager& licenseManager() const;
|
||||
|
||||
int raiseActivationDialog();
|
||||
#endif
|
||||
|
||||
void updateZeroconfService();
|
||||
|
||||
public slots:
|
||||
void setEdition(Edition edition);
|
||||
#ifndef SYNERGY_ENTERPRISE
|
||||
void beginTrial(bool isExpiring);
|
||||
void endTrial(bool isExpired);
|
||||
#endif
|
||||
void appendLogRaw(const QString& text);
|
||||
void appendLogInfo(const QString& text);
|
||||
void appendLogDebug(const QString& text);
|
||||
void appendLogError(const QString& text);
|
||||
void startSynergy();
|
||||
void retryStart(); // If the connection failed this will retry a startSynergy
|
||||
|
||||
protected slots:
|
||||
void sslToggled(bool enabled);
|
||||
@@ -148,7 +157,7 @@ public slots:
|
||||
void logOutput();
|
||||
void logError();
|
||||
void updateFound(const QString& version);
|
||||
void bonjourInstallFinished();
|
||||
void saveSettings();
|
||||
|
||||
protected:
|
||||
QSettings& settings() { return m_Settings; }
|
||||
@@ -160,7 +169,6 @@ public slots:
|
||||
void createStatusBar();
|
||||
void createTrayIcon();
|
||||
void loadSettings();
|
||||
void saveSettings();
|
||||
void setIcon(qSynergyState state);
|
||||
void setSynergyState(qSynergyState state);
|
||||
bool checkForApp(int which, QString& app);
|
||||
@@ -180,24 +188,31 @@ public slots:
|
||||
#else
|
||||
bool isServiceRunning();
|
||||
#endif
|
||||
bool isBonjourRunning();
|
||||
void downloadBonjour();
|
||||
void promptAutoConfig();
|
||||
|
||||
QString getProfileRootForArg();
|
||||
void checkConnected(const QString& line);
|
||||
void checkLicense(const QString& line);
|
||||
void checkFingerprint(const QString& line);
|
||||
void checkSecureSocket(const QString& line);
|
||||
#ifndef SYNERGY_ENTERPRISE
|
||||
void checkLicense(const QString& line);
|
||||
#endif
|
||||
bool autoHide();
|
||||
QString getTimeStamp();
|
||||
void restartSynergy();
|
||||
void proofreadInfo();
|
||||
|
||||
void showEvent (QShowEvent*);
|
||||
void secureSocket(bool secureSocket);
|
||||
|
||||
private:
|
||||
#ifndef SYNERGY_ENTERPRISE
|
||||
LicenseManager* m_LicenseManager;
|
||||
bool m_ActivationDialogRunning;
|
||||
QStringList m_PendingClientNames;
|
||||
#endif
|
||||
Zeroconf* m_pZeroconf;
|
||||
QSettings& m_Settings;
|
||||
AppConfig* m_AppConfig;
|
||||
LicenseManager* m_LicenseManager;
|
||||
QProcess* m_pSynergy;
|
||||
int m_SynergyState;
|
||||
ServerConfig m_ServerConfig;
|
||||
@@ -212,30 +227,22 @@ public slots:
|
||||
QMenu* m_pMenuEdit;
|
||||
QMenu* m_pMenuWindow;
|
||||
QMenu* m_pMenuHelp;
|
||||
ZeroconfService* m_pZeroconfService;
|
||||
DataDownloader* m_pDataDownloader;
|
||||
QMessageBox* m_DownloadMessageBox;
|
||||
QAbstractButton* m_pCancelButton;
|
||||
QMutex m_UpdateZeroconfMutex;
|
||||
bool m_SuppressAutoConfigWarning;
|
||||
CommandProcess* m_BonjourInstall;
|
||||
bool m_SuppressEmptyServerWarning;
|
||||
qRuningState m_ExpectedRunningState;
|
||||
QMutex m_StopDesktopMutex;
|
||||
SslCertificate* m_pSslCertificate;
|
||||
bool m_ActivationDialogRunning;
|
||||
QStringList m_PendingClientNames;
|
||||
bool m_SecureSocket;
|
||||
|
||||
void updateAutoConfigWidgets();
|
||||
|
||||
private slots:
|
||||
void on_m_pCheckBoxAutoConfig_toggled(bool checked);
|
||||
void on_m_pComboServerList_currentIndexChanged(QString );
|
||||
void on_m_pButtonApply_clicked();
|
||||
void installBonjour();
|
||||
void on_windowShown();
|
||||
|
||||
void on_m_pLabelAutoConfig_linkActivated(const QString &link);
|
||||
|
||||
void on_m_pComboServerList_currentIndexChanged(const QString &arg1);
|
||||
|
||||
signals:
|
||||
void windowShown();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
<string/>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap resource="Synergy.qrc">:/res/icons/16x16/warning.png</pixmap>
|
||||
<pixmap resource="../res/Synergy.qrc">:/res/icons/16x16/warning.png</pixmap>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -99,7 +99,7 @@
|
||||
<string/>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap resource="Synergy.qrc">:/res/icons/16x16/warning.png</pixmap>
|
||||
<pixmap resource="../res/Synergy.qrc">:/res/icons/16x16/warning.png</pixmap>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -129,6 +129,81 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QWidget" name="m_pWidgetAutoConfig" native="true">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>28</height>
|
||||
</size>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
||||
<property name="leftMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>8</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QLabel" name="m_pIconAutoConfig">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Minimum" vsizetype="Minimum">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>16</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>244</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap resource="../res/Synergy.qrc">:/res/icons/16x16/auto-config.png</pixmap>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="m_pLabelAutoConfig">
|
||||
<property name="text">
|
||||
<string><html><head/><body><p>Manual Config mode active, consider using Auto Config instead (<a href="#"><span style=" text-decoration: underline; color:#007af4;">Settings</span></a>)</p></body></html></string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::RichText</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="m_pSpacerAutoConfig">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>200</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="m_pGroupServer">
|
||||
<property name="sizePolicy">
|
||||
@@ -289,9 +364,9 @@
|
||||
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<widget class="QLabel" name="m_pLabelComputerName">
|
||||
<property name="text">
|
||||
<string>Screen name:</string>
|
||||
<string>Client name:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -305,7 +380,7 @@
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="m_pLabelServerName">
|
||||
<property name="text">
|
||||
<string>&Server IP:</string>
|
||||
<string>&Server:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>m_pLineEditHostname</cstring>
|
||||
@@ -313,16 +388,25 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QLineEdit" name="m_pLineEditHostname"/>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QCheckBox" name="m_pCheckBoxAutoConfig">
|
||||
<property name="text">
|
||||
<string>Auto config</string>
|
||||
<widget class="QLineEdit" name="m_pLineEditHostname">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>200</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Hostname or IP address of the server computer.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<item row="4" column="1">
|
||||
<widget class="QComboBox" name="m_pComboServerList">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Preferred">
|
||||
@@ -332,12 +416,19 @@
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>120</width>
|
||||
<width>200</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QLabel" name="m_pLabelAutoDetected">
|
||||
<property name="text">
|
||||
<string>Server:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -391,7 +482,7 @@
|
||||
<string/>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap resource="Synergy.qrc">:/res/icons/16x16/padlock.png</pixmap>
|
||||
<pixmap resource="../res/Synergy.qrc">:/res/icons/16x16/padlock.png</pixmap>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -542,7 +633,7 @@
|
||||
</action>
|
||||
</widget>
|
||||
<resources>
|
||||
<include location="Synergy.qrc"/>
|
||||
<include location="../res/Synergy.qrc"/>
|
||||
</resources>
|
||||
<connections>
|
||||
<connection>
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
#include <QtCore>
|
||||
#include <QtGui>
|
||||
#include <QHeaderView>
|
||||
|
||||
ScreenSetupView::ScreenSetupView(QWidget* parent) :
|
||||
QTableView(parent)
|
||||
|
||||
@@ -51,7 +51,9 @@ ServerConfig::ServerConfig(QSettings* settings, int numColumns, int numRows ,
|
||||
m_ServerName(serverName),
|
||||
m_IgnoreAutoConfigClient(false),
|
||||
m_EnableDragAndDrop(false),
|
||||
m_DisableLockToScreen(false),
|
||||
m_ClipboardSharing(true),
|
||||
m_ClipboardSharingSize(defaultClipboardSharingSize()),
|
||||
m_pMainWindow(mainWindow)
|
||||
{
|
||||
Q_ASSERT(m_pSettings);
|
||||
@@ -116,7 +118,10 @@ void ServerConfig::saveSettings()
|
||||
settings().setValue("switchDoubleTap", switchDoubleTap());
|
||||
settings().setValue("switchCornerSize", switchCornerSize());
|
||||
settings().setValue("ignoreAutoConfigClient", ignoreAutoConfigClient());
|
||||
settings().setValue("disableLockToScreen", disableLockToScreen());
|
||||
settings().setValue("enableDragAndDrop", enableDragAndDrop());
|
||||
settings().setValue("clipboardSharing", clipboardSharing());
|
||||
settings().setValue("clipboardSharingSize", QVariant::fromValue(clipboardSharingSize()));
|
||||
|
||||
writeSettings(settings(), switchCorners(), "switchCorner");
|
||||
|
||||
@@ -160,7 +165,11 @@ void ServerConfig::loadSettings()
|
||||
setSwitchDoubleTap(settings().value("switchDoubleTap", 250).toInt());
|
||||
setSwitchCornerSize(settings().value("switchCornerSize").toInt());
|
||||
setIgnoreAutoConfigClient(settings().value("ignoreAutoConfigClient").toBool());
|
||||
setDisableLockToScreen(settings().value("disableLockToScreen", false).toBool());
|
||||
setEnableDragAndDrop(settings().value("enableDragAndDrop", true).toBool());
|
||||
setClipboardSharing(settings().value("clipboardSharing", true).toBool());
|
||||
setClipboardSharingSize(settings().value("clipboardSharingSize",
|
||||
(int) ServerConfig::defaultClipboardSharingSize()).toULongLong());
|
||||
|
||||
readSettings(settings(), switchCorners(), "switchCorner", false, NumSwitchCorners);
|
||||
|
||||
@@ -247,7 +256,9 @@ QTextStream& operator<<(QTextStream& outStream, const ServerConfig& config)
|
||||
outStream << "\t" << "relativeMouseMoves = " << (config.relativeMouseMoves() ? "true" : "false") << endl;
|
||||
outStream << "\t" << "screenSaverSync = " << (config.screenSaverSync() ? "true" : "false") << endl;
|
||||
outStream << "\t" << "win32KeepForeground = " << (config.win32KeepForeground() ? "true" : "false") << endl;
|
||||
outStream << "\t" << "disableLockToScreen = " << (config.disableLockToScreen() ? "true" : "false") << endl;
|
||||
outStream << "\t" << "clipboardSharing = " << (config.clipboardSharing() ? "true" : "false") << endl;
|
||||
outStream << "\t" << "clipboardSharingSize = " << config.clipboardSharingSize() << endl;
|
||||
|
||||
if (config.hasSwitchDelay())
|
||||
outStream << "\t" << "switchDelay = " << config.switchDelay() << endl;
|
||||
@@ -292,7 +303,7 @@ int ServerConfig::autoAddScreen(const QString name)
|
||||
}
|
||||
}
|
||||
if (findScreenName(name, targetIndex)) {
|
||||
// already exists.
|
||||
m_pMainWindow->appendLogDebug(QString("ignoring screen already in config: %1").arg(name));
|
||||
return kAutoAddScreenIgnore;
|
||||
}
|
||||
|
||||
@@ -401,3 +412,21 @@ void::ServerConfig::addToFirstEmptyGrid(const QString &clientName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
size_t ServerConfig::defaultClipboardSharingSize() {
|
||||
return 3 * 1024; // 3 MiB
|
||||
}
|
||||
|
||||
size_t ServerConfig::setClipboardSharingSize(size_t size) {
|
||||
if (size) {
|
||||
size += 512; // Round up to the nearest megabyte
|
||||
size /= 1024;
|
||||
size *= 1024;
|
||||
setClipboardSharing(true);
|
||||
} else {
|
||||
setClipboardSharing(false);
|
||||
}
|
||||
using std::swap;
|
||||
swap (size, m_ClipboardSharingSize);
|
||||
return size;
|
||||
}
|
||||
|
||||
@@ -62,7 +62,10 @@ class ServerConfig : public BaseConfig
|
||||
const HotkeyList& hotkeys() const { return m_Hotkeys; }
|
||||
bool ignoreAutoConfigClient() const { return m_IgnoreAutoConfigClient; }
|
||||
bool enableDragAndDrop() const { return m_EnableDragAndDrop; }
|
||||
bool disableLockToScreen() const { return m_DisableLockToScreen; }
|
||||
bool clipboardSharing() const { return m_ClipboardSharing; }
|
||||
size_t clipboardSharingSize() const { return m_ClipboardSharingSize; }
|
||||
static size_t defaultClipboardSharingSize();
|
||||
|
||||
void saveSettings();
|
||||
void loadSettings();
|
||||
@@ -91,7 +94,9 @@ class ServerConfig : public BaseConfig
|
||||
void setSwitchCornerSize(int val) { m_SwitchCornerSize = val; }
|
||||
void setIgnoreAutoConfigClient(bool on) { m_IgnoreAutoConfigClient = on; }
|
||||
void setEnableDragAndDrop(bool on) { m_EnableDragAndDrop = on; }
|
||||
void setDisableLockToScreen(bool on) { m_DisableLockToScreen = on; }
|
||||
void setClipboardSharing(bool on) { m_ClipboardSharing = on; }
|
||||
size_t setClipboardSharingSize(size_t size);
|
||||
QList<bool>& switchCorners() { return m_SwitchCorners; }
|
||||
HotkeyList& hotkeys() { return m_Hotkeys; }
|
||||
|
||||
@@ -124,7 +129,9 @@ class ServerConfig : public BaseConfig
|
||||
QString m_ServerName;
|
||||
bool m_IgnoreAutoConfigClient;
|
||||
bool m_EnableDragAndDrop;
|
||||
bool m_DisableLockToScreen;
|
||||
bool m_ClipboardSharing;
|
||||
size_t m_ClipboardSharingSize;
|
||||
MainWindow* m_pMainWindow;
|
||||
};
|
||||
|
||||
|
||||
@@ -53,12 +53,16 @@ ServerConfigDialog::ServerConfigDialog(QWidget* parent, ServerConfig& config, co
|
||||
m_pCheckBoxCornerBottomLeft->setChecked(serverConfig().switchCorner(BaseConfig::BottomLeft));
|
||||
m_pCheckBoxCornerBottomRight->setChecked(serverConfig().switchCorner(BaseConfig::BottomRight));
|
||||
m_pSpinBoxSwitchCornerSize->setValue(serverConfig().switchCornerSize());
|
||||
m_pCheckBoxDisableLockToScreen->setChecked(serverConfig().disableLockToScreen());
|
||||
|
||||
m_pCheckBoxIgnoreAutoConfigClient->setChecked(serverConfig().ignoreAutoConfigClient());
|
||||
|
||||
m_pCheckBoxEnableDragAndDrop->setChecked(serverConfig().enableDragAndDrop());
|
||||
|
||||
m_pCheckBoxEnableClipboard->setChecked(serverConfig().clipboardSharing());
|
||||
int clipboardSharingSizeM = static_cast<int>(serverConfig().clipboardSharingSize() / 1024);
|
||||
m_pSpinBoxClipboardSizeLimit->setValue(clipboardSharingSizeM);
|
||||
m_pSpinBoxClipboardSizeLimit->setEnabled(serverConfig().clipboardSharing());
|
||||
|
||||
foreach(const Hotkey& hotkey, serverConfig().hotkeys())
|
||||
m_pListHotkeys->addItem(hotkey.text());
|
||||
@@ -102,7 +106,10 @@ void ServerConfigDialog::accept()
|
||||
serverConfig().setSwitchCornerSize(m_pSpinBoxSwitchCornerSize->value());
|
||||
serverConfig().setIgnoreAutoConfigClient(m_pCheckBoxIgnoreAutoConfigClient->isChecked());
|
||||
serverConfig().setEnableDragAndDrop(m_pCheckBoxEnableDragAndDrop->isChecked());
|
||||
serverConfig().setClipboardSharing(m_pCheckBoxEnableClipboard->isChecked());
|
||||
serverConfig().setDisableLockToScreen(m_pCheckBoxDisableLockToScreen->isChecked());
|
||||
serverConfig().setClipboardSharingSize(m_pSpinBoxClipboardSizeLimit->value() * 1024);
|
||||
serverConfig().setClipboardSharing(m_pCheckBoxEnableClipboard->isChecked()
|
||||
&& m_pSpinBoxClipboardSizeLimit->value());
|
||||
|
||||
// now that the dialog has been accepted, copy the new server config to the original one,
|
||||
// which is a reference to the one in MainWindow.
|
||||
@@ -212,6 +219,15 @@ void ServerConfigDialog::on_m_pButtonRemoveAction_clicked()
|
||||
delete m_pListActions->currentItem();
|
||||
}
|
||||
|
||||
void ServerConfigDialog::on_m_pCheckBoxEnableClipboard_stateChanged(int const state)
|
||||
{
|
||||
m_pSpinBoxClipboardSizeLimit->setEnabled (state == Qt::Checked);
|
||||
if ((state == Qt::Checked) && (!m_pSpinBoxClipboardSizeLimit->value())) {
|
||||
int size = static_cast<int>((serverConfig().defaultClipboardSharingSize() + 512) / 1024);
|
||||
m_pSpinBoxClipboardSizeLimit->setValue (size ? size : 1);
|
||||
}
|
||||
}
|
||||
|
||||
void ServerConfigDialog::on_m_pListActions_itemSelectionChanged()
|
||||
{
|
||||
m_pButtonEditAction->setEnabled(!m_pListActions->selectedItems().isEmpty());
|
||||
|
||||
@@ -50,6 +50,8 @@ class ServerConfigDialog : public QDialog, public Ui::ServerConfigDialogBase
|
||||
void on_m_pButtonEditAction_clicked();
|
||||
void on_m_pButtonRemoveAction_clicked();
|
||||
|
||||
void on_m_pCheckBoxEnableClipboard_stateChanged(int state);
|
||||
|
||||
protected:
|
||||
ServerConfig& serverConfig() { return m_ServerConfig; }
|
||||
void setOrigServerConfig(const ServerConfig& s) { m_OrigServerConfig = s; }
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
<string/>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap resource="Synergy.qrc">:/res/icons/64x64/user-trash.png</pixmap>
|
||||
<pixmap resource="../res/Synergy.qrc">:/res/icons/64x64/user-trash.png</pixmap>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -82,7 +82,7 @@
|
||||
<string/>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap resource="Synergy.qrc">:/res/icons/64x64/video-display.png</pixmap>
|
||||
<pixmap resource="../res/Synergy.qrc">:/res/icons/64x64/video-display.png</pixmap>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -408,6 +408,60 @@ Double click on a screen to edit its settings.</string>
|
||||
<string>&Options</string>
|
||||
</property>
|
||||
<layout class="QGridLayout">
|
||||
<item row="8" column="0">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QCheckBox" name="m_pCheckBoxEnableClipboard">
|
||||
<property name="text">
|
||||
<string>Enable clipboard sharing</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="m_pSpinBoxClipboardSizeLimit">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>50</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>3</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>MB</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QCheckBox" name="m_pCheckBoxEnableDragAndDrop">
|
||||
<property name="text">
|
||||
<string>Enable drag and drop file transfers</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QCheckBox" name="m_pCheckBoxWin32KeepForeground">
|
||||
<property name="enabled">
|
||||
@@ -428,13 +482,23 @@ Double click on a screen to edit its settings.</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="m_pCheckBoxScreenSaverSync">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
<item row="12" column="0">
|
||||
<spacer>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>16</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QCheckBox" name="m_pCheckBoxIgnoreAutoConfigClient">
|
||||
<property name="text">
|
||||
<string>S&ynchronize screen savers</string>
|
||||
<string>Ignore auto config clients</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -491,40 +555,20 @@ Double click on a screen to edit its settings.</string>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<spacer>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
<item row="2" column="0">
|
||||
<widget class="QCheckBox" name="m_pCheckBoxScreenSaverSync">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>16</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QCheckBox" name="m_pCheckBoxEnableDragAndDrop">
|
||||
<property name="text">
|
||||
<string>Enable drag and drop file transfers</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QCheckBox" name="m_pCheckBoxIgnoreAutoConfigClient">
|
||||
<property name="text">
|
||||
<string>Ignore auto config clients</string>
|
||||
<string>S&ynchronize screen savers</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QCheckBox" name="m_pCheckBoxEnableClipboard">
|
||||
<widget class="QCheckBox" name="m_pCheckBoxDisableLockToScreen">
|
||||
<property name="text">
|
||||
<string>Enable clipboard sharing</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
<string>Disable lock to screen</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -662,7 +706,7 @@ Double click on a screen to edit its settings.</string>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources>
|
||||
<include location="Synergy.qrc"/>
|
||||
<include location="../res/Synergy.qrc"/>
|
||||
</resources>
|
||||
<connections>
|
||||
<connection>
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2012-2016 Symless Ltd.
|
||||
* Copyright (C) 2008 Volker Lanz (vl@fidra.de)
|
||||
*
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* found in the file LICENSE that should have accompanied this file.
|
||||
*
|
||||
*
|
||||
* This package is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
@@ -25,6 +25,8 @@
|
||||
#include "AppConfig.h"
|
||||
#include "SslCertificate.h"
|
||||
#include "MainWindow.h"
|
||||
#include "BonjourWindows.h"
|
||||
#include "Zeroconf.h"
|
||||
|
||||
#include <QtCore>
|
||||
#include <QtGui>
|
||||
@@ -37,10 +39,14 @@ static const char networkSecurity[] = "ns";
|
||||
SettingsDialog::SettingsDialog(QWidget* parent, AppConfig& config) :
|
||||
QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint),
|
||||
Ui::SettingsDialogBase(),
|
||||
m_appConfig(config)
|
||||
m_appConfig(config),
|
||||
m_pBonjourWindows(nullptr)
|
||||
{
|
||||
setupUi(this);
|
||||
|
||||
// TODO: maybe just accept MainWindow type in ctor?
|
||||
m_pMainWindow = dynamic_cast<MainWindow*>(parent);
|
||||
|
||||
m_Locale.fillLanguageComboBox(m_pComboLanguage);
|
||||
|
||||
m_pLineEditScreenName->setText(appConfig().screenName());
|
||||
@@ -53,17 +59,42 @@ SettingsDialog::SettingsDialog(QWidget* parent, AppConfig& config) :
|
||||
m_pCheckBoxAutoHide->setChecked(appConfig().getAutoHide());
|
||||
|
||||
#if defined(Q_OS_WIN)
|
||||
m_pComboElevate->setCurrentIndex(static_cast<int>(appConfig().elevateMode()));
|
||||
m_pBonjourWindows = new BonjourWindows(this, m_pMainWindow, m_appConfig);
|
||||
if (m_pBonjourWindows->isRunning()) {
|
||||
allowAutoConfig();
|
||||
}
|
||||
|
||||
m_pComboElevate->setCurrentIndex(static_cast<int>(appConfig().elevateMode()));
|
||||
|
||||
m_pCheckBoxAutoHide->hide();
|
||||
#else
|
||||
// elevate checkbox is only useful on ms windows.
|
||||
m_pLabelElevate->hide();
|
||||
m_pComboElevate->hide();
|
||||
|
||||
// for linux and mac, allow auto config by default
|
||||
allowAutoConfig();
|
||||
#endif
|
||||
|
||||
m_pCheckBoxEnableCrypto->setChecked(m_appConfig.getCryptoEnabled());
|
||||
m_pCheckBoxEnableCrypto->setEnabled(m_appConfig.edition() == kPro);
|
||||
|
||||
#ifdef SYNERGY_ENTERPRISE
|
||||
|
||||
m_pCheckBoxEnableCrypto->setEnabled(true);
|
||||
m_pLabelProUpgrade->hide();
|
||||
|
||||
m_pCheckBoxAutoConfig->hide();
|
||||
m_pLabelInstallBonjour->hide();
|
||||
|
||||
#else
|
||||
|
||||
bool isPro = m_appConfig.edition() == kPro;
|
||||
m_pCheckBoxEnableCrypto->setEnabled(isPro);
|
||||
m_pLabelProUpgrade->setVisible(!isPro);
|
||||
|
||||
m_pCheckBoxAutoConfig->setChecked(appConfig().autoConfig());
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
void SettingsDialog::accept()
|
||||
@@ -77,6 +108,7 @@ void SettingsDialog::accept()
|
||||
appConfig().setLanguage(m_pComboLanguage->itemData(m_pComboLanguage->currentIndex()).toString());
|
||||
appConfig().setElevateMode(static_cast<ElevateMode>(m_pComboElevate->currentIndex()));
|
||||
appConfig().setAutoHide(m_pCheckBoxAutoHide->isChecked());
|
||||
appConfig().setAutoConfig(m_pCheckBoxAutoConfig->isChecked());
|
||||
appConfig().saveSettings();
|
||||
QDialog::accept();
|
||||
}
|
||||
@@ -92,7 +124,7 @@ void SettingsDialog::reject()
|
||||
|
||||
void SettingsDialog::changeEvent(QEvent* event)
|
||||
{
|
||||
if (event != 0)
|
||||
if (event != nullptr)
|
||||
{
|
||||
switch (event->type())
|
||||
{
|
||||
@@ -114,6 +146,13 @@ void SettingsDialog::changeEvent(QEvent* event)
|
||||
}
|
||||
}
|
||||
|
||||
void SettingsDialog::allowAutoConfig()
|
||||
{
|
||||
m_pLabelInstallBonjour->hide();
|
||||
m_pCheckBoxAutoConfig->setEnabled(true);
|
||||
m_pCheckBoxAutoConfig->setChecked(m_appConfig.autoConfig());
|
||||
}
|
||||
|
||||
void SettingsDialog::on_m_pCheckBoxLogToFile_stateChanged(int i)
|
||||
{
|
||||
bool checked = i == 2;
|
||||
@@ -148,7 +187,13 @@ void SettingsDialog::on_m_pCheckBoxEnableCrypto_toggled(bool checked)
|
||||
if (checked) {
|
||||
SslCertificate sslCertificate;
|
||||
sslCertificate.generateCertificate();
|
||||
MainWindow& mainWindow = dynamic_cast<MainWindow&> (*this->parent());
|
||||
mainWindow.updateLocalFingerprint();
|
||||
m_pMainWindow->updateLocalFingerprint();
|
||||
}
|
||||
}
|
||||
|
||||
void SettingsDialog::on_m_pLabelInstallBonjour_linkActivated(const QString&)
|
||||
{
|
||||
#if defined(Q_OS_WIN)
|
||||
m_pBonjourWindows->downloadAndInstall();
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -25,7 +25,9 @@
|
||||
#include "SynergyLocale.h"
|
||||
#include "CoreInterface.h"
|
||||
|
||||
class MainWindow;
|
||||
class AppConfig;
|
||||
class BonjourWindows;
|
||||
|
||||
class SettingsDialog : public QDialog, public Ui::SettingsDialogBase
|
||||
{
|
||||
@@ -35,6 +37,7 @@ class SettingsDialog : public QDialog, public Ui::SettingsDialogBase
|
||||
SettingsDialog(QWidget* parent, AppConfig& config);
|
||||
static QString browseForSynergyc(QWidget* parent, const QString& programDir, const QString& synergycName);
|
||||
static QString browseForSynergys(QWidget* parent, const QString& programDir, const QString& synergysName);
|
||||
void allowAutoConfig();
|
||||
|
||||
protected:
|
||||
void accept();
|
||||
@@ -43,15 +46,18 @@ class SettingsDialog : public QDialog, public Ui::SettingsDialogBase
|
||||
AppConfig& appConfig() { return m_appConfig; }
|
||||
|
||||
private:
|
||||
MainWindow* m_pMainWindow;
|
||||
AppConfig& m_appConfig;
|
||||
SynergyLocale m_Locale;
|
||||
CoreInterface m_CoreInterface;
|
||||
BonjourWindows* m_pBonjourWindows;
|
||||
|
||||
private slots:
|
||||
void on_m_pCheckBoxEnableCrypto_toggled(bool checked);
|
||||
void on_m_pComboLanguage_currentIndexChanged(int index);
|
||||
void on_m_pCheckBoxLogToFile_stateChanged(int );
|
||||
void on_m_pButtonBrowseLog_clicked();
|
||||
void on_m_pLabelInstallBonjour_linkActivated(const QString &link);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>368</width>
|
||||
<height>380</height>
|
||||
<width>357</width>
|
||||
<height>496</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
@@ -157,7 +157,23 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="m_pGroupNetworkSecurity">
|
||||
<spacer name="verticalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Minimum</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>10</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="m_pGroupNetwork">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
@@ -168,38 +184,96 @@
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>&Network Security</string>
|
||||
<string>&Network</string>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<property name="fieldGrowthPolicy">
|
||||
<enum>QFormLayout::AllNonFixedFieldsGrow</enum>
|
||||
</property>
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="m_pCheckBoxEnableCrypto">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Use &SSL encryption</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<property name="leftMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="topMargin">
|
||||
<number>12</number>
|
||||
</property>
|
||||
<property name="rightMargin">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="bottomMargin">
|
||||
<number>12</number>
|
||||
</property>
|
||||
<item row="0" column="1">
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
<layout class="QGridLayout" name="m_pGridLayoutNetwork">
|
||||
<property name="leftMargin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
<property name="verticalSpacing">
|
||||
<number>12</number>
|
||||
</property>
|
||||
</spacer>
|
||||
<item row="1" column="0">
|
||||
<widget class="QCheckBox" name="m_pCheckBoxEnableCrypto">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Enable &TLS Encryption</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
<widget class="QCheckBox" name="m_pCheckBoxAutoConfig">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Enable Auto Config</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="m_pLabelInstallBonjour">
|
||||
<property name="text">
|
||||
<string><html><head/><body><p><a href="#"><span style=" text-decoration: underline; color:#007af4;">Install Bonjour</span></a></p></body></html></string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::RichText</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLabel" name="m_pLabelProUpgrade">
|
||||
<property name="text">
|
||||
<string><html><head/><body><p><a href="https://symless.com/account?source=gui&amp;intent=upgrade"><span style=" text-decoration: underline; color:#007af4;">Upgrade to Pro</span></a></p></body></html></string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::RichText</enum>
|
||||
</property>
|
||||
<property name="openExternalLinks">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Minimum</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>10</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="m_pGroupLog">
|
||||
<property name="sizePolicy">
|
||||
@@ -236,21 +310,6 @@
|
||||
</item>
|
||||
<item row="0" column="1" colspan="2">
|
||||
<widget class="QComboBox" name="m_pComboLogLevel">
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Error</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Warning</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Note</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Info</string>
|
||||
@@ -305,10 +364,13 @@
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::MinimumExpanding</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>20</width>
|
||||
<height>40</height>
|
||||
<height>10</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
@@ -332,7 +394,6 @@
|
||||
<tabstop>m_pLineEditInterface</tabstop>
|
||||
<tabstop>m_pComboElevate</tabstop>
|
||||
<tabstop>m_pCheckBoxAutoHide</tabstop>
|
||||
<tabstop>m_pCheckBoxEnableCrypto</tabstop>
|
||||
<tabstop>m_pComboLogLevel</tabstop>
|
||||
<tabstop>m_pCheckBoxLogToFile</tabstop>
|
||||
<tabstop>m_pLineEditLogFilename</tabstop>
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2012-2016 Symless Ltd.
|
||||
*
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* found in the file LICENSE that should have accompanied this file.
|
||||
*
|
||||
*
|
||||
* This package is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
@@ -14,10 +14,9 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include "SetupWizard.h"
|
||||
#include "MainWindow.h"
|
||||
#include "WebClient.h"
|
||||
#include "ActivationNotifier.h"
|
||||
#include "LicenseManager.h"
|
||||
#include "QSynergyApplication.h"
|
||||
@@ -61,7 +60,7 @@ SetupWizard::~SetupWizard()
|
||||
}
|
||||
|
||||
bool SetupWizard::validateCurrentPage()
|
||||
{
|
||||
{
|
||||
QMessageBox message;
|
||||
message.setWindowTitle(tr("Setup Synergy"));
|
||||
message.setIcon(QMessageBox::Information);
|
||||
@@ -127,7 +126,6 @@ void SetupWizard::accept()
|
||||
|
||||
if (m_StartMain)
|
||||
{
|
||||
m_MainWindow.updateZeroconfService();
|
||||
m_MainWindow.open();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,83 +0,0 @@
|
||||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2015-2016 Symless Ltd.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* found in the file LICENSE that should have accompanied this file.
|
||||
*
|
||||
* This package is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "WebClient.h"
|
||||
|
||||
#include "QUtility.h"
|
||||
|
||||
#include <QProcess>
|
||||
#include <QMessageBox>
|
||||
#include <QCoreApplication>
|
||||
#include <stdexcept>
|
||||
|
||||
bool
|
||||
WebClient::getEdition (int& edition, QString& errorOut) {
|
||||
QString responseJson = request();
|
||||
|
||||
/* TODO: This is horrible and should be ripped out as soon as we move
|
||||
* to Qt 5. See issue #5630
|
||||
*/
|
||||
|
||||
QRegExp resultRegex(".*\"result\".*:.*(true|false).*");
|
||||
if (resultRegex.exactMatch (responseJson)) {
|
||||
QString boolString = resultRegex.cap(1);
|
||||
if (boolString == "true") {
|
||||
QRegExp editionRegex(".*\"edition\".*:.*\"([^\"]+)\".*");
|
||||
if (editionRegex.exactMatch(responseJson)) {
|
||||
QString e = editionRegex.cap(1);
|
||||
edition = e.toInt();
|
||||
return true;
|
||||
} else {
|
||||
throw std::runtime_error ("Unrecognised server response.");
|
||||
}
|
||||
} else {
|
||||
errorOut = tr("Login failed. Invalid email address or password.");
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
QRegExp errorRegex(".*\"error\".*:.*\"([^\"]+)\".*");
|
||||
if (errorRegex.exactMatch (responseJson)) {
|
||||
errorOut = errorRegex.cap(1).replace("\\n", "\n");
|
||||
return false;
|
||||
} else {
|
||||
throw std::runtime_error ("Unrecognised server response.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
WebClient::setEmail (QString email, QString& errorOut) {
|
||||
if (email.isEmpty()) {
|
||||
errorOut = tr("Your email address cannot be left blank.");
|
||||
return false;
|
||||
}
|
||||
m_Email = email;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
WebClient::setPassword (QString password, QString&) {
|
||||
m_Password = password;
|
||||
return true;
|
||||
}
|
||||
|
||||
QString
|
||||
WebClient::request() {
|
||||
QStringList args("--login-auth");
|
||||
QString credentials (m_Email + ":" + hash(m_Password) + "\n");
|
||||
return m_CoreInterface.run (args, credentials);
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2015-2016 Symless Ltd.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* found in the file LICENSE that should have accompanied this file.
|
||||
*
|
||||
* This package is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef WEBCLIENT_H
|
||||
#define WEBCLIENT_H
|
||||
|
||||
#include <QString>
|
||||
#include <QObject>
|
||||
|
||||
#include "CoreInterface.h"
|
||||
|
||||
class QMessageBox;
|
||||
class QWidget;
|
||||
class QStringList;
|
||||
|
||||
class WebClient : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
bool getEdition (int& edition, QString& errorOut);
|
||||
bool setEmail (QString email, QString& errorOut);
|
||||
bool setPassword (QString password, QString& errorOut);
|
||||
signals:
|
||||
void error(QString e);
|
||||
|
||||
private:
|
||||
QString request();
|
||||
|
||||
QString m_Email;
|
||||
QString m_Password;
|
||||
CoreInterface m_CoreInterface;
|
||||
};
|
||||
|
||||
#endif // WEBCLIENT_H
|
||||
58
src/gui/src/Zeroconf.cpp
Normal file
58
src/gui/src/Zeroconf.cpp
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2012-2018 Symless Ltd.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* found in the file LICENSE that should have accompanied this file.
|
||||
*
|
||||
* This package is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "Zeroconf.h"
|
||||
|
||||
#include "ZeroconfService.h"
|
||||
#include "MainWindow.h"
|
||||
|
||||
Zeroconf::Zeroconf(MainWindow* mainWindow) :
|
||||
m_pMainWindow(mainWindow),
|
||||
m_pZeroconfService(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
Zeroconf::~Zeroconf()
|
||||
{
|
||||
stopService();
|
||||
}
|
||||
|
||||
void Zeroconf::startService()
|
||||
{
|
||||
if (m_pZeroconfService != nullptr) {
|
||||
m_pMainWindow->appendLogInfo("restarting zeroconf service");
|
||||
delete m_pZeroconfService;
|
||||
m_pZeroconfService = nullptr;
|
||||
}
|
||||
else {
|
||||
m_pMainWindow->appendLogInfo("starting zeroconf service");
|
||||
}
|
||||
|
||||
m_pZeroconfService = new ZeroconfService(m_pMainWindow);
|
||||
|
||||
m_pMainWindow->appendLogInfo("started zeroconf service");
|
||||
}
|
||||
|
||||
void Zeroconf::stopService()
|
||||
{
|
||||
if (m_pZeroconfService != nullptr) {
|
||||
m_pMainWindow->appendLogInfo("stopping zeroconf service");
|
||||
delete m_pZeroconfService;
|
||||
m_pZeroconfService = nullptr;
|
||||
m_pMainWindow->appendLogInfo("stopped zeroconf service");
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2014-2016 Symless Ltd.
|
||||
* Copyright (C) 2012-2018 Symless Ltd.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@@ -17,12 +17,22 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#define ARCH_INTERNET ArchInternetUnix
|
||||
#include <QObject>
|
||||
|
||||
#include "base/String.h"
|
||||
class MainWindow;
|
||||
class ZeroconfService;
|
||||
|
||||
class Zeroconf : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
class ArchInternetUnix {
|
||||
public:
|
||||
String get(const String& url);
|
||||
String urlEncode(const String& url);
|
||||
Zeroconf(MainWindow* mainWindow);
|
||||
virtual ~Zeroconf();
|
||||
void startService();
|
||||
void stopService();
|
||||
|
||||
private:
|
||||
MainWindow* m_pMainWindow;
|
||||
ZeroconfService* m_pZeroconfService;
|
||||
};
|
||||
@@ -33,13 +33,13 @@ static const QStringList preferedIPAddress(
|
||||
"10." <<
|
||||
"172.");
|
||||
|
||||
const char* ZeroconfService:: m_ServerServiceName = "_synergyServerZeroconf._tcp";
|
||||
const char* ZeroconfService:: m_ClientServiceName = "_synergyClientZeroconf._tcp";
|
||||
const char* ZeroconfService:: m_ServerServiceName = "_synergyServer._tcp";
|
||||
const char* ZeroconfService:: m_ClientServiceName = "_synergyClient._tcp";
|
||||
|
||||
ZeroconfService::ZeroconfService(MainWindow* mainWindow) :
|
||||
m_pMainWindow(mainWindow),
|
||||
m_pZeroconfBrowser(0),
|
||||
m_pZeroconfRegister(0),
|
||||
m_pZeroconfBrowser(nullptr),
|
||||
m_pZeroconfRegister(nullptr),
|
||||
m_ServiceRegistered(false)
|
||||
{
|
||||
if (m_pMainWindow->synergyType() == MainWindow::synergyServer) {
|
||||
@@ -81,7 +81,7 @@ void ZeroconfService::serverDetected(const QList<ZeroconfRecord>& list)
|
||||
registerService(false);
|
||||
m_pMainWindow->appendLogInfo(tr("zeroconf server detected: %1").arg(
|
||||
record.serviceName));
|
||||
m_pMainWindow->serverDetected(record.serviceName);
|
||||
m_pMainWindow->addZeroconfServer(record.serviceName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,7 +96,8 @@ void ZeroconfService::clientDetected(const QList<ZeroconfRecord>& list)
|
||||
|
||||
void ZeroconfService::errorHandle(DNSServiceErrorType errorCode)
|
||||
{
|
||||
QMessageBox::critical(0, tr("Zero configuration service"),
|
||||
QMessageBox::critical(
|
||||
m_pMainWindow, tr("Synergy Auto Config"),
|
||||
tr("Error code: %1.").arg(errorCode));
|
||||
}
|
||||
|
||||
@@ -127,8 +128,9 @@ bool ZeroconfService::registerService(bool server)
|
||||
|
||||
if (!m_ServiceRegistered) {
|
||||
if (!m_zeroconfServer.listen()) {
|
||||
QMessageBox::critical(0, tr("Zero configuration service"),
|
||||
tr("Unable to start the zeroconf: %1.")
|
||||
QMessageBox::critical(
|
||||
m_pMainWindow, tr("Synergy Auto Config"),
|
||||
tr("Unable to start zeroconf: %1.")
|
||||
.arg(m_zeroconfServer.errorString()));
|
||||
result = false;
|
||||
}
|
||||
@@ -137,7 +139,8 @@ bool ZeroconfService::registerService(bool server)
|
||||
if (server) {
|
||||
QString localIP = getLocalIPAddresses();
|
||||
if (localIP.isEmpty()) {
|
||||
QMessageBox::warning(m_pMainWindow, tr("Synergy"),
|
||||
QMessageBox::warning(
|
||||
m_pMainWindow, tr("Synergy Auto Config"),
|
||||
tr("Failed to get local IP address. "
|
||||
"Please manually type in server address "
|
||||
"on your clients"));
|
||||
|
||||
@@ -41,10 +41,10 @@
|
||||
class QThreadImpl : public QThread
|
||||
{
|
||||
public:
|
||||
static void msleep(unsigned long msecs)
|
||||
{
|
||||
QThread::msleep(msecs);
|
||||
}
|
||||
static void msleep(unsigned long msecs)
|
||||
{
|
||||
QThread::msleep(msecs);
|
||||
}
|
||||
};
|
||||
|
||||
int waitForTray();
|
||||
@@ -59,80 +59,90 @@ int main(int argc, char* argv[])
|
||||
/* Workaround for QTBUG-40332 - "High ping when QNetworkAccessManager is instantiated" */
|
||||
::setenv ("QT_BEARER_POLL_TIMEOUT", "-1", 1);
|
||||
#endif
|
||||
QCoreApplication::setOrganizationName("Synergy");
|
||||
QCoreApplication::setOrganizationDomain("http://symless.com/");
|
||||
QCoreApplication::setApplicationName("Synergy");
|
||||
QCoreApplication::setOrganizationName("Synergy");
|
||||
QCoreApplication::setOrganizationDomain("http://symless.com/");
|
||||
QCoreApplication::setApplicationName("Synergy");
|
||||
|
||||
QSynergyApplication app(argc, argv);
|
||||
QSynergyApplication app(argc, argv);
|
||||
|
||||
#if defined(Q_OS_MAC)
|
||||
|
||||
if (app.applicationDirPath().startsWith("/Volumes/")) {
|
||||
QMessageBox::information(
|
||||
NULL, "Synergy",
|
||||
"Please drag Synergy to the Applications folder, and open it from there.");
|
||||
return 1;
|
||||
}
|
||||
if (app.applicationDirPath().startsWith("/Volumes/")) {
|
||||
QMessageBox::information(
|
||||
NULL, "Synergy",
|
||||
"Please drag Synergy to the Applications folder, and open it from there.");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!checkMacAssistiveDevices())
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
if (!checkMacAssistiveDevices())
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!waitForTray())
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
if (!waitForTray())
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifndef Q_OS_WIN
|
||||
QApplication::setQuitOnLastWindowClosed(false);
|
||||
QApplication::setQuitOnLastWindowClosed(false);
|
||||
#endif
|
||||
|
||||
QSettings settings;
|
||||
AppConfig appConfig (&settings);
|
||||
qRegisterMetaType<Edition>("Edition");
|
||||
LicenseManager licenseManager (&appConfig);
|
||||
QSettings settings;
|
||||
AppConfig appConfig (&settings);
|
||||
qRegisterMetaType<Edition>("Edition");
|
||||
#ifndef SYNERGY_ENTERPRISE
|
||||
LicenseManager licenseManager (&appConfig);
|
||||
#endif
|
||||
|
||||
app.switchTranslator(appConfig.language());
|
||||
app.switchTranslator(appConfig.language());
|
||||
|
||||
MainWindow mainWindow(settings, appConfig, licenseManager);
|
||||
SetupWizard setupWizard(mainWindow, true);
|
||||
#ifdef SYNERGY_ENTERPRISE
|
||||
MainWindow mainWindow(settings, appConfig);
|
||||
#else
|
||||
MainWindow mainWindow(settings, appConfig, licenseManager);
|
||||
#endif
|
||||
|
||||
if (appConfig.wizardShouldRun())
|
||||
{
|
||||
setupWizard.show();
|
||||
}
|
||||
else
|
||||
{
|
||||
mainWindow.open();
|
||||
}
|
||||
QObject::connect(dynamic_cast<QObject*>(&app), SIGNAL(aboutToQuit()),
|
||||
&mainWindow, SLOT(saveSettings()));
|
||||
|
||||
return app.exec();
|
||||
SetupWizard setupWizard(mainWindow, true);
|
||||
|
||||
if (appConfig.wizardShouldRun())
|
||||
{
|
||||
setupWizard.show();
|
||||
}
|
||||
else
|
||||
{
|
||||
mainWindow.open();
|
||||
}
|
||||
|
||||
return app.exec();
|
||||
}
|
||||
|
||||
int waitForTray()
|
||||
{
|
||||
// on linux, the system tray may not be available immediately after logging in,
|
||||
// so keep retrying but give up after a short time.
|
||||
int trayAttempts = 0;
|
||||
while (true)
|
||||
{
|
||||
if (QSystemTrayIcon::isSystemTrayAvailable())
|
||||
{
|
||||
break;
|
||||
}
|
||||
// on linux, the system tray may not be available immediately after logging in,
|
||||
// so keep retrying but give up after a short time.
|
||||
int trayAttempts = 0;
|
||||
while (true)
|
||||
{
|
||||
if (QSystemTrayIcon::isSystemTrayAvailable())
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if (++trayAttempts > TRAY_RETRY_COUNT)
|
||||
{
|
||||
QMessageBox::critical(NULL, "Synergy",
|
||||
QObject::tr("System tray is unavailable, don't close your window."));
|
||||
return true;
|
||||
}
|
||||
if (++trayAttempts > TRAY_RETRY_COUNT)
|
||||
{
|
||||
QMessageBox::critical(NULL, "Synergy",
|
||||
QObject::tr("System tray is unavailable, don't close your window."));
|
||||
return true;
|
||||
}
|
||||
|
||||
QThreadImpl::msleep(TRAY_RETRY_WAIT);
|
||||
}
|
||||
return true;
|
||||
QThreadImpl::msleep(TRAY_RETRY_WAIT);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#if defined(Q_OS_MAC)
|
||||
@@ -140,36 +150,36 @@ bool checkMacAssistiveDevices()
|
||||
{
|
||||
#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1090 // mavericks
|
||||
|
||||
// new in mavericks, applications are trusted individually
|
||||
// with use of the accessibility api. this call will show a
|
||||
// prompt which can show the security/privacy/accessibility
|
||||
// tab, with a list of allowed applications. synergy should
|
||||
// show up there automatically, but will be unchecked.
|
||||
// new in mavericks, applications are trusted individually
|
||||
// with use of the accessibility api. this call will show a
|
||||
// prompt which can show the security/privacy/accessibility
|
||||
// tab, with a list of allowed applications. synergy should
|
||||
// show up there automatically, but will be unchecked.
|
||||
|
||||
if (AXIsProcessTrusted()) {
|
||||
return true;
|
||||
}
|
||||
if (AXIsProcessTrusted()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const void* keys[] = { kAXTrustedCheckOptionPrompt };
|
||||
const void* trueValue[] = { kCFBooleanTrue };
|
||||
CFDictionaryRef options = CFDictionaryCreate(NULL, keys, trueValue, 1, NULL, NULL);
|
||||
const void* keys[] = { kAXTrustedCheckOptionPrompt };
|
||||
const void* trueValue[] = { kCFBooleanTrue };
|
||||
CFDictionaryRef options = CFDictionaryCreate(NULL, keys, trueValue, 1, NULL, NULL);
|
||||
|
||||
bool result = AXIsProcessTrustedWithOptions(options);
|
||||
CFRelease(options);
|
||||
return result;
|
||||
bool result = AXIsProcessTrustedWithOptions(options);
|
||||
CFRelease(options);
|
||||
return result;
|
||||
|
||||
#else
|
||||
|
||||
// now deprecated in mavericks.
|
||||
bool result = AXAPIEnabled();
|
||||
if (!result) {
|
||||
QMessageBox::information(
|
||||
NULL, "Synergy",
|
||||
"Please enable access to assistive devices "
|
||||
"System Preferences -> Security & Privacy -> "
|
||||
"Privacy -> Accessibility, then re-open Synergy.");
|
||||
}
|
||||
return result;
|
||||
// now deprecated in mavericks.
|
||||
bool result = AXAPIEnabled();
|
||||
if (!result) {
|
||||
QMessageBox::information(
|
||||
NULL, "Synergy",
|
||||
"Please enable access to assistive devices "
|
||||
"System Preferences -> Security & Privacy -> "
|
||||
"Privacy -> Accessibility, then re-open Synergy.");
|
||||
}
|
||||
return result;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -50,7 +50,6 @@
|
||||
# include "arch/win32/ArchSystemWindows.h"
|
||||
# include "arch/win32/ArchTaskBarWindows.h"
|
||||
# include "arch/win32/ArchTimeWindows.h"
|
||||
# include "arch/win32/ArchInternetWindows.h"
|
||||
#elif SYSAPI_UNIX
|
||||
# include "arch/unix/ArchConsoleUnix.h"
|
||||
# include "arch/unix/ArchDaemonUnix.h"
|
||||
@@ -65,7 +64,6 @@
|
||||
# include "arch/unix/ArchSystemUnix.h"
|
||||
# include "arch/unix/ArchTaskBarXWindows.h"
|
||||
# include "arch/unix/ArchTimeUnix.h"
|
||||
# include "arch/unix/ArchInternetUnix.h"
|
||||
#endif
|
||||
|
||||
/*!
|
||||
@@ -120,11 +118,8 @@ public:
|
||||
|
||||
static void setInstance(Arch* s) { s_instance = s; }
|
||||
|
||||
ARCH_INTERNET& internet() const { return (ARCH_INTERNET&)m_internet; }
|
||||
|
||||
private:
|
||||
static Arch* s_instance;
|
||||
ARCH_INTERNET m_internet;
|
||||
};
|
||||
|
||||
//! Convenience object to lock/unlock an arch mutex
|
||||
|
||||
@@ -40,5 +40,5 @@ endif()
|
||||
add_library(arch STATIC ${sources})
|
||||
|
||||
if (UNIX)
|
||||
target_link_libraries(arch dl ${libs})
|
||||
target_link_libraries(arch ${CMAKE_DL_LIBS} ${libs})
|
||||
endif()
|
||||
|
||||
@@ -91,7 +91,7 @@ IArchString::convStringWCToMB(char* dst,
|
||||
}
|
||||
ARCH->unlockMutex(s_mutex);
|
||||
|
||||
return len;
|
||||
return static_cast<int>(len);
|
||||
}
|
||||
|
||||
int
|
||||
@@ -141,8 +141,8 @@ IArchString::convStringMBToWC(wchar_t* dst,
|
||||
default:
|
||||
// normal character
|
||||
len += 1;
|
||||
scan += mblen;
|
||||
n -= mblen;
|
||||
scan += static_cast<int>(mblen);
|
||||
n -= static_cast<int>(mblen);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -176,8 +176,8 @@ IArchString::convStringMBToWC(wchar_t* dst,
|
||||
|
||||
default:
|
||||
// normal character
|
||||
scan += mblen;
|
||||
n -= mblen;
|
||||
scan += static_cast<int>(mblen);
|
||||
n -= static_cast<int>(mblen);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -185,5 +185,5 @@ IArchString::convStringMBToWC(wchar_t* dst,
|
||||
}
|
||||
ARCH->unlockMutex(s_mutex);
|
||||
|
||||
return len;
|
||||
return static_cast<int>(len);
|
||||
}
|
||||
|
||||
@@ -56,11 +56,4 @@ public:
|
||||
*/
|
||||
virtual void setting(const std::string& valueName, const std::string& valueString) const = 0;
|
||||
//@}
|
||||
|
||||
//! Get the pathnames of the libraries used by Synergy
|
||||
/*
|
||||
Returns a string containing the full path names of all loaded libraries at the point it is called.
|
||||
*/
|
||||
virtual std::string getLibsUsed(void) const = 0;
|
||||
//@}
|
||||
};
|
||||
|
||||
@@ -1,126 +0,0 @@
|
||||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2014-2016 Symless Ltd.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* found in the file LICENSE that should have accompanied this file.
|
||||
*
|
||||
* This package is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "arch/unix/ArchInternetUnix.h"
|
||||
|
||||
#include "arch/XArch.h"
|
||||
#include "common/Version.h"
|
||||
#include "base/Log.h"
|
||||
|
||||
#include <sstream>
|
||||
#include <curl/curl.h>
|
||||
|
||||
class CurlFacade {
|
||||
public:
|
||||
CurlFacade();
|
||||
~CurlFacade();
|
||||
String get(const String& url);
|
||||
String urlEncode(const String& url);
|
||||
|
||||
private:
|
||||
CURL* m_curl;
|
||||
};
|
||||
|
||||
//
|
||||
// ArchInternetUnix
|
||||
//
|
||||
|
||||
String
|
||||
ArchInternetUnix::get(const String& url)
|
||||
{
|
||||
CurlFacade curl;
|
||||
return curl.get(url);
|
||||
}
|
||||
|
||||
String
|
||||
ArchInternetUnix::urlEncode(const String& url)
|
||||
{
|
||||
CurlFacade curl;
|
||||
return curl.urlEncode(url);
|
||||
}
|
||||
|
||||
//
|
||||
// CurlFacade
|
||||
//
|
||||
|
||||
static size_t
|
||||
curlWriteCallback(void *contents, size_t size, size_t nmemb, void *userp)
|
||||
{
|
||||
((std::string*)userp)->append((char*)contents, size * nmemb);
|
||||
return size * nmemb;
|
||||
}
|
||||
|
||||
CurlFacade::CurlFacade() :
|
||||
m_curl(NULL)
|
||||
{
|
||||
CURLcode init = curl_global_init(CURL_GLOBAL_ALL);
|
||||
if (init != CURLE_OK) {
|
||||
throw XArch("CURL global init failed.");
|
||||
}
|
||||
|
||||
m_curl = curl_easy_init();
|
||||
if (m_curl == NULL) {
|
||||
throw XArch("CURL easy init failed.");
|
||||
}
|
||||
}
|
||||
|
||||
CurlFacade::~CurlFacade()
|
||||
{
|
||||
if (m_curl != NULL) {
|
||||
curl_easy_cleanup(m_curl);
|
||||
}
|
||||
|
||||
curl_global_cleanup();
|
||||
}
|
||||
|
||||
String
|
||||
CurlFacade::get(const String& url)
|
||||
{
|
||||
curl_easy_setopt(m_curl, CURLOPT_URL, url.c_str());
|
||||
curl_easy_setopt(m_curl, CURLOPT_WRITEFUNCTION, curlWriteCallback);
|
||||
|
||||
std::stringstream userAgent;
|
||||
userAgent << "Synergy ";
|
||||
userAgent << kVersion;
|
||||
curl_easy_setopt(m_curl, CURLOPT_USERAGENT, userAgent.str().c_str());
|
||||
|
||||
std::string result;
|
||||
curl_easy_setopt(m_curl, CURLOPT_WRITEDATA, &result);
|
||||
|
||||
CURLcode code = curl_easy_perform(m_curl);
|
||||
if (code != CURLE_OK) {
|
||||
LOG((CLOG_ERR "curl perform error: %s", curl_easy_strerror(code)));
|
||||
throw XArch("CURL perform failed.");
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
String
|
||||
CurlFacade::urlEncode(const String& url)
|
||||
{
|
||||
char* resultCStr = curl_easy_escape(m_curl, url.c_str(), 0);
|
||||
|
||||
if (resultCStr == NULL) {
|
||||
throw XArch("CURL escape failed.");
|
||||
}
|
||||
|
||||
std::string result(resultCStr);
|
||||
curl_free(resultCStr);
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -1,224 +0,0 @@
|
||||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2014-2016 Symless Ltd.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* found in the file LICENSE that should have accompanied this file.
|
||||
*
|
||||
* This package is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "arch/win32/ArchInternetWindows.h"
|
||||
#include "arch/win32/XArchWindows.h"
|
||||
#include "arch/Arch.h"
|
||||
#include "common/Version.h"
|
||||
|
||||
#include <sstream>
|
||||
#include <Wininet.h>
|
||||
#include <Shlwapi.h>
|
||||
|
||||
struct WinINetUrl {
|
||||
String m_scheme;
|
||||
String m_host;
|
||||
String m_path;
|
||||
INTERNET_PORT m_port;
|
||||
DWORD m_flags;
|
||||
};
|
||||
|
||||
class WinINetRequest {
|
||||
public:
|
||||
WinINetRequest(const String& url);
|
||||
~WinINetRequest();
|
||||
|
||||
String send();
|
||||
void openSession();
|
||||
void connect();
|
||||
void openRequest();
|
||||
|
||||
private:
|
||||
HINTERNET m_session;
|
||||
HINTERNET m_connect;
|
||||
HINTERNET m_request;
|
||||
WinINetUrl m_url;
|
||||
bool m_used;
|
||||
};
|
||||
|
||||
//
|
||||
// ArchInternetWindows
|
||||
//
|
||||
|
||||
String
|
||||
ArchInternetWindows::get(const String& url)
|
||||
{
|
||||
WinINetRequest request(url);
|
||||
return request.send();
|
||||
}
|
||||
|
||||
String
|
||||
ArchInternetWindows::urlEncode(const String& url)
|
||||
{
|
||||
TCHAR buffer[1024];
|
||||
DWORD bufferSize = sizeof(buffer);
|
||||
|
||||
if (UrlEscape(url.c_str(), buffer, &bufferSize, URL_ESCAPE_UNSAFE) != S_OK) {
|
||||
throw XArch(new XArchEvalWindows());
|
||||
}
|
||||
|
||||
String result(buffer);
|
||||
|
||||
// the win32 url encoding funcitons are pretty useless (to us) and only
|
||||
// escape "unsafe" chars, but not + or =, so we need to replace these
|
||||
// manually (and probably many other chars).
|
||||
synergy::string::findReplaceAll(result, "+", "%2B");
|
||||
synergy::string::findReplaceAll(result, "=", "%3D");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//
|
||||
// WinINetRequest
|
||||
//
|
||||
|
||||
static WinINetUrl parseUrl(const String& url);
|
||||
|
||||
WinINetRequest::WinINetRequest(const String& url) :
|
||||
m_session(NULL),
|
||||
m_connect(NULL),
|
||||
m_request(NULL),
|
||||
m_used(false),
|
||||
m_url(parseUrl(url))
|
||||
{
|
||||
}
|
||||
|
||||
WinINetRequest::~WinINetRequest()
|
||||
{
|
||||
if (m_request != NULL) {
|
||||
InternetCloseHandle(m_request);
|
||||
}
|
||||
|
||||
if (m_connect != NULL) {
|
||||
InternetCloseHandle(m_connect);
|
||||
}
|
||||
|
||||
if (m_session != NULL) {
|
||||
InternetCloseHandle(m_session);
|
||||
}
|
||||
}
|
||||
|
||||
String
|
||||
WinINetRequest::send()
|
||||
{
|
||||
if (m_used) {
|
||||
throw XArch("class is one time use.");
|
||||
}
|
||||
m_used = true;
|
||||
|
||||
openSession();
|
||||
connect();
|
||||
openRequest();
|
||||
|
||||
String headers("Content-Type: text/html");
|
||||
if (!HttpSendRequest(m_request, headers.c_str(), (DWORD)headers.length(), NULL, NULL)) {
|
||||
throw XArch(new XArchEvalWindows());
|
||||
}
|
||||
|
||||
std::stringstream result;
|
||||
CHAR buffer[1025];
|
||||
DWORD read = 0;
|
||||
|
||||
while (InternetReadFile(m_request, buffer, sizeof(buffer) - 1, &read) && (read != 0)) {
|
||||
buffer[read] = 0;
|
||||
result << buffer;
|
||||
read = 0;
|
||||
}
|
||||
|
||||
return result.str();
|
||||
}
|
||||
|
||||
void
|
||||
WinINetRequest::openSession()
|
||||
{
|
||||
std::stringstream userAgent;
|
||||
userAgent << "Synergy ";
|
||||
userAgent << kVersion;
|
||||
|
||||
m_session = InternetOpen(
|
||||
userAgent.str().c_str(),
|
||||
INTERNET_OPEN_TYPE_PRECONFIG,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
if (m_session == NULL) {
|
||||
throw XArch(new XArchEvalWindows());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
WinINetRequest::connect()
|
||||
{
|
||||
m_connect = InternetConnect(
|
||||
m_session,
|
||||
m_url.m_host.c_str(),
|
||||
m_url.m_port,
|
||||
NULL,
|
||||
NULL,
|
||||
INTERNET_SERVICE_HTTP,
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
if (m_connect == NULL) {
|
||||
throw XArch(new XArchEvalWindows());
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
WinINetRequest::openRequest()
|
||||
{
|
||||
m_request = HttpOpenRequest(
|
||||
m_connect,
|
||||
"GET",
|
||||
m_url.m_path.c_str(),
|
||||
HTTP_VERSION,
|
||||
NULL,
|
||||
NULL,
|
||||
m_url.m_flags,
|
||||
NULL);
|
||||
|
||||
if (m_request == NULL) {
|
||||
throw XArch(new XArchEvalWindows());
|
||||
}
|
||||
}
|
||||
|
||||
// nb: i tried to use InternetCrackUrl here, but couldn't quite get that to
|
||||
// work. here's some (less robust) code to split the url into components.
|
||||
// this works fine with simple urls, but doesn't consider the full url spec.
|
||||
static WinINetUrl
|
||||
parseUrl(const String& url)
|
||||
{
|
||||
WinINetUrl parsed;
|
||||
|
||||
size_t schemeEnd = url.find("://");
|
||||
size_t hostEnd = url.find('/', schemeEnd + 3);
|
||||
|
||||
parsed.m_scheme = url.substr(0, schemeEnd);
|
||||
parsed.m_host = url.substr(schemeEnd + 3, hostEnd - (schemeEnd + 3));
|
||||
parsed.m_path = url.substr(hostEnd);
|
||||
|
||||
parsed.m_port = INTERNET_DEFAULT_HTTP_PORT;
|
||||
parsed.m_flags = 0;
|
||||
|
||||
if (parsed.m_scheme.find("https") != String::npos) {
|
||||
parsed.m_port = INTERNET_DEFAULT_HTTPS_PORT;
|
||||
parsed.m_flags = INTERNET_FLAG_SECURE;
|
||||
}
|
||||
|
||||
return parsed;
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2014-2016 Symless Ltd.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* found in the file LICENSE that should have accompanied this file.
|
||||
*
|
||||
* This package is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 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, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#define ARCH_INTERNET ArchInternetWindows
|
||||
|
||||
#include "base/String.h"
|
||||
|
||||
class ArchInternetWindows {
|
||||
public:
|
||||
String get(const String& url);
|
||||
String urlEncode(const String& url);
|
||||
};
|
||||
@@ -128,39 +128,3 @@ ArchSystemWindows::isWOW64() const
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
#pragma comment(lib, "psapi")
|
||||
|
||||
std::string
|
||||
ArchSystemWindows::getLibsUsed(void) const
|
||||
{
|
||||
HMODULE hMods[1024];
|
||||
HANDLE hProcess;
|
||||
DWORD cbNeeded;
|
||||
unsigned int i;
|
||||
char hex[16];
|
||||
|
||||
DWORD pid = GetCurrentProcessId();
|
||||
|
||||
std::string msg = "pid:" + std::to_string((_ULonglong)pid) + "\n";
|
||||
|
||||
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid);
|
||||
|
||||
if (NULL == hProcess) {
|
||||
return msg;
|
||||
}
|
||||
|
||||
if (EnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded)) {
|
||||
for (i = 0; i < (cbNeeded / sizeof(HMODULE)); i++) {
|
||||
TCHAR szModName[MAX_PATH];
|
||||
if (GetModuleFileNameEx(hProcess, hMods[i], szModName, sizeof(szModName) / sizeof(TCHAR))) {
|
||||
sprintf(hex, "(0x%08llX)", reinterpret_cast<long long>(hMods[i]));
|
||||
msg += szModName;
|
||||
msg.append(hex);
|
||||
msg.append("\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
CloseHandle(hProcess);
|
||||
return msg;
|
||||
}
|
||||
|
||||
@@ -33,7 +33,6 @@ public:
|
||||
virtual std::string getPlatformName() const;
|
||||
virtual std::string setting(const std::string& valueName) const;
|
||||
virtual void setting(const std::string& valueName, const std::string& valueString) const;
|
||||
virtual std::string getLibsUsed(void) const;
|
||||
|
||||
bool isWOW64() const;
|
||||
};
|
||||
|
||||
@@ -46,7 +46,12 @@ static const char* g_priority[] = {
|
||||
// number of priorities
|
||||
static const int g_numPriority = (int)(sizeof(g_priority) / sizeof(g_priority[0]));
|
||||
|
||||
// the default priority
|
||||
// if NDEBUG (not debug) is not specified, i.e. you're building in debug,
|
||||
// then set default log level to DEBUG, otherwise the max level is INFO.
|
||||
//
|
||||
// GOTCHA: if `-DCMAKE_BUILD_TYPE=Debug` isn't set when configuring cmake
|
||||
// for visual studio, then NDEBUG will be set (even if your VS solution
|
||||
// config is Debug).
|
||||
#ifndef NDEBUG
|
||||
static const int g_defaultMaxPriority = kDEBUG;
|
||||
#else
|
||||
@@ -181,11 +186,11 @@ Log::print(const char* file, int line, const char* fmt, ...)
|
||||
|
||||
// square brackets, spaces, comma and null terminator take about 10
|
||||
int size = 10;
|
||||
size += strlen(timestamp);
|
||||
size += strlen(g_priority[priority]);
|
||||
size += strlen(buffer);
|
||||
size += static_cast<int>(strlen(timestamp));
|
||||
size += static_cast<int>(strlen(g_priority[priority]));
|
||||
size += static_cast<int>(strlen(buffer));
|
||||
#ifndef NDEBUG
|
||||
size += strlen(file);
|
||||
size += static_cast<int>(strlen(file));
|
||||
// assume there is no file contains over 100k lines of code
|
||||
size += 6;
|
||||
#endif
|
||||
|
||||
@@ -44,6 +44,8 @@
|
||||
#include <cstdlib>
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
#include <algorithm>
|
||||
#include <climits>
|
||||
|
||||
//
|
||||
// Client
|
||||
@@ -73,7 +75,8 @@ Client::Client(
|
||||
m_socket(NULL),
|
||||
m_useSecureNetwork(args.m_enableCrypto),
|
||||
m_args(args),
|
||||
m_enableClipboard(true)
|
||||
m_enableClipboard(true),
|
||||
m_maximumClipboardSize(INT_MAX)
|
||||
{
|
||||
assert(m_socketFactory != NULL);
|
||||
assert(m_screen != NULL);
|
||||
@@ -359,15 +362,26 @@ Client::setOptions(const OptionsList& options)
|
||||
const OptionID id = *index;
|
||||
if (id == kOptionClipboardSharing) {
|
||||
index++;
|
||||
if (*index == static_cast<OptionValue>(false)) {
|
||||
LOG((CLOG_NOTE "clipboard sharing is disabled"));
|
||||
if (index != options.end()) {
|
||||
if (!*index) {
|
||||
LOG((CLOG_NOTE "clipboard sharing disabled by server"));
|
||||
}
|
||||
m_enableClipboard = *index;
|
||||
}
|
||||
} else if (id == kOptionClipboardSharingSize) {
|
||||
index++;
|
||||
if (index != options.end()) {
|
||||
m_maximumClipboardSize = *index;
|
||||
}
|
||||
m_enableClipboard = *index;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (m_enableClipboard && !m_maximumClipboardSize) {
|
||||
m_enableClipboard = false;
|
||||
LOG((CLOG_NOTE "clipboard sharing is disabled because the server "
|
||||
"set the maximum clipboard size to 0"));
|
||||
}
|
||||
|
||||
m_screen->setOptions(options);
|
||||
}
|
||||
|
||||
@@ -397,12 +411,17 @@ Client::sendClipboard(ClipboardID id)
|
||||
// check time
|
||||
if (m_timeClipboard[id] == 0 ||
|
||||
clipboard.getTime() != m_timeClipboard[id]) {
|
||||
// save new time
|
||||
m_timeClipboard[id] = clipboard.getTime();
|
||||
|
||||
// marshall the data
|
||||
String data = clipboard.marshall();
|
||||
String data = clipboard.marshall();
|
||||
if (data.size() >= m_maximumClipboardSize * 1024) {
|
||||
LOG((CLOG_NOTE "Skipping clipboard transfer because the clipboard"
|
||||
" contents exceeds the %i MB size limit set by the server",
|
||||
m_maximumClipboardSize / 1024));
|
||||
return;
|
||||
}
|
||||
|
||||
// save new time
|
||||
m_timeClipboard[id] = clipboard.getTime();
|
||||
// save and send data if different or not yet sent
|
||||
if (!m_sentClipboard[id] || data != m_dataClipboard[id]) {
|
||||
m_sentClipboard[id] = true;
|
||||
@@ -656,7 +675,7 @@ Client::handleShapeChanged(const Event&, void*)
|
||||
void
|
||||
Client::handleClipboardGrabbed(const Event& event, void*)
|
||||
{
|
||||
if (!m_enableClipboard) {
|
||||
if (!m_enableClipboard || (m_maximumClipboardSize == 0)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -198,11 +198,11 @@ public:
|
||||
bool m_mock;
|
||||
|
||||
private:
|
||||
String m_name;
|
||||
NetworkAddress m_serverAddress;
|
||||
ISocketFactory* m_socketFactory;
|
||||
String m_name;
|
||||
NetworkAddress m_serverAddress;
|
||||
ISocketFactory* m_socketFactory;
|
||||
synergy::Screen* m_screen;
|
||||
synergy::IStream* m_stream;
|
||||
synergy::IStream* m_stream;
|
||||
EventQueueTimer* m_timer;
|
||||
ServerProxy* m_server;
|
||||
bool m_ready;
|
||||
@@ -212,16 +212,17 @@ private:
|
||||
bool m_ownClipboard[kClipboardEnd];
|
||||
bool m_sentClipboard[kClipboardEnd];
|
||||
IClipboard::Time m_timeClipboard[kClipboardEnd];
|
||||
String m_dataClipboard[kClipboardEnd];
|
||||
String m_dataClipboard[kClipboardEnd];
|
||||
IEventQueue* m_events;
|
||||
std::size_t m_expectedFileSize;
|
||||
String m_receivedFileData;
|
||||
std::size_t m_expectedFileSize;
|
||||
String m_receivedFileData;
|
||||
DragFileList m_dragFileList;
|
||||
String m_dragFileExt;
|
||||
Thread* m_sendFileThread;
|
||||
Thread* m_writeToDropDirThread;
|
||||
TCPSocket* m_socket;
|
||||
String m_dragFileExt;
|
||||
Thread* m_sendFileThread;
|
||||
Thread* m_writeToDropDirThread;
|
||||
TCPSocket* m_socket;
|
||||
bool m_useSecureNetwork;
|
||||
ClientArgs m_args;
|
||||
ClientArgs m_args;
|
||||
bool m_enableClipboard;
|
||||
size_t m_maximumClipboardSize;
|
||||
};
|
||||
|
||||
@@ -20,6 +20,15 @@
|
||||
|
||||
#include "common/common.h"
|
||||
|
||||
// VC++ has built-in sized types
|
||||
// moved from common.h (why was it there?)
|
||||
#if defined(_MSC_VER)
|
||||
# include <wchar.h>
|
||||
# define TYPE_OF_SIZE_1 __int8
|
||||
# define TYPE_OF_SIZE_2 __int16
|
||||
# define TYPE_OF_SIZE_4 __int32
|
||||
#endif
|
||||
|
||||
//
|
||||
// pick types of particular sizes
|
||||
//
|
||||
|
||||
@@ -27,19 +27,6 @@
|
||||
# error "config.h missing"
|
||||
#endif
|
||||
|
||||
// VC++ has built-in sized types
|
||||
#if defined(_MSC_VER)
|
||||
# include <wchar.h>
|
||||
# define TYPE_OF_SIZE_1 __int8
|
||||
# define TYPE_OF_SIZE_2 __int16
|
||||
# define TYPE_OF_SIZE_4 __int32
|
||||
#else
|
||||
# define SIZE_OF_CHAR 1
|
||||
# define SIZE_OF_SHORT 2
|
||||
# define SIZE_OF_INT 4
|
||||
# define SIZE_OF_LONG 4
|
||||
#endif
|
||||
|
||||
// define NULL
|
||||
#include <stddef.h>
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
*/
|
||||
|
||||
#include "io/StreamBuffer.h"
|
||||
#include "common/common.h"
|
||||
|
||||
//
|
||||
// StreamBuffer
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#define MAX_ERROR_SIZE 65535
|
||||
|
||||
static const float s_retryDelay = 0.01f;
|
||||
const char* k_tlsString = "TLSv1.2";
|
||||
|
||||
enum {
|
||||
kMsgSize = 128
|
||||
@@ -198,6 +199,7 @@ SecureSocket::doWrite()
|
||||
{
|
||||
static bool s_retry = false;
|
||||
static int s_retrySize = 0;
|
||||
static int s_staticBufferSize = 0;
|
||||
static void* s_staticBuffer = NULL;
|
||||
|
||||
// write data
|
||||
@@ -210,8 +212,13 @@ SecureSocket::doWrite()
|
||||
}
|
||||
else {
|
||||
bufferSize = m_outputBuffer.getSize();
|
||||
s_staticBuffer = malloc(bufferSize);
|
||||
memcpy(s_staticBuffer, m_outputBuffer.peek(bufferSize), bufferSize);
|
||||
if (bufferSize != 0) {
|
||||
if (bufferSize > s_staticBufferSize) {
|
||||
s_staticBuffer = realloc(s_staticBuffer, bufferSize);
|
||||
s_staticBufferSize = bufferSize;
|
||||
}
|
||||
memcpy(s_staticBuffer, m_outputBuffer.peek(bufferSize), bufferSize);
|
||||
}
|
||||
}
|
||||
|
||||
if (bufferSize == 0) {
|
||||
@@ -223,8 +230,6 @@ SecureSocket::doWrite()
|
||||
if (status > 0) {
|
||||
s_retry = false;
|
||||
bufferSize = 0;
|
||||
free(s_staticBuffer);
|
||||
s_staticBuffer = NULL;
|
||||
}
|
||||
else if (status < 0) {
|
||||
return kBreak;
|
||||
@@ -277,7 +282,7 @@ int
|
||||
SecureSocket::secureWrite(const void* buffer, int size, int& wrote)
|
||||
{
|
||||
if (m_ssl->m_ssl != NULL) {
|
||||
LOG((CLOG_DEBUG2 "writing secure socket:%p", this));
|
||||
LOG((CLOG_DEBUG2 "writing secure socket: %p", this));
|
||||
|
||||
wrote = SSL_write(m_ssl->m_ssl, buffer, size);
|
||||
|
||||
@@ -320,7 +325,7 @@ bool
|
||||
SecureSocket::loadCertificates(String& filename)
|
||||
{
|
||||
if (filename.empty()) {
|
||||
showError("ssl certificate is not specified");
|
||||
showError("tls certificate is not specified");
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
@@ -329,7 +334,7 @@ SecureSocket::loadCertificates(String& filename)
|
||||
file.close();
|
||||
|
||||
if (!exist) {
|
||||
String errorMsg("ssl certificate doesn't exist: ");
|
||||
String errorMsg("tls certificate doesn't exist: ");
|
||||
errorMsg.append(filename);
|
||||
showError(errorMsg.c_str());
|
||||
return false;
|
||||
@@ -339,19 +344,19 @@ SecureSocket::loadCertificates(String& filename)
|
||||
int r = 0;
|
||||
r = SSL_CTX_use_certificate_file(m_ssl->m_context, filename.c_str(), SSL_FILETYPE_PEM);
|
||||
if (r <= 0) {
|
||||
showError("could not use ssl certificate");
|
||||
showError("could not use tls certificate");
|
||||
return false;
|
||||
}
|
||||
|
||||
r = SSL_CTX_use_PrivateKey_file(m_ssl->m_context, filename.c_str(), SSL_FILETYPE_PEM);
|
||||
if (r <= 0) {
|
||||
showError("could not use ssl private key");
|
||||
showError("could not use tls private key");
|
||||
return false;
|
||||
}
|
||||
|
||||
r = SSL_CTX_check_private_key(m_ssl->m_context);
|
||||
if (!r) {
|
||||
showError("could not verify ssl private key");
|
||||
showError("could not verify tls private key");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -375,21 +380,23 @@ SecureSocket::initContext(bool server)
|
||||
showSecureLibInfo();
|
||||
}
|
||||
|
||||
// SSLv23_method uses TLSv1, with the ability to fall back to SSLv3
|
||||
// only use TLS 1.2 (latest as of 27 jul 18). previously we were using
|
||||
// the SSLv23_server_method and SSLv23_client_method functions with
|
||||
// SSL_OP_NO_SSLv3, but not SSL_OP_NO_SSLv2, so there was a potential
|
||||
// vulnerability where it could fall back to SSLv2 (not TLS). also,
|
||||
// the SSLv23_*_method functions could fall back to TLS 1.0 and 1.1,
|
||||
// which are nolonger PCI compliant.
|
||||
if (server) {
|
||||
method = SSLv23_server_method();
|
||||
method = TLSv1_2_server_method();
|
||||
}
|
||||
else {
|
||||
method = SSLv23_client_method();
|
||||
method = TLSv1_2_client_method();
|
||||
}
|
||||
|
||||
// create new context from method
|
||||
SSL_METHOD* m = const_cast<SSL_METHOD*>(method);
|
||||
m_ssl->m_context = SSL_CTX_new(m);
|
||||
|
||||
// drop SSLv3 support
|
||||
SSL_CTX_set_options(m_ssl->m_context, SSL_OP_NO_SSLv3);
|
||||
|
||||
if (m_ssl->m_context == NULL) {
|
||||
showError();
|
||||
}
|
||||
@@ -423,7 +430,7 @@ SecureSocket::secureAccept(int socket)
|
||||
if (isFatal()) {
|
||||
// tell user and sleep so the socket isn't hammered.
|
||||
LOG((CLOG_ERR "failed to accept secure socket"));
|
||||
LOG((CLOG_INFO "client connection may not be secure"));
|
||||
LOG((CLOG_WARN "client connection may not be secure"));
|
||||
m_secureReady = false;
|
||||
ARCH->sleep(1);
|
||||
retry = 0;
|
||||
@@ -516,12 +523,12 @@ SecureSocket::showCertificate()
|
||||
cert = SSL_get_peer_certificate(m_ssl->m_ssl);
|
||||
if (cert != NULL) {
|
||||
line = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0);
|
||||
LOG((CLOG_INFO "server ssl certificate info: %s", line));
|
||||
LOG((CLOG_INFO "server tls certificate info: %s", line));
|
||||
OPENSSL_free(line);
|
||||
X509_free(cert);
|
||||
}
|
||||
else {
|
||||
showError("server has no ssl certificate");
|
||||
showError("server has no tls certificate");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -545,7 +552,7 @@ SecureSocket::checkResult(int status, int& retry)
|
||||
case SSL_ERROR_ZERO_RETURN:
|
||||
// connection closed
|
||||
isFatal(true);
|
||||
LOG((CLOG_DEBUG "ssl connection closed"));
|
||||
LOG((CLOG_DEBUG "tls connection closed"));
|
||||
break;
|
||||
|
||||
case SSL_ERROR_WANT_READ:
|
||||
@@ -573,10 +580,10 @@ SecureSocket::checkResult(int status, int& retry)
|
||||
break;
|
||||
|
||||
case SSL_ERROR_SYSCALL:
|
||||
LOG((CLOG_ERR "ssl error occurred (system call failure)"));
|
||||
LOG((CLOG_ERR "tls error occurred (system call failure)"));
|
||||
if (ERR_peek_error() == 0) {
|
||||
if (status == 0) {
|
||||
LOG((CLOG_ERR "eof violates ssl protocol"));
|
||||
LOG((CLOG_ERR "eof violates tls protocol"));
|
||||
}
|
||||
else if (status == -1) {
|
||||
// underlying socket I/O reproted an error
|
||||
@@ -593,12 +600,12 @@ SecureSocket::checkResult(int status, int& retry)
|
||||
break;
|
||||
|
||||
case SSL_ERROR_SSL:
|
||||
LOG((CLOG_ERR "ssl error occurred (generic failure)"));
|
||||
LOG((CLOG_ERR "tls error occurred (generic failure)"));
|
||||
isFatal(true);
|
||||
break;
|
||||
|
||||
default:
|
||||
LOG((CLOG_ERR "ssl error occurred (unknown failure)"));
|
||||
LOG((CLOG_ERR "tls error occurred (unknown failure)"));
|
||||
isFatal(true);
|
||||
break;
|
||||
}
|
||||
@@ -614,12 +621,12 @@ void
|
||||
SecureSocket::showError(const char* reason)
|
||||
{
|
||||
if (reason != NULL) {
|
||||
LOG((CLOG_ERR "%s", reason));
|
||||
LOG((CLOG_ERR "secure socket error: %s", reason));
|
||||
}
|
||||
|
||||
String error = getError();
|
||||
if (!error.empty()) {
|
||||
LOG((CLOG_ERR "%s", error.c_str()));
|
||||
LOG((CLOG_ERR "openssl error: %s", error.c_str()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -826,11 +833,11 @@ SecureSocket::showSecureCipherInfo()
|
||||
void
|
||||
SecureSocket::showSecureLibInfo()
|
||||
{
|
||||
LOG((CLOG_INFO "%s",SSLeay_version(SSLEAY_VERSION)));
|
||||
LOG((CLOG_DEBUG1 "openSSL : %s",SSLeay_version(SSLEAY_CFLAGS)));
|
||||
LOG((CLOG_DEBUG1 "openSSL : %s",SSLeay_version(SSLEAY_BUILT_ON)));
|
||||
LOG((CLOG_DEBUG1 "openSSL : %s",SSLeay_version(SSLEAY_PLATFORM)));
|
||||
LOG((CLOG_DEBUG1 "%s",SSLeay_version(SSLEAY_DIR)));
|
||||
LOG((CLOG_DEBUG "openssl version: %s", SSLeay_version(SSLEAY_VERSION)));
|
||||
LOG((CLOG_DEBUG1 "openssl flags: %s", SSLeay_version(SSLEAY_CFLAGS)));
|
||||
LOG((CLOG_DEBUG1 "openssl built on: %s", SSLeay_version(SSLEAY_BUILT_ON)));
|
||||
LOG((CLOG_DEBUG1 "openssl platform: %s", SSLeay_version(SSLEAY_PLATFORM)));
|
||||
LOG((CLOG_DEBUG1 "openssl dir: %s", SSLeay_version(SSLEAY_DIR)));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -842,8 +849,16 @@ SecureSocket::showSecureConnectInfo()
|
||||
if (cipher != NULL) {
|
||||
char msg[kMsgSize];
|
||||
SSL_CIPHER_description(cipher, msg, kMsgSize);
|
||||
LOG((CLOG_INFO "%s", msg));
|
||||
LOG((CLOG_DEBUG "openssl cipher: %s", msg));
|
||||
|
||||
// show user a simpler version of the openssl cipher output
|
||||
if (std::string(msg).find(k_tlsString) != std::string::npos) {
|
||||
LOG((CLOG_INFO "network encryption protocol: %s", k_tlsString));
|
||||
}
|
||||
}
|
||||
else {
|
||||
LOG((CLOG_ERR "could not get secure socket cipher"));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -337,7 +337,7 @@ TCPSocket::doRead()
|
||||
|
||||
// slurp up as much as possible
|
||||
do {
|
||||
m_inputBuffer.write(buffer, bytesRead);
|
||||
m_inputBuffer.write(buffer, static_cast<UInt32>(bytesRead));
|
||||
|
||||
bytesRead = ARCH->readSocket(m_socket, buffer, sizeof(buffer));
|
||||
} while (bytesRead > 0);
|
||||
|
||||
@@ -47,6 +47,9 @@
|
||||
#include <comutil.h>
|
||||
#include <algorithm>
|
||||
|
||||
// suppress warning about GetVersionEx, which is used indirectly in this compilation unit.
|
||||
#pragma warning(disable: 4996)
|
||||
|
||||
//
|
||||
// add backwards compatible multihead support (and suppress bogus warning).
|
||||
// this isn't supported on MinGW yet AFAICT.
|
||||
|
||||
@@ -49,7 +49,8 @@ const char g_activeDesktop[] = {"activeDesktop:"};
|
||||
MSWindowsWatchdog::MSWindowsWatchdog(
|
||||
bool autoDetectCommand,
|
||||
IpcServer& ipcServer,
|
||||
IpcLogOutputter& ipcLogOutputter) :
|
||||
IpcLogOutputter& ipcLogOutputter,
|
||||
bool foreground) :
|
||||
m_thread(NULL),
|
||||
m_autoDetectCommand(autoDetectCommand),
|
||||
m_monitoring(true),
|
||||
@@ -63,7 +64,8 @@ MSWindowsWatchdog::MSWindowsWatchdog(
|
||||
m_processRunning(false),
|
||||
m_fileLogOutputter(NULL),
|
||||
m_autoElevated(false),
|
||||
m_ready(false)
|
||||
m_ready(false),
|
||||
m_foreground(foreground)
|
||||
{
|
||||
m_mutex = ARCH->newMutex();
|
||||
m_condVar = ARCH->newCondVar();
|
||||
@@ -105,104 +107,118 @@ MSWindowsWatchdog::stop()
|
||||
HANDLE
|
||||
MSWindowsWatchdog::duplicateProcessToken(HANDLE process, LPSECURITY_ATTRIBUTES security)
|
||||
{
|
||||
HANDLE sourceToken;
|
||||
HANDLE sourceToken;
|
||||
|
||||
BOOL tokenRet = OpenProcessToken(
|
||||
process,
|
||||
TOKEN_ASSIGN_PRIMARY | TOKEN_ALL_ACCESS,
|
||||
&sourceToken);
|
||||
BOOL tokenRet = OpenProcessToken(
|
||||
process,
|
||||
TOKEN_ASSIGN_PRIMARY | TOKEN_ALL_ACCESS,
|
||||
&sourceToken);
|
||||
|
||||
if (!tokenRet) {
|
||||
LOG((CLOG_ERR "could not open token, process handle: %d", process));
|
||||
throw XArch(new XArchEvalWindows());
|
||||
}
|
||||
|
||||
LOG((CLOG_DEBUG "got token %i, duplicating", sourceToken));
|
||||
if (!tokenRet) {
|
||||
LOG((CLOG_ERR "could not open token, process handle: %d", process));
|
||||
throw XArch(new XArchEvalWindows());
|
||||
}
|
||||
|
||||
HANDLE newToken;
|
||||
BOOL duplicateRet = DuplicateTokenEx(
|
||||
sourceToken, TOKEN_ASSIGN_PRIMARY | TOKEN_ALL_ACCESS, security,
|
||||
SecurityImpersonation, TokenPrimary, &newToken);
|
||||
LOG((CLOG_DEBUG "got token %i, duplicating", sourceToken));
|
||||
|
||||
if (!duplicateRet) {
|
||||
LOG((CLOG_ERR "could not duplicate token %i", sourceToken));
|
||||
throw XArch(new XArchEvalWindows());
|
||||
}
|
||||
|
||||
LOG((CLOG_DEBUG "duplicated, new token: %i", newToken));
|
||||
return newToken;
|
||||
HANDLE newToken;
|
||||
BOOL duplicateRet = DuplicateTokenEx(
|
||||
sourceToken, TOKEN_ASSIGN_PRIMARY | TOKEN_ALL_ACCESS, security,
|
||||
SecurityImpersonation, TokenPrimary, &newToken);
|
||||
|
||||
if (!duplicateRet) {
|
||||
LOG((CLOG_ERR "could not duplicate token %i", sourceToken));
|
||||
throw XArch(new XArchEvalWindows());
|
||||
}
|
||||
|
||||
LOG((CLOG_DEBUG "duplicated, new token: %i", newToken));
|
||||
return newToken;
|
||||
}
|
||||
|
||||
HANDLE
|
||||
HANDLE
|
||||
MSWindowsWatchdog::getUserToken(LPSECURITY_ATTRIBUTES security)
|
||||
{
|
||||
// always elevate if we are at the vista/7 login screen. we could also
|
||||
// elevate for the uac dialog (consent.exe) but this would be pointless,
|
||||
// since synergy would re-launch as non-elevated after the desk switch,
|
||||
// and so would be unusable with the new elevated process taking focus.
|
||||
if (m_elevateProcess
|
||||
|| m_autoElevated
|
||||
|| m_session.isProcessInSession("logonui.exe", NULL)) {
|
||||
|
||||
LOG((CLOG_DEBUG "getting elevated token, %s",
|
||||
(m_elevateProcess ? "elevation required" : "at login screen")));
|
||||
|
||||
HANDLE process;
|
||||
if (!m_session.isProcessInSession("winlogon.exe", &process)) {
|
||||
throw XMSWindowsWatchdogError("cannot get user token without winlogon.exe");
|
||||
}
|
||||
// always elevate if we are at the vista/7 login screen. we could also
|
||||
// elevate for the uac dialog (consent.exe) but this would be pointless,
|
||||
// since synergy would re-launch as non-elevated after the desk switch,
|
||||
// and so would be unusable with the new elevated process taking focus.
|
||||
if (m_elevateProcess
|
||||
|| m_autoElevated
|
||||
|| m_session.isProcessInSession("logonui.exe", NULL)) {
|
||||
|
||||
return duplicateProcessToken(process, security);
|
||||
}
|
||||
else {
|
||||
LOG((CLOG_DEBUG "getting non-elevated token"));
|
||||
return m_session.getUserToken(security);
|
||||
}
|
||||
LOG((CLOG_DEBUG "getting elevated token, %s",
|
||||
(m_elevateProcess ? "elevation required" : "at login screen")));
|
||||
|
||||
HANDLE process;
|
||||
if (!m_session.isProcessInSession("winlogon.exe", &process)) {
|
||||
throw XMSWindowsWatchdogError("cannot get user token without winlogon.exe");
|
||||
}
|
||||
|
||||
return duplicateProcessToken(process, security);
|
||||
}
|
||||
else {
|
||||
LOG((CLOG_DEBUG "getting non-elevated token"));
|
||||
return m_session.getUserToken(security);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MSWindowsWatchdog::mainLoop(void*)
|
||||
{
|
||||
shutdownExistingProcesses();
|
||||
shutdownExistingProcesses();
|
||||
|
||||
SendSas sendSasFunc = NULL;
|
||||
HINSTANCE sasLib = LoadLibrary("sas.dll");
|
||||
if (sasLib) {
|
||||
LOG((CLOG_DEBUG "found sas.dll"));
|
||||
sendSasFunc = (SendSas)GetProcAddress(sasLib, "SendSAS");
|
||||
}
|
||||
SendSas sendSasFunc = NULL;
|
||||
HINSTANCE sasLib = LoadLibrary("sas.dll");
|
||||
if (sasLib) {
|
||||
LOG((CLOG_DEBUG "found sas.dll"));
|
||||
sendSasFunc = (SendSas)GetProcAddress(sasLib, "SendSAS");
|
||||
}
|
||||
|
||||
SECURITY_ATTRIBUTES saAttr;
|
||||
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
|
||||
saAttr.bInheritHandle = TRUE;
|
||||
saAttr.lpSecurityDescriptor = NULL;
|
||||
SECURITY_ATTRIBUTES saAttr;
|
||||
saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
|
||||
saAttr.bInheritHandle = TRUE;
|
||||
saAttr.lpSecurityDescriptor = NULL;
|
||||
|
||||
if (!CreatePipe(&m_stdOutRead, &m_stdOutWrite, &saAttr, 0)) {
|
||||
throw XArch(new XArchEvalWindows());
|
||||
}
|
||||
if (!CreatePipe(&m_stdOutRead, &m_stdOutWrite, &saAttr, 0)) {
|
||||
throw XArch(new XArchEvalWindows());
|
||||
}
|
||||
|
||||
ZeroMemory(&m_processInfo, sizeof(PROCESS_INFORMATION));
|
||||
ZeroMemory(&m_processInfo, sizeof(PROCESS_INFORMATION));
|
||||
|
||||
while (m_monitoring) {
|
||||
try {
|
||||
while (m_monitoring) {
|
||||
try {
|
||||
|
||||
if (m_processRunning && getCommand().empty()) {
|
||||
LOG((CLOG_INFO "process started but command is empty, shutting down"));
|
||||
shutdownExistingProcesses();
|
||||
m_processRunning = false;
|
||||
continue;
|
||||
}
|
||||
if (m_processRunning && getCommand().empty()) {
|
||||
LOG((CLOG_INFO "process started but command is empty, shutting down"));
|
||||
shutdownExistingProcesses();
|
||||
m_processRunning = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (m_processFailures != 0) {
|
||||
// increasing backoff period, maximum of 10 seconds.
|
||||
int timeout = (m_processFailures * 2) < 10 ? (m_processFailures * 2) : 10;
|
||||
LOG((CLOG_INFO "backing off, wait=%ds, failures=%d", timeout, m_processFailures));
|
||||
ARCH->sleep(timeout);
|
||||
}
|
||||
|
||||
if (!getCommand().empty() && ((m_processFailures != 0) || m_session.hasChanged() || m_commandChanged)) {
|
||||
startProcess();
|
||||
}
|
||||
if (m_processFailures != 0) {
|
||||
// increasing backoff period, maximum of 10 seconds.
|
||||
int timeout = (m_processFailures * 2) < 10 ? (m_processFailures * 2) : 10;
|
||||
LOG((CLOG_INFO "backing off, wait=%ds, failures=%d", timeout, m_processFailures));
|
||||
ARCH->sleep(timeout);
|
||||
}
|
||||
|
||||
if (!getCommand().empty()) {
|
||||
bool startNeeded = false;
|
||||
|
||||
if (m_processFailures != 0) {
|
||||
startNeeded = true;
|
||||
}
|
||||
else if (!m_foreground && m_session.hasChanged()) {
|
||||
startNeeded = true;
|
||||
}
|
||||
else if (m_commandChanged) {
|
||||
startNeeded = true;
|
||||
}
|
||||
|
||||
if (startNeeded) {
|
||||
startProcess();
|
||||
}
|
||||
}
|
||||
|
||||
if (m_processRunning && !isProcessActive()) {
|
||||
|
||||
@@ -284,28 +300,35 @@ MSWindowsWatchdog::startProcess()
|
||||
m_processRunning = false;
|
||||
}
|
||||
|
||||
m_session.updateActiveSession();
|
||||
BOOL createRet;
|
||||
if (m_foreground) {
|
||||
LOG((CLOG_DEBUG "starting command in foreground"));
|
||||
createRet = startProcessInForeground(m_command);
|
||||
}
|
||||
else {
|
||||
LOG((CLOG_DEBUG "starting command as session user"));
|
||||
m_session.updateActiveSession();
|
||||
|
||||
SECURITY_ATTRIBUTES sa;
|
||||
ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES));
|
||||
SECURITY_ATTRIBUTES sa;
|
||||
ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES));
|
||||
|
||||
getActiveDesktop(&sa);
|
||||
getActiveDesktop(&sa);
|
||||
|
||||
ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES));
|
||||
HANDLE userToken = getUserToken(&sa);
|
||||
m_elevateProcess = m_autoElevated ? m_autoElevated : m_elevateProcess;
|
||||
m_autoElevated = false;
|
||||
ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES));
|
||||
HANDLE userToken = getUserToken(&sa);
|
||||
m_elevateProcess = m_autoElevated ? m_autoElevated : m_elevateProcess;
|
||||
m_autoElevated = false;
|
||||
|
||||
// patch by Jack Zhou and Henry Tung
|
||||
// set UIAccess to fix Windows 8 GUI interaction
|
||||
// http://symless.com/spit/issues/details/3338/#c70
|
||||
DWORD uiAccess = 1;
|
||||
SetTokenInformation(userToken, TokenUIAccess, &uiAccess, sizeof(DWORD));
|
||||
// patch by Jack Zhou and Henry Tung
|
||||
// set UIAccess to fix Windows 8 GUI interaction
|
||||
DWORD uiAccess = 1;
|
||||
SetTokenInformation(userToken, TokenUIAccess, &uiAccess, sizeof(DWORD));
|
||||
|
||||
BOOL createRet = doStartProcess(m_command, userToken, &sa);
|
||||
createRet = startProcessAsUser(m_command, userToken, &sa);
|
||||
}
|
||||
|
||||
if (!createRet) {
|
||||
LOG((CLOG_ERR "could not launch"));
|
||||
LOG((CLOG_ERR "could not launch command"));
|
||||
DWORD exitCode = 0;
|
||||
GetExitCodeProcess(m_processInfo.hProcess, &exitCode);
|
||||
LOG((CLOG_ERR "exit code: %d", exitCode));
|
||||
@@ -328,19 +351,44 @@ MSWindowsWatchdog::startProcess()
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
MSWindowsWatchdog::setStartupInfo(STARTUPINFO& si)
|
||||
{
|
||||
ZeroMemory(&si, sizeof(STARTUPINFO));
|
||||
si.cb = sizeof(STARTUPINFO);
|
||||
si.lpDesktop = "winsta0\\Default"; // TODO: maybe this should be \winlogon if we have logonui.exe?
|
||||
si.hStdError = m_stdOutWrite;
|
||||
si.hStdOutput = m_stdOutWrite;
|
||||
si.dwFlags |= STARTF_USESTDHANDLES;
|
||||
}
|
||||
|
||||
BOOL
|
||||
MSWindowsWatchdog::doStartProcess(String& command, HANDLE userToken, LPSECURITY_ATTRIBUTES sa)
|
||||
MSWindowsWatchdog::startProcessInForeground(String& command)
|
||||
{
|
||||
// clear, as we're reusing process info struct
|
||||
ZeroMemory(&m_processInfo, sizeof(PROCESS_INFORMATION));
|
||||
|
||||
// show the console window when in foreground mode,
|
||||
// so we can close it gracefully, but minimize it
|
||||
// so it doesn't get in the way.
|
||||
STARTUPINFO si;
|
||||
setStartupInfo(si);
|
||||
si.dwFlags |= STARTF_USESHOWWINDOW;
|
||||
si.wShowWindow = SW_MINIMIZE;
|
||||
|
||||
return CreateProcess(
|
||||
NULL, LPSTR(command.c_str()), NULL, NULL,
|
||||
TRUE, 0, NULL, NULL, &si, &m_processInfo);
|
||||
}
|
||||
|
||||
BOOL
|
||||
MSWindowsWatchdog::startProcessAsUser(String& command, HANDLE userToken, LPSECURITY_ATTRIBUTES sa)
|
||||
{
|
||||
// clear, as we're reusing process info struct
|
||||
ZeroMemory(&m_processInfo, sizeof(PROCESS_INFORMATION));
|
||||
|
||||
STARTUPINFO si;
|
||||
ZeroMemory(&si, sizeof(STARTUPINFO));
|
||||
si.cb = sizeof(STARTUPINFO);
|
||||
si.lpDesktop = "winsta0\\Default"; // TODO: maybe this should be \winlogon if we have logonui.exe?
|
||||
si.hStdError = m_stdOutWrite;
|
||||
si.hStdOutput = m_stdOutWrite;
|
||||
si.dwFlags |= STARTF_USESTDHANDLES;
|
||||
setStartupInfo(si);
|
||||
|
||||
LPVOID environment;
|
||||
BOOL blockRet = CreateEnvironmentBlock(&environment, userToken, FALSE);
|
||||
@@ -429,6 +477,16 @@ MSWindowsWatchdog::outputLoop(void*)
|
||||
if (m_fileLogOutputter != NULL) {
|
||||
m_fileLogOutputter->write(kINFO, buffer);
|
||||
}
|
||||
|
||||
#if SYSAPI_WIN32
|
||||
if (m_foreground) {
|
||||
// when in foreground mode (useful for debugging), send the core
|
||||
// process output to the VS debug output window.
|
||||
// we could use the MSWindowsDebugOutputter, but it's really fiddly to so,
|
||||
// and there doesn't seem to be an advantage of doing that.
|
||||
OutputDebugString(buffer);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -452,7 +510,7 @@ MSWindowsWatchdog::shutdownProcess(HANDLE handle, DWORD pid, int timeout)
|
||||
GetExitCodeProcess(handle, &exitCode);
|
||||
if (exitCode != STILL_ACTIVE) {
|
||||
// yay, we got a graceful shutdown. there should be no hook in use errors!
|
||||
LOG((CLOG_INFO "process %d was shutdown gracefully", pid));
|
||||
LOG((CLOG_DEBUG "process %d was shutdown gracefully", pid));
|
||||
break;
|
||||
}
|
||||
else {
|
||||
@@ -542,7 +600,7 @@ MSWindowsWatchdog::getActiveDesktop(LPSECURITY_ATTRIBUTES security)
|
||||
HANDLE userToken = getUserToken(security);
|
||||
m_elevateProcess = elevateProcess;
|
||||
|
||||
BOOL createRet = doStartProcess(syntoolCommand, userToken, security);
|
||||
BOOL createRet = startProcessAsUser(syntoolCommand, userToken, security);
|
||||
|
||||
if (!createRet) {
|
||||
DWORD rc = GetLastError();
|
||||
|
||||
@@ -37,7 +37,8 @@ public:
|
||||
MSWindowsWatchdog(
|
||||
bool autoDetectCommand,
|
||||
IpcServer& ipcServer,
|
||||
IpcLogOutputter& ipcLogOutputter);
|
||||
IpcLogOutputter& ipcLogOutputter,
|
||||
bool foreground);
|
||||
virtual ~MSWindowsWatchdog();
|
||||
|
||||
void startAsync();
|
||||
@@ -55,10 +56,12 @@ private:
|
||||
HANDLE duplicateProcessToken(HANDLE process, LPSECURITY_ATTRIBUTES security);
|
||||
HANDLE getUserToken(LPSECURITY_ATTRIBUTES security);
|
||||
void startProcess();
|
||||
BOOL doStartProcess(String& command, HANDLE userToken, LPSECURITY_ATTRIBUTES sa);
|
||||
BOOL startProcessAsUser(String& command, HANDLE userToken, LPSECURITY_ATTRIBUTES sa);
|
||||
BOOL startProcessInForeground(String& command);
|
||||
void sendSas();
|
||||
void getActiveDesktop(LPSECURITY_ATTRIBUTES security);
|
||||
void testOutput(String buffer);
|
||||
void setStartupInfo(STARTUPINFO& si);
|
||||
|
||||
private:
|
||||
Thread* m_thread;
|
||||
@@ -81,6 +84,7 @@ private:
|
||||
ArchMutex m_mutex;
|
||||
ArchCond m_condVar;
|
||||
bool m_ready;
|
||||
bool m_foreground;
|
||||
};
|
||||
|
||||
//! Relauncher error
|
||||
|
||||
@@ -118,7 +118,7 @@ private:
|
||||
void sendClipboardEvent(Event::Type type, ClipboardID id) const;
|
||||
|
||||
// message handlers
|
||||
bool onMouseMove(SInt32 mx, SInt32 my);
|
||||
bool onMouseMove(CGFloat mx, CGFloat my);
|
||||
// mouse button handler. pressed is true if this is a mousedown
|
||||
// event, false if it is a mouseup event. macButton is the index
|
||||
// of the button pressed using the mac button mapping.
|
||||
|
||||
@@ -1080,20 +1080,20 @@ OSXScreen::handleSystemEvent(const Event& event, void*)
|
||||
}
|
||||
|
||||
bool
|
||||
OSXScreen::onMouseMove(SInt32 mx, SInt32 my)
|
||||
OSXScreen::onMouseMove(CGFloat mx, CGFloat my)
|
||||
{
|
||||
LOG((CLOG_DEBUG2 "mouse move %+d,%+d", mx, my));
|
||||
LOG((CLOG_DEBUG2 "mouse move %+f,%+f", mx, my));
|
||||
|
||||
SInt32 x = mx - m_xCursor;
|
||||
SInt32 y = my - m_yCursor;
|
||||
CGFloat x = mx - m_xCursor;
|
||||
CGFloat y = my - m_yCursor;
|
||||
|
||||
if ((x == 0 && y == 0) || (mx == m_xCenter && mx == m_yCenter)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// save position to compute delta of next motion
|
||||
m_xCursor = mx;
|
||||
m_yCursor = my;
|
||||
m_xCursor = (SInt32)mx;
|
||||
m_yCursor = (SInt32)my;
|
||||
|
||||
if (m_isOnScreen) {
|
||||
// motion on primary screen
|
||||
@@ -1122,7 +1122,21 @@ OSXScreen::onMouseMove(SInt32 mx, SInt32 my)
|
||||
}
|
||||
else {
|
||||
// send motion
|
||||
sendEvent(m_events->forIPrimaryScreen().motionOnSecondary(), MotionInfo::alloc(x, y));
|
||||
// Accumulate together the move into the running total
|
||||
static CGFloat m_xFractionalMove = 0;
|
||||
static CGFloat m_yFractionalMove = 0;
|
||||
|
||||
m_xFractionalMove += x;
|
||||
m_yFractionalMove += y;
|
||||
|
||||
// Return the integer part
|
||||
SInt32 intX = (SInt32)m_xFractionalMove;
|
||||
SInt32 intY = (SInt32)m_yFractionalMove;
|
||||
|
||||
// And keep only the fractional part
|
||||
m_xFractionalMove -= intX;
|
||||
m_yFractionalMove -= intY;
|
||||
sendEvent(m_events->forIPrimaryScreen().motionOnSecondary(), MotionInfo::alloc(intX, intY));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -765,10 +765,15 @@ Config::readSectionOptions(ConfigReadContext& s)
|
||||
else if (name == "win32KeepForeground") {
|
||||
addOption("", kOptionWin32KeepForeground, s.parseBoolean(value));
|
||||
}
|
||||
else if (name == "disableLockToScreen") {
|
||||
addOption("", kOptionDisableLockToScreen, s.parseBoolean(value));
|
||||
}
|
||||
else if (name == "clipboardSharing") {
|
||||
addOption("", kOptionClipboardSharing, s.parseBoolean(value));
|
||||
}
|
||||
|
||||
else if (name == "clipboardSharingSize") {
|
||||
addOption("", kOptionClipboardSharingSize, s.parseInt(value));
|
||||
}
|
||||
else {
|
||||
handled = false;
|
||||
}
|
||||
@@ -1380,9 +1385,15 @@ Config::getOptionName(OptionID id)
|
||||
if (id == kOptionScreenPreserveFocus) {
|
||||
return "preserveFocus";
|
||||
}
|
||||
if (id == kOptionDisableLockToScreen) {
|
||||
return "disableLockToScreen";
|
||||
}
|
||||
if (id == kOptionClipboardSharing) {
|
||||
return "clipboardSharing";
|
||||
}
|
||||
if (id == kOptionClipboardSharingSize) {
|
||||
return "clipboardSharingSize";
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -1400,7 +1411,8 @@ Config::getOptionValue(OptionID id, OptionValue value)
|
||||
id == kOptionRelativeMouseMoves ||
|
||||
id == kOptionWin32KeepForeground ||
|
||||
id == kOptionScreenPreserveFocus ||
|
||||
id == kOptionClipboardSharing) {
|
||||
id == kOptionClipboardSharing ||
|
||||
id == kOptionClipboardSharingSize) {
|
||||
return (value != 0) ? "true" : "false";
|
||||
}
|
||||
if (id == kOptionModifierMapForShift ||
|
||||
@@ -2111,7 +2123,9 @@ ConfigReadContext::parseInterval(const ArgList& args) const
|
||||
throw XConfigRead(*this, "invalid interval \"%{1}\"", concatArgs(args));
|
||||
}
|
||||
|
||||
return Config::Interval(startValue / 100.0f, endValue / 100.0f);
|
||||
float startInterval = static_cast<float>(startValue / 100.0f);
|
||||
float endInterval = static_cast<float>(endValue / 100.0f);
|
||||
return Config::Interval(startInterval, endInterval);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -51,6 +51,7 @@
|
||||
#include <sstream>
|
||||
#include <fstream>
|
||||
#include <ctime>
|
||||
#include <climits>
|
||||
|
||||
//
|
||||
// Server
|
||||
@@ -92,7 +93,9 @@ Server::Server(
|
||||
m_sendFileThread(NULL),
|
||||
m_writeToDropDirThread(NULL),
|
||||
m_ignoreFileTransfer(false),
|
||||
m_disableLockToScreen(false),
|
||||
m_enableClipboard(true),
|
||||
m_maximumClipboardSize(INT_MAX),
|
||||
m_sendDragInfoThread(NULL),
|
||||
m_waitDragInfoThread(true),
|
||||
m_args(args)
|
||||
@@ -289,7 +292,7 @@ Server::setConfig(const Config& config)
|
||||
// we will unfortunately generate a warning. if the user has
|
||||
// configured a LockCursorToScreenAction then we don't add
|
||||
// ScrollLock as a hotkey.
|
||||
if (!m_config->hasLockToScreenAction()) {
|
||||
if (!m_disableLockToScreen && !m_config->hasLockToScreenAction()) {
|
||||
IPlatformScreen::KeyInfo* key =
|
||||
IPlatformScreen::KeyInfo::alloc(kKeyScrollLock, 0, 0, 0);
|
||||
InputFilter::Rule rule(new InputFilter::KeystrokeCondition(m_events, key));
|
||||
@@ -421,6 +424,10 @@ Server::isLockedToScreenServer() const
|
||||
bool
|
||||
Server::isLockedToScreen() const
|
||||
{
|
||||
if (m_disableLockToScreen) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// locked if we say we're locked
|
||||
if (isLockedToScreenServer()) {
|
||||
LOG((CLOG_NOTE "Cursor is locked to screen, check Scroll Lock key"));
|
||||
@@ -518,6 +525,10 @@ Server::switchScreen(BaseClientProxy* dst,
|
||||
if (m_enableClipboard) {
|
||||
// send the clipboard data to new active screen
|
||||
for (ClipboardID id = 0; id < kClipboardEnd; ++id) {
|
||||
// Hackity hackity hack
|
||||
if (m_clipboards[id].m_clipboard.marshall().size() > (m_maximumClipboardSize * 1024)) {
|
||||
continue;
|
||||
}
|
||||
m_active->setClipboard(id, &m_clipboards[id].m_clipboard);
|
||||
}
|
||||
}
|
||||
@@ -1177,13 +1188,24 @@ Server::processOptions()
|
||||
else if (id == kOptionRelativeMouseMoves) {
|
||||
newRelativeMoves = (value != 0);
|
||||
}
|
||||
else if (id == kOptionDisableLockToScreen) {
|
||||
m_disableLockToScreen = (value != 0);
|
||||
}
|
||||
else if (id == kOptionClipboardSharing) {
|
||||
m_enableClipboard = (value != 0);
|
||||
|
||||
if (m_enableClipboard == false) {
|
||||
m_enableClipboard = value;
|
||||
if (!m_enableClipboard) {
|
||||
LOG((CLOG_NOTE "clipboard sharing is disabled"));
|
||||
}
|
||||
}
|
||||
else if (id == kOptionClipboardSharingSize) {
|
||||
if (value <= 0) {
|
||||
m_maximumClipboardSize = 0;
|
||||
LOG((CLOG_NOTE "clipboard sharing is disabled because the "
|
||||
"maximum shared clipboard size is set to 0"));
|
||||
} else {
|
||||
m_maximumClipboardSize = static_cast<size_t>(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (m_relativeMoves && !newRelativeMoves) {
|
||||
stopRelativeMoves();
|
||||
@@ -1227,7 +1249,7 @@ Server::handleShapeChanged(const Event&, void* vclient)
|
||||
void
|
||||
Server::handleClipboardGrabbed(const Event& event, void* vclient)
|
||||
{
|
||||
if (!m_enableClipboard) {
|
||||
if (!m_enableClipboard || (m_maximumClipboardSize == 0)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1542,6 +1564,12 @@ Server::onClipboardChanged(BaseClientProxy* sender,
|
||||
|
||||
// ignore if data hasn't changed
|
||||
String data = clipboard.m_clipboard.marshall();
|
||||
if (data.size() > m_maximumClipboardSize * 1024) {
|
||||
LOG((CLOG_NOTE "not updating clipboard because it's over the size limit (%i KB) configured by the server",
|
||||
m_maximumClipboardSize));
|
||||
return;
|
||||
}
|
||||
|
||||
if (data == clipboard.m_clipboardData) {
|
||||
LOG((CLOG_DEBUG "ignored screen \"%s\" update of clipboard %d (unchanged)", clipboard.m_clipboardOwner.c_str(), id));
|
||||
return;
|
||||
|
||||
@@ -473,7 +473,9 @@ private:
|
||||
Thread* m_writeToDropDirThread;
|
||||
String m_dragFileExt;
|
||||
bool m_ignoreFileTransfer;
|
||||
bool m_disableLockToScreen;
|
||||
bool m_enableClipboard;
|
||||
size_t m_maximumClipboardSize;
|
||||
|
||||
Thread* m_sendDragInfoThread;
|
||||
bool m_waitDragInfoThread;
|
||||
|
||||
@@ -60,7 +60,8 @@ SerialKey::isExpiring(time_t currentTime) const
|
||||
bool result = false;
|
||||
|
||||
if (m_trial) {
|
||||
if (m_warnTime <= currentTime && currentTime < m_expireTime) {
|
||||
unsigned long long currentTimeAsLL = static_cast<unsigned long long>(currentTime);
|
||||
if ((m_warnTime <= currentTimeAsLL) && (currentTimeAsLL < m_expireTime)) {
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
@@ -74,7 +75,8 @@ SerialKey::isExpired(time_t currentTime) const
|
||||
bool result = false;
|
||||
|
||||
if (m_trial) {
|
||||
if (m_expireTime <= currentTime) {
|
||||
unsigned long long currentTimeAsLL = static_cast<unsigned long long>(currentTime);
|
||||
if (m_expireTime <= currentTimeAsLL) {
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
@@ -150,8 +152,9 @@ SerialKey::daysLeft(time_t currentTime) const
|
||||
unsigned long long timeLeft = 0;
|
||||
unsigned long long const day = 60 * 60 * 24;
|
||||
|
||||
if (currentTime < m_expireTime) {
|
||||
timeLeft = m_expireTime - currentTime;
|
||||
unsigned long long currentTimeAsLL = static_cast<unsigned long long>(currentTime);
|
||||
if (currentTimeAsLL < m_expireTime) {
|
||||
timeLeft = m_expireTime - currentTimeAsLL;
|
||||
}
|
||||
|
||||
unsigned long long daysLeft = 0;
|
||||
|
||||
@@ -179,10 +179,6 @@ ArgParser::parseToolArgs(ToolArgs& args, int argc, const char* const* argv)
|
||||
args.m_printActiveDesktopName = true;
|
||||
return true;
|
||||
}
|
||||
else if (isArg(i, argc, argv, NULL, "--login-auth", 0)) {
|
||||
args.m_loginAuthenticate = true;
|
||||
return true;
|
||||
}
|
||||
else if (isArg(i, argc, argv, NULL, "--get-installed-dir", 0)) {
|
||||
args.m_getInstalledDir = true;
|
||||
return true;
|
||||
@@ -195,14 +191,6 @@ ArgParser::parseToolArgs(ToolArgs& args, int argc, const char* const* argv)
|
||||
args.m_getArch = true;
|
||||
return true;
|
||||
}
|
||||
else if (isArg(i, argc, argv, NULL, "--notify-activation", 0)) {
|
||||
args.m_notifyActivation = true;
|
||||
return true;
|
||||
}
|
||||
else if (isArg(i, argc, argv, NULL, "--notify-update", 0)) {
|
||||
args.m_notifyUpdate = true;
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -155,7 +155,7 @@ DaemonApp::run(int argc, char** argv)
|
||||
if (foreground) {
|
||||
// run process in foreground instead of daemonizing.
|
||||
// useful for debugging.
|
||||
mainLoop(false);
|
||||
mainLoop(false, foreground);
|
||||
}
|
||||
else {
|
||||
#if SYSAPI_WIN32
|
||||
@@ -192,7 +192,7 @@ DaemonApp::run(int argc, char** argv)
|
||||
}
|
||||
|
||||
void
|
||||
DaemonApp::mainLoop(bool logToFile)
|
||||
DaemonApp::mainLoop(bool logToFile, bool foreground)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -215,7 +215,7 @@ DaemonApp::mainLoop(bool logToFile)
|
||||
CLOG->insert(m_ipcLogOutputter);
|
||||
|
||||
#if SYSAPI_WIN32
|
||||
m_watchdog = new MSWindowsWatchdog(false, *m_ipcServer, *m_ipcLogOutputter);
|
||||
m_watchdog = new MSWindowsWatchdog(false, *m_ipcServer, *m_ipcLogOutputter, foreground);
|
||||
m_watchdog->setFileLogOutputter(m_fileLogOutputter);
|
||||
#endif
|
||||
|
||||
@@ -337,23 +337,6 @@ DaemonApp::handleIpcMessage(const Event& e, void*)
|
||||
LOG((CLOG_ERR "failed to save LogLevel setting, %s", e.what()));
|
||||
}
|
||||
}
|
||||
|
||||
#if SYSAPI_WIN32
|
||||
String logFilename;
|
||||
if (argBase->m_logFile != NULL) {
|
||||
logFilename = String(argBase->m_logFile);
|
||||
ARCH->setting("LogFilename", logFilename);
|
||||
m_watchdog->setFileLogOutputter(m_fileLogOutputter);
|
||||
command = ArgParser::assembleCommand(argsArray, "--log", 1);
|
||||
LOG((CLOG_DEBUG "removed log file argument and filename %s from command ", logFilename.c_str()));
|
||||
LOG((CLOG_DEBUG "new command, elevate=%d command=%s", cm->elevate(), command.c_str()));
|
||||
}
|
||||
else {
|
||||
m_watchdog->setFileLogOutputter(NULL);
|
||||
}
|
||||
|
||||
m_fileLogOutputter->setLogFilename(logFilename.c_str());
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
LOG((CLOG_DEBUG "empty command, elevate=%d", cm->elevate()));
|
||||
@@ -392,8 +375,8 @@ DaemonApp::handleIpcMessage(const Event& e, void*)
|
||||
LOG((CLOG_DEBUG "ipc hello, type=%s", type.c_str()));
|
||||
|
||||
#if SYSAPI_WIN32
|
||||
String watchdogStatus = m_watchdog->isProcessActive() ? "ok" : "error";
|
||||
LOG((CLOG_INFO "watchdog status: %s", watchdogStatus.c_str()));
|
||||
String watchdogStatus = m_watchdog->isProcessActive() ? "active" : "idle";
|
||||
LOG((CLOG_INFO "service status: %s", watchdogStatus.c_str()));
|
||||
#endif
|
||||
|
||||
m_ipcLogOutputter->notifyBuffer();
|
||||
|
||||
@@ -37,7 +37,7 @@ public:
|
||||
DaemonApp();
|
||||
virtual ~DaemonApp();
|
||||
int run(int argc, char** argv);
|
||||
void mainLoop(bool logToFile);
|
||||
void mainLoop(bool logToFile, bool foreground = false);
|
||||
|
||||
private:
|
||||
void daemonize();
|
||||
|
||||
@@ -304,11 +304,11 @@ ServerApp::closeServer(Server* server)
|
||||
void
|
||||
ServerApp::stopRetryTimer()
|
||||
{
|
||||
if (m_timer != NULL) {
|
||||
m_events->deleteTimer(m_timer);
|
||||
m_events->removeHandler(Event::kTimer, NULL);
|
||||
m_timer = NULL;
|
||||
}
|
||||
if (m_timer != NULL) {
|
||||
m_events->removeHandler(Event::kTimer, m_timer);
|
||||
m_events->deleteTimer(m_timer);
|
||||
m_timer = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -68,9 +68,6 @@ ToolApp::run(int argc, char** argv)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else if (m_args.m_loginAuthenticate) {
|
||||
loginAuth();
|
||||
}
|
||||
else if (m_args.m_getInstalledDir) {
|
||||
std::cout << ARCH->getInstalledDirectory() << std::endl;
|
||||
}
|
||||
@@ -80,12 +77,6 @@ ToolApp::run(int argc, char** argv)
|
||||
else if (m_args.m_getArch) {
|
||||
std::cout << ARCH->getPlatformName() << std::endl;
|
||||
}
|
||||
else if (m_args.m_notifyUpdate) {
|
||||
notifyUpdate();
|
||||
}
|
||||
else if (m_args.m_notifyActivation) {
|
||||
notifyActivation();
|
||||
}
|
||||
else {
|
||||
throw XSynergy("Nothing to do");
|
||||
}
|
||||
@@ -111,96 +102,3 @@ void
|
||||
ToolApp::help()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
ToolApp::loginAuth()
|
||||
{
|
||||
String credentials;
|
||||
std::cin >> credentials;
|
||||
|
||||
std::vector<String> parts = synergy::string::splitString(credentials, ':');
|
||||
size_t count = parts.size();
|
||||
|
||||
if (count == 2 ) {
|
||||
String email = parts[0];
|
||||
String password = parts[1];
|
||||
|
||||
std::stringstream ss;
|
||||
ss << JSON_URL << "auth/";
|
||||
ss << "?email=" << ARCH->internet().urlEncode(email);
|
||||
ss << "&password=" << password;
|
||||
|
||||
std::cout << ARCH->internet().get(ss.str()) << std::endl;
|
||||
}
|
||||
else {
|
||||
throw XSynergy("Invalid credentials.");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ToolApp::notifyUpdate()
|
||||
{
|
||||
String data;
|
||||
std::cin >> data;
|
||||
|
||||
std::vector<String> parts = synergy::string::splitString(data, ':');
|
||||
size_t count = parts.size();
|
||||
|
||||
if (count == 3) {
|
||||
std::stringstream ss;
|
||||
ss << JSON_URL << "notify/update";
|
||||
ss << "?from=" << parts[0];
|
||||
ss << "&to=" << parts[1];
|
||||
ss << "&serial=" << parts[2];
|
||||
|
||||
std::cout << ARCH->internet().get(ss.str()) << std::endl;
|
||||
}
|
||||
else {
|
||||
throw XSynergy("Invalid update data.");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ToolApp::notifyActivation()
|
||||
{
|
||||
String info;
|
||||
std::cin >> info;
|
||||
|
||||
std::vector<String> parts = synergy::string::splitString(info, ':');
|
||||
size_t count = parts.size();
|
||||
|
||||
if (count == 3 || count == 4) {
|
||||
String action = parts[0];
|
||||
String identity = parts[1];
|
||||
String macHash = parts[2];
|
||||
String os;
|
||||
|
||||
if (count == 4) {
|
||||
os = parts[3];
|
||||
}
|
||||
else {
|
||||
os = ARCH->getOSName();
|
||||
}
|
||||
|
||||
std::stringstream ss;
|
||||
ss << JSON_URL << "notify/";
|
||||
ss << "?action=" << action;
|
||||
ss << "&identity=" << ARCH->internet().urlEncode(identity);
|
||||
ss << "&mac=" << ARCH->internet().urlEncode(macHash);
|
||||
ss << "&os=" << ARCH->internet().urlEncode(ARCH->getOSName());
|
||||
ss << "&arch=" << ARCH->internet().urlEncode(ARCH->getPlatformName());
|
||||
|
||||
try {
|
||||
std::cout << ARCH->internet().get(ss.str()) << std::endl;
|
||||
}
|
||||
catch (std::exception& e) {
|
||||
LOG((CLOG_NOTE "An error occurred during notification: %s\n", e.what()));
|
||||
}
|
||||
catch (...) {
|
||||
LOG((CLOG_NOTE "An unknown error occurred during notification.\n"));
|
||||
}
|
||||
}
|
||||
else {
|
||||
LOG((CLOG_NOTE "notification failed"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,11 +19,8 @@
|
||||
|
||||
ToolArgs::ToolArgs() :
|
||||
m_printActiveDesktopName(false),
|
||||
m_loginAuthenticate(false),
|
||||
m_getInstalledDir(false),
|
||||
m_getProfileDir(false),
|
||||
m_getArch(false),
|
||||
m_notifyActivation(false),
|
||||
m_notifyUpdate(false)
|
||||
m_getArch(false)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -25,10 +25,7 @@ public:
|
||||
|
||||
public:
|
||||
bool m_printActiveDesktopName;
|
||||
bool m_loginAuthenticate;
|
||||
bool m_getInstalledDir;
|
||||
bool m_getProfileDir;
|
||||
bool m_getArch;
|
||||
bool m_notifyActivation;
|
||||
bool m_notifyUpdate;
|
||||
};
|
||||
|
||||
@@ -67,7 +67,9 @@ static const OptionID kOptionXTestXineramaUnaware = OPTION_CODE("XTXU"
|
||||
static const OptionID kOptionScreenPreserveFocus = OPTION_CODE("SFOC");
|
||||
static const OptionID kOptionRelativeMouseMoves = OPTION_CODE("MDLT");
|
||||
static const OptionID kOptionWin32KeepForeground = OPTION_CODE("_KFW");
|
||||
static const OptionID kOptionDisableLockToScreen = OPTION_CODE("DLTS");
|
||||
static const OptionID kOptionClipboardSharing = OPTION_CODE("CLPS");
|
||||
static const OptionID kOptionClipboardSharingSize = OPTION_CODE("CLSZ");
|
||||
//@}
|
||||
|
||||
//! @name Screen switch corner enumeration
|
||||
|
||||
Reference in New Issue
Block a user