Solve low hanging reliability and maintainability issues (#7403)
* Add missing atom ctor init * Init members with `None` * Use in-class init and delcare getter inside if init * Temp revert of changes ahead of unit test repair * Move IPC header to shared, restore X clipboard test, simplify test cmake, new X clipboard unit test * Suppress sonar for undefs * Remove base dir include * Revert "Temp revert of changes ahead of unit test repair" This reverts commit 8f84b6ea5d5828f1be1362de3809279bcacb8cc8. * Use new accessor * Use default dtor * Beef up to 32 core * Use enum class * Make IPC protocol headers const at all levels * Use enum class and const char for better type safety * Use unique_ptr for m_clipboard * Use `-j` instead of `-j8` to utilize full parallelism * Increase thread count for sonar-scanner * Use 32 threads * Use in-class init for IpcClientProxy members * Use const instead of #define * Remove ctor member inits * Use unique_ptr on win * Implement temp bin dir for windows with more robust post-build copy * Fixed missing iostream * Add warning about copy errors * Only run clean-gcda on Linux * Use in-class init for IPC mutex * Do no-op on Windows * Hide clean-gcda task * Move flakey test to integtests * Delete dead code * Test * Temp disable post_config_all * Disable post config step * Revert "Disable post config step" This reverts commit 2f956a7714ba9bedacd4b39d4ae00940c3d565d6. * Revert "Temp disable post_config_all" This reverts commit b44ed72e44f838bfe1309f6e9672d2f1c6f21b75. * Restore -j8 * Simplify error handling * Use const for test port * Remove python check * Update changelog * Fixed order * Fixed bad issue number * Fixed bin copy source path * Remove redundant except
This commit is contained in:
5
.github/workflows/sonarcloud-analysis.yml
vendored
5
.github/workflows/sonarcloud-analysis.yml
vendored
@ -19,7 +19,7 @@ jobs:
|
||||
sonarcloud-analysis:
|
||||
if: ${{ vars.SONAR_SCANNER_ENABLED }}
|
||||
|
||||
runs-on: ubuntu-24.04-16-core-x64
|
||||
runs-on: ubuntu-24.04-32-core-x64
|
||||
container: symless/synergy-core:ubuntu-22.04-amd64
|
||||
timeout-minutes: 20
|
||||
|
||||
@ -27,6 +27,7 @@ jobs:
|
||||
SONAR_SCANNER_VERSION: 6.1.0.4477
|
||||
SONAR_SCANNER_OPTS: -server
|
||||
SONAR_SCANNER_URL_BASE: https://binaries.sonarsource.com/Distribution/sonar-scanner-cli
|
||||
SONAR_SCANNER_THREADS: 32
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
@ -83,7 +84,7 @@ jobs:
|
||||
-Dsonar.cfamily.build-wrapper-output=bw-output \
|
||||
-Dsonar.host.url=https://sonarcloud.io \
|
||||
-Dsonar.coverageReportPaths=build/coverage.xml \
|
||||
-Dsonar.cfamily.threads=2
|
||||
-Dsonar.cfamily.threads=${{ env.SONAR_SCANNER_THREADS }}
|
||||
env:
|
||||
SONAR_TOKEN: ${{secrets.SONAR_TOKEN}}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,6 +1,5 @@
|
||||
# temp dirs created during build
|
||||
/build
|
||||
/bin
|
||||
/dist
|
||||
/deps
|
||||
/tmp
|
||||
|
||||
27
.vscode/tasks.json
vendored
27
.vscode/tasks.json
vendored
@ -14,9 +14,9 @@
|
||||
},
|
||||
{
|
||||
"type": "cmake",
|
||||
"label": "coverage",
|
||||
"label": "clean",
|
||||
"command": "build",
|
||||
"targets": ["coverage"],
|
||||
"targets": ["clean"],
|
||||
"preset": "${command:cmake.activeBuildPresetName}",
|
||||
"group": "build"
|
||||
},
|
||||
@ -32,6 +32,17 @@
|
||||
"command": "${workspaceFolder}/build/bin/synergy",
|
||||
"dependsOn": ["build"]
|
||||
},
|
||||
{
|
||||
"label": "clean-gcda",
|
||||
"type": "shell",
|
||||
"command": "find . -name '*.gcda' -delete",
|
||||
"windows": {
|
||||
"command": "$null" // no-op
|
||||
},
|
||||
"presentation": {
|
||||
"reveal": "silent"
|
||||
}
|
||||
},
|
||||
{
|
||||
"label": "unittests (current)",
|
||||
"type": "shell",
|
||||
@ -42,7 +53,7 @@
|
||||
"--ignore-return-code",
|
||||
"--filter-file=${file}"
|
||||
],
|
||||
"dependsOn": ["build"]
|
||||
"dependsOn": ["build", "clean-gcda"]
|
||||
},
|
||||
{
|
||||
"label": "integtests (current)",
|
||||
@ -54,21 +65,21 @@
|
||||
"--ignore-return-code",
|
||||
"--filter-file=${file}"
|
||||
],
|
||||
"dependsOn": ["build"]
|
||||
"dependsOn": ["build", "clean-gcda"]
|
||||
},
|
||||
{
|
||||
"label": "unittests (all)",
|
||||
"type": "shell",
|
||||
"command": "python",
|
||||
"args": ["./scripts/tests.py", "--unit-tests", "--ignore-return-code"],
|
||||
"dependsOn": ["build"]
|
||||
"dependsOn": ["build", "clean-gcda"]
|
||||
},
|
||||
{
|
||||
"label": "integtests (all)",
|
||||
"type": "shell",
|
||||
"command": "python",
|
||||
"args": ["./scripts/tests.py", "--integ-tests", "--ignore-return-code"],
|
||||
"dependsOn": ["build"]
|
||||
"dependsOn": ["build", "clean-gcda"]
|
||||
},
|
||||
{
|
||||
"label": "unittests (current, valgrind)",
|
||||
@ -81,7 +92,7 @@
|
||||
"--filter-file=${file}",
|
||||
"--valgrind"
|
||||
],
|
||||
"dependsOn": ["build"]
|
||||
"dependsOn": ["build", "clean-gcda"]
|
||||
},
|
||||
{
|
||||
"label": "integtests (current, valgrind)",
|
||||
@ -94,7 +105,7 @@
|
||||
"--filter-file=${file}",
|
||||
"--valgrind"
|
||||
],
|
||||
"dependsOn": ["build"]
|
||||
"dependsOn": ["build", "clean-gcda"]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@ -19,6 +19,7 @@ project(synergy-core C CXX)
|
||||
|
||||
include(cmake/Version.cmake)
|
||||
include(cmake/Definitions.cmake)
|
||||
include(cmake/Build.cmake)
|
||||
include(cmake/Libraries.cmake)
|
||||
include(cmake/Packaging.cmake)
|
||||
|
||||
@ -28,3 +29,5 @@ configure_libs()
|
||||
configure_packaging()
|
||||
|
||||
add_subdirectory(src)
|
||||
|
||||
post_config_all()
|
||||
|
||||
@ -24,7 +24,7 @@ Enhancements:
|
||||
- #7326 Restore lpDesktop assignment in Windows daemon
|
||||
- #7327 Only use Ninja to build on Windows
|
||||
- #7328 Reset error state before calling Process32Next
|
||||
- #1177 Split CMake presets into debug and release
|
||||
- #7330 Split CMake presets into debug and release
|
||||
- #7331 Script to install deps (Windows only for now)
|
||||
- #7332 Static link OpenSSL libs in CMake preset for Windows
|
||||
- #7333 Update VS Code config for Windows daemon debugging
|
||||
@ -50,10 +50,11 @@ Enhancements:
|
||||
- #7380 Add `qt6-qpa-plugins` Qt dependency for Debian
|
||||
- #7381 Set macOS min version to macOS 12.0
|
||||
- #7382 Re-run `macdeployqt6` to copy missing Qt 6 dependencies
|
||||
- #7383 Solve SonarCloud security hotspots and bugs
|
||||
- #7384 Run `install_deps.py` script when building containers weekly
|
||||
- #7389 Correct Qt macOS target and drop `Core5Compat` lib
|
||||
- #7383 Solve SonarCloud security hotspots and bugs
|
||||
- #7401 Run Valgrind on unit tests in CI to detect memory leaks
|
||||
- #7403 Solve low hanging reliability and maintainability issues
|
||||
|
||||
# 1.14.6
|
||||
|
||||
|
||||
61
cmake/Build.cmake
Normal file
61
cmake/Build.cmake
Normal file
@ -0,0 +1,61 @@
|
||||
# Synergy -- mouse and keyboard sharing utility
|
||||
# Copyright (C) 2024 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/>.
|
||||
|
||||
macro(post_config)
|
||||
|
||||
# Build to a temp bin dir on Windows and then copy to the final bin dir
|
||||
# (ignore copy fail). It is neccesary to do this. Since the binary may already
|
||||
# be running and you can't write to a running binary (on Windows). It's common
|
||||
# to use Synergy to develop Synergy (i.e. eating your own dog food immediately
|
||||
# making it).
|
||||
if(WIN32)
|
||||
|
||||
if(NOT target)
|
||||
message(FATAL_ERROR "target not set")
|
||||
endif()
|
||||
|
||||
set_target_properties(${target} PROPERTIES RUNTIME_OUTPUT_DIRECTORY
|
||||
${BIN_TEMP_DIR})
|
||||
endif()
|
||||
|
||||
endmacro()
|
||||
|
||||
macro(post_config_all)
|
||||
|
||||
# Always try to copy the files to the bin directory after every build, even if
|
||||
# there was nothing to do. This is because the copy may have failed last time
|
||||
# due to the file being in use, and we'll usually want to try again.
|
||||
if(WIN32)
|
||||
|
||||
if(NOT EXISTS ${PYTHON_BIN})
|
||||
message(FATAL_ERROR "Python not found at: ${PYTHON_BIN}")
|
||||
endif()
|
||||
|
||||
add_custom_target(
|
||||
run_post_build ALL
|
||||
COMMAND ${PYTHON_BIN} ${CMAKE_SOURCE_DIR}/scripts/fancy_copy.py
|
||||
${BIN_TEMP_DIR} ${CMAKE_BINARY_DIR}/bin --ignore-errors
|
||||
VERBATIM
|
||||
COMMENT "Copying files to bin dir")
|
||||
|
||||
add_dependencies(
|
||||
run_post_build
|
||||
synergy
|
||||
synergyc
|
||||
synergys
|
||||
synergyd)
|
||||
endif()
|
||||
|
||||
endmacro()
|
||||
@ -28,6 +28,7 @@ macro(configure_definitions)
|
||||
|
||||
configure_ninja()
|
||||
configure_options()
|
||||
configure_python()
|
||||
|
||||
if("${VERSION_URL}" STREQUAL "")
|
||||
set(VERSION_URL "https://api.symless.com/version?version=v1")
|
||||
@ -58,17 +59,20 @@ macro(configure_definitions)
|
||||
add_definitions(-DNDEBUG)
|
||||
endif()
|
||||
|
||||
# TODO: find out why we need these, and remove them if we don't
|
||||
# TODO: find out why we need these, and remove them if we don't.
|
||||
if(COMMAND cmake_policy)
|
||||
cmake_policy(SET CMP0003 NEW)
|
||||
cmake_policy(SET CMP0005 NEW)
|
||||
endif()
|
||||
|
||||
# TODO: explain why we're adding headers to sources.
|
||||
if(${CMAKE_GENERATOR} STREQUAL "Unix Makefiles")
|
||||
set(SYNERGY_ADD_HEADERS FALSE)
|
||||
set(ADD_HEADERS_TO_SOURCES FALSE)
|
||||
else()
|
||||
set(SYNERGY_ADD_HEADERS TRUE)
|
||||
set(ADD_HEADERS_TO_SOURCES TRUE)
|
||||
endif()
|
||||
|
||||
set(BIN_TEMP_DIR ${CMAKE_BINARY_DIR}/temp/bin)
|
||||
endmacro()
|
||||
|
||||
macro(configure_ninja)
|
||||
|
||||
@ -361,3 +361,11 @@ macro(update_submodules)
|
||||
endif()
|
||||
|
||||
endmacro()
|
||||
|
||||
macro(configure_python)
|
||||
if(WIN32)
|
||||
set(PYTHON_BIN "${CMAKE_BINARY_DIR}/python/Scripts/python.exe")
|
||||
else()
|
||||
set(PYTHON_BIN "${CMAKE_BINARY_DIR}/python/bin/python")
|
||||
endif()
|
||||
endmacro()
|
||||
|
||||
41
scripts/fancy_copy.py
Normal file
41
scripts/fancy_copy.py
Normal file
@ -0,0 +1,41 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
import argparse
|
||||
import lib.env as env
|
||||
import lib.file_utils as file_utils
|
||||
|
||||
|
||||
def main():
|
||||
"""
|
||||
Cross platform script to copy files and directories.
|
||||
This script was mostly created beause the default `copy` command on Windows is too noisy.
|
||||
If this becomes complex it must be replaced with a library.
|
||||
"""
|
||||
|
||||
# important: load venv before loading modules that install deps.
|
||||
env.ensure_in_venv(__file__)
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("source", help="Source pattern to copy from")
|
||||
parser.add_argument("target", help="Destination pattern to copy to")
|
||||
parser.add_argument(
|
||||
"--ignore-errors", action="store_true", help="Ignore errors when copying"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--verbose", action="store_true", help="Print more information to the console"
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
options = file_utils.CopyOptions(args.ignore_errors, args.verbose)
|
||||
|
||||
try:
|
||||
file_utils.copy(args.source, args.target, options)
|
||||
except Exception as e:
|
||||
if not args.ignore_errors:
|
||||
raise e
|
||||
else:
|
||||
print(f"Error: {e}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
80
scripts/lib/file_utils.py
Normal file
80
scripts/lib/file_utils.py
Normal file
@ -0,0 +1,80 @@
|
||||
import glob, os, shutil, sys
|
||||
|
||||
import colorama # type: ignore
|
||||
from colorama import Fore # type: ignore
|
||||
|
||||
colorama.init()
|
||||
|
||||
|
||||
class CopyOptions:
|
||||
def __init__(self, ignore_errors, verbose):
|
||||
self.ignore_errors = ignore_errors
|
||||
self.verbose = verbose
|
||||
|
||||
|
||||
class CopyContext:
|
||||
def __init__(self):
|
||||
self.errors = 0
|
||||
self.permission_error = False
|
||||
|
||||
|
||||
def copy(source, target, options):
|
||||
"""Copy files and directories from source to target."""
|
||||
|
||||
context = CopyContext()
|
||||
if options.verbose:
|
||||
print(f"Copying files from {source} to {target}")
|
||||
for match in glob.glob(source):
|
||||
|
||||
if os.path.isfile(match):
|
||||
copy_file(match, target, options, context)
|
||||
elif os.path.isdir(match):
|
||||
copy_dir(match, target, options, context)
|
||||
else:
|
||||
raise RuntimeError(f"Path {match} is not a file or directory")
|
||||
|
||||
if context.errors and options.ignore_errors:
|
||||
print(
|
||||
f"{Fore.YELLOW}WARNING:{Fore.RESET} Ignored {context.errors} copy error(s)"
|
||||
)
|
||||
|
||||
if context.permission_error:
|
||||
print(
|
||||
f"{Fore.BLUE}HINT:{Fore.RESET} A permission error may mean that the file is in use"
|
||||
)
|
||||
|
||||
|
||||
def copy_dir(match, target, options, context):
|
||||
if options.verbose:
|
||||
print(f"Copying directory {match} to {target}")
|
||||
|
||||
try:
|
||||
shutil.copytree(match, target, dirs_exist_ok=True)
|
||||
|
||||
except PermissionError as e:
|
||||
context.permission_error = True
|
||||
handle_copy_error(e, options, context)
|
||||
except Exception as e:
|
||||
handle_copy_error(e, options, context)
|
||||
|
||||
|
||||
def copy_file(match, target, options, context):
|
||||
if options.verbose:
|
||||
print(f"Copying file {match} to {target}")
|
||||
|
||||
try:
|
||||
shutil.copy(match, target)
|
||||
except PermissionError as e:
|
||||
context.permission_error = True
|
||||
handle_copy_error(e, options, context)
|
||||
except Exception as e:
|
||||
handle_copy_error(e, options, context)
|
||||
|
||||
|
||||
def handle_copy_error(e, options, context):
|
||||
context.errors += 1
|
||||
|
||||
if not options.ignore_errors:
|
||||
raise e
|
||||
else:
|
||||
print(f"{Fore.YELLOW}WARNING:{Fore.RESET} Copy failed: {e}", file=sys.stderr)
|
||||
@ -1,14 +1,13 @@
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
import argparse
|
||||
import glob
|
||||
import os, sys, time, subprocess, argparse, glob
|
||||
import lib.windows as windows
|
||||
import lib.file_utils as file_utils
|
||||
import psutil
|
||||
|
||||
BIN_NAME = "synergyd"
|
||||
SOURCE_BIN_DIR = os.path.join("build", "bin")
|
||||
TARGET_BIN_DIR = "bin"
|
||||
DEFAULT_BIN_NAME = "synergyd"
|
||||
DEFAULT_SOURCE_DIR = os.path.join("build", "temp", "bin")
|
||||
DEFAULT_TARGET_DIR = os.path.join("build", "bin")
|
||||
SERVICE_NOT_RUNNING_ERROR = 2
|
||||
ERROR_ACCESS_VIOLATION = 0xC0000005
|
||||
|
||||
|
||||
def main():
|
||||
@ -16,10 +15,9 @@ def main():
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("--pause-on-exit", action="store_true")
|
||||
parser.add_argument("--source-bin-dir", default=SOURCE_BIN_DIR)
|
||||
parser.add_argument("--target-bin-dir", default=TARGET_BIN_DIR)
|
||||
parser.add_argument("--source-bin-name", default=BIN_NAME)
|
||||
parser.add_argument("--target-bin-name", default=BIN_NAME)
|
||||
parser.add_argument("--source-dir", default=DEFAULT_SOURCE_DIR)
|
||||
parser.add_argument("--target-dir", default=DEFAULT_TARGET_DIR)
|
||||
parser.add_argument("--bin-name", default=DEFAULT_BIN_NAME)
|
||||
args = parser.parse_args()
|
||||
|
||||
if not windows.is_admin():
|
||||
@ -28,19 +26,18 @@ def main():
|
||||
|
||||
try:
|
||||
reinstall(
|
||||
args.source_bin_dir,
|
||||
args.target_bin_dir,
|
||||
args.source_bin_name,
|
||||
args.target_bin_name,
|
||||
args.source_dir,
|
||||
args.target_dir,
|
||||
args.bin_name,
|
||||
)
|
||||
except Exception as e:
|
||||
print(f"Error: {e}")
|
||||
print(f"Error: {e}", file=sys.stderr)
|
||||
|
||||
if args.pause_on_exit:
|
||||
input("Press enter to continue...")
|
||||
|
||||
|
||||
def reinstall(source_bin_dir, target_bin_dir, source_bin_name, target_bin_name):
|
||||
def reinstall(source_dir, target_dir, bin_name):
|
||||
"""Stops the running daemon service, copies files, and reinstalls."""
|
||||
|
||||
print("Stopping daemon service")
|
||||
@ -52,43 +49,64 @@ def reinstall(source_bin_dir, target_bin_dir, source_bin_name, target_bin_name):
|
||||
else:
|
||||
raise e
|
||||
|
||||
copy_bin_files(source_bin_dir, target_bin_dir, source_bin_name, target_bin_name)
|
||||
source_bin_path = f"{os.path.join(source_dir, bin_name)}.exe"
|
||||
|
||||
target_bin_file = f"{os.path.join(target_bin_dir, target_bin_name)}.exe"
|
||||
# Wait for Windows to release the file handles after process termination.
|
||||
while is_any_process_running(target_dir):
|
||||
print("Waiting for file handles to release")
|
||||
time.sleep(1)
|
||||
|
||||
options = file_utils.CopyOptions(ignore_errors=True, verbose=False)
|
||||
print(f"Copying files from {source_dir} to {target_dir}")
|
||||
file_utils.copy(f"{source_dir}/*", target_dir, options)
|
||||
|
||||
print("Removing old daemon service")
|
||||
subprocess.run([target_bin_file, "/uninstall"], shell=True, check=True)
|
||||
try:
|
||||
subprocess.run([source_bin_path, "/uninstall"], shell=True, check=True)
|
||||
except subprocess.CalledProcessError as e:
|
||||
check_access_violation(e.returncode, source_bin_path)
|
||||
if e.returncode != 0:
|
||||
print(
|
||||
f"Warning: Uninstall failed, return code: {e.returncode}",
|
||||
file=sys.stderr,
|
||||
)
|
||||
|
||||
print("Installing daemon service")
|
||||
subprocess.run([target_bin_file, "/install"], shell=True, check=True)
|
||||
target_bin_path = os.path.join(target_dir, bin_name + ".exe")
|
||||
|
||||
try:
|
||||
print("Installing daemon service")
|
||||
subprocess.run([target_bin_path, "/install"], shell=True, check=True)
|
||||
except subprocess.CalledProcessError as e:
|
||||
check_access_violation(e.returncode, target_bin_path)
|
||||
if e.returncode != 0:
|
||||
print(f"Warning: Install failed, return code: {e.returncode}")
|
||||
|
||||
|
||||
def copy_bin_files(source_bin_dir, target_bin_dir, source_bin_name, target_bin_name):
|
||||
|
||||
if not os.path.isdir(source_bin_dir):
|
||||
raise RuntimeError(f"Invalid source bin dir: {source_bin_dir}")
|
||||
|
||||
print(f"Persisting dir: {target_bin_dir}")
|
||||
os.makedirs(target_bin_dir, exist_ok=True)
|
||||
|
||||
source_bin_glob = f"{source_bin_name}*"
|
||||
source_files = glob.glob(os.path.join(source_bin_dir, source_bin_glob))
|
||||
|
||||
if not source_files:
|
||||
raise RuntimeError(
|
||||
f"No files found in {source_bin_dir} matching {source_bin_glob}"
|
||||
def check_access_violation(return_code, bin_path):
|
||||
if return_code == ERROR_ACCESS_VIOLATION:
|
||||
print(
|
||||
f"Warning: Process crashed with memory access violation: {bin_path}",
|
||||
file=sys.stderr,
|
||||
)
|
||||
|
||||
for source_file in source_files:
|
||||
base_name = os.path.basename(source_file)
|
||||
base_name = base_name.replace(source_bin_name, target_bin_name)
|
||||
target_file = os.path.join(target_bin_dir, base_name)
|
||||
print(f"Copying {source_file} to {target_file}")
|
||||
# use the copy command; shutil.copy gives us a permission denied error.
|
||||
|
||||
def is_any_process_running(dir):
|
||||
"""Check if there is any running process that contains the given directory."""
|
||||
|
||||
print(f"Checking if any process is running in: {dir}")
|
||||
for proc in psutil.process_iter(attrs=["name", "exe"]):
|
||||
exe = proc.info["exe"]
|
||||
|
||||
if not exe:
|
||||
continue
|
||||
|
||||
try:
|
||||
subprocess.run(["copy", source_file, target_file], shell=True, check=True)
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(f"Copy failed: {e}")
|
||||
if dir.lower() in exe.lower():
|
||||
print(f"Process found: {exe}")
|
||||
return True
|
||||
except (psutil.NoSuchProcess, psutil.AccessDenied):
|
||||
pass
|
||||
return False
|
||||
|
||||
|
||||
main()
|
||||
|
||||
@ -44,7 +44,7 @@ endif()
|
||||
list(APPEND sources ${arch_sources})
|
||||
list(APPEND headers ${arch_headers})
|
||||
|
||||
if(SYNERGY_ADD_HEADERS)
|
||||
if(ADD_HEADERS_TO_SOURCES)
|
||||
list(APPEND sources ${headers})
|
||||
endif()
|
||||
|
||||
@ -69,3 +69,5 @@ if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
elseif(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
install(TARGETS ${target} DESTINATION bin)
|
||||
endif()
|
||||
|
||||
post_config()
|
||||
|
||||
@ -38,3 +38,5 @@ target_link_libraries(
|
||||
synlib
|
||||
shared
|
||||
${libs})
|
||||
|
||||
post_config()
|
||||
|
||||
@ -44,7 +44,7 @@ endif()
|
||||
list(APPEND sources ${arch_sources})
|
||||
list(APPEND headers ${arch_headers})
|
||||
|
||||
if(SYNERGY_ADD_HEADERS)
|
||||
if(ADD_HEADERS_TO_SOURCES)
|
||||
list(APPEND sources ${headers})
|
||||
endif()
|
||||
|
||||
@ -69,3 +69,5 @@ if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
elseif(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
install(TARGETS ${target} DESTINATION bin)
|
||||
endif()
|
||||
|
||||
post_config()
|
||||
|
||||
@ -1,3 +1,20 @@
|
||||
# Synergy -- mouse and keyboard sharing utility
|
||||
# Copyright (C) 2024 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/>.
|
||||
|
||||
set(target synergy)
|
||||
|
||||
find_package(
|
||||
Qt6
|
||||
COMPONENTS Core Widgets Network
|
||||
@ -33,7 +50,7 @@ if(WIN32)
|
||||
endif()
|
||||
|
||||
add_executable(
|
||||
synergy WIN32
|
||||
${target} WIN32
|
||||
${GUI_SOURCE_FILES}
|
||||
${GUI_UI_FILES}
|
||||
${GUI_RC_FILES}
|
||||
@ -41,16 +58,16 @@ add_executable(
|
||||
${QM_FILES})
|
||||
|
||||
include_directories(./src)
|
||||
target_link_libraries(synergy shared)
|
||||
target_link_libraries(${target} shared)
|
||||
|
||||
target_link_libraries(synergy Qt6::Core Qt6::Widgets Qt6::Network)
|
||||
target_link_libraries(${target} Qt6::Core Qt6::Widgets Qt6::Network)
|
||||
target_compile_definitions(
|
||||
synergy PRIVATE -DSYNERGY_VERSION_STAGE="${SYNERGY_VERSION_STAGE}")
|
||||
target_compile_definitions(synergy
|
||||
${target} PRIVATE -DSYNERGY_VERSION_STAGE="${SYNERGY_VERSION_STAGE}")
|
||||
target_compile_definitions(${target}
|
||||
PRIVATE -DSYNERGY_REVISION="${SYNERGY_REVISION}")
|
||||
|
||||
if(WIN32)
|
||||
set_target_properties(synergy PROPERTIES LINK_FLAGS "/NODEFAULTLIB:LIBCMT")
|
||||
set_target_properties(${target} PROPERTIES LINK_FLAGS "/NODEFAULTLIB:LIBCMT")
|
||||
endif()
|
||||
|
||||
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
@ -61,13 +78,13 @@ if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
set(MACDEPLOYQT_CMD
|
||||
"${MACDEPLOYQT_BIN} ${SYNERGY_BUNDLE_APP_DIR} -always-overwrite")
|
||||
|
||||
install(TARGETS synergy DESTINATION ${SYNERGY_BUNDLE_BINARY_DIR})
|
||||
install(TARGETS ${target} DESTINATION ${SYNERGY_BUNDLE_BINARY_DIR})
|
||||
install(CODE "MESSAGE (\"Running: ${MACDEPLOYQT_CMD}\")")
|
||||
install(CODE "execute_process(COMMAND ${MACDEPLOYQT_CMD})")
|
||||
|
||||
elseif(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
||||
|
||||
install(TARGETS synergy DESTINATION bin)
|
||||
install(TARGETS ${target} DESTINATION bin)
|
||||
|
||||
elseif(WIN32)
|
||||
|
||||
@ -96,7 +113,7 @@ elseif(WIN32)
|
||||
if(TARGET Qt6::windeployqt)
|
||||
# execute windeployqt in a tmp directory after build
|
||||
add_custom_command(
|
||||
TARGET synergy
|
||||
TARGET ${target}
|
||||
POST_BUILD
|
||||
COMMAND set PATH=%PATH%$<SEMICOLON>${qt6_install_prefix}/bin
|
||||
COMMAND Qt6::windeployqt
|
||||
@ -104,3 +121,5 @@ elseif(WIN32)
|
||||
endif()
|
||||
|
||||
endif()
|
||||
|
||||
post_config()
|
||||
|
||||
@ -22,8 +22,8 @@
|
||||
// command line argument to synergy core, determines if the server restarts
|
||||
// when switching Windows desktops (e.g. when Windows UAC dialog pops up).
|
||||
// The second, passed as a boolean flag to Synergyd over the IPC inside
|
||||
// kIpcCommandMessage, determines whether Synergy should be started with
|
||||
// elevated privileges.
|
||||
// IpcMessageType::CommandMessage, determines whether Synergy should be started
|
||||
// with elevated privileges.
|
||||
//
|
||||
// The matrix for these two behaviours is as follows:
|
||||
// SodS Elevate
|
||||
|
||||
@ -17,7 +17,7 @@
|
||||
*/
|
||||
|
||||
#include "IpcReader.h"
|
||||
#include "Ipc.h"
|
||||
#include "shared/Ipc.h"
|
||||
#include <QByteArray>
|
||||
#include <QMutex>
|
||||
#include <QTcpSocket>
|
||||
|
||||
@ -31,13 +31,12 @@
|
||||
#include "AppConfig.h"
|
||||
#include "ClientConnection.h"
|
||||
#include "ConfigWriter.h"
|
||||
#include "Ipc.h"
|
||||
#include "QIpcClient.h"
|
||||
#include "ServerConfig.h"
|
||||
#include "ServerConnection.h"
|
||||
#include "VersionChecker.h"
|
||||
|
||||
#include "TrayIcon.h"
|
||||
#include "VersionChecker.h"
|
||||
#include "shared/Ipc.h"
|
||||
|
||||
class QAction;
|
||||
class QMenu;
|
||||
@ -169,8 +168,7 @@ protected:
|
||||
bool clientArgs(QStringList &args, QString &app);
|
||||
bool serverArgs(QStringList &args, QString &app);
|
||||
void setStatus(const QString &status);
|
||||
void
|
||||
sendIpcMessage(qIpcMessageType type, const char *buffer, bool showErrors);
|
||||
void sendIpcMessage(IpcMessageType type, const char *buffer, bool showErrors);
|
||||
void updateFromLogLine(const QString &line);
|
||||
QString getIPAddresses();
|
||||
void stopService();
|
||||
|
||||
@ -16,12 +16,13 @@
|
||||
*/
|
||||
|
||||
#include "QIpcClient.h"
|
||||
#include "Ipc.h"
|
||||
#include "IpcReader.h"
|
||||
#include "shared/Ipc.h"
|
||||
|
||||
#include <QDataStream>
|
||||
#include <QHostAddress>
|
||||
#include <QTimer>
|
||||
#include <qglobal.h>
|
||||
|
||||
QIpcClient::QIpcClient(const StreamProvider &streamProvider)
|
||||
: m_ReaderStarted(false),
|
||||
@ -61,7 +62,8 @@ void QIpcClient::connectToHost() {
|
||||
m_Enabled = true;
|
||||
|
||||
infoMessage("connecting to service...");
|
||||
m_Socket->connectToHost(QHostAddress(QHostAddress::LocalHost), IPC_PORT);
|
||||
const auto port = static_cast<quint16>(kIpcPort);
|
||||
m_Socket->connectToHost(QHostAddress(QHostAddress::LocalHost), port);
|
||||
|
||||
if (!m_ReaderStarted) {
|
||||
m_Reader->start();
|
||||
@ -105,7 +107,7 @@ void QIpcClient::sendHello() {
|
||||
stream->writeRawData(kIpcMsgHello, 4);
|
||||
|
||||
char typeBuf[1];
|
||||
typeBuf[0] = kIpcClientGui;
|
||||
typeBuf[0] = static_cast<char>(IpcClientType::GUI);
|
||||
stream->writeRawData(typeBuf, 1);
|
||||
}
|
||||
|
||||
|
||||
@ -17,7 +17,7 @@
|
||||
file(GLOB headers "*.h")
|
||||
file(GLOB sources "*.cpp")
|
||||
|
||||
if(SYNERGY_ADD_HEADERS)
|
||||
if(ADD_HEADERS_TO_SOURCES)
|
||||
list(APPEND sources ${headers})
|
||||
endif()
|
||||
|
||||
@ -33,7 +33,7 @@ endif()
|
||||
list(APPEND sources ${arch_sources})
|
||||
list(APPEND headers ${arch_headers})
|
||||
|
||||
if(SYNERGY_ADD_HEADERS)
|
||||
if(ADD_HEADERS_TO_SOURCES)
|
||||
list(APPEND sources ${headers})
|
||||
endif()
|
||||
|
||||
|
||||
@ -17,7 +17,7 @@
|
||||
file(GLOB headers "*.h")
|
||||
file(GLOB sources "*.cpp")
|
||||
|
||||
if(SYNERGY_ADD_HEADERS)
|
||||
if(ADD_HEADERS_TO_SOURCES)
|
||||
list(APPEND sources ${headers})
|
||||
endif()
|
||||
|
||||
|
||||
@ -212,40 +212,3 @@ void FileLogOutputter::open(const char *title) {}
|
||||
void FileLogOutputter::close() {}
|
||||
|
||||
void FileLogOutputter::show(bool showIfEmpty) {}
|
||||
|
||||
//
|
||||
// MesssageBoxLogOutputter
|
||||
//
|
||||
|
||||
MesssageBoxLogOutputter::MesssageBoxLogOutputter() {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
MesssageBoxLogOutputter::~MesssageBoxLogOutputter() {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
void MesssageBoxLogOutputter::open(const char *title) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
void MesssageBoxLogOutputter::close() {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
void MesssageBoxLogOutputter::show(bool showIfEmpty) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
bool MesssageBoxLogOutputter::write(ELevel level, const char *msg) {
|
||||
// don't spam user with messages.
|
||||
if (level > kERROR) {
|
||||
return true;
|
||||
}
|
||||
|
||||
#if SYSAPI_WIN32
|
||||
MessageBox(NULL, msg, CLOG->getFilterName(level), MB_OK);
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -160,19 +160,3 @@ private:
|
||||
UInt32 m_maxBufferSize;
|
||||
Buffer m_buffer;
|
||||
};
|
||||
|
||||
//! Write log to message box
|
||||
/*!
|
||||
The level for each message is ignored.
|
||||
*/
|
||||
class MesssageBoxLogOutputter : public ILogOutputter {
|
||||
public:
|
||||
MesssageBoxLogOutputter();
|
||||
virtual ~MesssageBoxLogOutputter();
|
||||
|
||||
// ILogOutputter overrides
|
||||
virtual void open(const char *title);
|
||||
virtual void close();
|
||||
virtual void show(bool showIfEmpty);
|
||||
virtual bool write(ELevel level, const char *message);
|
||||
};
|
||||
|
||||
@ -17,7 +17,7 @@
|
||||
file(GLOB headers "*.h")
|
||||
file(GLOB sources "*.cpp")
|
||||
|
||||
if(SYNERGY_ADD_HEADERS)
|
||||
if(ADD_HEADERS_TO_SOURCES)
|
||||
list(APPEND sources ${headers})
|
||||
endif()
|
||||
|
||||
|
||||
@ -17,7 +17,7 @@
|
||||
file(GLOB headers "*.h")
|
||||
file(GLOB sources "*.cpp")
|
||||
|
||||
if(SYNERGY_ADD_HEADERS)
|
||||
if(ADD_HEADERS_TO_SOURCES)
|
||||
list(APPEND sources ${headers})
|
||||
endif()
|
||||
|
||||
|
||||
@ -17,7 +17,7 @@
|
||||
file(GLOB headers "*.h")
|
||||
file(GLOB sources "*.cpp")
|
||||
|
||||
if(SYNERGY_ADD_HEADERS)
|
||||
if(ADD_HEADERS_TO_SOURCES)
|
||||
list(APPEND sources ${headers})
|
||||
endif()
|
||||
|
||||
|
||||
@ -17,7 +17,7 @@
|
||||
file(GLOB headers "*.h")
|
||||
file(GLOB sources "*.cpp")
|
||||
|
||||
if(SYNERGY_ADD_HEADERS)
|
||||
if(ADD_HEADERS_TO_SOURCES)
|
||||
list(APPEND sources ${headers})
|
||||
endif()
|
||||
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2012-2016 Symless Ltd.
|
||||
* Copyright (C) 2012 Nick Bolton
|
||||
* Copyright (C) 2012 Symless Ltd.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@ -18,16 +17,16 @@
|
||||
|
||||
#include "ipc/IpcClient.h"
|
||||
#include "base/TMethodEventJob.h"
|
||||
#include "ipc/Ipc.h"
|
||||
#include "ipc/IpcMessage.h"
|
||||
#include "ipc/IpcServerProxy.h"
|
||||
#include "shared/Ipc.h"
|
||||
|
||||
//
|
||||
// IpcClient
|
||||
//
|
||||
|
||||
IpcClient::IpcClient(IEventQueue *events, SocketMultiplexer *socketMultiplexer)
|
||||
: m_serverAddress(NetworkAddress(IPC_HOST, IPC_PORT)),
|
||||
: m_serverAddress(NetworkAddress(kIpcHost, kIpcPort)),
|
||||
m_socket(events, socketMultiplexer),
|
||||
m_server(nullptr),
|
||||
m_events(events) {
|
||||
@ -36,7 +35,7 @@ IpcClient::IpcClient(IEventQueue *events, SocketMultiplexer *socketMultiplexer)
|
||||
|
||||
IpcClient::IpcClient(
|
||||
IEventQueue *events, SocketMultiplexer *socketMultiplexer, int port)
|
||||
: m_serverAddress(NetworkAddress(IPC_HOST, port)),
|
||||
: m_serverAddress(NetworkAddress(kIpcHost, port)),
|
||||
m_socket(events, socketMultiplexer),
|
||||
m_server(nullptr),
|
||||
m_events(events) {
|
||||
@ -81,7 +80,7 @@ void IpcClient::handleConnected(const Event &, void *) {
|
||||
m_events->forIpcClient().connected(), this, m_server,
|
||||
Event::kDontFreeData));
|
||||
|
||||
IpcHelloMessage message(kIpcClientNode);
|
||||
IpcHelloMessage message(IpcClientType::Node);
|
||||
send(message);
|
||||
}
|
||||
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2012-2016 Symless Ltd.
|
||||
* Copyright (C) 2012 Nick Bolton
|
||||
* Copyright (C) 2012 Symless Ltd.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@ -18,13 +17,12 @@
|
||||
|
||||
#include "ipc/IpcClientProxy.h"
|
||||
|
||||
#include "arch/Arch.h"
|
||||
#include "base/Log.h"
|
||||
#include "base/TMethodEventJob.h"
|
||||
#include "io/IStream.h"
|
||||
#include "ipc/Ipc.h"
|
||||
#include "ipc/IpcMessage.h"
|
||||
#include "ipc/IpcSettingMessage.h"
|
||||
#include "shared/Ipc.h"
|
||||
#include "synergy/ProtocolUtil.h"
|
||||
|
||||
//
|
||||
@ -33,10 +31,6 @@
|
||||
|
||||
IpcClientProxy::IpcClientProxy(synergy::IStream &stream, IEventQueue *events)
|
||||
: m_stream(stream),
|
||||
m_clientType(kIpcClientUnknown),
|
||||
m_disconnecting(false),
|
||||
m_readMutex(ARCH->newMutex()),
|
||||
m_writeMutex(ARCH->newMutex()),
|
||||
m_events(events) {
|
||||
m_events->adoptHandler(
|
||||
m_events->forIStream().inputReady(), stream.getEventTarget(),
|
||||
@ -135,7 +129,7 @@ void IpcClientProxy::send(const IpcMessage &message) {
|
||||
LOG((CLOG_DEBUG4 "ipc write: %d", message.type()));
|
||||
|
||||
switch (message.type()) {
|
||||
case kIpcLogLine: {
|
||||
case IpcMessageType::LogLine: {
|
||||
const IpcLogLineMessage &llm =
|
||||
static_cast<const IpcLogLineMessage &>(message);
|
||||
const String logLine = llm.logLine();
|
||||
@ -143,11 +137,11 @@ void IpcClientProxy::send(const IpcMessage &message) {
|
||||
break;
|
||||
}
|
||||
|
||||
case kIpcShutdown:
|
||||
case IpcMessageType::Shutdown:
|
||||
ProtocolUtil::writef(&m_stream, kIpcMsgShutdown);
|
||||
break;
|
||||
|
||||
case kIpcHelloBack:
|
||||
case IpcMessageType::HelloBack:
|
||||
ProtocolUtil::writef(&m_stream, kIpcMsgHelloBack);
|
||||
break;
|
||||
|
||||
@ -161,7 +155,7 @@ IpcHelloMessage *IpcClientProxy::parseHello() {
|
||||
UInt8 type;
|
||||
ProtocolUtil::readf(&m_stream, kIpcMsgHello + 4, &type);
|
||||
|
||||
m_clientType = static_cast<EIpcClientType>(type);
|
||||
m_clientType = static_cast<IpcClientType>(type);
|
||||
|
||||
// must be deleted by event handler.
|
||||
return new IpcHelloMessage(m_clientType);
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2012-2016 Symless Ltd.
|
||||
* Copyright (C) 2012 Nick Bolton
|
||||
* Copyright (C) 2012 Symless Ltd.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@ -18,10 +17,11 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "arch/Arch.h"
|
||||
#include "arch/IArchMultithread.h"
|
||||
#include "base/Event.h"
|
||||
#include "base/EventTypes.h"
|
||||
#include "ipc/Ipc.h"
|
||||
#include "shared/Ipc.h"
|
||||
|
||||
namespace synergy {
|
||||
class IStream;
|
||||
@ -56,9 +56,9 @@ private:
|
||||
|
||||
private:
|
||||
synergy::IStream &m_stream;
|
||||
EIpcClientType m_clientType;
|
||||
bool m_disconnecting;
|
||||
ArchMutex m_readMutex;
|
||||
ArchMutex m_writeMutex;
|
||||
IEventQueue *m_events;
|
||||
IpcClientType m_clientType = IpcClientType::Unknown;
|
||||
bool m_disconnecting = false;
|
||||
ArchMutex m_readMutex = ARCH->newMutex();
|
||||
ArchMutex m_writeMutex = ARCH->newMutex();
|
||||
};
|
||||
|
||||
@ -24,11 +24,11 @@
|
||||
#include "base/EventQueue.h"
|
||||
#include "base/TMethodEventJob.h"
|
||||
#include "base/TMethodJob.h"
|
||||
#include "ipc/Ipc.h"
|
||||
#include "ipc/IpcClientProxy.h"
|
||||
#include "ipc/IpcMessage.h"
|
||||
#include "ipc/IpcServer.h"
|
||||
#include "mt/Thread.h"
|
||||
#include "shared/Ipc.h"
|
||||
|
||||
enum EIpcLogOutputter {
|
||||
kBufferMaxSize = 1000,
|
||||
@ -38,7 +38,7 @@ enum EIpcLogOutputter {
|
||||
};
|
||||
|
||||
IpcLogOutputter::IpcLogOutputter(
|
||||
IpcServer &ipcServer, EIpcClientType clientType, bool useThread)
|
||||
IpcServer &ipcServer, IpcClientType clientType, bool useThread)
|
||||
: m_ipcServer(ipcServer),
|
||||
m_bufferMutex(ARCH->newMutex()),
|
||||
m_sending(false),
|
||||
@ -179,7 +179,7 @@ void IpcLogOutputter::sendBuffer() {
|
||||
|
||||
IpcLogLineMessage message(getChunk(kMaxSendLines));
|
||||
m_sending = true;
|
||||
m_ipcServer.send(message, kIpcClientGui);
|
||||
m_ipcServer.send(message, IpcClientType::GUI);
|
||||
m_sending = false;
|
||||
}
|
||||
|
||||
|
||||
@ -21,7 +21,7 @@
|
||||
#include "arch/Arch.h"
|
||||
#include "arch/IArchMultithread.h"
|
||||
#include "base/ILogOutputter.h"
|
||||
#include "ipc/Ipc.h"
|
||||
#include "shared/Ipc.h"
|
||||
|
||||
#include <deque>
|
||||
|
||||
@ -41,7 +41,7 @@ public:
|
||||
using the \c sendBuffer() function.
|
||||
*/
|
||||
IpcLogOutputter(
|
||||
IpcServer &ipcServer, EIpcClientType clientType, bool useThread);
|
||||
IpcServer &ipcServer, IpcClientType clientType, bool useThread);
|
||||
IpcLogOutputter(IpcLogOutputter const &) = delete;
|
||||
virtual ~IpcLogOutputter();
|
||||
|
||||
@ -115,6 +115,6 @@ private:
|
||||
double m_bufferRateTimeLimit;
|
||||
UInt16 m_bufferWriteCount;
|
||||
double m_bufferRateStart;
|
||||
EIpcClientType m_clientType;
|
||||
IpcClientType m_clientType;
|
||||
ArchMutex m_runningMutex;
|
||||
};
|
||||
|
||||
@ -17,35 +17,25 @@
|
||||
*/
|
||||
|
||||
#include "ipc/IpcMessage.h"
|
||||
#include "ipc/Ipc.h"
|
||||
#include "shared/Ipc.h"
|
||||
|
||||
IpcMessage::IpcMessage(UInt8 type) : m_type(type) {}
|
||||
IpcMessage::IpcMessage(IpcMessageType type) : m_type(type) {}
|
||||
|
||||
IpcMessage::~IpcMessage() {}
|
||||
|
||||
IpcHelloMessage::IpcHelloMessage(EIpcClientType clientType)
|
||||
: IpcMessage(kIpcHello),
|
||||
IpcHelloMessage::IpcHelloMessage(IpcClientType clientType)
|
||||
: IpcMessage(IpcMessageType::Hello),
|
||||
m_clientType(clientType) {}
|
||||
|
||||
IpcHelloMessage::~IpcHelloMessage() {}
|
||||
IpcHelloBackMessage::IpcHelloBackMessage()
|
||||
: IpcMessage(IpcMessageType::HelloBack) {}
|
||||
|
||||
IpcHelloBackMessage::IpcHelloBackMessage() : IpcMessage(kIpcHelloBack) {}
|
||||
|
||||
IpcHelloBackMessage::~IpcHelloBackMessage() {}
|
||||
|
||||
IpcShutdownMessage::IpcShutdownMessage() : IpcMessage(kIpcShutdown) {}
|
||||
|
||||
IpcShutdownMessage::~IpcShutdownMessage() {}
|
||||
IpcShutdownMessage::IpcShutdownMessage()
|
||||
: IpcMessage(IpcMessageType::Shutdown) {}
|
||||
|
||||
IpcLogLineMessage::IpcLogLineMessage(const String &logLine)
|
||||
: IpcMessage(kIpcLogLine),
|
||||
: IpcMessage(IpcMessageType::LogLine),
|
||||
m_logLine(logLine) {}
|
||||
|
||||
IpcLogLineMessage::~IpcLogLineMessage() {}
|
||||
|
||||
IpcCommandMessage::IpcCommandMessage(const String &command, bool elevate)
|
||||
: IpcMessage(kIpcCommand),
|
||||
: IpcMessage(IpcMessageType::Command),
|
||||
m_command(command),
|
||||
m_elevate(elevate) {}
|
||||
|
||||
IpcCommandMessage::~IpcCommandMessage() {}
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2012-2016 Symless Ltd.
|
||||
* Copyright (C) 2012 Nick Bolton
|
||||
* Copyright (C) 2012 Symless Ltd.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@ -19,52 +18,51 @@
|
||||
#pragma once
|
||||
|
||||
#include "base/Event.h"
|
||||
#include "base/EventTypes.h"
|
||||
#include "base/String.h"
|
||||
#include "ipc/Ipc.h"
|
||||
#include "shared/Ipc.h"
|
||||
|
||||
class IpcMessage : public EventData {
|
||||
public:
|
||||
virtual ~IpcMessage();
|
||||
~IpcMessage() override = default;
|
||||
|
||||
//! Gets the message type ID.
|
||||
UInt8 type() const { return m_type; }
|
||||
IpcMessageType type() const { return m_type; }
|
||||
|
||||
protected:
|
||||
IpcMessage(UInt8 type);
|
||||
explicit IpcMessage(IpcMessageType type);
|
||||
|
||||
private:
|
||||
UInt8 m_type;
|
||||
IpcMessageType m_type;
|
||||
};
|
||||
|
||||
class IpcHelloMessage : public IpcMessage {
|
||||
public:
|
||||
IpcHelloMessage(EIpcClientType clientType);
|
||||
virtual ~IpcHelloMessage();
|
||||
explicit IpcHelloMessage(IpcClientType clientType);
|
||||
~IpcHelloMessage() override = default;
|
||||
|
||||
//! Gets the message type ID.
|
||||
EIpcClientType clientType() const { return m_clientType; }
|
||||
IpcClientType clientType() const { return m_clientType; }
|
||||
|
||||
private:
|
||||
EIpcClientType m_clientType;
|
||||
IpcClientType m_clientType;
|
||||
};
|
||||
|
||||
class IpcHelloBackMessage : public IpcMessage {
|
||||
public:
|
||||
IpcHelloBackMessage();
|
||||
virtual ~IpcHelloBackMessage();
|
||||
explicit IpcHelloBackMessage();
|
||||
~IpcHelloBackMessage() override = default;
|
||||
};
|
||||
|
||||
class IpcShutdownMessage : public IpcMessage {
|
||||
public:
|
||||
IpcShutdownMessage();
|
||||
virtual ~IpcShutdownMessage();
|
||||
explicit IpcShutdownMessage();
|
||||
~IpcShutdownMessage() override = default;
|
||||
};
|
||||
|
||||
class IpcLogLineMessage : public IpcMessage {
|
||||
public:
|
||||
IpcLogLineMessage(const String &logLine);
|
||||
virtual ~IpcLogLineMessage();
|
||||
explicit IpcLogLineMessage(const String &logLine);
|
||||
~IpcLogLineMessage() override = default;
|
||||
|
||||
//! Gets the log line.
|
||||
String logLine() const { return m_logLine; }
|
||||
@ -75,8 +73,8 @@ private:
|
||||
|
||||
class IpcCommandMessage : public IpcMessage {
|
||||
public:
|
||||
IpcCommandMessage(const String &command, bool elevate);
|
||||
virtual ~IpcCommandMessage();
|
||||
explicit IpcCommandMessage(const String &command, bool elevate);
|
||||
~IpcCommandMessage() override = default;
|
||||
|
||||
//! Gets the command.
|
||||
String command() const { return m_command; }
|
||||
|
||||
@ -23,10 +23,10 @@
|
||||
#include "base/Log.h"
|
||||
#include "base/TMethodEventJob.h"
|
||||
#include "io/IStream.h"
|
||||
#include "ipc/Ipc.h"
|
||||
#include "ipc/IpcClientProxy.h"
|
||||
#include "ipc/IpcMessage.h"
|
||||
#include "net/IDataSocket.h"
|
||||
#include "shared/Ipc.h"
|
||||
|
||||
//
|
||||
// IpcServer
|
||||
@ -37,7 +37,7 @@ IpcServer::IpcServer(IEventQueue *events, SocketMultiplexer *socketMultiplexer)
|
||||
m_events(events),
|
||||
m_socketMultiplexer(socketMultiplexer),
|
||||
m_socket(nullptr),
|
||||
m_address(NetworkAddress(IPC_HOST, IPC_PORT)) {
|
||||
m_address(NetworkAddress(kIpcHost, kIpcPort)) {
|
||||
init();
|
||||
}
|
||||
|
||||
@ -46,7 +46,7 @@ IpcServer::IpcServer(
|
||||
: m_mock(false),
|
||||
m_events(events),
|
||||
m_socketMultiplexer(socketMultiplexer),
|
||||
m_address(NetworkAddress(IPC_HOST, port)) {
|
||||
m_address(NetworkAddress(kIpcHost, port)) {
|
||||
init();
|
||||
}
|
||||
|
||||
@ -135,7 +135,7 @@ void IpcServer::deleteClient(IpcClientProxy *proxy) {
|
||||
delete proxy;
|
||||
}
|
||||
|
||||
bool IpcServer::hasClients(EIpcClientType clientType) const {
|
||||
bool IpcServer::hasClients(IpcClientType clientType) const {
|
||||
ArchMutexLock lock(m_clientsMutex);
|
||||
|
||||
if (m_clients.empty()) {
|
||||
@ -155,7 +155,7 @@ bool IpcServer::hasClients(EIpcClientType clientType) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
void IpcServer::send(const IpcMessage &message, EIpcClientType filterType) {
|
||||
void IpcServer::send(const IpcMessage &message, IpcClientType filterType) {
|
||||
ArchMutexLock lock(m_clientsMutex);
|
||||
|
||||
ClientList::iterator it;
|
||||
|
||||
@ -20,9 +20,9 @@
|
||||
|
||||
#include "arch/Arch.h"
|
||||
#include "base/EventTypes.h"
|
||||
#include "ipc/Ipc.h"
|
||||
#include "net/NetworkAddress.h"
|
||||
#include "net/TCPListenSocket.h"
|
||||
#include "shared/Ipc.h"
|
||||
|
||||
#include <list>
|
||||
|
||||
@ -58,14 +58,14 @@ public:
|
||||
virtual void listen();
|
||||
|
||||
//! Send a message to all clients matching the filter type.
|
||||
virtual void send(const IpcMessage &message, EIpcClientType filterType);
|
||||
virtual void send(const IpcMessage &message, IpcClientType filterType);
|
||||
|
||||
//@}
|
||||
//! @name accessors
|
||||
//@{
|
||||
|
||||
//! Returns true when there are clients of the specified type connected.
|
||||
virtual bool hasClients(EIpcClientType clientType) const;
|
||||
virtual bool hasClients(IpcClientType clientType) const;
|
||||
|
||||
//@}
|
||||
|
||||
|
||||
@ -21,8 +21,8 @@
|
||||
#include "base/Log.h"
|
||||
#include "base/TMethodEventJob.h"
|
||||
#include "io/IStream.h"
|
||||
#include "ipc/Ipc.h"
|
||||
#include "ipc/IpcMessage.h"
|
||||
#include "shared/Ipc.h"
|
||||
#include "synergy/ProtocolUtil.h"
|
||||
|
||||
//
|
||||
@ -78,13 +78,13 @@ void IpcServerProxy::send(const IpcMessage &message) {
|
||||
LOG((CLOG_DEBUG4 "ipc write: %d", message.type()));
|
||||
|
||||
switch (message.type()) {
|
||||
case kIpcHello: {
|
||||
case IpcMessageType::Hello: {
|
||||
const IpcHelloMessage &hm = static_cast<const IpcHelloMessage &>(message);
|
||||
ProtocolUtil::writef(&m_stream, kIpcMsgHello, hm.clientType());
|
||||
break;
|
||||
}
|
||||
|
||||
case kIpcCommand: {
|
||||
case IpcMessageType::Command: {
|
||||
const IpcCommandMessage &cm =
|
||||
static_cast<const IpcCommandMessage &>(message);
|
||||
const String command = cm.command();
|
||||
|
||||
@ -20,7 +20,7 @@
|
||||
|
||||
IpcSettingMessage::IpcSettingMessage(
|
||||
const std::string &name, const std::string &value)
|
||||
: IpcMessage(kIpcSetting),
|
||||
: IpcMessage(IpcMessageType::Setting),
|
||||
m_name(name),
|
||||
m_value(value) {}
|
||||
|
||||
|
||||
@ -17,7 +17,7 @@
|
||||
file(GLOB headers "*.h")
|
||||
file(GLOB sources "*.cpp")
|
||||
|
||||
if(SYNERGY_ADD_HEADERS)
|
||||
if(ADD_HEADERS_TO_SOURCES)
|
||||
list(APPEND sources ${headers})
|
||||
endif()
|
||||
|
||||
|
||||
@ -17,7 +17,7 @@
|
||||
file(GLOB headers "*.h" "InverseSockets/*.h")
|
||||
file(GLOB sources "*.cpp" "InverseSockets/*.cpp")
|
||||
|
||||
if(SYNERGY_ADD_HEADERS)
|
||||
if(ADD_HEADERS_TO_SOURCES)
|
||||
list(APPEND sources ${headers})
|
||||
endif()
|
||||
|
||||
|
||||
@ -31,7 +31,7 @@ elseif(UNIX)
|
||||
file(GLOB sources "XWindows*.cpp")
|
||||
endif()
|
||||
|
||||
if(SYNERGY_ADD_HEADERS)
|
||||
if(ADD_HEADERS_TO_SOURCES)
|
||||
list(APPEND sources ${headers})
|
||||
endif()
|
||||
|
||||
|
||||
@ -23,11 +23,11 @@
|
||||
#include "base/Log.h"
|
||||
#include "base/TMethodJob.h"
|
||||
#include "base/log_outputters.h"
|
||||
#include "ipc/Ipc.h"
|
||||
#include "ipc/IpcLogOutputter.h"
|
||||
#include "ipc/IpcMessage.h"
|
||||
#include "ipc/IpcServer.h"
|
||||
#include "mt/Thread.h"
|
||||
#include "shared/Ipc.h"
|
||||
#include "synergy/App.h"
|
||||
#include "synergy/ArgsBase.h"
|
||||
|
||||
@ -510,7 +510,7 @@ void MSWindowsWatchdog::shutdownProcess(HANDLE handle, DWORD pid, int timeout) {
|
||||
}
|
||||
|
||||
IpcShutdownMessage shutdown;
|
||||
m_ipcServer.send(shutdown, kIpcClientNode);
|
||||
m_ipcServer.send(shutdown, IpcClientType::Node);
|
||||
|
||||
// wait for process to exit gracefully.
|
||||
double start = ARCH->time();
|
||||
|
||||
@ -21,8 +21,8 @@
|
||||
#include "arch/Arch.h"
|
||||
#include "base/Log.h"
|
||||
#include "base/Stopwatch.h"
|
||||
#include "common/basic_types.h"
|
||||
#include "common/stdvector.h"
|
||||
#include "mt/Thread.h"
|
||||
#include "platform/XWindowsClipboardBMPConverter.h"
|
||||
#include "platform/XWindowsClipboardHTMLConverter.h"
|
||||
#include "platform/XWindowsClipboardTextConverter.h"
|
||||
@ -534,13 +534,13 @@ bool XWindowsClipboard::icccmGetSelection(
|
||||
assert(data != nullptr);
|
||||
|
||||
// request data conversion
|
||||
CICCCMGetClipboard getter(m_window, m_time, m_atomData);
|
||||
if (!getter.readClipboard(
|
||||
if (CICCCMGetClipboard getter(m_window, m_time, m_atomData);
|
||||
!getter.readClipboard(
|
||||
m_display, m_selection, target, actualTarget, data)) {
|
||||
LOG(
|
||||
(CLOG_DEBUG1 "can't get data for selection target %s",
|
||||
XWindowsUtil::atomToString(m_display, target).c_str()));
|
||||
LOGC(getter.m_error, (CLOG_WARN "icccm violation by clipboard owner"));
|
||||
LOGC(getter.error(), (CLOG_WARN "icccm violation by clipboard owner"));
|
||||
return false;
|
||||
} else if (*actualTarget == None) {
|
||||
LOG(
|
||||
@ -630,7 +630,7 @@ bool XWindowsClipboard::motifOwnsClipboard() const {
|
||||
if (data.size() >= sizeof(MotifClipHeader)) {
|
||||
MotifClipHeader header;
|
||||
std::memcpy(&header, data.data(), sizeof(header));
|
||||
if ((header.m_id == kMotifClipHeader) &&
|
||||
if ((header.m_id == MotifClip::Header) &&
|
||||
(static_cast<Window>(header.m_selectionOwner) == owner)) {
|
||||
return true;
|
||||
}
|
||||
@ -658,7 +658,7 @@ void XWindowsClipboard::motifFillCache() {
|
||||
return;
|
||||
}
|
||||
std::memcpy(&header, data.data(), sizeof(header));
|
||||
if (header.m_id != kMotifClipHeader || header.m_numItems < 1) {
|
||||
if (header.m_id != MotifClip::Header || header.m_numItems < 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -678,7 +678,7 @@ void XWindowsClipboard::motifFillCache() {
|
||||
return;
|
||||
}
|
||||
std::memcpy(&item, data.data(), sizeof(item));
|
||||
if (item.m_id != kMotifClipItem ||
|
||||
if (item.m_id != MotifClip::Item ||
|
||||
item.m_numFormats - item.m_numDeletedFormats < 1) {
|
||||
return;
|
||||
}
|
||||
@ -707,7 +707,7 @@ void XWindowsClipboard::motifFillCache() {
|
||||
continue;
|
||||
}
|
||||
std::memcpy(&motifFormat, data.data(), sizeof(motifFormat));
|
||||
if (motifFormat.m_id != kMotifClipFormat || motifFormat.m_length < 0 ||
|
||||
if (motifFormat.m_id != MotifClip::Format || motifFormat.m_length < 0 ||
|
||||
motifFormat.m_type == None || motifFormat.m_deleted != 0) {
|
||||
continue;
|
||||
}
|
||||
@ -1197,18 +1197,7 @@ XWindowsClipboard::CICCCMGetClipboard::CICCCMGetClipboard(
|
||||
Window requestor, Time time, Atom property)
|
||||
: m_requestor(requestor),
|
||||
m_time(time),
|
||||
m_property(property),
|
||||
m_incr(false),
|
||||
m_failed(false),
|
||||
m_done(false),
|
||||
m_reading(false),
|
||||
m_error(false) {
|
||||
// do nothing
|
||||
}
|
||||
|
||||
XWindowsClipboard::CICCCMGetClipboard::~CICCCMGetClipboard() {
|
||||
// do nothing
|
||||
}
|
||||
m_property(property) {}
|
||||
|
||||
bool XWindowsClipboard::CICCCMGetClipboard::readClipboard(
|
||||
Display *display, Atom selection, Atom target, Atom *actualTarget,
|
||||
|
||||
@ -132,6 +132,7 @@ private:
|
||||
void fillCache() const;
|
||||
void doFillCache();
|
||||
|
||||
protected:
|
||||
//
|
||||
// helper classes
|
||||
//
|
||||
@ -140,7 +141,7 @@ private:
|
||||
class CICCCMGetClipboard {
|
||||
public:
|
||||
CICCCMGetClipboard(Window requestor, Time time, Atom property);
|
||||
~CICCCMGetClipboard();
|
||||
~CICCCMGetClipboard() = default;
|
||||
|
||||
// convert the given selection to the given type. returns
|
||||
// true iff the conversion was successful or the conversion
|
||||
@ -156,16 +157,16 @@ private:
|
||||
Window m_requestor;
|
||||
Time m_time;
|
||||
Atom m_property;
|
||||
bool m_incr;
|
||||
bool m_failed;
|
||||
bool m_done;
|
||||
bool m_incr = false;
|
||||
bool m_failed = false;
|
||||
bool m_done = false;
|
||||
|
||||
// atoms needed for the protocol
|
||||
Atom m_atomNone; // NONE, not None
|
||||
Atom m_atomIncr;
|
||||
Atom m_atomNone = None;
|
||||
Atom m_atomIncr = None;
|
||||
|
||||
// true iff we've received the selection notify
|
||||
bool m_reading;
|
||||
bool m_reading = false;
|
||||
|
||||
// the converted selection data
|
||||
String *m_data = nullptr;
|
||||
@ -174,18 +175,20 @@ private:
|
||||
// selection owner cannot convert to the requested type.
|
||||
Atom *m_actualTarget = nullptr;
|
||||
|
||||
public:
|
||||
// true iff the selection owner didn't follow ICCCM conventions
|
||||
bool m_error;
|
||||
bool m_error = false;
|
||||
|
||||
public:
|
||||
bool error() const { return m_error; }
|
||||
};
|
||||
|
||||
// Motif structure IDs
|
||||
enum { kMotifClipFormat = 1, kMotifClipItem, kMotifClipHeader };
|
||||
enum class MotifClip : SInt32 { Format = 1, Item = 2, Header = 3 };
|
||||
|
||||
// _MOTIF_CLIP_HEADER structure
|
||||
class MotifClipHeader {
|
||||
public:
|
||||
SInt32 m_id; // kMotifClipHeader
|
||||
MotifClip m_id;
|
||||
SInt32 m_pad1[3];
|
||||
SInt32 m_item;
|
||||
SInt32 m_pad2[4];
|
||||
@ -198,7 +201,7 @@ private:
|
||||
// Motif clip item structure
|
||||
class MotifClipItem {
|
||||
public:
|
||||
SInt32 m_id; // kMotifClipItem
|
||||
MotifClip m_id;
|
||||
SInt32 m_pad1[5];
|
||||
SInt32 m_size;
|
||||
SInt32 m_numFormats;
|
||||
@ -209,7 +212,7 @@ private:
|
||||
// Motif clip format structure
|
||||
class MotifClipFormat {
|
||||
public:
|
||||
SInt32 m_id; // kMotifClipFormat
|
||||
MotifClip m_id;
|
||||
SInt32 m_pad1[6];
|
||||
SInt32 m_length;
|
||||
SInt32 m_data;
|
||||
|
||||
@ -17,7 +17,7 @@
|
||||
file(GLOB headers "*.h")
|
||||
file(GLOB sources "*.cpp")
|
||||
|
||||
if(SYNERGY_ADD_HEADERS)
|
||||
if(ADD_HEADERS_TO_SOURCES)
|
||||
list(APPEND sources ${headers})
|
||||
endif()
|
||||
|
||||
|
||||
@ -17,7 +17,7 @@
|
||||
file(GLOB headers "*.h")
|
||||
file(GLOB sources "*.cpp")
|
||||
|
||||
if(SYNERGY_ADD_HEADERS)
|
||||
if(ADD_HEADERS_TO_SOURCES)
|
||||
list(APPEND sources ${headers})
|
||||
endif()
|
||||
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2012-2016 Symless Ltd.
|
||||
* Copyright (C) 2012 Nick Bolton
|
||||
* Copyright (C) 2012 Symless Ltd.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@ -16,11 +15,14 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "ipc/Ipc.h"
|
||||
#include "Ipc.h"
|
||||
|
||||
const char *kIpcMsgHello = "IHEL%1i";
|
||||
const char *kIpcMsgHelloBack = "IHEL";
|
||||
const char *kIpcMsgLogLine = "ILOG%s";
|
||||
const char *kIpcMsgCommand = "ICMD%s%1i";
|
||||
const char *kIpcMsgShutdown = "ISDN";
|
||||
const char *kIpcMsgSetting = "SSET%s%s";
|
||||
const char *const kIpcHost = "127.0.0.1";
|
||||
const int kIpcPort = 24801;
|
||||
|
||||
const char *const kIpcMsgHello = "IHEL%1i";
|
||||
const char *const kIpcMsgHelloBack = "IHEL";
|
||||
const char *const kIpcMsgLogLine = "ILOG%s";
|
||||
const char *const kIpcMsgCommand = "ICMD%s%1i";
|
||||
const char *const kIpcMsgShutdown = "ISDN";
|
||||
const char *const kIpcMsgSetting = "SSET%s%s";
|
||||
@ -1,7 +1,6 @@
|
||||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2012-2016 Symless Ltd.
|
||||
* Copyright (C) 2012 Nick Bolton
|
||||
* Copyright (C) 2012 Symless Ltd.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@ -18,42 +17,44 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#define IPC_HOST "127.0.0.1"
|
||||
#define IPC_PORT 24801
|
||||
#include "common/basic_types.h"
|
||||
|
||||
enum EIpcMessage {
|
||||
kIpcHello,
|
||||
kIpcHelloBack,
|
||||
kIpcLogLine,
|
||||
kIpcCommand,
|
||||
kIpcShutdown,
|
||||
kIpcSetting
|
||||
enum class IpcMessageType : UInt8 {
|
||||
Hello,
|
||||
HelloBack,
|
||||
LogLine,
|
||||
Command,
|
||||
Shutdown,
|
||||
Setting
|
||||
};
|
||||
|
||||
enum EIpcClientType { kIpcClientUnknown, kIpcClientGui, kIpcClientNode };
|
||||
enum class IpcClientType { Unknown, GUI, Node };
|
||||
|
||||
extern const char *const kIpcHost;
|
||||
extern const int kIpcPort;
|
||||
|
||||
// handshake: node/gui -> daemon
|
||||
// $1 = type, the client identifies it's self as gui or node (synergyc/s).
|
||||
extern const char *kIpcMsgHello;
|
||||
extern const char *const kIpcMsgHello;
|
||||
|
||||
// handshake: daemon -> node/gui
|
||||
// the daemon responds to the handshake.
|
||||
extern const char *kIpcMsgHelloBack;
|
||||
extern const char *const kIpcMsgHelloBack;
|
||||
|
||||
// log line: daemon -> gui
|
||||
// $1 = aggregate log lines collected from synergys/c or the daemon itself.
|
||||
extern const char *kIpcMsgLogLine;
|
||||
extern const char *const kIpcMsgLogLine;
|
||||
|
||||
// command: gui -> daemon
|
||||
// $1 = command; the command for the daemon to launch, typically the full
|
||||
// path to synergys/c. $2 = true when process must be elevated on ms windows.
|
||||
extern const char *kIpcMsgCommand;
|
||||
extern const char *const kIpcMsgCommand;
|
||||
|
||||
// shutdown: daemon -> node
|
||||
// the daemon tells synergys/c to shut down gracefully.
|
||||
extern const char *kIpcMsgShutdown;
|
||||
extern const char *const kIpcMsgShutdown;
|
||||
|
||||
// set setting: gui -> daemon
|
||||
// $1 = setting name
|
||||
// $2 = setting value
|
||||
extern const char *kIpcMsgSetting;
|
||||
extern const char *const kIpcMsgSetting;
|
||||
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2012-2016 Symless Ltd.
|
||||
* Copyright (C) 2012 Symless Ltd.
|
||||
* Copyright (C) 2002 Chris Schoeneman
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
@ -27,9 +27,9 @@
|
||||
#include "base/XBase.h"
|
||||
#include "base/log_outputters.h"
|
||||
#include "common/Version.h"
|
||||
#include "ipc/Ipc.h"
|
||||
#include "ipc/IpcMessage.h"
|
||||
#include "ipc/IpcServerProxy.h"
|
||||
#include "shared/Ipc.h"
|
||||
#include "synergy/ArgsBase.h"
|
||||
#include "synergy/XSynergy.h"
|
||||
#include "synergy/protocol_types.h"
|
||||
@ -230,7 +230,7 @@ void App::cleanupIpcClient() {
|
||||
|
||||
void App::handleIpcMessage(const Event &e, void *) {
|
||||
IpcMessage *m = static_cast<IpcMessage *>(e.getDataObject());
|
||||
if (m->type() == kIpcShutdown) {
|
||||
if (m->type() == IpcMessageType::Shutdown) {
|
||||
LOG((CLOG_INFO "got ipc shutdown message"));
|
||||
m_events->addEvent(Event(Event::kQuit));
|
||||
}
|
||||
|
||||
@ -39,7 +39,7 @@ endif()
|
||||
list(APPEND sources ${arch_sources})
|
||||
list(APPEND headers ${arch_headers})
|
||||
|
||||
if(SYNERGY_ADD_HEADERS)
|
||||
if(ADD_HEADERS_TO_SOURCES)
|
||||
list(APPEND sources ${headers})
|
||||
endif()
|
||||
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2012-2016 Symless Ltd.
|
||||
* Copyright (C) 2012 Nick Bolton
|
||||
* Copyright (C) 2012 Symless Ltd.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@ -25,41 +24,43 @@
|
||||
#include "base/EventQueue.h"
|
||||
#include "base/Log.h"
|
||||
#include "base/TMethodEventJob.h"
|
||||
#include "base/TMethodJob.h"
|
||||
#include "base/log_outputters.h"
|
||||
#include "ipc/Ipc.h"
|
||||
#include "ipc/IpcClientProxy.h"
|
||||
#include "ipc/IpcLogOutputter.h"
|
||||
#include "ipc/IpcMessage.h"
|
||||
#include "ipc/IpcSettingMessage.h"
|
||||
#include "net/SocketMultiplexer.h"
|
||||
#include "shared/Ipc.h"
|
||||
#include "synergy/App.h"
|
||||
#include "synergy/ArgParser.h"
|
||||
#include "synergy/ClientArgs.h"
|
||||
#include "synergy/ServerArgs.h"
|
||||
#include "synergy/protocol_types.h"
|
||||
|
||||
#if SYSAPI_WIN32
|
||||
|
||||
#include "arch/win32/ArchMiscWindows.h"
|
||||
#include "arch/win32/XArchWindows.h"
|
||||
#include "platform/MSWindowsDebugOutputter.h"
|
||||
#include "platform/MSWindowsEventQueueBuffer.h"
|
||||
#include "platform/MSWindowsScreen.h"
|
||||
#include "platform/MSWindowsWatchdog.h"
|
||||
#include "synergy/Screen.h"
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <Windows.h>
|
||||
|
||||
#endif
|
||||
#elif SYSAPI_UNIX
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#endif
|
||||
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
using namespace std;
|
||||
|
||||
const char *const kLogFilename = "synergyd.log";
|
||||
|
||||
namespace {
|
||||
void updateSetting(const IpcMessage &message) {
|
||||
try {
|
||||
@ -84,7 +85,7 @@ bool isServerCommandLine(const std::vector<String> &cmd) {
|
||||
|
||||
} // namespace
|
||||
|
||||
DaemonApp *DaemonApp::s_instance = NULL;
|
||||
DaemonApp *DaemonApp::s_instance = nullptr;
|
||||
|
||||
int mainLoopStatic() {
|
||||
DaemonApp::s_instance->mainLoop(true);
|
||||
@ -99,18 +100,9 @@ int winMainLoopStatic(int, const char **) {
|
||||
}
|
||||
#endif
|
||||
|
||||
DaemonApp::DaemonApp()
|
||||
: m_ipcServer(nullptr),
|
||||
m_ipcLogOutputter(nullptr),
|
||||
#if SYSAPI_WIN32
|
||||
m_watchdog(nullptr),
|
||||
#endif
|
||||
m_events(nullptr),
|
||||
m_fileLogOutputter(nullptr) {
|
||||
s_instance = this;
|
||||
}
|
||||
DaemonApp::DaemonApp() { s_instance = this; }
|
||||
|
||||
DaemonApp::~DaemonApp() {}
|
||||
DaemonApp::~DaemonApp() { s_instance = nullptr; }
|
||||
|
||||
int DaemonApp::run(int argc, char **argv) {
|
||||
#if SYSAPI_WIN32
|
||||
@ -122,8 +114,7 @@ int DaemonApp::run(int argc, char **argv) {
|
||||
arch.init();
|
||||
|
||||
Log log;
|
||||
EventQueue events;
|
||||
m_events = &events;
|
||||
m_events = std::make_unique<EventQueue>();
|
||||
|
||||
bool uninstall = false;
|
||||
try {
|
||||
@ -134,8 +125,7 @@ int DaemonApp::run(int argc, char **argv) {
|
||||
#endif
|
||||
|
||||
// default log level to system setting.
|
||||
string logLevel = arch.setting("LogLevel");
|
||||
if (logLevel != "")
|
||||
if (string logLevel = arch.setting("LogLevel"); logLevel != "")
|
||||
log.setFilter(logLevel.c_str());
|
||||
|
||||
bool foreground = false;
|
||||
@ -210,8 +200,9 @@ void DaemonApp::mainLoop(bool logToFile, bool foreground) {
|
||||
DAEMON_RUNNING(true);
|
||||
|
||||
if (logToFile) {
|
||||
m_fileLogOutputter = new FileLogOutputter(logFilename().c_str());
|
||||
CLOG->insert(m_fileLogOutputter);
|
||||
m_fileLogOutputter =
|
||||
std::make_unique<FileLogOutputter>(logFilename().c_str());
|
||||
CLOG->insert(m_fileLogOutputter.get());
|
||||
}
|
||||
|
||||
// create socket multiplexer. this must happen after daemonization
|
||||
@ -219,20 +210,21 @@ void DaemonApp::mainLoop(bool logToFile, bool foreground) {
|
||||
SocketMultiplexer multiplexer;
|
||||
|
||||
// uses event queue, must be created here.
|
||||
m_ipcServer = new IpcServer(m_events, &multiplexer);
|
||||
m_ipcServer = std::make_unique<IpcServer>(m_events.get(), &multiplexer);
|
||||
|
||||
// send logging to gui via ipc, log system adopts outputter.
|
||||
m_ipcLogOutputter = new IpcLogOutputter(*m_ipcServer, kIpcClientGui, true);
|
||||
CLOG->insert(m_ipcLogOutputter);
|
||||
m_ipcLogOutputter = std::make_unique<IpcLogOutputter>(
|
||||
*m_ipcServer, IpcClientType::GUI, true);
|
||||
CLOG->insert(m_ipcLogOutputter.get());
|
||||
|
||||
#if SYSAPI_WIN32
|
||||
m_watchdog = new MSWindowsWatchdog(
|
||||
m_watchdog = std::make_unique<MSWindowsWatchdog>(
|
||||
false, *m_ipcServer, *m_ipcLogOutputter, foreground);
|
||||
m_watchdog->setFileLogOutputter(m_fileLogOutputter);
|
||||
m_watchdog->setFileLogOutputter(m_fileLogOutputter.get());
|
||||
#endif
|
||||
|
||||
m_events->adoptHandler(
|
||||
m_events->forIpcServer().messageReceived(), m_ipcServer,
|
||||
m_events->forIpcServer().messageReceived(), m_ipcServer.get(),
|
||||
new TMethodEventJob<DaemonApp>(this, &DaemonApp::handleIpcMessage));
|
||||
|
||||
m_ipcServer->listen();
|
||||
@ -240,7 +232,7 @@ void DaemonApp::mainLoop(bool logToFile, bool foreground) {
|
||||
#if SYSAPI_WIN32
|
||||
|
||||
// install the platform event queue to handle service stop events.
|
||||
m_events->adoptBuffer(new MSWindowsEventQueueBuffer(m_events));
|
||||
m_events->adoptBuffer(new MSWindowsEventQueueBuffer(m_events.get()));
|
||||
|
||||
String command = ARCH->setting("Command");
|
||||
bool elevate = ARCH->setting("Elevate") == "1";
|
||||
@ -255,15 +247,12 @@ void DaemonApp::mainLoop(bool logToFile, bool foreground) {
|
||||
|
||||
#if SYSAPI_WIN32
|
||||
m_watchdog->stop();
|
||||
delete m_watchdog;
|
||||
#endif
|
||||
|
||||
m_events->removeHandler(
|
||||
m_events->forIpcServer().messageReceived(), m_ipcServer);
|
||||
m_events->forIpcServer().messageReceived(), m_ipcServer.get());
|
||||
|
||||
CLOG->remove(m_ipcLogOutputter);
|
||||
delete m_ipcLogOutputter;
|
||||
delete m_ipcServer;
|
||||
CLOG->remove(m_ipcLogOutputter.get());
|
||||
|
||||
DAEMON_RUNNING(false);
|
||||
} catch (std::exception &e) {
|
||||
@ -287,7 +276,7 @@ std::string DaemonApp::logFilename() {
|
||||
if (logFilename.empty()) {
|
||||
logFilename = ARCH->getLogDirectory();
|
||||
logFilename.append("/");
|
||||
logFilename.append(LOG_FILENAME);
|
||||
logFilename.append(kLogFilename);
|
||||
}
|
||||
|
||||
return logFilename;
|
||||
@ -296,7 +285,7 @@ std::string DaemonApp::logFilename() {
|
||||
void DaemonApp::handleIpcMessage(const Event &e, void *) {
|
||||
IpcMessage *m = static_cast<IpcMessage *>(e.getDataObject());
|
||||
switch (m->type()) {
|
||||
case kIpcCommand: {
|
||||
case IpcMessageType::Command: {
|
||||
IpcCommandMessage *cm = static_cast<IpcCommandMessage *>(m);
|
||||
String command = cm->command();
|
||||
|
||||
@ -361,14 +350,14 @@ void DaemonApp::handleIpcMessage(const Event &e, void *) {
|
||||
break;
|
||||
}
|
||||
|
||||
case kIpcHello: {
|
||||
case IpcMessageType::Hello: {
|
||||
IpcHelloMessage *hm = static_cast<IpcHelloMessage *>(m);
|
||||
String type;
|
||||
switch (hm->clientType()) {
|
||||
case kIpcClientGui:
|
||||
case IpcClientType::GUI:
|
||||
type = "gui";
|
||||
break;
|
||||
case kIpcClientNode:
|
||||
case IpcClientType::Node:
|
||||
type = "node";
|
||||
break;
|
||||
default:
|
||||
@ -379,7 +368,7 @@ void DaemonApp::handleIpcMessage(const Event &e, void *) {
|
||||
LOG((CLOG_DEBUG "ipc hello, type=%s", type.c_str()));
|
||||
|
||||
// TODO: implement hello back handling in s1 gui and node (server/client).
|
||||
if (hm->clientType() == kIpcClientGui) {
|
||||
if (hm->clientType() == IpcClientType::GUI) {
|
||||
LOG((CLOG_DEBUG "sending ipc hello back"));
|
||||
IpcHelloBackMessage hbm;
|
||||
m_ipcServer->send(hbm, hm->clientType());
|
||||
@ -394,7 +383,7 @@ void DaemonApp::handleIpcMessage(const Event &e, void *) {
|
||||
break;
|
||||
}
|
||||
|
||||
case kIpcSetting:
|
||||
case IpcMessageType::Setting:
|
||||
updateSetting(*m);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2012-2016 Symless Ltd.
|
||||
* Copyright (C) 2012 Nick Bolton
|
||||
* Copyright (C) 2012 Symless Ltd.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@ -18,9 +17,9 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "arch/Arch.h"
|
||||
#include "ipc/IpcServer.h"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
class Event;
|
||||
@ -31,11 +30,13 @@ class FileLogOutputter;
|
||||
class MSWindowsWatchdog;
|
||||
#endif
|
||||
|
||||
extern const char *const kLogFilename;
|
||||
|
||||
class DaemonApp {
|
||||
|
||||
public:
|
||||
DaemonApp();
|
||||
virtual ~DaemonApp();
|
||||
~DaemonApp();
|
||||
int run(int argc, char **argv);
|
||||
void mainLoop(bool logToFile, bool foreground = false);
|
||||
|
||||
@ -49,14 +50,12 @@ public:
|
||||
static DaemonApp *s_instance;
|
||||
|
||||
#if SYSAPI_WIN32
|
||||
MSWindowsWatchdog *m_watchdog;
|
||||
std::unique_ptr<MSWindowsWatchdog> m_watchdog;
|
||||
#endif
|
||||
|
||||
private:
|
||||
IpcServer *m_ipcServer;
|
||||
IpcLogOutputter *m_ipcLogOutputter;
|
||||
IEventQueue *m_events;
|
||||
FileLogOutputter *m_fileLogOutputter;
|
||||
std::unique_ptr<IpcServer> m_ipcServer;
|
||||
std::unique_ptr<IpcLogOutputter> m_ipcLogOutputter;
|
||||
std::unique_ptr<IEventQueue> m_events;
|
||||
std::unique_ptr<FileLogOutputter> m_fileLogOutputter;
|
||||
};
|
||||
|
||||
#define LOG_FILENAME "synergyd.log"
|
||||
|
||||
@ -14,18 +14,158 @@
|
||||
# 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_directories(
|
||||
../../ext/googletest/googletest ../../ext/googletest/googletest/include
|
||||
../../ext/googletest/googlemock ../../ext/googletest/googlemock/include)
|
||||
macro(config_all_tests)
|
||||
|
||||
add_library(gtest STATIC ../../ext/googletest/googletest/src/gtest-all.cc)
|
||||
add_library(gmock STATIC ../../ext/googletest/googlemock/src/gmock-all.cc)
|
||||
set(base_dir ${CMAKE_SOURCE_DIR})
|
||||
set(src_dir ${base_dir}/src)
|
||||
set(test_base_dir ${src_dir}/test)
|
||||
set(ext_dir ${base_dir}/ext)
|
||||
set(gtest_base_dir ${ext_dir}/googletest)
|
||||
set(gui_dir ${src_dir}/gui/src)
|
||||
|
||||
if(UNIX)
|
||||
# ignore warnings in gtest and gmock
|
||||
set_target_properties(gtest PROPERTIES COMPILE_FLAGS "-w")
|
||||
set_target_properties(gmock PROPERTIES COMPILE_FLAGS "-w")
|
||||
endif()
|
||||
config_test_deps()
|
||||
|
||||
add_subdirectory(integtests)
|
||||
add_subdirectory(unittests)
|
||||
add_subdirectory(integtests)
|
||||
add_subdirectory(unittests)
|
||||
|
||||
endmacro()
|
||||
|
||||
macro(config_test)
|
||||
|
||||
include_directories(
|
||||
${test_base_dir}
|
||||
${src_dir}
|
||||
${src_dir}/lib
|
||||
${gui_dir}
|
||||
${ext_dir})
|
||||
|
||||
set_sources()
|
||||
|
||||
endmacro()
|
||||
|
||||
macro(set_sources)
|
||||
|
||||
file(GLOB_RECURSE headers ${CMAKE_CURRENT_SOURCE_DIR}/*.h)
|
||||
file(GLOB_RECURSE sources ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
|
||||
|
||||
file(GLOB_RECURSE shared_headers ${test_base_dir}/shared/*.h)
|
||||
file(GLOB_RECURSE shared_sources ${test_base_dir}/shared/*.cpp)
|
||||
|
||||
list(APPEND headers ${shared_headers})
|
||||
list(APPEND sources ${shared_sources})
|
||||
|
||||
file(GLOB_RECURSE mock_headers ${test_base_dir}/mock/*.h)
|
||||
file(GLOB_RECURSE mock_sources ${test_base_dir}/mock/*.cpp)
|
||||
|
||||
list(APPEND headers ${mock_headers})
|
||||
list(APPEND sources ${mock_sources})
|
||||
|
||||
file(GLOB_RECURSE gui_sources ${gui_dir}/*.cpp)
|
||||
|
||||
file(GLOB activation_sources ${gui_dir}/*Activation* ${gui_dir}/*License*)
|
||||
if(NOT ENABLE_LICENSING)
|
||||
list(REMOVE_ITEM gui_sources ${activation_sources})
|
||||
endif()
|
||||
|
||||
# remove main gui as the test already has its own main.
|
||||
file(GLOB gui_main ${gui_dir}/main.cpp)
|
||||
list(REMOVE_ITEM gui_sources ${gui_main})
|
||||
|
||||
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
file(GLOB mac_gui_sources ${gui_dir}/*.mm)
|
||||
list(APPEND gui_sources ${mac_gui_sources})
|
||||
endif()
|
||||
|
||||
list(APPEND sources ${gui_sources})
|
||||
|
||||
if(ADD_HEADERS_TO_SOURCES)
|
||||
list(APPEND sources ${headers})
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
list(APPEND sources ${CMAKE_BINARY_DIR}/src/version.rc)
|
||||
endif()
|
||||
|
||||
add_platform_sources()
|
||||
|
||||
endmacro()
|
||||
|
||||
macro(add_platform_sources)
|
||||
|
||||
set(platform_dir ${CMAKE_CURRENT_SOURCE_DIR}/platform)
|
||||
|
||||
# Remove platform files so that specific platform files can be added later.
|
||||
# This is a bit weird, but it's simpler to include everything, remove all
|
||||
# platform files, then only include the platforms we need.
|
||||
file(GLOB_RECURSE all_platform_files ${platform_dir}/*)
|
||||
list(REMOVE_ITEM headers ${all_platform_files})
|
||||
list(REMOVE_ITEM sources ${all_platform_files})
|
||||
|
||||
if(WIN32)
|
||||
file(GLOB platform_sources ${platform_dir}/MSWindows*.cpp)
|
||||
file(GLOB platform_headers ${platform_dir}/MSWindows*.h)
|
||||
elseif(APPLE)
|
||||
file(GLOB platform_sources ${platform_dir}/OSX*.cpp)
|
||||
file(GLOB platform_headers ${platform_dir}/OSX*.h)
|
||||
elseif(UNIX)
|
||||
file(GLOB platform_sources ${platform_dir}/XWindows*.cpp)
|
||||
file(GLOB platform_headers ${platform_dir}/XWindows*.h)
|
||||
endif()
|
||||
|
||||
list(APPEND sources ${platform_sources})
|
||||
list(APPEND headers ${platform_headers})
|
||||
|
||||
endmacro()
|
||||
|
||||
macro(config_test_deps)
|
||||
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_AUTORCC ON)
|
||||
set(CMAKE_AUTOUIC ON)
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
|
||||
find_package(
|
||||
Qt6
|
||||
COMPONENTS Core Widgets Network Test
|
||||
REQUIRED)
|
||||
|
||||
set(gtest_dir ${gtest_base_dir}/googletest)
|
||||
set(gmock_dir ${gtest_base_dir}/googlemock)
|
||||
|
||||
include_directories(${gtest_dir} ${gmock_dir} ${gtest_dir}/include
|
||||
${gmock_dir}/include)
|
||||
|
||||
add_library(gtest STATIC ${gtest_dir}/src/gtest-all.cc)
|
||||
add_library(gmock STATIC ${gmock_dir}/src/gmock-all.cc)
|
||||
|
||||
if(UNIX)
|
||||
# ignore warnings in gtest and gmock
|
||||
set_target_properties(gtest PROPERTIES COMPILE_FLAGS "-w")
|
||||
set_target_properties(gmock PROPERTIES COMPILE_FLAGS "-w")
|
||||
endif()
|
||||
|
||||
set(test_libs
|
||||
arch
|
||||
base
|
||||
client
|
||||
server
|
||||
common
|
||||
io
|
||||
net
|
||||
platform
|
||||
server
|
||||
synlib
|
||||
mt
|
||||
ipc
|
||||
gtest
|
||||
gmock
|
||||
shared
|
||||
Qt6::Core
|
||||
Qt6::Widgets
|
||||
Qt6::Network
|
||||
Qt6::Test
|
||||
${libs})
|
||||
|
||||
endmacro()
|
||||
|
||||
config_all_tests()
|
||||
|
||||
@ -14,67 +14,7 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
file(GLOB_RECURSE headers "*.h")
|
||||
file(GLOB_RECURSE sources "*.cpp")
|
||||
|
||||
# remove platform files (specific platform added later).
|
||||
file(GLOB_RECURSE remove_platform "platform/*")
|
||||
list(REMOVE_ITEM headers ${remove_platform})
|
||||
list(REMOVE_ITEM sources ${remove_platform})
|
||||
|
||||
# platform
|
||||
if(WIN32)
|
||||
file(GLOB platform_sources "platform/MSWindows*.cpp")
|
||||
file(GLOB platform_headers "platform/MSWindows*.h")
|
||||
elseif(APPLE)
|
||||
file(GLOB platform_sources "platform/OSX*.cpp")
|
||||
file(GLOB platform_headers "platform/OSX*.h")
|
||||
elseif(UNIX)
|
||||
file(GLOB platform_sources "platform/XWindows*.cpp")
|
||||
file(GLOB platform_headers "platform/XWindows*.h")
|
||||
endif()
|
||||
|
||||
list(APPEND sources ${platform_sources})
|
||||
list(APPEND headers ${platform_headers})
|
||||
|
||||
file(GLOB_RECURSE shared_headers "../../test/shared/*.h")
|
||||
file(GLOB_RECURSE shared_sources "../../test/shared/*.cpp")
|
||||
|
||||
list(APPEND headers ${shared_headers})
|
||||
list(APPEND sources ${shared_sources})
|
||||
|
||||
file(GLOB_RECURSE mock_headers "../../test/mock/*.h")
|
||||
file(GLOB_RECURSE mock_sources "../../test/mock/*.cpp")
|
||||
|
||||
list(APPEND headers ${mock_headers})
|
||||
list(APPEND sources ${mock_sources})
|
||||
|
||||
if(SYNERGY_ADD_HEADERS)
|
||||
list(APPEND sources ${headers})
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
list(APPEND sources ${CMAKE_BINARY_DIR}/src/version.rc)
|
||||
endif()
|
||||
|
||||
include_directories(
|
||||
../../ ../../lib/ ../../../ext/googletest/googletest/include
|
||||
../../../ext/googletest/googlemock/include)
|
||||
|
||||
add_executable(integtests ${sources})
|
||||
target_link_libraries(
|
||||
integtests
|
||||
arch
|
||||
base
|
||||
client
|
||||
common
|
||||
io
|
||||
ipc
|
||||
mt
|
||||
net
|
||||
platform
|
||||
server
|
||||
synlib
|
||||
gtest
|
||||
gmock
|
||||
${libs})
|
||||
config_test()
|
||||
set(target integtests)
|
||||
add_executable(${target} ${sources})
|
||||
target_link_libraries(${target} ${test_libs})
|
||||
|
||||
@ -27,7 +27,6 @@
|
||||
#include "base/String.h"
|
||||
#include "base/TMethodEventJob.h"
|
||||
#include "base/TMethodJob.h"
|
||||
#include "ipc/Ipc.h"
|
||||
#include "ipc/IpcClient.h"
|
||||
#include "ipc/IpcClientProxy.h"
|
||||
#include "ipc/IpcMessage.h"
|
||||
@ -35,11 +34,12 @@
|
||||
#include "ipc/IpcServerProxy.h"
|
||||
#include "mt/Thread.h"
|
||||
#include "net/SocketMultiplexer.h"
|
||||
#include "shared/Ipc.h"
|
||||
#include "test/shared/TestEventQueue.h"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#define TEST_IPC_PORT 24802
|
||||
const int kTestPort = 24802;
|
||||
|
||||
class IpcTests : public ::testing::Test {
|
||||
public:
|
||||
@ -65,7 +65,7 @@ public:
|
||||
|
||||
TEST_F(IpcTests, connectToServer) {
|
||||
SocketMultiplexer socketMultiplexer;
|
||||
IpcServer server(&m_events, &socketMultiplexer, TEST_IPC_PORT);
|
||||
IpcServer server(&m_events, &socketMultiplexer, kTestPort);
|
||||
server.listen();
|
||||
m_connectToServer_server = &server;
|
||||
|
||||
@ -74,7 +74,7 @@ TEST_F(IpcTests, connectToServer) {
|
||||
new TMethodEventJob<IpcTests>(
|
||||
this, &IpcTests::connectToServer_handleMessageReceived));
|
||||
|
||||
IpcClient client(&m_events, &socketMultiplexer, TEST_IPC_PORT);
|
||||
IpcClient client(&m_events, &socketMultiplexer, kTestPort);
|
||||
client.connect();
|
||||
|
||||
m_events.initQuitTimeout(5);
|
||||
@ -88,7 +88,7 @@ TEST_F(IpcTests, connectToServer) {
|
||||
|
||||
TEST_F(IpcTests, sendMessageToServer) {
|
||||
SocketMultiplexer socketMultiplexer;
|
||||
IpcServer server(&m_events, &socketMultiplexer, TEST_IPC_PORT);
|
||||
IpcServer server(&m_events, &socketMultiplexer, kTestPort);
|
||||
server.listen();
|
||||
|
||||
// event handler sends "test" command to server.
|
||||
@ -97,7 +97,7 @@ TEST_F(IpcTests, sendMessageToServer) {
|
||||
new TMethodEventJob<IpcTests>(
|
||||
this, &IpcTests::sendMessageToServer_serverHandleMessageReceived));
|
||||
|
||||
IpcClient client(&m_events, &socketMultiplexer, TEST_IPC_PORT);
|
||||
IpcClient client(&m_events, &socketMultiplexer, kTestPort);
|
||||
client.connect();
|
||||
m_sendMessageToServer_client = &client;
|
||||
|
||||
@ -111,7 +111,7 @@ TEST_F(IpcTests, sendMessageToServer) {
|
||||
|
||||
TEST_F(IpcTests, sendMessageToClient) {
|
||||
SocketMultiplexer socketMultiplexer;
|
||||
IpcServer server(&m_events, &socketMultiplexer, TEST_IPC_PORT);
|
||||
IpcServer server(&m_events, &socketMultiplexer, kTestPort);
|
||||
server.listen();
|
||||
m_sendMessageToClient_server = &server;
|
||||
|
||||
@ -121,7 +121,7 @@ TEST_F(IpcTests, sendMessageToClient) {
|
||||
new TMethodEventJob<IpcTests>(
|
||||
this, &IpcTests::sendMessageToClient_serverHandleClientConnected));
|
||||
|
||||
IpcClient client(&m_events, &socketMultiplexer, TEST_IPC_PORT);
|
||||
IpcClient client(&m_events, &socketMultiplexer, kTestPort);
|
||||
client.connect();
|
||||
|
||||
m_events.adoptHandler(
|
||||
@ -149,9 +149,9 @@ IpcTests::~IpcTests() {}
|
||||
|
||||
void IpcTests::connectToServer_handleMessageReceived(const Event &e, void *) {
|
||||
IpcMessage *m = static_cast<IpcMessage *>(e.getDataObject());
|
||||
if (m->type() == kIpcHello) {
|
||||
if (m->type() == IpcMessageType::Hello) {
|
||||
m_connectToServer_hasClientNode =
|
||||
m_connectToServer_server->hasClients(kIpcClientNode);
|
||||
m_connectToServer_server->hasClients(IpcClientType::Node);
|
||||
m_connectToServer_helloMessageReceived = true;
|
||||
m_events.raiseQuitEvent();
|
||||
}
|
||||
@ -160,11 +160,11 @@ void IpcTests::connectToServer_handleMessageReceived(const Event &e, void *) {
|
||||
void IpcTests::sendMessageToServer_serverHandleMessageReceived(
|
||||
const Event &e, void *) {
|
||||
IpcMessage *m = static_cast<IpcMessage *>(e.getDataObject());
|
||||
if (m->type() == kIpcHello) {
|
||||
if (m->type() == IpcMessageType::Hello) {
|
||||
LOG((CLOG_DEBUG "client said hello, sending test to server"));
|
||||
IpcCommandMessage m("test", true);
|
||||
m_sendMessageToServer_client->send(m);
|
||||
} else if (m->type() == kIpcCommand) {
|
||||
} else if (m->type() == IpcMessageType::Command) {
|
||||
IpcCommandMessage *cm = static_cast<IpcCommandMessage *>(m);
|
||||
LOG((CLOG_DEBUG "got ipc command message, %d", cm->command().c_str()));
|
||||
m_sendMessageToServer_receivedString = cm->command();
|
||||
@ -175,17 +175,17 @@ void IpcTests::sendMessageToServer_serverHandleMessageReceived(
|
||||
void IpcTests::sendMessageToClient_serverHandleClientConnected(
|
||||
const Event &e, void *) {
|
||||
IpcMessage *m = static_cast<IpcMessage *>(e.getDataObject());
|
||||
if (m->type() == kIpcHello) {
|
||||
if (m->type() == IpcMessageType::Hello) {
|
||||
LOG((CLOG_DEBUG "client said hello, sending test to client"));
|
||||
IpcLogLineMessage m("test");
|
||||
m_sendMessageToClient_server->send(m, kIpcClientNode);
|
||||
m_sendMessageToClient_server->send(m, IpcClientType::Node);
|
||||
}
|
||||
}
|
||||
|
||||
void IpcTests::sendMessageToClient_clientHandleMessageReceived(
|
||||
const Event &e, void *) {
|
||||
IpcMessage *m = static_cast<IpcMessage *>(e.getDataObject());
|
||||
if (m->type() == kIpcLogLine) {
|
||||
if (m->type() == IpcMessageType::LogLine) {
|
||||
IpcLogLineMessage *llm = static_cast<IpcLogLineMessage *>(m);
|
||||
LOG((CLOG_DEBUG "got ipc log message, %d", llm->logLine().c_str()));
|
||||
m_sendMessageToClient_receivedString = llm->logLine();
|
||||
|
||||
@ -16,142 +16,122 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// TODO: fix tests - compile error on linux
|
||||
#if 0
|
||||
|
||||
#include "platform/XWindowsClipboard.h"
|
||||
|
||||
#include "test/shared/undef_x11_macros.h"
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
#include <iostream>
|
||||
#include <memory>
|
||||
|
||||
class CXWindowsClipboardTests : public ::testing::Test
|
||||
{
|
||||
class XWindowsClipboardTests : public ::testing::Test {
|
||||
protected:
|
||||
virtual void
|
||||
SetUp()
|
||||
{
|
||||
m_display = XOpenDisplay(NULL);
|
||||
int screen = DefaultScreen(m_display);
|
||||
Window root = XRootWindow(m_display, screen);
|
||||
|
||||
XSetWindowAttributes attr;
|
||||
attr.do_not_propagate_mask = 0;
|
||||
attr.override_redirect = True;
|
||||
attr.cursor = Cursor();
|
||||
|
||||
m_window = XCreateWindow(
|
||||
m_display, root, 0, 0, 1, 1, 0, 0,
|
||||
InputOnly, CopyFromParent, 0, &attr);
|
||||
}
|
||||
void SetUp() override {
|
||||
m_display = XOpenDisplay(nullptr);
|
||||
int screen = DefaultScreen(m_display);
|
||||
Window root = XRootWindow(m_display, screen);
|
||||
|
||||
virtual void
|
||||
TearDown()
|
||||
{
|
||||
XDestroyWindow(m_display, m_window);
|
||||
XCloseDisplay(m_display);
|
||||
}
|
||||
XSetWindowAttributes attr;
|
||||
attr.do_not_propagate_mask = 0;
|
||||
attr.override_redirect = True;
|
||||
attr.cursor = Cursor();
|
||||
|
||||
CXWindowsClipboard&
|
||||
createClipboard()
|
||||
{
|
||||
CXWindowsClipboard* clipboard;
|
||||
clipboard = new CXWindowsClipboard(m_display, m_window, 0);
|
||||
clipboard->open(0); // needed to empty the clipboard
|
||||
clipboard->empty(); // needed to own the clipboard
|
||||
return *clipboard;
|
||||
}
|
||||
m_window = XCreateWindow(
|
||||
m_display, root, 0, 0, 1, 1, 0, 0, InputOnly, nullptr, 0, &attr);
|
||||
|
||||
Display* m_display;
|
||||
Window m_window;
|
||||
m_clipboard = std::make_unique<XWindowsClipboard>(m_display, m_window, 0);
|
||||
m_clipboard->open(0);
|
||||
m_clipboard->empty();
|
||||
}
|
||||
|
||||
void TearDown() override {
|
||||
XDestroyWindow(m_display, m_window);
|
||||
XCloseDisplay(m_display);
|
||||
}
|
||||
|
||||
XWindowsClipboard &getClipboard() { return *m_clipboard; }
|
||||
|
||||
private:
|
||||
Display *m_display;
|
||||
Window m_window;
|
||||
std::unique_ptr<XWindowsClipboard> m_clipboard;
|
||||
};
|
||||
|
||||
TEST_F(CXWindowsClipboardTests, empty_openCalled_returnsTrue)
|
||||
{
|
||||
CXWindowsClipboard clipboard = createClipboard();
|
||||
|
||||
bool actual = clipboard.empty();
|
||||
|
||||
EXPECT_EQ(true, actual);
|
||||
TEST_F(XWindowsClipboardTests, empty_openCalled_returnsTrue) {
|
||||
XWindowsClipboard &clipboard = getClipboard();
|
||||
|
||||
bool actual = clipboard.empty();
|
||||
|
||||
EXPECT_EQ(true, actual);
|
||||
}
|
||||
|
||||
TEST_F(CXWindowsClipboardTests, empty_singleFormat_hasReturnsFalse)
|
||||
{
|
||||
CXWindowsClipboard clipboard = createClipboard();
|
||||
clipboard.add(CXWindowsClipboard::kText, "synergy rocks!");
|
||||
|
||||
clipboard.empty();
|
||||
|
||||
bool actual = clipboard.has(CXWindowsClipboard::kText);
|
||||
EXPECT_FALSE(actual);
|
||||
TEST_F(XWindowsClipboardTests, empty_singleFormat_hasReturnsFalse) {
|
||||
XWindowsClipboard &clipboard = getClipboard();
|
||||
clipboard.add(XWindowsClipboard::kText, "synergy rocks!");
|
||||
|
||||
clipboard.empty();
|
||||
|
||||
bool actual = clipboard.has(XWindowsClipboard::kText);
|
||||
EXPECT_FALSE(actual);
|
||||
}
|
||||
|
||||
TEST_F(CXWindowsClipboardTests, add_newValue_valueWasStored)
|
||||
{
|
||||
CXWindowsClipboard clipboard = createClipboard();
|
||||
|
||||
clipboard.add(IClipboard::kText, "synergy rocks!");
|
||||
|
||||
String actual = clipboard.get(IClipboard::kText);
|
||||
EXPECT_EQ("synergy rocks!", actual);
|
||||
TEST_F(XWindowsClipboardTests, add_newValue_valueWasStored) {
|
||||
XWindowsClipboard &clipboard = getClipboard();
|
||||
|
||||
clipboard.add(IClipboard::kText, "synergy rocks!");
|
||||
|
||||
String actual = clipboard.get(IClipboard::kText);
|
||||
EXPECT_EQ("synergy rocks!", actual);
|
||||
}
|
||||
|
||||
TEST_F(CXWindowsClipboardTests, add_replaceValue_valueWasReplaced)
|
||||
{
|
||||
CXWindowsClipboard clipboard = createClipboard();
|
||||
|
||||
clipboard.add(IClipboard::kText, "synergy rocks!");
|
||||
clipboard.add(IClipboard::kText, "maxivista sucks"); // haha, just kidding.
|
||||
|
||||
String actual = clipboard.get(IClipboard::kText);
|
||||
EXPECT_EQ("maxivista sucks", actual);
|
||||
TEST_F(XWindowsClipboardTests, add_replaceValue_valueWasReplaced) {
|
||||
XWindowsClipboard &clipboard = getClipboard();
|
||||
|
||||
clipboard.add(IClipboard::kText, "synergy rocks!");
|
||||
clipboard.add(IClipboard::kText, "maxivista sucks"); // haha, just kidding.
|
||||
|
||||
String actual = clipboard.get(IClipboard::kText);
|
||||
EXPECT_EQ("maxivista sucks", actual);
|
||||
}
|
||||
|
||||
TEST_F(CXWindowsClipboardTests, close_isOpen_noErrors)
|
||||
{
|
||||
CXWindowsClipboard clipboard = createClipboard();
|
||||
|
||||
// clipboard opened in createClipboard()
|
||||
clipboard.close();
|
||||
|
||||
// can't assert anything
|
||||
TEST_F(XWindowsClipboardTests, close_isOpen_noErrors) {
|
||||
XWindowsClipboard &clipboard = getClipboard();
|
||||
|
||||
// clipboard opened in createClipboard()
|
||||
clipboard.close();
|
||||
|
||||
// can't assert anything
|
||||
}
|
||||
|
||||
TEST_F(CXWindowsClipboardTests, has_withFormatAdded_returnsTrue)
|
||||
{
|
||||
CXWindowsClipboard clipboard = createClipboard();
|
||||
clipboard.add(IClipboard::kText, "synergy rocks!");
|
||||
|
||||
bool actual = clipboard.has(IClipboard::kText);
|
||||
|
||||
EXPECT_EQ(true, actual);
|
||||
TEST_F(XWindowsClipboardTests, has_withFormatAdded_returnsTrue) {
|
||||
XWindowsClipboard &clipboard = getClipboard();
|
||||
clipboard.add(IClipboard::kText, "synergy rocks!");
|
||||
|
||||
bool actual = clipboard.has(IClipboard::kText);
|
||||
|
||||
EXPECT_EQ(true, actual);
|
||||
}
|
||||
|
||||
TEST_F(CXWindowsClipboardTests, has_withNoFormats_returnsFalse)
|
||||
{
|
||||
CXWindowsClipboard clipboard = createClipboard();
|
||||
|
||||
bool actual = clipboard.has(IClipboard::kText);
|
||||
|
||||
EXPECT_FALSE(actual);
|
||||
TEST_F(XWindowsClipboardTests, has_withNoFormats_returnsFalse) {
|
||||
XWindowsClipboard &clipboard = getClipboard();
|
||||
|
||||
bool actual = clipboard.has(IClipboard::kText);
|
||||
|
||||
EXPECT_FALSE(actual);
|
||||
}
|
||||
|
||||
TEST_F(CXWindowsClipboardTests, get_withNoFormats_returnsEmpty)
|
||||
{
|
||||
CXWindowsClipboard clipboard = createClipboard();
|
||||
|
||||
String actual = clipboard.get(IClipboard::kText);
|
||||
|
||||
EXPECT_EQ("", actual);
|
||||
TEST_F(XWindowsClipboardTests, get_withNoFormats_returnsEmpty) {
|
||||
XWindowsClipboard &clipboard = getClipboard();
|
||||
|
||||
String actual = clipboard.get(IClipboard::kText);
|
||||
|
||||
EXPECT_EQ("", actual);
|
||||
}
|
||||
|
||||
TEST_F(CXWindowsClipboardTests, get_withFormatAdded_returnsExpected)
|
||||
{
|
||||
CXWindowsClipboard clipboard = createClipboard();
|
||||
clipboard.add(IClipboard::kText, "synergy rocks!");
|
||||
|
||||
String actual = clipboard.get(IClipboard::kText);
|
||||
|
||||
EXPECT_EQ("synergy rocks!", actual);
|
||||
}
|
||||
TEST_F(XWindowsClipboardTests, get_withFormatAdded_returnsExpected) {
|
||||
XWindowsClipboard &clipboard = getClipboard();
|
||||
clipboard.add(IClipboard::kText, "synergy rocks!");
|
||||
|
||||
#endif
|
||||
String actual = clipboard.get(IClipboard::kText);
|
||||
|
||||
EXPECT_EQ("synergy rocks!", actual);
|
||||
}
|
||||
|
||||
@ -45,8 +45,8 @@ public:
|
||||
}
|
||||
|
||||
MOCK_METHOD(void, listen, (), (override));
|
||||
MOCK_METHOD(void, send, (const IpcMessage &, EIpcClientType), (override));
|
||||
MOCK_METHOD(bool, hasClients, (EIpcClientType), (const, override));
|
||||
MOCK_METHOD(void, send, (const IpcMessage &, IpcClientType), (override));
|
||||
MOCK_METHOD(bool, hasClients, (IpcClientType), (const, override));
|
||||
|
||||
void delegateToFake() {
|
||||
ON_CALL(*this, send(_, _))
|
||||
@ -56,7 +56,7 @@ public:
|
||||
void waitForSend() { ARCH->waitCondVar(m_sendCond, m_sendMutex, 5); }
|
||||
|
||||
private:
|
||||
void mockSend(const IpcMessage &, EIpcClientType) {
|
||||
void mockSend(const IpcMessage &, IpcClientType) {
|
||||
ArchMutexLock lock(m_sendMutex);
|
||||
ARCH->broadcastCondVar(m_sendCond);
|
||||
}
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2012-2016 Symless Ltd.
|
||||
* Copyright (C) 2012 Nick Bolton
|
||||
* Copyright (C) 2024 Symless Ltd.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@ -16,11 +15,12 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// this class is a duplicate of /src/lib/ipc/Ipc.cpp
|
||||
/**
|
||||
* This header fixes conflicts between X11 and Google Test.
|
||||
*
|
||||
* It should be included after headers of code under test (that use X11)
|
||||
* and before including Google Test headers.
|
||||
*/
|
||||
|
||||
#include "Ipc.h"
|
||||
|
||||
const char *kIpcMsgHello = "IHEL%1i";
|
||||
const char *kIpcMsgLogLine = "ILOG%s";
|
||||
const char *kIpcMsgCommand = "ICMD%s%1i";
|
||||
const char *kIpcMsgShutdown = "ISDN";
|
||||
#undef None // NOSONAR
|
||||
#undef Bool // NOSONAR
|
||||
@ -14,110 +14,7 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
config_test()
|
||||
set(target unittests)
|
||||
|
||||
file(GLOB_RECURSE headers "*.h" "languages/*.h")
|
||||
file(GLOB_RECURSE sources "*.cpp" "languages/*.cpp")
|
||||
|
||||
file(GLOB_RECURSE remove_platform "platform/*")
|
||||
list(REMOVE_ITEM headers ${remove_platform})
|
||||
list(REMOVE_ITEM sources ${remove_platform})
|
||||
|
||||
file(GLOB_RECURSE shared_headers "../../test/shared/*.h")
|
||||
file(GLOB_RECURSE shared_sources "../../test/shared/*.cpp")
|
||||
|
||||
list(APPEND headers ${shared_headers})
|
||||
list(APPEND sources ${shared_sources})
|
||||
|
||||
file(GLOB_RECURSE mock_headers "../../test/mock/*.h")
|
||||
file(GLOB_RECURSE mock_sources "../../test/mock/*.cpp")
|
||||
|
||||
list(APPEND headers ${mock_headers})
|
||||
list(APPEND sources ${mock_sources})
|
||||
|
||||
set(gui_dir "../../gui/src")
|
||||
file(GLOB_RECURSE gui_sources "${gui_dir}/*.cpp")
|
||||
|
||||
file(GLOB activation_sources "${gui_dir}/*Activation*" "${gui_dir}/*License*")
|
||||
if(NOT ENABLE_LICENSING)
|
||||
list(REMOVE_ITEM gui_sources ${activation_sources})
|
||||
endif()
|
||||
|
||||
# remove main gui as the test already has its own main.
|
||||
file(GLOB gui_main "${gui_dir}/main.cpp")
|
||||
list(REMOVE_ITEM gui_sources ${gui_main})
|
||||
|
||||
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
|
||||
file(GLOB mac_gui_sources "${gui_dir}/*.mm")
|
||||
list(APPEND gui_sources ${mac_gui_sources})
|
||||
endif()
|
||||
|
||||
list(APPEND sources ${gui_sources})
|
||||
|
||||
# platform
|
||||
if(WIN32)
|
||||
file(GLOB platform_sources "platform/MSWindows*.cpp")
|
||||
file(GLOB platform_headers "platform/MSWindows*.h")
|
||||
elseif(APPLE)
|
||||
file(GLOB platform_sources "platform/OSX*.cpp")
|
||||
file(GLOB platform_headers "platform/OSX*.h")
|
||||
elseif(UNIX)
|
||||
file(GLOB platform_sources "platform/XWindows*.cpp")
|
||||
file(GLOB platform_headers "platform/XWindows*.h")
|
||||
endif()
|
||||
|
||||
list(APPEND sources ${platform_sources})
|
||||
list(APPEND headers ${platform_headers})
|
||||
|
||||
set(ext_dir "../../../ext")
|
||||
|
||||
include_directories(
|
||||
"../.."
|
||||
"../../lib"
|
||||
${ext_dir}
|
||||
${gui_dir}
|
||||
"${ext_dir}/gtest/include"
|
||||
"${ext_dir}/gmock/include")
|
||||
|
||||
if(SYNERGY_ADD_HEADERS)
|
||||
list(APPEND sources ${headers})
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
list(APPEND sources ${CMAKE_BINARY_DIR}/src/version.rc)
|
||||
endif()
|
||||
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_AUTORCC ON)
|
||||
set(CMAKE_AUTOUIC ON)
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
|
||||
find_package(
|
||||
Qt6
|
||||
COMPONENTS Core Widgets Network Test
|
||||
REQUIRED)
|
||||
|
||||
add_executable(${target} ${sources})
|
||||
|
||||
target_link_libraries(
|
||||
${target}
|
||||
arch
|
||||
base
|
||||
client
|
||||
server
|
||||
common
|
||||
io
|
||||
net
|
||||
platform
|
||||
server
|
||||
synlib
|
||||
mt
|
||||
ipc
|
||||
gtest
|
||||
gmock
|
||||
shared
|
||||
Qt6::Core
|
||||
Qt6::Widgets
|
||||
Qt6::Network
|
||||
Qt6::Test
|
||||
${libs})
|
||||
target_link_libraries(${target} ${test_libs})
|
||||
|
||||
@ -62,7 +62,7 @@ using namespace synergy;
|
||||
// _)).Times(1); EXPECT_CALL(mockServer, send(IpcLogLineMessageEq("mock
|
||||
// 2\n"), _)).Times(1);
|
||||
//
|
||||
// IpcLogOutputter outputter(mockServer, kIpcClientUnknown, true);
|
||||
// IpcLogOutputter outputter(mockServer, IpcClientType::Unknown, true);
|
||||
// outputter.write(kNOTE, "mock 1");
|
||||
// mockServer.waitForSend();
|
||||
// outputter.write(kNOTE, "mock 2");
|
||||
@ -78,7 +78,7 @@ using namespace synergy;
|
||||
// EXPECT_CALL(mockServer, send(IpcLogLineMessageEq("mock 2\nmock 3\n"),
|
||||
// _)).Times(1);
|
||||
//
|
||||
// IpcLogOutputter outputter(mockServer, kIpcClientUnknown, false);
|
||||
// IpcLogOutputter outputter(mockServer, IpcClientType::Unknown, false);
|
||||
// outputter.bufferMaxSize(2);
|
||||
//
|
||||
// // log more lines than the buffer can contain
|
||||
@ -98,7 +98,7 @@ using namespace synergy;
|
||||
// EXPECT_CALL(mockServer, send(IpcLogLineMessageEq("mock 1\nmock 2\n"),
|
||||
// _)).Times(1);
|
||||
//
|
||||
// IpcLogOutputter outputter(mockServer, kIpcClientUnknown, false);
|
||||
// IpcLogOutputter outputter(mockServer, IpcClientType::Unknown, false);
|
||||
// outputter.bufferMaxSize(2);
|
||||
//
|
||||
// // log more lines than the buffer can contain
|
||||
@ -156,7 +156,7 @@ using namespace synergy;
|
||||
// _)).Times(1); EXPECT_CALL(mockServer, send(IpcLogLineMessageEq("mock
|
||||
// 3\nmock 4\n"), _)).Times(1);
|
||||
//
|
||||
// IpcLogOutputter outputter(mockServer, kIpcClientUnknown, false);
|
||||
// IpcLogOutputter outputter(mockServer, IpcClientType::Unknown, false);
|
||||
// outputter.bufferRateLimit(4, 1); // 1s (should be plenty of time)
|
||||
//
|
||||
// // log 1 more line than the buffer can accept in time limit.
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2012-2016 Symless Ltd.
|
||||
* Copyright (C) 2012 Nick Bolton
|
||||
* Copyright (C) 2024 Symless Ltd.
|
||||
*
|
||||
* This package is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@ -16,27 +15,24 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
// this class is a duplicate of /src/lib/ipc/Ipc.h
|
||||
#include "platform/XWindowsClipboard.h"
|
||||
|
||||
#pragma once
|
||||
#include "test/shared/undef_x11_macros.h"
|
||||
|
||||
#define IPC_HOST "127.0.0.1"
|
||||
#define IPC_PORT 24801
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
enum qIpcMessageType {
|
||||
kIpcHello,
|
||||
kIpcLogLine,
|
||||
kIpcCommand,
|
||||
kIpcShutdown,
|
||||
const auto None = 0L;
|
||||
|
||||
class TestXWindowsClipboard : public XWindowsClipboard {
|
||||
public:
|
||||
class TestCICCCMGetClipboard : public CICCCMGetClipboard {
|
||||
public:
|
||||
TestCICCCMGetClipboard() : CICCCMGetClipboard(None, None, None) {}
|
||||
};
|
||||
};
|
||||
|
||||
enum qIpcClientType {
|
||||
kIpcClientUnknown,
|
||||
kIpcClientGui,
|
||||
kIpcClientNode,
|
||||
};
|
||||
TEST(XWindowsClipboardTests_CICCCMGetClipboard, ctor_default_errorNone) {
|
||||
TestXWindowsClipboard::TestCICCCMGetClipboard clipboard;
|
||||
|
||||
extern const char *kIpcMsgHello;
|
||||
extern const char *kIpcMsgLogLine;
|
||||
extern const char *kIpcMsgCommand;
|
||||
extern const char *kIpcMsgShutdown;
|
||||
EXPECT_EQ(None, clipboard.error());
|
||||
}
|
||||
Reference in New Issue
Block a user