Compare commits

...

49 Commits

Author SHA1 Message Date
Adrian Lucrèce Céleste
1a5eae46fe [Travis] bring up to date 2018-07-02 22:45:35 -04:00
walker0643
f65189190c Merge pull request #75 from debauchee/master
pull in recent patches from master
2018-06-30 18:51:49 -04:00
dc5dc25de7 screen settings dialog handles internationalized default name better
(ref #71)
2018-06-30 17:33:49 -04:00
walker0643
53ee9c7803 Merge pull request #64 from p12tic/osx-server-jumpy-scrolling
Improve precision of grabbed scroll events on OSX server
2018-06-30 16:40:10 -04:00
1f3a91e74e fix email in debian changelog 2018-06-30 16:32:05 -04:00
walker0643
99188fe24b Merge pull request #69 from p12tic/debian-add-fake-changelog
Add fake changelog so that debian package may be built (p
2018-06-30 16:30:32 -04:00
a956cad0da add patch from Gentoo packager to fix cmake issue (reported on Arch, too). ref #49 2018-06-30 13:44:34 -04:00
e88bc97e63 non-GUI build should not require bonjour headers 2018-06-30 13:26:18 -04:00
walker0643
f857354535 Merge pull request #68 from p12tic/linux-client-accumulate-small-scrolls
Accumulate scrolls less than supported scroll on XWindows (patch by p12tic)
2018-06-30 12:52:09 -04:00
Povilas Kanapickas
b570e57591 Add fake changelog so that debian package may be built 2018-06-21 01:13:41 +03:00
Povilas Kanapickas
76c39aaf4e Accumulate scrolls less than supported scroll on XWindows
This fixes barrier case #67 and synergy case #5670.
2018-06-21 00:50:08 +03:00
Povilas Kanapickas
a645e9a296 Improve precision of grabbed scroll events on OSX server
This is barrier issue #63, synergy issue #5672.
2018-06-21 00:13:40 +03:00
walker0643
3747ea51fd Merge pull request #48 from Johnnynator/master
use pkg-config for finding avahi include dir (patch by johnnynator)
2018-05-26 22:27:22 -04:00
John
ecb61f41dc use pkg-config for finding avahi include dir 2018-05-26 00:00:13 +02:00
773a0081e3 remove (wrong) version line from .desktop file 2018-05-15 22:48:18 -04:00
8b69f9fe03 better handling of non-git builds 2018-05-14 12:55:03 -04:00
0b2dfd80e2 move protocol version to new line in --version output (fix display issue in created manpages) 2018-05-14 12:23:24 -04:00
c7569f8af7 update manpages 2018-05-12 18:35:18 -04:00
walker0643
b8ad9b8aba Set theme jekyll-theme-slate 2018-05-12 18:24:22 -04:00
9ab77545ee fix ipv6 handling between GUI and barriers/barrierc; zero-fill sockaddr_in(6) structs prior to initializing; update --help output 2018-05-12 17:42:55 -04:00
f4301a7618 fix usage of m_pname and rename to m_exename 2018-05-12 17:32:26 -04:00
f299558cdf remove stale definitions 2018-05-12 17:20:35 -04:00
7fd6711829 remove stale references to syntool/synwinhk 2018-05-10 11:42:08 -04:00
b43581c2f5 remove explicit paths from .desktop file 2018-05-07 13:21:25 -04:00
bd4c214c39 bump version to 2.1. remove dependence on git for tarball builds. 2018-05-07 13:20:40 -04:00
642eb33446 make linux/bsd data directory conform to freedesktop standards. fixes #31 2018-05-07 12:57:06 -04:00
walker0643
0b5ca57b9c Merge pull request #26 from debauchee/nosyntool
Drop syntool. In the process some platform-dependent locations have changed. Some users may need to recreate config files or copy the from the old location(s).
2018-04-14 18:20:19 -04:00
a7fb1b56f6 Merge branch 'master' into nosyntool 2018-04-01 21:14:32 -04:00
5e19820425 remove dangling handler..fixes race condition when a clipboard event is queued but not dispatched before disconnect 2018-04-01 21:13:56 -04:00
9e7792e2ae add comment re C++17 to MSWindowsUtil.cpp 2018-04-01 14:57:22 -04:00
42a8f69050 better comments in PathUtilities.cpp 2018-04-01 14:47:34 -04:00
1734e6d7f6 Merge branch 'master' into nosyntool 2018-04-01 14:04:53 -04:00
6c4199b11a fix mainwindow icon 2018-04-01 14:00:52 -04:00
767188799e add desktop name to DEBUG output. when is desktop ever NOT "Default" ? 2018-04-01 13:59:14 -04:00
e6d0f40a36 add legal header to new files 2018-04-01 12:43:55 -04:00
129e61a33a server should look for config in the profile() dir rather than the personal() dir. removed personal() since it is no longer used. 2018-03-31 22:48:59 -04:00
4c04f39685 reimplement path operations basename() and concat() in Common. these were the last bits remaining in ArchFile* so it was removed 2018-03-31 22:41:00 -04:00
131a19d478 reimplement ArchFile*::getSystemDirectory() as DataDirectories::systemconfig(). windows will now use ProgramData by default rather than C:\Windows 2018-03-30 14:39:12 -04:00
6c5acdd552 remove DataDirectory wrappers in ArchFile* 2018-03-30 14:01:18 -04:00
d81054ab6e remove some stale code and put windows service logfile in a better spot 2018-03-29 21:41:30 -04:00
1be86a9248 remove syntool, CoreInterface, and WebClient 2018-03-29 17:14:57 -04:00
ea025f5958 fix --profile-dir argument 2018-03-29 17:13:45 -04:00
6e5b340bcc replace CoreInterface syntool calls with DataDirectory calls 2018-03-29 16:38:50 -04:00
451bd72b30 MSWindowsWatchdog checks active desktop without external call to syntool 2018-03-29 16:32:51 -04:00
c16fd089f6 old personal and profile directory functions now wrap the new implementations 2018-03-29 16:12:45 -04:00
96627f4f07 reimplement finding personal & profile directories on unix (not yet used) 2018-03-29 15:54:41 -04:00
c5e70af09a DataDirectories header should be shared between platform-specific implementations 2018-03-29 15:50:23 -04:00
72cc7e3d89 link gui with common; reimplement finding personal and profile directories on windows (not yet used) 2018-03-29 14:01:07 -04:00
fe818a4955 add console for ctrl+c to daemon app when debugging in foreground 2018-03-29 12:02:35 -04:00
72 changed files with 695 additions and 1568 deletions

View File

@@ -1,10 +1,34 @@
language: cpp
before_install:
- sudo apt-get update -qq
- sudo apt-get install -qq libxtst-dev
- sudo apt-get install -qq qtdeclarative5-dev
- sudo apt-get install -qq libavahi-compat-libdnssd-dev
script: sh -x ./clean_build.sh
# skip install phase since we have a customized install package
# creation tool for each supported platform
matrix:
include:
- os: linux
sudo: false
dist: trusty
addons:
apt:
packages:
- libxtst-dev
- qtdeclarative5-dev
- libavahi-compat-libdnssd-dev
script: sh -x ./clean_build.sh
- os: osx
osx_image: xcode9
script:
- export COLUMNS=80
- curl -LO https://raw.githubusercontent.com/GiovanniBussi/macports-ci/master/macports-ci
- chmod +x ./macports-ci
- ./macports-ci install
- PATH="$PATH:/opt/local/bin"
- sudo port -N install qt5-qtbase openssl
- sh -x ./clean_build.sh
- os: osx
osx_image: xcode9
script:
- brew update
- brew install qt openssl
- sh -x ./clean_build.sh
install: true

View File

@@ -63,6 +63,7 @@ if (UNIX)
include (CheckIncludeFileCXX)
include (CheckSymbolExists)
include (CheckCSourceCompiles)
include (FindPkgConfig)
check_include_file_cxx (istream HAVE_ISTREAM)
check_include_file_cxx (ostream HAVE_OSTREAM)
@@ -162,6 +163,11 @@ if (UNIX)
include_directories("/usr/local/include" "/usr/local/include/avahi-compat-libdns_sd")
link_directories("/usr/local/lib")
endif()
if (${PKG_CONFIG_FOUND})
pkg_check_modules (AVAHI_COMPAT REQUIRED avahi-compat-libdns_sd)
include_directories (BEFORE SYSTEM ${AVAHI_COMPAT_INCLUDE_DIRS})
set (CMAKE_REQUIRED_INCLUDES "${CMAKE_REQUIRED_INCLUDES};${AVAHI_COMPAT_INCLUDE_DIRS}")
endif ()
set (XKBlib "X11/Xlib.h;X11/XKBlib.h")
set (CMAKE_EXTRA_INCLUDE_FILES "${XKBlib};X11/extensions/Xrandr.h")
@@ -187,7 +193,7 @@ if (UNIX)
message (FATAL_ERROR "Missing header: " ${XKBlib})
endif()
if (NOT HAVE_DNSSD)
if (BARRIER_BUILD_GUI AND NOT HAVE_DNSSD)
message (FATAL_ERROR "Missing header: dns_sd.h")
endif()

1
_config.yml Normal file
View File

@@ -0,0 +1 @@
theme: jekyll-theme-slate

View File

@@ -1,7 +1,7 @@
cmake_minimum_required (VERSION 3.4)
set (BARRIER_VERSION_MAJOR 2)
set (BARRIER_VERSION_MINOR 0)
set (BARRIER_VERSION_MINOR 1)
set (BARRIER_VERSION_PATCH 0)
#
@@ -44,24 +44,24 @@ if (NOT DEFINED BARRIER_REVISION)
if (DEFINED ENV{GIT_COMMIT})
string (SUBSTRING $ENV{GIT_COMMIT} 0 8 BARRIER_REVISION)
else()
execute_process (
COMMAND git rev-parse --short=8 HEAD
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
OUTPUT_VARIABLE BARRIER_REVISION
OUTPUT_STRIP_TRAILING_WHITESPACE
)
find_program (GIT_BINARY git)
if (NOT GIT_BINARY STREQUAL "GIT_BINARY-NOTFOUND")
execute_process (
COMMAND git rev-parse --short=8 HEAD
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
OUTPUT_VARIABLE BARRIER_REVISION
OUTPUT_STRIP_TRAILING_WHITESPACE
)
endif()
endif()
endif()
if (DEFINED BARRIER_REVISION)
string(LENGTH ${BARRIER_REVISION} BARRIER_REVISION_LENGTH)
if (NOT ((BARRIER_REVISION MATCHES "^[a-f0-9]+") AND (BARRIER_REVISION_LENGTH EQUAL "8")))
message (FATAL_ERROR "BARRIER_REVISION ('${BARRIER_REVISION}') should be a short commit hash")
endif()
unset (BARRIER_REVISION_LENGTH)
else()
set (BARRIER_REVISION "0badc0de")
string(LENGTH "${BARRIER_REVISION}" BARRIER_REVISION_LENGTH)
if (NOT BARRIER_REVISION_LENGTH EQUAL 8 OR NOT BARRIER_REVISION MATCHES "^[a-f0-9]+")
set (BARRIER_REVISION "00000000")
message (WARNING "revision not found. setting to ${BARRIER_REVISION}")
endif()
unset (BARRIER_REVISION_LENGTH)
if (DEFINED ENV{BUILD_NUMBER})
set (BARRIER_BUILD_NUMBER $ENV{BUILD_NUMBER})

5
debian/changelog vendored Normal file
View File

@@ -0,0 +1,5 @@
barrier (2.1-1) unstable; urgency=low
* Initial release (Closes: #123456)
-- Debauchee Open Source Group <debauchee.oss@gmail.com> Sat, 01 Apr 2018 00:00:00 +0000

View File

@@ -18,7 +18,6 @@ Work seamlessly across Windows, macOS and Linux.
%{_bindir}/barrier
%{_bindir}/barrierc
%{_bindir}/barriers
%{_bindir}/syntool
%attr(644,-,-) %{_datarootdir}/applications/barrier.desktop
%attr(644,-,-) %{_datarootdir}/icons/hicolor/scalable/apps/barrier.svg

View File

@@ -60,8 +60,6 @@
<fire:FirewallException Id="ServerFirewallException" IgnoreFailure="yes" Name="$(var.Name)" Scope="any"/>
</File>
<File Source="$(var.BinPath)/barrierc.exe"/>
<File Source="$(var.BinPath)/syntool.exe"/>
<File Source="$(var.BinPath)/synwinhk.dll"/>
<File Source="$(var.OpenSSLBinPath)/libeay32.dll"/>
<File Source="$(var.OpenSSLBinPath)/ssleay32.dll"/>
<File Source="$(var.OpenSSLBinPath)/openssl.exe"/>

View File

@@ -1,5 +1,5 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.6.
.TH BARRIERC "1" "March 2018" "barrierc 2.0.0, protocol version 1.6" "User Commands"
.TH BARRIERC "1" "May 2018" "barrierc 2.1.0-snapshot" "User Commands"
.SH NAME
barrierc \- Barrier Keyboard/Mouse Client
.SH SYNOPSIS
@@ -59,9 +59,10 @@ display version information and exit.
.PP
Default options are marked with a *
.PP
The server address is of the form: [<hostname>][:<port>]. The hostname
must be the address or hostname of the server. The port overrides the
default port, 24800.
The server address is of the form: [<hostname>][:<port>]. The hostname
must be the address or hostname of the server. Placing brackets around
an IPv6 address is required when also specifying a port number and
optional otherwise. The default port number is 24800.
.SH COPYRIGHT
Copyright \(co 2018 Debauchee Open Source Group
.br

View File

@@ -1,5 +1,5 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.6.
.TH BARRIERS "1" "March 2018" "barriers 2.0.0, protocol version 1.6" "User Commands"
.TH BARRIERS "1" "May 2018" "barriers 2.1.0-snapshot" "User Commands"
.SH NAME
barriers \- Barrier Keyboard/Mouse Server
.SH SYNOPSIS
@@ -63,13 +63,14 @@ Default options are marked with a *
.PP
The argument for \fB\-\-address\fR is of the form: [<hostname>][:<port>]. The
hostname must be the address or hostname of an interface on the system.
The default is to listen on all interfaces. The port overrides the
default port, 24800.
Placing brackets around an IPv6 address is required when also specifying
a port number and optional otherwise. The default is to listen on all
interfaces using port number 24800.
.PP
If no configuration file pathname is provided then the first of the
following to load successfully sets the configuration:
.IP
$HOME/.barrier.conf
$HOME/.local/share/barrier/barrier.conf
\fI\,/etc/barrier.conf\/\fP
.SH COPYRIGHT
Copyright \(co 2018 Debauchee Open Source Group

View File

@@ -1,10 +1,8 @@
[Desktop Entry]
Type=Application
Version=1.0
Name=Barrier
Comment=Keyboard and mouse sharing solution
Path=/usr/bin
Exec=/usr/bin/barrier
Exec=barrier
Icon=barrier
Terminal=false
Categories=Utility;

View File

@@ -1,11 +0,0 @@
[Desktop Entry]
Type=Application
Version=1.0
Name=Barrier
Comment=Keyboard and mouse sharing solution
Path=/usr/bin
Exec=/usr/bin/barrier2
Icon=barrier
Terminal=false
Categories=Utility;
Keywords=keyboard;mouse;sharing;network;share;

View File

@@ -16,7 +16,6 @@
add_subdirectory(barrierc)
add_subdirectory(barriers)
add_subdirectory(syntool)
if (WIN32)
add_subdirectory(barrierd)

View File

@@ -1,27 +0,0 @@
# barrier -- mouse and keyboard sharing utility
# Copyright (C) 2014-2016 Symless Ltd.
#
# This package is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# found in the file LICENSE that should have accompanied this file.
#
# This package is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
file(GLOB headers "*.h")
file(GLOB sources "*.cpp")
add_executable(syntool ${sources})
target_link_libraries(syntool
synlib arch base client common io ipc mt net platform server ${libs} ${OPENSSL_LIBS})
if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
install (TARGETS syntool DESTINATION ${BARRIER_BUNDLE_BINARY_DIR})
elseif (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
install (TARGETS syntool DESTINATION bin)
endif()

View File

@@ -1,31 +0,0 @@
/*
* barrier -- mouse and keyboard sharing utility
* Copyright (C) 2014-2016 Symless Ltd.
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "barrier/ToolApp.h"
#include "arch/Arch.h"
int
main(int argc, char** argv)
{
#if SYSAPI_WIN32
// record window instance for tray icon, etc
ArchMiscWindows::setInstanceWin32(GetModuleHandle(NULL));
#endif
ToolApp app;
return app.run(argc, argv);
}

View File

@@ -22,7 +22,7 @@ add_executable (barrier WIN32
include_directories (./src)
qt5_use_modules (barrier Core Widgets Network)
target_link_libraries (barrier Qt5::Core Qt5::Widgets Qt5::Network)
target_compile_definitions (barrier PRIVATE -DBARRIER_VERSION_STAGE="${BARRIER_VERSION_STAGE}")
target_compile_definitions (barrier PRIVATE -DBARRIER_REVISION="${BARRIER_REVISION}")
@@ -45,6 +45,8 @@ if (HAVE_X11)
target_link_libraries (barrier X11)
endif()
target_link_libraries (barrier common)
if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
install (TARGETS barrier DESTINATION ${BARRIER_BUNDLE_BINARY_DIR})
elseif (${CMAKE_SYSTEM_NAME} MATCHES "Linux")

View File

@@ -25,6 +25,7 @@
#include <QtCore>
#include <QtGui>
#include <QButtonGroup>
ActionDialog::ActionDialog(QWidget* parent, ServerConfig& config, Hotkey& hotkey, Action& action) :
QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint),

View File

@@ -1,96 +0,0 @@
/*
* barrier -- mouse and keyboard sharing utility
* Copyright (C) 2015-2016 Symless Ltd.
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "CoreInterface.h"
#include "CommandProcess.h"
#include "QUtility.h"
#include <QCoreApplication>
#include <QProcess>
#include <QtGlobal>
#include <QDir>
#include <stdexcept>
static const char kCoreBinary[] = "syntool";
#ifdef Q_WS_WIN
static const char kSerialKeyFilename[] = "Barrier.subkey";
#else
static const char kSerialKeyFilename[] = ".barrier.subkey";
#endif
CoreInterface::CoreInterface()
{
}
QString CoreInterface::getProfileDir()
{
QStringList args("--get-profile-dir");
return run(args);
}
QString CoreInterface::getInstalledDir()
{
QStringList args("--get-installed-dir");
return run(args);
}
QString CoreInterface::getArch()
{
QStringList args("--get-arch");
return run(args);
}
QString CoreInterface::getSerialKeyFilePath()
{
QString filename = getProfileDir() + QDir::separator() + kSerialKeyFilename;
return filename;
}
QString CoreInterface::notifyUpdate (QString const& fromVersion,
QString const& toVersion,
QString const& serialKey) {
QStringList args("--notify-update");
QString input(fromVersion + ":" + toVersion + ":" + serialKey);
input.append("\n");
return run(args, input);
}
QString CoreInterface::notifyActivation(const QString& identity)
{
QStringList args("--notify-activation");
QString input(identity + ":" + hash(getFirstMacAddress()));
QString os= getOSInformation();
if (!os.isEmpty()) {
input.append(":").append(os);
}
input.append("\n");
return run(args, input);
}
QString CoreInterface::run(const QStringList& args, const QString& input)
{
QString program(
QCoreApplication::applicationDirPath()
+ "/" + kCoreBinary);
CommandProcess commandProcess(program, args, input);
return commandProcess.run();
}

View File

@@ -1,36 +0,0 @@
/*
* barrier -- mouse and keyboard sharing utility
* Copyright (C) 2015-2016 Symless Ltd.
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <QString>
class CoreInterface
{
public:
CoreInterface();
QString getProfileDir();
QString getInstalledDir();
QString getArch();
QString getSerialKeyFilePath();
QString notifyActivation(const QString& identity);
QString notifyUpdate (QString const& fromVersion,
QString const& toVersion,
QString const& serialKey);
QString run(const QStringList& args, const QString& input = "");
};

View File

@@ -17,7 +17,7 @@
#include "Fingerprint.h"
#include "CoreInterface.h"
#include "common/DataDirectories.h"
#include <QDir>
#include <QTextStream>
@@ -125,8 +125,7 @@ void Fingerprint::persistDirectory()
QString Fingerprint::directoryPath()
{
CoreInterface coreInterface;
QString profileDir = coreInterface.getProfileDir();
auto profileDir = QString::fromStdString(DataDirectories::profile());
return QString("%1/%2")
.arg(profileDir)

View File

@@ -21,9 +21,6 @@
class Fingerprint
{
private:
Fingerprint(const QString& filename);
public:
void trust(const QString& fingerprintText, bool append = true);
bool isTrusted(const QString& fingerprintText);
@@ -32,15 +29,14 @@ public:
QString filePath() const;
bool fileExists() const;
public:
static Fingerprint local();
static Fingerprint trustedServers();
static Fingerprint trustedClients();
static QString directoryPath();
static QString localFingerprint();
static bool localFingerprintExists();
static void persistDirectory();
private:
Fingerprint(const QString& filename);
QString m_Filename;
};

View File

@@ -31,6 +31,7 @@
#include "ProcessorArch.h"
#include "SslCertificate.h"
#include "ShutdownCh.h"
#include "common/DataDirectories.h"
#include <QtCore>
#include <QtGui>
@@ -72,6 +73,8 @@ static const char* barrierIconFiles[] =
":/res/icons/16x16/barrier-transfering.png"
};
static const char* barrierLargeIcon = ":/res/icons/256x256/barrier.ico";
MainWindow::MainWindow(QSettings& settings, AppConfig& appConfig) :
m_Settings(settings),
m_AppConfig(&appConfig),
@@ -104,7 +107,7 @@ MainWindow::MainWindow(QSettings& settings, AppConfig& appConfig) :
setAttribute(Qt::WA_X11NetWmWindowTypeDialog, true);
setupUi(this);
setWindowIcon(QIcon(barrierLargeIcon));
createMenuBar();
loadSettings();
initConnections();
@@ -285,13 +288,8 @@ void MainWindow::saveSettings()
void MainWindow::setIcon(qBarrierState state)
{
QIcon icon;
icon.addFile(barrierIconFiles[state]);
setWindowIcon(icon);
if (m_pTrayIcon)
m_pTrayIcon->setIcon(icon);
m_pTrayIcon->setIcon(QIcon(barrierIconFiles[state]));
}
void MainWindow::trayActivated(QSystemTrayIcon::ActivationReason reason)
@@ -503,7 +501,7 @@ void MainWindow::startBarrier()
// launched the process (e.g. when launched with elevation). setting the
// profile dir on launch ensures it uses the same profile dir is used
// no matter how its relaunched.
args << "--profile-dir" << getProfileRootForArg();
args << "--profile-dir" << QString::fromStdString("\"" + DataDirectories::profile() + "\"");
#endif
if ((barrierType() == barrierClient && !clientArgs(args, app))
@@ -583,7 +581,7 @@ bool MainWindow::clientArgs(QStringList& args, QString& app)
if (m_pCheckBoxAutoConfig->isChecked()) {
if (m_pComboServerList->count() != 0) {
QString serverIp = m_pComboServerList->currentText();
args << serverIp + ":" + QString::number(appConfig().port());
args << "[" + serverIp + "]:" + QString::number(appConfig().port());
return true;
}
}
@@ -597,7 +595,7 @@ bool MainWindow::clientArgs(QStringList& args, QString& app)
return false;
}
args << m_pLineEditHostname->text() + ":" + QString::number(appConfig().port());
args << "[" + m_pLineEditHostname->text() + "]:" + QString::number(appConfig().port());
return true;
}
@@ -639,8 +637,10 @@ QString MainWindow::configFilename()
QString MainWindow::address()
{
QString i = appConfig().networkInterface();
return (!i.isEmpty() ? i : "") + ":" + QString::number(appConfig().port());
QString address = appConfig().networkInterface();
if (!address.isEmpty())
address = "[" + address + "]";
return address + ":" + QString::number(appConfig().port());
}
QString MainWindow::appPath(const QString& name)
@@ -1252,21 +1252,6 @@ void MainWindow::bonjourInstallFinished()
m_pCheckBoxAutoConfig->setChecked(true);
}
QString MainWindow::getProfileRootForArg()
{
CoreInterface coreInterface;
QString dir = coreInterface.getProfileDir();
// HACK: strip our app name since we're returning the root dir.
#if defined(Q_OS_WIN)
dir.replace("\\Barrier", "");
#else
dir.replace("/.barrier", "");
#endif
return QString("\"%1\"").arg(dir);
}
void MainWindow::windowStateChanged()
{
if (windowState() == Qt::WindowMinimized && appConfig().getMinimizeToTray())

View File

@@ -166,7 +166,6 @@ public slots:
bool isBonjourRunning();
void downloadBonjour();
void promptAutoConfig();
QString getProfileRootForArg();
void checkConnected(const QString& line);
void checkFingerprint(const QString& line);
void restartBarrier();

View File

@@ -1,4 +1,4 @@
/*
/*
* barrier -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd.
* Copyright (C) 2008 Volker Lanz (vl@fidra.de)

View File

@@ -23,6 +23,19 @@
#include <QtGui>
#include <QMessageBox>
static const QRegExp ValidScreenName("[a-z0-9\\._-]{,255}", Qt::CaseInsensitive);
static QString check_name_param(QString name)
{
// after internationalization happens the default name "Unnamed" might
// be translated with spaces (or other chars). let's replace the spaces
// with dashes and just give up if that doesn't pass the regexp
name.replace(' ', '-');
if (ValidScreenName.exactMatch(name))
return name;
return "";
}
ScreenSettingsDialog::ScreenSettingsDialog(QWidget* parent, Screen* pScreen) :
QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint),
Ui::ScreenSettingsDialogBase(),
@@ -30,13 +43,11 @@ ScreenSettingsDialog::ScreenSettingsDialog(QWidget* parent, Screen* pScreen) :
{
setupUi(this);
QRegExp validScreenName("[a-z0-9\\._-]{,255}", Qt::CaseInsensitive);
m_pLineEditName->setText(m_pScreen->name());
m_pLineEditName->setValidator(new QRegExpValidator(validScreenName, m_pLineEditName));
m_pLineEditName->setText(check_name_param(m_pScreen->name()));
m_pLineEditName->setValidator(new QRegExpValidator(ValidScreenName, m_pLineEditName));
m_pLineEditName->selectAll();
m_pLineEditAlias->setValidator(new QRegExpValidator(validScreenName, m_pLineEditName));
m_pLineEditAlias->setValidator(new QRegExpValidator(ValidScreenName, m_pLineEditName));
for (int i = 0; i < m_pScreen->aliases().count(); i++)
new QListWidgetItem(m_pScreen->aliases()[i], m_pListAliases);

View File

@@ -22,6 +22,7 @@
#include <QtCore>
#include <QtGui>
#include <QHeaderView>
ScreenSetupView::ScreenSetupView(QWidget* parent) :
QTableView(parent)

View File

@@ -18,7 +18,6 @@
#include "SettingsDialog.h"
#include "CoreInterface.h"
#include "BarrierLocale.h"
#include "QBarrierApplication.h"
#include "QUtility.h"

View File

@@ -23,7 +23,6 @@
#include <QDialog>
#include "ui_SettingsDialogBase.h"
#include "BarrierLocale.h"
#include "CoreInterface.h"
class AppConfig;
@@ -43,7 +42,6 @@ class SettingsDialog : public QDialog, public Ui::SettingsDialogBase
private:
AppConfig& m_appConfig;
BarrierLocale m_Locale;
CoreInterface m_CoreInterface;
private slots:
void on_m_pComboLanguage_currentIndexChanged(int index);

View File

@@ -17,7 +17,6 @@
#include "SetupWizard.h"
#include "MainWindow.h"
#include "WebClient.h"
#include "QBarrierApplication.h"
#include "QUtility.h"

View File

@@ -16,8 +16,8 @@
*/
#include "SslCertificate.h"
#include "Fingerprint.h"
#include "common/DataDirectories.h"
#include <QProcess>
#include <QDir>
@@ -37,7 +37,7 @@ static const char kConfigFile[] = "barrier.conf";
SslCertificate::SslCertificate(QObject *parent) :
QObject(parent)
{
m_ProfileDir = m_CoreInterface.getProfileDir();
m_ProfileDir = QString::fromStdString(DataDirectories::profile());
if (m_ProfileDir.isEmpty()) {
emit error(tr("Failed to get profile directory."));
}

View File

@@ -17,8 +17,6 @@
#pragma once
#include "CoreInterface.h"
#include <QObject>
class SslCertificate : public QObject
@@ -43,5 +41,4 @@ private:
private:
QString m_ProfileDir;
QString m_ToolOutput;
CoreInterface m_CoreInterface;
};

View File

@@ -1,83 +0,0 @@
/*
* barrier -- mouse and keyboard sharing utility
* Copyright (C) 2015-2016 Symless Ltd.
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "WebClient.h"
#include "QUtility.h"
#include <QProcess>
#include <QMessageBox>
#include <QCoreApplication>
#include <stdexcept>
bool
WebClient::getEdition (int& edition, QString& errorOut) {
QString responseJson = request();
/* TODO: This is horrible and should be ripped out as soon as we move
* to Qt 5. See issue #5630
*/
QRegExp resultRegex(".*\"result\".*:.*(true|false).*");
if (resultRegex.exactMatch (responseJson)) {
QString boolString = resultRegex.cap(1);
if (boolString == "true") {
QRegExp editionRegex(".*\"edition\".*:.*\"([^\"]+)\".*");
if (editionRegex.exactMatch(responseJson)) {
QString e = editionRegex.cap(1);
edition = e.toInt();
return true;
} else {
throw std::runtime_error ("Unrecognised server response.");
}
} else {
errorOut = tr("Login failed. Invalid email address or password.");
return false;
}
} else {
QRegExp errorRegex(".*\"error\".*:.*\"([^\"]+)\".*");
if (errorRegex.exactMatch (responseJson)) {
errorOut = errorRegex.cap(1).replace("\\n", "\n");
return false;
} else {
throw std::runtime_error ("Unrecognised server response.");
}
}
}
bool
WebClient::setEmail (QString email, QString& errorOut) {
if (email.isEmpty()) {
errorOut = tr("Your email address cannot be left blank.");
return false;
}
m_Email = email;
return true;
}
bool
WebClient::setPassword (QString password, QString&) {
m_Password = password;
return true;
}
QString
WebClient::request() {
QStringList args("--login-auth");
QString credentials (m_Email + ":" + hash(m_Password) + "\n");
return m_CoreInterface.run (args, credentials);
}

View File

@@ -1,49 +0,0 @@
/*
* barrier -- mouse and keyboard sharing utility
* Copyright (C) 2015-2016 Symless Ltd.
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef WEBCLIENT_H
#define WEBCLIENT_H
#include <QString>
#include <QObject>
#include "CoreInterface.h"
class QMessageBox;
class QWidget;
class QStringList;
class WebClient : public QObject
{
Q_OBJECT
public:
bool getEdition (int& edition, QString& errorOut);
bool setEmail (QString email, QString& errorOut);
bool setPassword (QString password, QString& errorOut);
signals:
void error(QString e);
private:
QString request();
QString m_Email;
QString m_Password;
CoreInterface m_CoreInterface;
};
#endif // WEBCLIENT_H

View File

@@ -40,7 +40,6 @@
#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/ArchMiscWindows.h"
# include "arch/win32/ArchMultithreadWindows.h"
@@ -54,7 +53,6 @@
#elif SYSAPI_UNIX
# include "arch/unix/ArchConsoleUnix.h"
# include "arch/unix/ArchDaemonUnix.h"
# include "arch/unix/ArchFileUnix.h"
# include "arch/unix/ArchLogUnix.h"
# if HAVE_PTHREAD
# include "arch/unix/ArchMultithreadPosix.h"
@@ -86,7 +84,6 @@ 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,

View File

@@ -1,105 +0,0 @@
/*
* barrier -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd.
* Copyright (C) 2002 Chris Schoeneman
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "common/IInterface.h"
#include "common/stdstring.h"
#include "base/String.h"
//! Interface for architecture dependent file system operations
/*!
This interface defines the file system operations required by
barrier. 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 Barrier 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 String& s) = 0;
//@}
//! Set the user's plugin directory
/*
Returns the user's plugin directory.
*/
virtual void setPluginDirectory(const String& s) = 0;
};

View File

@@ -1,163 +0,0 @@
/*
* barrier -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd.
* Copyright (C) 2002 Chris Schoeneman
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "arch/unix/ArchFileUnix.h"
#include <stdio.h>
#include <unistd.h>
#include <pwd.h>
#include <sys/types.h>
#include <cstring>
//
// 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
return "/Applications/Barrier.app/Contents/MacOS";
#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()
{
String dir;
if (!m_profileDirectory.empty()) {
dir = m_profileDirectory;
}
else {
#if WINAPI_XWINDOWS
dir = getUserDirectory().append("/.barrier");
#else
dir = getUserDirectory().append("/Library/Application Support/Barrier");
#endif
}
return dir;
}
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 String& s)
{
m_profileDirectory = s;
}
void
ArchFileUnix::setPluginDirectory(const String& s)
{
m_pluginDirectory = s;
}

View File

@@ -1,47 +0,0 @@
/*
* barrier -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd.
* Copyright (C) 2002 Chris Schoeneman
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "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 String& s);
virtual void setPluginDirectory(const String& s);
private:
String m_profileDirectory;
String m_pluginDirectory;
};

View File

@@ -113,6 +113,11 @@ ArchNetworkBSD::newSocket(EAddressFamily family, ESocketType type)
}
try {
setBlockingOnSocket(fd, false);
if (family == kINET6) {
int flag = 0;
if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &flag, sizeof(flag)) != 0)
throwError(errno);
}
}
catch (...) {
close(fd);
@@ -647,8 +652,8 @@ ArchNetworkBSD::newAnyAddr(EAddressFamily family)
switch (family) {
case kINET: {
auto* ipAddr = TYPED_ADDR(struct sockaddr_in, addr);
memset(ipAddr, 0, sizeof(struct sockaddr_in));
ipAddr->sin_family = AF_INET;
ipAddr->sin_port = 0;
ipAddr->sin_addr.s_addr = INADDR_ANY;
addr->m_len = (socklen_t)sizeof(struct sockaddr_in);
break;
@@ -656,8 +661,8 @@ ArchNetworkBSD::newAnyAddr(EAddressFamily family)
case kINET6: {
auto* ipAddr = TYPED_ADDR(struct sockaddr_in6, addr);
memset(ipAddr, 0, sizeof(struct sockaddr_in6));
ipAddr->sin6_family = AF_INET6;
ipAddr->sin6_port = 0;
memcpy(&ipAddr->sin6_addr, &in6addr_any, sizeof(in6addr_any));
addr->m_len = (socklen_t)sizeof(struct sockaddr_in6);
break;

View File

@@ -1,203 +0,0 @@
/*
* barrier -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd.
* Copyright (C) 2002 Chris Schoeneman
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "arch/win32/ArchFileWindows.h"
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
#include <shlobj.h>
#include <tchar.h>
#include <string.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()
{
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("\\Barrier");
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 String& s)
{
m_profileDirectory = s;
}
void
ArchFileWindows::setPluginDirectory(const String& s)
{
m_pluginDirectory = s;
}

View File

@@ -1,47 +0,0 @@
/*
* barrier -- mouse and keyboard sharing utility
* Copyright (C) 2012-2016 Symless Ltd.
* Copyright (C) 2002 Chris Schoeneman
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "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 String& s);
virtual void setPluginDirectory(const String& s);
private:
String m_profileDirectory;
String m_pluginDirectory;
};

View File

@@ -213,10 +213,10 @@ ArchNetworkWinsock::newSocket(EAddressFamily family, ESocketType type)
}
try {
setBlockingOnSocket(fd, false);
BOOL flag = 0;
int size = sizeof(flag);
if (setsockopt_winsock(fd, IPPROTO_IPV6, IPV6_V6ONLY, &flag, size) == SOCKET_ERROR) {
throwError(getsockerror_winsock());
if (family == kINET6) {
int flag = 0;
if (setsockopt_winsock(fd, IPPROTO_IPV6, IPV6_V6ONLY, &flag, sizeof(flag)) == SOCKET_ERROR)
throwError(getsockerror_winsock());
}
}
catch (...) {
@@ -685,8 +685,8 @@ ArchNetworkWinsock::newAnyAddr(EAddressFamily family)
case kINET: {
addr = ArchNetAddressImpl::alloc(sizeof(struct sockaddr_in));
auto* ipAddr = TYPED_ADDR(struct sockaddr_in, addr);
memset(ipAddr, 0, sizeof(struct sockaddr_in));
ipAddr->sin_family = AF_INET;
ipAddr->sin_port = 0;
ipAddr->sin_addr.s_addr = INADDR_ANY;
break;
}
@@ -694,8 +694,8 @@ ArchNetworkWinsock::newAnyAddr(EAddressFamily family)
case kINET6: {
addr = ArchNetAddressImpl::alloc(sizeof(struct sockaddr_in6));
auto* ipAddr = TYPED_ADDR(struct sockaddr_in6, addr);
memset(ipAddr, 0, sizeof(struct sockaddr_in6));
ipAddr->sin6_family = AF_INET6;
ipAddr->sin6_port = 0;
memcpy(&ipAddr->sin6_addr, &in6addr_any, sizeof(in6addr_any));
break;
}

View File

@@ -21,9 +21,7 @@
#include "base/Log.h"
#include "common/Version.h"
#include "barrier/protocol_types.h"
#include "arch/Arch.h"
#include "base/XBase.h"
#include "arch/XArch.h"
#include "base/log_outputters.h"
#include "barrier/XBarrier.h"
#include "barrier/ArgsBase.h"
@@ -32,9 +30,9 @@
#include "ipc/IpcMessage.h"
#include "ipc/Ipc.h"
#include "base/EventQueue.h"
#include "common/DataDirectories.h"
#if SYSAPI_WIN32
#include "arch/win32/ArchMiscWindows.h"
#include "base/IEventQueue.h"
#include "base/TMethodJob.h"
#endif
@@ -81,18 +79,9 @@ App::~App()
void
App::version()
{
char buffer[500];
sprintf(
buffer,
"%s %s, protocol version %d.%d\n%s",
argsBase().m_pname,
kVersion,
kProtocolMajorVersion,
kProtocolMinorVersion,
kCopyright
);
std::cout << buffer << std::endl;
std::cout << argsBase().m_exename << " " << kVersion << std::endl;
std::cout <<"Protocol version " << kProtocolMajorVersion << "." << kProtocolMinorVersion << std::endl;
std::cout << kCopyright << std::endl;
}
int
@@ -175,13 +164,12 @@ App::initApp(int argc, const char** argv)
// parse command line
parseArgs(argc, argv);
ARCH->setProfileDirectory(argsBase().m_profileDirectory);
ARCH->setPluginDirectory(argsBase().m_pluginDirectory);
DataDirectories::profile(argsBase().m_profileDirectory);
// set log filter
if (!CLOG->setFilter(argsBase().m_logFilter)) {
LOG((CLOG_PRINT "%s: unrecognized log level `%s'" BYE,
argsBase().m_pname, argsBase().m_logFilter, argsBase().m_pname));
argsBase().m_exename.c_str(), argsBase().m_logFilter, argsBase().m_exename.c_str()));
m_bye(kExitArgs);
}
loggingFilterWarning();

View File

@@ -21,10 +21,10 @@
#include "barrier/App.h"
#include "barrier/ServerArgs.h"
#include "barrier/ClientArgs.h"
#include "barrier/ToolArgs.h"
#include "barrier/ArgsBase.h"
#include "base/Log.h"
#include "base/String.h"
#include "common/PathUtilities.h"
#ifdef WINAPI_MSWINDOWS
#include <VersionHelpers.h>
@@ -62,7 +62,7 @@ ArgParser::parseServerArgs(ServerArgs& args, int argc, const char* const* argv)
args.m_configFile = argv[++i];
}
else {
LOG((CLOG_PRINT "%s: unrecognized option `%s'" BYE, args.m_pname, argv[i], args.m_pname));
LOG((CLOG_PRINT "%s: unrecognized option `%s'" BYE, args.m_exename.c_str(), argv[i], args.m_exename.c_str()));
return false;
}
}
@@ -107,7 +107,7 @@ ArgParser::parseClientArgs(ClientArgs& args, int argc, const char* const* argv)
return true;
}
LOG((CLOG_PRINT "%s: unrecognized option `%s'" BYE, args.m_pname, argv[i], args.m_pname));
LOG((CLOG_PRINT "%s: unrecognized option `%s'" BYE, args.m_exename.c_str(), argv[i], args.m_exename.c_str()));
return false;
}
}
@@ -118,7 +118,7 @@ ArgParser::parseClientArgs(ClientArgs& args, int argc, const char* const* argv)
// exactly one non-option argument (server-address)
if (i == argc) {
LOG((CLOG_PRINT "%s: a server address or name is required" BYE,
args.m_pname, args.m_pname));
args.m_exename.c_str(), args.m_exename.c_str()));
return false;
}
@@ -171,46 +171,6 @@ ArgParser::parsePlatformArg(ArgsBase& argsBase, const int& argc, const char* con
#endif
}
bool
ArgParser::parseToolArgs(ToolArgs& args, int argc, const char* const* argv)
{
for (int i = 1; i < argc; ++i) {
if (isArg(i, argc, argv, NULL, "--get-active-desktop", 0)) {
args.m_printActiveDesktopName = true;
return true;
}
else if (isArg(i, argc, argv, NULL, "--login-auth", 0)) {
args.m_loginAuthenticate = true;
return true;
}
else if (isArg(i, argc, argv, NULL, "--get-installed-dir", 0)) {
args.m_getInstalledDir = true;
return true;
}
else if (isArg(i, argc, argv, NULL, "--get-profile-dir", 0)) {
args.m_getProfileDir = true;
return true;
}
else if (isArg(i, argc, argv, NULL, "--get-arch", 0)) {
args.m_getArch = true;
return true;
}
else if (isArg(i, argc, argv, NULL, "--notify-activation", 0)) {
args.m_notifyActivation = true;
return true;
}
else if (isArg(i, argc, argv, NULL, "--notify-update", 0)) {
args.m_notifyUpdate = true;
return true;
}
else {
return false;
}
}
return false;
}
bool
ArgParser::parseGenericArgs(int argc, const char* const* argv, int& i)
{
@@ -353,7 +313,7 @@ ArgParser::isArg(
// match. check args left.
if (argi + minRequiredParameters >= argc) {
LOG((CLOG_PRINT "%s: missing arguments for `%s'" BYE,
argsBase().m_pname, argv[argi], argsBase().m_pname));
argsBase().m_exename.c_str(), argv[argi], argsBase().m_exename.c_str()));
argsBase().m_shouldExit = true;
return false;
}
@@ -496,7 +456,7 @@ void
ArgParser::updateCommonArgs(const char* const* argv)
{
argsBase().m_name = ARCH->getHostName();
argsBase().m_pname = ARCH->getBasename(argv[0]);
argsBase().m_exename = PathUtilities::basename(argv[0]);
}
bool
@@ -510,7 +470,7 @@ ArgParser::checkUnexpectedArgs()
LOG((CLOG_ERR
"the --daemon argument is not supported on windows. "
"instead, install %s as a service (--service install)",
argsBase().m_pname));
argsBase().m_exename.c_str()));
return true;
}
#endif

View File

@@ -22,7 +22,6 @@
class ServerArgs;
class ClientArgs;
class ToolArgs;
class ArgsBase;
class App;
@@ -34,7 +33,6 @@ public:
bool parseServerArgs(ServerArgs& args, int argc, const char* const* argv);
bool parseClientArgs(ClientArgs& args, int argc, const char* const* argv);
bool parsePlatformArg(ArgsBase& argsBase, const int& argc, const char* const* argv, int& i);
bool parseToolArgs(ToolArgs& args, int argc, const char* const* argv);
bool parseGenericArgs(int argc, const char* const* argv, int& i);
bool parseDeprecatedArgs(int argc, const char* const* argv, int& i);
void setArgsBase(ArgsBase& argsBase) { m_argsBase = &argsBase; }

View File

@@ -33,7 +33,6 @@ m_disableXInitThreads(false),
m_backend(false),
m_restartable(true),
m_noHooks(false),
m_pname(NULL),
m_logFilter(NULL),
m_logFile(NULL),
m_display(NULL),

View File

@@ -30,7 +30,7 @@ public:
bool m_backend;
bool m_restartable;
bool m_noHooks;
const char* m_pname;
std::string m_exename;
const char* m_logFilter;
const char* m_logFile;
const char* m_display;

View File

@@ -40,10 +40,7 @@
#include "base/TMethodJob.h"
#include "base/Log.h"
#include "common/Version.h"
#if SYSAPI_WIN32
#include "arch/win32/ArchMiscWindows.h"
#endif
#include "common/PathUtilities.h"
#if WINAPI_MSWINDOWS
#include "platform/MSWindowsScreen.h"
@@ -98,7 +95,7 @@ ClientApp::parseArgs(int argc, const char* const* argv)
// Priddy.
if (!args().m_restartable || e.getError() == XSocketAddress::kBadPort) {
LOG((CLOG_PRINT "%s: %s" BYE,
args().m_pname, e.what(), args().m_pname));
args().m_exename.c_str(), e.what(), args().m_exename.c_str()));
m_bye(kExitFailed);
}
}
@@ -123,7 +120,7 @@ ClientApp::help()
std::ostringstream buffer;
buffer << "Start the barrier client and connect to a remote server component." << std::endl
<< std::endl
<< "Usage: " << args().m_pname << " [--yscroll <delta>]" << WINAPI_ARG << HELP_SYS_ARGS
<< "Usage: " << args().m_exename << " [--yscroll <delta>]" << WINAPI_ARG << HELP_SYS_ARGS
<< HELP_COMMON_ARGS << " <server-address>" << std::endl
<< std::endl
<< "Options:" << std::endl
@@ -134,9 +131,10 @@ ClientApp::help()
<< std::endl
<< "Default options are marked with a *" << std::endl
<< std::endl
<< "The server address is of the form: [<hostname>][:<port>]. The hostname" << std::endl
<< "must be the address or hostname of the server. The port overrides the" << std::endl
<< "default port, " << kDefaultPort << "." << std::endl;
<< "The server address is of the form: [<hostname>][:<port>]. The hostname" << std::endl
<< "must be the address or hostname of the server. Placing brackets around" << std::endl
<< "an IPv6 address is required when also specifying a port number and " << std::endl
<< "optional otherwise. The default port number is " << kDefaultPort << "." << std::endl;
LOG((CLOG_PRINT "%s", buffer.str().c_str()));
}
@@ -519,7 +517,7 @@ ClientApp::runInner(int argc, char** argv, ILogOutputter* outputter, StartupFunc
{
// general initialization
m_serverAddress = new NetworkAddress;
args().m_pname = ARCH->getBasename(argv[0]);
args().m_exename = PathUtilities::basename(argv[0]);
// install caller's output filter
if (outputter != NULL) {

View File

@@ -39,6 +39,8 @@
#include "base/Log.h"
#include "base/TMethodEventJob.h"
#include "common/Version.h"
#include "common/DataDirectories.h"
#include "common/PathUtilities.h"
#if SYSAPI_WIN32
#include "arch/win32/ArchMiscWindows.h"
@@ -99,7 +101,7 @@ ServerApp::parseArgs(int argc, const char* const* argv)
}
catch (XSocketAddress& e) {
LOG((CLOG_PRINT "%s: %s" BYE,
args().m_pname, e.what(), args().m_pname));
args().m_exename.c_str(), e.what(), args().m_exename.c_str()));
m_bye(kExitArgs);
}
}
@@ -124,7 +126,7 @@ ServerApp::help()
std::ostringstream buffer;
buffer << "Start the barrier server component." << std::endl
<< std::endl
<< "Usage: " << args().m_pname
<< "Usage: " << args().m_exename
<< " [--address <address>]"
<< " [--config <pathname>]"
<< WINAPI_ARGS << HELP_SYS_ARGS << HELP_COMMON_ARGS << std::endl
@@ -137,13 +139,14 @@ ServerApp::help()
<< std::endl
<< "The argument for --address is of the form: [<hostname>][:<port>]. The" << std::endl
<< "hostname must be the address or hostname of an interface on the system." << std::endl
<< "The default is to listen on all interfaces. The port overrides the" << std::endl
<< "default port, " << kDefaultPort << "." << std::endl
<< "Placing brackets around an IPv6 address is required when also specifying " << std::endl
<< "a port number and optional otherwise. The default is to listen on all" << std::endl
<< "interfaces using port number " << kDefaultPort << "." << std::endl
<< std::endl
<< "If no configuration file pathname is provided then the first of the" << std::endl
<< "following to load successfully sets the configuration:" << std::endl
<< " $HOME/" << USR_CONFIG_NAME << std::endl
<< " " << ARCH->concatPath(ARCH->getSystemDirectory(), SYS_CONFIG_NAME) << std::endl;
<< " " << PathUtilities::concat(DataDirectories::profile(), SYS_CONFIG_NAME) << std::endl
<< " " << PathUtilities::concat(DataDirectories::systemconfig(), SYS_CONFIG_NAME) << std::endl;
LOG((CLOG_PRINT "%s", buffer.str().c_str()));
}
@@ -180,11 +183,10 @@ ServerApp::loadConfig()
// load the default configuration if no explicit file given
else {
// get the user's home directory
String path = ARCH->getUserDirectory();
String path = DataDirectories::profile();
if (!path.empty()) {
// complete path
path = ARCH->concatPath(path, USR_CONFIG_NAME);
path = PathUtilities::concat(path, USR_CONFIG_NAME);
// now try loading the user's configuration
if (loadConfig(path)) {
@@ -194,9 +196,9 @@ ServerApp::loadConfig()
}
if (!loaded) {
// try the system-wide config file
path = ARCH->getSystemDirectory();
path = DataDirectories::systemconfig();
if (!path.empty()) {
path = ARCH->concatPath(path, SYS_CONFIG_NAME);
path = PathUtilities::concat(path, SYS_CONFIG_NAME);
if (loadConfig(path)) {
loaded = true;
args().m_configFile = path;
@@ -206,7 +208,7 @@ ServerApp::loadConfig()
}
if (!loaded) {
LOG((CLOG_PRINT "%s: no configuration available", args().m_pname));
LOG((CLOG_PRINT "%s: no configuration available", args().m_exename.c_str()));
m_bye(kExitConfig);
}
}
@@ -505,6 +507,16 @@ ServerApp::openServerScreen()
return screen;
}
static const char* const family_string(IArchNetwork::EAddressFamily family)
{
if (family == IArchNetwork::kINET)
return "IPv4";
if (family == IArchNetwork::kINET6)
// assume IPv6 sockets are setup to support IPv4 traffic as well
return "IPv4/IPv6";
return "Unknown";
}
bool
ServerApp::startServer()
{
@@ -530,13 +542,15 @@ ServerApp::startServer()
double retryTime;
ClientListener* listener = NULL;
try {
listener = openClientListener(args().m_config->getBarrierAddress());
auto listenAddress = args().m_config->getBarrierAddress();
auto family = family_string(ARCH->getAddrFamily(listenAddress.getAddress()));
listener = openClientListener(listenAddress);
m_server = openServer(*args().m_config, m_primaryClient);
listener->setServer(m_server);
m_server->setListener(listener);
m_listener = listener;
updateStatus();
LOG((CLOG_NOTE "started server, waiting for clients"));
LOG((CLOG_NOTE "started server (%s), waiting for clients", family));
m_serverState = kStarted;
return true;
}
@@ -779,7 +793,7 @@ ServerApp::runInner(int argc, char** argv, ILogOutputter* outputter, StartupFunc
// general initialization
m_barrierAddress = new NetworkAddress;
args().m_config = new Config(m_events);
args().m_pname = ARCH->getBasename(argv[0]);
args().m_exename = PathUtilities::basename(argv[0]);
// install caller's output filter
if (outputter != NULL) {

View File

@@ -1,205 +0,0 @@
/*
* barrier -- mouse and keyboard sharing utility
* Copyright (C) 2014-2016 Symless Ltd.
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "barrier/ToolApp.h"
#include "barrier/ArgParser.h"
#include "arch/Arch.h"
#include "base/Log.h"
#include "base/String.h"
#include <iostream>
#include <sstream>
#if SYSAPI_WIN32
#include "platform/MSWindowsSession.h"
#endif
#define JSON_URL "https://symless.com/account/json/"
enum {
kErrorOk,
kErrorArgs,
kErrorException,
kErrorUnknown
};
UInt32
ToolApp::run(int argc, char** argv)
{
if (argc <= 1) {
std::cerr << "no args" << std::endl;
return kErrorArgs;
}
try {
ArgParser argParser(this);
bool result = argParser.parseToolArgs(m_args, argc, argv);
if (!result) {
m_bye(kExitArgs);
}
if (m_args.m_printActiveDesktopName) {
#if SYSAPI_WIN32
MSWindowsSession session;
String name = session.getActiveDesktopName();
if (name.empty()) {
LOG((CLOG_CRIT "failed to get active desktop name"));
return kExitFailed;
}
else {
String output = barrier::string::sprintf("activeDesktop:%s", name.c_str());
LOG((CLOG_INFO "%s", output.c_str()));
}
#endif
}
else if (m_args.m_loginAuthenticate) {
loginAuth();
}
else if (m_args.m_getInstalledDir) {
std::cout << ARCH->getInstalledDirectory() << std::endl;
}
else if (m_args.m_getProfileDir) {
std::cout << ARCH->getProfileDirectory() << std::endl;
}
else if (m_args.m_getArch) {
std::cout << ARCH->getPlatformName() << std::endl;
}
else if (m_args.m_notifyUpdate) {
notifyUpdate();
}
else if (m_args.m_notifyActivation) {
notifyActivation();
}
else {
throw XBarrier("Nothing to do");
}
}
catch (std::exception& e) {
LOG((CLOG_CRIT "An error occurred: %s\n", e.what()));
return kExitFailed;
}
catch (...) {
LOG((CLOG_CRIT "An unknown error occurred.\n"));
return kExitFailed;
}
#if WINAPI_XWINDOWS
// HACK: avoid sigsegv on linux
m_bye(kErrorOk);
#endif
return kErrorOk;
}
void
ToolApp::help()
{
}
void
ToolApp::loginAuth()
{
String credentials;
std::cin >> credentials;
std::vector<String> parts = barrier::string::splitString(credentials, ':');
size_t count = parts.size();
if (count == 2 ) {
String email = parts[0];
String password = parts[1];
std::stringstream ss;
ss << JSON_URL << "auth/";
ss << "?email=" << ARCH->internet().urlEncode(email);
ss << "&password=" << password;
std::cout << ARCH->internet().get(ss.str()) << std::endl;
}
else {
throw XBarrier("Invalid credentials.");
}
}
void
ToolApp::notifyUpdate()
{
String data;
std::cin >> data;
std::vector<String> parts = barrier::string::splitString(data, ':');
size_t count = parts.size();
if (count == 3) {
std::stringstream ss;
ss << JSON_URL << "notify/update";
ss << "?from=" << parts[0];
ss << "&to=" << parts[1];
std::cout << ARCH->internet().get(ss.str()) << std::endl;
}
else {
throw XBarrier("Invalid update data.");
}
}
void
ToolApp::notifyActivation()
{
String info;
std::cin >> info;
std::vector<String> parts = barrier::string::splitString(info, ':');
size_t count = parts.size();
if (count == 3 || count == 4) {
String action = parts[0];
String identity = parts[1];
String macHash = parts[2];
String os;
if (count == 4) {
os = parts[3];
}
else {
os = ARCH->getOSName();
}
std::stringstream ss;
ss << JSON_URL << "notify/";
ss << "?action=" << action;
ss << "&identity=" << ARCH->internet().urlEncode(identity);
ss << "&mac=" << ARCH->internet().urlEncode(macHash);
ss << "&os=" << ARCH->internet().urlEncode(ARCH->getOSName());
ss << "&arch=" << ARCH->internet().urlEncode(ARCH->getPlatformName());
try {
std::cout << ARCH->internet().get(ss.str()) << std::endl;
}
catch (std::exception& e) {
LOG((CLOG_NOTE "An error occurred during notification: %s\n", e.what()));
}
catch (...) {
LOG((CLOG_NOTE "An unknown error occurred during notification.\n"));
}
}
else {
LOG((CLOG_NOTE "notification failed"));
}
}

View File

@@ -1,37 +0,0 @@
/*
* barrier -- mouse and keyboard sharing utility
* Copyright (C) 2014-2016 Symless Ltd.
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "barrier/App.h"
#include "barrier/ToolArgs.h"
#include "common/basic_types.h"
class ToolApp : public MinimalApp
{
public:
UInt32 run(int argc, char** argv);
void help();
private:
void loginAuth();
void notifyActivation();
void notifyUpdate();
private:
ToolArgs m_args;
};

View File

@@ -1,29 +0,0 @@
/*
* barrier -- mouse and keyboard sharing utility
* Copyright (C) 2014-2016 Symless Ltd.
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "barrier/ToolArgs.h"
ToolArgs::ToolArgs() :
m_printActiveDesktopName(false),
m_loginAuthenticate(false),
m_getInstalledDir(false),
m_getProfileDir(false),
m_getArch(false),
m_notifyActivation(false),
m_notifyUpdate(false)
{
}

View File

@@ -1,34 +0,0 @@
/*
* barrier -- mouse and keyboard sharing utility
* Copyright (C) 2014-2016 Symless Ltd.
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "base/String.h"
class ToolArgs {
public:
ToolArgs();
public:
bool m_printActiveDesktopName;
bool m_loginAuthenticate;
bool m_getInstalledDir;
bool m_getProfileDir;
bool m_getArch;
bool m_notifyActivation;
bool m_notifyUpdate;
};

View File

@@ -33,6 +33,7 @@
#include "base/EventQueue.h"
#include "base/log_outputters.h"
#include "base/Log.h"
#include "common/DataDirectories.h"
#include "arch/win32/ArchMiscWindows.h"
#include "arch/win32/XArchWindows.h"
@@ -41,6 +42,7 @@
#include "platform/MSWindowsDebugOutputter.h"
#include "platform/MSWindowsWatchdog.h"
#include "platform/MSWindowsEventQueueBuffer.h"
#include "platform/MSWindowsUtil.h"
#define WIN32_LEAN_AND_MEAN
#include <Windows.h>
@@ -130,8 +132,10 @@ DaemonApp::run(int argc, char** argv)
}
if (foreground) {
// run process in foreground instead of daemonizing.
// useful for debugging.
// add a console to catch Ctrl+C and run process in foreground
// instead of daemonizing. useful for debugging.
if (IsDebuggerPresent())
AllocConsole();
mainLoop(false);
}
else {
@@ -239,14 +243,10 @@ DaemonApp::foregroundError(const char* message)
std::string
DaemonApp::logFilename()
{
string logFilename;
logFilename = ARCH->setting("LogFilename");
if (logFilename.empty()) {
logFilename = ARCH->getLogDirectory();
logFilename.append("/");
logFilename.append(LOG_FILENAME);
}
string logFilename = ARCH->setting("LogFilename");
if (logFilename.empty())
logFilename = DataDirectories::global() + "\\" + LOG_FILENAME;
MSWindowsUtil::createDirectory(logFilename, true);
return logFilename;
}

View File

@@ -81,6 +81,7 @@ ServerProxy::~ServerProxy()
setKeepAliveRate(-1.0);
m_events->removeHandler(m_events->forIStream().inputReady(),
m_stream->getEventTarget());
m_events->removeHandler(m_events->forClipboard().clipboardSending(), this);
}
void

View File

@@ -17,8 +17,24 @@
file(GLOB headers "*.h")
file(GLOB sources "*.cpp")
if (WIN32)
file(GLOB arch_headers "win32/*.h")
file(GLOB arch_sources "win32/*.cpp")
elseif (UNIX)
file(GLOB arch_headers "unix/*.h")
file(GLOB arch_sources "unix/*.cpp")
endif()
list(APPEND headers ${arch_headers})
list(APPEND sources ${arch_sources})
if (BARRIER_ADD_HEADERS)
list(APPEND sources ${headers})
endif()
add_library(common STATIC ${sources})
if (HAVE_GETPWUID_R)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DHAVE_GETPWUID_R=1")
endif()

View File

@@ -0,0 +1,41 @@
/*
* barrier -- mouse and keyboard sharing utility
* Copyright (C) 2018 Debauchee Open Source Group
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <string>
class DataDirectories
{
public:
static const std::string& profile();
static const std::string& profile(const std::string& path);
static const std::string& global();
static const std::string& global(const std::string& path);
static const std::string& systemconfig();
static const std::string& systemconfig(const std::string& path);
private:
// static class
DataDirectories() {}
static std::string _profile;
static std::string _global;
static std::string _systemconfig;
};

View File

@@ -0,0 +1,23 @@
/*
* barrier -- mouse and keyboard sharing utility
* Copyright (C) 2018 Debauchee Open Source Group
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "DataDirectories.h"
// static member
std::string DataDirectories::_profile;
std::string DataDirectories::_global;
std::string DataDirectories::_systemconfig;

View File

@@ -0,0 +1,75 @@
/*
* barrier -- mouse and keyboard sharing utility
* Copyright (C) 2018 Debauchee Open Source Group
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/*
These functions cover the vast majority of cases for different paths across
windows and unixes. They are not, however, fullproof and probably don't cover
fringe cases very well. The library below might be used as an alternative if
these implementations prove to be insufficient. As the library's readme states
it is simply a temporary band-aid until std::filesystem is integrated (C++17
has it in std::experimental) and this class should also be treated as such.
https://github.com/wjakob/filesystem/
*/
#include "PathUtilities.h"
// keep the default platform delimiter as the first in the list
#ifdef _WIN32
static const char *Delimiters = "\\/";
#else
static const char *Delimiters = "/";
#endif
static const char DefaultDelimiter = Delimiters[0];
std::string PathUtilities::basename(const std::string& path)
{
return path.substr(path.find_last_of(Delimiters) + 1);
}
std::string PathUtilities::concat(const std::string& left, const std::string& right)
{
// although npos is usually (-1) we can't count on that so handle it explicitly
auto leftEnd = left.find_last_not_of(Delimiters);
if (leftEnd == std::string::npos)
leftEnd = 0;
else
++leftEnd;
auto rightStart = right.find_first_not_of(Delimiters, 0);
if (rightStart == std::string::npos) {
// both left/right are empty
if (left.size() == 0 && right.size() == 0)
return "";
// right is full of delims, left is okay
if (leftEnd > 0)
return left.substr(0, leftEnd);
// both left/right useless but at least one has delims
return std::string(1, DefaultDelimiter);
}
if (leftEnd == 0) {
// right is okay and not prefixed with delims, left is empty
if (left.size() == 0 && rightStart == 0)
return right.substr(rightStart);
// (right is okay and prefixed with delims) OR left is full of delims
return DefaultDelimiter + right.substr(rightStart);
}
// concatenation using both left and right
return left.substr(0, leftEnd) + DefaultDelimiter + right.substr(rightStart);
}

View File

@@ -0,0 +1,31 @@
/*
* barrier -- mouse and keyboard sharing utility
* Copyright (C) 2018 Debauchee Open Source Group
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <string>
class PathUtilities
{
public:
static std::string basename(const std::string& path);
static std::string concat(const std::string& left, const std::string& right);
private:
// static class
PathUtilities() {}
};

View File

@@ -0,0 +1,114 @@
/*
* barrier -- mouse and keyboard sharing utility
* Copyright (C) 2018 Debauchee Open Source Group
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "../DataDirectories.h"
#include <unistd.h> // sysconf
#include <stdlib.h> // getenv
#include <sys/types.h> // getpwuid(_r)
#include <pwd.h> // getpwuid(_r)
const std::string ProfileSubdir = "/barrier";
static std::string pw_dir(struct passwd* pwentp)
{
if (pwentp != NULL && pwentp->pw_dir != NULL)
return pwentp->pw_dir;
return "";
}
#ifdef HAVE_GETPWUID_R
static std::string unix_home()
{
long size = -1;
#if defined(_SC_GETPW_R_SIZE_MAX)
size = sysconf(_SC_GETPW_R_SIZE_MAX);
#endif
if (size == -1)
size = BUFSIZ;
struct passwd pwent;
struct passwd* pwentp;
std::string buffer(size, 0);
getpwuid_r(getuid(), &pwent, &buffer[0], size, &pwentp);
return pw_dir(pwentp);
}
#else // not HAVE_GETPWUID_R
static std::string unix_home()
{
return pw_dir(getpwuid(getuid()));
}
#endif // HAVE_GETPWUID_R
static std::string profile_basedir()
{
#ifdef WINAPI_XWINDOWS
// linux/bsd adheres to freedesktop standards
// https://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
const char* dir = getenv("XDG_DATA_HOME");
if (dir != NULL)
return dir;
return unix_home() + "/.local/share";
#else
// macos has its own standards
// https://developer.apple.com/library/content/documentation/General/Conceptual/MOSXAppProgrammingGuide/AppRuntime/AppRuntime.html
return unix_home() + "/Library/Application Support";
#endif
}
const std::string& DataDirectories::profile()
{
if (_profile.empty())
_profile = profile_basedir() + ProfileSubdir;
return _profile;
}
const std::string& DataDirectories::profile(const std::string& path)
{
_profile = path;
return _profile;
}
const std::string& DataDirectories::global()
{
if (_global.empty())
// TODO: where on a unix system should public/global shared data go?
// as of march 2018 global() is not used for unix
_global = "/tmp";
return _global;
}
const std::string& DataDirectories::global(const std::string& path)
{
_global = path;
return _global;
}
const std::string& DataDirectories::systemconfig()
{
if (_systemconfig.empty())
_systemconfig = "/etc";
return _systemconfig;
}
const std::string& DataDirectories::systemconfig(const std::string& path)
{
_systemconfig = path;
return _systemconfig;
}

View File

@@ -0,0 +1,81 @@
/*
* barrier -- mouse and keyboard sharing utility
* Copyright (C) 2018 Debauchee Open Source Group
*
* This package is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* found in the file LICENSE that should have accompanied this file.
*
* This package is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "../DataDirectories.h"
#include <Shlobj.h>
std::string unicode_to_mb(const WCHAR* utfStr)
{
int utfLength = lstrlenW(utfStr);
int mbLength = WideCharToMultiByte(CP_UTF8, 0, utfStr, utfLength, NULL, 0, NULL, NULL);
std::string mbStr(mbLength, 0);
WideCharToMultiByte(CP_UTF8, 0, utfStr, utfLength, &mbStr[0], mbLength, NULL, NULL);
return mbStr;
}
std::string known_folder_path(const KNOWNFOLDERID& id)
{
std::string path;
WCHAR* buffer;
HRESULT result = SHGetKnownFolderPath(id, 0, NULL, &buffer);
if (result == S_OK) {
path = unicode_to_mb(buffer);
CoTaskMemFree(buffer);
}
return path;
}
const std::string& DataDirectories::profile()
{
if (_profile.empty())
_profile = known_folder_path(FOLDERID_LocalAppData) + "\\Barrier";
return _profile;
}
const std::string& DataDirectories::profile(const std::string& path)
{
_profile = path;
return _profile;
}
const std::string& DataDirectories::global()
{
if (_global.empty())
_global = known_folder_path(FOLDERID_ProgramData) + "\\Barrier";
return _global;
}
const std::string& DataDirectories::global(const std::string& path)
{
_global = path;
return _global;
}
const std::string& DataDirectories::systemconfig()
{
// systemconfig() is a special case in that it will track the current value
// of global() unless and until it is explictly set otherwise
// previously it would default to the windows folder which was horrible!
if (_systemconfig.empty())
return global();
return _systemconfig;
}
const std::string& DataDirectories::systemconfig(const std::string& path)
{
_systemconfig = path;
return _systemconfig;
}

View File

@@ -28,6 +28,45 @@
// NetworkAddress
//
static bool parse_address(const std::string& address, std::string& host, int& port)
{
/* Three cases ---
* brackets: parse inside for host, check end for port as :INTEGER. DONE
* one colon: ipv4 address with port. DONE
* otherwise: all host, no port. DONE
*
* very, very little error checking. depends on address being trimmed before call.
*
* does not override port with a default value if no port was found in address.
*/
if (address[0] == '[') {
// bracketed host possibly followed by port as :INTEGER
auto endBracket = address.find(']', 1);
if (endBracket == std::string::npos)
return false;
host = address.substr(1, endBracket - 1);
if (endBracket + 1 < address.length()) {
// port follows (or garbage)
if (address[endBracket + 1] != ':')
return false;
port = std::strtol(&address[endBracket + 2], nullptr, 10);
}
} else {
auto colon = address.find(':');
if (colon != std::string::npos && address.find(':', colon + 1) == std::string::npos) {
// one single colon, must be ipv4 with port
host = address.substr(0, colon);
port = std::strtol(&address[colon + 1], nullptr, 10);
} else {
// no colons (ipv4) or more than one colon (ipv6), both without port
host = address;
}
}
return true;
}
// name re-resolution adapted from a patch by Brent Priddy.
NetworkAddress::NetworkAddress() :
@@ -62,50 +101,9 @@ NetworkAddress::NetworkAddress(const String& hostname, int port) :
m_hostname(hostname),
m_port(port)
{
// check for port suffix
String::size_type i = m_hostname.rfind(':');
if (i != String::npos && i + 1 < m_hostname.size()) {
// found a colon. see if it looks like an IPv6 address.
bool colonNotation = false;
bool dotNotation = false;
bool doubleColon = false;
for (String::size_type j = 0; j < i; ++j) {
if (m_hostname[j] == ':') {
colonNotation = true;
dotNotation = false;
if (m_hostname[j + 1] == ':') {
doubleColon = true;
}
}
else if (m_hostname[j] == '.' && colonNotation) {
dotNotation = true;
}
}
// port suffix is ambiguous with IPv6 notation if there's
// a double colon and the end of the address is not in dot
// notation. in that case we assume it's not a port suffix.
// the user can replace the double colon with zeros to
// disambiguate.
if ((!doubleColon || dotNotation) && !colonNotation) {
// parse port from hostname
char* end;
const char* chostname = m_hostname.c_str();
long suffixPort = strtol(chostname + i + 1, &end, 10);
if (end == chostname + i + 1 || *end != '\0') {
throw XSocketAddress(XSocketAddress::kBadPort,
m_hostname, m_port);
}
// trim port from hostname
m_hostname.erase(i);
// save port
m_port = static_cast<int>(suffixPort);
}
}
// check port number
if (!parse_address(hostname, m_hostname, m_port))
throw XSocketAddress(XSocketAddress::kUnknown,
m_hostname, m_port);
checkPort();
}
@@ -145,7 +143,7 @@ NetworkAddress::resolve()
// if hostname is empty then use wildcard address otherwise look
// up the name.
if (m_hostname.empty()) {
m_address = ARCH->newAnyAddr(IArchNetwork::kINET);
m_address = ARCH->newAnyAddr(IArchNetwork::kINET6);
}
else {
m_address = ARCH->nameToAddr(m_hostname);

View File

@@ -22,6 +22,7 @@
#include "net/SocketMultiplexer.h"
#include "net/TSocketMultiplexerMethodJob.h"
#include "arch/XArch.h"
#include "common/DataDirectories.h"
static const char s_certificateDir[] = { "SSL" };
static const char s_certificateFilename[] = { "Barrier.pem" };
@@ -54,7 +55,7 @@ SecureListenSocket::accept()
}
String certificateFilename = barrier::string::sprintf("%s/%s/%s",
ARCH->getProfileDirectory().c_str(),
DataDirectories::profile().c_str(),
s_certificateDir,
s_certificateFilename);

View File

@@ -23,6 +23,7 @@
#include "mt/Lock.h"
#include "arch/XArch.h"
#include "base/Log.h"
#include "common/DataDirectories.h"
#include <openssl/ssl.h>
#include <openssl/err.h>
@@ -699,7 +700,7 @@ SecureSocket::verifyCertFingerprint()
String trustedServersFilename;
trustedServersFilename = barrier::string::sprintf(
"%s/%s/%s",
ARCH->getProfileDirectory().c_str(),
DataDirectories::profile().c_str(),
kFingerprintDirName,
kFingerprintTrustedServersFilename);

View File

@@ -22,6 +22,7 @@
#include "platform/ImmuneKeysReader.h"
#include "barrier/protocol_types.h"
#include "barrier/XScreen.h"
#include "common/DataDirectories.h"
#include "base/Log.h"
//
@@ -52,7 +53,7 @@ static BYTE g_keyState[256] = { 0 };
static bool g_fakeServerInput = false;
static std::vector<DWORD> g_immuneKeys;
static const std::string ImmuneKeysPath = ArchFileWindows().getProfileDirectory() + "\\ImmuneKeys.txt";
static const std::string ImmuneKeysPath = DataDirectories::profile() + "\\ImmuneKeys.txt";
static std::vector<DWORD> immune_keys_list()
{

View File

@@ -62,3 +62,23 @@ MSWindowsUtil::getErrorString(HINSTANCE hinstance, DWORD error, DWORD id)
return result;
}
}
/*
This is a quick and dirty iterative CreateDirectory() wrapper that does zero
error checking. A much better cross-platform option exists in C++17 via
std::filesystem. If/when the project is updated to use 17 this function should
absolutley be replaced!
*/
void
MSWindowsUtil::createDirectory(const std::string& path, bool stripLast)
{
// create parent directories
for (auto pos = path.find_first_of('\\'); pos != std::string::npos; pos = path.find_first_of('\\', pos + 1))
CreateDirectory(path.substr(0, pos).c_str(), NULL);
if (!stripLast)
// create innermost directory
CreateDirectory(path.c_str(), NULL);
}

View File

@@ -37,4 +37,11 @@ public:
found return the string for \p id, replacing ${1} with \p error.
*/
static String getErrorString(HINSTANCE, DWORD error, DWORD id);
//! Create directory
/*!
Create directory \p recursively optionally stripping the last component
(presumably the filename) if \p is set.
*/
static void createDirectory(const std::string& path, bool stripLast = false);
};

View File

@@ -44,7 +44,20 @@ enum {
typedef VOID (WINAPI *SendSas)(BOOL asUser);
const char g_activeDesktop[] = {"activeDesktop:"};
std::string activeDesktopName()
{
const std::size_t BufferLength = 1024;
std::string name;
HDESK desk = OpenInputDesktop(0, FALSE, GENERIC_READ);
if (desk != NULL) {
TCHAR buffer[BufferLength];
if (GetUserObjectInformation(desk, UOI_NAME, buffer, BufferLength - 1, NULL) == TRUE)
name = buffer;
CloseDesktop(desk);
}
LOG((CLOG_DEBUG "found desktop name: %.64s", name.c_str()));
return name;
}
MSWindowsWatchdog::MSWindowsWatchdog(
bool daemonized,
@@ -64,22 +77,8 @@ MSWindowsWatchdog::MSWindowsWatchdog(
m_processRunning(false),
m_fileLogOutputter(NULL),
m_autoElevated(false),
m_ready(false),
m_daemonized(daemonized)
{
m_mutex = ARCH->newMutex();
m_condVar = ARCH->newCondVar();
}
MSWindowsWatchdog::~MSWindowsWatchdog()
{
if (m_condVar != NULL) {
ARCH->closeCondVar(m_condVar);
}
if (m_mutex != NULL) {
ARCH->closeMutex(m_mutex);
}
}
void
@@ -288,12 +287,9 @@ MSWindowsWatchdog::startProcess()
if (!m_daemonized) {
createRet = doStartProcessAsSelf(m_command);
} else {
SECURITY_ATTRIBUTES sa;
ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES));
m_autoElevated = activeDesktopName() != "Default";
getActiveDesktop(&sa);
ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES));
SECURITY_ATTRIBUTES sa{ 0 };
HANDLE userToken = getUserToken(&sa);
m_elevateProcess = m_autoElevated ? m_autoElevated : m_elevateProcess;
m_autoElevated = false;
@@ -408,7 +404,7 @@ MSWindowsWatchdog::getCommand() const
}
// seems like a fairly convoluted way to get the process name
const char* launchName = App::instance().argsBase().m_pname;
const char* launchName = App::instance().argsBase().m_exename.c_str();
std::string args = ARCH->commandLine();
// build up a full command line
@@ -444,11 +440,7 @@ MSWindowsWatchdog::outputLoop(void*)
}
else {
buffer[bytesRead] = '\0';
testOutput(buffer);
m_ipcLogOutputter.write(kINFO, buffer);
if (m_fileLogOutputter != NULL) {
m_fileLogOutputter->write(kINFO, buffer);
}
@@ -549,63 +541,3 @@ MSWindowsWatchdog::shutdownExistingProcesses()
CloseHandle(snapshot);
m_processRunning = false;
}
void
MSWindowsWatchdog::getActiveDesktop(LPSECURITY_ATTRIBUTES security)
{
String installedDir = ARCH->getInstalledDirectory();
if (!installedDir.empty()) {
String syntoolCommand;
syntoolCommand.append("\"").append(installedDir).append("\\").append("syntool").append("\"");
syntoolCommand.append(" --get-active-desktop");
m_session.updateActiveSession();
bool elevateProcess = m_elevateProcess;
m_elevateProcess = true;
HANDLE userToken = getUserToken(security);
m_elevateProcess = elevateProcess;
BOOL createRet = doStartProcessAsUser(syntoolCommand, userToken, security);
if (!createRet) {
DWORD rc = GetLastError();
RevertToSelf();
}
else {
LOG((CLOG_DEBUG "launched syntool to check active desktop"));
}
ARCH->lockMutex(m_mutex);
int waitTime = 0;
while (!m_ready) {
if (waitTime >= MAXIMUM_WAIT_TIME) {
break;
}
ARCH->waitCondVar(m_condVar, m_mutex, 1.0);
waitTime++;
}
m_ready = false;
ARCH->unlockMutex(m_mutex);
}
}
void
MSWindowsWatchdog::testOutput(String buffer)
{
// HACK: check standard output seems hacky.
size_t i = buffer.find(g_activeDesktop);
if (i != String::npos) {
size_t s = sizeof(g_activeDesktop);
String defaultDesktop("Default");
String sub = buffer.substr(i + s - 1, defaultDesktop.size());
if (sub != defaultDesktop) {
m_autoElevated = true;
}
ARCH->lockMutex(m_mutex);
m_ready = true;
ARCH->broadcastCondVar(m_condVar);
ARCH->unlockMutex(m_mutex);
}
}

