Compare commits

..

37 Commits

Author SHA1 Message Date
1e3aca0837 fix finding default address on windows 2018-08-05 13:13:33 -04:00
a352683702 Merge branch 'master' into smartzeroconf 2018-08-05 13:12:41 -04:00
a381347233 bump qt/vs versions on windows 2018-08-05 13:08:42 -04:00
73c13ab023 bump version to 2.2 2018-08-05 13:08:30 -04:00
a8d0c1620d implement wireless checking for bsd/osx 2018-07-05 19:31:34 -04:00
c9bd5c2aff weed out inactive interfaces on windows 2018-07-04 17:15:49 -04:00
b120fe4d67 only include net/if.h for bsd/osx 2018-07-04 16:18:24 -04:00
a739ce784a reinsert netinet/in.h 2018-07-04 16:04:40 -04:00
e2acbdb409 add net/if.h 2018-07-03 23:33:14 -04:00
30cce2dda2 remove netinet/in.h 2018-07-03 23:24:00 -04:00
b84202aa9a change order of headers and leave out wireless checking on osx for now 2018-07-03 23:09:00 -04:00
walker0643
6761528e0b Merge pull request #90 from debauchee/master
merge travis CI patches (and others)
2018-07-03 22:36:43 -04:00
a2b365815a add unix implementation for DefaultInterfaceIP 2018-07-03 22:28:32 -04:00
33224a1f97 drop Qt discovery of best IP address in favor of pure WINAPI method (with wireless detection) 2018-07-03 18:48:24 -04:00
5498836b6f fix formatting in last merge 2018-07-03 16:55:57 -04:00
Adrian Lucrèce Céleste
cc69299ea3 Merge pkgconfig branch into master (#86)
* use pkg-config for finding avahi include dir

* [Travis] bring up to date
2018-07-02 23:21:08 -04:00
Adrian Lucrèce Céleste
ccfa11ca7b [Travis] use container builds for linux (#85)
Things should build faster
2018-07-02 22:40:54 -04:00
walker0643
b28442ee1b Merge pull request #82 from sidneys/fix-macos-build
Use standard methods for detecting XCode installation and macOS SDK (patch by sidneys)
2018-07-02 20:43:30 -04:00
walker0643
4806441cb2 Merge pull request #84 from p12tic/osx-ci
More complete OSX config for Travis CI
2018-07-02 20:42:13 -04:00
Povilas Kanapickas
55c74e9075 travis: Add homebrew-based OSX script 2018-07-02 22:34:21 +03:00
Povilas Kanapickas
4c0690dd96 travis: Add macports-based OSX script 2018-07-02 22:33:57 +03:00
Povilas Kanapickas
af789958f0 travis: Rewrite the CI config to use platform matrix 2018-07-02 22:33:42 +03:00
Povilas Kanapickas
5467b90982 OSX: Prefer Macports over Homebrew if available 2018-07-02 22:33:42 +03:00
Povilas Kanapickas
f928c81afc OSX: Add support for building on macports 2018-07-02 22:33:21 +03:00
sidneys
39ccc4cbe6 fix(macos-build): use standard methods for detecting default XCode installation and default macOS platform SDK 2018-07-02 11:14:42 +02:00
2d7818fe49 better discovery of default IP address via ZeroConf 2018-07-02 00:32:09 -04:00
2ddc81d927 rephrase language in README.md 2018-07-01 14:50: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
26 changed files with 480 additions and 89 deletions

View File

@@ -1,10 +1,34 @@
language: cpp language: cpp
before_install:
- sudo apt-get update -qq matrix:
- sudo apt-get install -qq libxtst-dev include:
- sudo apt-get install -qq qtdeclarative5-dev - os: linux
- sudo apt-get install -qq libavahi-compat-libdnssd-dev sudo: false
script: sh -x ./clean_build.sh dist: trusty
# skip install phase since we have a customized install package addons:
# creation tool for each supported platform 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 install: true

View File

@@ -63,6 +63,7 @@ if (UNIX)
include (CheckIncludeFileCXX) include (CheckIncludeFileCXX)
include (CheckSymbolExists) include (CheckSymbolExists)
include (CheckCSourceCompiles) include (CheckCSourceCompiles)
include (FindPkgConfig)
check_include_file_cxx (istream HAVE_ISTREAM) check_include_file_cxx (istream HAVE_ISTREAM)
check_include_file_cxx (ostream HAVE_OSTREAM) check_include_file_cxx (ostream HAVE_OSTREAM)
@@ -163,6 +164,12 @@ if (UNIX)
link_directories("/usr/local/lib") link_directories("/usr/local/lib")
endif() 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 (XKBlib "X11/Xlib.h;X11/XKBlib.h")
set (CMAKE_EXTRA_INCLUDE_FILES "${XKBlib};X11/extensions/Xrandr.h") set (CMAKE_EXTRA_INCLUDE_FILES "${XKBlib};X11/extensions/Xrandr.h")
check_type_size ("XRRNotifyEvent" X11_EXTENSIONS_XRANDR_H) check_type_size ("XRRNotifyEvent" X11_EXTENSIONS_XRANDR_H)
@@ -187,7 +194,7 @@ if (UNIX)
message (FATAL_ERROR "Missing header: " ${XKBlib}) message (FATAL_ERROR "Missing header: " ${XKBlib})
endif() endif()
if (NOT HAVE_DNSSD) if (BARRIER_BUILD_GUI AND NOT HAVE_DNSSD)
message (FATAL_ERROR "Missing header: dns_sd.h") message (FATAL_ERROR "Missing header: dns_sd.h")
endif() endif()
@@ -302,13 +309,28 @@ if (${CMAKE_SYSTEM_NAME} MATCHES "Windows")
${OPENSSL_ROOT}/lib/ssleay32.lib ${OPENSSL_ROOT}/lib/ssleay32.lib
) )
elseif (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") elseif (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
if (IS_DIRECTORY /opt/local)
# macports
set (OPENSSL_ROOT /opt/local)
set (OPENSSL_LIBS
${OPENSSL_ROOT}/lib/libssl.a
${OPENSSL_ROOT}/lib/libcrypto.a
z
)
elseif (IS_DIRECTORY /usr/local/opt/openssl)
# brew
set (OPENSSL_ROOT /usr/local/opt/openssl) set (OPENSSL_ROOT /usr/local/opt/openssl)
include_directories (BEFORE SYSTEM ${OPENSSL_ROOT}/include) include_directories (BEFORE SYSTEM ${OPENSSL_ROOT}/include)
set (OPENSSL_LIBS set (OPENSSL_LIBS
${OPENSSL_ROOT}/lib/libssl.a ${OPENSSL_ROOT}/lib/libssl.a
${OPENSSL_ROOT}/lib/libcrypto.a ${OPENSSL_ROOT}/lib/libcrypto.a
) )
endif()
elseif (${CMAKE_SYSTEM_NAME} MATCHES "Linux") elseif (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
set (OPENSSL_LIBS ssl crypto) set (OPENSSL_LIBS ssl crypto)
else() else()

View File

@@ -10,7 +10,7 @@ Barrier is KVM software forked from Symless's synergy 1.9 codebase. Synergy was
### What's different? ### What's different?
Whereas synergy has moved beyond its goals from the 1.x era, barrier aims to maintain that simplicity. Barrier will let you use your keyboard and mouse from machine A to control machine B (or more). That's it. Whereas synergy has moved beyond its goals from the 1.x era, barrier aims to maintain that simplicity. Barrier will let you use your keyboard and mouse from machine A to control machine B (or more). It's that simple.
### Project goals ### Project goals

View File

@@ -3,8 +3,8 @@
REM defaults - override them by creating a build_env.bat file REM defaults - override them by creating a build_env.bat file
set B_BUILD_TYPE=Debug set B_BUILD_TYPE=Debug
set B_QT_ROOT=C:\Qt set B_QT_ROOT=C:\Qt
set B_QT_VER=5.6.3 set B_QT_VER=5.11.1
set B_QT_MSVC=msvc2015_64 set B_QT_MSVC=msvc2017_64
set B_BONJOUR=C:\Program Files\Bonjour SDK set B_BONJOUR=C:\Program Files\Bonjour SDK
set savedir=%cd% set savedir=%cd%

View File

@@ -14,7 +14,7 @@ if [ "$(uname)" = "Darwin" ]; then
# OSX needs a lot of extra help, poor thing # OSX needs a lot of extra help, poor thing
# run the osx_environment.sh script to fix paths # run the osx_environment.sh script to fix paths
. ./osx_environment.sh . ./osx_environment.sh
B_CMAKE_FLAGS="-DCMAKE_OSX_SYSROOT=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.13.sdk -DCMAKE_OSX_DEPLOYMENT_TARGET=10.9 $B_CMAKE_FLAGS" B_CMAKE_FLAGS="-DCMAKE_OSX_SYSROOT=$(xcode-select --print-path)/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk -DCMAKE_OSX_DEPLOYMENT_TARGET=10.9 $B_CMAKE_FLAGS"
fi fi
# allow local customizations to build environment # allow local customizations to build environment
[ -r ./build_env.sh ] && . ./build_env.sh [ -r ./build_env.sh ] && . ./build_env.sh

View File

@@ -1,7 +1,7 @@
cmake_minimum_required (VERSION 3.4) cmake_minimum_required (VERSION 3.4)
set (BARRIER_VERSION_MAJOR 2) set (BARRIER_VERSION_MAJOR 2)
set (BARRIER_VERSION_MINOR 1) set (BARRIER_VERSION_MINOR 2)
set (BARRIER_VERSION_PATCH 0) set (BARRIER_VERSION_PATCH 0)
# #

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

@@ -1,16 +1,37 @@
#!/bin/sh #!/bin/bash
if [ ! $BARRIER_BUILD_ENV ]; then if [ ! $BARRIER_BUILD_ENV ]; then
printf "Modifying environment for Barrier build..." printf "Modifying environment for Barrier build..."
if command -v port; then
printf "Detected Macports"
if [ ! -d /opt/local/lib/cmake/Qt5 ]; then
printf "Please install qt5-qtbase port"
fi
export BARRIER_BUILD_MACPORTS=1
export CMAKE_PREFIX_PATH="/opt/local/lib/cmake/Qt5:$CMAKE_PREFIX_PATH"
export LD_LIBRARY_PATH="/opt/local/lib:$LD_LIBRARY_PATH"
export CPATH="/opt/local/include:$CPATH"
export PKG_CONFIG_PATH="/opt/local/libexec/qt5/lib/pkgconfig:$PKG_CONFIG_PATH"
elif command -v brew; then
printf "Detected Homebrew"
QT_PATH=$(brew --prefix qt) QT_PATH=$(brew --prefix qt)
OPENSSL_PATH=$(brew --prefix openssl) OPENSSL_PATH=$(brew --prefix openssl)
export BARRIER_BUILD_BREW=1
export CMAKE_PREFIX_PATH="$QT_PATH:$CMAKE_PREFIX_PATH" export CMAKE_PREFIX_PATH="$QT_PATH:$CMAKE_PREFIX_PATH"
export LD_LIBRARY_PATH="$OPENSSL_PATH/lib:$LD_LIBRARY_PATH" export LD_LIBRARY_PATH="$OPENSSL_PATH/lib:$LD_LIBRARY_PATH"
export CPATH="$OPENSSL_PATH/include:$CPATH" export CPATH="$OPENSSL_PATH/include:$CPATH"
export PKG_CONFIG_PATH="$OPENSSL_PATH/lib/pkgconfig:$PKG_CONFIG_PATH" export PKG_CONFIG_PATH="$OPENSSL_PATH/lib/pkgconfig:$PKG_CONFIG_PATH"
else
printf "Neither Homebrew nor Macports is installed. Can't get dependency paths"
exit 1
fi
export BARRIER_BUILD_ENV=1 export BARRIER_BUILD_ENV=1
printf "done\n" printf "done\n"

View File

@@ -6,23 +6,31 @@ set (CMAKE_AUTORCC ON)
set (CMAKE_AUTOUIC ON) set (CMAKE_AUTOUIC ON)
set (CMAKE_INCLUDE_CURRENT_DIR ON) set (CMAKE_INCLUDE_CURRENT_DIR ON)
file (GLOB GUI_SOURCE_FILES src/*.cpp src/*.h)
file (GLOB GUI_UI_FILES src/*.ui)
if (WIN32) if (WIN32)
set (GUI_RC_FILES res/win/Barrier.rc) set (resources res/win/Barrier.rc)
set (arch "win32")
else()
set (arch "unix")
endif()
file (GLOB sources src/*.cpp src/${arch}/*.cpp)
file (GLOB headers src/*.h src/${arch}/*.h)
file (GLOB designs src/*.ui)
if (BARRIER_ADD_HEADERS)
list (APPEND sources ${headers})
endif() endif()
add_executable (barrier WIN32 add_executable (barrier WIN32
${GUI_SOURCE_FILES} ${sources}
${GUI_UI_FILES} ${designs}
${GUI_RC_FILES} ${resources}
res/Barrier.qrc res/Barrier.qrc
) )
include_directories (./src) 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_VERSION_STAGE="${BARRIER_VERSION_STAGE}")
target_compile_definitions (barrier PRIVATE -DBARRIER_REVISION="${BARRIER_REVISION}") target_compile_definitions (barrier PRIVATE -DBARRIER_REVISION="${BARRIER_REVISION}")
@@ -32,7 +40,7 @@ if (WIN32)
HINTS ENV BONJOUR_SDK_HOME HINTS ENV BONJOUR_SDK_HOME
PATH_SUFFIXES "Lib/x64") PATH_SUFFIXES "Lib/x64")
set_target_properties (barrier PROPERTIES LINK_FLAGS "/NODEFAULTLIB:LIBCMT") set_target_properties (barrier PROPERTIES LINK_FLAGS "/NODEFAULTLIB:LIBCMT")
target_link_libraries (barrier ${DNSSD_LIB}) target_link_libraries (barrier ${DNSSD_LIB} Ws2_32.lib Iphlpapi.lib)
elseif (APPLE) elseif (APPLE)
find_library(APPSERVICES_LIB ApplicationServices) find_library(APPSERVICES_LIB ApplicationServices)
target_link_libraries(barrier ${APPSERVICES_LIB}) target_link_libraries(barrier ${APPSERVICES_LIB})

View File

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

View File

@@ -0,0 +1,10 @@
#pragma once
#include <string>
namespace Debauchee
{
std::string default_interface_ip();
}

View File

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

View File

@@ -23,6 +23,19 @@
#include <QtGui> #include <QtGui>
#include <QMessageBox> #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) : ScreenSettingsDialog::ScreenSettingsDialog(QWidget* parent, Screen* pScreen) :
QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint), QDialog(parent, Qt::WindowTitleHint | Qt::WindowSystemMenuHint),
Ui::ScreenSettingsDialogBase(), Ui::ScreenSettingsDialogBase(),
@@ -30,13 +43,11 @@ ScreenSettingsDialog::ScreenSettingsDialog(QWidget* parent, Screen* pScreen) :
{ {
setupUi(this); setupUi(this);
QRegExp validScreenName("[a-z0-9\\._-]{,255}", Qt::CaseInsensitive); m_pLineEditName->setText(check_name_param(m_pScreen->name()));
m_pLineEditName->setValidator(new QRegExpValidator(ValidScreenName, m_pLineEditName));
m_pLineEditName->setText(m_pScreen->name());
m_pLineEditName->setValidator(new QRegExpValidator(validScreenName, m_pLineEditName));
m_pLineEditName->selectAll(); 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++) for (int i = 0; i < m_pScreen->aliases().count(); i++)
new QListWidgetItem(m_pScreen->aliases()[i], m_pListAliases); new QListWidgetItem(m_pScreen->aliases()[i], m_pListAliases);

View File

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

View File

@@ -20,6 +20,7 @@
#include "MainWindow.h" #include "MainWindow.h"
#include "ZeroconfRegister.h" #include "ZeroconfRegister.h"
#include "ZeroconfBrowser.h" #include "ZeroconfBrowser.h"
#include "DefaultInterfaceIP.h"
#include <QtNetwork> #include <QtNetwork>
#include <QMessageBox> #include <QMessageBox>
@@ -34,12 +35,6 @@
#include <stdlib.h> #include <stdlib.h>
#endif #endif
static const QStringList preferedIPAddress(
QStringList() <<
"192.168." <<
"10." <<
"172.");
const char* ZeroconfService:: m_ServerServiceName = "_barrierServerZeroconf._tcp"; const char* ZeroconfService:: m_ServerServiceName = "_barrierServerZeroconf._tcp";
const char* ZeroconfService:: m_ClientServiceName = "_barrierClientZeroconf._tcp"; const char* ZeroconfService:: m_ClientServiceName = "_barrierClientZeroconf._tcp";
@@ -124,27 +119,6 @@ void ZeroconfService::errorHandle(DNSServiceErrorType errorCode)
tr("Error code: %1.").arg(errorCode)); tr("Error code: %1.").arg(errorCode));
} }
QString ZeroconfService::getLocalIPAddresses()
{
QStringList addresses;
foreach (const QHostAddress& address, QNetworkInterface::allAddresses()) {
if (address.protocol() == QAbstractSocket::IPv4Protocol &&
address != QHostAddress(QHostAddress::LocalHost)) {
addresses.append(address.toString());
}
}
foreach (const QString& preferedIP, preferedIPAddress) {
foreach (const QString& address, addresses) {
if (address.startsWith(preferedIP)) {
return address;
}
}
}
return "";
}
bool ZeroconfService::registerService(bool server) bool ZeroconfService::registerService(bool server)
{ {
bool result = true; bool result = true;
@@ -159,7 +133,7 @@ bool ZeroconfService::registerService(bool server)
else { else {
m_pZeroconfRegister = new ZeroconfRegister(this); m_pZeroconfRegister = new ZeroconfRegister(this);
if (server) { if (server) {
QString localIP = getLocalIPAddresses(); QString localIP = QString::fromStdString(Debauchee::default_interface_ip());
if (localIP.isEmpty()) { if (localIP.isEmpty()) {
QMessageBox::warning(m_pMainWindow, tr("Barrier"), QMessageBox::warning(m_pMainWindow, tr("Barrier"),
tr("Failed to get local IP address. " tr("Failed to get local IP address. "

View File

@@ -42,7 +42,6 @@ private slots:
void errorHandle(DNSServiceErrorType errorCode); void errorHandle(DNSServiceErrorType errorCode);
private: private:
QString getLocalIPAddresses();
bool registerService(bool server); bool registerService(bool server);
private: private:

View File

@@ -67,6 +67,13 @@ int main(int argc, char* argv[])
/* Workaround for QTBUG-40332 - "High ping when QNetworkAccessManager is instantiated" */ /* Workaround for QTBUG-40332 - "High ping when QNetworkAccessManager is instantiated" */
::setenv ("QT_BEARER_POLL_TIMEOUT", "-1", 1); ::setenv ("QT_BEARER_POLL_TIMEOUT", "-1", 1);
#endif #endif
#if _WIN32
// winsock needs to be initialized for DefaultInterfaceIP
WSADATA wd;
WSAStartup(MAKEWORD(2, 0), &wd);
#endif
QCoreApplication::setOrganizationName("Debauchee"); QCoreApplication::setOrganizationName("Debauchee");
QCoreApplication::setOrganizationDomain("github.com"); QCoreApplication::setOrganizationDomain("github.com");
QCoreApplication::setApplicationName("Barrier"); QCoreApplication::setApplicationName("Barrier");

View File

@@ -0,0 +1,79 @@
#include "IfAddrsResource.h"
#include "SocketResource.h"
#include <sys/ioctl.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#ifdef __linux__
#include <linux/wireless.h>
#else
#include <net/if.h>
#include <net/if_media.h>
#endif
#include <string>
#include <cstring>
namespace Debauchee
{
static bool is_wireless(const char * ifname, const SocketResource& sock)
{
#ifdef __linux__
struct iwreq req;
::memset(&req, 0, sizeof(struct iwreq));
::strncpy(req.ifr_name, ifname, IFNAMSIZ - 1);
return ioctl(sock, SIOCGIWMODE, &req) >= 0;
#else
struct ifmediareq req;
::memset(&req, 0, sizeof(struct ifmediareq));
::strncpy(req.ifm_name, ifname, IFNAMSIZ - 1);
if (ioctl(sock, SIOCGIFMEDIA, &req) >= 0 &&
(req.ifm_status & IFM_AVALID)
) {
return IFM_TYPE(req.ifm_active) == IFM_IEEE80211;
}
return false;
#endif
}
static bool is_wireless(const char * ifname)
{
if (ifname) {
SocketResource sock(AF_INET, SOCK_DGRAM, 0);
if (sock.is_valid()) {
return is_wireless(ifname, sock);
}
}
return false;
}
std::string default_interface_ip()
{
std::string wirelessAddress;
IfAddrsResource ifa;
if (ifa.is_valid()) {
for (struct ifaddrs * next = ifa; next; next = next->ifa_next) {
auto sain = (struct sockaddr_in *)next->ifa_addr;
if (!sain || sain->sin_family != AF_INET ||
!(next->ifa_flags & IFF_RUNNING) ||
(next->ifa_flags & IFF_LOOPBACK)
) {
continue;
}
std::string address = inet_ntoa(sain->sin_addr);
// take first wired address right away
if (!is_wireless(next->ifa_name)) {
return address;
}
// save first wireless address to be used if we don't find a wired one
if (wirelessAddress.empty()) {
wirelessAddress = address;
}
}
}
return wirelessAddress;
}
}

View File

@@ -0,0 +1,32 @@
#include <sys/types.h>
#include <ifaddrs.h>
namespace Debauchee
{
class IfAddrsResource
{
public:
explicit IfAddrsResource() :
_valid(getifaddrs(&_ifa) == 0)
{
}
~IfAddrsResource()
{
if (_valid) {
freeifaddrs(_ifa);
}
}
bool is_valid() const { return _valid; }
operator struct ifaddrs * () const { return _ifa; }
private:
bool _valid;
struct ifaddrs * _ifa;
};
}

View File

@@ -0,0 +1,32 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <unistd.h>
namespace Debauchee
{
class SocketResource
{
public:
explicit SocketResource(int domain, int type, int protocol) :
_fd(socket(domain, type, protocol))
{
}
~SocketResource()
{
if (is_valid()) {
close(_fd);
}
}
bool is_valid() const { return _fd >= 0; }
operator int() const { return _fd; }
private:
int _fd;
};
}

View File

@@ -0,0 +1,100 @@
// REQUIRES: Ws2_32.lib, Iphlpapi.lib
// REQUIRES: WSAStartup(..)
// see comments regarding WSAAddressToStringA in address_string(..)
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <WinSock2.h>
#include <iphlpapi.h>
#include <string>
#include "HeapResource.h"
namespace Debauchee
{
static ULONG get_addresses(IP_ADAPTER_ADDRESSES * addresses, PULONG sz)
{
return GetAdaptersAddresses(AF_INET,
GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_SKIP_FRIENDLY_NAME,
NULL, addresses, sz);
}
static std::string address_string(const SOCKET_ADDRESS& address)
{
// planning to use this with Qt but QString does not have a c'tor
// for wide strings so we need to force the ANSI API here
DWORD szStrAddress = 1023;
char strAddress[1024];
if (WSAAddressToStringA(address.lpSockaddr, address.iSockaddrLength, NULL, strAddress, &szStrAddress)) {
return "";
}
return strAddress;
}
static std::string first_unicast_address(IP_ADAPTER_UNICAST_ADDRESS * unicast)
{
while (unicast) {
auto address = address_string(unicast->Address);
if (!address.empty()) {
return address;
}
unicast = unicast->Next;
}
return std::string();
}
static bool is_useable_interface(const IP_ADAPTER_ADDRESSES * ifa)
{
return
// is an ethernet or wireless interface AND
(ifa->IfType == IF_TYPE_ETHERNET_CSMACD || ifa->IfType == IF_TYPE_IEEE80211) &&
// is up
ifa->OperStatus == IfOperStatusUp;
}
static std::string default_ip_address(const IP_ADAPTER_ADDRESSES * next)
{
std::string wirelessAddress;
for ( ; next; next = next->Next) {
if (!is_useable_interface(next)) {
continue;
}
std::string address = first_unicast_address(next->FirstUnicastAddress);
if (address.empty()) {
continue;
}
// take first wired address right away
if (next->IfType == IF_TYPE_ETHERNET_CSMACD) {
return address;
}
// save first wireless address to be used if we don't find a wired one
if (wirelessAddress.empty()) {
wirelessAddress = address;
}
}
return wirelessAddress;
}
std::string default_interface_ip()
{
const ULONG DefaultSzAddresses = 15 * 1024; // 15k recommended by msdn
ULONG szAddresses = DefaultSzAddresses;
HeapResource<IP_ADAPTER_ADDRESSES> addresses(GetProcessHeap(), 0, DefaultSzAddresses);
if (addresses.is_valid()) {
ULONG result;
while (ERROR_BUFFER_OVERFLOW == (result = get_addresses(addresses, &szAddresses))) {
// add more space in case more adapters have shown up
szAddresses += DefaultSzAddresses;
swap(addresses, HeapResource<IP_ADAPTER_ADDRESSES>(GetProcessHeap(), 0, szAddresses));
if (!addresses.is_valid()) {
break;
}
}
if (result == ERROR_SUCCESS) {
return default_ip_address(addresses);
}
}
return std::string();
}
}

View File

@@ -0,0 +1,48 @@
#pragma once
namespace Debauchee
{
template<class T>
class HeapResource
{
public:
explicit HeapResource(HANDLE heap, DWORD flags, SIZE_T sz) :
_heap(heap),
_flags(flags),
_mem((T*)HeapAlloc(heap, flags, sz))
{
}
HeapResource(HeapResource<T>&& other)
: _mem(NULL)
{
swap(*this, other);
}
~HeapResource()
{
if (is_valid()) {
HeapFree(_heap, _flags, _mem);
}
}
friend void swap(HeapResource<T>& first, HeapResource<T>& second)
{
using std::swap;
swap(first._heap, second._heap);
swap(first._flags, second._flags);
swap(first._mem, second._mem);
}
bool is_valid() const { return _mem != NULL; }
operator T*() const { return _mem; }
private:
HANDLE _heap;
DWORD _flags;
T * _mem;
};
}

View File

@@ -144,10 +144,10 @@ private:
ButtonID mapMacButtonToBarrier(UInt16) const; ButtonID mapMacButtonToBarrier(UInt16) const;
// map mac scroll wheel value to a barrier scroll wheel value // 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 // 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 // get the current scroll wheel speed
double getScrollSpeed() const; double getScrollSpeed() const;

View File

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

View File

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

View File

@@ -136,6 +136,10 @@ private:
void onMouseRelease(const XButtonEvent&); void onMouseRelease(const XButtonEvent&);
void onMouseMove(const XMotionEvent&); 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(); bool detectXI2();
#ifdef HAVE_XI2 #ifdef HAVE_XI2
void selectXIRawMotion(); void selectXIRawMotion();
@@ -172,8 +176,15 @@ private:
// true if screen is being used as a primary screen, false otherwise // true if screen is being used as a primary screen, false otherwise
bool m_isPrimary; bool m_isPrimary;
// The size of a smallest supported scroll event, in points
int m_mouseScrollDelta; 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; Display* m_display;
Window m_root; Window m_root;
Window m_window; Window m_window;