diff --git a/.github/workflows/sonarcloud-analysis.yml b/.github/workflows/sonarcloud-analysis.yml index 61af45eff..52b1fc0f5 100644 --- a/.github/workflows/sonarcloud-analysis.yml +++ b/.github/workflows/sonarcloud-analysis.yml @@ -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 }} diff --git a/.gitignore b/.gitignore index 88b9a7285..56067f54d 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,5 @@ # temp dirs created during build /build -/bin /dist /deps /tmp diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 9f24b1ed0..e9d78ce96 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -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"] } ] } diff --git a/CMakeLists.txt b/CMakeLists.txt index c3ba38851..ecaaf24f8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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() diff --git a/ChangeLog b/ChangeLog index 0de307bd3..642a28249 100644 --- a/ChangeLog +++ b/ChangeLog @@ -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 diff --git a/cmake/Build.cmake b/cmake/Build.cmake new file mode 100644 index 000000000..f0c232c7f --- /dev/null +++ b/cmake/Build.cmake @@ -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 . + +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() diff --git a/cmake/Definitions.cmake b/cmake/Definitions.cmake index e43b59268..1245ea024 100644 --- a/cmake/Definitions.cmake +++ b/cmake/Definitions.cmake @@ -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) diff --git a/cmake/Libraries.cmake b/cmake/Libraries.cmake index 8ca7a7e8a..a0c6a4f85 100644 --- a/cmake/Libraries.cmake +++ b/cmake/Libraries.cmake @@ -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() diff --git a/scripts/fancy_copy.py b/scripts/fancy_copy.py new file mode 100644 index 000000000..3d6e69a43 --- /dev/null +++ b/scripts/fancy_copy.py @@ -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() diff --git a/scripts/lib/file_utils.py b/scripts/lib/file_utils.py new file mode 100644 index 000000000..278c0cfae --- /dev/null +++ b/scripts/lib/file_utils.py @@ -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) diff --git a/scripts/windows_daemon.py b/scripts/windows_daemon.py index 2bea265fe..daf36a1d0 100644 --- a/scripts/windows_daemon.py +++ b/scripts/windows_daemon.py @@ -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() diff --git a/src/cmd/synergyc/CMakeLists.txt b/src/cmd/synergyc/CMakeLists.txt index 8f3a5f01b..45c60fb0e 100644 --- a/src/cmd/synergyc/CMakeLists.txt +++ b/src/cmd/synergyc/CMakeLists.txt @@ -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() diff --git a/src/cmd/synergyd/CMakeLists.txt b/src/cmd/synergyd/CMakeLists.txt index d6087a163..545724242 100644 --- a/src/cmd/synergyd/CMakeLists.txt +++ b/src/cmd/synergyd/CMakeLists.txt @@ -38,3 +38,5 @@ target_link_libraries( synlib shared ${libs}) + +post_config() diff --git a/src/cmd/synergys/CMakeLists.txt b/src/cmd/synergys/CMakeLists.txt index 60942febe..021c6c486 100644 --- a/src/cmd/synergys/CMakeLists.txt +++ b/src/cmd/synergys/CMakeLists.txt @@ -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() diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index 56d17ee6f..2262e49dd 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -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 . + +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%$${qt6_install_prefix}/bin COMMAND Qt6::windeployqt @@ -104,3 +121,5 @@ elseif(WIN32) endif() endif() + +post_config() diff --git a/src/gui/src/ElevateMode.h b/src/gui/src/ElevateMode.h index 8b00fea0e..0d87f4e98 100644 --- a/src/gui/src/ElevateMode.h +++ b/src/gui/src/ElevateMode.h @@ -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 diff --git a/src/gui/src/IpcReader.cpp b/src/gui/src/IpcReader.cpp index 73fe67cfc..8631e010f 100644 --- a/src/gui/src/IpcReader.cpp +++ b/src/gui/src/IpcReader.cpp @@ -17,7 +17,7 @@ */ #include "IpcReader.h" -#include "Ipc.h" +#include "shared/Ipc.h" #include #include #include diff --git a/src/gui/src/MainWindow.h b/src/gui/src/MainWindow.h index 232cb4c05..fe808d2fd 100644 --- a/src/gui/src/MainWindow.h +++ b/src/gui/src/MainWindow.h @@ -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(); diff --git a/src/gui/src/QIpcClient.cpp b/src/gui/src/QIpcClient.cpp index 6a327e73a..515ac8ed3 100644 --- a/src/gui/src/QIpcClient.cpp +++ b/src/gui/src/QIpcClient.cpp @@ -16,12 +16,13 @@ */ #include "QIpcClient.h" -#include "Ipc.h" #include "IpcReader.h" +#include "shared/Ipc.h" #include #include #include +#include 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(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(IpcClientType::GUI); stream->writeRawData(typeBuf, 1); } diff --git a/src/lib/arch/CMakeLists.txt b/src/lib/arch/CMakeLists.txt index d49bc34e7..d1fa02a34 100644 --- a/src/lib/arch/CMakeLists.txt +++ b/src/lib/arch/CMakeLists.txt @@ -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() diff --git a/src/lib/base/CMakeLists.txt b/src/lib/base/CMakeLists.txt index 3a6416bab..a84258745 100644 --- a/src/lib/base/CMakeLists.txt +++ b/src/lib/base/CMakeLists.txt @@ -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() diff --git a/src/lib/base/log_outputters.cpp b/src/lib/base/log_outputters.cpp index 11cb2e203..5be96dad8 100644 --- a/src/lib/base/log_outputters.cpp +++ b/src/lib/base/log_outputters.cpp @@ -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; -} diff --git a/src/lib/base/log_outputters.h b/src/lib/base/log_outputters.h index 2bf65060e..61d1efa02 100644 --- a/src/lib/base/log_outputters.h +++ b/src/lib/base/log_outputters.h @@ -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); -}; diff --git a/src/lib/client/CMakeLists.txt b/src/lib/client/CMakeLists.txt index 298a02274..a74afe69b 100644 --- a/src/lib/client/CMakeLists.txt +++ b/src/lib/client/CMakeLists.txt @@ -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() diff --git a/src/lib/common/CMakeLists.txt b/src/lib/common/CMakeLists.txt index 4f66ba841..6c08ef760 100644 --- a/src/lib/common/CMakeLists.txt +++ b/src/lib/common/CMakeLists.txt @@ -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() diff --git a/src/lib/io/CMakeLists.txt b/src/lib/io/CMakeLists.txt index ee52610d3..4093a970b 100644 --- a/src/lib/io/CMakeLists.txt +++ b/src/lib/io/CMakeLists.txt @@ -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() diff --git a/src/lib/ipc/CMakeLists.txt b/src/lib/ipc/CMakeLists.txt index 0d535f405..9ca26df86 100644 --- a/src/lib/ipc/CMakeLists.txt +++ b/src/lib/ipc/CMakeLists.txt @@ -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() diff --git a/src/lib/ipc/IpcClient.cpp b/src/lib/ipc/IpcClient.cpp index fe8736908..c9bd18797 100644 --- a/src/lib/ipc/IpcClient.cpp +++ b/src/lib/ipc/IpcClient.cpp @@ -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); } diff --git a/src/lib/ipc/IpcClientProxy.cpp b/src/lib/ipc/IpcClientProxy.cpp index 7c5dcc7fb..2c9949e90 100644 --- a/src/lib/ipc/IpcClientProxy.cpp +++ b/src/lib/ipc/IpcClientProxy.cpp @@ -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(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(type); + m_clientType = static_cast(type); // must be deleted by event handler. return new IpcHelloMessage(m_clientType); diff --git a/src/lib/ipc/IpcClientProxy.h b/src/lib/ipc/IpcClientProxy.h index 4b61900da..7362d16a2 100644 --- a/src/lib/ipc/IpcClientProxy.h +++ b/src/lib/ipc/IpcClientProxy.h @@ -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(); }; diff --git a/src/lib/ipc/IpcLogOutputter.cpp b/src/lib/ipc/IpcLogOutputter.cpp index 91891714a..2b4213100 100644 --- a/src/lib/ipc/IpcLogOutputter.cpp +++ b/src/lib/ipc/IpcLogOutputter.cpp @@ -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; } diff --git a/src/lib/ipc/IpcLogOutputter.h b/src/lib/ipc/IpcLogOutputter.h index a0f866cc6..a38a3380e 100644 --- a/src/lib/ipc/IpcLogOutputter.h +++ b/src/lib/ipc/IpcLogOutputter.h @@ -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 @@ -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; }; diff --git a/src/lib/ipc/IpcMessage.cpp b/src/lib/ipc/IpcMessage.cpp index e2fd70a64..955564b39 100644 --- a/src/lib/ipc/IpcMessage.cpp +++ b/src/lib/ipc/IpcMessage.cpp @@ -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() {} diff --git a/src/lib/ipc/IpcMessage.h b/src/lib/ipc/IpcMessage.h index a10a4647c..594d6c666 100644 --- a/src/lib/ipc/IpcMessage.h +++ b/src/lib/ipc/IpcMessage.h @@ -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; } diff --git a/src/lib/ipc/IpcServer.cpp b/src/lib/ipc/IpcServer.cpp index 1cafec99d..0c3f6f730 100644 --- a/src/lib/ipc/IpcServer.cpp +++ b/src/lib/ipc/IpcServer.cpp @@ -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; diff --git a/src/lib/ipc/IpcServer.h b/src/lib/ipc/IpcServer.h index 36357d856..453a9abe9 100644 --- a/src/lib/ipc/IpcServer.h +++ b/src/lib/ipc/IpcServer.h @@ -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 @@ -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; //@} diff --git a/src/lib/ipc/IpcServerProxy.cpp b/src/lib/ipc/IpcServerProxy.cpp index 545d9b2cb..25578e93f 100644 --- a/src/lib/ipc/IpcServerProxy.cpp +++ b/src/lib/ipc/IpcServerProxy.cpp @@ -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(message); ProtocolUtil::writef(&m_stream, kIpcMsgHello, hm.clientType()); break; } - case kIpcCommand: { + case IpcMessageType::Command: { const IpcCommandMessage &cm = static_cast(message); const String command = cm.command(); diff --git a/src/lib/ipc/IpcSettingMessage.cpp b/src/lib/ipc/IpcSettingMessage.cpp index b539520bb..3ba9a5310 100644 --- a/src/lib/ipc/IpcSettingMessage.cpp +++ b/src/lib/ipc/IpcSettingMessage.cpp @@ -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) {} diff --git a/src/lib/mt/CMakeLists.txt b/src/lib/mt/CMakeLists.txt index 10e440a2f..671a2768b 100644 --- a/src/lib/mt/CMakeLists.txt +++ b/src/lib/mt/CMakeLists.txt @@ -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() diff --git a/src/lib/net/CMakeLists.txt b/src/lib/net/CMakeLists.txt index da3afb27d..29ffd3768 100644 --- a/src/lib/net/CMakeLists.txt +++ b/src/lib/net/CMakeLists.txt @@ -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() diff --git a/src/lib/platform/CMakeLists.txt b/src/lib/platform/CMakeLists.txt index 30679a8fb..a8b23812b 100644 --- a/src/lib/platform/CMakeLists.txt +++ b/src/lib/platform/CMakeLists.txt @@ -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() diff --git a/src/lib/platform/MSWindowsWatchdog.cpp b/src/lib/platform/MSWindowsWatchdog.cpp index c8652c1c8..2b4e783db 100644 --- a/src/lib/platform/MSWindowsWatchdog.cpp +++ b/src/lib/platform/MSWindowsWatchdog.cpp @@ -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(); diff --git a/src/lib/platform/XWindowsClipboard.cpp b/src/lib/platform/XWindowsClipboard.cpp index 7c72d2c30..8c1ad4ac6 100644 --- a/src/lib/platform/XWindowsClipboard.cpp +++ b/src/lib/platform/XWindowsClipboard.cpp @@ -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(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, diff --git a/src/lib/platform/XWindowsClipboard.h b/src/lib/platform/XWindowsClipboard.h index bb4ba96ea..ea88c905a 100644 --- a/src/lib/platform/XWindowsClipboard.h +++ b/src/lib/platform/XWindowsClipboard.h @@ -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; diff --git a/src/lib/server/CMakeLists.txt b/src/lib/server/CMakeLists.txt index a2ff5f6f2..f0adc6324 100644 --- a/src/lib/server/CMakeLists.txt +++ b/src/lib/server/CMakeLists.txt @@ -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() diff --git a/src/lib/shared/CMakeLists.txt b/src/lib/shared/CMakeLists.txt index 9d91779eb..a58291bfe 100644 --- a/src/lib/shared/CMakeLists.txt +++ b/src/lib/shared/CMakeLists.txt @@ -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() diff --git a/src/lib/ipc/Ipc.cpp b/src/lib/shared/Ipc.cpp similarity index 62% rename from src/lib/ipc/Ipc.cpp rename to src/lib/shared/Ipc.cpp index d7f9fba72..74179ffc2 100644 --- a/src/lib/ipc/Ipc.cpp +++ b/src/lib/shared/Ipc.cpp @@ -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 . */ -#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"; diff --git a/src/lib/ipc/Ipc.h b/src/lib/shared/Ipc.h similarity index 71% rename from src/lib/ipc/Ipc.h rename to src/lib/shared/Ipc.h index 22253276d..46b8a2eec 100644 --- a/src/lib/ipc/Ipc.h +++ b/src/lib/shared/Ipc.h @@ -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; diff --git a/src/lib/synergy/App.cpp b/src/lib/synergy/App.cpp index 4e1ae33d7..efc904e6b 100644 --- a/src/lib/synergy/App.cpp +++ b/src/lib/synergy/App.cpp @@ -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(e.getDataObject()); - if (m->type() == kIpcShutdown) { + if (m->type() == IpcMessageType::Shutdown) { LOG((CLOG_INFO "got ipc shutdown message")); m_events->addEvent(Event(Event::kQuit)); } diff --git a/src/lib/synergy/CMakeLists.txt b/src/lib/synergy/CMakeLists.txt index 4e07c7780..29acc491c 100644 --- a/src/lib/synergy/CMakeLists.txt +++ b/src/lib/synergy/CMakeLists.txt @@ -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() diff --git a/src/lib/synergy/DaemonApp.cpp b/src/lib/synergy/DaemonApp.cpp index 8fe7f8d85..0c73186e1 100644 --- a/src/lib/synergy/DaemonApp.cpp +++ b/src/lib/synergy/DaemonApp.cpp @@ -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 -#endif +#elif SYSAPI_UNIX #include + +#endif + +#include #include #include 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 &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(); 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(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(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( + *m_ipcServer, IpcClientType::GUI, true); + CLOG->insert(m_ipcLogOutputter.get()); #if SYSAPI_WIN32 - m_watchdog = new MSWindowsWatchdog( + m_watchdog = std::make_unique( 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(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(e.getDataObject()); switch (m->type()) { - case kIpcCommand: { + case IpcMessageType::Command: { IpcCommandMessage *cm = static_cast(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(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; } diff --git a/src/lib/synergy/DaemonApp.h b/src/lib/synergy/DaemonApp.h index 197c3e4ab..0dd94a86a 100644 --- a/src/lib/synergy/DaemonApp.h +++ b/src/lib/synergy/DaemonApp.h @@ -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 #include 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 m_watchdog; #endif private: - IpcServer *m_ipcServer; - IpcLogOutputter *m_ipcLogOutputter; - IEventQueue *m_events; - FileLogOutputter *m_fileLogOutputter; + std::unique_ptr m_ipcServer; + std::unique_ptr m_ipcLogOutputter; + std::unique_ptr m_events; + std::unique_ptr m_fileLogOutputter; }; - -#define LOG_FILENAME "synergyd.log" diff --git a/src/test/CMakeLists.txt b/src/test/CMakeLists.txt index ad7f338d7..cc682af00 100644 --- a/src/test/CMakeLists.txt +++ b/src/test/CMakeLists.txt @@ -14,18 +14,158 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -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() diff --git a/src/test/integtests/CMakeLists.txt b/src/test/integtests/CMakeLists.txt index 58c256a04..82b350ac6 100644 --- a/src/test/integtests/CMakeLists.txt +++ b/src/test/integtests/CMakeLists.txt @@ -14,67 +14,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . -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}) diff --git a/src/test/unittests/gui/MainWindowTests.cpp b/src/test/integtests/gui/MainWindowTests.cpp similarity index 100% rename from src/test/unittests/gui/MainWindowTests.cpp rename to src/test/integtests/gui/MainWindowTests.cpp diff --git a/src/test/integtests/ipc/IpcTests.cpp b/src/test/integtests/ipc/IpcTests.cpp index ad42732a6..679e2366e 100644 --- a/src/test/integtests/ipc/IpcTests.cpp +++ b/src/test/integtests/ipc/IpcTests.cpp @@ -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 -#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( 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( 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( 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(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(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(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(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(e.getDataObject()); - if (m->type() == kIpcLogLine) { + if (m->type() == IpcMessageType::LogLine) { IpcLogLineMessage *llm = static_cast(m); LOG((CLOG_DEBUG "got ipc log message, %d", llm->logLine().c_str())); m_sendMessageToClient_receivedString = llm->logLine(); diff --git a/src/test/integtests/platform/XWindowsClipboardTests.cpp b/src/test/integtests/platform/XWindowsClipboardTests.cpp index 362750dc6..78963843a 100644 --- a/src/test/integtests/platform/XWindowsClipboardTests.cpp +++ b/src/test/integtests/platform/XWindowsClipboardTests.cpp @@ -16,142 +16,122 @@ * along with this program. If not, see . */ -// TODO: fix tests - compile error on linux -#if 0 - #include "platform/XWindowsClipboard.h" +#include "test/shared/undef_x11_macros.h" + #include -#include +#include -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(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 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); +} diff --git a/src/test/mock/ipc/MockIpcServer.h b/src/test/mock/ipc/MockIpcServer.h index abe7bf1e9..7e0e7163c 100644 --- a/src/test/mock/ipc/MockIpcServer.h +++ b/src/test/mock/ipc/MockIpcServer.h @@ -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); } diff --git a/src/gui/src/Ipc.cpp b/src/test/shared/undef_x11_macros.h similarity index 68% rename from src/gui/src/Ipc.cpp rename to src/test/shared/undef_x11_macros.h index 39be8686c..aabf58bf3 100644 --- a/src/gui/src/Ipc.cpp +++ b/src/test/shared/undef_x11_macros.h @@ -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 . */ -// 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 diff --git a/src/test/unittests/CMakeLists.txt b/src/test/unittests/CMakeLists.txt index ef9117b42..45df145f1 100644 --- a/src/test/unittests/CMakeLists.txt +++ b/src/test/unittests/CMakeLists.txt @@ -14,110 +14,7 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +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}) diff --git a/src/test/unittests/ipc/IpcLogOutputterTests.cpp b/src/test/unittests/ipc/IpcLogOutputterTests.cpp index ceebd6c7b..f52e60850 100644 --- a/src/test/unittests/ipc/IpcLogOutputterTests.cpp +++ b/src/test/unittests/ipc/IpcLogOutputterTests.cpp @@ -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. diff --git a/src/gui/src/Ipc.h b/src/test/unittests/platform/XWindowsClipboardTests.cpp similarity index 54% rename from src/gui/src/Ipc.h rename to src/test/unittests/platform/XWindowsClipboardTests.cpp index 76d7bc6b0..3bb4f9f60 100644 --- a/src/gui/src/Ipc.h +++ b/src/test/unittests/platform/XWindowsClipboardTests.cpp @@ -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 . */ -// 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 -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()); +}