View File

@@ -39,7 +39,6 @@ public:
bool autoDetectCommand,
IpcServer& ipcServer,
IpcLogOutputter& ipcLogOutputter);
virtual ~MSWindowsWatchdog();
void startAsync();
std::string getCommand() const;
@@ -58,9 +57,6 @@ private:
void startProcess();
BOOL doStartProcessAsUser(String& command, HANDLE userToken, LPSECURITY_ATTRIBUTES sa);
BOOL doStartProcessAsSelf(String& command);
void sendSas();
void getActiveDesktop(LPSECURITY_ATTRIBUTES security);
void testOutput(String buffer);
private:
Thread* m_thread;
@@ -80,9 +76,6 @@ private:
bool m_processRunning;
FileLogOutputter* m_fileLogOutputter;
bool m_autoElevated;
ArchMutex m_mutex;
ArchCond m_condVar;
bool m_ready;
bool m_daemonized;
};

View File

@@ -144,10 +144,10 @@ private:
ButtonID mapMacButtonToBarrier(UInt16) const;
// map mac scroll wheel value to a barrier scroll wheel value
SInt32 mapScrollWheelToBarrier(SInt32) const;
SInt32 mapScrollWheelToBarrier(float) const;
// map barrier scroll wheel value to a mac scroll wheel value
SInt32 mapScrollWheelFromBarrier(SInt32) const;
SInt32 mapScrollWheelFromBarrier(float) const;
// get the current scroll wheel speed
double getScrollSpeed() const;

