Compare commits
242 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 5355e84b63 | |||
| 8fbcf907b2 | |||
| d2bf5e63e4 | |||
| 3ed0915b57 | |||
| 01878b0522 | |||
| af6b42fe9e | |||
| a0051ea0bc | |||
| 40c915f6bd | |||
| 1cee520e2b | |||
| 1dd5654af6 | |||
| 2708fc96fe | |||
| 5cfaa4a4e0 | |||
| a6453a6819 | |||
| f781ac9855 | |||
| d6087cc5bd | |||
| 6e9694b5d8 | |||
| 201df59cb7 | |||
| bcfc77fde6 | |||
| 245a522188 | |||
| fdf1df1a30 | |||
| 84b433853a | |||
| e225a357fd | |||
| 54fac87ed2 | |||
| 56a665cd18 | |||
| cb8c6fe9d9 | |||
| 239a265e18 | |||
| ee53d28af7 | |||
| 91fd139a49 | |||
| 7f1a234d06 | |||
| db20c4b0c7 | |||
| 7bd3fc1eb5 | |||
| 8fde0d764e | |||
| e1eb4ebf98 | |||
| 4b06160f84 | |||
| 2160f7826f | |||
| 7f6a68bb2f | |||
| 95521c53d6 | |||
| 446847f4fb | |||
| 37bc70896b | |||
| f9c8d08ff7 | |||
| 55c611f754 | |||
| 541e30f406 | |||
| 4b24b5b38d | |||
| df8500178b | |||
| 378fdae140 | |||
| 31e95ad2dc | |||
| 8b5a61f07f | |||
| 516f803eb4 | |||
| c1a7b836ce | |||
| 9530b9c6ba | |||
| 9df2a2c28d | |||
| 133545d03f | |||
| 75e852d95f | |||
| 9c44653fff | |||
| 2adee7c460 | |||
| 6f6e9cddb7 | |||
| fdd9b1bb6d | |||
| b2ff6aa938 | |||
| 5e4188b2fe | |||
| a3875bf71c | |||
| f3930d9520 | |||
| f66a50dab7 | |||
| 68ebc88293 | |||
| 83c8d295d4 | |||
| 07219ed431 | |||
| da5f3c0be1 | |||
| a23e35c522 | |||
| eb74d8ca99 | |||
| 65b6fe7ca3 | |||
| 9b6615328b | |||
| 7fb87b32f5 | |||
| 8508805f5d | |||
| 385a610da2 | |||
| e00058a332 | |||
| 45b6ff19e7 | |||
| 1798d7e4e6 | |||
| 854787e6b3 | |||
| 498ffe85c3 | |||
| cd3f9b2e7d | |||
| 42b16efdb9 | |||
| 003f87db9e | |||
| 86dca27e4c | |||
| 26fa6860e4 | |||
| d9798a9b2b | |||
| 70a2554370 | |||
| 13c325eb3f | |||
| a3ad66dfb0 | |||
| c9d1a50bb0 | |||
| cb3e516206 | |||
| de2e3fb9ce | |||
| 3bad718bb7 | |||
| 40c10766f3 | |||
| bf09df835d | |||
| 4a16804d27 | |||
| 5e1aa9eb5d | |||
| 3c86d9dc83 | |||
| 099262d8ce | |||
| d9e6ec4b70 | |||
| d7b20fad5c | |||
| 6e6a88af87 | |||
| ce17167248 | |||
| 656ad6402b | |||
| 329742a411 | |||
| 4df982dd6f | |||
| b1010751ba | |||
| 4238441018 | |||
| a13bd3d0bd | |||
| 516e612282 | |||
| bfd4bbd8f4 | |||
| 1c4ec6ec41 | |||
| 2ef23b8206 | |||
| ecf70f09f3 | |||
| 397c652e1c | |||
| 1666a30b94 | |||
| 827d020d16 | |||
| 0138372871 | |||
| 9e78cb55aa | |||
| 38cc678ad2 | |||
| e624e6f174 | |||
| 96b50b7d1c | |||
| ffbe2cf885 | |||
| b1b8720781 | |||
| 8609cbc20a | |||
| 7fe862b715 | |||
| 377272e917 | |||
| b051c5ae60 | |||
| 38f00da704 | |||
| dcd2c62880 | |||
| b7f29d76c3 | |||
| 55601debe0 | |||
| 6c8eca6c41 | |||
| 6444e2c208 | |||
| b3ce7c41d3 | |||
| 6963c28219 | |||
| 99ed548495 | |||
| d37bda6edb | |||
| 73de5e964e | |||
| 27451d3425 | |||
| 613f3651ea | |||
| 0e3cee6287 | |||
| 6056e5850b | |||
| 1b01a010ed | |||
| 7faf76c7df | |||
| 55f513941b | |||
| 9e74100960 | |||
| 531b988dd1 | |||
| 5647121dd8 | |||
| c1af4c3b71 | |||
| dd895ed99f | |||
| 7771dcd04c | |||
| d537a23fda | |||
| f7b98465fa | |||
| ed1bf01306 | |||
| 80f814a2da | |||
| 5355c9080b | |||
| 16517ca541 | |||
| e8ea9f53ee | |||
| 7da8c54924 | |||
| 3683db0db9 | |||
| cd0aa6496a | |||
| c583252b03 | |||
| 2c433eddd7 | |||
| 5ee39c9b00 | |||
| c1642b8d9d | |||
| f2c16c4432 | |||
| 37b4e4b57f | |||
| b502a6b848 | |||
| fe0ddf85e4 | |||
| 6990477504 | |||
| e05b35dda4 | |||
| f50e4e850b | |||
| 3cd3d7b1ff | |||
| 5a7284fd6a | |||
| 362b2e1477 | |||
| 7bf716b232 | |||
| 554178b658 | |||
| af17b14224 | |||
| 1e9f92c93f | |||
| 8bb325a2d2 | |||
| 8606dc8618 | |||
| 6362948e15 | |||
| 085a70d5a5 | |||
| 93abf4217b | |||
| 88b0a7d2e1 | |||
| 5fa70d0d0a | |||
| d01c07cab8 | |||
| 6834862413 | |||
| 4273fe2318 | |||
| 266a4a5edf | |||
| 5e6381c88a | |||
| 9aa1d6b79d | |||
| d45d6baacb | |||
| a887ac066c | |||
| 787a48424e | |||
| b20d6361d6 | |||
| b833ca7a45 | |||
| 43eab1f04c | |||
| dc9e104f8c | |||
| f456aab196 | |||
| de3b9d8e2e | |||
| b7960eecb4 | |||
| 03f142977f | |||
| 5360fb3c89 | |||
| 4eb7ea3491 | |||
| 5642879a21 | |||
| 737328d7b0 | |||
| bee0f84556 | |||
| 2721de220a | |||
| 4c6195cc5d | |||
| 1e46bd2727 | |||
| 54ecdad101 | |||
| 51a749b109 | |||
| 788f6c3eb2 | |||
| e01c595071 | |||
| bcd90434a2 | |||
| 698fd3f83c | |||
| 2a53d4f187 | |||
| 53487e757b | |||
| ef315183f3 | |||
| 8b1e8dfd9f | |||
| b73aceee7d | |||
| 3b811a1bd0 | |||
| a099276e4e | |||
| 38f8159e9d | |||
| 87fb06781c | |||
| b9017de881 | |||
| 24d1d4e620 | |||
| 3bcc1e11ed | |||
| d26c75a784 | |||
| 5b091dee56 | |||
| 3344644d2e | |||
| 39e7f60c5a | |||
| 57d1e42eca | |||
| cd45164e40 | |||
| 0ed583a7fe | |||
| 751c869435 | |||
| 4cfeadf0be | |||
| 402baf3bde | |||
| d199130b43 | |||
| 758c1044b5 | |||
| 6e8952c8a0 | |||
| bb38ad0766 |
2
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
2
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
@ -1,6 +1,6 @@
|
||||
name: Bug report
|
||||
description: If you find a bug in Deskflow, please let us know so we can fix it.
|
||||
labels: ["bug", "triage", "unanswered"]
|
||||
type: "Triage [bug]"
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
|
||||
2
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
2
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
@ -1,6 +1,6 @@
|
||||
name: Feature request
|
||||
description: Had an idea how to improve Deskflow? Share it with us.
|
||||
labels: ["enhancement", "triage", "unanswered"]
|
||||
type: "Triage [feature]"
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
|
||||
20
.github/actions/install-dependencies/action.yml
vendored
20
.github/actions/install-dependencies/action.yml
vendored
@ -37,30 +37,26 @@ runs:
|
||||
apt update -qqq > /dev/null
|
||||
apt install -qqq cmake build-essential ninja-build \
|
||||
xorg-dev libx11-dev libxtst-dev libssl-dev \
|
||||
libglib2.0-dev libgdk-pixbuf-2.0-dev libnotify-dev \
|
||||
libxkbfile-dev qt6-base-dev qt6-tools-dev \
|
||||
libgtk-3-dev libgtest-dev libgmock-dev libpugixml-dev \
|
||||
libglib2.0-dev libxkbfile-dev qt6-base-dev qt6-tools-dev \
|
||||
libgtk-3-dev libgtest-dev libgmock-dev \
|
||||
libei-dev libportal-dev libtomlplusplus-dev libcli11-dev -y >/dev/null
|
||||
elif [ ${{inputs.like}} == "fedora" ]; then
|
||||
dnf install -y cmake make ninja-build gcc-c++ \
|
||||
rpm-build openssl-devel glib2-devel \
|
||||
gdk-pixbuf2-devel libXtst-devel libnotify-devel \
|
||||
libxkbfile-devel qt6-qtbase-devel qt6-qttools-devel \
|
||||
gtk3-devel gtest-devel gmock-devel pugixml-devel \
|
||||
libXtst-devel libxkbfile-devel qt6-qtbase-devel qt6-qttools-devel \
|
||||
gtk3-devel gtest-devel gmock-devel \
|
||||
libei-devel libportal-devel tomlplusplus-devel \
|
||||
cli11-devel
|
||||
elif [ ${{inputs.like}} == "suse" ]; then
|
||||
zypper refresh
|
||||
zypper install -y --force-resolution \
|
||||
cmake make ninja gcc-c++ rpm-build libopenssl-devel \
|
||||
glib2-devel gdk-pixbuf-devel libXtst-devel libnotify-devel \
|
||||
libxkbfile-devel qt6-base-devel qt6-tools-devel gtk3-devel \
|
||||
googletest-devel googlemock-devel pugixml-devel libei-devel \
|
||||
glib2-devel libXtst-devel libxkbfile-devel qt6-base-devel qt6-tools-devel gtk3-devel \
|
||||
googletest-devel googlemock-devel libei-devel \
|
||||
libportal-devel tomlplusplus-devel cli11-devel
|
||||
elif [ ${{ inputs.like }} == "arch" ]; then
|
||||
pacman -Syu --noconfirm base-devel cmake ninja \
|
||||
gcc openssl glib2 gdk-pixbuf2 libxtst libnotify \
|
||||
libxkbfile gtest pugixml libei libportal \
|
||||
gcc openssl glib2 libxtst libxkbfile gtest libei libportal \
|
||||
qt6-base qt6-tools gtk3 tomlplusplus cli11
|
||||
else
|
||||
echo "Unknown like"
|
||||
@ -91,7 +87,7 @@ runs:
|
||||
id: vcpkg
|
||||
uses: johnwason/vcpkg-action@v6
|
||||
with:
|
||||
pkgs: wintoast gtest pkgconf openssl
|
||||
pkgs: gtest openssl
|
||||
extra-args: --classic
|
||||
triplet: x64-windows-release
|
||||
token: ${{ github.token }}
|
||||
|
||||
2
.github/actions/lint-check/action.yml
vendored
2
.github/actions/lint-check/action.yml
vendored
@ -5,7 +5,7 @@ runs:
|
||||
using: "composite"
|
||||
steps:
|
||||
- name: Install Dependencies
|
||||
run: pipx install --global clang_format
|
||||
run: pipx install --global clang-format==20.1.0
|
||||
shell: bash
|
||||
|
||||
- name: Run format command
|
||||
|
||||
@ -18,7 +18,7 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
|
||||
# Fallback for when git can not be found
|
||||
set(DESKFLOW_VERSION_MAJOR 1)
|
||||
set(DESKFLOW_VERSION_MINOR 20)
|
||||
set(DESKFLOW_VERSION_MINOR 21)
|
||||
set(DESKFLOW_VERSION_PATCH 1)
|
||||
set(DESKFLOW_VERSION_TWEAK 0)
|
||||
|
||||
@ -95,6 +95,22 @@ set(REQUIRED_LIBEI_VERSION 1.3)
|
||||
set(REQUIRED_LIBPORTAL_VERSION 0.8)
|
||||
set(REQUIRED_QT_VERSION 6.7.0)
|
||||
|
||||
if (MSVC)
|
||||
# On Windows, require that the same MSVC runtime is used as on the host.
|
||||
# Mitigates things like access violations caused by accidental ABI-compatibility breakage.
|
||||
set(REQUIRED_MSVC_RUNTIME_MAJOR 14)
|
||||
cmake_host_system_information(
|
||||
RESULT REQUIRED_MSVC_RUNTIME_MINOR
|
||||
QUERY WINDOWS_REGISTRY
|
||||
"HKLM/SOFTWARE/Microsoft/VisualStudio/${REQUIRED_MSVC_RUNTIME_MAJOR}.0/VC/Runtimes/x64"
|
||||
VALUE "Minor")
|
||||
if (REQUIRED_MSVC_RUNTIME_MINOR)
|
||||
message(STATUS "MSVC runtime: ${REQUIRED_MSVC_RUNTIME_MAJOR}.${REQUIRED_MSVC_RUNTIME_MINOR}")
|
||||
else()
|
||||
message(FATAL_ERROR "MSVC runtime registry entry not found")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Control debug item visibility
|
||||
# When not set logging is forced to DEBUG and show code locations
|
||||
# Also exposes a test menu
|
||||
|
||||
@ -194,13 +194,13 @@ SPDX-FileCopyrightText = "Chris Rizzitello <sithlord48@gmail.com>"
|
||||
SPDX-License-Identifier = "LGPL-2.1-only"
|
||||
|
||||
[[annotations]]
|
||||
path = "src/apps/deskflow-gui/MainWindow.ui"
|
||||
path = "src/lib/gui/MainWindow.ui"
|
||||
precedence = "override"
|
||||
SPDX-FileCopyrightText = "Deskflow Developers"
|
||||
SPDX-License-Identifier = "GPL-2.0-only WITH LicenseRef-OpenSSL-Exception"
|
||||
|
||||
[[annotations]]
|
||||
path = "src/apps/deskflow-gui/dialogs/*.ui"
|
||||
path = "src/lib/gui/dialogs/*.ui"
|
||||
precedence = "override"
|
||||
SPDX-FileCopyrightText = "Deskflow Developers"
|
||||
SPDX-License-Identifier = "GPL-2.0-only WITH LicenseRef-OpenSSL-Exception"
|
||||
|
||||
@ -21,7 +21,7 @@ macro(configure_libs)
|
||||
|
||||
find_package(Qt6 ${REQUIRED_QT_VERSION} REQUIRED COMPONENTS Core Widgets Network)
|
||||
if(UNIX AND NOT APPLE)
|
||||
find_package(Qt6 ${REQUIRED_QT_VERSION} REQUIRED COMPONENTS DBus)
|
||||
find_package(Qt6 ${REQUIRED_QT_VERSION} REQUIRED COMPONENTS DBus Xml)
|
||||
endif()
|
||||
|
||||
# Define the location of Qt deployment tool
|
||||
@ -89,20 +89,11 @@ macro(configure_unix_libs)
|
||||
include(CheckSymbolExists)
|
||||
include(CheckCSourceCompiles)
|
||||
|
||||
check_include_file_cxx(istream HAVE_ISTREAM)
|
||||
check_include_file_cxx(ostream HAVE_OSTREAM)
|
||||
check_include_file_cxx(sstream HAVE_SSTREAM)
|
||||
|
||||
check_include_files(locale.h HAVE_LOCALE_H)
|
||||
check_include_files(sys/select.h HAVE_SYS_SELECT_H)
|
||||
check_include_files(sys/socket.h HAVE_SYS_SOCKET_H)
|
||||
check_include_files(sys/time.h HAVE_SYS_TIME_H)
|
||||
check_include_files(sys/utsname.h HAVE_SYS_UTSNAME_H)
|
||||
check_include_files(unistd.h HAVE_UNISTD_H)
|
||||
check_include_files(wchar.h HAVE_WCHAR_H)
|
||||
|
||||
check_function_exists(getpwuid_r HAVE_GETPWUID_R)
|
||||
check_function_exists(gmtime_r HAVE_GMTIME_R)
|
||||
check_function_exists(nanosleep HAVE_NANOSLEEP)
|
||||
check_function_exists(sigwait HAVE_POSIX_SIGWAIT)
|
||||
check_function_exists(inet_aton HAVE_INET_ATON)
|
||||
@ -158,34 +149,16 @@ macro(configure_unix_libs)
|
||||
configure_xorg_libs()
|
||||
|
||||
include(FindPkgConfig)
|
||||
|
||||
find_package(PkgConfig)
|
||||
if(PKG_CONFIG_FOUND)
|
||||
pkg_check_modules(LIBXKBCOMMON REQUIRED xkbcommon)
|
||||
pkg_check_modules(GLIB2 REQUIRED glib-2.0 gio-2.0)
|
||||
pkg_check_modules(GLIB2 REQUIRED glib-2.0)
|
||||
find_library(LIBM m)
|
||||
include_directories(${LIBXKBCOMMON_INCLUDE_DIRS} ${GLIB2_INCLUDE_DIRS}
|
||||
${LIBM_INCLUDE_DIRS})
|
||||
else()
|
||||
message(WARNING "pkg-config not found, skipping wayland libraries")
|
||||
endif()
|
||||
|
||||
|
||||
find_package(pugixml REQUIRED)
|
||||
|
||||
find_package(PkgConfig)
|
||||
if(PKG_CONFIG_FOUND)
|
||||
pkg_check_modules(lib_glib REQUIRED IMPORTED_TARGET glib-2.0)
|
||||
pkg_search_module(PC_GDKPIXBUF gdk-pixbuf-2.0)
|
||||
|
||||
include_directories(${PC_GDKPIXBUF_INCLUDE_DIRS})
|
||||
|
||||
pkg_check_modules(lib_gdkpixbuf REQUIRED IMPORTED_TARGET gdk-pixbuf-2.0)
|
||||
pkg_check_modules(lib_notify REQUIRED IMPORTED_TARGET libnotify)
|
||||
|
||||
add_definitions(-DHAVE_GDK_PIXBUF=1 -DHAVE_LIBNOTIFY=1)
|
||||
else()
|
||||
message(WARNING "pkg-config not found, skipping libnotify and gdk-pixbuf")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# For config.h, set some static values; it may be a good idea to make these
|
||||
@ -200,8 +173,8 @@ macro(configure_unix_libs)
|
||||
# Unix only: For config.h, save the results based on a template (config.h.in).
|
||||
# Note that this won't work on Windows because filenames are not case sensitive,
|
||||
# and we have header files named "Config.h" (upper case 'C').
|
||||
configure_file(${CMAKE_SOURCE_DIR}/src/lib/config.h.in
|
||||
${CMAKE_BINARY_DIR}/src/lib/config.h @ONLY)
|
||||
configure_file(${CMAKE_SOURCE_DIR}/src/lib/Config.h.in
|
||||
${CMAKE_BINARY_DIR}/src/lib/Config.h @ONLY)
|
||||
|
||||
add_definitions(-DSYSAPI_UNIX=1 -DHAVE_CONFIG_H)
|
||||
|
||||
|
||||
@ -26,6 +26,7 @@
|
||||
"Hadzhylov",
|
||||
"Hetu",
|
||||
"HINSTANCE",
|
||||
"HKLM",
|
||||
"hotspots",
|
||||
"Hutterer",
|
||||
"ifdef",
|
||||
@ -65,6 +66,7 @@
|
||||
"qobject",
|
||||
"qputenv",
|
||||
"readf",
|
||||
"Redist",
|
||||
"Regen",
|
||||
"Repology",
|
||||
"Rizzitello",
|
||||
|
||||
@ -22,9 +22,7 @@ depends=(
|
||||
'libxtst'
|
||||
'libxinerama'
|
||||
'libxkbcommon-x11'
|
||||
'libnotify'
|
||||
'hicolor-icon-theme'
|
||||
'pugixml'
|
||||
'qt6-base'
|
||||
'qt6-tools'
|
||||
'libei'
|
||||
|
||||
@ -23,17 +23,6 @@ cleanup:
|
||||
- /share/gir-1.0
|
||||
- /lib/girepository-1.0
|
||||
modules:
|
||||
- name: python3-attrs
|
||||
buildsystem: simple
|
||||
build-commands:
|
||||
- pip3 install --verbose --exists-action=i --no-index --find-links="file://${PWD}"
|
||||
--prefix=${FLATPAK_DEST} --no-build-isolation attrs
|
||||
sources:
|
||||
- type: file
|
||||
url: https://files.pythonhosted.org/packages/e0/44/827b2a91a5816512fcaf3cc4ebc465ccd5d598c45cefa6703fcf4a79018f/attrs-23.2.0-py3-none-any.whl
|
||||
sha256: 99b87a485a5820b23b879f04c2305b44b951b502fd64be915879d77a7e8fc6f1
|
||||
cleanup:
|
||||
- '*'
|
||||
- name: python3-Jinja2
|
||||
buildsystem: simple
|
||||
build-commands:
|
||||
@ -57,8 +46,8 @@ modules:
|
||||
sources:
|
||||
- type: git
|
||||
url: https://gitlab.freedesktop.org/libinput/libei
|
||||
tag: 1.3.0
|
||||
commit: 997b7c0f37faea4f8bae59613c8f27370925d5b0
|
||||
tag: 1.4.0
|
||||
commit: 5d6d8e6590df210b75559a889baa9459c68d9366
|
||||
- name: libportal
|
||||
buildsystem: meson
|
||||
config-opts:
|
||||
@ -70,15 +59,8 @@ modules:
|
||||
sources:
|
||||
- type: git
|
||||
url: https://github.com/flatpak/libportal.git
|
||||
tag: 0.8.1
|
||||
commit: 26c15008cbe579f57f89468384f8efc033f25f6f
|
||||
- name: puixml
|
||||
buildsystem: cmake-ninja
|
||||
sources:
|
||||
- type: git
|
||||
url: https://github.com/zeux/pugixml
|
||||
tag: v1.14
|
||||
commit: db78afc2b7d8f043b4bc6b185635d949ea2ed2a8
|
||||
tag: 0.9.1
|
||||
commit: 8f5dc8d192f6e31dafe69e35219e3b707bde71ce
|
||||
- name: cli11
|
||||
buildsystem: cmake-ninja
|
||||
config-opts:
|
||||
|
||||
@ -42,6 +42,33 @@
|
||||
</branding>
|
||||
<content_rating type="oars-1.0" />
|
||||
<releases>
|
||||
<release version="1.21.1" date="2025-03-31" urgency="high">
|
||||
<description>
|
||||
<p>This stable release fixes a few critical bugs in 1.21.0. For the full changelog see the release page.</p>
|
||||
<ul>
|
||||
<li>Fix: Flatpak can't save settings'</li>
|
||||
<li>Fix: Crash on localfingerprint dialog</li>
|
||||
<li>Fix: Check for updates settings reading from wrong value</li>
|
||||
<li>Fix: Windows settings saving blocked for non admin users </li>
|
||||
</ul>
|
||||
</description>
|
||||
<url>https://github.com/deskflow/deskflow/releases/tag/v1.21.1</url>
|
||||
</release>
|
||||
<release version="1.21.0" date="2025-03-27" urgency="high">
|
||||
<description>
|
||||
<p>This stable release removes some dependencies, additionally fixes several bugs. For the full changelog see the release page.</p>
|
||||
<ul>
|
||||
<li>Cleanup unused classes</li>
|
||||
<li>New Settings class</li>
|
||||
<li>Remove need for pugixml</li>
|
||||
<li>Remove need for libNotify</li>
|
||||
<li>Remove need for gio</li>
|
||||
<li>Remove need for gitkpixbuf</li>
|
||||
<li>Fix issues with windows installer when msvc is missing</li>
|
||||
</ul>
|
||||
</description>
|
||||
<url>https://github.com/deskflow/deskflow/releases/tag/v1.21.0</url>
|
||||
</release>
|
||||
<release version="1.20.1" date="2025-03-07" urgency="low">
|
||||
<description>
|
||||
<p>This stable release introduces a Windows dependency requirement and fixes a macOS bug.</p>
|
||||
|
||||
@ -53,3 +53,18 @@ configure_file(
|
||||
|
||||
# This patch set ups filewall rules, the service and msm module
|
||||
set(CPACK_WIX_PATCH_FILE "${CMAKE_CURRENT_BINARY_DIR}/wix-patch.xml")
|
||||
|
||||
# Creates a DLL that can be used by our MSI for custom actions.
|
||||
configure_file(
|
||||
${MY_DIR}/wix-custom.h.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/wix-custom.h @ONLY
|
||||
)
|
||||
add_library(
|
||||
wix-custom SHARED
|
||||
${MY_DIR}/wix-custom.cpp
|
||||
)
|
||||
target_include_directories(wix-custom PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
|
||||
set_target_properties(wix-custom PROPERTIES
|
||||
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
|
||||
)
|
||||
target_link_libraries(wix-custom PRIVATE Msi)
|
||||
|
||||
72
deploy/windows/wix-custom.cpp
Normal file
72
deploy/windows/wix-custom.cpp
Normal file
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Deskflow -- mouse and keyboard sharing utility
|
||||
* SPDX-FileCopyrightText: (C) 2025 Symless Ltd.
|
||||
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
|
||||
*/
|
||||
|
||||
#include "wix-custom.h"
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <Windows.h>
|
||||
|
||||
// Include after Windows.h
|
||||
#include <MsiQuery.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string>
|
||||
|
||||
namespace {
|
||||
// Warning: DLL will crash with error code 1603 if we exceed this.
|
||||
const auto kLogLineMax = 1024;
|
||||
|
||||
// Prefixes log messages with the app name so they're easier to find/filter.
|
||||
const std::string kLogPrefix = std::string(kAppId) + " installer: ";
|
||||
|
||||
// Note: Resized to log line max when used.
|
||||
static std::string s_logMessageBuffer; // NOSONAR - Must be mutable.
|
||||
} // namespace
|
||||
|
||||
// This log output can be viewed by using the DebugView program.
|
||||
#define MS_LOG_DEBUG(message, ...) \
|
||||
s_logMessageBuffer.resize(kLogLineMax); \
|
||||
sprintf(s_logMessageBuffer.data(), message, __VA_ARGS__); \
|
||||
OutputDebugStringA((kLogPrefix + s_logMessageBuffer + "\n").c_str())
|
||||
|
||||
extern "C" __declspec(dllexport) UINT __stdcall CheckVCRedist(MSIHANDLE hInstall)
|
||||
{
|
||||
const auto kKeyName = TEXT("SOFTWARE\\Microsoft\\VisualStudio\\14.0\\VC\\Runtimes\\x64");
|
||||
const auto kValueName = TEXT("Minor");
|
||||
const auto kProperty = "VC_REDIST_VERSION_OK";
|
||||
|
||||
MS_LOG_DEBUG("checking for msvc redist v%d.%d", kWindowsRuntimeMajor, kWindowsRuntimeMinor);
|
||||
|
||||
HKEY hKey;
|
||||
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, kKeyName, 0, KEY_READ, &hKey) != ERROR_SUCCESS) {
|
||||
MS_LOG_DEBUG("msvc redist registry key not found");
|
||||
return ERROR_FUNCTION_FAILED;
|
||||
}
|
||||
|
||||
MS_LOG_DEBUG("msvc redist registry key found, querying minor version");
|
||||
|
||||
DWORD minorVersion = 0;
|
||||
DWORD size = sizeof(DWORD);
|
||||
RegQueryValueEx(hKey, kValueName, nullptr, nullptr, (LPBYTE)&minorVersion, &size);
|
||||
RegCloseKey(hKey);
|
||||
|
||||
MS_LOG_DEBUG("msvc redist minor version: %lu", minorVersion);
|
||||
|
||||
if (minorVersion < kWindowsRuntimeMinor) {
|
||||
MS_LOG_DEBUG("msvc redist minor version %lu too low, expected >= %d", minorVersion, kWindowsRuntimeMinor);
|
||||
// Returning success allows the installer will show a friendly error message.
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
MS_LOG_DEBUG("msvc redist version ok, setting: %s", kProperty);
|
||||
if (MsiSetProperty(hInstall, kProperty, "ok") != ERROR_SUCCESS) {
|
||||
MS_LOG_DEBUG("failed to set property: %s", kProperty);
|
||||
return ERROR_FUNCTION_FAILED;
|
||||
}
|
||||
|
||||
MS_LOG_DEBUG("msvc redist version check successful");
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
14
deploy/windows/wix-custom.h.in
Normal file
14
deploy/windows/wix-custom.h.in
Normal file
@ -0,0 +1,14 @@
|
||||
/*
|
||||
* Deskflow -- mouse and keyboard sharing utility
|
||||
* SPDX-FileCopyrightText: (C) 2025 Symless Ltd.
|
||||
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
const auto kAppId = "@CMAKE_PROJECT_NAME@";
|
||||
|
||||
// clang-format off
|
||||
const auto kWindowsRuntimeMajor = @REQUIRED_MSVC_RUNTIME_MAJOR@;
|
||||
const auto kWindowsRuntimeMinor = @REQUIRED_MSVC_RUNTIME_MINOR@;
|
||||
// clang-format on
|
||||
@ -32,20 +32,47 @@
|
||||
<RegistrySearch
|
||||
Id="FindVCRedist"
|
||||
Root="HKLM"
|
||||
Key="SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\x64"
|
||||
Key="SOFTWARE\Microsoft\VisualStudio\@REQUIRED_MSVC_RUNTIME_MAJOR@.0\VC\Runtimes\x64"
|
||||
Name="Installed"
|
||||
Type="raw" />
|
||||
</Property>
|
||||
|
||||
<CustomAction Id="Run_Deskflow" ExeCommand="Deskflow" FileRef="CM_FP_deskflow.exe" Return="asyncNoWait"/>
|
||||
|
||||
<Binary Id="CustomDLL" SourceFile="@CMAKE_CURRENT_BINARY_DIR@/wix-custom.dll" />
|
||||
|
||||
<UI>
|
||||
<Publish Dialog="ExitDialog"
|
||||
Control="Finish"
|
||||
Event="DoAction"
|
||||
Value="RunDeskflow"
|
||||
Condition= "NOT Installed" />
|
||||
</UI>
|
||||
<CustomAction
|
||||
Id="CheckVCRedist"
|
||||
BinaryRef="CustomDLL"
|
||||
DllEntry="CheckVCRedist"
|
||||
Execute="immediate" />
|
||||
|
||||
<CustomAction
|
||||
Id="ShowVCRedistError"
|
||||
Error="Latest Microsoft Visual C++ Redistributable is required. Please install it before proceeding."/>
|
||||
Error="Microsoft Visual C++ Redistributable v@REQUIRED_MSVC_RUNTIME_MAJOR@.@REQUIRED_MSVC_RUNTIME_MINOR@ or later is required. Please download and install the latest version and then restart the installation. See our documentation for instructions." />
|
||||
|
||||
<CustomAction
|
||||
Id="RunDeskflow"
|
||||
ExeCommand="[INSTALL_ROOT]deskflow.exe"
|
||||
Directory="INSTALL_ROOT"
|
||||
Execute="immediate"
|
||||
Impersonate="yes"
|
||||
Return="asyncNoWait" />
|
||||
|
||||
<InstallExecuteSequence>
|
||||
<Custom Action="ShowVCRedistError" Before="InstallServices" Condition="NOT Installed AND NOT VC_REDIST_INSTALLED"/>
|
||||
<Custom Action="Run_Deskflow" OnExit="success" Condition="NOT Installed"/>
|
||||
<Custom
|
||||
Action="CheckVCRedist"
|
||||
Before="InstallInitialize"
|
||||
Condition="NOT Installed AND VC_REDIST_INSTALLED" />
|
||||
<Custom
|
||||
Action="ShowVCRedistError"
|
||||
Before="InstallInitialize"
|
||||
Condition="NOT Installed AND (NOT VC_REDIST_INSTALLED OR NOT VC_REDIST_VERSION_OK)" />
|
||||
</InstallExecuteSequence>
|
||||
</CPackWiXFragment>
|
||||
</CPackWiXPatch>
|
||||
|
||||
@ -1,3 +1,26 @@
|
||||
# GUI Config
|
||||
|
||||
The search order for a setting file is:
|
||||
1. `<install-path>/settings/Deskflow.conf`
|
||||
1. `<XDG_CONFIG_HOME>/Deskflow/Deskflow.conf`
|
||||
1. A user settings file
|
||||
1. A system settings file
|
||||
|
||||
A new settings file will be created in the user path if no settings file is found.
|
||||
The path of the settings file will be used as the base for all other config files.
|
||||
|
||||
### Windows
|
||||
- System: `C:\ProgramData\Deskflow\Deskflow.conf`
|
||||
- User: `C:\Users\userName\AppData\Local\Deskflow\Deskflow.conf`
|
||||
|
||||
### Linux
|
||||
- System: `/etc/Deskflow/Deskflow.conf`
|
||||
- User: `~/.config/Deskflow/Deskflow.conf`
|
||||
|
||||
### macOS
|
||||
- System: `/Library/Deskflow/Deskflow.conf`
|
||||
- User: `~/Library/Deskflow/Deskflow.conf`
|
||||
|
||||
# Server Config Examples
|
||||
|
||||
The `deskflow-server` command accepts the `-c` or `--config` option, which takes one argument,
|
||||
|
||||
@ -8,7 +8,7 @@
|
||||
#include "arch/Arch.h"
|
||||
#include "base/EventQueue.h"
|
||||
#include "base/Log.h"
|
||||
#include "common/constants.h"
|
||||
#include "common/Settings.h"
|
||||
#include "deskflow/DaemonApp.h"
|
||||
#include "deskflow/ipc/DaemonIpcServer.h"
|
||||
|
||||
@ -21,12 +21,13 @@
|
||||
|
||||
#endif
|
||||
|
||||
#include <QCommandLineParser>
|
||||
#include <QCoreApplication>
|
||||
#include <QThread>
|
||||
|
||||
using namespace deskflow::core;
|
||||
|
||||
void handleError(const char *message);
|
||||
void handleError(const char *message = "Unrecognized error.");
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
@ -43,84 +44,86 @@ int main(int argc, char **argv)
|
||||
Log log;
|
||||
EventQueue events;
|
||||
|
||||
auto &daemon = DaemonApp::instance();
|
||||
DaemonApp::InitResult initResult;
|
||||
try {
|
||||
initResult = daemon.init(&events, argc, argv);
|
||||
} catch (std::exception &e) {
|
||||
handleError(e.what());
|
||||
return kExitFailed;
|
||||
} catch (...) {
|
||||
handleError("Unrecognized error.");
|
||||
return kExitFailed;
|
||||
// Daemon deliberately does not have a parent, as it will be moved to a new thread.
|
||||
DaemonApp daemon(events);
|
||||
|
||||
QCoreApplication app(argc, argv);
|
||||
QCoreApplication::setApplicationName(QStringLiteral("%1 Daemon").arg(kAppName));
|
||||
|
||||
QCommandLineParser parser;
|
||||
parser.addHelpOption();
|
||||
parser.addVersionOption();
|
||||
|
||||
const auto foregroundOption = QCommandLineOption({"f", "foreground"}, "Run in the foreground (show console)");
|
||||
parser.addOption(foregroundOption);
|
||||
|
||||
const auto installOption = QCommandLineOption({"i", "install"}, "Install as a Windows service");
|
||||
parser.addOption(installOption);
|
||||
|
||||
const auto uninstallOption = QCommandLineOption({"u", "uninstall"}, "Uninstall the Windows service");
|
||||
parser.addOption(uninstallOption);
|
||||
|
||||
parser.process(app);
|
||||
|
||||
if (parser.isSet(foregroundOption)) {
|
||||
daemon.setForeground();
|
||||
}
|
||||
|
||||
// Important: Log the app name and version number to the log file after the daemon app init
|
||||
// because the file log outputter is created there. Logging before would only log to stdout
|
||||
// which is not useful for troubleshooting Windows services.
|
||||
// Depends on whether foreground option was set.
|
||||
daemon.initLogging();
|
||||
|
||||
// Important: Log the app name and version number to the log file daemon app has initialized
|
||||
// logging as it creates the file logger. Logging before would only log to stdout which is not
|
||||
// useful for troubleshooting Windows services.
|
||||
// It's important to write the version number to the log file so we can be certain the old daemon
|
||||
// was uninstalled, since sometimes Windows services can get stuck and fail to be removed.
|
||||
LOG_PRINT("%s Daemon v%s", kAppName, kDisplayVersion);
|
||||
LOG_PRINT("%s v%s", QCoreApplication::applicationName().toStdString().c_str(), kDisplayVersion);
|
||||
|
||||
switch (initResult) {
|
||||
using enum DaemonApp::InitResult;
|
||||
// Default log level to system setting (found in Registry).
|
||||
auto logLevel = Settings::value(Settings::Daemon::LogLevel).toString().toStdString();
|
||||
if (logLevel != "") {
|
||||
CLOG->setFilter(logLevel.c_str());
|
||||
LOG_DEBUG("log level: %s", logLevel.c_str());
|
||||
}
|
||||
|
||||
case StartDaemon: {
|
||||
LOG_INFO("starting daemon");
|
||||
QCoreApplication app(argc, argv);
|
||||
try {
|
||||
|
||||
#if SYSAPI_WIN32
|
||||
// Show warning if not running as admin as daemon will behave differently.
|
||||
if (!ArchMiscWindows::isProcessElevated()) {
|
||||
LOG_WARN("not running as admin, some features may not work");
|
||||
}
|
||||
#endif
|
||||
|
||||
if (parser.isSet(installOption)) {
|
||||
daemon.install();
|
||||
return kExitSuccess;
|
||||
} else if (parser.isSet(uninstallOption)) {
|
||||
daemon.uninstall();
|
||||
return kExitSuccess;
|
||||
}
|
||||
|
||||
const auto ipcServer =
|
||||
new ipc::DaemonIpcServer(&app, DaemonApp::logFilename().toStdString().c_str()); // NOSONAR - Qt managed
|
||||
ipcServer->listen();
|
||||
daemon.connectIpcServer(ipcServer);
|
||||
|
||||
QThread daemonThread;
|
||||
daemon.moveToThread(&daemonThread);
|
||||
|
||||
QObject::connect(&daemonThread, &QThread::started, [&daemon, &daemonThread]() {
|
||||
LOG_DEBUG("daemon thread started");
|
||||
daemon.run();
|
||||
daemonThread.quit();
|
||||
LOG_DEBUG("daemon thread finished");
|
||||
});
|
||||
QObject::connect(&daemonThread, &QThread::finished, &app, &QCoreApplication::quit);
|
||||
daemon.run(daemonThread);
|
||||
|
||||
ipc::DaemonIpcServer ipcServer(&app, QString::fromStdString(daemon.logFilename()));
|
||||
|
||||
// Use direct connection as the daemon app is on it's own thread, and so is on a different event loop.
|
||||
QObject::connect(
|
||||
&ipcServer, &ipc::DaemonIpcServer::logLevelChanged, &daemon, &DaemonApp::saveLogLevel, //
|
||||
Qt::DirectConnection
|
||||
);
|
||||
QObject::connect(
|
||||
&ipcServer, &ipc::DaemonIpcServer::elevateModeChanged, &daemon, &DaemonApp::setElevate, //
|
||||
Qt::DirectConnection
|
||||
);
|
||||
QObject::connect(
|
||||
&ipcServer, &ipc::DaemonIpcServer::commandChanged, &daemon, &DaemonApp::setCommand, //
|
||||
Qt::DirectConnection
|
||||
);
|
||||
QObject::connect(
|
||||
&ipcServer, &ipc::DaemonIpcServer::startProcessRequested, &daemon, &DaemonApp::applyWatchdogCommand, //
|
||||
Qt::DirectConnection
|
||||
);
|
||||
QObject::connect(
|
||||
&ipcServer, &ipc::DaemonIpcServer::stopProcessRequested, &daemon, &DaemonApp::clearWatchdogCommand, //
|
||||
Qt::DirectConnection
|
||||
);
|
||||
QObject::connect(
|
||||
&ipcServer, &ipc::DaemonIpcServer::clearSettingsRequested, &daemon, &DaemonApp::clearSettings, //
|
||||
Qt::DirectConnection
|
||||
);
|
||||
|
||||
daemonThread.start();
|
||||
const auto exitCode = QCoreApplication::exec();
|
||||
daemonThread.wait();
|
||||
|
||||
LOG_DEBUG("daemon exited, code: %d", exitCode);
|
||||
return exitCode;
|
||||
}
|
||||
|
||||
case FatalError:
|
||||
} catch (std::exception &e) {
|
||||
handleError(e.what());
|
||||
return kExitFailed;
|
||||
} catch (...) {
|
||||
handleError();
|
||||
return kExitFailed;
|
||||
|
||||
default:
|
||||
return kExitSuccess;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -44,60 +44,7 @@ endif()
|
||||
add_executable(${target} WIN32 MACOSX_BUNDLE
|
||||
${platform_extra}
|
||||
../res/deskflow.qrc
|
||||
Action.cpp
|
||||
Action.h
|
||||
DataDownloader.cpp
|
||||
DataDownloader.h
|
||||
Hotkey.cpp
|
||||
Hotkey.h
|
||||
KeySequence.cpp
|
||||
KeySequence.h
|
||||
main.cpp
|
||||
MainWindow.cpp
|
||||
MainWindow.h
|
||||
MainWindow.ui
|
||||
ProcessorArch.h
|
||||
QUtility.cpp
|
||||
QUtility.h
|
||||
ScreenSetupModel.cpp
|
||||
ScreenSetupModel.h
|
||||
ServerConfig.cpp
|
||||
ServerConfig.h
|
||||
VersionChecker.cpp
|
||||
VersionChecker.h
|
||||
dialogs/AboutDialog.cpp
|
||||
dialogs/AboutDialog.h
|
||||
dialogs/AboutDialog.ui
|
||||
dialogs/ActionDialog.cpp
|
||||
dialogs/ActionDialog.h
|
||||
dialogs/ActionDialog.ui
|
||||
dialogs/AddClientDialog.cpp
|
||||
dialogs/AddClientDialog.h
|
||||
dialogs/AddClientDialog.ui
|
||||
dialogs/FingerprintDialog.h
|
||||
dialogs/FingerprintDialog.cpp
|
||||
dialogs/HotkeyDialog.cpp
|
||||
dialogs/HotkeyDialog.h
|
||||
dialogs/HotkeyDialog.ui
|
||||
dialogs/ScreenSettingsDialog.cpp
|
||||
dialogs/ScreenSettingsDialog.h
|
||||
dialogs/ScreenSettingsDialog.ui
|
||||
dialogs/ServerConfigDialog.cpp
|
||||
dialogs/ServerConfigDialog.h
|
||||
dialogs/ServerConfigDialog.ui
|
||||
dialogs/SettingsDialog.cpp
|
||||
dialogs/SettingsDialog.h
|
||||
dialogs/SettingsDialog.ui
|
||||
widgets/FingerprintPreview.h
|
||||
widgets/FingerprintPreview.cpp
|
||||
widgets/KeySequenceWidget.cpp
|
||||
widgets/KeySequenceWidget.h
|
||||
widgets/NewScreenWidget.h
|
||||
widgets/NewScreenWidget.cpp
|
||||
widgets/ScreenSetupView.cpp
|
||||
widgets/ScreenSetupView.h
|
||||
widgets/TrashScreenWidget.cpp
|
||||
widgets/TrashScreenWidget.h
|
||||
deskflow-gui.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(
|
||||
|
||||
@ -1,18 +0,0 @@
|
||||
/*
|
||||
* Deskflow -- mouse and keyboard sharing utility
|
||||
* SPDX-FileCopyrightText: (C) 2015 - 2016 Symless Ltd.
|
||||
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
enum qProcessorArch
|
||||
{
|
||||
kProcessorArchWin32,
|
||||
kProcessorArchWin64,
|
||||
kProcessorArchMac32,
|
||||
kProcessorArchMac64,
|
||||
kProcessorArchLinux32,
|
||||
kProcessorArchLinux64,
|
||||
kProcessorArchUnknown
|
||||
};
|
||||
@ -1,65 +0,0 @@
|
||||
/*
|
||||
* Deskflow -- mouse and keyboard sharing utility
|
||||
* SPDX-FileCopyrightText: (C) 2013 - 2016 Symless Ltd.
|
||||
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
|
||||
*/
|
||||
|
||||
#include "QUtility.h"
|
||||
|
||||
#include "ProcessorArch.h"
|
||||
|
||||
#if defined(Q_OS_LINUX)
|
||||
#include <QFile>
|
||||
#include <QProcess>
|
||||
#endif
|
||||
|
||||
#if defined(Q_OS_WIN)
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <Windows.h>
|
||||
#endif
|
||||
|
||||
void setIndexFromItemData(QComboBox *comboBox, const QVariant &itemData)
|
||||
{
|
||||
for (int i = 0; i < comboBox->count(); ++i) {
|
||||
if (comboBox->itemData(i) == itemData) {
|
||||
comboBox->setCurrentIndex(i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QString hash(const QString &string)
|
||||
{
|
||||
QByteArray data = string.toUtf8();
|
||||
QByteArray hash = QCryptographicHash::hash(data, QCryptographicHash::Md5);
|
||||
return hash.toHex();
|
||||
}
|
||||
|
||||
qProcessorArch getProcessorArch()
|
||||
{
|
||||
#if defined(Q_OS_WIN)
|
||||
SYSTEM_INFO systemInfo;
|
||||
GetNativeSystemInfo(&systemInfo);
|
||||
|
||||
switch (systemInfo.wProcessorArchitecture) {
|
||||
case PROCESSOR_ARCHITECTURE_INTEL:
|
||||
return kProcessorArchWin32;
|
||||
case PROCESSOR_ARCHITECTURE_IA64:
|
||||
return kProcessorArchWin64;
|
||||
case PROCESSOR_ARCHITECTURE_AMD64:
|
||||
return kProcessorArchWin64;
|
||||
default:
|
||||
return kProcessorArchUnknown;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(Q_OS_LINUX)
|
||||
#ifdef __i386__
|
||||
return kProcessorArchLinux32;
|
||||
#else
|
||||
return kProcessorArchLinux64;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
return kProcessorArchUnknown;
|
||||
}
|
||||
@ -1,18 +0,0 @@
|
||||
/*
|
||||
* Deskflow -- mouse and keyboard sharing utility
|
||||
* SPDX-FileCopyrightText: (C) 2013 - 2016 Symless Ltd.
|
||||
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ProcessorArch.h"
|
||||
|
||||
#include <QComboBox>
|
||||
#include <QCryptographicHash>
|
||||
#include <QNetworkInterface>
|
||||
#include <QVariant>
|
||||
|
||||
void setIndexFromItemData(QComboBox *comboBox, const QVariant &itemData);
|
||||
QString hash(const QString &string);
|
||||
qProcessorArch getProcessorArch();
|
||||
@ -6,17 +6,14 @@
|
||||
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
|
||||
*/
|
||||
|
||||
#include "MainWindow.h"
|
||||
#include "common/constants.h"
|
||||
#include "common/Constants.h"
|
||||
#include "common/UrlConstants.h"
|
||||
#include "gui/Diagnostic.h"
|
||||
#include "gui/DotEnv.h"
|
||||
#include "gui/Logger.h"
|
||||
#include "gui/config/AppConfig.h"
|
||||
#include "gui/config/ConfigScopes.h"
|
||||
#include "gui/constants.h"
|
||||
#include "gui/diagnostic.h"
|
||||
#include "gui/dotenv.h"
|
||||
#include "gui/messages.h"
|
||||
#include "gui/string_utils.h"
|
||||
#include "gui/style_utils.h"
|
||||
#include "gui/MainWindow.h"
|
||||
#include "gui/Messages.h"
|
||||
#include "gui/StyleUtils.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QDebug>
|
||||
@ -120,8 +117,10 @@ int main(int argc, char *argv[])
|
||||
#if defined(Q_OS_MAC)
|
||||
|
||||
if (app.applicationDirPath().startsWith("/Volumes/")) {
|
||||
QString msgBody = QStringLiteral("Please drag %1 to the Applications folder, "
|
||||
"and open it from there.");
|
||||
QString msgBody = QStringLiteral(
|
||||
"Please drag %1 to the Applications folder, "
|
||||
"and open it from there."
|
||||
);
|
||||
QMessageBox::information(NULL, kAppName, msgBody.arg(kAppName));
|
||||
return 1;
|
||||
}
|
||||
@ -131,23 +130,15 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
#endif
|
||||
|
||||
ConfigScopes configScopes;
|
||||
|
||||
// --no-reset
|
||||
QStringList arguments = QCoreApplication::arguments();
|
||||
const auto noReset = hasArg("--no-reset", arguments);
|
||||
const auto resetEnvVar = strToTrue(qEnvironmentVariable("DESKFLOW_RESET_ALL"));
|
||||
const auto resetEnvVar = QVariant(qEnvironmentVariable("DESKFLOW_RESET_ALL")).toBool();
|
||||
if (resetEnvVar && !noReset) {
|
||||
diagnostic::clearSettings(configScopes, false);
|
||||
diagnostic::clearSettings(false);
|
||||
}
|
||||
|
||||
AppConfig appConfig(configScopes);
|
||||
|
||||
QObject::connect(
|
||||
&configScopes, &ConfigScopes::saving, &appConfig, [&appConfig]() { appConfig.commit(); }, Qt::DirectConnection
|
||||
);
|
||||
|
||||
MainWindow mainWindow(configScopes, appConfig);
|
||||
MainWindow mainWindow;
|
||||
mainWindow.open();
|
||||
|
||||
return QApplication::exec();
|
||||
@ -181,9 +172,11 @@ bool checkMacAssistiveDevices()
|
||||
// now deprecated in mavericks.
|
||||
bool result = AXAPIEnabled();
|
||||
if (!result) {
|
||||
QString msgBody = QString("Please enable access to assistive devices "
|
||||
"System Preferences -> Security & Privacy -> "
|
||||
"Privacy -> Accessibility, then re-open %1.");
|
||||
QString msgBody = QString(
|
||||
"Please enable access to assistive devices "
|
||||
"System Preferences -> Security & Privacy -> "
|
||||
"Privacy -> Accessibility, then re-open %1."
|
||||
);
|
||||
QMessageBox::information(NULL, kAppName, msgBody.arg(kAppName));
|
||||
}
|
||||
return result;
|
||||
@ -10,27 +10,12 @@
|
||||
/* Define if the <X11/extensions/dpms.h> header file declares function prototypes. */
|
||||
#cmakedefine HAVE_DPMS_PROTOTYPES @HAVE_DPMS_PROTOTYPES@
|
||||
|
||||
/* Define if you have a working `getpwuid_r` function. */
|
||||
#cmakedefine HAVE_GETPWUID_R @HAVE_GETPWUID_R@
|
||||
|
||||
/* Define to 1 if you have the `gmtime_r` function. */
|
||||
#cmakedefine HAVE_GMTIME_R @HAVE_GMTIME_R@
|
||||
|
||||
/* Define if you have the `inet_aton` function. */
|
||||
#cmakedefine HAVE_INET_ATON @HAVE_INET_ATON@
|
||||
|
||||
/* Define to 1 if you have the <istream> header file. */
|
||||
#cmakedefine HAVE_ISTREAM @HAVE_ISTREAM@
|
||||
|
||||
/* Define to 1 if you have the <locale.h> header file. */
|
||||
#cmakedefine HAVE_LOCALE_H @HAVE_LOCALE_H@
|
||||
|
||||
/* Define if you have the `nanosleep` function. */
|
||||
#cmakedefine HAVE_NANOSLEEP @HAVE_NANOSLEEP@
|
||||
|
||||
/* Define to 1 if you have the <ostream> header file. */
|
||||
#cmakedefine HAVE_OSTREAM @HAVE_OSTREAM@
|
||||
|
||||
/* Define if you have a POSIX `sigwait` function. */
|
||||
#cmakedefine HAVE_POSIX_SIGWAIT @HAVE_POSIX_SIGWAIT@
|
||||
|
||||
@ -43,9 +28,6 @@
|
||||
/* Define if your compiler defines socklen_t. */
|
||||
#cmakedefine HAVE_SOCKLEN_T @HAVE_SOCKLEN_T@
|
||||
|
||||
/* Define to 1 if you have the <sstream> header file. */
|
||||
#cmakedefine HAVE_SSTREAM @HAVE_SSTREAM@
|
||||
|
||||
/* Define to 1 if you have the <sys/select.h> header file. */
|
||||
#cmakedefine HAVE_SYS_SELECT_H @HAVE_SYS_SELECT_H@
|
||||
|
||||
@ -58,15 +40,9 @@
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#cmakedefine HAVE_SYS_TYPES_H @HAVE_SYS_TYPES_H@
|
||||
|
||||
/* Define to 1 if you have the <sys/utsname.h> header file. */
|
||||
#cmakedefine HAVE_SYS_UTSNAME_H @HAVE_SYS_UTSNAME_H@
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#cmakedefine HAVE_UNISTD_H @HAVE_UNISTD_H@
|
||||
|
||||
/* Define to 1 if you have the <wchar.h> header file. */
|
||||
#cmakedefine HAVE_WCHAR_H @HAVE_WCHAR_H@
|
||||
|
||||
/* Define to 1 if you have the <X11/extensions/Xrandr.h> header file. */
|
||||
#cmakedefine HAVE_X11_EXTENSIONS_XRANDR_H @HAVE_X11_EXTENSIONS_XRANDR_H@
|
||||
|
||||
@ -30,9 +30,6 @@ Arch::Arch(Arch *arch)
|
||||
|
||||
Arch::~Arch()
|
||||
{
|
||||
#if SYSAPI_WIN32
|
||||
ArchMiscWindows::cleanup();
|
||||
#endif
|
||||
}
|
||||
|
||||
void Arch::init()
|
||||
|
||||
@ -24,31 +24,27 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/common.h"
|
||||
#include "common/Common.h"
|
||||
|
||||
#if SYSAPI_WIN32
|
||||
|
||||
#include "arch/win32/ArchConsoleWindows.h"
|
||||
#include "arch/win32/ArchDaemonWindows.h"
|
||||
#include "arch/win32/ArchFileWindows.h"
|
||||
#include "arch/win32/ArchLogWindows.h"
|
||||
#include "arch/win32/ArchMultithreadWindows.h"
|
||||
#include "arch/win32/ArchNetworkWinsock.h"
|
||||
#include "arch/win32/ArchSleepWindows.h"
|
||||
#include "arch/win32/ArchStringWindows.h"
|
||||
#include "arch/win32/ArchSystemWindows.h"
|
||||
#include "arch/win32/ArchTimeWindows.h"
|
||||
|
||||
#elif SYSAPI_UNIX
|
||||
|
||||
#include "arch/unix/ArchConsoleUnix.h"
|
||||
#include "arch/unix/ArchDaemonUnix.h"
|
||||
#include "arch/unix/ArchFileUnix.h"
|
||||
#include "arch/unix/ArchLogUnix.h"
|
||||
#include "arch/unix/ArchNetworkBSD.h"
|
||||
#include "arch/unix/ArchSleepUnix.h"
|
||||
#include "arch/unix/ArchStringUnix.h"
|
||||
#include "arch/unix/ArchSystemUnix.h"
|
||||
#include "arch/unix/ArchTimeUnix.h"
|
||||
|
||||
#if HAVE_PTHREAD
|
||||
@ -75,13 +71,11 @@ typically at the beginning of \c main().
|
||||
*/
|
||||
class Arch : public ARCH_CONSOLE,
|
||||
public ARCH_DAEMON,
|
||||
public ARCH_FILE,
|
||||
public ARCH_LOG,
|
||||
public ARCH_MULTITHREAD,
|
||||
public ARCH_NETWORK,
|
||||
public ARCH_SLEEP,
|
||||
public ARCH_STRING,
|
||||
public ARCH_SYSTEM,
|
||||
public ARCH_TIME
|
||||
{
|
||||
public:
|
||||
|
||||
@ -10,8 +10,6 @@ if(WIN32)
|
||||
win32/ArchConsoleWindows.h
|
||||
win32/ArchDaemonWindows.cpp
|
||||
win32/ArchDaemonWindows.h
|
||||
win32/ArchFileWindows.cpp
|
||||
win32/ArchFileWindows.h
|
||||
win32/ArchLogWindows.cpp
|
||||
win32/ArchLogWindows.h
|
||||
win32/ArchMiscWindows.cpp
|
||||
@ -24,8 +22,6 @@ if(WIN32)
|
||||
win32/ArchSleepWindows.h
|
||||
win32/ArchStringWindows.cpp
|
||||
win32/ArchStringWindows.h
|
||||
win32/ArchSystemWindows.cpp
|
||||
win32/ArchSystemWindows.h
|
||||
win32/ArchTimeWindows.cpp
|
||||
win32/ArchTimeWindows.h
|
||||
win32/XArchWindows.cpp
|
||||
@ -38,8 +34,6 @@ elseif(UNIX)
|
||||
unix/ArchConsoleUnix.h
|
||||
unix/ArchDaemonUnix.cpp
|
||||
unix/ArchDaemonUnix.h
|
||||
unix/ArchFileUnix.cpp
|
||||
unix/ArchFileUnix.h
|
||||
unix/ArchLogUnix.cpp
|
||||
unix/ArchLogUnix.h
|
||||
unix/ArchMultithreadPosix.cpp
|
||||
@ -50,8 +44,6 @@ elseif(UNIX)
|
||||
unix/ArchSleepUnix.h
|
||||
unix/ArchStringUnix.cpp
|
||||
unix/ArchStringUnix.h
|
||||
unix/ArchSystemUnix.cpp
|
||||
unix/ArchSystemUnix.h
|
||||
unix/ArchTimeUnix.cpp
|
||||
unix/ArchTimeUnix.h
|
||||
unix/XArchUnix.cpp
|
||||
@ -68,22 +60,16 @@ add_library(arch STATIC ${PLATFORM_CODE}
|
||||
ArchDaemonNone.h
|
||||
IArchConsole.h
|
||||
IArchDaemon.h
|
||||
IArchFile.h
|
||||
IArchLog.h
|
||||
IArchMultithread.h
|
||||
IArchNetwork.h
|
||||
IArchSleep.h
|
||||
IArchString.cpp
|
||||
IArchString.h
|
||||
IArchSystem.h
|
||||
IArchTime.h
|
||||
multibyte.h
|
||||
XArch.h
|
||||
)
|
||||
|
||||
if(UNIX)
|
||||
target_link_libraries(arch ${libs})
|
||||
if(NOT APPLE)
|
||||
target_link_libraries(arch Qt6::DBus)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
@ -8,6 +8,8 @@
|
||||
#pragma once
|
||||
|
||||
#include "common/IInterface.h"
|
||||
|
||||
#include <functional>
|
||||
#include <string>
|
||||
|
||||
//! Interface for architecture dependent daemonizing
|
||||
@ -19,7 +21,7 @@ implement this interface.
|
||||
class IArchDaemon : public IInterface
|
||||
{
|
||||
public:
|
||||
typedef int (*DaemonFunc)(int argc, const char **argv);
|
||||
using DaemonFunc = std::function<int(int, const char **)>;
|
||||
|
||||
//! @name manipulators
|
||||
//@{
|
||||
|
||||
@ -1,92 +0,0 @@
|
||||
/*
|
||||
* Deskflow -- mouse and keyboard sharing utility
|
||||
* SPDX-FileCopyrightText: (C) 2012 - 2016 Symless Ltd.
|
||||
* SPDX-FileCopyrightText: (C) 2002 Chris Schoeneman
|
||||
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/IInterface.h"
|
||||
#include <string>
|
||||
|
||||
//! Interface for architecture dependent file system operations
|
||||
/*!
|
||||
This interface defines the file system operations required by
|
||||
deskflow. Each architecture must implement this interface.
|
||||
*/
|
||||
class IArchFile : public IInterface
|
||||
{
|
||||
public:
|
||||
//! @name manipulators
|
||||
//@{
|
||||
|
||||
//! Extract base name
|
||||
/*!
|
||||
Find the base name in the given \c pathname.
|
||||
*/
|
||||
virtual const char *getBasename(const char *pathname) = 0;
|
||||
|
||||
//! Get user's home directory
|
||||
/*!
|
||||
Returns the user's home directory. Returns the empty string if
|
||||
this cannot be determined.
|
||||
*/
|
||||
virtual std::string getUserDirectory() = 0;
|
||||
|
||||
//! Get system directory
|
||||
/*!
|
||||
Returns the ussystem configuration file directory.
|
||||
*/
|
||||
virtual std::string getSystemDirectory() = 0;
|
||||
|
||||
//! Get installed directory
|
||||
/*!
|
||||
Returns the directory in which Deskflow is installed.
|
||||
*/
|
||||
virtual std::string getInstalledDirectory() = 0;
|
||||
|
||||
//! Get log directory
|
||||
/*!
|
||||
Returns the log file directory.
|
||||
*/
|
||||
virtual std::string getLogDirectory() = 0;
|
||||
|
||||
//! Get plugins directory
|
||||
/*!
|
||||
Returns the plugin files directory. If no plugin directory is set,
|
||||
this will return the plugin folder within the user's profile.
|
||||
*/
|
||||
virtual std::string getPluginDirectory() = 0;
|
||||
|
||||
//! Get user's profile directory
|
||||
/*!
|
||||
Returns the user's profile directory. If no profile directory is set,
|
||||
this will return the user's profile according to the operating system,
|
||||
which will depend on which user launched the program.
|
||||
*/
|
||||
virtual std::string getProfileDirectory() = 0;
|
||||
|
||||
//! Concatenate path components
|
||||
/*!
|
||||
Concatenate pathname components with a directory separator
|
||||
between them. This should not check if the resulting path
|
||||
is longer than allowed by the system; we'll rely on the
|
||||
system calls to tell us that.
|
||||
*/
|
||||
virtual std::string concatPath(const std::string &prefix, const std::string &suffix) = 0;
|
||||
|
||||
//@}
|
||||
//! Set the user's profile directory
|
||||
/*
|
||||
Returns the user's profile directory.
|
||||
*/
|
||||
virtual void setProfileDirectory(const std::string &s) = 0;
|
||||
|
||||
//@}
|
||||
//! Set the user's plugin directory
|
||||
/*
|
||||
Returns the user's plugin directory.
|
||||
*/
|
||||
virtual void setPluginDirectory(const std::string &s) = 0;
|
||||
};
|
||||
@ -7,7 +7,7 @@
|
||||
|
||||
#include "arch/IArchString.h"
|
||||
#include "arch/Arch.h"
|
||||
#include "common/common.h"
|
||||
#include "common/Common.h"
|
||||
|
||||
#include <climits>
|
||||
#include <cstdlib>
|
||||
|
||||
@ -8,8 +8,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/Common.h"
|
||||
#include "common/IInterface.h"
|
||||
#include "common/common.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
|
||||
|
||||
@ -1,56 +0,0 @@
|
||||
/*
|
||||
* Deskflow -- mouse and keyboard sharing utility
|
||||
* SPDX-FileCopyrightText: (C) 2012 - 2016 Symless Ltd.
|
||||
* SPDX-FileCopyrightText: (C) 2004 Chris Schoeneman
|
||||
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/IInterface.h"
|
||||
#include <string>
|
||||
|
||||
//! Interface for architecture dependent system queries
|
||||
/*!
|
||||
This interface defines operations for querying system info.
|
||||
*/
|
||||
class IArchSystem : public IInterface
|
||||
{
|
||||
public:
|
||||
//! @name accessors
|
||||
//@{
|
||||
|
||||
//! Identify the OS
|
||||
/*!
|
||||
Returns a string identifying the operating system.
|
||||
*/
|
||||
virtual std::string getOSName() const = 0;
|
||||
|
||||
//! Identify the platform
|
||||
/*!
|
||||
Returns a string identifying the platform this OS is running on.
|
||||
*/
|
||||
virtual std::string getPlatformName() const = 0;
|
||||
//@}
|
||||
|
||||
//! Get a Deskflow setting
|
||||
/*!
|
||||
Reads a Deskflow setting from the system.
|
||||
*/
|
||||
virtual std::string setting(const std::string &valueName) const = 0;
|
||||
//@}
|
||||
|
||||
//! Set a Deskflow setting
|
||||
/*!
|
||||
Writes a Deskflow setting from the system.
|
||||
*/
|
||||
virtual void setting(const std::string &valueName, const std::string &valueString) const = 0;
|
||||
//@}
|
||||
|
||||
//! Delete settings
|
||||
/*!
|
||||
Deletes all Core settings from the system.
|
||||
*/
|
||||
virtual void clearSettings() const = 0;
|
||||
//@}
|
||||
};
|
||||
@ -7,8 +7,9 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/common.h"
|
||||
#include "common/stdexcept.h"
|
||||
#include "common/Common.h"
|
||||
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
//! Generic thread exception
|
||||
@ -57,7 +58,7 @@ public:
|
||||
XArchEval()
|
||||
{
|
||||
}
|
||||
virtual ~XArchEval() _NOEXCEPT
|
||||
virtual ~XArchEval() throw()
|
||||
{
|
||||
}
|
||||
|
||||
@ -75,7 +76,7 @@ public:
|
||||
XArch(const std::string &msg) : std::runtime_error(msg)
|
||||
{
|
||||
}
|
||||
virtual ~XArch() _NOEXCEPT
|
||||
virtual ~XArch() throw()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
@ -1,41 +0,0 @@
|
||||
/*
|
||||
* Deskflow -- mouse and keyboard sharing utility
|
||||
* SPDX-FileCopyrightText: (C) 2012 - 2016 Symless Ltd.
|
||||
* SPDX-FileCopyrightText: (C) 2002 Chris Schoeneman
|
||||
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "arch/Arch.h"
|
||||
#include "common/common.h"
|
||||
|
||||
#include <climits>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#if HAVE_LOCALE_H
|
||||
#include <locale.h>
|
||||
#endif
|
||||
#if HAVE_WCHAR_H || defined(_MSC_VER)
|
||||
#include <wchar.h>
|
||||
#elif __APPLE__
|
||||
// wtf? Darwin puts mbtowc() et al. in stdlib
|
||||
#include <cstdlib>
|
||||
#else
|
||||
// platform apparently has no wchar_t support. provide dummy
|
||||
// implementations. hopefully at least the C++ compiler has
|
||||
// a built-in wchar_t type.
|
||||
|
||||
static inline int mbtowc(wchar_t *dst, const char *src, int n)
|
||||
{
|
||||
*dst = static_cast<wchar_t>(*src);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline int wctomb(char *dst, wchar_t src)
|
||||
{
|
||||
*dst = static_cast<char>(src);
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -1,146 +0,0 @@
|
||||
/*
|
||||
* Deskflow -- mouse and keyboard sharing utility
|
||||
* SPDX-FileCopyrightText: (C) 2012 - 2016 Symless Ltd.
|
||||
* SPDX-FileCopyrightText: (C) 2002 Chris Schoeneman
|
||||
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
|
||||
*/
|
||||
|
||||
#include "arch/unix/ArchFileUnix.h"
|
||||
|
||||
#include "common/constants.h"
|
||||
#include <cstring>
|
||||
#include <filesystem>
|
||||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
//
|
||||
// ArchFileUnix
|
||||
//
|
||||
|
||||
ArchFileUnix::ArchFileUnix()
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
ArchFileUnix::~ArchFileUnix()
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
const char *ArchFileUnix::getBasename(const char *pathname)
|
||||
{
|
||||
if (pathname == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const char *basename = strrchr(pathname, '/');
|
||||
if (basename != NULL) {
|
||||
return basename + 1;
|
||||
} else {
|
||||
return pathname;
|
||||
}
|
||||
}
|
||||
|
||||
std::string ArchFileUnix::getUserDirectory()
|
||||
{
|
||||
char *buffer = NULL;
|
||||
std::string dir;
|
||||
#if HAVE_GETPWUID_R
|
||||
struct passwd pwent;
|
||||
struct passwd *pwentp{};
|
||||
#if defined(_SC_GETPW_R_SIZE_MAX)
|
||||
long size = sysconf(_SC_GETPW_R_SIZE_MAX);
|
||||
if (size == -1) {
|
||||
size = BUFSIZ;
|
||||
}
|
||||
#else
|
||||
long size = BUFSIZ;
|
||||
#endif
|
||||
buffer = new char[size];
|
||||
getpwuid_r(getuid(), &pwent, buffer, size, &pwentp);
|
||||
#else
|
||||
struct passwd *pwentp = getpwuid(getuid());
|
||||
#endif
|
||||
if (pwentp != NULL && pwentp->pw_dir != NULL) {
|
||||
dir = pwentp->pw_dir;
|
||||
}
|
||||
delete[] buffer;
|
||||
return dir;
|
||||
}
|
||||
|
||||
std::string ArchFileUnix::getSystemDirectory()
|
||||
{
|
||||
return "/etc";
|
||||
}
|
||||
|
||||
std::string ArchFileUnix::getInstalledDirectory()
|
||||
{
|
||||
#if WINAPI_XWINDOWS
|
||||
return "/usr/bin";
|
||||
#else
|
||||
std::string rtn = "/Applications/";
|
||||
rtn.append(kAppName).append(".app/Contents/MacOS");
|
||||
return rtn;
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string ArchFileUnix::getLogDirectory()
|
||||
{
|
||||
return "/var/log";
|
||||
}
|
||||
|
||||
std::string ArchFileUnix::getPluginDirectory()
|
||||
{
|
||||
if (!m_pluginDirectory.empty()) {
|
||||
return m_pluginDirectory;
|
||||
}
|
||||
|
||||
#if WINAPI_XWINDOWS
|
||||
return getProfileDirectory().append("/plugins");
|
||||
#else
|
||||
return getProfileDirectory().append("/Plugins");
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string ArchFileUnix::getProfileDirectory()
|
||||
{
|
||||
if (!m_profileDirectory.empty()) {
|
||||
return m_profileDirectory;
|
||||
} else {
|
||||
const std::filesystem::path homeDir = getUserDirectory();
|
||||
#if WINAPI_XWINDOWS
|
||||
const auto xdgDir = std::getenv("XDG_CONFIG_HOME");
|
||||
if (xdgDir != nullptr) {
|
||||
return std::filesystem::path(xdgDir) / kAppName;
|
||||
} else {
|
||||
return homeDir / ".config" / kAppName;
|
||||
}
|
||||
#else
|
||||
return homeDir / "Library" / kAppName;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
std::string ArchFileUnix::concatPath(const std::string &prefix, const std::string &suffix)
|
||||
{
|
||||
std::string path;
|
||||
path.reserve(prefix.size() + 1 + suffix.size());
|
||||
path += prefix;
|
||||
if (path.size() == 0 || path[path.size() - 1] != '/') {
|
||||
path += '/';
|
||||
}
|
||||
path += suffix;
|
||||
return path;
|
||||
}
|
||||
|
||||
void ArchFileUnix::setProfileDirectory(const std::string &s)
|
||||
{
|
||||
m_profileDirectory = s;
|
||||
}
|
||||
|
||||
void ArchFileUnix::setPluginDirectory(const std::string &s)
|
||||
{
|
||||
m_pluginDirectory = s;
|
||||
}
|
||||
@ -1,36 +0,0 @@
|
||||
/*
|
||||
* Deskflow -- mouse and keyboard sharing utility
|
||||
* SPDX-FileCopyrightText: (C) 2012 - 2016 Symless Ltd.
|
||||
* SPDX-FileCopyrightText: (C) 2002 Chris Schoeneman
|
||||
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "arch/IArchFile.h"
|
||||
|
||||
#define ARCH_FILE ArchFileUnix
|
||||
|
||||
//! Unix implementation of IArchFile
|
||||
class ArchFileUnix : public IArchFile
|
||||
{
|
||||
public:
|
||||
ArchFileUnix();
|
||||
virtual ~ArchFileUnix();
|
||||
|
||||
// IArchFile overrides
|
||||
virtual const char *getBasename(const char *pathname);
|
||||
virtual std::string getUserDirectory();
|
||||
virtual std::string getSystemDirectory();
|
||||
virtual std::string getInstalledDirectory();
|
||||
virtual std::string getLogDirectory();
|
||||
virtual std::string getPluginDirectory();
|
||||
virtual std::string getProfileDirectory();
|
||||
virtual std::string concatPath(const std::string &prefix, const std::string &suffix);
|
||||
virtual void setProfileDirectory(const std::string &s);
|
||||
virtual void setPluginDirectory(const std::string &s);
|
||||
|
||||
private:
|
||||
std::string m_profileDirectory;
|
||||
std::string m_pluginDirectory;
|
||||
};
|
||||
@ -8,8 +8,8 @@
|
||||
#pragma once
|
||||
|
||||
#include "arch/IArchMultithread.h"
|
||||
#include "common/stdlist.h"
|
||||
|
||||
#include <list>
|
||||
#include <pthread.h>
|
||||
|
||||
#define ARCH_MULTITHREAD ArchMultithreadPosix
|
||||
|
||||
@ -13,8 +13,6 @@
|
||||
// ArchStringUnix
|
||||
//
|
||||
|
||||
#include "arch/multibyte.h"
|
||||
|
||||
ArchStringUnix::ArchStringUnix()
|
||||
{
|
||||
}
|
||||
|
||||
@ -1,131 +0,0 @@
|
||||
/*
|
||||
* Deskflow -- mouse and keyboard sharing utility
|
||||
* SPDX-FileCopyrightText: (C) 2012 - 2016 Symless Ltd.
|
||||
* SPDX-FileCopyrightText: (C) 2002 Chris Schoeneman
|
||||
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
|
||||
*/
|
||||
|
||||
#include "arch/unix/ArchSystemUnix.h"
|
||||
#include <array>
|
||||
|
||||
#include <common/constants.h>
|
||||
#include <sys/utsname.h>
|
||||
|
||||
#ifndef __APPLE__
|
||||
#include <QDBusConnection>
|
||||
#include <QDBusError>
|
||||
#include <QDBusInterface>
|
||||
#include <QDBusReply>
|
||||
#endif
|
||||
|
||||
//
|
||||
// ArchSystemUnix
|
||||
//
|
||||
|
||||
ArchSystemUnix::ArchSystemUnix()
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
ArchSystemUnix::~ArchSystemUnix()
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
std::string ArchSystemUnix::getOSName() const
|
||||
{
|
||||
#if defined(HAVE_SYS_UTSNAME_H)
|
||||
struct utsname info;
|
||||
if (uname(&info) == 0) {
|
||||
std::string msg;
|
||||
msg += info.sysname;
|
||||
msg += " ";
|
||||
msg += info.release;
|
||||
return msg;
|
||||
}
|
||||
#endif
|
||||
return "Unix";
|
||||
}
|
||||
|
||||
std::string ArchSystemUnix::getPlatformName() const
|
||||
{
|
||||
#if defined(HAVE_SYS_UTSNAME_H)
|
||||
struct utsname info;
|
||||
if (uname(&info) == 0) {
|
||||
return std::string(info.machine);
|
||||
}
|
||||
#endif
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
std::string ArchSystemUnix::setting(const std::string &) const
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
void ArchSystemUnix::setting(const std::string &, const std::string &) const
|
||||
{
|
||||
}
|
||||
|
||||
void ArchSystemUnix::clearSettings() const
|
||||
{
|
||||
// Not implemented
|
||||
}
|
||||
|
||||
std::string ArchSystemUnix::getLibsUsed(void) const
|
||||
{
|
||||
return "not implemented.\nuse lsof on shell";
|
||||
}
|
||||
|
||||
#ifndef __APPLE__
|
||||
bool ArchSystemUnix::DBusInhibitScreenCall(InhibitScreenServices serviceID, bool state, std::string &error)
|
||||
{
|
||||
error = "";
|
||||
static const std::array<QString, 2> services = {"org.freedesktop.ScreenSaver", "org.gnome.SessionManager"};
|
||||
static const std::array<QString, 2> paths = {"/org/freedesktop/ScreenSaver", "/org/gnome/SessionManager"};
|
||||
static std::array<uint, 2> cookies;
|
||||
|
||||
auto serviceNum = static_cast<uint8_t>(serviceID);
|
||||
|
||||
QDBusConnection bus = QDBusConnection::sessionBus();
|
||||
if (!bus.isConnected()) {
|
||||
error = "bus failed to connect";
|
||||
return false;
|
||||
}
|
||||
|
||||
QDBusInterface screenSaverInterface(services[serviceNum], paths[serviceNum], services[serviceNum], bus);
|
||||
|
||||
if (!screenSaverInterface.isValid()) {
|
||||
error = "screen saver interface failed to initialize";
|
||||
return false;
|
||||
}
|
||||
|
||||
QDBusReply<uint> reply;
|
||||
if (state) {
|
||||
if (cookies[serviceNum]) {
|
||||
error = "coockies are not empty";
|
||||
return false;
|
||||
}
|
||||
|
||||
QString msg = "Sleep is manually prevented by the %1 preferences";
|
||||
reply = screenSaverInterface.call("Inhibit", kAppName, msg.arg(kAppName));
|
||||
if (reply.isValid())
|
||||
cookies[serviceNum] = reply.value();
|
||||
} else {
|
||||
if (!cookies[serviceNum]) {
|
||||
error = "coockies are empty";
|
||||
return false;
|
||||
}
|
||||
reply = screenSaverInterface.call("UnInhibit", cookies[serviceNum]);
|
||||
cookies[serviceNum] = 0;
|
||||
}
|
||||
|
||||
if (!reply.isValid()) {
|
||||
QDBusError qerror = reply.error();
|
||||
error = qerror.name().toStdString() + " : " + qerror.message().toStdString();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
@ -1,37 +0,0 @@
|
||||
/*
|
||||
* Deskflow -- mouse and keyboard sharing utility
|
||||
* SPDX-FileCopyrightText: (C) 2012 - 2016 Symless Ltd.
|
||||
* SPDX-FileCopyrightText: (C) 2002 Chris Schoeneman
|
||||
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "arch/IArchSystem.h"
|
||||
|
||||
#define ARCH_SYSTEM ArchSystemUnix
|
||||
|
||||
//! Unix implementation of IArchString
|
||||
class ArchSystemUnix : public IArchSystem
|
||||
{
|
||||
public:
|
||||
ArchSystemUnix();
|
||||
virtual ~ArchSystemUnix();
|
||||
|
||||
// IArchSystem overrides
|
||||
virtual std::string getOSName() const;
|
||||
virtual std::string getPlatformName() const;
|
||||
virtual std::string setting(const std::string &) const;
|
||||
virtual void setting(const std::string &, const std::string &) const;
|
||||
virtual std::string getLibsUsed(void) const;
|
||||
virtual void clearSettings() const;
|
||||
|
||||
#ifndef __APPLE__
|
||||
enum class InhibitScreenServices
|
||||
{
|
||||
kScreenSaver,
|
||||
kSessionManager
|
||||
};
|
||||
static bool DBusInhibitScreenCall(InhibitScreenServices serviceID, bool state, std::string &error);
|
||||
#endif
|
||||
};
|
||||
@ -16,7 +16,7 @@ public:
|
||||
XArchEvalUnix(int error) : m_error(error)
|
||||
{
|
||||
}
|
||||
virtual ~XArchEvalUnix() _NOEXCEPT
|
||||
virtual ~XArchEvalUnix() throw()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@ -350,6 +350,8 @@ void ArchDaemonWindows::setStatus(DWORD state, DWORD step, DWORD waitHint)
|
||||
{
|
||||
assert(s_daemon != NULL);
|
||||
|
||||
LOG_DEBUG("setting service status: state=%d, step=%d, waitHint=%d", state, step, waitHint);
|
||||
|
||||
SERVICE_STATUS status;
|
||||
status.dwServiceType = SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS;
|
||||
status.dwCurrentState = state;
|
||||
|
||||
@ -9,20 +9,22 @@
|
||||
|
||||
#include "arch/IArchDaemon.h"
|
||||
#include "arch/IArchMultithread.h"
|
||||
#include "common/constants.h"
|
||||
#include <string>
|
||||
#include "common/Constants.h"
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <Windows.h>
|
||||
#include <tchar.h>
|
||||
|
||||
#include <functional>
|
||||
#include <string>
|
||||
|
||||
#define ARCH_DAEMON ArchDaemonWindows
|
||||
|
||||
//! Win32 implementation of IArchDaemon
|
||||
class ArchDaemonWindows : public IArchDaemon
|
||||
{
|
||||
public:
|
||||
typedef int (*RunFunc)(void);
|
||||
using RunFunc = std::function<int()>;
|
||||
|
||||
ArchDaemonWindows();
|
||||
virtual ~ArchDaemonWindows();
|
||||
|
||||
@ -1,173 +0,0 @@
|
||||
/*
|
||||
* Deskflow -- mouse and keyboard sharing utility
|
||||
* SPDX-FileCopyrightText: (C) 2012 - 2016 Symless Ltd.
|
||||
* SPDX-FileCopyrightText: (C) 2002 Chris Schoeneman
|
||||
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
|
||||
*/
|
||||
|
||||
#include "arch/win32/ArchFileWindows.h"
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <Windows.h>
|
||||
#include <shlobj.h>
|
||||
#include <string.h>
|
||||
#include <tchar.h>
|
||||
|
||||
//
|
||||
// ArchFileWindows
|
||||
//
|
||||
|
||||
ArchFileWindows::ArchFileWindows()
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
ArchFileWindows::~ArchFileWindows()
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
const char *ArchFileWindows::getBasename(const char *pathname)
|
||||
{
|
||||
if (pathname == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// check for last slash
|
||||
const char *basename = strrchr(pathname, '/');
|
||||
if (basename != NULL) {
|
||||
++basename;
|
||||
} else {
|
||||
basename = pathname;
|
||||
}
|
||||
|
||||
// check for last backslash
|
||||
const char *basename2 = strrchr(pathname, '\\');
|
||||
if (basename2 != NULL && basename2 > basename) {
|
||||
basename = basename2 + 1;
|
||||
}
|
||||
|
||||
return basename;
|
||||
}
|
||||
|
||||
std::string ArchFileWindows::getUserDirectory()
|
||||
{
|
||||
// try %HOMEPATH%
|
||||
TCHAR dir[MAX_PATH];
|
||||
DWORD size = sizeof(dir) / sizeof(TCHAR);
|
||||
DWORD result = GetEnvironmentVariable(_T("HOMEPATH"), dir, size);
|
||||
if (result != 0 && result <= size) {
|
||||
// sanity check -- if dir doesn't appear to start with a
|
||||
// drive letter and isn't a UNC name then don't use it
|
||||
// FIXME -- allow UNC names
|
||||
if (dir[0] != '\0' && (dir[1] == ':' || ((dir[0] == '\\' || dir[0] == '/') && (dir[1] == '\\' || dir[1] == '/')))) {
|
||||
return dir;
|
||||
}
|
||||
}
|
||||
|
||||
// get the location of the personal files. that's as close to
|
||||
// a home directory as we're likely to find.
|
||||
ITEMIDLIST *idl;
|
||||
if (SUCCEEDED(SHGetSpecialFolderLocation(NULL, CSIDL_PERSONAL, &idl))) {
|
||||
TCHAR *path = NULL;
|
||||
if (SHGetPathFromIDList(idl, dir)) {
|
||||
DWORD attr = GetFileAttributes(dir);
|
||||
if (attr != 0xffffffff && (attr & FILE_ATTRIBUTE_DIRECTORY) != 0)
|
||||
path = dir;
|
||||
}
|
||||
|
||||
IMalloc *shalloc;
|
||||
if (SUCCEEDED(SHGetMalloc(&shalloc))) {
|
||||
shalloc->Free(idl);
|
||||
shalloc->Release();
|
||||
}
|
||||
|
||||
if (path != NULL) {
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
// use root of C drive as a default
|
||||
return "C:";
|
||||
}
|
||||
|
||||
std::string ArchFileWindows::getSystemDirectory()
|
||||
{
|
||||
// get windows directory
|
||||
char dir[MAX_PATH];
|
||||
if (GetWindowsDirectory(dir, sizeof(dir)) != 0) {
|
||||
return dir;
|
||||
} else {
|
||||
// can't get it. use C:\ as a default.
|
||||
return "C:";
|
||||
}
|
||||
}
|
||||
|
||||
std::string ArchFileWindows::getInstalledDirectory()
|
||||
{
|
||||
char fileNameBuffer[MAX_PATH];
|
||||
GetModuleFileName(NULL, fileNameBuffer, MAX_PATH);
|
||||
std::string fileName(fileNameBuffer);
|
||||
size_t lastSlash = fileName.find_last_of("\\");
|
||||
fileName = fileName.substr(0, lastSlash);
|
||||
|
||||
return fileName;
|
||||
}
|
||||
|
||||
std::string ArchFileWindows::getLogDirectory()
|
||||
{
|
||||
return getInstalledDirectory();
|
||||
}
|
||||
|
||||
std::string ArchFileWindows::getPluginDirectory()
|
||||
{
|
||||
if (!m_pluginDirectory.empty()) {
|
||||
return m_pluginDirectory;
|
||||
}
|
||||
|
||||
std::string dir = getProfileDirectory();
|
||||
dir.append("\\Plugins");
|
||||
return dir;
|
||||
}
|
||||
|
||||
std::string ArchFileWindows::getProfileDirectory()
|
||||
{
|
||||
std::string dir;
|
||||
if (!m_profileDirectory.empty()) {
|
||||
dir = m_profileDirectory;
|
||||
} else {
|
||||
TCHAR result[MAX_PATH];
|
||||
if (SUCCEEDED(SHGetFolderPath(NULL, CSIDL_LOCAL_APPDATA, NULL, 0, result))) {
|
||||
dir = result;
|
||||
} else {
|
||||
dir = getUserDirectory();
|
||||
}
|
||||
}
|
||||
|
||||
// HACK: append program name, this seems wrong.
|
||||
dir.append("\\Deskflow");
|
||||
|
||||
return dir;
|
||||
}
|
||||
|
||||
std::string ArchFileWindows::concatPath(const std::string &prefix, const std::string &suffix)
|
||||
{
|
||||
std::string path;
|
||||
path.reserve(prefix.size() + 1 + suffix.size());
|
||||
path += prefix;
|
||||
if (path.size() == 0 || (path[path.size() - 1] != '\\' && path[path.size() - 1] != '/')) {
|
||||
path += '\\';
|
||||
}
|
||||
path += suffix;
|
||||
return path;
|
||||
}
|
||||
|
||||
void ArchFileWindows::setProfileDirectory(const std::string &s)
|
||||
{
|
||||
m_profileDirectory = s;
|
||||
}
|
||||
|
||||
void ArchFileWindows::setPluginDirectory(const std::string &s)
|
||||
{
|
||||
m_pluginDirectory = s;
|
||||
}
|
||||
@ -1,36 +0,0 @@
|
||||
/*
|
||||
* Deskflow -- mouse and keyboard sharing utility
|
||||
* SPDX-FileCopyrightText: (C) 2012 - 2016 Symless Ltd.
|
||||
* SPDX-FileCopyrightText: (C) 2002 Chris Schoeneman
|
||||
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "arch/IArchFile.h"
|
||||
|
||||
#define ARCH_FILE ArchFileWindows
|
||||
|
||||
//! Win32 implementation of IArchFile
|
||||
class ArchFileWindows : public IArchFile
|
||||
{
|
||||
public:
|
||||
ArchFileWindows();
|
||||
virtual ~ArchFileWindows();
|
||||
|
||||
// IArchFile overrides
|
||||
virtual const char *getBasename(const char *pathname);
|
||||
virtual std::string getUserDirectory();
|
||||
virtual std::string getSystemDirectory();
|
||||
virtual std::string getInstalledDirectory();
|
||||
virtual std::string getLogDirectory();
|
||||
virtual std::string getPluginDirectory();
|
||||
virtual std::string getProfileDirectory();
|
||||
virtual std::string concatPath(const std::string &prefix, const std::string &suffix);
|
||||
virtual void setProfileDirectory(const std::string &s);
|
||||
virtual void setPluginDirectory(const std::string &s);
|
||||
|
||||
private:
|
||||
std::string m_profileDirectory;
|
||||
std::string m_pluginDirectory;
|
||||
};
|
||||
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Deskflow -- mouse and keyboard sharing utility
|
||||
* SPDX-FileCopyrightText: (C) 2012 - 2016 Symless Ltd.
|
||||
* SPDX-FileCopyrightText: (C) 2012 - 2016, 2024 - 2025 Symless Ltd.
|
||||
* SPDX-FileCopyrightText: (C) 2002 Chris Schoeneman
|
||||
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
|
||||
*/
|
||||
@ -12,95 +12,55 @@
|
||||
#include "base/Log.h"
|
||||
#include "base/String.h"
|
||||
|
||||
#include <Wtsapi32.h>
|
||||
#pragma warning(disable : 4099)
|
||||
#include <Userenv.h>
|
||||
#pragma warning(default : 4099)
|
||||
#include <Psapi.h>
|
||||
|
||||
#include <array>
|
||||
#include <filesystem>
|
||||
|
||||
// Welcome to DLL hell! :)
|
||||
//
|
||||
// Microsoft lets you run a program with an old runtime DLL, as long as the name matches.
|
||||
// Unfortunately if you compile on VS2022 and then use the VS2019 runtime, which both have the
|
||||
// same runtime DLL name, the app will randomly crash (e.g. access violation) or break in strange
|
||||
// and unpredictable ways due to ABI differences.
|
||||
//
|
||||
// In Windows, there is no concept of requiring a minimum version of the runtime DLL, so we have
|
||||
// to check the version ourselves.
|
||||
//
|
||||
// Our CI is set up to build with the latest compiler, so in this case we should insist on the
|
||||
// latest runtime DLL.
|
||||
//
|
||||
// As a developer convenience, we also allow builds on older compilers such as the minimum
|
||||
// requirements for the current Qt version we support.
|
||||
//
|
||||
// See table of the compiler versions and the matching runtime DLL versions:
|
||||
// https://dev.to/yumetodo/list-of-mscver-and-mscfullver-8nd
|
||||
#if _MSC_VER >= 1942 // Visual Studio 2022 Update 12 (v17.12.4)
|
||||
const auto kRequiredMajor = 14;
|
||||
const auto kRequiredMinor = 42;
|
||||
#elif _MSC_VER >= 1920 // Visual Studio 2019 Update 7 (v16.7)
|
||||
const auto kRequiredMajor = 14;
|
||||
const auto kRequiredMinor = 27;
|
||||
#else
|
||||
#pragma message("MSC version: " STRINGIFY(_MSC_VER))
|
||||
#error "Unsupported MSC version"
|
||||
#endif
|
||||
// Useful for debugging Windows specific bootstrapping code before the logging system is initialized.
|
||||
// This output can be viewed by attaching a Microsoft debugger or by using the DebugView program.
|
||||
#define MS_LOG_DEBUG(message, ...) \
|
||||
OutputDebugStringA((deskflow::string::sprintf((s_binaryName + ": " + message + "\n").c_str(), __VA_ARGS__)).c_str())
|
||||
|
||||
// parent process name for services in Vista
|
||||
#define SERVICE_LAUNCHER "services.exe"
|
||||
//
|
||||
// Free functions
|
||||
//
|
||||
|
||||
#ifndef ES_SYSTEM_REQUIRED
|
||||
#define ES_SYSTEM_REQUIRED ((DWORD)0x00000001)
|
||||
#endif
|
||||
#ifndef ES_DISPLAY_REQUIRED
|
||||
#define ES_DISPLAY_REQUIRED ((DWORD)0x00000002)
|
||||
#endif
|
||||
#ifndef ES_CONTINUOUS
|
||||
#define ES_CONTINUOUS ((DWORD)0x80000000)
|
||||
#endif
|
||||
using EXECUTION_STATE = DWORD;
|
||||
void errorMessageBox(const char *message, const char *title = "Fatal Error");
|
||||
|
||||
void errorMessageBox(const char *message, const char *title = "Fatal Error")
|
||||
std::string getBinaryName()
|
||||
{
|
||||
std::array<char, MAX_PATH> buffer;
|
||||
if (!GetModuleFileNameA(NULL, buffer.data(), MAX_PATH)) {
|
||||
errorMessageBox("Failed to get binary name.");
|
||||
abort();
|
||||
}
|
||||
|
||||
return std::filesystem::path(buffer.data()).filename().string();
|
||||
}
|
||||
|
||||
void errorMessageBox(const char *message, const char *title)
|
||||
{
|
||||
MessageBoxA(nullptr, message, title, MB_ICONERROR | MB_OK);
|
||||
}
|
||||
|
||||
// Used by bootstrap logging to differentiate between daemon and client/server messages.
|
||||
const std::string s_binaryName = getBinaryName();
|
||||
|
||||
//
|
||||
// ArchMiscWindows
|
||||
//
|
||||
|
||||
ArchMiscWindows::Dialogs *ArchMiscWindows::s_dialogs = NULL;
|
||||
DWORD ArchMiscWindows::s_busyState = 0;
|
||||
ArchMiscWindows::STES_t ArchMiscWindows::s_stes = NULL;
|
||||
HICON ArchMiscWindows::s_largeIcon = NULL;
|
||||
HICON ArchMiscWindows::s_smallIcon = NULL;
|
||||
HINSTANCE ArchMiscWindows::s_instanceWin32 = NULL;
|
||||
|
||||
void ArchMiscWindows::cleanup()
|
||||
{
|
||||
delete s_dialogs;
|
||||
}
|
||||
|
||||
void ArchMiscWindows::init()
|
||||
{
|
||||
// stop windows system error dialogs from showing.
|
||||
SetErrorMode(SEM_FAILCRITICALERRORS);
|
||||
|
||||
s_dialogs = new Dialogs;
|
||||
}
|
||||
|
||||
void ArchMiscWindows::setIcons(HICON largeIcon, HICON smallIcon)
|
||||
{
|
||||
s_largeIcon = largeIcon;
|
||||
s_smallIcon = smallIcon;
|
||||
}
|
||||
|
||||
void ArchMiscWindows::getIcons(HICON &largeIcon, HICON &smallIcon)
|
||||
{
|
||||
largeIcon = s_largeIcon;
|
||||
smallIcon = s_smallIcon;
|
||||
}
|
||||
|
||||
int ArchMiscWindows::runDaemon(RunFunc runFunc)
|
||||
@ -193,31 +153,6 @@ void ArchMiscWindows::deleteKey(HKEY key, const TCHAR *name)
|
||||
RegDeleteKey(key, name);
|
||||
}
|
||||
|
||||
void ArchMiscWindows::deleteValue(HKEY key, const TCHAR *name)
|
||||
{
|
||||
assert(key != NULL);
|
||||
assert(name != NULL);
|
||||
if (key == NULL || name == NULL)
|
||||
return;
|
||||
RegDeleteValue(key, name);
|
||||
}
|
||||
|
||||
void ArchMiscWindows::deleteKeyTree(HKEY key, const TCHAR *name)
|
||||
{
|
||||
assert(key != NULL);
|
||||
assert(name != NULL);
|
||||
if (key == NULL || name == NULL)
|
||||
return;
|
||||
RegDeleteTree(key, name);
|
||||
}
|
||||
|
||||
bool ArchMiscWindows::hasValue(HKEY key, const TCHAR *name)
|
||||
{
|
||||
DWORD type;
|
||||
LONG result = RegQueryValueEx(key, name, 0, &type, NULL, NULL);
|
||||
return (result == ERROR_SUCCESS && (type == REG_DWORD || type == REG_SZ));
|
||||
}
|
||||
|
||||
ArchMiscWindows::EValueType ArchMiscWindows::typeOfValue(HKEY key, const TCHAR *name)
|
||||
{
|
||||
DWORD type;
|
||||
@ -260,17 +195,6 @@ void ArchMiscWindows::setValue(HKEY key, const TCHAR *name, DWORD value)
|
||||
RegSetValueEx(key, name, 0, REG_DWORD, reinterpret_cast<CONST BYTE *>(&value), sizeof(DWORD));
|
||||
}
|
||||
|
||||
void ArchMiscWindows::setValueBinary(HKEY key, const TCHAR *name, const std::string &value)
|
||||
{
|
||||
assert(key != NULL);
|
||||
assert(name != NULL);
|
||||
if (key == NULL || name == NULL) {
|
||||
// TODO: throw exception
|
||||
return;
|
||||
}
|
||||
RegSetValueEx(key, name, 0, REG_BINARY, reinterpret_cast<const BYTE *>(value.data()), (DWORD)value.size());
|
||||
}
|
||||
|
||||
std::string ArchMiscWindows::readBinaryOrString(HKEY key, const TCHAR *name, DWORD type)
|
||||
{
|
||||
// get the size of the string
|
||||
@ -311,11 +235,6 @@ std::string ArchMiscWindows::readValueString(HKEY key, const TCHAR *name)
|
||||
return readBinaryOrString(key, name, REG_SZ);
|
||||
}
|
||||
|
||||
std::string ArchMiscWindows::readValueBinary(HKEY key, const TCHAR *name)
|
||||
{
|
||||
return readBinaryOrString(key, name, REG_BINARY);
|
||||
}
|
||||
|
||||
DWORD
|
||||
ArchMiscWindows::readValueInt(HKEY key, const TCHAR *name)
|
||||
{
|
||||
@ -329,26 +248,6 @@ ArchMiscWindows::readValueInt(HKEY key, const TCHAR *name)
|
||||
return value;
|
||||
}
|
||||
|
||||
void ArchMiscWindows::addDialog(HWND hwnd)
|
||||
{
|
||||
s_dialogs->insert(hwnd);
|
||||
}
|
||||
|
||||
void ArchMiscWindows::removeDialog(HWND hwnd)
|
||||
{
|
||||
s_dialogs->erase(hwnd);
|
||||
}
|
||||
|
||||
bool ArchMiscWindows::processDialog(MSG *msg)
|
||||
{
|
||||
for (Dialogs::const_iterator index = s_dialogs->begin(); index != s_dialogs->end(); ++index) {
|
||||
if (IsDialogMessage(*index, msg)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void ArchMiscWindows::addBusyState(DWORD busyModes)
|
||||
{
|
||||
s_busyState |= busyModes;
|
||||
@ -375,7 +274,7 @@ void ArchMiscWindows::setThreadExecutionState(DWORD busyModes)
|
||||
}
|
||||
|
||||
// convert to STES form
|
||||
EXECUTION_STATE state = 0;
|
||||
DWORD state = 0;
|
||||
if ((busyModes & kSYSTEM) != 0) {
|
||||
state |= ES_SYSTEM_REQUIRED;
|
||||
}
|
||||
@ -426,7 +325,7 @@ bool ArchMiscWindows::wasLaunchedAsService()
|
||||
return false;
|
||||
}
|
||||
|
||||
return (name == SERVICE_LAUNCHER);
|
||||
return (name == "services.exe");
|
||||
}
|
||||
|
||||
bool ArchMiscWindows::getParentProcessName(std::string &name)
|
||||
@ -521,40 +420,89 @@ std::string ArchMiscWindows::getActiveDesktopName()
|
||||
return name;
|
||||
}
|
||||
|
||||
void ArchMiscWindows::guardRuntimeVersion() // NOSONAR - `noreturn` is not available
|
||||
HMODULE ArchMiscWindows::findLoadedModule(std::array<const char *, 2> moduleNames)
|
||||
{
|
||||
const auto kRuntimeDll = "vcruntime140.dll";
|
||||
std::array<HMODULE, 1024> hModules;
|
||||
DWORD cbNeeded;
|
||||
|
||||
HMODULE hModule = nullptr;
|
||||
if (!GetModuleHandleEx(0, kRuntimeDll, &hModule) && hModule) {
|
||||
errorMessageBox("Microsoft Visual C++ Runtime is not installed.");
|
||||
HANDLE hProcess = GetCurrentProcess();
|
||||
if (!EnumProcessModules(hProcess, hModules.data(), sizeof(hModules), &cbNeeded)) {
|
||||
errorMessageBox("Failed to enumerate process modules.");
|
||||
abort();
|
||||
}
|
||||
|
||||
std::string loadedModuleName;
|
||||
for (size_t i = 0; i < (cbNeeded / sizeof(HMODULE)); ++i) {
|
||||
if (!GetModuleBaseNameA(hProcess, hModules[i], loadedModuleName.data(), sizeof(loadedModuleName))) {
|
||||
LOG_WARN("could not get base name of loaded module %d", i);
|
||||
continue;
|
||||
}
|
||||
|
||||
for (const auto &moduleName : moduleNames) {
|
||||
if (_stricmp(loadedModuleName.data(), moduleName) == 0) {
|
||||
return hModules[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Enforcing minimum MSVC runtime version is quite strict, but we have a good reason.
|
||||
//
|
||||
// Microsoft lets you run a program with an older version of the runtime DLL than the one it was
|
||||
// compiled with. This is because the runtime DLLs are supposedly ABI-compatible when the major
|
||||
// version is the same, so hypothetically MSVC runtime 14.0 is compatible with 14.42.
|
||||
// However, we have found subtle edge cases such as mutex lock causes access violation.
|
||||
//
|
||||
// Example of how Microsoft breaks ABI compatibility between minor runtime versions:
|
||||
// https://stackoverflow.com/questions/69990339/why-is-stdmutex-so-much-worse-than-stdshared-mutex-in-visual-c
|
||||
//
|
||||
// Our CI is set up to build with the latest compiler, so in this case we should insist on at least
|
||||
// the runtime DLL that was released at the same time as the compiler.
|
||||
//
|
||||
// As a developer convenience, we also allow builds on older compilers such as the minimum
|
||||
// requirements for the current Qt version we support.
|
||||
void ArchMiscWindows::guardRuntimeVersion() // NOSONAR - `noreturn` is not available
|
||||
{
|
||||
auto hModule = findLoadedModule({"vcruntime140.dll", "vcruntime140d.dll"});
|
||||
if (hModule == nullptr) {
|
||||
errorMessageBox("Failed to find MSVC runtime DLL.");
|
||||
abort();
|
||||
}
|
||||
|
||||
MS_LOG_DEBUG("found msvc runtime dll, handle: %p", hModule);
|
||||
|
||||
std::array<char, MAX_PATH> pathBuffer;
|
||||
const auto path = pathBuffer.data();
|
||||
if (!GetModuleFileNameA(hModule, path, MAX_PATH)) {
|
||||
errorMessageBox("Failed to get the path of Microsoft Visual C++ Runtime.");
|
||||
errorMessageBox("Failed to get path of MSVC runtime.");
|
||||
abort();
|
||||
}
|
||||
|
||||
MS_LOG_DEBUG("msvc runtime dll path: %s", path);
|
||||
|
||||
DWORD handle;
|
||||
DWORD size = GetFileVersionInfoSizeA(path, &handle);
|
||||
if (size <= 0) {
|
||||
errorMessageBox("Failed to get the version info size for Microsoft Visual C++ Runtime.");
|
||||
errorMessageBox("Failed to get version info size for MSVC runtime.");
|
||||
abort();
|
||||
}
|
||||
|
||||
MS_LOG_DEBUG("msvc runtime dll version info size: %d", size);
|
||||
|
||||
std::vector<BYTE> versionInfo(size);
|
||||
if (!GetFileVersionInfoA(path, handle, size, versionInfo.data())) {
|
||||
errorMessageBox("Failed to get the file version info for Microsoft Visual C++ Runtime.");
|
||||
errorMessageBox("Failed to get file version info for MSVC runtime.");
|
||||
abort();
|
||||
}
|
||||
|
||||
MS_LOG_DEBUG("msvc runtime dll version info ok, querying values");
|
||||
|
||||
VS_FIXEDFILEINFO *fileInfo = nullptr;
|
||||
const auto lplpFileInfo = reinterpret_cast<void **>(&fileInfo); // NOSONAR - Idiomatic Win32
|
||||
if (UINT len = 0; !VerQueryValueA(versionInfo.data(), "\\", lplpFileInfo, &len)) {
|
||||
errorMessageBox("Failed to get the version information for Microsoft Visual C++ Runtime.");
|
||||
errorMessageBox("Failed to query file version info for MSVC runtime.");
|
||||
abort();
|
||||
}
|
||||
|
||||
@ -562,14 +510,42 @@ void ArchMiscWindows::guardRuntimeVersion() // NOSONAR - `noreturn` is not avail
|
||||
const auto currentMinor = LOWORD(fileInfo->dwFileVersionMS);
|
||||
const auto currentBuild = HIWORD(fileInfo->dwFileVersionLS);
|
||||
|
||||
if (currentMajor < kRequiredMajor || currentMinor < kRequiredMinor) {
|
||||
MS_LOG_DEBUG("msvc runtime dll version: %d.%d.%d", currentMajor, currentMinor, currentBuild);
|
||||
|
||||
if (currentMajor < kWindowsRuntimeMajor || currentMinor < kWindowsRuntimeMinor) {
|
||||
const auto message = deskflow::string::sprintf(
|
||||
"Installed Microsoft Visual C++ Runtime v%d.%d.%d is outdated.\n\n"
|
||||
"Minimum required version: v%d.%d\n\n"
|
||||
"Please update to the latest Microsoft Visual C++ Redistributable.",
|
||||
currentMajor, currentMinor, currentBuild, kRequiredMajor, kRequiredMinor
|
||||
currentMajor, currentMinor, currentBuild, kWindowsRuntimeMajor, kWindowsRuntimeMinor
|
||||
);
|
||||
MessageBoxA(nullptr, message.c_str(), "Dependency Error", MB_ICONERROR | MB_OK);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
bool ArchMiscWindows::isProcessElevated()
|
||||
{
|
||||
LOG_DEBUG("checking if process is elevated");
|
||||
|
||||
HANDLE hToken = nullptr;
|
||||
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken)) {
|
||||
throw XArch(new XArchEvalWindows());
|
||||
}
|
||||
|
||||
TOKEN_ELEVATION elevation;
|
||||
|
||||
try {
|
||||
DWORD dwSize = sizeof(TOKEN_ELEVATION);
|
||||
if (!GetTokenInformation(hToken, TokenElevation, &elevation, sizeof(elevation), &dwSize)) {
|
||||
throw XArch(new XArchEvalWindows());
|
||||
}
|
||||
} catch (...) {
|
||||
CloseHandle(hToken);
|
||||
throw;
|
||||
}
|
||||
|
||||
const auto isElevated = elevation.TokenIsElevated;
|
||||
LOG_DEBUG("process is %s", isElevated ? "elevated" : "not elevated");
|
||||
return isElevated;
|
||||
}
|
||||
|
||||
@ -7,7 +7,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/stdset.h"
|
||||
#include <string>
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
@ -15,6 +14,8 @@
|
||||
|
||||
#include <Tlhelp32.h>
|
||||
|
||||
#include <functional>
|
||||
|
||||
//! Miscellaneous win32 functions.
|
||||
class ArchMiscWindows
|
||||
{
|
||||
@ -34,26 +35,11 @@ public:
|
||||
kDISPLAY = 0x0002
|
||||
};
|
||||
|
||||
typedef int (*RunFunc)(void);
|
||||
using RunFunc = std::function<int(void)>;
|
||||
|
||||
//! Initialize
|
||||
static void init();
|
||||
|
||||
//! Delete memory
|
||||
static void cleanup();
|
||||
|
||||
//! Set the application icons
|
||||
/*!
|
||||
Set the application icons.
|
||||
*/
|
||||
static void setIcons(HICON largeIcon, HICON smallIcon);
|
||||
|
||||
//! Get the application icons
|
||||
/*!
|
||||
Get the application icons.
|
||||
*/
|
||||
static void getIcons(HICON &largeIcon, HICON &smallIcon);
|
||||
|
||||
//! Run the daemon
|
||||
/*!
|
||||
Delegates to ArchDaemonWindows.
|
||||
@ -96,15 +82,6 @@ public:
|
||||
//! Delete a key (which should have no subkeys)
|
||||
static void deleteKey(HKEY parent, const TCHAR *name);
|
||||
|
||||
//! Delete a value
|
||||
static void deleteValue(HKEY parent, const TCHAR *name);
|
||||
|
||||
//! Delete a tree of keys from the registry
|
||||
static void deleteKeyTree(HKEY parent, const TCHAR *name);
|
||||
|
||||
//! Test if a value exists
|
||||
static bool hasValue(HKEY key, const TCHAR *name);
|
||||
|
||||
//! Get type of value
|
||||
static EValueType typeOfValue(HKEY key, const TCHAR *name);
|
||||
|
||||
@ -114,34 +91,12 @@ public:
|
||||
//! Set a DWORD value in the registry
|
||||
static void setValue(HKEY key, const TCHAR *name, DWORD value);
|
||||
|
||||
//! Set a BINARY value in the registry
|
||||
/*!
|
||||
Sets the \p name value of \p key to \p value.data().
|
||||
*/
|
||||
static void setValueBinary(HKEY key, const TCHAR *name, const std::string &value);
|
||||
|
||||
//! Read a string value from the registry
|
||||
static std::string readValueString(HKEY, const TCHAR *name);
|
||||
|
||||
//! Read a DWORD value from the registry
|
||||
static DWORD readValueInt(HKEY, const TCHAR *name);
|
||||
|
||||
//! Read a BINARY value from the registry
|
||||
static std::string readValueBinary(HKEY, const TCHAR *name);
|
||||
|
||||
//! Add a dialog
|
||||
static void addDialog(HWND);
|
||||
|
||||
//! Remove a dialog
|
||||
static void removeDialog(HWND);
|
||||
|
||||
//! Process dialog message
|
||||
/*!
|
||||
Checks if the message is destined for a dialog. If so the message
|
||||
is passed to the dialog and returns true, otherwise returns false.
|
||||
*/
|
||||
static bool processDialog(MSG *);
|
||||
|
||||
//! Disable power saving
|
||||
static void addBusyState(DWORD busyModes);
|
||||
|
||||
@ -160,13 +115,21 @@ public:
|
||||
//! Prevent hard to troubleshoot errors, e.g. access violations.
|
||||
static void guardRuntimeVersion();
|
||||
|
||||
//! Gets the window instance saved at program start.
|
||||
/*!
|
||||
e.g. Used by `GetModuleFileName` which is used when installing the daemon.
|
||||
*/
|
||||
static HINSTANCE instanceWin32();
|
||||
|
||||
//! Saves the window instance for later use.
|
||||
static void setInstanceWin32(HINSTANCE instance);
|
||||
static BOOL WINAPI getProcessEntry(PROCESSENTRY32 &entry, DWORD processID);
|
||||
static BOOL WINAPI getSelfProcessEntry(PROCESSENTRY32 &entry);
|
||||
static BOOL WINAPI getParentProcessEntry(PROCESSENTRY32 &entry);
|
||||
|
||||
//! Get the name of the active input desktop.
|
||||
static std::string getActiveDesktopName();
|
||||
|
||||
//! Returns true if the process is running with elevated privileges (i.e. as admin).
|
||||
static bool isProcessElevated();
|
||||
|
||||
private:
|
||||
//! Open and return a registry key, closing the parent key
|
||||
static HKEY openKey(HKEY parent, const TCHAR *child, bool create);
|
||||
@ -180,15 +143,29 @@ private:
|
||||
//! Set thread busy state
|
||||
static void setThreadExecutionState(DWORD);
|
||||
|
||||
//! Dummy function for thread execution state
|
||||
static DWORD WINAPI dummySetThreadExecutionState(DWORD);
|
||||
|
||||
//! Iterates over the process snapshot to find a process entry
|
||||
static BOOL WINAPI getProcessEntry(PROCESSENTRY32 &entry, DWORD processID);
|
||||
|
||||
//! Calls `getProcessEntry` with the current process ID
|
||||
static BOOL WINAPI getSelfProcessEntry(PROCESSENTRY32 &entry);
|
||||
|
||||
//! Calls `getProcessEntry` with the parent process ID
|
||||
static BOOL WINAPI getParentProcessEntry(PROCESSENTRY32 &entry);
|
||||
|
||||
//! Searches the loaded modules and returns the matching module handle
|
||||
/**
|
||||
* @param moduleNames Provide two module names to search for both release and debug versions.
|
||||
*/
|
||||
static HMODULE findLoadedModule(std::array<const char *, 2> moduleNames);
|
||||
|
||||
private:
|
||||
using Dialogs = std::set<HWND>;
|
||||
typedef DWORD(WINAPI *STES_t)(DWORD);
|
||||
|
||||
static Dialogs *s_dialogs;
|
||||
static DWORD s_busyState;
|
||||
static STES_t s_stes;
|
||||
static STES_t s_stes; // STES: Set thread execution state
|
||||
static HICON s_largeIcon;
|
||||
static HICON s_smallIcon;
|
||||
static HINSTANCE s_instanceWin32;
|
||||
|
||||
@ -8,7 +8,8 @@
|
||||
#pragma once
|
||||
|
||||
#include "arch/IArchMultithread.h"
|
||||
#include "common/stdlist.h"
|
||||
|
||||
#include <list>
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <Windows.h>
|
||||
|
||||
@ -1,111 +0,0 @@
|
||||
/*
|
||||
* Deskflow -- mouse and keyboard sharing utility
|
||||
* SPDX-FileCopyrightText: (C) 2012 - 2016 Symless Ltd.
|
||||
* SPDX-FileCopyrightText: (C) 2004 Chris Schoeneman
|
||||
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
|
||||
*/
|
||||
|
||||
#include "arch/win32/ArchSystemWindows.h"
|
||||
#include "arch/win32/ArchMiscWindows.h"
|
||||
|
||||
#include "arch/XArch.h"
|
||||
#include "base/Log.h"
|
||||
#include "common/constants.h"
|
||||
|
||||
#include "tchar.h"
|
||||
#include <string>
|
||||
|
||||
#include <psapi.h>
|
||||
#include <windows.h>
|
||||
|
||||
static const TCHAR *s_settingsKeyNames[] = {_T("SOFTWARE"), _T(kAppName), NULL};
|
||||
|
||||
//
|
||||
// ArchSystemWindows
|
||||
//
|
||||
|
||||
ArchSystemWindows::ArchSystemWindows()
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
ArchSystemWindows::~ArchSystemWindows()
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
std::string ArchSystemWindows::getOSName() const
|
||||
{
|
||||
std::string osName("Microsoft Windows <unknown>");
|
||||
static const TCHAR *const windowsVersionKeyNames[] = {
|
||||
_T("SOFTWARE"), _T("Microsoft"), _T("Windows NT"), _T("CurrentVersion"), NULL
|
||||
};
|
||||
|
||||
HKEY key = ArchMiscWindows::openKey(HKEY_LOCAL_MACHINE, windowsVersionKeyNames);
|
||||
if (key == NULL) {
|
||||
return osName;
|
||||
}
|
||||
|
||||
std::string productName = ArchMiscWindows::readValueString(key, "ProductName");
|
||||
if (osName.empty()) {
|
||||
return osName;
|
||||
}
|
||||
|
||||
return "Microsoft " + productName;
|
||||
}
|
||||
|
||||
std::string ArchSystemWindows::getPlatformName() const
|
||||
{
|
||||
#ifdef _X86_
|
||||
if (isWOW64())
|
||||
return "x86 (WOW64)";
|
||||
else
|
||||
return "x86";
|
||||
#else
|
||||
#ifdef _AMD64_
|
||||
return "x64";
|
||||
#else
|
||||
return "Unknown";
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string ArchSystemWindows::setting(const std::string &valueName) const
|
||||
{
|
||||
HKEY key = ArchMiscWindows::openKey(HKEY_LOCAL_MACHINE, s_settingsKeyNames);
|
||||
if (key == NULL)
|
||||
return "";
|
||||
|
||||
return ArchMiscWindows::readValueString(key, valueName.c_str());
|
||||
}
|
||||
|
||||
void ArchSystemWindows::setting(const std::string &valueName, const std::string &valueString) const
|
||||
{
|
||||
HKEY key = ArchMiscWindows::addKey(HKEY_LOCAL_MACHINE, s_settingsKeyNames);
|
||||
if (key == NULL)
|
||||
throw XArch(std::string("could not access registry key: ") + valueName);
|
||||
ArchMiscWindows::setValue(key, valueName.c_str(), valueString.c_str());
|
||||
}
|
||||
|
||||
void ArchSystemWindows::clearSettings() const
|
||||
{
|
||||
ArchMiscWindows::deleteKeyTree(HKEY_LOCAL_MACHINE, kWindowsRegistryKey);
|
||||
}
|
||||
|
||||
bool ArchSystemWindows::isWOW64() const
|
||||
{
|
||||
#if WINVER >= _WIN32_WINNT_WINXP
|
||||
typedef BOOL(WINAPI * LPFN_ISWOW64PROCESS)(HANDLE, PBOOL);
|
||||
HMODULE hModule = GetModuleHandle(TEXT("kernel32"));
|
||||
if (!hModule)
|
||||
return FALSE;
|
||||
|
||||
LPFN_ISWOW64PROCESS fnIsWow64Process = (LPFN_ISWOW64PROCESS)GetProcAddress(hModule, "IsWow64Process");
|
||||
|
||||
BOOL bIsWow64 = FALSE;
|
||||
if (NULL != fnIsWow64Process && fnIsWow64Process(GetCurrentProcess(), &bIsWow64) && bIsWow64) {
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
@ -1,29 +0,0 @@
|
||||
/*
|
||||
* Deskflow -- mouse and keyboard sharing utility
|
||||
* SPDX-FileCopyrightText: (C) 2012 - 2016 Symless Ltd.
|
||||
* SPDX-FileCopyrightText: (C) 2004 Chris Schoeneman
|
||||
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "arch/IArchSystem.h"
|
||||
|
||||
#define ARCH_SYSTEM ArchSystemWindows
|
||||
|
||||
//! Win32 implementation of IArchString
|
||||
class ArchSystemWindows : public IArchSystem
|
||||
{
|
||||
public:
|
||||
ArchSystemWindows();
|
||||
virtual ~ArchSystemWindows();
|
||||
|
||||
// IArchSystem overrides
|
||||
virtual std::string getOSName() const;
|
||||
virtual std::string getPlatformName() const;
|
||||
virtual std::string setting(const std::string &valueName) const;
|
||||
virtual void setting(const std::string &valueName, const std::string &valueString) const;
|
||||
virtual void clearSettings() const;
|
||||
|
||||
bool isWOW64() const;
|
||||
};
|
||||
@ -41,92 +41,166 @@ std::string XArchEvalWinsock::eval() const throw()
|
||||
{
|
||||
int m_code;
|
||||
const char *m_msg;
|
||||
} s_netErrorCodes[] = {
|
||||
/* 10004 */ {WSAEINTR, "The (blocking) call was canceled via WSACancelBlockingCall"},
|
||||
/* 10009 */ {WSAEBADF, "Bad file handle"},
|
||||
/* 10013 */
|
||||
{WSAEACCES, "The requested address is a broadcast address, but the "
|
||||
"appropriate flag was not set"},
|
||||
/* 10014 */ {WSAEFAULT, "WSAEFAULT"},
|
||||
/* 10022 */ {WSAEINVAL, "WSAEINVAL"},
|
||||
/* 10024 */ {WSAEMFILE, "No more file descriptors available"},
|
||||
/* 10035 */
|
||||
{WSAEWOULDBLOCK, "Socket is marked as non-blocking and no connections "
|
||||
"are present or the receive operation would block"},
|
||||
/* 10036 */
|
||||
}
|
||||
|
||||
s_netErrorCodes[] = {
|
||||
|
||||
// 10004
|
||||
{WSAEINTR, "The (blocking) call was canceled via WSACancelBlockingCall"},
|
||||
|
||||
// 10009
|
||||
{WSAEBADF, "Bad file handle"},
|
||||
|
||||
// 10013
|
||||
{WSAEACCES, "The requested address is a broadcast address, but the appropriate flag was not set"},
|
||||
|
||||
// 10014
|
||||
{WSAEFAULT, "WSAEFAULT"},
|
||||
|
||||
// 10022
|
||||
{WSAEINVAL, "WSAEINVAL"},
|
||||
|
||||
// 10024
|
||||
{WSAEMFILE, "No more file descriptors available"},
|
||||
|
||||
// 10035
|
||||
{WSAEWOULDBLOCK,
|
||||
"Socket is marked as non-blocking and no connections are present or the receive operation would block"},
|
||||
|
||||
// 10036
|
||||
{WSAEINPROGRESS, "A blocking Windows Sockets operation is in progress"},
|
||||
/* 10037 */
|
||||
|
||||
// 10037
|
||||
{WSAEALREADY, "The asynchronous routine being canceled has already completed"},
|
||||
/* 10038 */ {WSAENOTSOCK, "At least on descriptor is not a socket"},
|
||||
/* 10039 */ {WSAEDESTADDRREQ, "A destination address is required"},
|
||||
/* 10040 */
|
||||
{WSAEMSGSIZE, "The datagram was too large to fit into the specified "
|
||||
"buffer and was truncated"},
|
||||
/* 10041 */
|
||||
|
||||
// 10038
|
||||
{WSAENOTSOCK, "At least on descriptor is not a socket"},
|
||||
|
||||
// 10039
|
||||
{WSAEDESTADDRREQ, "A destination address is required"},
|
||||
|
||||
// 10040
|
||||
{WSAEMSGSIZE, "The datagram was too large to fit into the specified buffer and was truncated"},
|
||||
|
||||
// 10041
|
||||
{WSAEPROTOTYPE, "The specified protocol is the wrong type for this socket"},
|
||||
/* 10042 */ {WSAENOPROTOOPT, "The option is unknown or unsupported"},
|
||||
/* 10043 */
|
||||
|
||||
// 10042
|
||||
{WSAENOPROTOOPT, "The option is unknown or unsupported"},
|
||||
|
||||
// 10043
|
||||
{WSAEPROTONOSUPPORT, "The specified protocol is not supported"},
|
||||
/* 10044 */
|
||||
|
||||
// 10044
|
||||
{WSAESOCKTNOSUPPORT, "The specified socket type is not supported by this address family"},
|
||||
/* 10045 */
|
||||
|
||||
// 10045
|
||||
{WSAEOPNOTSUPP, "The referenced socket is not a type that supports that operation"},
|
||||
/* 10046 */ {WSAEPFNOSUPPORT, "BSD: Protocol family not supported"},
|
||||
/* 10047 */
|
||||
|
||||
// 10046
|
||||
{WSAEPFNOSUPPORT, "BSD: Protocol family not supported"},
|
||||
|
||||
// 10047
|
||||
{WSAEAFNOSUPPORT, "The specified address family is not supported"},
|
||||
/* 10048 */ {WSAEADDRINUSE, "The specified address is already in use"},
|
||||
/* 10049 */
|
||||
|
||||
// 10048
|
||||
{WSAEADDRINUSE, "The specified address is already in use"},
|
||||
|
||||
// 10049
|
||||
{WSAEADDRNOTAVAIL, "The specified address is not available from the local machine"},
|
||||
/* 10050 */
|
||||
{WSAENETDOWN, "The Windows Sockets implementation has detected that the "
|
||||
"network subsystem has failed"},
|
||||
/* 10051 */
|
||||
|
||||
// 10050
|
||||
{WSAENETDOWN, "The Windows Sockets implementation has detected that the network subsystem has failed"},
|
||||
|
||||
// 10051
|
||||
{WSAENETUNREACH, "The network can't be reached from this host at this time"},
|
||||
/* 10052 */
|
||||
{WSAENETRESET, "The connection must be reset because the Windows Sockets "
|
||||
"implementation dropped it"},
|
||||
/* 10053 */
|
||||
|
||||
// 10052
|
||||
{WSAENETRESET, "The connection must be reset because the Windows Sockets implementation dropped it"},
|
||||
|
||||
// 10053
|
||||
{WSAECONNABORTED, "The virtual circuit was aborted due to timeout or other failure"},
|
||||
/* 10054 */
|
||||
|
||||
// 10054
|
||||
{WSAECONNRESET, "The virtual circuit was reset by the remote side"},
|
||||
/* 10055 */
|
||||
{WSAENOBUFS, "No buffer space is available or a buffer deadlock has "
|
||||
"occured. The socket cannot be created"},
|
||||
/* 10056 */ {WSAEISCONN, "The socket is already connected"},
|
||||
/* 10057 */ {WSAENOTCONN, "The socket is not connected"},
|
||||
/* 10058 */ {WSAESHUTDOWN, "The socket has been shutdown"},
|
||||
/* 10059 */ {WSAETOOMANYREFS, "BSD: Too many references"},
|
||||
/* 10060 */
|
||||
|
||||
// 10055
|
||||
{WSAENOBUFS, "No buffer space is available or a buffer deadlock has occurred. The socket cannot be created"},
|
||||
|
||||
// 10056
|
||||
{WSAEISCONN, "The socket is already connected"},
|
||||
|
||||
// 10057
|
||||
{WSAENOTCONN, "The socket is not connected"},
|
||||
|
||||
// 10058
|
||||
{WSAESHUTDOWN, "The socket has been shutdown"},
|
||||
|
||||
// 10059
|
||||
{WSAETOOMANYREFS, "BSD: Too many references"},
|
||||
|
||||
// 10060
|
||||
{WSAETIMEDOUT, "Attempt to connect timed out without establishing a connection"},
|
||||
/* 10061 */ {WSAECONNREFUSED, "Connection was refused"},
|
||||
/* 10062 */ {WSAELOOP, "Undocumented WinSock error code used in BSD"},
|
||||
/* 10063 */
|
||||
|
||||
// 10061
|
||||
{WSAECONNREFUSED, "Connection was refused"},
|
||||
|
||||
// 10062
|
||||
{WSAELOOP, "Undocumented WinSock error code used in BSD"},
|
||||
|
||||
// 10063
|
||||
{WSAENAMETOOLONG, "Undocumented WinSock error code used in BSD"},
|
||||
/* 10064 */ {WSAEHOSTDOWN, "Undocumented WinSock error code used in BSD"},
|
||||
/* 10065 */ {WSAEHOSTUNREACH, "No route to host"},
|
||||
/* 10066 */ {WSAENOTEMPTY, "Undocumented WinSock error code"},
|
||||
/* 10067 */ {WSAEPROCLIM, "Undocumented WinSock error code"},
|
||||
/* 10068 */ {WSAEUSERS, "Undocumented WinSock error code"},
|
||||
/* 10069 */ {WSAEDQUOT, "Undocumented WinSock error code"},
|
||||
/* 10070 */ {WSAESTALE, "Undocumented WinSock error code"},
|
||||
/* 10071 */ {WSAEREMOTE, "Undocumented WinSock error code"},
|
||||
/* 10091 */
|
||||
|
||||
// 10064
|
||||
{WSAEHOSTDOWN, "Undocumented WinSock error code used in BSD"},
|
||||
|
||||
// 10065
|
||||
{WSAEHOSTUNREACH, "No route to host"},
|
||||
|
||||
// 10066
|
||||
{WSAENOTEMPTY, "Undocumented WinSock error code"},
|
||||
|
||||
// 10067
|
||||
{WSAEPROCLIM, "Undocumented WinSock error code"},
|
||||
|
||||
// 10068
|
||||
{WSAEUSERS, "Undocumented WinSock error code"},
|
||||
|
||||
// 10069
|
||||
{WSAEDQUOT, "Undocumented WinSock error code"},
|
||||
|
||||
// 10070
|
||||
{WSAESTALE, "Undocumented WinSock error code"},
|
||||
|
||||
// 10071
|
||||
{WSAEREMOTE, "Undocumented WinSock error code"},
|
||||
|
||||
// 10091
|
||||
{WSASYSNOTREADY, "Underlying network subsytem is not ready for network communication"},
|
||||
/* 10092 */
|
||||
{WSAVERNOTSUPPORTED, "The version of WinSock API support requested is "
|
||||
"not provided in this implementation"},
|
||||
/* 10093 */
|
||||
|
||||
// 10092
|
||||
{WSAVERNOTSUPPORTED, "The version of WinSock API support requested is not provided in this implementation"},
|
||||
|
||||
// 10093
|
||||
{WSANOTINITIALISED, "WinSock subsystem not properly initialized"},
|
||||
/* 10101 */
|
||||
|
||||
// 10101
|
||||
{WSAEDISCON, "Virtual circuit has gracefully terminated connection"},
|
||||
/* 11001 */ {WSAHOST_NOT_FOUND, "The specified host is unknown"},
|
||||
/* 11002 */
|
||||
|
||||
// 11001
|
||||
{WSAHOST_NOT_FOUND, "The specified host is unknown"},
|
||||
|
||||
// 11002
|
||||
{WSATRY_AGAIN, "A temporary error occurred on an authoritative name server"},
|
||||
/* 11003 */
|
||||
|
||||
// 11003
|
||||
{WSANO_RECOVERY, "A non-recoverable name server error occurred"},
|
||||
/* 11004 */
|
||||
|
||||
// 11004
|
||||
{WSANO_DATA, "The requested name is valid but does not have an IP address"},
|
||||
/* end */ {0, NULL}
|
||||
|
||||
// end
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
for (unsigned int i = 0; s_netErrorCodes[i].m_code != 0; ++i) {
|
||||
|
||||
@ -11,7 +11,7 @@ add_library(base STATIC
|
||||
EventQueue.h
|
||||
EventTypes.cpp
|
||||
EventTypes.h
|
||||
finally.h
|
||||
FinalAction.h
|
||||
FunctionEventJob.cpp
|
||||
FunctionEventJob.h
|
||||
FunctionJob.cpp
|
||||
@ -21,8 +21,8 @@ add_library(base STATIC
|
||||
IEventQueueBuffer.h
|
||||
IJob.h
|
||||
ILogOutputter.h
|
||||
log_outputters.cpp
|
||||
log_outputters.h
|
||||
LogOutputters.cpp
|
||||
LogOutputters.h
|
||||
Log.cpp
|
||||
Log.h
|
||||
Path.cpp
|
||||
|
||||
@ -7,8 +7,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/common.h"
|
||||
#include "common/stdmap.h"
|
||||
#include "common/Common.h"
|
||||
|
||||
class EventData
|
||||
{
|
||||
|
||||
@ -11,7 +11,6 @@
|
||||
#include "base/IEventJob.h"
|
||||
#include "base/Log.h"
|
||||
#include "base/SimpleEventQueueBuffer.h"
|
||||
#include "base/Stopwatch.h"
|
||||
#include "mt/Lock.h"
|
||||
#include "mt/Mutex.h"
|
||||
|
||||
|
||||
@ -7,17 +7,15 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "arch/IArchMultithread.h"
|
||||
#include "base/Event.h"
|
||||
#include "base/EventTypes.h"
|
||||
#include "base/IEventQueue.h"
|
||||
#include "base/PriorityQueue.h"
|
||||
#include "base/Stopwatch.h"
|
||||
#include "common/stdmap.h"
|
||||
#include "common/stdset.h"
|
||||
#include "mt/CondVar.h"
|
||||
|
||||
#include <map>
|
||||
#include <queue>
|
||||
#include <set>
|
||||
|
||||
class Mutex;
|
||||
|
||||
|
||||
@ -8,7 +8,6 @@
|
||||
#include "base/IEventQueue.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stddef.h>
|
||||
|
||||
EventTypes::EventTypes() : m_events(NULL)
|
||||
{
|
||||
@ -160,7 +159,7 @@ REGISTER_EVENT(Clipboard, clipboardSending)
|
||||
//
|
||||
|
||||
REGISTER_EVENT(File, fileChunkSending)
|
||||
REGISTER_EVENT(File, fileRecieveCompleted)
|
||||
REGISTER_EVENT(File, fileReceiveCompleted)
|
||||
REGISTER_EVENT(File, keepAlive)
|
||||
|
||||
//
|
||||
|
||||
@ -673,7 +673,7 @@ class FileEvents : public EventTypes
|
||||
public:
|
||||
FileEvents()
|
||||
: m_fileChunkSending(Event::kUnknown),
|
||||
m_fileRecieveCompleted(Event::kUnknown),
|
||||
m_fileReceiveCompleted(Event::kUnknown),
|
||||
m_keepAlive(Event::kUnknown)
|
||||
{
|
||||
}
|
||||
@ -685,7 +685,7 @@ public:
|
||||
Event::Type fileChunkSending();
|
||||
|
||||
//! Completed receiving a file
|
||||
Event::Type fileRecieveCompleted();
|
||||
Event::Type fileReceiveCompleted();
|
||||
|
||||
//! Send a keep alive
|
||||
Event::Type keepAlive();
|
||||
@ -694,7 +694,7 @@ public:
|
||||
|
||||
private:
|
||||
Event::Type m_fileChunkSending;
|
||||
Event::Type m_fileRecieveCompleted;
|
||||
Event::Type m_fileReceiveCompleted;
|
||||
Event::Type m_keepAlive;
|
||||
};
|
||||
|
||||
|
||||
@ -7,8 +7,6 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <utility>
|
||||
|
||||
namespace deskflow {
|
||||
|
||||
/**
|
||||
@ -7,8 +7,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/Common.h"
|
||||
#include "common/IInterface.h"
|
||||
#include "common/common.h"
|
||||
|
||||
class Event;
|
||||
class EventQueueTimer;
|
||||
|
||||
@ -7,8 +7,8 @@
|
||||
|
||||
#include "base/Log.h"
|
||||
#include "arch/Arch.h"
|
||||
#include "base/log_outputters.h"
|
||||
#include "common/constants.h"
|
||||
#include "base/LogOutputters.h"
|
||||
#include "common/Constants.h"
|
||||
|
||||
#include <cstdarg>
|
||||
#include <cstdint>
|
||||
|
||||
@ -9,10 +9,7 @@
|
||||
|
||||
#include "arch/Arch.h"
|
||||
#include "arch/IArchMultithread.h"
|
||||
#include "common/common.h"
|
||||
#include "common/stdlist.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include "common/Common.h"
|
||||
|
||||
#define CLOG (Log::getInstance())
|
||||
#define BYE "\nTry `%s --help' for more information."
|
||||
|
||||
@ -6,11 +6,10 @@
|
||||
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
|
||||
*/
|
||||
|
||||
#include "base/log_outputters.h"
|
||||
#include "base/LogOutputters.h"
|
||||
#include "arch/Arch.h"
|
||||
#include "base/Path.h"
|
||||
#include "base/String.h"
|
||||
#include "base/TMethodJob.h"
|
||||
|
||||
#include <fstream>
|
||||
|
||||
@ -9,14 +9,9 @@
|
||||
#pragma once
|
||||
|
||||
#include "base/ILogOutputter.h"
|
||||
#include "common/common.h"
|
||||
#include "common/stddeque.h"
|
||||
#include "common/Common.h"
|
||||
#include "mt/Thread.h"
|
||||
|
||||
#include <fstream>
|
||||
#include <list>
|
||||
#include <string>
|
||||
|
||||
//! Stop traversing log chain outputter
|
||||
/*!
|
||||
This outputter performs no output and returns false from \c write(),
|
||||
@ -6,7 +6,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <common/common.h>
|
||||
#include "common/Common.h"
|
||||
#include <string>
|
||||
|
||||
namespace deskflow {
|
||||
|
||||
@ -7,10 +7,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/stdvector.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
|
||||
//! A priority queue with an iterator
|
||||
/*!
|
||||
|
||||
@ -9,8 +9,8 @@
|
||||
|
||||
#include "arch/IArchMultithread.h"
|
||||
#include "base/IEventQueueBuffer.h"
|
||||
#include "common/stddeque.h"
|
||||
|
||||
#include <deque>
|
||||
//! In-memory event queue buffer
|
||||
/*!
|
||||
An event queue buffer provides a queue of events for an IEventQueue.
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/common.h"
|
||||
#include "common/Common.h"
|
||||
|
||||
//! A timer class
|
||||
/*!
|
||||
|
||||
@ -7,20 +7,11 @@
|
||||
*/
|
||||
|
||||
#include "base/String.h"
|
||||
#include "common/stdvector.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
#include <cerrno>
|
||||
#include <cstdarg>
|
||||
#include <cstdint>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
#include <stdio.h>
|
||||
#include <string>
|
||||
|
||||
namespace deskflow {
|
||||
namespace string {
|
||||
@ -147,26 +138,6 @@ std::string sprintf(const char *fmt, ...)
|
||||
return result;
|
||||
}
|
||||
|
||||
void findReplaceAll(std::string &subject, const std::string &find, const std::string &replace)
|
||||
{
|
||||
size_t pos = 0;
|
||||
while ((pos = subject.find(find, pos)) != std::string::npos) {
|
||||
subject.replace(pos, find.length(), replace);
|
||||
pos += replace.length();
|
||||
}
|
||||
}
|
||||
|
||||
std::string removeFileExt(std::string filename)
|
||||
{
|
||||
size_t dot = filename.find_last_of('.');
|
||||
|
||||
if (dot == std::string::npos) {
|
||||
return filename;
|
||||
}
|
||||
|
||||
return filename.substr(0, dot);
|
||||
}
|
||||
|
||||
std::string toHex(const std::string &subject, int width, const char fill)
|
||||
{
|
||||
std::stringstream ss;
|
||||
@ -253,11 +224,6 @@ void uppercase(std::string &subject)
|
||||
std::transform(subject.begin(), subject.end(), subject.begin(), ::toupper);
|
||||
}
|
||||
|
||||
void removeChar(std::string &subject, const char c)
|
||||
{
|
||||
subject.erase(std::remove(subject.begin(), subject.end(), c), subject.end());
|
||||
}
|
||||
|
||||
std::string sizeTypeToString(size_t n)
|
||||
{
|
||||
std::stringstream ss;
|
||||
@ -273,27 +239,6 @@ size_t stringToSizeType(std::string string)
|
||||
return value;
|
||||
}
|
||||
|
||||
std::vector<std::string> splitString(std::string string, const char c)
|
||||
{
|
||||
std::vector<std::string> results;
|
||||
|
||||
size_t head = 0;
|
||||
size_t separator = string.find(c);
|
||||
while (separator != std::string::npos) {
|
||||
if (head != separator) {
|
||||
results.push_back(string.substr(head, separator - head));
|
||||
}
|
||||
head = separator + 1;
|
||||
separator = string.find(c, head);
|
||||
}
|
||||
|
||||
if (head < string.size()) {
|
||||
results.push_back(string.substr(head, string.size() - head));
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
//
|
||||
// CaselessCmp
|
||||
//
|
||||
@ -319,11 +264,5 @@ bool CaselessCmp::cmpLess(const std::string::value_type &a, const std::string::v
|
||||
return tolower(a) < tolower(b);
|
||||
}
|
||||
|
||||
bool CaselessCmp::cmpEqual(const std::string::value_type &a, const std::string::value_type &b)
|
||||
{
|
||||
// should use std::tolower but not in all versions of libstdc++ have it
|
||||
return tolower(a) == tolower(b);
|
||||
}
|
||||
|
||||
} // namespace string
|
||||
} // namespace deskflow
|
||||
|
||||
@ -8,10 +8,9 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/common.h"
|
||||
#include <string>
|
||||
#include "common/Common.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace deskflow {
|
||||
@ -46,18 +45,6 @@ Equivalent to sprintf() except the result is returned as a String.
|
||||
*/
|
||||
std::string sprintf(const char *fmt, ...);
|
||||
|
||||
//! Find and replace all
|
||||
/*!
|
||||
Finds \c find inside \c subject and replaces it with \c replace
|
||||
*/
|
||||
void findReplaceAll(std::string &subject, const std::string &find, const std::string &replace);
|
||||
|
||||
//! Remove file extension
|
||||
/*!
|
||||
Finds the last dot and remove all characters from the dot to the end
|
||||
*/
|
||||
std::string removeFileExt(std::string filename);
|
||||
|
||||
//! Convert into hexdecimal
|
||||
/*!
|
||||
Convert each character in \c subject into hexdecimal form with \c width
|
||||
@ -94,12 +81,6 @@ Convert each character in \c subject to uppercase
|
||||
*/
|
||||
void uppercase(std::string &subject);
|
||||
|
||||
//! Remove all specific char in suject
|
||||
/*!
|
||||
Remove all specific \c c in \c suject
|
||||
*/
|
||||
void removeChar(std::string &subject, const char c);
|
||||
|
||||
//! Convert a size type to a string
|
||||
/*!
|
||||
Convert an size type to a string
|
||||
@ -112,12 +93,6 @@ Convert an a \c string to an size type
|
||||
*/
|
||||
size_t stringToSizeType(std::string string);
|
||||
|
||||
//! Split a string into substrings
|
||||
/*!
|
||||
Split a \c string that separated by a \c c into substrings
|
||||
*/
|
||||
std::vector<std::string> splitString(std::string string, const char c);
|
||||
|
||||
//! Case-insensitive comparisons
|
||||
/*!
|
||||
This class provides case-insensitve comparison functions.
|
||||
@ -136,9 +111,6 @@ public:
|
||||
|
||||
//! Returns true iff \c a is lexicographically less than \c b
|
||||
static bool cmpLess(const std::string::value_type &a, const std::string::value_type &b);
|
||||
|
||||
//! Returns true iff \c a is lexicographically equal to \c b
|
||||
static bool cmpEqual(const std::string::value_type &a, const std::string::value_type &b);
|
||||
};
|
||||
|
||||
} // namespace string
|
||||
|
||||
@ -8,8 +8,6 @@
|
||||
#include "base/Unicode.h"
|
||||
#include "arch/Arch.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
//
|
||||
// local utility functions
|
||||
//
|
||||
|
||||
@ -8,7 +8,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "arch/IArchString.h"
|
||||
#include "common/common.h"
|
||||
#include "common/Common.h"
|
||||
#include <string>
|
||||
|
||||
//! Unicode utility functions
|
||||
|
||||
@ -8,9 +8,7 @@
|
||||
#include "base/XBase.h"
|
||||
#include "base/String.h"
|
||||
|
||||
#include <cerrno>
|
||||
#include <cstdarg>
|
||||
#include <cstring>
|
||||
|
||||
//
|
||||
// XBase
|
||||
@ -26,12 +24,12 @@ XBase::XBase(const std::string &msg) : std::runtime_error(msg)
|
||||
// do nothing
|
||||
}
|
||||
|
||||
XBase::~XBase() _NOEXCEPT
|
||||
XBase::~XBase() throw()
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
const char *XBase::what() const _NOEXCEPT
|
||||
const char *XBase::what() const throw()
|
||||
{
|
||||
if (const char *what = std::runtime_error::what(); what != nullptr && what[0] != '\0') {
|
||||
return what;
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/stdexcept.h"
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
//! Exception base class
|
||||
@ -21,10 +21,10 @@ public:
|
||||
XBase();
|
||||
//! Use \c msg as the result of what()
|
||||
XBase(const std::string &msg);
|
||||
virtual ~XBase() _NOEXCEPT;
|
||||
virtual ~XBase() throw();
|
||||
|
||||
//! Reason for exception
|
||||
virtual const char *what() const _NOEXCEPT;
|
||||
virtual const char *what() const throw();
|
||||
|
||||
protected:
|
||||
//! Get a human readable string describing the exception
|
||||
@ -61,7 +61,7 @@ declared.
|
||||
name_(const std::string &msg) : super_(msg) \
|
||||
{ \
|
||||
} \
|
||||
virtual ~name_() _NOEXCEPT \
|
||||
virtual ~name_() throw() \
|
||||
{ \
|
||||
} \
|
||||
}
|
||||
@ -82,7 +82,7 @@ implemented.
|
||||
name_(const std::string &msg) : super_(msg) \
|
||||
{ \
|
||||
} \
|
||||
virtual ~name_() _NOEXCEPT \
|
||||
virtual ~name_() throw() \
|
||||
{ \
|
||||
} \
|
||||
\
|
||||
@ -116,11 +116,11 @@ c'tor.
|
||||
name_(const std::string &msg) : super_(msg), m_state(kFirst) \
|
||||
{ \
|
||||
} \
|
||||
virtual ~name_() _NOEXCEPT \
|
||||
virtual ~name_() throw() \
|
||||
{ \
|
||||
} \
|
||||
\
|
||||
virtual const char *what() const _NOEXCEPT \
|
||||
virtual const char *what() const throw() \
|
||||
{ \
|
||||
if (m_state == kFirst) { \
|
||||
m_state = kFormat; \
|
||||
|
||||
@ -14,17 +14,16 @@
|
||||
#include "base/TMethodEventJob.h"
|
||||
#include "base/TMethodJob.h"
|
||||
#include "client/ServerProxy.h"
|
||||
#include "common/stdexcept.h"
|
||||
#include "deskflow/AppUtil.h"
|
||||
#include "deskflow/DropHelper.h"
|
||||
#include "deskflow/FileChunk.h"
|
||||
#include "deskflow/IPlatformScreen.h"
|
||||
#include "deskflow/PacketStreamFilter.h"
|
||||
#include "deskflow/ProtocolTypes.h"
|
||||
#include "deskflow/ProtocolUtil.h"
|
||||
#include "deskflow/Screen.h"
|
||||
#include "deskflow/StreamChunker.h"
|
||||
#include "deskflow/XDeskflow.h"
|
||||
#include "deskflow/protocol_types.h"
|
||||
#include "mt/Thread.h"
|
||||
#include "net/IDataSocket.h"
|
||||
#include "net/ISocketFactory.h"
|
||||
@ -39,6 +38,7 @@
|
||||
#include <iterator>
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
|
||||
using namespace deskflow::client;
|
||||
|
||||
@ -86,8 +86,8 @@ Client::Client(
|
||||
m_events->forFile().fileChunkSending(), this, new TMethodEventJob<Client>(this, &Client::handleFileChunkSending)
|
||||
);
|
||||
m_events->adoptHandler(
|
||||
m_events->forFile().fileRecieveCompleted(), this,
|
||||
new TMethodEventJob<Client>(this, &Client::handleFileRecieveCompleted)
|
||||
m_events->forFile().fileReceiveCompleted(), this,
|
||||
new TMethodEventJob<Client>(this, &Client::handleFileReceiveCompleted)
|
||||
);
|
||||
}
|
||||
|
||||
@ -702,12 +702,12 @@ void Client::handleFileChunkSending(const Event &event, void *)
|
||||
sendFileChunk(event.getDataObject());
|
||||
}
|
||||
|
||||
void Client::handleFileRecieveCompleted(const Event &event, void *)
|
||||
void Client::handleFileReceiveCompleted(const Event &event, void *)
|
||||
{
|
||||
onFileRecieveCompleted();
|
||||
onFileReceiveCompleted();
|
||||
}
|
||||
|
||||
void Client::onFileRecieveCompleted()
|
||||
void Client::onFileReceiveCompleted()
|
||||
{
|
||||
if (isReceivedFileSizeValid()) {
|
||||
auto method = new TMethodJob<Client>(this, &Client::writeToDropDirThread);
|
||||
|
||||
@ -212,9 +212,9 @@ private:
|
||||
void handleSuspend(const Event &event, void *);
|
||||
void handleResume(const Event &event, void *);
|
||||
void handleFileChunkSending(const Event &, void *);
|
||||
void handleFileRecieveCompleted(const Event &, void *);
|
||||
void handleFileReceiveCompleted(const Event &, void *);
|
||||
void handleStopRetry(const Event &, void *);
|
||||
void onFileRecieveCompleted();
|
||||
void onFileReceiveCompleted();
|
||||
void sendClipboardThread(void *);
|
||||
void bindNetworkInterface(IDataSocket *socket) const;
|
||||
|
||||
|
||||
@ -7,8 +7,8 @@
|
||||
#include "HelloBack.h"
|
||||
|
||||
#include "base/Log.h"
|
||||
#include "deskflow/ProtocolTypes.h"
|
||||
#include "deskflow/ProtocolUtil.h"
|
||||
#include "deskflow/protocol_types.h"
|
||||
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
||||
@ -6,8 +6,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/common.h"
|
||||
#include "deskflow/protocol_types.h"
|
||||
#include "common/Common.h"
|
||||
#include "deskflow/ProtocolTypes.h"
|
||||
#include "io/IStream.h"
|
||||
|
||||
#include <functional>
|
||||
|
||||
@ -16,11 +16,11 @@
|
||||
#include "deskflow/Clipboard.h"
|
||||
#include "deskflow/ClipboardChunk.h"
|
||||
#include "deskflow/FileChunk.h"
|
||||
#include "deskflow/OptionTypes.h"
|
||||
#include "deskflow/ProtocolTypes.h"
|
||||
#include "deskflow/ProtocolUtil.h"
|
||||
#include "deskflow/StreamChunker.h"
|
||||
#include "deskflow/XDeskflow.h"
|
||||
#include "deskflow/option_types.h"
|
||||
#include "deskflow/protocol_types.h"
|
||||
#include "io/IStream.h"
|
||||
|
||||
#include <algorithm>
|
||||
@ -822,7 +822,7 @@ void ServerProxy::fileChunkReceived()
|
||||
int result = FileChunk::assemble(m_stream, m_client->getReceivedFileData(), m_client->getExpectedFileSize());
|
||||
|
||||
if (result == kFinish) {
|
||||
m_events->addEvent(Event(m_events->forFile().fileRecieveCompleted(), m_client));
|
||||
m_events->addEvent(Event(m_events->forFile().fileReceiveCompleted(), m_client));
|
||||
} else if (result == kStart) {
|
||||
if (m_client->getDragFileList().size() > 0) {
|
||||
std::string filename = m_client->getDragFileList().at(0).getFilename();
|
||||
@ -861,21 +861,7 @@ void ServerProxy::secureInputNotification()
|
||||
{
|
||||
std::string app;
|
||||
ProtocolUtil::readf(m_stream, kMsgDSecureInputNotification + 4, &app);
|
||||
|
||||
// display this notification on the client
|
||||
if (app != "unknown") {
|
||||
AppUtil::instance().showNotification(
|
||||
"The keyboard may stop working.", "'Secure input' enabled by " + app +
|
||||
" on the server. "
|
||||
"To fix the keyboard, " +
|
||||
app + " must be closed."
|
||||
);
|
||||
} else {
|
||||
AppUtil::instance().showNotification(
|
||||
"The keyboard may stop working.", "'Secure input' enabled by an application on the server. "
|
||||
"To fix the keyboard, the application must be closed."
|
||||
);
|
||||
}
|
||||
LOG((CLOG_INFO "application \"%s\" is blocking the keyboard", app.c_str()));
|
||||
}
|
||||
|
||||
void ServerProxy::setServerLanguages()
|
||||
|
||||
@ -9,8 +9,8 @@
|
||||
|
||||
#include "base/Event.h"
|
||||
#include "base/Stopwatch.h"
|
||||
#include "deskflow/clipboard_types.h"
|
||||
#include "deskflow/key_types.h"
|
||||
#include "deskflow/ClipboardTypes.h"
|
||||
#include "deskflow/KeyTypes.h"
|
||||
#include "deskflow/languages/LanguageManager.h"
|
||||
|
||||
class Client;
|
||||
|
||||
@ -1,27 +1,17 @@
|
||||
# SPDX-FileCopyrightText: (C) 2024 - 2025 Chris Rizzitello <sithlord48@gmail.com>
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
configure_file(constants.h.in constants.h @ONLY)
|
||||
configure_file(Constants.h.in Constants.h @ONLY)
|
||||
|
||||
add_library(common STATIC
|
||||
common.h
|
||||
Common.h
|
||||
IInterface.h
|
||||
stddeque.h
|
||||
stdexcept.h
|
||||
stdistream.h
|
||||
stdlist.h
|
||||
stdmap.h
|
||||
stdostream.h
|
||||
stdpost.h
|
||||
stdpre.h
|
||||
stdset.h
|
||||
stdvector.h
|
||||
${CMAKE_CURRENT_BINARY_DIR}/constants.h
|
||||
Settings.h
|
||||
Settings.cpp
|
||||
QSettingsProxy.cpp
|
||||
QSettingsProxy.h
|
||||
UrlConstants.h
|
||||
${CMAKE_CURRENT_BINARY_DIR}/Constants.h
|
||||
)
|
||||
|
||||
set_target_properties(common PROPERTIES LINKER_LANGUAGE CXX)
|
||||
target_link_libraries(common PUBLIC Qt6::Core)
|
||||
|
||||
if(APPLE)
|
||||
target_sources(common PUBLIC MacOSXPrecomp.h)
|
||||
endif()
|
||||
|
||||
@ -11,7 +11,7 @@
|
||||
#define SYSAPI_WIN32 1
|
||||
#define WINAPI_MSWINDOWS 1
|
||||
#elif HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#include "Config.h"
|
||||
#else
|
||||
#error "config.h missing"
|
||||
#endif
|
||||
@ -41,11 +41,3 @@ enum
|
||||
kExitArgs = 3, // bad arguments
|
||||
kExitConfig = 4, // cannot read configuration
|
||||
};
|
||||
|
||||
#if WINAPI_MSWINDOWS
|
||||
namespace deskflow::common {
|
||||
|
||||
const auto kCloseEventName = "Global\\DeskflowClose";
|
||||
|
||||
}
|
||||
#endif
|
||||
@ -12,11 +12,14 @@ const auto kAppId = "@CMAKE_PROJECT_NAME@";
|
||||
const auto kAppDescription = "@CMAKE_PROJECT_DESCRIPTION@";
|
||||
const auto kVersion = "@CMAKE_PROJECT_VERSION@";
|
||||
const auto kVersionGitSha = "@GIT_SHA_SHORT@";
|
||||
const auto kDisplayVersion = @CMAKE_PROJECT_VERSION_TWEAK@ ? "@CMAKE_PROJECT_VERSION@ (@GIT_SHA_SHORT@)" : "@CMAKE_PROJECT_VERSION_MAJOR@.@CMAKE_PROJECT_VERSION_MINOR@.@CMAKE_PROJECT_VERSION_PATCH@";
|
||||
const auto kDaemonBinName = "@CMAKE_PROJECT_NAME@-daemon";
|
||||
const auto kDaemonIpcName = "@CMAKE_PROJECT_NAME@-daemon";
|
||||
const auto kDaemonLogFilename = "@CMAKE_PROJECT_NAME@-daemon.log";
|
||||
const auto kWindowsRegistryKey = "SOFTWARE\\@CMAKE_PROJECT_PROPER_NAME@";
|
||||
const auto kDefaultLogFile = "@CMAKE_PROJECT_NAME@.log";
|
||||
|
||||
// clang-format off
|
||||
const auto kDisplayVersion = @CMAKE_PROJECT_VERSION_TWEAK@ ? "@CMAKE_PROJECT_VERSION@ (@GIT_SHA_SHORT@)" : "@CMAKE_PROJECT_VERSION_MAJOR@.@CMAKE_PROJECT_VERSION_MINOR@.@CMAKE_PROJECT_VERSION_PATCH@";
|
||||
// clang-format on
|
||||
|
||||
const auto kCopyright = //
|
||||
"Copyright @CMAKE_PROJECT_COPYRIGHT@\n"
|
||||
@ -30,9 +33,31 @@ const auto kDebugBuild = true;
|
||||
const auto kDebugBuild = false;
|
||||
#endif
|
||||
|
||||
const auto kSslDir = "tls";
|
||||
const auto kTlsDirName = "tls";
|
||||
const auto kTlsDbSize = 2;
|
||||
const auto kCertificateFilename = "@CMAKE_PROJECT_NAME@.pem";
|
||||
const auto kFingerprintLocalFilename = "local-fingerprint";
|
||||
const auto kFingerprintTrustedServersFilename = "trusted-servers";
|
||||
const auto kFingerprintTrustedClientsFilename = "trusted-clients";
|
||||
const auto kTlsCertificateFilename = "@CMAKE_PROJECT_NAME@.pem";
|
||||
const auto kTlsFingerprintLocalFilename = "local-fingerprint";
|
||||
const auto kTlsFingerprintTrustedServersFilename = "trusted-servers";
|
||||
const auto kTlsFingerprintTrustedClientsFilename = "trusted-clients";
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
// clang-format off
|
||||
const auto kWindowsRuntimeMajor = @REQUIRED_MSVC_RUNTIME_MAJOR@;
|
||||
const auto kWindowsRuntimeMinor = @REQUIRED_MSVC_RUNTIME_MINOR@;
|
||||
// clang-format on
|
||||
|
||||
const auto kWindowsRegistryKey = "SOFTWARE\\@CMAKE_PROJECT_PROPER_NAME@";
|
||||
const auto kCloseEventName = "Global\\@CMAKE_PROJECT_PROPER_NAME@Close";
|
||||
const auto kSendSasEventName = "Global\\@CMAKE_PROJECT_PROPER_NAME@SendSAS";
|
||||
|
||||
const auto kClientBinName = "@CMAKE_PROJECT_NAME@-client.exe";
|
||||
const auto kServerBinName = "@CMAKE_PROJECT_NAME@-server.exe";
|
||||
|
||||
#else
|
||||
|
||||
const auto kClientBinName = "@CMAKE_PROJECT_NAME@-client";
|
||||
const auto kServerBinName = "@CMAKE_PROJECT_NAME@-server";
|
||||
|
||||
#endif
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common.h"
|
||||
#include "Common.h"
|
||||
|
||||
//! Base class of interfaces
|
||||
/*!
|
||||
|
||||
@ -1,13 +0,0 @@
|
||||
/*
|
||||
* Deskflow -- mouse and keyboard sharing utility
|
||||
* SPDX-FileCopyrightText: (C) 2012 - 2016 Symless Ltd.
|
||||
* SPDX-FileCopyrightText: (C) 2002 Chris Schoeneman
|
||||
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
|
||||
*/
|
||||
|
||||
//
|
||||
// Prefix header for all source files of the 'deleteme' target in the 'deleteme'
|
||||
// project.
|
||||
//
|
||||
#pragma once
|
||||
#include <Carbon/Carbon.h>
|
||||
89
src/lib/common/QSettingsProxy.cpp
Normal file
89
src/lib/common/QSettingsProxy.cpp
Normal file
@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Deskflow -- mouse and keyboard sharing utility
|
||||
* SPDX-FileCopyrightText: (C) 2024 Symless Ltd.
|
||||
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
|
||||
*/
|
||||
|
||||
#include "QSettingsProxy.h"
|
||||
|
||||
#include "common/Settings.h"
|
||||
|
||||
/**
|
||||
* @brief The base dir for the system settings file.
|
||||
*
|
||||
* Important: Qt will append the org name as a dir, and the app name as the
|
||||
* settings filename, i.e.: `{base-dir}/Deskflow/Deskflow.ini`
|
||||
*/
|
||||
QString getSystemSettingsBaseDir()
|
||||
{
|
||||
return Settings::SystemDir;
|
||||
}
|
||||
|
||||
//
|
||||
// QSettingsProxy
|
||||
//
|
||||
|
||||
void QSettingsProxy::load(const QString &fileName)
|
||||
{
|
||||
m_pSettings = std::make_unique<QSettings>(fileName, QSettings::IniFormat);
|
||||
}
|
||||
|
||||
int QSettingsProxy::beginReadArray(const QString &prefix)
|
||||
{
|
||||
return m_pSettings->beginReadArray(prefix);
|
||||
}
|
||||
|
||||
void QSettingsProxy::setArrayIndex(int i)
|
||||
{
|
||||
m_pSettings->setArrayIndex(i);
|
||||
}
|
||||
|
||||
QVariant QSettingsProxy::value(const QString &key) const
|
||||
{
|
||||
return m_pSettings->value(key);
|
||||
}
|
||||
|
||||
QVariant QSettingsProxy::value(const QString &key, const QVariant &defaultValue) const
|
||||
{
|
||||
return m_pSettings->value(key, defaultValue);
|
||||
}
|
||||
|
||||
void QSettingsProxy::endArray()
|
||||
{
|
||||
m_pSettings->endArray();
|
||||
}
|
||||
|
||||
void QSettingsProxy::beginWriteArray(const QString &prefix)
|
||||
{
|
||||
m_pSettings->beginWriteArray(prefix);
|
||||
}
|
||||
|
||||
void QSettingsProxy::setValue(const QString &key, const QVariant &value)
|
||||
{
|
||||
m_pSettings->setValue(key, value);
|
||||
}
|
||||
|
||||
void QSettingsProxy::beginGroup(const QString &prefix)
|
||||
{
|
||||
m_pSettings->beginGroup(prefix);
|
||||
}
|
||||
|
||||
void QSettingsProxy::remove(const QString &key)
|
||||
{
|
||||
m_pSettings->remove(key);
|
||||
}
|
||||
|
||||
void QSettingsProxy::endGroup()
|
||||
{
|
||||
m_pSettings->endGroup();
|
||||
}
|
||||
|
||||
bool QSettingsProxy::isWritable() const
|
||||
{
|
||||
return m_pSettings->isWritable();
|
||||
}
|
||||
|
||||
bool QSettingsProxy::contains(const QString &key) const
|
||||
{
|
||||
return m_pSettings->contains(key);
|
||||
}
|
||||
@ -8,8 +8,6 @@
|
||||
|
||||
#include <QSettings>
|
||||
|
||||
namespace deskflow::gui::proxy {
|
||||
|
||||
QString getSystemSettingBaseDir();
|
||||
|
||||
class QSettingsProxy
|
||||
@ -17,8 +15,7 @@ class QSettingsProxy
|
||||
public:
|
||||
virtual ~QSettingsProxy() = default;
|
||||
|
||||
virtual void loadUser();
|
||||
virtual void loadSystem();
|
||||
virtual void load(const QString &fileName);
|
||||
virtual void clear()
|
||||
{
|
||||
m_pSettings->clear();
|
||||
@ -52,5 +49,3 @@ public:
|
||||
private:
|
||||
std::unique_ptr<QSettings> m_pSettings;
|
||||
};
|
||||
|
||||
} // namespace deskflow::gui::proxy
|
||||
217
src/lib/common/Settings.cpp
Normal file
217
src/lib/common/Settings.cpp
Normal file
@ -0,0 +1,217 @@
|
||||
/*
|
||||
* Deskflow -- mouse and keyboard sharing utility
|
||||
* SPDX-FileCopyrightText: (C) 2025 Chris Rizzitello <sithlord48@gmail.com>
|
||||
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
|
||||
*/
|
||||
|
||||
#include "Settings.h"
|
||||
|
||||
#include "UrlConstants.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QFile>
|
||||
#include <QRect>
|
||||
|
||||
Settings *Settings::instance()
|
||||
{
|
||||
static Settings m;
|
||||
return &m;
|
||||
}
|
||||
|
||||
void Settings::setSettingFile(const QString &settingsFile)
|
||||
{
|
||||
if (instance()->m_portableSettingsFile == settingsFile) {
|
||||
qDebug().noquote() << "settings file already in use";
|
||||
return;
|
||||
}
|
||||
|
||||
instance()->m_portableSettingsFile = settingsFile;
|
||||
if (instance()->m_settings)
|
||||
instance()->m_settings->deleteLater();
|
||||
instance()->m_settings = new QSettings(instance()->m_portableSettingsFile, QSettings::IniFormat);
|
||||
instance()->m_settingsProxy->load(instance()->m_portableSettingsFile);
|
||||
qInfo().noquote() << "settings file:" << instance()->m_settings->fileName();
|
||||
}
|
||||
|
||||
Settings::Settings(QObject *parent) : QObject(parent)
|
||||
{
|
||||
m_portableSettingsFile = m_portableSettingsFile.arg(QCoreApplication::applicationDirPath(), kAppName);
|
||||
QString fileToLoad;
|
||||
if (QFile(m_portableSettingsFile).exists()) {
|
||||
fileToLoad = m_portableSettingsFile;
|
||||
} else {
|
||||
if (!qEnvironmentVariable("XDG_CONFIG_HOME").isEmpty())
|
||||
fileToLoad = QStringLiteral("%1/%2/%2.conf").arg(qEnvironmentVariable("XDG_CONFIG_HOME"), kAppName);
|
||||
else if (QFile(UserSettingFile).exists())
|
||||
fileToLoad = UserSettingFile;
|
||||
else if (QFile(SystemSettingFile).exists())
|
||||
fileToLoad = SystemSettingFile;
|
||||
else
|
||||
fileToLoad = UserSettingFile;
|
||||
}
|
||||
|
||||
m_settings = new QSettings(fileToLoad, QSettings::IniFormat);
|
||||
m_settingsProxy = std::make_shared<QSettingsProxy>();
|
||||
m_settingsProxy->load(fileToLoad);
|
||||
qInfo().noquote() << "settings file:" << m_settings->fileName();
|
||||
}
|
||||
|
||||
void Settings::cleanSettings()
|
||||
{
|
||||
const QStringList keys = m_settings->allKeys();
|
||||
for (const QString &key : keys) {
|
||||
if (!m_validKeys.contains(key))
|
||||
m_settings->remove(key);
|
||||
if (m_settings->value(key).toString().isEmpty() && !m_settings->value(key).isValid())
|
||||
m_settings->remove(key);
|
||||
}
|
||||
}
|
||||
|
||||
QVariant Settings::defaultValue(const QString &key)
|
||||
{
|
||||
if ((key == Gui::Autohide) || (key == Core::StartedBefore) || (key == Core::PreventSleep) ||
|
||||
(key == Server::ExternalConfig) || (key == Client::InvertScrollDirection) || (key == Log::ToFile)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((key == Gui::CloseToTray) || (key == Gui::LogExpanded) || (key == Gui::SymbolicTrayIcon) ||
|
||||
(key == Gui::CloseReminder) || (key == Security::TlsEnabled) || (key == Security::CheckPeers) ||
|
||||
(key == Client::LanguageSync)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (key == Core::ScreenName)
|
||||
return QSysInfo::machineHostName();
|
||||
|
||||
if (key == Gui::WindowGeometry)
|
||||
return QRect();
|
||||
|
||||
if (key == Security::Certificate)
|
||||
return QStringLiteral("%1/%2").arg(instance()->tlsDir(), kTlsCertificateFilename);
|
||||
|
||||
if (key == Security::KeySize)
|
||||
return 2048;
|
||||
|
||||
if (key == Log::File)
|
||||
return QStringLiteral("%1/%2").arg(QDir::homePath(), kDefaultLogFile);
|
||||
|
||||
if (key == Log::Level)
|
||||
return 0;
|
||||
|
||||
if (key == Client::Binary)
|
||||
return kClientBinName;
|
||||
|
||||
if (key == Server::Binary)
|
||||
return kServerBinName;
|
||||
|
||||
if (key == Core::ElevateMode)
|
||||
return Settings::ElevateMode::Always;
|
||||
|
||||
if (key == Core::UpdateUrl)
|
||||
return kUrlUpdateCheck;
|
||||
|
||||
if (key == Server::ExternalConfigFile)
|
||||
return QStringLiteral("%1/%2.conf").arg(instance()->settingsPath(), kAppId);
|
||||
|
||||
if (key == Core::Port)
|
||||
return 24800;
|
||||
|
||||
if (key == Core::ProcessMode)
|
||||
return defaultProcessMode;
|
||||
|
||||
if (key == Daemon::LogFile) {
|
||||
#ifdef Q_OS_WIN
|
||||
return QStringLiteral("%1/%2").arg(QCoreApplication::applicationDirPath(), kDaemonLogFilename);
|
||||
#else
|
||||
return QStringLiteral("%1/%2").arg(instance()->settingsPath(), kDaemonLogFilename);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (key == Daemon::Elevate)
|
||||
return true;
|
||||
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
const QString Settings::logLevelText()
|
||||
{
|
||||
return instance()->m_logLevels.at(instance()->value(Log::Level).toInt());
|
||||
}
|
||||
|
||||
QSettingsProxy &Settings::proxy()
|
||||
{
|
||||
return *instance()->m_settingsProxy;
|
||||
}
|
||||
|
||||
void Settings::save(bool emitSaving)
|
||||
{
|
||||
if (emitSaving)
|
||||
Q_EMIT instance()->serverSettingsChanged();
|
||||
instance()->m_settings->sync();
|
||||
}
|
||||
|
||||
const QStringList Settings::validKeys()
|
||||
{
|
||||
return instance()->m_validKeys;
|
||||
}
|
||||
|
||||
bool Settings::isWritable()
|
||||
{
|
||||
return instance()->m_settings->isWritable();
|
||||
}
|
||||
|
||||
const QString Settings::settingsFile()
|
||||
{
|
||||
return instance()->m_settings->fileName();
|
||||
}
|
||||
|
||||
const QString Settings::settingsPath()
|
||||
{
|
||||
return QFileInfo(instance()->m_settings->fileName()).absolutePath();
|
||||
}
|
||||
|
||||
const QString Settings::tlsDir()
|
||||
{
|
||||
return QStringLiteral("%1/%2").arg(instance()->settingsPath(), kTlsDirName);
|
||||
}
|
||||
|
||||
const QString Settings::tlsLocalDb()
|
||||
{
|
||||
return QStringLiteral("%1/%2").arg(instance()->tlsDir(), kTlsFingerprintLocalFilename);
|
||||
}
|
||||
|
||||
const QString Settings::tlsTrustedServersDb()
|
||||
{
|
||||
return QStringLiteral("%1/%2").arg(instance()->tlsDir(), kTlsFingerprintTrustedServersFilename);
|
||||
}
|
||||
|
||||
const QString Settings::tlsTrustedClientsDb()
|
||||
{
|
||||
return QStringLiteral("%1/%2").arg(instance()->tlsDir(), kTlsFingerprintTrustedClientsFilename);
|
||||
}
|
||||
|
||||
void Settings::setValue(const QString &key, const QVariant &value)
|
||||
{
|
||||
if (instance()->m_settings->value(key) == value)
|
||||
return;
|
||||
|
||||
if (!value.isValid())
|
||||
instance()->m_settings->remove(key);
|
||||
else
|
||||
instance()->m_settings->setValue(key, value);
|
||||
|
||||
instance()->m_settings->sync();
|
||||
Q_EMIT instance()->settingsChanged(key);
|
||||
}
|
||||
|
||||
QVariant Settings::value(const QString &key)
|
||||
{
|
||||
return instance()->m_settings->value(key, defaultValue(key));
|
||||
}
|
||||
|
||||
void Settings::restoreDefaultSettings()
|
||||
{
|
||||
for (const auto &key : m_validKeys) {
|
||||
instance()->setValue(key, defaultValue(key));
|
||||
}
|
||||
}
|
||||
221
src/lib/common/Settings.h
Normal file
221
src/lib/common/Settings.h
Normal file
@ -0,0 +1,221 @@
|
||||
/*
|
||||
* Deskflow -- mouse and keyboard sharing utility
|
||||
* SPDX-FileCopyrightText: (C) 2025 Chris Rizzitello <sithlord48@gmail.com>
|
||||
* SPDX-FileCopyrightText: (C) 2016 - 2025 Symless Ltd.
|
||||
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QSettings>
|
||||
|
||||
#include <QDir>
|
||||
|
||||
#include "common/Constants.h"
|
||||
#include "common/QSettingsProxy.h"
|
||||
|
||||
class Settings : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
#if defined(Q_OS_WIN)
|
||||
inline const static auto UserDir = QStringLiteral("%1/AppData/Local/%2").arg(QDir::homePath(), kAppName);
|
||||
inline const static auto SystemDir = QStringLiteral("C:/ProgramData/%1").arg(kAppName);
|
||||
#elif defined(Q_OS_MAC)
|
||||
inline const static auto UserDir = QStringLiteral("%1/Library/%2").arg(QDir::homePath(), kAppName);
|
||||
inline const static auto SystemDir = QStringLiteral("/Library/%1").arg(kAppName);
|
||||
#else
|
||||
inline const static auto UserDir = QStringLiteral("%1/.config/%2").arg(QDir::homePath(), kAppName);
|
||||
inline const static auto SystemDir = QStringLiteral("/etc/%1").arg(kAppName);
|
||||
#endif
|
||||
inline const static auto UserSettingFile = QStringLiteral("%1/%2.conf").arg(UserDir, kAppName);
|
||||
inline const static auto SystemSettingFile = QStringLiteral("%1/%2.conf").arg(SystemDir, kAppName);
|
||||
|
||||
struct Client
|
||||
{
|
||||
inline static const auto Binary = QStringLiteral("client/binary");
|
||||
inline static const auto InvertScrollDirection = QStringLiteral("client/invertScrollDirection");
|
||||
inline static const auto LanguageSync = QStringLiteral("client/languageSync");
|
||||
inline static const auto RemoteHost = QStringLiteral("client/remoteHost");
|
||||
};
|
||||
struct Core
|
||||
{
|
||||
inline static const auto CoreMode = QStringLiteral("core/coreMode");
|
||||
inline static const auto ElevateMode = QStringLiteral("core/elevateMode");
|
||||
inline static const auto Interface = QStringLiteral("core/interface");
|
||||
inline static const auto LastVersion = QStringLiteral("core/lastVersion");
|
||||
inline static const auto Port = QStringLiteral("core/port");
|
||||
inline static const auto PreventSleep = QStringLiteral("core/preventSleep");
|
||||
inline static const auto ProcessMode = QStringLiteral("core/processMode");
|
||||
inline static const auto ScreenName = QStringLiteral("core/screenName");
|
||||
inline static const auto StartedBefore = QStringLiteral("core/startedBefore");
|
||||
inline static const auto UpdateUrl = QStringLiteral("core/updateUrl");
|
||||
};
|
||||
struct Daemon
|
||||
{
|
||||
inline static const auto Command = QStringLiteral("daemon/command");
|
||||
inline static const auto Elevate = QStringLiteral("daemon/elevate");
|
||||
inline static const auto LogFile = QStringLiteral("daemon/logFile");
|
||||
inline static const auto LogLevel = QStringLiteral("daemon/logLevel");
|
||||
};
|
||||
struct Gui
|
||||
{
|
||||
inline static const auto Autohide = QStringLiteral("gui/autoHide");
|
||||
inline static const auto AutoUpdateCheck = QStringLiteral("gui/enableUpdateCheck");
|
||||
inline static const auto CloseReminder = QStringLiteral("gui/closeReminder");
|
||||
inline static const auto CloseToTray = QStringLiteral("gui/closeToTray");
|
||||
inline static const auto LogExpanded = QStringLiteral("gui/logExpanded");
|
||||
inline static const auto SymbolicTrayIcon = QStringLiteral("gui/symbolicTrayIcon");
|
||||
inline static const auto WindowGeometry = QStringLiteral("gui/windowGeometry");
|
||||
};
|
||||
struct Log
|
||||
{
|
||||
inline static const auto File = QStringLiteral("log/file");
|
||||
inline static const auto Level = QStringLiteral("log/level");
|
||||
inline static const auto ToFile = QStringLiteral("log/toFile");
|
||||
};
|
||||
struct Security
|
||||
{
|
||||
inline static const auto CheckPeers = QStringLiteral("security/checkPeerFingerprints");
|
||||
inline static const auto Certificate = QStringLiteral("security/certificate");
|
||||
inline static const auto KeySize = QStringLiteral("security/keySize");
|
||||
inline static const auto TlsEnabled = QStringLiteral("security/tlsEnabled");
|
||||
};
|
||||
struct Server
|
||||
{
|
||||
inline static const auto Binary = QStringLiteral("server/binary");
|
||||
inline static const auto ConfigVisible = QStringLiteral("server/configVisible");
|
||||
inline static const auto ExternalConfig = QStringLiteral("server/externalConfig");
|
||||
inline static const auto ExternalConfigFile = QStringLiteral("server/externalConfigFile");
|
||||
};
|
||||
|
||||
// Enums types used in settings
|
||||
// The use of enum classes is not use for these
|
||||
// enum classes are more specific when used with QVariant
|
||||
// This leads longer function calls in code
|
||||
// and longer more cryptic output in the settings file
|
||||
// The using of standard enum will just write ints
|
||||
// and we can read / write them as if they were ints
|
||||
enum ProcessMode
|
||||
{
|
||||
Service,
|
||||
Desktop
|
||||
};
|
||||
Q_ENUM(ProcessMode)
|
||||
|
||||
/**
|
||||
* @brief The elevate mode tristate determines two behaviors on Windows.
|
||||
* The matrix for these two behaviors is as follows:
|
||||
* | sods | elevate |
|
||||
* |-----------|------------|
|
||||
* kAutomatic | true | false |
|
||||
* kAlways | false | true |
|
||||
* kNever | false | false |
|
||||
* The first, --stop-on-desk-switch (sods), is passed through the daemon as a
|
||||
* command line argument to the server/client, and determines if it restarts
|
||||
* when switching Windows desktops (e.g. when Windows UAC dialog pops up).
|
||||
* The second, elevate, is passed as a boolean flag to the daemon over IPC,
|
||||
* and determines whether the server/client should be started with elevated privileges.
|
||||
*/
|
||||
enum ElevateMode
|
||||
{
|
||||
Automatic = 0,
|
||||
Always = 1,
|
||||
Never = 2
|
||||
};
|
||||
Q_ENUM(ElevateMode)
|
||||
|
||||
enum CoreMode
|
||||
{
|
||||
None,
|
||||
Client,
|
||||
Server
|
||||
};
|
||||
Q_ENUM(CoreMode)
|
||||
|
||||
static Settings *instance();
|
||||
static void setSettingFile(const QString &settingsFile = QString());
|
||||
static void setValue(const QString &key = QString(), const QVariant &value = QVariant());
|
||||
static QVariant value(const QString &key = QString());
|
||||
static void restoreDefaultSettings();
|
||||
static QVariant defaultValue(const QString &key);
|
||||
static bool isWritable();
|
||||
static const QString settingsFile();
|
||||
static const QString settingsPath();
|
||||
static const QString tlsDir();
|
||||
static const QString tlsLocalDb();
|
||||
static const QString tlsTrustedServersDb();
|
||||
static const QString tlsTrustedClientsDb();
|
||||
static const QString logLevelText();
|
||||
static QSettingsProxy &proxy();
|
||||
static void save(bool emitSaving = true);
|
||||
static const QStringList validKeys();
|
||||
|
||||
signals:
|
||||
void settingsChanged(const QString key);
|
||||
void serverSettingsChanged();
|
||||
|
||||
private:
|
||||
explicit Settings(QObject *parent = nullptr);
|
||||
Settings *operator=(Settings &other) = delete;
|
||||
Settings(const Settings &other) = delete;
|
||||
~Settings() = default;
|
||||
void cleanSettings();
|
||||
|
||||
QSettings *m_settings = nullptr;
|
||||
QString m_portableSettingsFile = QStringLiteral("%1/settings/%2.conf");
|
||||
std::shared_ptr<QSettingsProxy> m_settingsProxy;
|
||||
|
||||
// clang-format off
|
||||
inline static const QStringList m_logLevels = {
|
||||
QStringLiteral("INFO")
|
||||
, QStringLiteral("DEBUG")
|
||||
, QStringLiteral("DEBUG1")
|
||||
, QStringLiteral("DEBUG2")
|
||||
};
|
||||
|
||||
inline static const QStringList m_validKeys = {
|
||||
Settings::Client::Binary
|
||||
, Settings::Client::InvertScrollDirection
|
||||
, Settings::Client::LanguageSync
|
||||
, Settings::Client::RemoteHost
|
||||
, Settings::Core::CoreMode
|
||||
, Settings::Core::ElevateMode
|
||||
, Settings::Core::Interface
|
||||
, Settings::Core::LastVersion
|
||||
, Settings::Core::Port
|
||||
, Settings::Core::PreventSleep
|
||||
, Settings::Core::ProcessMode
|
||||
, Settings::Core::ScreenName
|
||||
, Settings::Core::StartedBefore
|
||||
, Settings::Core::UpdateUrl
|
||||
, Settings::Daemon::Command
|
||||
, Settings::Daemon::Elevate
|
||||
, Settings::Daemon::LogFile
|
||||
, Settings::Log::File
|
||||
, Settings::Log::Level
|
||||
, Settings::Log::ToFile
|
||||
, Settings::Gui::Autohide
|
||||
, Settings::Gui::AutoUpdateCheck
|
||||
, Settings::Gui::CloseReminder
|
||||
, Settings::Gui::CloseToTray
|
||||
, Settings::Gui::LogExpanded
|
||||
, Settings::Gui::SymbolicTrayIcon
|
||||
, Settings::Gui::WindowGeometry
|
||||
, Settings::Security::Certificate
|
||||
, Settings::Security::CheckPeers
|
||||
, Settings::Security::KeySize
|
||||
, Settings::Security::TlsEnabled
|
||||
, Settings::Server::Binary
|
||||
, Settings::Server::ConfigVisible
|
||||
, Settings::Server::ExternalConfig
|
||||
, Settings::Server::ExternalConfigFile
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
inline static const auto defaultProcessMode = Settings::ProcessMode::Service;
|
||||
#else
|
||||
inline static const auto defaultProcessMode = Settings::ProcessMode::Desktop;
|
||||
#endif
|
||||
};
|
||||
@ -8,20 +8,18 @@
|
||||
|
||||
#include <QString>
|
||||
|
||||
namespace deskflow::gui {
|
||||
|
||||
// important: this is used for settings paths on some platforms,
|
||||
// and must not be a url. qt automatically converts this to reverse domain
|
||||
// notation (rdn), e.g. org.deskflow
|
||||
const auto kOrgDomain = QStringLiteral("deskflow.org");
|
||||
|
||||
const auto kUrlSourceQuery = QStringLiteral("source=gui");
|
||||
const auto kUrlApp = QStringLiteral("https://deskflow.org");
|
||||
const auto kUrlApp = QStringLiteral("https://%1").arg(kOrgDomain);
|
||||
const auto kUrlHelp = QStringLiteral("%1/help?%2").arg(kUrlApp, kUrlSourceQuery);
|
||||
const auto kUrlDownload = QStringLiteral("%1/download?%2").arg(kUrlApp, kUrlSourceQuery);
|
||||
|
||||
const auto kUrlUpdateCheck = QStringLiteral("https://api.%1/version").arg(kOrgDomain);
|
||||
|
||||
#if defined(Q_OS_LINUX)
|
||||
const auto kUrlGnomeTrayFix = QStringLiteral("https://extensions.gnome.org/extension/615/appindicator-support/");
|
||||
#endif
|
||||
|
||||
} // namespace deskflow::gui
|
||||
@ -1,13 +0,0 @@
|
||||
/*
|
||||
* Deskflow -- mouse and keyboard sharing utility
|
||||
* SPDX-FileCopyrightText: (C) 2012 - 2016 Symless Ltd.
|
||||
* SPDX-FileCopyrightText: (C) 2002 Chris Schoeneman
|
||||
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include "stdpre.h"
|
||||
|
||||
#include <deque>
|
||||
|
||||
#include "stdpost.h"
|
||||
@ -1,14 +0,0 @@
|
||||
/*
|
||||
* Deskflow -- mouse and keyboard sharing utility
|
||||
* SPDX-FileCopyrightText: (C) 2014 - 2016 Symless Ltd.
|
||||
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
// apple declares _NOEXCEPT
|
||||
#ifndef _NOEXCEPT
|
||||
#define _NOEXCEPT throw()
|
||||
#endif
|
||||
@ -1,18 +0,0 @@
|
||||
/*
|
||||
* Deskflow -- mouse and keyboard sharing utility
|
||||
* SPDX-FileCopyrightText: (C) 2012 - 2016 Symless Ltd.
|
||||
* SPDX-FileCopyrightText: (C) 2002 Chris Schoeneman
|
||||
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "stdpre.h"
|
||||
|
||||
#if HAVE_ISTREAM
|
||||
#include <istream>
|
||||
#else
|
||||
#include <iostream>
|
||||
#endif
|
||||
|
||||
#include "stdpost.h"
|
||||
@ -1,14 +0,0 @@
|
||||
/*
|
||||
* Deskflow -- mouse and keyboard sharing utility
|
||||
* SPDX-FileCopyrightText: (C) 2012 - 2016 Symless Ltd.
|
||||
* SPDX-FileCopyrightText: (C) 2002 Chris Schoeneman
|
||||
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "stdpre.h"
|
||||
|
||||
#include <list>
|
||||
|
||||
#include "stdpost.h"
|
||||
@ -1,14 +0,0 @@
|
||||
/*
|
||||
* Deskflow -- mouse and keyboard sharing utility
|
||||
* SPDX-FileCopyrightText: (C) 2012 - 2016 Symless Ltd.
|
||||
* SPDX-FileCopyrightText: (C) 2002 Chris Schoeneman
|
||||
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "stdpre.h"
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "stdpost.h"
|
||||
@ -1,18 +0,0 @@
|
||||
/*
|
||||
* Deskflow -- mouse and keyboard sharing utility
|
||||
* SPDX-FileCopyrightText: (C) 2012 - 2016 Symless Ltd.
|
||||
* SPDX-FileCopyrightText: (C) 2002 Chris Schoeneman
|
||||
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "stdpre.h"
|
||||
|
||||
#if HAVE_OSTREAM
|
||||
#include <ostream>
|
||||
#else
|
||||
#include <iostream>
|
||||
#endif
|
||||
|
||||
#include "stdpost.h"
|
||||
@ -1,12 +0,0 @@
|
||||
/*
|
||||
* Deskflow -- mouse and keyboard sharing utility
|
||||
* SPDX-FileCopyrightText: (C) 2012 - 2016 Symless Ltd.
|
||||
* SPDX-FileCopyrightText: (C) 2002 Chris Schoeneman
|
||||
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
@ -1,22 +0,0 @@
|
||||
/*
|
||||
* Deskflow -- mouse and keyboard sharing utility
|
||||
* SPDX-FileCopyrightText: (C) 2012 - 2016 Symless Ltd.
|
||||
* SPDX-FileCopyrightText: (C) 2002 Chris Schoeneman
|
||||
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
#pragma warning(disable : 4786) // identifier truncated
|
||||
#pragma warning(disable : 4514) // unreferenced inline
|
||||
#pragma warning(disable : 4710) // not inlined
|
||||
#pragma warning(disable : 4663) // C++ change, template specialization
|
||||
#pragma warning(disable : 4503) // decorated name length too long
|
||||
#pragma warning(push, 3)
|
||||
#pragma warning(disable : 4018) // signed/unsigned mismatch
|
||||
#pragma warning(disable : 4284)
|
||||
#pragma warning(disable : 4146) // unary minus on unsigned value
|
||||
#pragma warning(disable : 4127) // conditional expression is constant
|
||||
#pragma warning(disable : 4701) // variable possibly used uninitialized
|
||||
#endif
|
||||
@ -1,14 +0,0 @@
|
||||
/*
|
||||
* Deskflow -- mouse and keyboard sharing utility
|
||||
* SPDX-FileCopyrightText: (C) 2012 - 2016 Symless Ltd.
|
||||
* SPDX-FileCopyrightText: (C) 2002 Chris Schoeneman
|
||||
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "stdpre.h"
|
||||
|
||||
#include <set>
|
||||
|
||||
#include "stdpost.h"
|
||||
@ -1,14 +0,0 @@
|
||||
/*
|
||||
* Deskflow -- mouse and keyboard sharing utility
|
||||
* SPDX-FileCopyrightText: (C) 2012 - 2016 Symless Ltd.
|
||||
* SPDX-FileCopyrightText: (C) 2002 Chris Schoeneman
|
||||
* SPDX-License-Identifier: GPL-2.0-only WITH LicenseRef-OpenSSL-Exception
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "stdpre.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "stdpost.h"
|
||||
@ -10,12 +10,12 @@
|
||||
#include "DisplayInvalidException.h"
|
||||
#include "arch/Arch.h"
|
||||
#include "base/Log.h"
|
||||
#include "base/log_outputters.h"
|
||||
#include "common/constants.h"
|
||||
#include "base/LogOutputters.h"
|
||||
#include "common/Constants.h"
|
||||
#include "deskflow/ArgsBase.h"
|
||||
#include "deskflow/Config.h"
|
||||
#include "deskflow/ProtocolTypes.h"
|
||||
#include "deskflow/XDeskflow.h"
|
||||
#include "deskflow/protocol_types.h"
|
||||
|
||||
#if SYSAPI_WIN32
|
||||
#include "base/IEventQueue.h"
|
||||
@ -175,9 +175,6 @@ void App::initApp(int argc, const char **argv)
|
||||
parseArgs(argc, argv);
|
||||
}
|
||||
|
||||
ARCH->setProfileDirectory(argsBase().m_profileDirectory);
|
||||
ARCH->setPluginDirectory(argsBase().m_pluginDirectory);
|
||||
|
||||
// set log filter
|
||||
if (!CLOG->setFilter(argsBase().m_logFilter)) {
|
||||
LOG((
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
|
||||
#include "base/EventQueue.h"
|
||||
#include "base/Log.h"
|
||||
#include "common/common.h"
|
||||
#include "common/Common.h"
|
||||
#include "deskflow/IApp.h"
|
||||
|
||||
#if SYSAPI_WIN32
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user