View File

@@ -1421,7 +1421,7 @@ OSXScreen::mapMacButtonToBarrier(UInt16 macButton) const
}
SInt32
OSXScreen::mapScrollWheelToBarrier(SInt32 x) const
OSXScreen::mapScrollWheelToBarrier(float x) const
{
// return accelerated scrolling but not exponentially scaled as it is
// on the mac.
@@ -1430,7 +1430,7 @@ OSXScreen::mapScrollWheelToBarrier(SInt32 x) const
}
SInt32
OSXScreen::mapScrollWheelFromBarrier(SInt32 x) const
OSXScreen::mapScrollWheelFromBarrier(float x) const
{
// use server's acceleration with a little boost since other platforms
// take one wheel step as a larger step than the mac does.
@@ -1948,9 +1948,9 @@ OSXScreen::handleCGInputEvent(CGEventTapProxy proxy,
break;
case kCGEventScrollWheel:
screen->onMouseWheel(screen->mapScrollWheelToBarrier(
CGEventGetIntegerValueField(event, kCGScrollWheelEventDeltaAxis2)),
CGEventGetIntegerValueField(event, kCGScrollWheelEventFixedPtDeltaAxis2) / 65536.0f),
screen->mapScrollWheelToBarrier(
CGEventGetIntegerValueField(event, kCGScrollWheelEventDeltaAxis1)));
CGEventGetIntegerValueField(event, kCGScrollWheelEventFixedPtDeltaAxis1) / 65536.0f));
break;
case kCGEventKeyDown:
case kCGEventKeyUp:

View File

@@ -99,6 +99,7 @@ XWindowsScreen::XWindowsScreen(
IEventQueue* events) :
m_isPrimary(isPrimary),
m_mouseScrollDelta(mouseScrollDelta),
m_accumulatedScroll(0),
m_display(NULL),
m_root(None),
m_window(None),
@@ -865,9 +866,11 @@ XWindowsScreen::fakeMouseWheel(SInt32, SInt32 yDelta) const
return;
}
// choose button depending on rotation direction
const unsigned int xButton = mapButtonToX(static_cast<ButtonID>(
(yDelta >= 0) ? -1 : -2));
int numEvents = accumulateMouseScroll(yDelta);
// choose button depending on rotation direction
const unsigned int xButton = mapButtonToX(static_cast<ButtonID>(
(numEvents >= 0) ? -1 : -2));
if (xButton == 0) {
// If we get here, then the XServer does not support the scroll
// wheel buttons, so send PageUp/PageDown keystrokes instead.
@@ -886,20 +889,14 @@ XWindowsScreen::fakeMouseWheel(SInt32, SInt32 yDelta) const
return;
}
// now use absolute value of delta
if (yDelta < 0) {
yDelta = -yDelta;
}
if (yDelta < m_mouseScrollDelta) {
LOG((CLOG_WARN "Wheel scroll delta (%d) smaller than threshold (%d)", yDelta, m_mouseScrollDelta));
}
numEvents = std::abs(numEvents);
// send as many clicks as necessary
for (; yDelta >= m_mouseScrollDelta; yDelta -= m_mouseScrollDelta) {
for (; numEvents > 0; numEvents--) {
XTestFakeButtonEvent(m_display, xButton, True, CurrentTime);
XTestFakeButtonEvent(m_display, xButton, False, CurrentTime);
}
XFlush(m_display);
}
@@ -1643,6 +1640,15 @@ XWindowsScreen::onMouseMove(const XMotionEvent& xmotion)
}
}
int
XWindowsScreen::accumulateMouseScroll(SInt32 yDelta) const
{
m_accumulatedScroll += yDelta;
int numEvents = m_accumulatedScroll / m_mouseScrollDelta;
m_accumulatedScroll -= numEvents * m_mouseScrollDelta;
return numEvents;
}
Cursor
XWindowsScreen::createBlankCursor() const
{

View File

@@ -136,6 +136,10 @@ private:
void onMouseRelease(const XButtonEvent&);
void onMouseMove(const XMotionEvent&);
// Returns the number of scroll events needed after the current delta has
// been taken into account
int accumulateMouseScroll(SInt32 yDelta) const;
bool detectXI2();
#ifdef HAVE_XI2
void selectXIRawMotion();
@@ -172,8 +176,15 @@ private:
// true if screen is being used as a primary screen, false otherwise
bool m_isPrimary;
// The size of a smallest supported scroll event, in points
int m_mouseScrollDelta;
// Accumulates scrolls of less than m_mouseScrollDelta across multiple
// scroll events. We dispatch a scroll event whenever the accumulated scroll
// becomes larger than m_mouseScrollDelta
mutable int m_accumulatedScroll;
Display* m_display;
Window m_root;
Window m_window;