Restored lost files and changes in version 1.3.1 to depot.

This commit is contained in:
crs 2007-06-17 11:19:18 +00:00
parent 73acb7860d
commit 52ae656411
199 changed files with 27622 additions and 13726 deletions

1894
ChangeLog

File diff suppressed because it is too large Load Diff

View File

@ -300,6 +300,8 @@ dnl version
AC_DEFUN([ACX_PTHREAD], [
AC_REQUIRE([AC_CANONICAL_HOST])
AC_LANG_SAVE
AC_LANG_C
acx_pthread_ok=no
# We used to check for pthread.h first, but this fails if pthread.h
@ -310,11 +312,11 @@ acx_pthread_ok=no
# etcetera environment variables, and if threads linking works using
# them:
if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
save_CXXFLAGS="$CXXFLAGS"
CXXFLAGS="$CXXFLAGS $PTHREAD_CFLAGS"
save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
save_LIBS="$LIBS"
LIBS="$PTHREAD_LIBS $LIBS"
AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CXXFLAGS=$PTHREAD_CFLAGS])
AC_MSG_CHECKING([for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS])
AC_TRY_LINK_FUNC(pthread_join, acx_pthread_ok=yes)
AC_MSG_RESULT($acx_pthread_ok)
if test x"$acx_pthread_ok" = xno; then
@ -322,7 +324,7 @@ if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
PTHREAD_CFLAGS=""
fi
LIBS="$save_LIBS"
CXXFLAGS="$save_CXXFLAGS"
CFLAGS="$save_CFLAGS"
fi
# We must check for the threads library under a number of different
@ -332,9 +334,10 @@ fi
# Create a list of thread flags to try. Items starting with a "-" are
# C compiler flags, and other items are library names, except for "none"
# which indicates that we try without any flags at all.
# which indicates that we try without any flags at all, and "pthread-config"
# which is a program returning the flags for the Pth emulation library.
acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt"
acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
# The ordering *is* (sometimes) important. Some notes on the
# individual items follow:
@ -353,6 +356,7 @@ acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -m
# also defines -D_REENTRANT)
# pthread: Linux, etcetera
# --thread-safe: KAI C++
# pthread-config: use pthread-config program (for GNU Pth library)
case "${host_cpu}-${host_os}" in
*solaris*)
@ -382,6 +386,13 @@ for flag in $acx_pthread_flags; do
PTHREAD_CFLAGS="$flag"
;;
pthread-config)
AC_CHECK_PROG(acx_pthread_config, pthread-config, yes, no)
if test x"$acx_pthread_config" = xno; then continue; fi
PTHREAD_CFLAGS="`pthread-config --cflags`"
PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
;;
*)
AC_MSG_CHECKING([for the pthreads library -l$flag])
PTHREAD_LIBS="-l$flag"
@ -389,9 +400,9 @@ for flag in $acx_pthread_flags; do
esac
save_LIBS="$LIBS"
save_CXXFLAGS="$CXXFLAGS"
save_CFLAGS="$CFLAGS"
LIBS="$PTHREAD_LIBS $LIBS"
CXXFLAGS="$CXXFLAGS $PTHREAD_CFLAGS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
# Check for various functions. We must include pthread.h,
# since some functions may be macros. (On the Sequent, we
@ -409,7 +420,7 @@ for flag in $acx_pthread_flags; do
[acx_pthread_ok=yes])
LIBS="$save_LIBS"
CXXFLAGS="$save_CXXFLAGS"
CFLAGS="$save_CFLAGS"
AC_MSG_RESULT($acx_pthread_ok)
if test "x$acx_pthread_ok" = xyes; then
@ -425,36 +436,28 @@ fi
if test "x$acx_pthread_ok" = xyes; then
save_LIBS="$LIBS"
LIBS="$PTHREAD_LIBS $LIBS"
save_CXXFLAGS="$CXXFLAGS"
CXXFLAGS="$CXXFLAGS $PTHREAD_CFLAGS"
save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
# Detect AIX lossage: threads are created detached by default
# and the JOINABLE attribute has a nonstandard name (UNDETACHED).
# Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
AC_MSG_CHECKING([for joinable pthread attribute])
AC_TRY_LINK([#include <pthread.h>],
[int attr=PTHREAD_CREATE_JOINABLE;],
ok=PTHREAD_CREATE_JOINABLE, ok=unknown)
if test x"$ok" = xunknown; then
AC_TRY_LINK([#include <pthread.h>],
[int attr=PTHREAD_CREATE_UNDETACHED;],
ok=PTHREAD_CREATE_UNDETACHED, ok=unknown)
fi
if test x"$ok" != xPTHREAD_CREATE_JOINABLE; then
AC_DEFINE(PTHREAD_CREATE_JOINABLE, $ok,
[Define to the necessary symbol if this constant
attr_name=unknown
for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
AC_TRY_LINK([#include <pthread.h>], [int attr=$attr;],
[attr_name=$attr; break])
done
AC_MSG_RESULT($attr_name)
if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then
AC_DEFINE_UNQUOTED(PTHREAD_CREATE_JOINABLE, $attr_name,
[Define to necessary symbol if this constant
uses a non-standard name on your system.])
fi
AC_MSG_RESULT(${ok})
if test x"$ok" = xunknown; then
AC_MSG_WARN([we do not know how to create joinable pthreads])
fi
AC_MSG_CHECKING([if more special flags are required for pthreads])
flag=no
case "${host_cpu}-${host_os}" in
*-aix* | *-freebsd*) flag="-D_THREAD_SAFE";;
alpha*-osf*) flag="-D_REENTRANT";;
*solaris*) flag="-D_REENTRANT";;
*-aix* | *-freebsd* | *-darwin*) flag="-D_THREAD_SAFE";;
*solaris* | *-osf* | *-hpux*) flag="-D_REENTRANT";;
esac
AC_MSG_RESULT(${flag})
if test "x$flag" != xno; then
@ -468,13 +471,13 @@ if test "x$acx_pthread_ok" = xyes; then
[sigset_t sigset; int signal; sigwait(&sigset, &signal);],
ok=yes, ok=unknown)
if test x"$ok" = xunknown; then
save_CXXFLAGS2="$CXXFLAGS"
CXXFLAGS="$CXXFLAGS -D_POSIX_PTHREAD_SEMANTICS"
save_CFLAGS2="$CFLAGS"
CFLAGS="$CFLAGS -D_POSIX_PTHREAD_SEMANTICS"
AC_TRY_LINK([#include <pthread.h>
#include <signal.h>],
[sigset_t sigset; int signal; sigwait(&sigset, &signal);],
ok=-D_POSIX_PTHREAD_SEMANTICS, ok=no)
CXXFLAGS="$save_CXXFLAGS2"
CFLAGS="$save_CFLAGS2"
fi
AC_MSG_RESULT(${ok})
if test x"$ok" != xno; then
@ -496,7 +499,7 @@ if test "x$acx_pthread_ok" = xyes; then
fi
LIBS="$save_LIBS"
CXXFLAGS="$save_CXXFLAGS"
CFLAGS="$save_CFLAGS"
# More AIX lossage: must compile with cc_r
AC_CHECK_PROG(PTHREAD_CC, cc_r, cc_r, ${CC})
@ -516,6 +519,7 @@ else
acx_pthread_ok=no
$2
fi
AC_LANG_RESTORE
])dnl ACX_PTHREAD
dnl enable maximum compiler warnings. must ignore unknown pragmas to

427
cmd/launcher/CAddScreen.cpp Normal file
View File

@ -0,0 +1,427 @@
/*
* synergy -- mouse and keyboard sharing utility
* 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 COPYING 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.
*/
#include "CConfig.h"
#include "KeyTypes.h"
#include "OptionTypes.h"
#include "ProtocolTypes.h"
#include "CStringUtil.h"
#include "CArch.h"
#include "CAddScreen.h"
#include "LaunchUtil.h"
#include "resource.h"
struct CModifierInfo {
public:
int m_ctrlID;
const char* m_name;
KeyModifierID m_modifierID;
OptionID m_optionID;
};
static const CModifierInfo s_modifiers[] = {
{ IDC_ADD_MOD_SHIFT, "Shift",
kKeyModifierIDShift, kOptionModifierMapForShift },
{ IDC_ADD_MOD_CTRL, "Ctrl",
kKeyModifierIDControl, kOptionModifierMapForControl },
{ IDC_ADD_MOD_ALT, "Alt",
kKeyModifierIDAlt, kOptionModifierMapForAlt },
{ IDC_ADD_MOD_META, "Meta",
kKeyModifierIDMeta, kOptionModifierMapForMeta },
{ IDC_ADD_MOD_SUPER, "Super",
kKeyModifierIDSuper, kOptionModifierMapForSuper }
};
static const KeyModifierID baseModifier = kKeyModifierIDShift;
//
// CAddScreen
//
CAddScreen* CAddScreen::s_singleton = NULL;
CAddScreen::CAddScreen(HWND parent, CConfig* config, const CString& name) :
m_parent(parent),
m_config(config),
m_name(name)
{
assert(s_singleton == NULL);
s_singleton = this;
}
CAddScreen::~CAddScreen()
{
s_singleton = NULL;
}
bool
CAddScreen::doModal()
{
// do dialog
return (DialogBoxParam(s_instance, MAKEINTRESOURCE(IDD_ADD),
m_parent, dlgProc, (LPARAM)this) != 0);
}
CString
CAddScreen::getName() const
{
return m_name;
}
void
CAddScreen::init(HWND hwnd)
{
// set title
CString title;
if (m_name.empty()) {
title = getString(IDS_ADD_SCREEN);
}
else {
title = CStringUtil::format(
getString(IDS_EDIT_SCREEN).c_str(),
m_name.c_str());
}
SendMessage(hwnd, WM_SETTEXT, 0, (LPARAM)title.c_str());
// fill in screen name
HWND child = getItem(hwnd, IDC_ADD_SCREEN_NAME_EDIT);
SendMessage(child, WM_SETTEXT, 0, (LPARAM)m_name.c_str());
// fill in aliases
CString aliases;
for (CConfig::all_const_iterator index = m_config->beginAll();
index != m_config->endAll(); ++index) {
if (CStringUtil::CaselessCmp::equal(index->second, m_name) &&
!CStringUtil::CaselessCmp::equal(index->second, index->first)) {
if (!aliases.empty()) {
aliases += "\r\n";
}
aliases += index->first;
}
}
child = getItem(hwnd, IDC_ADD_ALIASES_EDIT);
SendMessage(child, WM_SETTEXT, 0, (LPARAM)aliases.c_str());
// set options
CConfig::CScreenOptions options;
getOptions(options);
CConfig::CScreenOptions::const_iterator index;
child = getItem(hwnd, IDC_ADD_HD_CAPS_CHECK);
index = options.find(kOptionHalfDuplexCapsLock);
setItemChecked(child, (index != options.end() && index->second != 0));
child = getItem(hwnd, IDC_ADD_HD_NUM_CHECK);
index = options.find(kOptionHalfDuplexNumLock);
setItemChecked(child, (index != options.end() && index->second != 0));
child = getItem(hwnd, IDC_ADD_HD_SCROLL_CHECK);
index = options.find(kOptionHalfDuplexScrollLock);
setItemChecked(child, (index != options.end() && index->second != 0));
// modifier options
for (UInt32 i = 0; i < sizeof(s_modifiers) /
sizeof(s_modifiers[0]); ++i) {
child = getItem(hwnd, s_modifiers[i].m_ctrlID);
// fill in options
for (UInt32 j = 0; j < sizeof(s_modifiers) /
sizeof(s_modifiers[0]); ++j) {
SendMessage(child, CB_ADDSTRING, 0,
(LPARAM)s_modifiers[j].m_name);
}
// choose current value
index = options.find(s_modifiers[i].m_optionID);
KeyModifierID id = s_modifiers[i].m_modifierID;
if (index != options.end()) {
id = index->second;
}
SendMessage(child, CB_SETCURSEL, id - baseModifier, 0);
}
// dead corners
UInt32 corners = 0;
index = options.find(kOptionScreenSwitchCorners);
if (index != options.end()) {
corners = index->second;
}
child = getItem(hwnd, IDC_ADD_DC_TOP_LEFT);
setItemChecked(child, (corners & kTopLeftMask) != 0);
child = getItem(hwnd, IDC_ADD_DC_TOP_RIGHT);
setItemChecked(child, (corners & kTopRightMask) != 0);
child = getItem(hwnd, IDC_ADD_DC_BOTTOM_LEFT);
setItemChecked(child, (corners & kBottomLeftMask) != 0);
child = getItem(hwnd, IDC_ADD_DC_BOTTOM_RIGHT);
setItemChecked(child, (corners & kBottomRightMask) != 0);
index = options.find(kOptionScreenSwitchCornerSize);
SInt32 size = 0;
if (index != options.end()) {
size = index->second;
}
char buffer[20];
sprintf(buffer, "%d", size);
child = getItem(hwnd, IDC_ADD_DC_SIZE);
SendMessage(child, WM_SETTEXT, 0, (LPARAM)buffer);
}
bool
CAddScreen::save(HWND hwnd)
{
// get the old aliases and options
CStringList oldAliases;
getAliases(oldAliases);
CConfig::CScreenOptions options;
getOptions(options);
// extract name and aliases
CString newName;
HWND child = getItem(hwnd, IDC_ADD_SCREEN_NAME_EDIT);
newName = getWindowText(child);
CStringList newAliases;
child = getItem(hwnd, IDC_ADD_ALIASES_EDIT);
tokenize(newAliases, getWindowText(child));
// name must be valid
if (!m_config->isValidScreenName(newName)) {
showError(hwnd, CStringUtil::format(
getString(IDS_INVALID_SCREEN_NAME).c_str(),
newName.c_str()));
return false;
}
// aliases must be valid
for (CStringList::const_iterator index = newAliases.begin();
index != newAliases.end(); ++index) {
if (!m_config->isValidScreenName(*index)) {
showError(hwnd, CStringUtil::format(
getString(IDS_INVALID_SCREEN_NAME).c_str(),
index->c_str()));
return false;
}
}
// new name may not be in the new alias list
if (isNameInList(newAliases, newName)) {
showError(hwnd, CStringUtil::format(
getString(IDS_SCREEN_NAME_IS_ALIAS).c_str(),
newName.c_str()));
return false;
}
// name must not exist in config but allow same name. also
// allow name if it exists in the old alias list but not the
// new one.
if (m_config->isScreen(newName) &&
!CStringUtil::CaselessCmp::equal(newName, m_name) &&
!isNameInList(oldAliases, newName)) {
showError(hwnd, CStringUtil::format(
getString(IDS_DUPLICATE_SCREEN_NAME).c_str(),
newName.c_str()));
return false;
}
// aliases must not exist in config but allow same aliases and
// allow an alias to be the old name.
for (CStringList::const_iterator index = newAliases.begin();
index != newAliases.end(); ++index) {
if (m_config->isScreen(*index) &&
!CStringUtil::CaselessCmp::equal(*index, m_name) &&
!isNameInList(oldAliases, *index)) {
showError(hwnd, CStringUtil::format(
getString(IDS_DUPLICATE_SCREEN_NAME).c_str(),
index->c_str()));
return false;
}
}
// dead corner size must be non-negative
child = getItem(hwnd, IDC_ADD_DC_SIZE);
CString valueString = getWindowText(child);
int cornerSize = atoi(valueString.c_str());
if (cornerSize < 0) {
showError(hwnd, CStringUtil::format(
getString(IDS_INVALID_CORNER_SIZE).c_str(),
valueString.c_str()));
SetFocus(child);
return false;
}
// collect options
child = getItem(hwnd, IDC_ADD_HD_CAPS_CHECK);
if (isItemChecked(child)) {
options[kOptionHalfDuplexCapsLock] = 1;
}
else {
options.erase(kOptionHalfDuplexCapsLock);
}
child = getItem(hwnd, IDC_ADD_HD_NUM_CHECK);
if (isItemChecked(child)) {
options[kOptionHalfDuplexNumLock] = 1;
}
else {
options.erase(kOptionHalfDuplexNumLock);
}
child = getItem(hwnd, IDC_ADD_HD_SCROLL_CHECK);
if (isItemChecked(child)) {
options[kOptionHalfDuplexScrollLock] = 1;
}
else {
options.erase(kOptionHalfDuplexScrollLock);
}
// save modifier options
for (UInt32 i = 0; i < sizeof(s_modifiers) /
sizeof(s_modifiers[0]); ++i) {
child = getItem(hwnd, s_modifiers[i].m_ctrlID);
KeyModifierID id = static_cast<KeyModifierID>(
SendMessage(child, CB_GETCURSEL, 0, 0) +
baseModifier);
if (id != s_modifiers[i].m_modifierID) {
options[s_modifiers[i].m_optionID] = id;
}
else {
options.erase(s_modifiers[i].m_optionID);
}
}
// save dead corner options
UInt32 corners = 0;
if (isItemChecked(getItem(hwnd, IDC_ADD_DC_TOP_LEFT))) {
corners |= kTopLeftMask;
}
if (isItemChecked(getItem(hwnd, IDC_ADD_DC_TOP_RIGHT))) {
corners |= kTopRightMask;
}
if (isItemChecked(getItem(hwnd, IDC_ADD_DC_BOTTOM_LEFT))) {
corners |= kBottomLeftMask;
}
if (isItemChecked(getItem(hwnd, IDC_ADD_DC_BOTTOM_RIGHT))) {
corners |= kBottomRightMask;
}
options[kOptionScreenSwitchCorners] = corners;
options[kOptionScreenSwitchCornerSize] = cornerSize;
// save new data to config
if (m_name.empty()) {
// added screen
m_config->addScreen(newName);
}
else {
// edited screen
m_config->removeAliases(m_name);
m_config->removeOptions(m_name);
m_config->renameScreen(m_name, newName);
}
m_name = newName;
for (CStringList::const_iterator index = newAliases.begin();
index != newAliases.end(); ++index) {
m_config->addAlias(m_name, *index);
}
for (CConfig::CScreenOptions::const_iterator
index = options.begin();
index != options.end(); ++index) {
m_config->addOption(m_name, index->first, index->second);
}
return true;
}
BOOL
CAddScreen::doDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM)
{
switch (message) {
case WM_INITDIALOG:
init(hwnd);
return TRUE;
case WM_COMMAND:
switch (LOWORD(wParam)) {
case IDOK:
if (save(hwnd)) {
EndDialog(hwnd, 1);
}
return TRUE;
case IDCANCEL:
EndDialog(hwnd, 0);
return TRUE;
}
break;
default:
break;
}
return FALSE;
}
BOOL CALLBACK
CAddScreen::dlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
return s_singleton->doDlgProc(hwnd, message, wParam, lParam);
}
void
CAddScreen::getAliases(CStringList& aliases) const
{
for (CConfig::all_const_iterator index = m_config->beginAll();
index != m_config->endAll(); ++index) {
if (CStringUtil::CaselessCmp::equal(index->second, m_name) &&
!CStringUtil::CaselessCmp::equal(index->second, index->first)) {
aliases.push_back(index->first);
}
}
}
void
CAddScreen::getOptions(CConfig::CScreenOptions& optionsOut) const
{
const CConfig::CScreenOptions* options = m_config->getOptions(m_name);
if (options == NULL) {
optionsOut = CConfig::CScreenOptions();
}
else {
optionsOut = *options;
}
}
void
CAddScreen::tokenize(CStringList& tokens, const CString& src)
{
// find first non-whitespace
CString::size_type x = src.find_first_not_of(" \t\r\n");
if (x == CString::npos) {
return;
}
// find next whitespace
do {
CString::size_type y = src.find_first_of(" \t\r\n", x);
if (y == CString::npos) {
y = src.size();
}
tokens.push_back(src.substr(x, y - x));
x = src.find_first_not_of(" \t\r\n", y);
} while (x != CString::npos);
}
bool
CAddScreen::isNameInList(const CStringList& names, const CString& name)
{
for (CStringList::const_iterator index = names.begin();
index != names.end(); ++index) {
if (CStringUtil::CaselessCmp::equal(name, *index)) {
return true;
}
}
return false;
}

74
cmd/launcher/CAddScreen.h Normal file
View File

@ -0,0 +1,74 @@
/*
* synergy -- mouse and keyboard sharing utility
* Copyright (C) 2003 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 COPYING 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.
*/
#ifndef CADDSCREEN_H
#define CADDSCREEN_H
#include "CString.h"
#define WINDOWS_LEAN_AND_MEAN
#include <windows.h>
class CConfig;
//! Add screen dialog for Microsoft Windows launcher
class CAddScreen {
public:
CAddScreen(HWND parent, CConfig*, const CString& name);
~CAddScreen();
//! @name manipulators
//@{
//! Run dialog
/*!
Display and handle the dialog until closed by the user. Return
\c true if the user accepted the changes, false otherwise.
*/
bool doModal();
//@}
//! @name accessors
//@{
CString getName() const;
//@}
private:
typedef std::vector<CString> CStringList;
void getAliases(CStringList&) const;
void getOptions(CConfig::CScreenOptions&) const;
static void tokenize(CStringList& tokens, const CString& src);
static bool isNameInList(const CStringList& tokens,
const CString& src);
void init(HWND hwnd);
bool save(HWND hwnd);
// message handling
BOOL doDlgProc(HWND, UINT, WPARAM, LPARAM);
static BOOL CALLBACK dlgProc(HWND, UINT, WPARAM, LPARAM);
private:
static CAddScreen* s_singleton;
HWND m_parent;
CConfig* m_config;
CString m_name;
};
#endif

View File

@ -206,7 +206,7 @@ CAdvancedOptions::save(HWND hwnd)
m_interface = iface;
// save values to registry
HKEY key = CArchMiscWindows::openKey(HKEY_CURRENT_USER, getSettingsPath());
HKEY key = CArchMiscWindows::addKey(HKEY_CURRENT_USER, getSettingsPath());
if (key != NULL) {
CArchMiscWindows::setValue(key, "port", m_port);
CArchMiscWindows::setValue(key, "name", m_screenName);

View File

@ -21,10 +21,10 @@
#include "LaunchUtil.h"
#include "resource.h"
#define CLIENT_DAEMON_NAME "Synergy Client"
#define SERVER_DAEMON_NAME "Synergy Server"
#define CLIENT_DAEMON_INFO "Shares this system's mouse and keyboard with others."
#define SERVER_DAEMON_INFO "Shares this system's mouse and keyboard with others."
static const char* CLIENT_DAEMON_NAME = "Synergy Client";
static const char* SERVER_DAEMON_NAME = "Synergy Server";
static const char* CLIENT_DAEMON_INFO = "Uses a shared mouse and keyboard.";
static const char* SERVER_DAEMON_INFO = "Shares this system's mouse and keyboard with others.";
//
// CAutoStartOutputter
@ -40,6 +40,7 @@ public:
// ILogOutputter overrides
virtual void open(const char*) { }
virtual void close() { }
virtual void show(bool) { }
virtual bool write(ELevel level, const char* message);
virtual const char* getNewline() const { return ""; }
@ -63,14 +64,11 @@ CAutoStartOutputter::write(ELevel level, const char* message)
CAutoStart* CAutoStart::s_singleton = NULL;
CAutoStart::CAutoStart(HWND parent, CConfig* config, const CString& cmdLine) :
CAutoStart::CAutoStart(HWND parent, bool isServer, const CString& cmdLine) :
m_parent(parent),
m_config(config),
m_isServer(config != NULL),
m_isServer(isServer),
m_cmdLine(cmdLine),
m_name((config != NULL) ? SERVER_DAEMON_NAME : CLIENT_DAEMON_NAME),
m_userConfigSaved(false)
m_name(isServer ? SERVER_DAEMON_NAME : CLIENT_DAEMON_NAME)
{
assert(s_singleton == NULL);
s_singleton = this;
@ -87,9 +85,6 @@ CAutoStart::doModal()
// install our log outputter
CLOG->insert(new CAutoStartOutputter(&m_errorMessage));
// reset saved flag
m_userConfigSaved = false;
// do dialog
DialogBoxParam(s_instance, MAKEINTRESOURCE(IDD_AUTOSTART),
m_parent, dlgProc, (LPARAM)this);
@ -98,10 +93,98 @@ CAutoStart::doModal()
CLOG->pop_front();
}
bool
CAutoStart::wasUserConfigSaved() const
void
CAutoStart::reinstallDaemon(bool isClient, const CString& cmdLine)
{
return m_userConfigSaved;
// get installation state
const char* name = (isClient ? CLIENT_DAEMON_NAME : SERVER_DAEMON_NAME);
bool installedSystem = ARCH->isDaemonInstalled(name, true);
bool installedUser = ARCH->isDaemonInstalled(name, false);
// reinstall if anything is installed
if (installedSystem || installedUser) {
ARCH->installDaemon(name,
isClient ? CLIENT_DAEMON_INFO : SERVER_DAEMON_INFO,
getAppPath(isClient ? CLIENT_APP : SERVER_APP).c_str(),
cmdLine.c_str(),
NULL,
installedSystem);
}
}
void
CAutoStart::uninstallDaemons(bool client)
{
if (client) {
try {
ARCH->uninstallDaemon(CLIENT_DAEMON_NAME, true);
}
catch (...) {
}
try {
ARCH->uninstallDaemon(CLIENT_DAEMON_NAME, false);
}
catch (...) {
}
}
else {
try {
ARCH->uninstallDaemon(SERVER_DAEMON_NAME, true);
}
catch (...) {
}
try {
ARCH->uninstallDaemon(SERVER_DAEMON_NAME, false);
}
catch (...) {
}
}
}
bool
CAutoStart::startDaemon()
{
const char* name = NULL;
if (ARCH->isDaemonInstalled(CLIENT_DAEMON_NAME, true)) {
name = CLIENT_DAEMON_NAME;
}
else if (ARCH->isDaemonInstalled(SERVER_DAEMON_NAME, true)) {
name = SERVER_DAEMON_NAME;
}
if (name == NULL) {
return false;
}
// open service manager
SC_HANDLE mgr = OpenSCManager(NULL, NULL, GENERIC_READ);
if (mgr == NULL) {
return false;
}
// open the service
SC_HANDLE service = OpenService(mgr, name, SERVICE_START);
if (service == NULL) {
CloseServiceHandle(mgr);
return false;
}
// start the service
BOOL okay = StartService(service, 0, NULL);
// clean up
CloseServiceHandle(service);
CloseServiceHandle(mgr);
return (okay != 0);
}
bool
CAutoStart::isDaemonInstalled()
{
return (ARCH->isDaemonInstalled(CLIENT_DAEMON_NAME, false) ||
ARCH->isDaemonInstalled(CLIENT_DAEMON_NAME, true) ||
ARCH->isDaemonInstalled(SERVER_DAEMON_NAME, false) ||
ARCH->isDaemonInstalled(SERVER_DAEMON_NAME, true));
}
void
@ -177,22 +260,6 @@ CAutoStart::onInstall(bool allUsers)
return onUninstall(allUsers);
}
// try saving configuration. if we can't then don't try
// installing the daemon.
if (m_config != NULL) {
if (!saveConfig(*m_config, allUsers)) {
showError(m_hwnd, CStringUtil::format(
getString(IDS_SAVE_FAILED).c_str(),
getErrorString(GetLastError()).c_str()));
return false;
}
// note if we've saved the user's configuration
if (!allUsers) {
m_userConfigSaved = true;
}
}
// get the app path
CString appPath = getAppPath(m_isServer ? SERVER_APP : CLIENT_APP);

View File

@ -20,14 +20,10 @@
#define WINDOWS_LEAN_AND_MEAN
#include <windows.h>
class CConfig;
//! Auto start dialog for Microsoft Windows launcher
class CAutoStart {
public:
// if config == NULL then it's assumed we're installing/uninstalling
// the client, otherwise the server.
CAutoStart(HWND parent, CConfig* config, const CString& cmdLine);
CAutoStart(HWND parent, bool isServer, const CString& cmdLine);
~CAutoStart();
//! @name manipulators
@ -39,16 +35,34 @@ public:
*/
void doModal();
//! Reinstall daemon
/*!
Reinstalls the currently installed daemon.
*/
static void reinstallDaemon(bool isClient, const CString& cmdLine);
//! Uninstalls daemon
/*!
Uninstalls all installed client (\p client is \c true) or server daemons.
*/
static void uninstallDaemons(bool client);
//! Starts an installed daemon
/*!
Returns \c true iff a daemon was started. This will only start daemons
installed for all users.
*/
static bool startDaemon();
//@}
//! @name accessors
//@{
//! Test if user configuration was saved
//! Tests if any daemons are installed
/*!
Returns true if the user's configuration (as opposed to the system-wide
configuration) was saved successfully while in doModal().
Returns \c true if any daemons are installed.
*/
bool wasUserConfigSaved() const;
static bool isDaemonInstalled();
//@}
@ -65,14 +79,12 @@ private:
static CAutoStart* s_singleton;
HWND m_parent;
CConfig* m_config;
bool m_isServer;
CString m_cmdLine;
CString m_name;
HWND m_hwnd;
bool m_install;
CString m_errorMessage;
bool m_userConfigSaved;
};
#endif

View File

@ -79,6 +79,8 @@ CGlobalOptions::init(HWND hwnd)
setItemChecked(child, true);
child = getItem(hwnd, IDC_GLOBAL_RELATIVE_MOVES);
setItemChecked(child, false);
child = getItem(hwnd, IDC_GLOBAL_LEAVE_FOREGROUND);
setItemChecked(child, false);
// get the global options
const CConfig::CScreenOptions* options = m_config->getOptions("");
@ -122,6 +124,10 @@ CGlobalOptions::init(HWND hwnd)
child = getItem(hwnd, IDC_GLOBAL_RELATIVE_MOVES);
setItemChecked(child, (value != 0));
}
else if (id == kOptionWin32KeepForeground) {
child = getItem(hwnd, IDC_GLOBAL_LEAVE_FOREGROUND);
setItemChecked(child, (value != 0));
}
}
}
}
@ -187,6 +193,7 @@ CGlobalOptions::save(HWND hwnd)
m_config->removeOption("", kOptionHeartbeat);
m_config->removeOption("", kOptionScreenSaverSync);
m_config->removeOption("", kOptionRelativeMouseMoves);
m_config->removeOption("", kOptionWin32KeepForeground);
// add requested options
child = getItem(hwnd, IDC_GLOBAL_DELAY_CHECK);
@ -209,6 +216,10 @@ CGlobalOptions::save(HWND hwnd)
if (isItemChecked(child)) {
m_config->addOption("", kOptionRelativeMouseMoves, 1);
}
child = getItem(hwnd, IDC_GLOBAL_LEAVE_FOREGROUND);
if (isItemChecked(child)) {
m_config->addOption("", kOptionWin32KeepForeground, 1);
}
// save last values
m_delayTime = newDelayTime;

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,225 @@
/*
* synergy -- mouse and keyboard sharing utility
* Copyright (C) 2006 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 COPYING 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.
*/
#ifndef CHOTKEYOPTIONS_H
#define CHOTKEYOPTIONS_H
#include "CString.h"
#include "KeyTypes.h"
#include "MouseTypes.h"
#include "CInputFilter.h"
#define WINDOWS_LEAN_AND_MEAN
#include <windows.h>
class CConfig;
//! Hotkey options dialog for Microsoft Windows launcher
class CHotkeyOptions {
public:
CHotkeyOptions(HWND parent, CConfig*);
~CHotkeyOptions();
//! @name manipulators
//@{
//! Run dialog
/*!
Display and handle the dialog until closed by the user.
*/
void doModal();
//@}
//! @name accessors
//@{
//@}
private:
void doInit(HWND hwnd);
void fillHotkeys(HWND hwnd, UInt32 select = (UInt32)-1);
void updateHotkeysControls(HWND hwnd);
void addHotkey(HWND hwnd);
void removeHotkey(HWND hwnd);
void editHotkey(HWND hwnd);
void fillActions(HWND hwnd, UInt32 select = (UInt32)-1);
void updateActionsControls(HWND hwnd);
void addAction(HWND hwnd);
void removeAction(HWND hwnd);
void editAction(HWND hwnd);
bool editCondition(HWND hwnd, CInputFilter::CCondition*&);
bool editAction(HWND hwnd, CInputFilter::CAction*&,
bool& onActivate);
void openRule(HWND hwnd);
void closeRule(HWND hwnd);
UInt32 findMatchingAction(
const CInputFilter::CKeystrokeAction*) const;
UInt32 findMatchingAction(
const CInputFilter::CMouseButtonAction*) const;
// message handling
BOOL doDlgProc(HWND, UINT, WPARAM, LPARAM);
static BOOL CALLBACK dlgProc(HWND, UINT, WPARAM, LPARAM);
// special actions we use to combine matching down/up actions into a
// single action for the convenience of the user.
class CKeystrokeDownUpAction : public CInputFilter::CKeystrokeAction {
public:
CKeystrokeDownUpAction(IPlatformScreen::CKeyInfo* adoptedInfo) :
CInputFilter::CKeystrokeAction(adoptedInfo, true) { }
// CAction overrides
virtual CInputFilter::CAction* clone() const
{
IKeyState::CKeyInfo* info = IKeyState::CKeyInfo::alloc(*getInfo());
return new CKeystrokeDownUpAction(info);
}
protected:
// CKeystrokeAction overrides
virtual const char* formatName() const { return "keystroke"; }
};
class CMouseButtonDownUpAction : public CInputFilter::CMouseButtonAction {
public:
CMouseButtonDownUpAction(IPrimaryScreen::CButtonInfo* adoptedInfo) :
CInputFilter::CMouseButtonAction(adoptedInfo, true) { }
// CAction overrides
virtual CInputFilter::CAction* clone() const
{
IPlatformScreen::CButtonInfo* info =
IPrimaryScreen::CButtonInfo::alloc(*getInfo());
return new CMouseButtonDownUpAction(info);
}
protected:
// CMouseButtonAction overrides
virtual const char* formatName() const { return "mousebutton"; }
};
class CConditionDialog {
public:
static bool doModal(HWND parent, CInputFilter::CCondition*&);
private:
static void doInit(HWND hwnd);
static void fillHotkey(HWND hwnd);
static void onButton(HWND hwnd, ButtonID button);
static void onKey(HWND hwnd, WPARAM wParam, LPARAM lParam);
static KeyID getChar(WPARAM wParam, LPARAM lParam);
static KeyModifierMask
getModifiers();
static bool isGoodCondition();
static BOOL CALLBACK dlgProc(HWND, UINT, WPARAM, LPARAM);
static LRESULT CALLBACK editProc(HWND hwnd, UINT, WPARAM, LPARAM);
private:
static CInputFilter::CCondition*
s_condition;
static CInputFilter::CCondition*
s_lastGoodCondition;
static WNDPROC s_editWndProc;
};
class CActionDialog {
public:
static bool doModal(HWND parent, CConfig* config,
CInputFilter::CAction*&, bool& onActivate);
private:
static void doInit(HWND hwnd);
static void fillHotkey(HWND hwnd);
static void updateControls(HWND hwnd);
static void onButton(HWND hwnd, ButtonID button);
static void onKey(HWND hwnd, WPARAM wParam, LPARAM lParam);
static void onLockAction(HWND hwnd);
static void onSwitchToAction(HWND hwnd);
static void onSwitchInAction(HWND hwnd);
static KeyID getChar(WPARAM wParam, LPARAM lParam);
static KeyModifierMask
getModifiers();
static bool isGoodAction();
static void convertAction(HWND hwnd);
static bool isDownUpAction();
static BOOL CALLBACK dlgProc(HWND, UINT, WPARAM, LPARAM);
static LRESULT CALLBACK editProc(HWND hwnd, UINT, WPARAM, LPARAM);
private:
static CConfig* s_config;
static bool s_onActivate;
static CInputFilter::CAction*
s_action;
static CInputFilter::CAction*
s_lastGoodAction;
static WNDPROC s_editWndProc;
};
// public to allow CActionDialog to use it
public:
class CScreensDialog {
public:
static void doModal(HWND parent, CConfig* config,
CInputFilter::CKeystrokeAction*);
// public due to compiler brokenness
typedef std::set<CString> CScreens;
private:
static void doInit(HWND hwnd);
static void doFini(HWND hwnd);
static void fillScreens(HWND hwnd);
static void updateControls(HWND hwnd);
static void add(HWND hwnd);
static void remove(HWND hwnd);
static void getSelected(HWND hwnd, UINT id,
const CScreens& inScreens, CScreens& outScreens);
static BOOL CALLBACK dlgProc(HWND, UINT, WPARAM, LPARAM);
private:
static CConfig* s_config;
static CInputFilter::CKeystrokeAction* s_action;
static CScreens s_nonTargets;
static CScreens s_targets;
static CString s_allScreens;
};
private:
static CHotkeyOptions* s_singleton;
HWND m_parent;
CConfig* m_config;
CInputFilter* m_inputFilter;
CInputFilter::CRule m_activeRule;
UInt32 m_activeRuleIndex;
};
#endif

111
cmd/launcher/CInfo.cpp Normal file
View File

@ -0,0 +1,111 @@
/*
* synergy -- mouse and keyboard sharing utility
* Copyright (C) 2006 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 COPYING 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.
*/
#include "ProtocolTypes.h"
#include "CStringUtil.h"
#include "Version.h"
#include "CArch.h"
#include "CInfo.h"
#include "LaunchUtil.h"
#include "resource.h"
//
// CInfo
//
CInfo* CInfo::s_singleton = NULL;
CInfo::CInfo(HWND parent) :
m_parent(parent)
{
assert(s_singleton == NULL);
s_singleton = this;
}
CInfo::~CInfo()
{
s_singleton = NULL;
}
void
CInfo::doModal()
{
// do dialog
DialogBoxParam(s_instance, MAKEINTRESOURCE(IDD_INFO),
m_parent, dlgProc, (LPARAM)this);
}
void
CInfo::init(HWND hwnd)
{
// collect info
CString version =
CStringUtil::format(getString(IDS_TITLE).c_str(), VERSION);
CString hostname = ARCH->getHostName();
CString address = ARCH->addrToString(ARCH->nameToAddr(hostname));
CString userConfig = ARCH->getUserDirectory();
if (!userConfig.empty()) {
userConfig = ARCH->concatPath(userConfig, CONFIG_NAME);
}
CString sysConfig = ARCH->getSystemDirectory();
if (!sysConfig.empty()) {
sysConfig = ARCH->concatPath(sysConfig, CONFIG_NAME);
}
// set info
HWND child;
child = getItem(hwnd, IDC_INFO_VERSION);
setWindowText(child, version);
child = getItem(hwnd, IDC_INFO_HOSTNAME);
setWindowText(child, hostname);
child = getItem(hwnd, IDC_INFO_IP_ADDRESS);
setWindowText(child, address);
child = getItem(hwnd, IDC_INFO_USER_CONFIG);
setWindowText(child, userConfig);
child = getItem(hwnd, IDC_INFO_SYS_CONFIG);
setWindowText(child, sysConfig);
// focus on okay button
SetFocus(getItem(hwnd, IDOK));
}
BOOL
CInfo::doDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM)
{
switch (message) {
case WM_INITDIALOG:
init(hwnd);
return FALSE;
case WM_COMMAND:
switch (LOWORD(wParam)) {
case IDOK:
case IDCANCEL:
EndDialog(hwnd, 0);
return TRUE;
}
break;
default:
break;
}
return FALSE;
}
BOOL CALLBACK
CInfo::dlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
return s_singleton->doDlgProc(hwnd, message, wParam, lParam);
}

57
cmd/launcher/CInfo.h Normal file
View File

@ -0,0 +1,57 @@
/*
* synergy -- mouse and keyboard sharing utility
* Copyright (C) 2006 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 COPYING 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.
*/
#ifndef CINFO_H
#define CINFO_H
#include "CString.h"
#define WINDOWS_LEAN_AND_MEAN
#include <windows.h>
//! Info dialog for Microsoft Windows launcher
class CInfo {
public:
CInfo(HWND parent);
~CInfo();
//! @name manipulators
//@{
//! Run dialog
/*!
Display and handle the dialog until closed by the user.
*/
void doModal();
//@}
//! @name accessors
//@{
//@}
private:
void init(HWND hwnd);
// message handling
BOOL doDlgProc(HWND, UINT, WPARAM, LPARAM);
static BOOL CALLBACK dlgProc(HWND, UINT, WPARAM, LPARAM);
private:
static CInfo* s_singleton;
HWND m_parent;
};
#endif

View File

@ -0,0 +1,855 @@
/*
* synergy -- mouse and keyboard sharing utility
* 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 COPYING 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.
*/
#include "CConfig.h"
#include "ProtocolTypes.h"
#include "CStringUtil.h"
#include "CArch.h"
#include "CScreensLinks.h"
#include "CAddScreen.h"
#include "LaunchUtil.h"
#include "resource.h"
//
// CScreensLinks
//
CScreensLinks* CScreensLinks::s_singleton = NULL;
CScreensLinks::CScreensLinks(HWND parent, CConfig* config) :
m_parent(parent),
m_mainConfig(config),
m_config(&m_scratchConfig)
{
assert(s_singleton == NULL);
s_singleton = this;
// get formatting strings
m_linkFormat = getString(IDS_LINK_FORMAT);
m_intervalFormat = getString(IDS_LINK_INTERVAL_FORMAT);
m_newLinkLabel = getString(IDS_NEW_LINK);
m_sideLabel[kLeft - kFirstDirection] = getString(IDS_SIDE_LEFT);
m_sideLabel[kRight - kFirstDirection] = getString(IDS_SIDE_RIGHT);
m_sideLabel[kTop - kFirstDirection] = getString(IDS_SIDE_TOP);
m_sideLabel[kBottom - kFirstDirection] = getString(IDS_SIDE_BOTTOM);
// GDI objects
m_redPen = CreatePen(PS_INSIDEFRAME, 1, RGB(255, 0, 0));
}
CScreensLinks::~CScreensLinks()
{
DeleteObject(m_redPen);
s_singleton = NULL;
}
void
CScreensLinks::doModal()
{
// do dialog
DialogBoxParam(s_instance, MAKEINTRESOURCE(IDD_SCREENS_LINKS),
m_parent, dlgProc, (LPARAM)this);
}
void
CScreensLinks::init(HWND hwnd)
{
// get initial config
m_scratchConfig = *m_mainConfig;
// fill side list box (in EDirection order)
HWND child = getItem(hwnd, IDC_SCREENS_SRC_SIDE);
SendMessage(child, CB_ADDSTRING, 0, (LPARAM)TEXT("---"));
SendMessage(child, CB_ADDSTRING, 0,
(LPARAM)getString(IDS_EDGE_LEFT).c_str());
SendMessage(child, CB_ADDSTRING, 0,
(LPARAM)getString(IDS_EDGE_RIGHT).c_str());
SendMessage(child, CB_ADDSTRING, 0,
(LPARAM)getString(IDS_EDGE_TOP).c_str());
SendMessage(child, CB_ADDSTRING, 0,
(LPARAM)getString(IDS_EDGE_BOTTOM).c_str());
// create error boxes
m_srcSideError = createErrorBox(hwnd);
m_srcScreenError = createErrorBox(hwnd);
m_dstScreenError = createErrorBox(hwnd);
resizeErrorBoxes();
m_selectedLink = -1;
m_editedLink = CEdgeLink();
m_edgeLinks.clear();
updateScreens(hwnd, "");
updateScreensControls(hwnd);
updateLinks(hwnd);
updateLinksControls(hwnd);
}
bool
CScreensLinks::save(HWND /*hwnd*/)
{
*m_mainConfig = m_scratchConfig;
return true;
}
BOOL
CScreensLinks::doDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message) {
case WM_INITDIALOG:
init(hwnd);
return TRUE;
case WM_SIZE:
resizeErrorBoxes();
break;
case WM_COMMAND:
switch (LOWORD(wParam)) {
case IDOK:
SetFocus(getItem(hwnd, IDOK));
if (save(hwnd)) {
EndDialog(hwnd, 0);
}
return TRUE;
case IDCANCEL:
EndDialog(hwnd, 0);
return TRUE;
case IDC_SCREENS_SCREENS:
switch (HIWORD(wParam)) {
case LBN_DBLCLK:
editScreen(hwnd);
return TRUE;
case LBN_SELCHANGE:
updateScreensControls(hwnd);
updateLinkView(hwnd);
return TRUE;
case LBN_SELCANCEL:
updateScreensControls(hwnd);
updateLinkView(hwnd);
return TRUE;
}
break;
case IDC_SCREENS_ADD_SCREEN:
addScreen(hwnd);
return TRUE;
case IDC_SCREENS_REMOVE_SCREEN:
removeScreen(hwnd);
return TRUE;
case IDC_SCREENS_EDIT_SCREEN:
editScreen(hwnd);
return TRUE;
case IDC_SCREENS_LINKS:
switch (HIWORD(wParam)) {
case LBN_SELCHANGE:
editLink(hwnd);
return TRUE;
case LBN_SELCANCEL:
editLink(hwnd);
return TRUE;
}
break;
case IDC_SCREENS_ADD_LINK:
addLink(hwnd);
return TRUE;
case IDC_SCREENS_REMOVE_LINK:
removeLink(hwnd);
return TRUE;
case IDC_SCREENS_SRC_SIDE:
switch (HIWORD(wParam)) {
case CBN_SELCHANGE:
changeSrcSide(hwnd);
break;
}
break;
case IDC_SCREENS_SRC_SCREEN:
switch (HIWORD(wParam)) {
case CBN_SELCHANGE:
changeSrcScreen(hwnd);
break;
}
break;
case IDC_SCREENS_DST_SCREEN:
switch (HIWORD(wParam)) {
case CBN_SELCHANGE:
changeDstScreen(hwnd);
break;
}
break;
case IDC_SCREENS_SRC_START:
switch (HIWORD(wParam)) {
case EN_KILLFOCUS:
changeIntervalStart(hwnd, LOWORD(wParam),
m_editedLink.m_srcInterval);
break;
}
break;
case IDC_SCREENS_SRC_END:
switch (HIWORD(wParam)) {
case EN_KILLFOCUS:
changeIntervalEnd(hwnd, LOWORD(wParam),
m_editedLink.m_srcInterval);
break;
}
break;
case IDC_SCREENS_DST_START:
switch (HIWORD(wParam)) {
case EN_KILLFOCUS:
changeIntervalStart(hwnd, LOWORD(wParam),
m_editedLink.m_dstInterval);
break;
}
break;
case IDC_SCREENS_DST_END:
switch (HIWORD(wParam)) {
case EN_KILLFOCUS:
changeIntervalEnd(hwnd, LOWORD(wParam),
m_editedLink.m_dstInterval);
break;
}
break;
}
break;
case WM_CTLCOLORSTATIC:
switch (GetDlgCtrlID((HWND)lParam)) {
case IDC_SCREENS_OVERLAP_ERROR:
SetBkColor((HDC)wParam, GetSysColor(COLOR_3DFACE));
SetTextColor((HDC)wParam, RGB(255, 0, 0));
return (BOOL)GetSysColorBrush(COLOR_3DFACE);
}
break;
// error outlines
case WM_DRAWITEM: {
DRAWITEMSTRUCT* di = (DRAWITEMSTRUCT*)lParam;
if (di->CtlType == ODT_STATIC) {
HGDIOBJ oldPen = SelectObject(di->hDC, m_redPen);
HGDIOBJ oldBrush = SelectObject(di->hDC,
GetStockObject(NULL_BRUSH));
Rectangle(di->hDC, di->rcItem.left, di->rcItem.top,
di->rcItem.right, di->rcItem.bottom);
SelectObject(di->hDC, oldPen);
SelectObject(di->hDC, oldBrush);
return TRUE;
}
break;
}
default:
break;
}
return FALSE;
}
BOOL CALLBACK
CScreensLinks::dlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
return s_singleton->doDlgProc(hwnd, message, wParam, lParam);
}
CString
CScreensLinks::getSelectedScreen(HWND hwnd) const
{
HWND child = getItem(hwnd, IDC_SCREENS_SCREENS);
LRESULT index = SendMessage(child, LB_GETCURSEL, 0, 0);
if (index == LB_ERR) {
return CString();
}
LRESULT size = SendMessage(child, LB_GETTEXTLEN, index, 0);
char* buffer = new char[size + 1];
SendMessage(child, LB_GETTEXT, index, (LPARAM)buffer);
buffer[size] = '\0';
CString result(buffer);
delete[] buffer;
return result;
}
void
CScreensLinks::addScreen(HWND hwnd)
{
CAddScreen dialog(hwnd, m_config, "");
if (dialog.doModal()) {
updateScreens(hwnd, dialog.getName());
updateScreensControls(hwnd);
updateLinks(hwnd);
updateLinksControls(hwnd);
}
}
void
CScreensLinks::editScreen(HWND hwnd)
{
CString oldName = getSelectedScreen(hwnd);
CAddScreen dialog(hwnd, m_config, oldName);
if (dialog.doModal()) {
CString newName = dialog.getName();
// rename screens in the edge list
if (newName != oldName) {
for (size_t i = 0; i < m_edgeLinks.size(); ++i) {
m_edgeLinks[i].rename(oldName, newName);
}
m_editedLink.rename(oldName, newName);
}
updateScreens(hwnd, newName);
updateScreensControls(hwnd);
updateLinks(hwnd);
updateLinksControls(hwnd);
}
}
void
CScreensLinks::removeScreen(HWND hwnd)
{
// remove screen from config (this also removes aliases)
m_config->removeScreen(getSelectedScreen(hwnd));
// update dialog
updateScreens(hwnd, "");
updateScreensControls(hwnd);
updateLinks(hwnd);
updateLinksControls(hwnd);
}
void
CScreensLinks::addLink(HWND hwnd)
{
if (m_editedLink.connect(m_config)) {
m_editedLink = CEdgeLink();
updateLinks(hwnd);
updateLinksControls(hwnd);
}
}
void
CScreensLinks::editLink(HWND hwnd)
{
// get selection
HWND child = getItem(hwnd, IDC_SCREENS_LINKS);
DWORD i = SendMessage(child, LB_GETCURSEL, 0, 0);
if (i != LB_ERR && i != (DWORD)m_edgeLinks.size()) {
// existing link
m_selectedLink = (SInt32)SendMessage(child, LB_GETITEMDATA, i, 0);
m_editedLink = m_edgeLinks[m_selectedLink];
}
else {
// new link
m_selectedLink = -1;
m_editedLink = CEdgeLink();
}
updateLinksControls(hwnd);
}
void
CScreensLinks::removeLink(HWND hwnd)
{
if (m_editedLink.disconnect(m_config)) {
updateLinks(hwnd);
updateLinksControls(hwnd);
}
}
void
CScreensLinks::updateScreens(HWND hwnd, const CString& selectName)
{
HWND child;
// set screen list
child = getItem(hwnd, IDC_SCREENS_SCREENS);
SendMessage(child, LB_RESETCONTENT, 0, 0);
for (CConfig::const_iterator index = m_config->begin();
index != m_config->end(); ) {
const CString& name = *index;
++index;
if (index != m_config->end()) {
SendMessage(child, LB_INSERTSTRING,
(WPARAM)-1, (LPARAM)name.c_str());
}
else {
SendMessage(child, LB_ADDSTRING, 0, (LPARAM)name.c_str());
}
}
// find the named screen
if (!selectName.empty()) {
DWORD i = SendMessage(child, LB_FINDSTRINGEXACT,
(UINT)-1, (LPARAM)selectName.c_str());
if (i != LB_ERR) {
SendMessage(child, LB_SETSEL, TRUE, i);
}
}
}
void
CScreensLinks::updateScreensControls(HWND hwnd)
{
HWND child = getItem(hwnd, IDC_SCREENS_SCREENS);
bool screenSelected = (SendMessage(child, LB_GETCURSEL, 0, 0) != LB_ERR);
enableItem(hwnd, IDC_SCREENS_ADD_SCREEN, TRUE);
enableItem(hwnd, IDC_SCREENS_EDIT_SCREEN, screenSelected);
enableItem(hwnd, IDC_SCREENS_REMOVE_SCREEN, screenSelected);
}
void
CScreensLinks::updateLinks(HWND hwnd)
{
HWND links = getItem(hwnd, IDC_SCREENS_LINKS);
HWND srcScreens = getItem(hwnd, IDC_SCREENS_SRC_SCREEN);
HWND dstScreens = getItem(hwnd, IDC_SCREENS_DST_SCREEN);
// get old selection
CEdgeLink oldLink;
if (m_selectedLink != -1) {
oldLink = m_edgeLinks[m_selectedLink];
}
// clear links and screens
SendMessage(links, LB_RESETCONTENT, 0, 0);
SendMessage(srcScreens, CB_RESETCONTENT, 0, 0);
SendMessage(dstScreens, CB_RESETCONTENT, 0, 0);
m_edgeLinks.clear();
// add "no screen" items
SendMessage(srcScreens, CB_INSERTSTRING, (WPARAM)-1, (LPARAM)TEXT("----"));
SendMessage(dstScreens, CB_INSERTSTRING, (WPARAM)-1, (LPARAM)TEXT("----"));
// add links and screens
for (CConfig::const_iterator i = m_config->begin();
i != m_config->end(); ++i) {
const CString& name = *i;
// add screen
SendMessage(srcScreens, CB_INSERTSTRING, (WPARAM)-1,
(LPARAM)name.c_str());
SendMessage(dstScreens, CB_INSERTSTRING, (WPARAM)-1,
(LPARAM)name.c_str());
// add links for screen
for (CConfig::link_const_iterator j = m_config->beginNeighbor(name),
n = m_config->endNeighbor(name);
j != n; ++j) {
DWORD k = m_edgeLinks.size();
m_edgeLinks.push_back(CEdgeLink(name, *j));
SendMessage(links, LB_INSERTSTRING, (WPARAM)-1,
(LPARAM)formatLink(m_edgeLinks.back()).c_str());
SendMessage(links, LB_SETITEMDATA, (WPARAM)k, (LPARAM)k);
}
}
// add "new link" item to sort
SendMessage(links, LB_ADDSTRING, 0, (LPARAM)m_newLinkLabel.c_str());
// remove the "new link" item then insert it on the end
DWORD i = SendMessage(links, LB_FINDSTRINGEXACT,
(UINT)-1, (LPARAM)m_newLinkLabel.c_str());
if (i != LB_ERR) {
SendMessage(links, LB_DELETESTRING, i, 0);
}
SendMessage(links, LB_INSERTSTRING, (WPARAM)-1,
(LPARAM)getString(IDS_NEW_LINK).c_str());
SendMessage(links, LB_SETITEMDATA, (WPARAM)m_edgeLinks.size(),
(LPARAM)-1);
// select the same link as before
SendMessage(links, LB_SETCURSEL, (WPARAM)m_edgeLinks.size(), 0);
if (m_selectedLink != -1) {
m_selectedLink = -1;
for (size_t j = 0; j < m_edgeLinks.size(); ++j) {
if (m_edgeLinks[j] == oldLink) {
// found matching link
m_selectedLink = j;
for (size_t k = 0; k < m_edgeLinks.size(); ++k) {
if (SendMessage(links, LB_GETITEMDATA, k, 0) == (int)j) {
SendMessage(links, LB_SETCURSEL, k, 0);
break;
}
}
break;
}
}
// if we can't find the link anymore then reset edited link
if (m_selectedLink == -1) {
m_editedLink = CEdgeLink();
}
}
}
void
CScreensLinks::updateLinksControls(HWND hwnd)
{
// get selection. select "new link" if nothing is selected.
HWND child = getItem(hwnd, IDC_SCREENS_LINKS);
if (m_selectedLink == -1) {
SendMessage(child, LB_SETCURSEL, m_edgeLinks.size(), 0);
}
// enable/disable remove button
enableItem(hwnd, IDC_SCREENS_REMOVE_LINK, m_selectedLink != -1);
// fill link entry controls from m_editedLink
updateLinkEditControls(hwnd, m_editedLink);
updateLinkValid(hwnd, m_editedLink);
updateLinkView(hwnd);
}
void
CScreensLinks::changeSrcSide(HWND hwnd)
{
HWND child = getItem(hwnd, IDC_SCREENS_SRC_SIDE);
m_editedLink.m_srcSide = (EDirection)SendMessage(child, CB_GETCURSEL, 0, 0);
updateLink(hwnd);
}
void
CScreensLinks::changeSrcScreen(HWND hwnd)
{
HWND child = getItem(hwnd, IDC_SCREENS_SRC_SCREEN);
m_editedLink.m_srcName = getWindowText(child);
updateLink(hwnd);
}
void
CScreensLinks::changeDstScreen(HWND hwnd)
{
HWND child = getItem(hwnd, IDC_SCREENS_DST_SCREEN);
m_editedLink.m_dstName = getWindowText(child);
updateLink(hwnd);
}
void
CScreensLinks::changeIntervalStart(HWND hwnd, int id, CConfig::CInterval& i)
{
int x = (int)GetDlgItemInt(hwnd, id, NULL, FALSE);
if (x < 0) {
x = 0;
}
else if (x > 99) {
x = 99;
}
i.first = 0.01f * (float)x;
if (i.first >= i.second) {
i.second = 0.01f * (float)(x + 1);
}
updateLinkIntervalControls(hwnd, m_editedLink);
updateLink(hwnd);
}
void
CScreensLinks::changeIntervalEnd(HWND hwnd, int id, CConfig::CInterval& i)
{
int x = (int)GetDlgItemInt(hwnd, id, NULL, FALSE);
if (x < 1) {
x = 1;
}
else if (x > 100) {
x = 100;
}
i.second = 0.01f * (float)x;
if (i.first >= i.second) {
i.first = 0.01f * (float)(x - 1);
}
updateLinkIntervalControls(hwnd, m_editedLink);
updateLink(hwnd);
}
void
CScreensLinks::selectScreen(HWND hwnd, int id, const CString& name)
{
HWND child = getItem(hwnd, id);
DWORD i = SendMessage(child, CB_FINDSTRINGEXACT, (WPARAM)-1,
(LPARAM)name.c_str());
if (i == CB_ERR) {
// no match, select no screen
SendMessage(child, CB_SETCURSEL, 0, 0);
}
else {
SendMessage(child, CB_SETCURSEL, i, 0);
}
}
void
CScreensLinks::updateLinkEditControls(HWND hwnd, const CEdgeLink& link)
{
// fill link entry controls from link
HWND child = getItem(hwnd, IDC_SCREENS_SRC_SIDE);
SendMessage(child, CB_SETCURSEL, link.m_srcSide, 0);
selectScreen(hwnd, IDC_SCREENS_SRC_SCREEN, link.m_srcName);
selectScreen(hwnd, IDC_SCREENS_DST_SCREEN, link.m_dstName);
updateLinkIntervalControls(hwnd, link);
}
void
CScreensLinks::updateLinkIntervalControls(HWND hwnd, const CEdgeLink& link)
{
HWND child;
// src interval
child = getItem(hwnd, IDC_SCREENS_SRC_START);
setWindowText(child, formatIntervalValue(link.m_srcInterval.first));
child = getItem(hwnd, IDC_SCREENS_SRC_END);
setWindowText(child, formatIntervalValue(link.m_srcInterval.second));
// dst interval
child = getItem(hwnd, IDC_SCREENS_DST_START);
setWindowText(child, formatIntervalValue(link.m_dstInterval.first));
child = getItem(hwnd, IDC_SCREENS_DST_END);
setWindowText(child, formatIntervalValue(link.m_dstInterval.second));
}
void
CScreensLinks::updateLink(HWND hwnd)
{
updateLinkValid(hwnd, m_editedLink);
// update link in config
if (m_selectedLink != -1 && m_editedLinkIsValid) {
// editing an existing link and entry is valid
if (m_edgeLinks[m_selectedLink].disconnect(m_config)) {
// successfully removed old link
if (!m_editedLink.connect(m_config)) {
// couldn't set new link so restore old link
m_edgeLinks[m_selectedLink].connect(m_config);
}
else {
m_edgeLinks[m_selectedLink] = m_editedLink;
updateLinks(hwnd);
updateLinkEditControls(hwnd, m_editedLink);
}
}
}
updateLinkView(hwnd);
}
void
CScreensLinks::updateLinkValid(HWND hwnd, const CEdgeLink& link)
{
m_editedLinkIsValid = true;
// check source side and screen
if (link.m_srcSide == kNoDirection) {
m_editedLinkIsValid = false;
ShowWindow(m_srcSideError, SW_SHOWNA);
}
else {
ShowWindow(m_srcSideError, SW_HIDE);
}
if (!m_config->isCanonicalName(link.m_srcName)) {
m_editedLinkIsValid = false;
ShowWindow(m_srcScreenError, SW_SHOWNA);
}
else {
ShowWindow(m_srcScreenError, SW_HIDE);
}
// check for overlap. if editing a link we must remove it, then
// check for overlap and restore the old link.
bool overlap = false;
if (m_editedLinkIsValid) {
if (m_selectedLink == -1) {
if (link.overlaps(m_config)) {
m_editedLinkIsValid = false;
overlap = true;
}
}
else {
if (m_edgeLinks[m_selectedLink].disconnect(m_config)) {
overlap = link.overlaps(m_config);
m_edgeLinks[m_selectedLink].connect(m_config);
if (overlap) {
m_editedLinkIsValid = false;
}
}
}
}
ShowWindow(getItem(hwnd, IDC_SCREENS_OVERLAP_ERROR),
overlap ? SW_SHOWNA : SW_HIDE);
// check dst screen
if (!m_config->isCanonicalName(link.m_dstName)) {
m_editedLinkIsValid = false;
ShowWindow(m_dstScreenError, SW_SHOWNA);
}
else {
ShowWindow(m_dstScreenError, SW_HIDE);
}
// update add link button
enableItem(hwnd, IDC_SCREENS_ADD_LINK,
m_selectedLink == -1 && m_editedLinkIsValid);
}
void
CScreensLinks::updateLinkView(HWND /*hwnd*/)
{
// XXX -- draw visual of selected screen, highlighting selected link
}
HWND
CScreensLinks::createErrorBox(HWND parent)
{
return CreateWindow(TEXT("STATIC"), TEXT(""),
WS_CHILD | SS_OWNERDRAW,
0, 0, 1, 1,
parent, (HMENU)-1,
s_instance, NULL);
}
void
CScreensLinks::resizeErrorBoxes()
{
HWND hwnd = GetParent(m_srcSideError);
resizeErrorBox(m_srcSideError, getItem(hwnd, IDC_SCREENS_SRC_SIDE));
resizeErrorBox(m_srcScreenError, getItem(hwnd, IDC_SCREENS_SRC_SCREEN));
resizeErrorBox(m_dstScreenError, getItem(hwnd, IDC_SCREENS_DST_SCREEN));
}
void
CScreensLinks::resizeErrorBox(HWND box, HWND assoc)
{
RECT rect;
GetWindowRect(assoc, &rect);
MapWindowPoints(NULL, GetParent(box), (POINT*)&rect, 2);
SetWindowPos(box, HWND_TOP, rect.left - 1, rect.top - 1,
rect.right - rect.left + 2,
rect.bottom - rect.top + 2, SWP_NOACTIVATE);
}
CString
CScreensLinks::formatIntervalValue(float x) const
{
return CStringUtil::print("%d", (int)(x * 100.0f + 0.5f));
}
CString
CScreensLinks::formatInterval(const CConfig::CInterval& i) const
{
if (i.first == 0.0f && i.second == 1.0f) {
return "";
}
else {
CString start = formatIntervalValue(i.first);
CString end = formatIntervalValue(i.second);
return CStringUtil::format(m_intervalFormat.c_str(),
start.c_str(), end.c_str());
}
}
CString
CScreensLinks::formatLink(const CEdgeLink& link) const
{
CString srcInterval = formatInterval(link.m_srcInterval);
CString dstInterval = formatInterval(link.m_dstInterval);
return CStringUtil::format(m_linkFormat.c_str(),
link.m_srcName.c_str(), srcInterval.c_str(),
m_sideLabel[link.m_srcSide - kFirstDirection].c_str(),
link.m_dstName.c_str(), dstInterval.c_str());
}
//
// CScreensLinks::CEdgeLink
//
CScreensLinks::CEdgeLink::CEdgeLink() :
m_srcName(),
m_srcSide(kNoDirection),
m_srcInterval(0.0f, 1.0f),
m_dstName(),
m_dstInterval(0.0f, 1.0f)
{
// do nothing
}
CScreensLinks::CEdgeLink::CEdgeLink(const CString& name,
const CConfigLink& link) :
m_srcName(name),
m_srcSide(link.first.getSide()),
m_srcInterval(link.first.getInterval()),
m_dstName(link.second.getName()),
m_dstInterval(link.second.getInterval())
{
// do nothing
}
bool
CScreensLinks::CEdgeLink::connect(CConfig* config)
{
return config->connect(m_srcName, m_srcSide,
m_srcInterval.first, m_srcInterval.second,
m_dstName,
m_dstInterval.first, m_dstInterval.second);
}
bool
CScreensLinks::CEdgeLink::disconnect(CConfig* config)
{
return config->disconnect(m_srcName, m_srcSide, 0.5f *
(m_srcInterval.first + m_srcInterval.second));
}
void
CScreensLinks::CEdgeLink::rename(const CString& oldName, const CString& newName)
{
if (m_srcName == oldName) {
m_srcName = newName;
}
if (m_dstName == oldName) {
m_dstName = newName;
}
}
bool
CScreensLinks::CEdgeLink::overlaps(const CConfig* config) const
{
return config->hasNeighbor(m_srcName, m_srcSide,
m_srcInterval.first, m_srcInterval.second);
}
bool
CScreensLinks::CEdgeLink::operator==(const CEdgeLink& x) const
{
return (m_srcName == x.m_srcName &&
m_srcSide == x.m_srcSide &&
m_srcInterval == x.m_srcInterval &&
m_dstName == x.m_dstName &&
m_dstInterval == x.m_dstInterval);
}

View File

@ -0,0 +1,138 @@
/*
* synergy -- mouse and keyboard sharing utility
* Copyright (C) 2003 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 COPYING 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.
*/
#ifndef CSCREENSLINKS_H
#define CSCREENSLINKS_H
#include "CConfig.h"
#include "ProtocolTypes.h"
#include "CString.h"
#define WINDOWS_LEAN_AND_MEAN
#include <windows.h>
//! Screens and links dialog for Microsoft Windows launcher
class CScreensLinks {
public:
CScreensLinks(HWND parent, CConfig*);
~CScreensLinks();
//! @name manipulators
//@{
//! Run dialog
/*!
Display and handle the dialog until closed by the user.
*/
void doModal();
//@}
//! @name accessors
//@{
//@}
private:
typedef std::pair<CConfig::CCellEdge, CConfig::CCellEdge> CConfigLink;
struct CEdgeLink {
public:
CEdgeLink();
CEdgeLink(const CString& name, const CConfigLink&);
bool connect(CConfig*);
bool disconnect(CConfig*);
void rename(const CString& oldName, const CString& newName);
bool overlaps(const CConfig* config) const;
bool operator==(const CEdgeLink&) const;
public:
CString m_srcName;
EDirection m_srcSide;
CConfig::CInterval m_srcInterval;
CString m_dstName;
CConfig::CInterval m_dstInterval;
};
typedef std::vector<CEdgeLink> CEdgeLinkList;
void init(HWND hwnd);
bool save(HWND hwnd);
CString getSelectedScreen(HWND hwnd) const;
void addScreen(HWND hwnd);
void editScreen(HWND hwnd);
void removeScreen(HWND hwnd);
void addLink(HWND hwnd);
void editLink(HWND hwnd);
void removeLink(HWND hwnd);
void updateScreens(HWND hwnd, const CString& name);
void updateScreensControls(HWND hwnd);
void updateLinks(HWND hwnd);
void updateLinksControls(HWND hwnd);
void changeSrcSide(HWND hwnd);
void changeSrcScreen(HWND hwnd);
void changeDstScreen(HWND hwnd);
void changeIntervalStart(HWND hwnd, int id,
CConfig::CInterval&);
void changeIntervalEnd(HWND hwnd, int id,
CConfig::CInterval&);
void selectScreen(HWND hwnd, int id, const CString& name);
void updateLinkEditControls(HWND hwnd,
const CEdgeLink& link);
void updateLinkIntervalControls(HWND hwnd,
const CEdgeLink& link);
void updateLink(HWND hwnd);
void updateLinkValid(HWND hwnd, const CEdgeLink& link);
void updateLinkView(HWND hwnd);
HWND createErrorBox(HWND parent);
void resizeErrorBoxes();
void resizeErrorBox(HWND box, HWND assoc);
CString formatIntervalValue(float) const;
CString formatInterval(const CConfig::CInterval&) const;
CString formatLink(const CEdgeLink&) const;
// message handling
BOOL doDlgProc(HWND, UINT, WPARAM, LPARAM);
static BOOL CALLBACK dlgProc(HWND, UINT, WPARAM, LPARAM);
private:
static CScreensLinks* s_singleton;
HWND m_parent;
CConfig* m_mainConfig;
CConfig m_scratchConfig;
CConfig* m_config;
CString m_linkFormat;
CString m_intervalFormat;
CString m_newLinkLabel;
CString m_sideLabel[kNumDirections];
CEdgeLinkList m_edgeLinks;
SInt32 m_selectedLink;
CEdgeLink m_editedLink;
bool m_editedLinkIsValid;
HPEN m_redPen;
HWND m_srcSideError;
HWND m_srcScreenError;
HWND m_dstScreenError;
};
#endif

View File

@ -19,7 +19,7 @@
#include "resource.h"
#include "stdfstream.h"
#define CONFIG_NAME "synergy.sgc"
size_t s_showingDialog = 0;
CString
getString(DWORD id)
@ -37,24 +37,36 @@ void
showError(HWND hwnd, const CString& msg)
{
CString title = getString(IDS_ERROR);
++s_showingDialog;
MessageBox(hwnd, msg.c_str(), title.c_str(), MB_OK | MB_APPLMODAL);
--s_showingDialog;
}
void
askOkay(HWND hwnd, const CString& title, const CString& msg)
{
++s_showingDialog;
MessageBox(hwnd, msg.c_str(), title.c_str(), MB_OK | MB_APPLMODAL);
--s_showingDialog;
}
bool
askVerify(HWND hwnd, const CString& msg)
{
CString title = getString(IDS_VERIFY);
++s_showingDialog;
int result = MessageBox(hwnd, msg.c_str(),
title.c_str(), MB_OKCANCEL | MB_APPLMODAL);
--s_showingDialog;
return (result == IDOK);
}
bool
isShowingDialog()
{
return (s_showingDialog != 0);
}
void
setWindowText(HWND hwnd, const CString& msg)
{
@ -109,6 +121,39 @@ getAppPath(const CString& appName)
return appPath;
}
static
void
getFileTime(const CString& path, time_t& t)
{
struct _stat s;
if (_stat(path.c_str(), &s) != -1) {
t = s.st_mtime;
}
}
bool
isConfigNewer(time_t& oldTime, bool userConfig)
{
time_t newTime = oldTime;
if (userConfig) {
CString path = ARCH->getUserDirectory();
if (!path.empty()) {
path = ARCH->concatPath(path, CONFIG_NAME);
getFileTime(path, newTime);
}
}
else {
CString path = ARCH->getSystemDirectory();
if (!path.empty()) {
path = ARCH->concatPath(path, CONFIG_NAME);
getFileTime(path, newTime);
}
}
bool result = (newTime > oldTime);
oldTime = newTime;
return result;
}
static
bool
loadConfig(const CString& pathname, CConfig& config)
@ -127,7 +172,7 @@ loadConfig(const CString& pathname, CConfig& config)
}
bool
loadConfig(CConfig& config)
loadConfig(CConfig& config, time_t& t, bool& userConfig)
{
// load configuration
bool configLoaded = false;
@ -137,6 +182,8 @@ loadConfig(CConfig& config)
path = ARCH->concatPath(path, CONFIG_NAME);
if (loadConfig(path, config)) {
configLoaded = true;
userConfig = true;
getFileTime(path, t);
}
else {
// try the system-wide config file
@ -145,6 +192,8 @@ loadConfig(CConfig& config)
path = ARCH->concatPath(path, CONFIG_NAME);
if (loadConfig(path, config)) {
configLoaded = true;
userConfig = false;
getFileTime(path, t);
}
}
}
@ -170,7 +219,7 @@ saveConfig(const CString& pathname, const CConfig& config)
}
bool
saveConfig(const CConfig& config, bool sysOnly)
saveConfig(const CConfig& config, bool sysOnly, time_t& t)
{
// try saving the user's configuration
if (!sysOnly) {
@ -178,6 +227,7 @@ saveConfig(const CConfig& config, bool sysOnly)
if (!path.empty()) {
path = ARCH->concatPath(path, CONFIG_NAME);
if (saveConfig(path, config)) {
getFileTime(path, t);
return true;
}
}
@ -189,6 +239,7 @@ saveConfig(const CConfig& config, bool sysOnly)
if (!path.empty()) {
path = ARCH->concatPath(path, CONFIG_NAME);
if (saveConfig(path, config)) {
getFileTime(path, t);
return true;
}
}

View File

@ -19,9 +19,12 @@
#define WINDOWS_LEAN_AND_MEAN
#include <windows.h>
#include <sys/types.h>
#include <sys/stat.h>
#define CLIENT_APP "synergyc.exe"
#define SERVER_APP "synergys.exe"
#define CONFIG_NAME "synergy.sgc"
class CConfig;
@ -35,6 +38,7 @@ void showError(HWND hwnd, const CString& msg);
void askOkay(HWND hwnd, const CString& title,
const CString& msg);
bool askVerify(HWND hwnd, const CString& msg);
bool isShowingDialog();
void setWindowText(HWND hwnd, const CString& msg);
CString getWindowText(HWND hwnd);
@ -47,8 +51,10 @@ bool isItemChecked(HWND);
CString getAppPath(const CString& appName);
bool loadConfig(CConfig& config);
bool saveConfig(const CConfig& config, bool sysOnly);
bool isConfigNewer(time_t&, bool userConfig);
bool loadConfig(CConfig& config, time_t&, bool& userConfig);
bool saveConfig(const CConfig& config,
bool sysOnly, time_t&);
const TCHAR* const* getSettingsPath();

View File

@ -14,14 +14,22 @@
NULL =
MSWINDOWS_SOURCE_FILES = \
CAddScreen.cpp \
CAdvancedOptions.cpp \
CAutoStart.cpp \
CGlobalOptions.cpp \
CHotkeyOptions.cpp \
CInfo.cpp \
CScreensLinks.cpp \
LaunchUtil.cpp \
launcher.cpp \
CAddScreen.h \
CAdvancedOptions.h \
CAutoStart.h \
CGlobalOptions.h \
CHotkeyOptions.h \
CInfo.h \
CScreensLinks.h \
LaunchUtil.h \
resource.h \
launcher.rc \

File diff suppressed because it is too large Load Diff

View File

@ -43,7 +43,7 @@ RSC=rc.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /MT /W4 /GX /O2 /I "..\..\lib\common" /I "..\..\lib\arch" /I "..\..\lib\base" /I "..\..\lib\mt" /I "..\..\lib\io" /I "..\..\lib\net" /I "..\..\lib\synergy" /I "..\..\lib\platform" /I "..\..\lib\server" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /Fd"..\..\gen\build\launcher.pdb" /FD /c
# ADD CPP /nologo /MT /W4 /GR /GX /O2 /I "..\..\lib\common" /I "..\..\lib\arch" /I "..\..\lib\base" /I "..\..\lib\mt" /I "..\..\lib\io" /I "..\..\lib\net" /I "..\..\lib\synergy" /I "..\..\lib\platform" /I "..\..\lib\server" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /Fd"..\..\gen\build\launcher.pdb" /FD /c
# SUBTRACT CPP /YX
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
@ -71,7 +71,7 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
# ADD CPP /nologo /MTd /W4 /Gm /GX /ZI /Od /I "..\..\lib\common" /I "..\..\lib\arch" /I "..\..\lib\base" /I "..\..\lib\mt" /I "..\..\lib\io" /I "..\..\lib\net" /I "..\..\lib\synergy" /I "..\..\lib\platform" /I "..\..\lib\server" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /Fd"..\..\gen\debug\launcher.pdb" /FD /GZ /c
# ADD CPP /nologo /MTd /W4 /Gm /GR /GX /ZI /Od /I "..\..\lib\common" /I "..\..\lib\arch" /I "..\..\lib\base" /I "..\..\lib\mt" /I "..\..\lib\io" /I "..\..\lib\net" /I "..\..\lib\synergy" /I "..\..\lib\platform" /I "..\..\lib\server" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /Fd"..\..\gen\debug\launcher.pdb" /FD /GZ /c
# SUBTRACT CPP /YX
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
@ -95,6 +95,10 @@ LINK32=link.exe
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
# Begin Source File
SOURCE=.\CAddScreen.cpp
# End Source File
# Begin Source File
SOURCE=.\CAdvancedOptions.cpp
# End Source File
# Begin Source File
@ -107,6 +111,18 @@ SOURCE=.\CGlobalOptions.cpp
# End Source File
# Begin Source File
SOURCE=.\CHotkeyOptions.cpp
# End Source File
# Begin Source File
SOURCE=.\CInfo.cpp
# End Source File
# Begin Source File
SOURCE=.\CScreensLinks.cpp
# End Source File
# Begin Source File
SOURCE=.\launcher.cpp
# End Source File
# Begin Source File
@ -123,6 +139,10 @@ SOURCE=.\LaunchUtil.cpp
# PROP Default_Filter "h;hpp;hxx;hm;inl"
# Begin Source File
SOURCE=.\CAddScreen.h
# End Source File
# Begin Source File
SOURCE=.\CAdvancedOptions.h
# End Source File
# Begin Source File
@ -135,6 +155,18 @@ SOURCE=.\CGlobalOptions.h
# End Source File
# Begin Source File
SOURCE=.\CHotkeyOptions.h
# End Source File
# Begin Source File
SOURCE=.\CInfo.h
# End Source File
# Begin Source File
SOURCE=.\CScreensLinks.h
# End Source File
# Begin Source File
SOURCE=.\LaunchUtil.h
# End Source File
# Begin Source File

View File

@ -7,10 +7,7 @@
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "winres.h"
#if !defined(IDC_STATIC)
#define IDC_STATIC (-1)
#endif
#include "afxres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
@ -55,55 +52,41 @@ END
// Dialog
//
IDD_MAIN DIALOG DISCARDABLE 32768, 0, 300, 262
IDD_MAIN DIALOG DISCARDABLE 32768, 0, 300, 199
STYLE DS_MODALFRAME | WS_MINIMIZEBOX | WS_CAPTION | WS_SYSMENU
CAPTION "Synergy"
CLASS "GoSynergy"
FONT 8, "MS Sans Serif"
BEGIN
LTEXT "Choose to start either the Client or Server and provide the requested information. Then click Test to check your settings or Start to save your settings and start Synergy.",
LTEXT "Choose to share or use a shared keyboard and mouse, provide the requested information, then click Test to check your settings or Start to save your settings and start Synergy.",
IDC_STATIC,7,7,286,19
GROUPBOX "",IDC_STATIC,7,29,286,31
GROUPBOX "",IDC_STATIC,7,67,286,103
GROUPBOX "Options",IDC_STATIC,7,177,286,56
CONTROL "&Client",IDC_MAIN_CLIENT_RADIO,"Button",
BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,11,29,33,10
CONTROL "Server",IDC_MAIN_SERVER_RADIO,"Button",
BS_AUTORADIOBUTTON,11,67,37,10
LTEXT "Server &Host Name:",IDC_MAIN_CLIENT_SERVER_NAME_LABEL,
12,41,61,8
EDITTEXT IDC_MAIN_CLIENT_SERVER_NAME_EDIT,79,39,106,12,
GROUPBOX "",IDC_STATIC,7,29,286,36
GROUPBOX "",IDC_STATIC,7,72,286,36
GROUPBOX "Options",IDC_STATIC,7,115,286,56
CONTROL "&Use another computer's shared keyboard and mouse (client)",
IDC_MAIN_CLIENT_RADIO,"Button",BS_AUTORADIOBUTTON |
WS_GROUP | WS_TABSTOP,11,29,205,10
CONTROL "Share this computer's keyboard and mouse (server)",
IDC_MAIN_SERVER_RADIO,"Button",BS_AUTORADIOBUTTON,11,72,
177,10
LTEXT "Other Computer's &Host Name:",
IDC_MAIN_CLIENT_SERVER_NAME_LABEL,12,46,94,8
EDITTEXT IDC_MAIN_CLIENT_SERVER_NAME_EDIT,111,44,106,12,
ES_AUTOHSCROLL
LTEXT "&Screens:",IDC_MAIN_SERVER_SCREENS_LABEL,12,79,29,8
LISTBOX IDC_MAIN_SERVER_SCREENS_LIST,12,91,106,36,
LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "&Add",IDC_MAIN_SERVER_ADD_BUTTON,12,132,50,14
PUSHBUTTON "&Edit",IDC_MAIN_SERVER_EDIT_BUTTON,68,132,50,14
PUSHBUTTON "&Remove",IDC_MAIN_SERVER_REMOVE_BUTTON,12,150,50,14
LTEXT "&Layout:",IDC_MAIN_SERVER_LAYOUT_LABEL,138,79,24,8
LTEXT "Left:",IDC_MAIN_SERVER_LEFT_LABEL,144,93,15,8
COMBOBOX IDC_MAIN_SERVER_LEFT_COMBO,175,91,111,75,
CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
LTEXT "Right:",IDC_MAIN_SERVER_RIGHT_LABEL,144,109,20,8
COMBOBOX IDC_MAIN_SERVER_RIGHT_COMBO,175,107,112,75,
CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
LTEXT "Above:",IDC_MAIN_SERVER_TOP_LABEL,144,125,24,8
COMBOBOX IDC_MAIN_SERVER_TOP_COMBO,175,123,112,75,
CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
LTEXT "Below:",IDC_MAIN_SERVER_BOTTOM_LABEL,144,141,22,8
COMBOBOX IDC_MAIN_SERVER_BOTTOM_COMBO,175,139,112,75,
CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "&Options...",IDC_MAIN_OPTIONS,12,191,50,14
PUSHBUTTON "Adva&nced...",IDC_MAIN_ADVANCED,68,191,50,14
LTEXT "Automatic Startup:",IDC_STATIC,138,193,59,8
PUSHBUTTON "Con&figure...",IDC_MAIN_AUTOSTART,202,191,50,14
LTEXT "Lo&gging Level:",IDC_STATIC,12,216,48,8
COMBOBOX IDC_MAIN_DEBUG,68,213,61,60,CBS_DROPDOWNLIST |
LTEXT "&Screens && Links:",IDC_MAIN_SERVER_SCREENS_LABEL,12,89,
54,8
PUSHBUTTON "Configure...",IDC_MAIN_SCREENS,71,86,50,14
PUSHBUTTON "&Options...",IDC_MAIN_OPTIONS,12,129,50,14
PUSHBUTTON "Hot &Keys...",IDC_MAIN_HOTKEYS,68,129,50,14
PUSHBUTTON "Adva&nced...",IDC_MAIN_ADVANCED,124,129,50,14
PUSHBUTTON "&AutoStart...",IDC_MAIN_AUTOSTART,180,129,50,14
LTEXT "&Logging Level:",IDC_STATIC,12,154,48,8
COMBOBOX IDC_MAIN_DEBUG,68,151,61,60,CBS_DROPDOWNLIST |
WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "Sa&ve",IDC_MAIN_SAVE,75,241,50,14
DEFPUSHBUTTON "&Test",IDC_MAIN_TEST,131,241,50,14
PUSHBUTTON "Start",IDOK,187,241,50,14
PUSHBUTTON "Quit",IDCANCEL,243,241,50,14
PUSHBUTTON "&Info",IDC_MAIN_INFO,7,178,50,14
DEFPUSHBUTTON "&Test",IDC_MAIN_TEST,131,179,50,14
PUSHBUTTON "Start",IDOK,187,179,50,14
PUSHBUTTON "Quit",IDCANCEL,243,179,50,14
END
IDD_ADD DIALOG DISCARDABLE 0, 0, 192, 254
@ -114,33 +97,46 @@ BEGIN
LTEXT "&Screen Name:",IDC_STATIC,7,9,46,8
EDITTEXT IDC_ADD_SCREEN_NAME_EDIT,79,7,106,12,ES_AUTOHSCROLL
LTEXT "&Aliases:",IDC_STATIC,7,25,25,8
EDITTEXT IDC_ADD_ALIASES_EDIT,79,26,106,40,ES_MULTILINE |
EDITTEXT IDC_ADD_ALIASES_EDIT,79,26,106,24,ES_MULTILINE |
ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN
GROUPBOX "Options",IDC_STATIC,7,72,178,80
GROUPBOX "Options",IDC_STATIC,7,55,178,54
LTEXT "If your Caps, Num, or Scroll Lock keys behave strangely on this client screen then try turning the half-duplex options on and reconnect the client.",
IDC_STATIC,13,82,165,25
CONTROL "Half-duplex &Caps Lock",IDC_ADD_HD_CAPS_CHECK,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,13,110,165,10
CONTROL "Half-duplex &Num Lock",IDC_ADD_HD_NUM_CHECK,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,13,122,165,10
CONTROL "Half-duplex Sc&roll Lock",IDC_ADD_HD_SCROLL_CHECK,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,134,165,10
GROUPBOX "Modifiers",IDC_STATIC,7,155,178,65
LTEXT "Shift",IDC_STATIC,13,171,15,8
COMBOBOX IDC_ADD_MOD_SHIFT,37,168,48,60,CBS_DROPDOWNLIST |
IDC_STATIC,13,65,165,25
CONTROL "&Caps Lock",IDC_ADD_HD_CAPS_CHECK,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,13,93,51,10
CONTROL "&Num Lock",IDC_ADD_HD_NUM_CHECK,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,69,93,51,10
CONTROL "Sc&roll Lock",IDC_ADD_HD_SCROLL_CHECK,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,125,93,51,10
GROUPBOX "Modifiers",IDC_STATIC,7,113,178,65
LTEXT "Shift",IDC_STATIC,13,129,15,8
COMBOBOX IDC_ADD_MOD_SHIFT,37,126,48,60,CBS_DROPDOWNLIST |
WS_VSCROLL | WS_TABSTOP
LTEXT "Ctrl",IDC_STATIC,13,186,11,8
COMBOBOX IDC_ADD_MOD_CTRL,37,184,48,60,CBS_DROPDOWNLIST |
LTEXT "Ctrl",IDC_STATIC,13,144,11,8
COMBOBOX IDC_ADD_MOD_CTRL,37,142,48,60,CBS_DROPDOWNLIST |
WS_VSCROLL | WS_TABSTOP
LTEXT "Alt",IDC_STATIC,13,202,9,8
COMBOBOX IDC_ADD_MOD_ALT,37,200,48,60,CBS_DROPDOWNLIST |
LTEXT "Alt",IDC_STATIC,13,160,9,8
COMBOBOX IDC_ADD_MOD_ALT,37,158,48,60,CBS_DROPDOWNLIST |
WS_VSCROLL | WS_TABSTOP
LTEXT "Meta",IDC_STATIC,101,170,17,8
COMBOBOX IDC_ADD_MOD_META,125,168,48,60,CBS_DROPDOWNLIST |
LTEXT "Meta",IDC_STATIC,101,128,17,8
COMBOBOX IDC_ADD_MOD_META,125,126,48,60,CBS_DROPDOWNLIST |
WS_VSCROLL | WS_TABSTOP
LTEXT "Super",IDC_STATIC,101,186,20,8
COMBOBOX IDC_ADD_MOD_SUPER,125,184,48,60,CBS_DROPDOWNLIST |
LTEXT "Super",IDC_STATIC,101,144,20,8
COMBOBOX IDC_ADD_MOD_SUPER,125,142,48,60,CBS_DROPDOWNLIST |
WS_VSCROLL | WS_TABSTOP
GROUPBOX "Dead Corners",IDC_STATIC,7,183,178,43
LTEXT "Don't switch in these corners:",IDC_STATIC,14,198,52,18
CONTROL "",IDC_STATIC,"Static",SS_BLACKFRAME,68,193,47,28
CONTROL "",IDC_ADD_DC_TOP_LEFT,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,76,197,16,8
CONTROL "",IDC_ADD_DC_TOP_RIGHT,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,98,197,16,8
CONTROL "",IDC_ADD_DC_BOTTOM_LEFT,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,76,210,16,8
CONTROL "",IDC_ADD_DC_BOTTOM_RIGHT,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,98,210,16,8
LTEXT "Size",IDC_STATIC,120,202,14,8
EDITTEXT IDC_ADD_DC_SIZE,139,200,40,12,ES_AUTOHSCROLL | ES_NUMBER
DEFPUSHBUTTON "OK",IDOK,79,233,50,14
PUSHBUTTON "Cancel",IDCANCEL,135,233,50,14
END
@ -175,7 +171,7 @@ BEGIN
IDC_STATIC,7,43,181,17
END
IDD_GLOBAL_OPTIONS DIALOG DISCARDABLE 0, 0, 207, 269
IDD_GLOBAL_OPTIONS DIALOG DISCARDABLE 0, 0, 207, 290
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Options"
FONT 8, "MS Sans Serif"
@ -207,12 +203,15 @@ BEGIN
IDC_STATIC,7,176,193,8
CONTROL "Synchronize screen savers",IDC_GLOBAL_SCREENSAVER_SYNC,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,192,101,10
LTEXT "Experimental: Relative mouse moves on secondary screens.",
IDC_STATIC,7,213,193,8
LTEXT "Relative mouse moves on secondary screens.",IDC_STATIC,
7,213,193,8
CONTROL "Use relative mouse moves",IDC_GLOBAL_RELATIVE_MOVES,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,229,99,10
DEFPUSHBUTTON "OK",IDOK,94,248,50,14
PUSHBUTTON "Cancel",IDCANCEL,150,248,50,14
CONTROL "Don't take foreground window on Windows servers",
IDC_GLOBAL_LEAVE_FOREGROUND,"Button",BS_AUTOCHECKBOX |
WS_TABSTOP,7,250,177,10
DEFPUSHBUTTON "OK",IDOK,94,269,50,14
PUSHBUTTON "Cancel",IDCANCEL,150,269,50,14
END
IDD_ADVANCED_OPTIONS DIALOG DISCARDABLE 0, 0, 230, 186
@ -238,6 +237,158 @@ BEGIN
PUSHBUTTON "Cancel",IDCANCEL,173,165,50,14
END
IDD_SCREENS_LINKS DIALOG DISCARDABLE 0, 0, 354, 213
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Screens & Links"
FONT 8, "MS Sans Serif"
BEGIN
LTEXT "&Screens:",IDC_STATIC,7,7,29,8
LISTBOX IDC_SCREENS_SCREENS,7,18,100,36,LBS_SORT |
LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "+",IDC_SCREENS_ADD_SCREEN,7,57,17,14
PUSHBUTTON "-",IDC_SCREENS_REMOVE_SCREEN,28,57,17,14
PUSHBUTTON "Edit",IDC_SCREENS_EDIT_SCREEN,49,57,24,14
LTEXT "&Links:",IDC_STATIC,7,83,20,8
LISTBOX IDC_SCREENS_LINKS,7,94,339,59,LBS_SORT |
LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
EDITTEXT IDC_SCREENS_SRC_START,7,156,16,12,ES_AUTOHSCROLL |
ES_NUMBER
LTEXT "to",IDC_STATIC,25,158,8,8
EDITTEXT IDC_SCREENS_SRC_END,33,156,16,12,ES_AUTOHSCROLL |
ES_NUMBER
LTEXT "% of the",IDC_STATIC,52,158,27,8
COMBOBOX IDC_SCREENS_SRC_SIDE,80,156,48,69,CBS_DROPDOWNLIST |
WS_VSCROLL | WS_TABSTOP
LTEXT "of",IDC_STATIC,129,158,8,8
COMBOBOX IDC_SCREENS_SRC_SCREEN,139,156,59,53,CBS_DROPDOWNLIST |
WS_VSCROLL | WS_TABSTOP
LTEXT "goes to",IDC_STATIC,200,158,24,8
EDITTEXT IDC_SCREENS_DST_START,225,156,16,12,ES_AUTOHSCROLL |
ES_NUMBER
LTEXT "to",IDC_STATIC,243,158,8,8
EDITTEXT IDC_SCREENS_DST_END,251,156,16,12,ES_AUTOHSCROLL |
ES_NUMBER
LTEXT "% of",IDC_STATIC,270,158,15,8
COMBOBOX IDC_SCREENS_DST_SCREEN,287,156,59,53,CBS_DROPDOWNLIST |
WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "+",IDC_SCREENS_ADD_LINK,7,172,17,14
PUSHBUTTON "-",IDC_SCREENS_REMOVE_LINK,28,172,17,14
DEFPUSHBUTTON "OK",IDOK,241,192,50,14
PUSHBUTTON "Cancel",IDCANCEL,297,192,50,14
LTEXT "Source edge overlaps an existing edge.",
IDC_SCREENS_OVERLAP_ERROR,72,175,126,8,NOT WS_VISIBLE |
NOT WS_GROUP
END
IDD_INFO DIALOG DISCARDABLE 0, 0, 186, 95
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Info"
FONT 8, "MS Sans Serif"
BEGIN
LTEXT "Version:",IDC_STATIC,7,7,26,8
EDITTEXT IDC_INFO_VERSION,52,7,127,12,ES_AUTOHSCROLL |
ES_READONLY | NOT WS_BORDER
LTEXT "Hostname:",IDC_STATIC,7,19,35,8
EDITTEXT IDC_INFO_HOSTNAME,52,19,127,12,ES_AUTOHSCROLL |
ES_READONLY | NOT WS_BORDER
LTEXT "IP Address:",IDC_STATIC,7,31,37,8
EDITTEXT IDC_INFO_IP_ADDRESS,52,31,127,12,ES_AUTOHSCROLL |
ES_READONLY | NOT WS_BORDER
LTEXT "User Config:",IDC_STATIC,7,43,40,8
EDITTEXT IDC_INFO_USER_CONFIG,52,43,127,12,ES_AUTOHSCROLL |
ES_READONLY | NOT WS_BORDER
LTEXT "Sys Config:",IDC_STATIC,7,55,36,8
EDITTEXT IDC_INFO_SYS_CONFIG,52,55,127,12,ES_AUTOHSCROLL |
ES_READONLY | NOT WS_BORDER
DEFPUSHBUTTON "OK",IDOK,129,74,50,14
END
IDD_HOTKEY_OPTIONS DIALOG DISCARDABLE 0, 0, 360, 151
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Hot Keys"
FONT 8, "MS Sans Serif"
BEGIN
LTEXT "&Hot Keys:",IDC_STATIC,7,7,32,8
LISTBOX IDC_HOTKEY_HOTKEYS,7,18,169,88,LBS_SORT |
LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "+",IDC_HOTKEY_ADD_HOTKEY,7,109,17,14
PUSHBUTTON "-",IDC_HOTKEY_REMOVE_HOTKEY,28,109,17,14
PUSHBUTTON "Edit",IDC_HOTKEY_EDIT_HOTKEY,49,109,24,14
LTEXT "&Actions:",IDC_STATIC,183,7,26,8
LISTBOX IDC_HOTKEY_ACTIONS,183,18,169,88,LBS_SORT |
LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
PUSHBUTTON "+",IDC_HOTKEY_ADD_ACTION,183,109,17,14
PUSHBUTTON "-",IDC_HOTKEY_REMOVE_ACTION,204,109,17,14
PUSHBUTTON "Edit",IDC_HOTKEY_EDIT_ACTION,225,109,24,14
DEFPUSHBUTTON "OK",IDOK,302,130,50,14
END
IDD_HOTKEY_CONDITION DIALOG DISCARDABLE 0, 0, 183, 58
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Hot Key"
FONT 8, "MS Sans Serif"
BEGIN
LTEXT "Enter &new hot key or mouse button:",IDC_STATIC,7,7,113,
8
EDITTEXT IDC_HOTKEY_CONDITION_HOTKEY,7,17,169,12,ES_WANTRETURN
DEFPUSHBUTTON "OK",IDOK,70,37,50,14
PUSHBUTTON "Cancel",IDCANCEL,126,37,50,14
END
IDD_HOTKEY_ACTION DIALOG DISCARDABLE 0, 0, 183, 202
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Action"
FONT 8, "MS Sans Serif"
BEGIN
LTEXT "&Action:",IDC_STATIC,7,7,23,8
CONTROL "Press:",IDC_HOTKEY_ACTION_DOWN,"Button",
BS_AUTORADIOBUTTON | WS_TABSTOP,7,19,35,10
CONTROL "Release:",IDC_HOTKEY_ACTION_UP,"Button",
BS_AUTORADIOBUTTON,7,31,44,10
CONTROL "Press && Release:",IDC_HOTKEY_ACTION_DOWNUP,"Button",
BS_AUTORADIOBUTTON,7,43,69,10
CONTROL "Switch To Screen:",IDC_HOTKEY_ACTION_SWITCH_TO,"Button",
BS_AUTORADIOBUTTON,7,85,75,10
CONTROL "Switch In Direction:",IDC_HOTKEY_ACTION_SWITCH_IN,
"Button",BS_AUTORADIOBUTTON,7,101,77,10
CONTROL "Lock Cursor to Screen:",IDC_HOTKEY_ACTION_LOCK,"Button",
BS_AUTORADIOBUTTON,7,117,89,10
LTEXT "&Hot key or mouse button:",IDC_STATIC,7,55,80,8
EDITTEXT IDC_HOTKEY_ACTION_HOTKEY,7,67,152,12,ES_WANTRETURN
PUSHBUTTON "...",IDC_HOTKEY_ACTION_SCREENS,162,67,14,12
COMBOBOX IDC_HOTKEY_ACTION_SWITCH_TO_LIST,87,83,89,62,
CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
COMBOBOX IDC_HOTKEY_ACTION_SWITCH_IN_LIST,106,99,70,66,
CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
COMBOBOX IDC_HOTKEY_ACTION_LOCK_LIST,106,115,70,58,
CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
LTEXT "Action takes place &when:",IDC_STATIC,7,137,81,8
CONTROL "Hot key is pressed",IDC_HOTKEY_ACTION_ON_ACTIVATE,
"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,7,149,74,10
CONTROL "Hot key is released",IDC_HOTKEY_ACTION_ON_DEACTIVATE,
"Button",BS_AUTORADIOBUTTON,7,161,76,10
DEFPUSHBUTTON "OK",IDOK,70,181,50,14
PUSHBUTTON "Cancel",IDCANCEL,126,181,50,14
END
IDD_HOTKEY_SCREENS DIALOG DISCARDABLE 0, 0, 237, 79
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Target Screens"
FONT 8, "MS Sans Serif"
BEGIN
LTEXT "&Available screens:",IDC_STATIC,7,7,58,8
LISTBOX IDC_HOTKEY_SCREENS_SRC,7,17,100,36,LBS_NOINTEGRALHEIGHT |
LBS_EXTENDEDSEL | WS_VSCROLL | WS_TABSTOP
LISTBOX IDC_HOTKEY_SCREENS_DST,130,17,100,36,
LBS_NOINTEGRALHEIGHT | LBS_EXTENDEDSEL | WS_VSCROLL |
WS_TABSTOP
PUSHBUTTON "-->",IDC_HOTKEY_SCREENS_ADD,109,21,17,14
PUSHBUTTON "<--",IDC_HOTKEY_SCREENS_REMOVE,109,38,17,14
DEFPUSHBUTTON "OK",IDOK,124,58,50,14
PUSHBUTTON "Cancel",IDCANCEL,180,58,50,14
LTEXT "&Send action to screens:",IDC_STATIC,130,7,76,8
END
/////////////////////////////////////////////////////////////////////////////
//
@ -252,7 +403,7 @@ BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 293
TOPMARGIN, 7
BOTTOMMARGIN, 255
BOTTOMMARGIN, 192
END
IDD_ADD, DIALOG
@ -284,7 +435,7 @@ BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 200
TOPMARGIN, 7
BOTTOMMARGIN, 262
BOTTOMMARGIN, 283
END
IDD_ADVANCED_OPTIONS, DIALOG
@ -294,6 +445,54 @@ BEGIN
TOPMARGIN, 7
BOTTOMMARGIN, 179
END
IDD_SCREENS_LINKS, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 347
TOPMARGIN, 7
BOTTOMMARGIN, 206
END
IDD_INFO, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 179
TOPMARGIN, 7
BOTTOMMARGIN, 88
END
IDD_HOTKEY_OPTIONS, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 353
TOPMARGIN, 7
BOTTOMMARGIN, 144
END
IDD_HOTKEY_CONDITION, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 176
TOPMARGIN, 7
BOTTOMMARGIN, 51
END
IDD_HOTKEY_ACTION, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 176
TOPMARGIN, 7
BOTTOMMARGIN, 195
END
IDD_HOTKEY_SCREENS, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 230
TOPMARGIN, 7
BOTTOMMARGIN, 72
END
END
#endif // APSTUDIO_INVOKED
@ -358,13 +557,37 @@ BEGIN
IDS_UNINSTALLED_USER "Removed auto-start. Synergy will not automatically start each time you log in."
IDS_INVALID_SERVER_NAME "Server name `%{1}' is invalid."
IDS_TITLE "Synergy - Version %{1}"
IDS_SERVER_IS_CLIENT "Please enter the computer name of the synergy server, not\nthe name of this computer, in the Server Host Name field."
IDS_SERVER_IS_CLIENT "Please enter the name of the computer sharing a\nkeyboard and mouse, not the name of this computer,\nin the Other Computer's Host Name field."
IDS_ADD_SCREEN "Add Screen"
IDS_EDIT_SCREEN "Edit Screen %{1}"
IDS_ERROR_CODE "Error code: %{1}"
IDS_AUTOSTART_PERMISSION_ALL
"You have sufficient access rights to install and uninstall Auto Start for all users or for just yourself."
IDS_INVALID_INTERFACE_NAME "The interface '%{1}' is invalid: %{2}"
IDS_INVALID_CORNER_SIZE "The dead corner size %{1} is invalid; it must be 0 or higher."
IDS_NEW_LINK "[New Link]"
IDS_SIDE_LEFT "left of"
IDS_SIDE_RIGHT "right of"
IDS_SIDE_TOP "above"
IDS_SIDE_BOTTOM "below"
END
STRINGTABLE DISCARDABLE
BEGIN
IDS_LINK_FORMAT "%{4}%{5} is %{3} %{1}%{2}"
IDS_LINK_INTERVAL_FORMAT "(%{1},%{2})"
IDS_EDGE_LEFT "left"
IDS_EDGE_RIGHT "right"
IDS_EDGE_TOP "top"
IDS_EDGE_BOTTOM "bottom"
IDS_AUTOSTART_SAVE_FAILED "Failed to save autostart configuration: %{1}"
IDS_LOAD_FAILED "Failed to load configuration."
IDS_CONFIG_CHANGED "Configuration changed on disk. Reload?"
IDS_LOCK_MODE_OFF "off"
IDS_LOCK_MODE_ON "on"
IDS_LOCK_MODE_TOGGLE "toggle"
IDS_ALL_SCREENS "All Screens"
IDS_ACTIVE_SCREEN "Active Screen"
END
#endif // English (U.S.) resources

View File

@ -44,6 +44,26 @@
#define IDS_ERROR_CODE 39
#define IDS_AUTOSTART_PERMISSION_ALL 40
#define IDS_INVALID_INTERFACE_NAME 41
#define IDS_INVALID_CORNER_SIZE 42
#define IDS_NEW_LINK 43
#define IDS_SIDE_LEFT 44
#define IDS_SIDE_RIGHT 45
#define IDS_SIDE_TOP 46
#define IDS_SIDE_BOTTOM 47
#define IDS_LINK_FORMAT 48
#define IDS_LINK_INTERVAL_FORMAT 49
#define IDS_EDGE_LEFT 50
#define IDS_EDGE_RIGHT 51
#define IDS_EDGE_TOP 52
#define IDS_EDGE_BOTTOM 53
#define IDS_AUTOSTART_SAVE_FAILED 54
#define IDS_LOAD_FAILED 55
#define IDS_CONFIG_CHANGED 56
#define IDS_LOCK_MODE_OFF 57
#define IDS_LOCK_MODE_ON 58
#define IDS_LOCK_MODE_TOGGLE 59
#define IDS_ALL_SCREENS 60
#define IDS_ACTIVE_SCREEN 61
#define IDD_MAIN 101
#define IDD_ADD 102
#define IDD_WAIT 103
@ -51,45 +71,36 @@
#define IDD_AUTOSTART 105
#define IDD_ADVANCED_OPTIONS 106
#define IDD_GLOBAL_OPTIONS 107
#define IDD_SCREENS_LINKS 110
#define IDD_INFO 111
#define IDD_HOTKEY_OPTIONS 112
#define IDD_HOTKEY_CONDITION 113
#define IDD_HOTKEY_ACTION 114
#define IDD_HOTKEY_SCREENS 115
#define IDC_MAIN_CLIENT_RADIO 1000
#define IDC_MAIN_SERVER_RADIO 1001
#define IDC_MAIN_CLIENT_SERVER_NAME_EDIT 1002
#define IDC_MAIN_ADVANCED_NAME_EDIT 1006
#define IDC_MAIN_ADVANCED_PORT_EDIT 1008
#define IDC_MAIN_CLIENT_SERVER_NAME_LABEL 1002
#define IDC_MAIN_CLIENT_SERVER_NAME_EDIT 1003
#define IDC_MAIN_SERVER_SCREENS_LABEL 1004
#define IDC_MAIN_SCREENS 1005
#define IDC_MAIN_OPTIONS 1006
#define IDC_MAIN_ADVANCED 1007
#define IDC_MAIN_AUTOSTART 1008
#define IDC_MAIN_TEST 1009
#define IDC_MAIN_SAVE 1010
#define IDC_MAIN_CLIENT_SERVER_NAME_LABEL 1011
#define IDC_MAIN_SERVER_SCREENS_LIST 1012
#define IDC_MAIN_SERVER_SCREENS_LABEL 1013
#define IDC_MAIN_SERVER_LAYOUT_LABEL 1014
#define IDC_MAIN_SERVER_ADD_BUTTON 1018
#define IDC_MAIN_SERVER_EDIT_BUTTON 1019
#define IDC_MAIN_HOTKEYS 1010
#define IDC_MAIN_DEBUG 1011
#define IDC_ADD_SCREEN_NAME_EDIT 1020
#define IDC_MAIN_SERVER_REMOVE_BUTTON 1020
#define IDC_ADD_ALIASES_EDIT 1021
#define IDC_MAIN_SERVER_OPTIONS_BUTTON 1021
#define IDC_MAIN_SERVER_LEFT_COMBO 1022
#define IDC_MAIN_SERVER_RIGHT_COMBO 1023
#define IDC_MAIN_SERVER_TOP_COMBO 1024
#define IDC_MAIN_SERVER_BOTTOM_COMBO 1025
#define IDC_MAIN_SERVER_LEFT_LABEL 1026
#define IDC_MAIN_SERVER_RIGHT_LABEL 1027
#define IDC_MAIN_SERVER_TOP_LABEL 1028
#define IDC_MAIN_SERVER_BOTTOM_LABEL 1029
#define IDC_MAIN_UNINSTALL 1030
#define IDC_AUTOSTART_INSTALLED_MSG 1031
#define IDC_AUTOSTART_PERMISSION_MSG 1032
#define IDC_AUTOSTART_INSTALL_USER 1033
#define IDC_AUTOSTART_INSTALL_SYSTEM 1034
#define IDC_MAIN_AUTOSTART 1035
#define IDC_MAIN_OPTIONS 1036
#define IDC_ADD_HD_CAPS_CHECK 1037
#define IDC_MAIN_ADVANCED 1037
#define IDC_ADD_HD_NUM_CHECK 1038
#define IDC_ADVANCED_NAME_EDIT 1038
#define IDC_ADVANCED_PORT_EDIT 1039
#define IDC_ADD_HD_SCROLL_CHECK 1039
#define IDC_MAIN_DEBUG 1040
#define IDC_ADVANCED_INTERFACE_EDIT 1040
#define IDC_GLOBAL_DELAY_CHECK 1041
#define IDC_GLOBAL_DELAY_TIME 1042
@ -105,15 +116,68 @@
#define IDC_GLOBAL_SCREENSAVER_SYNC 1047
#define IDC_GLOBAL_RELATIVE_MOVES 1048
#define IDC_ADVANCED_DEFAULTS 1049
#define IDC_GLOBAL_LEAVE_FOREGROUND 1049
#define IDC_ADD_DC_SIZE 1052
#define IDC_ADD_DC_TOP_LEFT 1053
#define IDC_ADD_DC_TOP_RIGHT 1054
#define IDC_ADD_DC_BOTTOM_LEFT 1055
#define IDC_ADD_DC_BOTTOM_RIGHT 1056
#define IDC_SCREENS_SRC_SIDE 1057
#define IDC_SCREENS_SRC_START 1058
#define IDC_SCREENS_SRC_END 1059
#define IDC_SCREENS_SRC_SCREEN 1060
#define IDC_SCREENS_SCREENS 1061
#define IDC_SCREENS_ADD_SCREEN 1062
#define IDC_SCREENS_LINKS 1063
#define IDC_SCREENS_DST_START 1064
#define IDC_SCREENS_DST_END 1065
#define IDC_SCREENS_DST_SCREEN 1066
#define IDC_SCREENS_REMOVE_SCREEN 1067
#define IDC_SCREENS_EDIT_SCREEN 1068
#define IDC_SCREENS_ADD_LINK 1069
#define IDC_SCREENS_REMOVE_LINK 1070
#define IDC_SCREENS_OVERLAP_ERROR 1071
#define IDC_INFO_VERSION 1073
#define IDC_MAIN_INFO 1074
#define IDC_INFO_HOSTNAME 1076
#define IDC_HOTKEY_HOTKEYS 1076
#define IDC_INFO_IP_ADDRESS 1077
#define IDC_HOTKEY_ADD_HOTKEY 1077
#define IDC_INFO_USER_CONFIG 1078
#define IDC_HOTKEY_REMOVE_HOTKEY 1078
#define IDC_INFO_SYS_CONFIG 1079
#define IDC_HOTKEY_EDIT_HOTKEY 1079
#define IDC_HOTKEY_ACTIONS 1080
#define IDC_HOTKEY_CONDITION_HOTKEY 1080
#define IDC_HOTKEY_ACTION_DOWNUP 1081
#define IDC_HOTKEY_ADD_ACTION 1082
#define IDC_HOTKEY_ACTION_DOWN 1082
#define IDC_HOTKEY_REMOVE_ACTION 1083
#define IDC_HOTKEY_ACTION_UP 1083
#define IDC_HOTKEY_EDIT_ACTION 1084
#define IDC_HOTKEY_ACTION_HOTKEY 1085
#define IDC_HOTKEY_ACTION_SWITCH_TO_LIST 1086
#define IDC_HOTKEY_ACTION_SWITCH_TO 1087
#define IDC_HOTKEY_ACTION_SWITCH_IN 1088
#define IDC_HOTKEY_ACTION_LOCK 1089
#define IDC_HOTKEY_ACTION_SWITCH_IN_LIST 1090
#define IDC_HOTKEY_ACTION_LOCK_LIST 1091
#define IDC_HOTKEY_ACTION_ON_ACTIVATE 1092
#define IDC_HOTKEY_ACTION_ON_DEACTIVATE 1093
#define IDC_HOTKEY_ACTION_SCREENS 1094
#define IDC_HOTKEY_SCREENS_SRC 1095
#define IDC_HOTKEY_SCREENS_DST 1096
#define IDC_HOTKEY_SCREENS_ADD 1097
#define IDC_HOTKEY_SCREENS_REMOVE 1098
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NO_MFC 1
#define _APS_NEXT_RESOURCE_VALUE 110
#define _APS_NEXT_RESOURCE_VALUE 116
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1052
#define _APS_NEXT_CONTROL_VALUE 1098
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 8.3 KiB

View File

@ -15,8 +15,10 @@
#include "CClientTaskBarReceiver.h"
#include "CClient.h"
#include "CLock.h"
#include "CStringUtil.h"
#include "IEventQueue.h"
#include "CArch.h"
#include "Version.h"
//
// CClientTaskBarReceiver
@ -48,6 +50,8 @@ CClientTaskBarReceiver::updateStatus(CClient* client, const CString& errorMsg)
}
}
else {
m_server = client->getServerAddress().getHostname();
if (client->isConnected()) {
m_state = kConnected;
}
@ -108,19 +112,23 @@ CClientTaskBarReceiver::getToolTip() const
{
switch (m_state) {
case kNotRunning:
return "Synergy: Not running";
return CStringUtil::print("%s: Not running", kAppVersion);
case kNotWorking:
return CString("Synergy: ") + m_errorMessage;
return CStringUtil::print("%s: %s",
kAppVersion, m_errorMessage.c_str());
case kNotConnected:
return CString("Synergy: Not connected: ") + m_errorMessage;
return CStringUtil::print("%s: Not connected: %s",
kAppVersion, m_errorMessage.c_str());
case kConnecting:
return "Synergy: Connecting...";
return CStringUtil::print("%s: Connecting to %s...",
kAppVersion, m_server.c_str());
case kConnected:
return "Synergy: Connected";
return CStringUtil::print("%s: Connected to %s",
kAppVersion, m_server.c_str());
default:
return "";

View File

@ -77,6 +77,7 @@ protected:
private:
EState m_state;
CString m_errorMessage;
CString m_server;
};
#endif

View File

@ -139,6 +139,9 @@ CMSWindowsClientTaskBarReceiver::runMenu(int x, int y)
SetForegroundWindow(m_window);
HMENU menu = GetSubMenu(m_menu, 0);
SetMenuDefaultItem(menu, IDC_TASKBAR_STATUS, FALSE);
HMENU logLevelMenu = GetSubMenu(menu, 3);
CheckMenuRadioItem(logLevelMenu, 0, 6,
CLOG->getFilter() - CLog::kERROR, MF_BYPOSITION);
int n = TrackPopupMenu(menu,
TPM_NONOTIFY |
TPM_RETURNCMD |
@ -157,6 +160,38 @@ CMSWindowsClientTaskBarReceiver::runMenu(int x, int y)
copyLog();
break;
case IDC_TASKBAR_SHOW_LOG:
ARCH->showConsole(true);
break;
case IDC_TASKBAR_LOG_LEVEL_ERROR:
CLOG->setFilter(CLog::kERROR);
break;
case IDC_TASKBAR_LOG_LEVEL_WARNING:
CLOG->setFilter(CLog::kWARNING);
break;
case IDC_TASKBAR_LOG_LEVEL_NOTE:
CLOG->setFilter(CLog::kNOTE);
break;
case IDC_TASKBAR_LOG_LEVEL_INFO:
CLOG->setFilter(CLog::kINFO);
break;
case IDC_TASKBAR_LOG_LEVEL_DEBUG:
CLOG->setFilter(CLog::kDEBUG);
break;
case IDC_TASKBAR_LOG_LEVEL_DEBUG1:
CLOG->setFilter(CLog::kDEBUG1);
break;
case IDC_TASKBAR_LOG_LEVEL_DEBUG2:
CLOG->setFilter(CLog::kDEBUG2);
break;
case IDC_TASKBAR_QUIT:
quit();
break;

View File

@ -67,6 +67,12 @@ synergyc_SOURCES = \
$(COMMON_SOURCE_FILES) \
$(CARBON_SOURCE_FILES) \
$(NULL)
synergyc_LDFLAGS = \
-framework ScreenSaver \
-framework IOKit \
-framework ApplicationServices \
-framework Foundation \
$(NULL)
endif
synergyc_LDADD = \
$(top_builddir)/lib/client/libclient.a \

View File

@ -16,13 +16,21 @@
#define IDC_TASKBAR_QUIT 40001
#define IDC_TASKBAR_STATUS 40002
#define IDC_TASKBAR_LOG 40003
#define IDC_TASKBAR_SHOW_LOG 40004
#define IDC_TASKBAR_LOG_LEVEL_ERROR 40009
#define IDC_TASKBAR_LOG_LEVEL_WARNING 40010
#define IDC_TASKBAR_LOG_LEVEL_NOTE 40011
#define IDC_TASKBAR_LOG_LEVEL_INFO 40012
#define IDC_TASKBAR_LOG_LEVEL_DEBUG 40013
#define IDC_TASKBAR_LOG_LEVEL_DEBUG1 40014
#define IDC_TASKBAR_LOG_LEVEL_DEBUG2 40015
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 109
#define _APS_NEXT_COMMAND_VALUE 40004
#define _APS_NEXT_COMMAND_VALUE 40016
#define _APS_NEXT_CONTROL_VALUE 1001
#define _APS_NEXT_SYMED_VALUE 101
#endif

View File

@ -60,10 +60,6 @@
typedef int (*StartupFunc)(int, char**);
static bool startClient();
static void parse(int argc, const char* const* argv);
#if WINAPI_MSWINDOWS
static void handleSystemSuspend(void*);
static void handleSystemResume(void*);
#endif
//
// program arguments
@ -108,9 +104,7 @@ CScreen*
createScreen()
{
#if WINAPI_MSWINDOWS
return new CScreen(new CMSWindowsScreen(false,
new CFunctionJob(&handleSystemSuspend),
new CFunctionJob(&handleSystemResume)));
return new CScreen(new CMSWindowsScreen(false));
#elif WINAPI_XWINDOWS
return new CScreen(new CXWindowsScreen(ARG->m_display, false));
#elif WINAPI_CARBON
@ -199,26 +193,6 @@ handleScreenError(const CEvent&, void*)
EVENTQUEUE->addEvent(CEvent(CEvent::kQuit));
}
#if WINAPI_MSWINDOWS
static
void
handleSystemSuspend(void*)
{
LOG((CLOG_NOTE "system suspending"));
s_suspened = true;
s_client->disconnect(NULL);
}
static
void
handleSystemResume(void*)
{
LOG((CLOG_NOTE "system resuming"));
s_suspened = false;
startClient();
}
#endif
static
CScreen*
openClientScreen()
@ -252,9 +226,7 @@ handleClientRestart(const CEvent&, void* vtimer)
EVENTQUEUE->removeHandler(CEvent::kTimer, timer);
// reconnect
if (!s_suspened) {
startClient();
}
}
static
@ -287,6 +259,7 @@ handleClientFailed(const CEvent& e, void*)
updateStatus(CString("Failed to connect to server: ") + info->m_what);
if (!ARG->m_restartable || !info->m_retry) {
LOG((CLOG_ERR "failed to connect to server: %s", info->m_what));
EVENTQUEUE->addEvent(CEvent(CEvent::kQuit));
}
else {
LOG((CLOG_WARN "failed to connect to server: %s", info->m_what));
@ -441,7 +414,11 @@ static
int
daemonMainLoop(int, const char**)
{
CSystemLogger sysLogger(DAEMON_NAME);
#if SYSAPI_WIN32
CSystemLogger sysLogger(DAEMON_NAME, false);
#else
CSystemLogger sysLogger(DAEMON_NAME, true);
#endif
return mainLoop();
}
@ -449,6 +426,10 @@ static
int
standardStartup(int argc, char** argv)
{
if (!ARG->m_daemon) {
ARCH->showConsole(false);
}
// parse command line
parse(argc, argv);
@ -758,6 +739,7 @@ public:
// ILogOutputter overrides
virtual void open(const char*) { }
virtual void close() { }
virtual void show(bool) { }
virtual bool write(ELevel level, const char* message);
virtual const char* getNewline() const { return ""; }
};
@ -802,11 +784,24 @@ static
int
daemonNTStartup(int, char**)
{
CSystemLogger sysLogger(DAEMON_NAME);
CSystemLogger sysLogger(DAEMON_NAME, false);
bye = &byeThrow;
return ARCH->daemonize(DAEMON_NAME, &daemonNTMainLoop);
}
static
int
foregroundStartup(int argc, char** argv)
{
ARCH->showConsole(false);
// parse command line
parse(argc, argv);
// never daemonize
return mainLoop();
}
static
void
showError(HINSTANCE instance, const char* title, UINT id, const char* arg)
@ -820,12 +815,23 @@ int WINAPI
WinMain(HINSTANCE instance, HINSTANCE, LPSTR, int)
{
try {
CArchMiscWindows::setIcons((HICON)LoadImage(instance,
MAKEINTRESOURCE(IDI_SYNERGY),
IMAGE_ICON,
32, 32, LR_SHARED),
(HICON)LoadImage(instance,
MAKEINTRESOURCE(IDI_SYNERGY),
IMAGE_ICON,
16, 16, LR_SHARED));
CArch arch(instance);
CMSWindowsScreen::init(instance);
CLOG;
CThread::getCurrentThread().setPriority(-14);
CArgs args;
// set title on log window
ARCH->openConsole((CString(kAppVersion) + " " + "Client").c_str());
// windows NT family starts services using no command line options.
// since i'm not sure how to tell the difference between that and
// a user providing no options we'll assume that if there are no
@ -833,9 +839,14 @@ WinMain(HINSTANCE instance, HINSTANCE, LPSTR, int)
// users on NT can use `--daemon' or `--no-daemon' to force us out
// of the service code path.
StartupFunc startup = &standardStartup;
if (__argc <= 1 && !CArchMiscWindows::isWindows95Family()) {
if (!CArchMiscWindows::isWindows95Family()) {
if (__argc <= 1) {
startup = &daemonNTStartup;
}
else {
startup = &foregroundStartup;
}
}
// send PRINT and FATAL output to a message box
int result = run(__argc, __argv, new CMessageBoxOutputter, startup);

View File

@ -43,7 +43,7 @@ RSC=rc.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /MT /W4 /GX /O2 /I "..\..\lib\common" /I "..\..\lib\arch" /I "..\..\lib\base" /I "..\..\lib\io" /I "..\..\lib\mt" /I "..\..\lib\net" /I "..\..\lib\synergy" /I "..\..\lib\platform" /I "..\..\lib\client" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /FD /c /Fd..\..\gen\build\synergyc.pdb
# ADD CPP /nologo /MT /W4 /GR /GX /O2 /I "..\..\lib\common" /I "..\..\lib\arch" /I "..\..\lib\base" /I "..\..\lib\io" /I "..\..\lib\mt" /I "..\..\lib\net" /I "..\..\lib\synergy" /I "..\..\lib\platform" /I "..\..\lib\client" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /Fd"..\..\gen\build\synergyc.pdb" /FD /c
# SUBTRACT CPP /YX
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
@ -70,7 +70,7 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
# ADD CPP /nologo /MTd /W4 /Gm /GX /ZI /Od /I "..\..\lib\common" /I "..\..\lib\arch" /I "..\..\lib\base" /I "..\..\lib\io" /I "..\..\lib\mt" /I "..\..\lib\net" /I "..\..\lib\synergy" /I "..\..\lib\platform" /I "..\..\lib\client" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /FD /GZ /c /Fd..\..\gen\debug\synergyc.pdb
# ADD CPP /nologo /MTd /W4 /Gm /GR /GX /ZI /Od /I "..\..\lib\common" /I "..\..\lib\arch" /I "..\..\lib\base" /I "..\..\lib\io" /I "..\..\lib\mt" /I "..\..\lib\net" /I "..\..\lib\synergy" /I "..\..\lib\platform" /I "..\..\lib\client" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /Fd"..\..\gen\debug\synergyc.pdb" /FD /GZ /c
# SUBTRACT CPP /YX
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 8.3 KiB

View File

@ -87,7 +87,25 @@ BEGIN
POPUP "Synergy"
BEGIN
MENUITEM "Show Status", IDC_TASKBAR_STATUS
MENUITEM "Show Log", IDC_TASKBAR_SHOW_LOG
MENUITEM "Copy Log To Clipboard", IDC_TASKBAR_LOG
POPUP "Set Log Level"
BEGIN
MENUITEM "Error", IDC_TASKBAR_LOG_LEVEL_ERROR
MENUITEM "Warning", IDC_TASKBAR_LOG_LEVEL_WARNING
MENUITEM "Note", IDC_TASKBAR_LOG_LEVEL_NOTE
MENUITEM "Info", IDC_TASKBAR_LOG_LEVEL_INFO
MENUITEM "Debug", IDC_TASKBAR_LOG_LEVEL_DEBUG
MENUITEM "Debug1", IDC_TASKBAR_LOG_LEVEL_DEBUG1
MENUITEM "Debug2", IDC_TASKBAR_LOG_LEVEL_DEBUG2
END
MENUITEM SEPARATOR
MENUITEM "Quit", IDC_TASKBAR_QUIT
END

Binary file not shown.

Before

Width:  |  Height:  |  Size: 318 B

After

Width:  |  Height:  |  Size: 318 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 318 B

After

Width:  |  Height:  |  Size: 318 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 318 B

After

Width:  |  Height:  |  Size: 318 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 318 B

After

Width:  |  Height:  |  Size: 318 B

View File

@ -157,6 +157,9 @@ CMSWindowsServerTaskBarReceiver::runMenu(int x, int y)
SetForegroundWindow(m_window);
HMENU menu = GetSubMenu(m_menu, 0);
SetMenuDefaultItem(menu, IDC_TASKBAR_STATUS, FALSE);
HMENU logLevelMenu = GetSubMenu(menu, 3);
CheckMenuRadioItem(logLevelMenu, 0, 6,
CLOG->getFilter() - CLog::kERROR, MF_BYPOSITION);
int n = TrackPopupMenu(menu,
TPM_NONOTIFY |
TPM_RETURNCMD |
@ -175,6 +178,10 @@ CMSWindowsServerTaskBarReceiver::runMenu(int x, int y)
copyLog();
break;
case IDC_TASKBAR_SHOW_LOG:
ARCH->showConsole(true);
break;
case IDC_RELOAD_CONFIG:
EVENTQUEUE->addEvent(CEvent(getReloadConfigEvent(),
IEventQueue::getSystemTarget()));
@ -185,6 +192,34 @@ CMSWindowsServerTaskBarReceiver::runMenu(int x, int y)
IEventQueue::getSystemTarget()));
break;
case IDC_TASKBAR_LOG_LEVEL_ERROR:
CLOG->setFilter(CLog::kERROR);
break;
case IDC_TASKBAR_LOG_LEVEL_WARNING:
CLOG->setFilter(CLog::kWARNING);
break;
case IDC_TASKBAR_LOG_LEVEL_NOTE:
CLOG->setFilter(CLog::kNOTE);
break;
case IDC_TASKBAR_LOG_LEVEL_INFO:
CLOG->setFilter(CLog::kINFO);
break;
case IDC_TASKBAR_LOG_LEVEL_DEBUG:
CLOG->setFilter(CLog::kDEBUG);
break;
case IDC_TASKBAR_LOG_LEVEL_DEBUG1:
CLOG->setFilter(CLog::kDEBUG1);
break;
case IDC_TASKBAR_LOG_LEVEL_DEBUG2:
CLOG->setFilter(CLog::kDEBUG2);
break;
case IDC_TASKBAR_QUIT:
quit();
break;

View File

@ -15,8 +15,10 @@
#include "CServerTaskBarReceiver.h"
#include "CServer.h"
#include "CLock.h"
#include "CStringUtil.h"
#include "IEventQueue.h"
#include "CArch.h"
#include "Version.h"
//
// CServerTaskBarReceiver
@ -113,16 +115,17 @@ CServerTaskBarReceiver::getToolTip() const
{
switch (m_state) {
case kNotRunning:
return "Synergy: Not running";
return CStringUtil::print("%s: Not running", kAppVersion);
case kNotWorking:
return std::string("Synergy: ") + m_errorMessage;
return CStringUtil::print("%s: %s",
kAppVersion, m_errorMessage.c_str());
case kNotConnected:
return "Synergy: Waiting for clients";
return CStringUtil::print("%s: Waiting for clients", kAppVersion);
case kConnected:
return "Synergy: Connected";
return CStringUtil::print("%s: Connected", kAppVersion);
default:
return "";

View File

@ -67,6 +67,12 @@ synergys_SOURCES = \
$(COMMON_SOURCE_FILES) \
$(CARBON_SOURCE_FILES) \
$(NULL)
synergys_LDFLAGS = \
-framework ScreenSaver \
-framework IOKit \
-framework ApplicationServices \
-framework Foundation \
$(NULL)
endif
synergys_LDADD = \
$(top_builddir)/lib/server/libserver.a \

View File

@ -19,13 +19,21 @@
#define IDC_TASKBAR_LOG 40005
#define IDC_RELOAD_CONFIG 40006
#define IDC_FORCE_RECONNECT 40007
#define IDC_TASKBAR_SHOW_LOG 40008
#define IDC_TASKBAR_LOG_LEVEL_ERROR 40009
#define IDC_TASKBAR_LOG_LEVEL_WARNING 40010
#define IDC_TASKBAR_LOG_LEVEL_NOTE 40011
#define IDC_TASKBAR_LOG_LEVEL_INFO 40012
#define IDC_TASKBAR_LOG_LEVEL_DEBUG 40013
#define IDC_TASKBAR_LOG_LEVEL_DEBUG1 40014
#define IDC_TASKBAR_LOG_LEVEL_DEBUG2 40015
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 109
#define _APS_NEXT_COMMAND_VALUE 40008
#define _APS_NEXT_COMMAND_VALUE 40016
#define _APS_NEXT_CONTROL_VALUE 1003
#define _APS_NEXT_SYMED_VALUE 101
#endif

View File

@ -121,7 +121,7 @@ CScreen*
createScreen()
{
#if WINAPI_MSWINDOWS
return new CScreen(new CMSWindowsScreen(true, NULL, NULL));
return new CScreen(new CMSWindowsScreen(true));
#elif WINAPI_XWINDOWS
return new CScreen(new CXWindowsScreen(ARG->m_display, true));
#elif WINAPI_CARBON
@ -148,6 +148,16 @@ createTaskBarReceiver(const CBufferedLogOutputter* logBuffer)
// platform independent main
//
enum EServerState {
kUninitialized,
kInitializing,
kInitializingToStart,
kInitialized,
kStarting,
kStarted
};
static EServerState s_serverState = kUninitialized;
static CServer* s_server = NULL;
static CScreen* s_serverScreen = NULL;
static CPrimaryClient* s_primaryClient = NULL;
@ -155,6 +165,8 @@ static CClientListener* s_listener = NULL;
static CServerTaskBarReceiver* s_taskBarReceiver = NULL;
static CEvent::Type s_reloadConfigEvent = CEvent::kUnknown;
static CEvent::Type s_forceReconnectEvent = CEvent::kUnknown;
static bool s_suspended = false;
static CEventQueueTimer* s_timer = NULL;
CEvent::Type
getReloadConfigEvent()
@ -224,6 +236,10 @@ handleScreenError(const CEvent&, void*)
EVENTQUEUE->addEvent(CEvent(CEvent::kQuit));
}
static void handleSuspend(const CEvent& event, void*);
static void handleResume(const CEvent& event, void*);
static
CScreen*
openServerScreen()
@ -233,6 +249,14 @@ openServerScreen()
screen->getEventTarget(),
new CFunctionEventJob(
&handleScreenError));
EVENTQUEUE->adoptHandler(IScreen::getSuspendEvent(),
screen->getEventTarget(),
new CFunctionEventJob(
&handleSuspend));
EVENTQUEUE->adoptHandler(IScreen::getResumeEvent(),
screen->getEventTarget(),
new CFunctionEventJob(
&handleResume));
return screen;
}
@ -243,6 +267,10 @@ closeServerScreen(CScreen* screen)
if (screen != NULL) {
EVENTQUEUE->removeHandler(IScreen::getErrorEvent(),
screen->getEventTarget());
EVENTQUEUE->removeHandler(IScreen::getSuspendEvent(),
screen->getEventTarget());
EVENTQUEUE->removeHandler(IScreen::getResumeEvent(),
screen->getEventTarget());
delete screen;
}
}
@ -319,69 +347,105 @@ closeServer(CServer* server)
delete server;
}
static bool initServer();
static bool startServer();
static
void
retryStartHandler(const CEvent&, void* vtimer)
stopRetryTimer()
{
if (s_timer != NULL) {
EVENTQUEUE->deleteTimer(s_timer);
EVENTQUEUE->removeHandler(CEvent::kTimer, NULL);
s_timer = NULL;
}
}
static
void
retryHandler(const CEvent&, void*)
{
// discard old timer
CEventQueueTimer* timer = reinterpret_cast<CEventQueueTimer*>(vtimer);
EVENTQUEUE->deleteTimer(timer);
EVENTQUEUE->removeHandler(CEvent::kTimer, NULL);
assert(s_timer != NULL);
stopRetryTimer();
// try starting the server again
// try initializing/starting the server again
switch (s_serverState) {
case kUninitialized:
case kInitialized:
case kStarted:
assert(0 && "bad internal server state");
break;
case kInitializing:
LOG((CLOG_DEBUG1 "retry server initialization"));
s_serverState = kUninitialized;
if (!initServer()) {
EVENTQUEUE->addEvent(CEvent(CEvent::kQuit));
}
break;
case kInitializingToStart:
LOG((CLOG_DEBUG1 "retry server initialization"));
s_serverState = kUninitialized;
if (!initServer()) {
EVENTQUEUE->addEvent(CEvent(CEvent::kQuit));
}
else if (s_serverState == kInitialized) {
LOG((CLOG_DEBUG1 "starting server"));
if (!startServer()) {
EVENTQUEUE->addEvent(CEvent(CEvent::kQuit));
}
}
break;
case kStarting:
LOG((CLOG_DEBUG1 "retry starting server"));
startServer();
s_serverState = kInitialized;
if (!startServer()) {
EVENTQUEUE->addEvent(CEvent(CEvent::kQuit));
}
break;
}
}
static
bool
startServer()
initServer()
{
// skip if already initialized or initializing
if (s_serverState != kUninitialized) {
return true;
}
double retryTime;
CScreen* serverScreen = NULL;
CPrimaryClient* primaryClient = NULL;
CClientListener* listener = NULL;
try {
CString name = ARG->m_config->getCanonicalName(ARG->m_name);
serverScreen = openServerScreen();
primaryClient = openPrimaryClient(name, serverScreen);
listener = openClientListener(ARG->m_config->getSynergyAddress());
s_server = openServer(*ARG->m_config, primaryClient);
s_serverScreen = serverScreen;
s_primaryClient = primaryClient;
s_listener = listener;
s_serverState = kInitialized;
updateStatus();
LOG((CLOG_NOTE "started server"));
return true;
}
catch (XScreenUnavailable& e) {
LOG((CLOG_WARN "cannot open primary screen: %s", e.what()));
closeClientListener(listener);
closePrimaryClient(primaryClient);
closeServerScreen(serverScreen);
updateStatus(CString("cannot open primary screen: ") + e.what());
retryTime = e.getRetryTime();
}
catch (XSocketAddressInUse& e) {
LOG((CLOG_WARN "cannot listen for clients: %s", e.what()));
closeClientListener(listener);
closePrimaryClient(primaryClient);
closeServerScreen(serverScreen);
updateStatus(CString("cannot listen for clients: ") + e.what());
retryTime = 10.0;
}
catch (XScreenOpenFailure& e) {
LOG((CLOG_CRIT "cannot open primary screen: %s", e.what()));
closeClientListener(listener);
closePrimaryClient(primaryClient);
closeServerScreen(serverScreen);
return false;
}
catch (XBase& e) {
LOG((CLOG_CRIT "failed to start server: %s", e.what()));
closeClientListener(listener);
closePrimaryClient(primaryClient);
closeServerScreen(serverScreen);
return false;
@ -389,10 +453,74 @@ startServer()
if (ARG->m_restartable) {
// install a timer and handler to retry later
assert(s_timer == NULL);
LOG((CLOG_DEBUG "retry in %.0f seconds", retryTime));
CEventQueueTimer* timer = EVENTQUEUE->newOneShotTimer(retryTime, NULL);
EVENTQUEUE->adoptHandler(CEvent::kTimer, timer,
new CFunctionEventJob(&retryStartHandler, timer));
s_timer = EVENTQUEUE->newOneShotTimer(retryTime, NULL);
EVENTQUEUE->adoptHandler(CEvent::kTimer, s_timer,
new CFunctionEventJob(&retryHandler, NULL));
s_serverState = kInitializing;
return true;
}
else {
// don't try again
return false;
}
}
static
bool
startServer()
{
// skip if already started or starting
if (s_serverState == kStarting || s_serverState == kStarted) {
return true;
}
// initialize if necessary
if (s_serverState != kInitialized) {
if (!initServer()) {
// hard initialization failure
return false;
}
if (s_serverState == kInitializing) {
// not ready to start
s_serverState = kInitializingToStart;
return true;
}
assert(s_serverState == kInitialized);
}
double retryTime;
CClientListener* listener = NULL;
try {
listener = openClientListener(ARG->m_config->getSynergyAddress());
s_server = openServer(*ARG->m_config, s_primaryClient);
s_listener = listener;
updateStatus();
LOG((CLOG_NOTE "started server"));
s_serverState = kStarted;
return true;
}
catch (XSocketAddressInUse& e) {
LOG((CLOG_WARN "cannot listen for clients: %s", e.what()));
closeClientListener(listener);
updateStatus(CString("cannot listen for clients: ") + e.what());
retryTime = 10.0;
}
catch (XBase& e) {
LOG((CLOG_CRIT "failed to start server: %s", e.what()));
closeClientListener(listener);
return false;
}
if (ARG->m_restartable) {
// install a timer and handler to retry later
assert(s_timer == NULL);
LOG((CLOG_DEBUG "retry in %.0f seconds", retryTime));
s_timer = EVENTQUEUE->newOneShotTimer(retryTime, NULL);
EVENTQUEUE->adoptHandler(CEvent::kTimer, s_timer,
new CFunctionEventJob(&retryHandler, NULL));
s_serverState = kStarting;
return true;
}
else {
@ -405,14 +533,63 @@ static
void
stopServer()
{
if (s_serverState == kStarted) {
closeClientListener(s_listener);
closeServer(s_server);
closePrimaryClient(s_primaryClient);
closeServerScreen(s_serverScreen);
s_server = NULL;
s_listener = NULL;
s_serverState = kInitialized;
}
else if (s_serverState == kStarting) {
stopRetryTimer();
s_serverState = kInitialized;
}
assert(s_server == NULL);
assert(s_listener == NULL);
}
static
void
cleanupServer()
{
stopServer();
if (s_serverState == kInitialized) {
closePrimaryClient(s_primaryClient);
closeServerScreen(s_serverScreen);
s_primaryClient = NULL;
s_serverScreen = NULL;
s_serverState = kUninitialized;
}
else if (s_serverState == kInitializing ||
s_serverState == kInitializingToStart) {
stopRetryTimer();
s_serverState = kUninitialized;
}
assert(s_primaryClient == NULL);
assert(s_serverScreen == NULL);
assert(s_serverState == kUninitialized);
}
static
void
handleSuspend(const CEvent&, void*)
{
if (!s_suspended) {
LOG((CLOG_INFO "suspend"));
stopServer();
s_suspended = true;
}
}
static
void
handleResume(const CEvent&, void*)
{
if (s_suspended) {
LOG((CLOG_INFO "resume"));
startServer();
s_suspended = false;
}
}
static
@ -517,7 +694,7 @@ mainLoop()
IEventQueue::getSystemTarget());
EVENTQUEUE->removeHandler(getReloadConfigEvent(),
IEventQueue::getSystemTarget());
stopServer();
cleanupServer();
updateStatus();
LOG((CLOG_NOTE "stopped server"));
@ -528,7 +705,11 @@ static
int
daemonMainLoop(int, const char**)
{
CSystemLogger sysLogger(DAEMON_NAME);
#if SYSAPI_WIN32
CSystemLogger sysLogger(DAEMON_NAME, false);
#else
CSystemLogger sysLogger(DAEMON_NAME, true);
#endif
return mainLoop();
}
@ -536,6 +717,10 @@ static
int
standardStartup(int argc, char** argv)
{
if (!ARG->m_daemon) {
ARCH->showConsole(false);
}
// parse command line
parse(argc, argv);
@ -952,6 +1137,7 @@ public:
// ILogOutputter overrides
virtual void open(const char*) { }
virtual void close() { }
virtual void show(bool) { }
virtual bool write(ELevel level, const char* message);
virtual const char* getNewline() const { return ""; }
};
@ -997,11 +1183,27 @@ static
int
daemonNTStartup(int, char**)
{
CSystemLogger sysLogger(DAEMON_NAME);
CSystemLogger sysLogger(DAEMON_NAME, false);
bye = &byeThrow;
return ARCH->daemonize(DAEMON_NAME, &daemonNTMainLoop);
}
static
int
foregroundStartup(int argc, char** argv)
{
ARCH->showConsole(false);
// parse command line
parse(argc, argv);
// load configuration
loadConfig();
// never daemonize
return mainLoop();
}
static
void
showError(HINSTANCE instance, const char* title, UINT id, const char* arg)
@ -1015,12 +1217,23 @@ int WINAPI
WinMain(HINSTANCE instance, HINSTANCE, LPSTR, int)
{
try {
CArchMiscWindows::setIcons((HICON)LoadImage(instance,
MAKEINTRESOURCE(IDI_SYNERGY),
IMAGE_ICON,
32, 32, LR_SHARED),
(HICON)LoadImage(instance,
MAKEINTRESOURCE(IDI_SYNERGY),
IMAGE_ICON,
16, 16, LR_SHARED));
CArch arch(instance);
CMSWindowsScreen::init(instance);
CLOG;
CThread::getCurrentThread().setPriority(-14);
CArgs args;
// set title on log window
ARCH->openConsole((CString(kAppVersion) + " " + "Server").c_str());
// windows NT family starts services using no command line options.
// since i'm not sure how to tell the difference between that and
// a user providing no options we'll assume that if there are no
@ -1028,9 +1241,14 @@ WinMain(HINSTANCE instance, HINSTANCE, LPSTR, int)
// users on NT can use `--daemon' or `--no-daemon' to force us out
// of the service code path.
StartupFunc startup = &standardStartup;
if (__argc <= 1 && !CArchMiscWindows::isWindows95Family()) {
if (!CArchMiscWindows::isWindows95Family()) {
if (__argc <= 1) {
startup = &daemonNTStartup;
}
else {
startup = &foregroundStartup;
}
}
// send PRINT and FATAL output to a message box
int result = run(__argc, __argv, new CMessageBoxOutputter, startup);

View File

@ -43,7 +43,7 @@ RSC=rc.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /MT /W4 /GX /O2 /I "..\..\lib\common" /I "..\..\lib\arch" /I "..\..\lib\base" /I "..\..\lib\mt" /I "..\..\lib\io" /I "..\..\lib\net" /I "..\..\lib\synergy" /I "..\..\lib\platform" /I "..\..\lib\server" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /Fd"..\..\gen\build\synergys.pdb" /FD /c
# ADD CPP /nologo /MT /W4 /GR /GX /O2 /I "..\..\lib\common" /I "..\..\lib\arch" /I "..\..\lib\base" /I "..\..\lib\mt" /I "..\..\lib\io" /I "..\..\lib\net" /I "..\..\lib\synergy" /I "..\..\lib\platform" /I "..\..\lib\server" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /Fd"..\..\gen\build\synergys.pdb" /FD /c
# SUBTRACT CPP /YX
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
@ -70,7 +70,7 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
# ADD CPP /nologo /MTd /W4 /Gm /GX /ZI /Od /I "..\..\lib\common" /I "..\..\lib\arch" /I "..\..\lib\base" /I "..\..\lib\mt" /I "..\..\lib\io" /I "..\..\lib\net" /I "..\..\lib\synergy" /I "..\..\lib\platform" /I "..\..\lib\server" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /Fd"..\..\gen\debug\synergys.pdb" /FD /GZ /c
# ADD CPP /nologo /MTd /W4 /Gm /GR /GX /ZI /Od /I "..\..\lib\common" /I "..\..\lib\arch" /I "..\..\lib\base" /I "..\..\lib\mt" /I "..\..\lib\io" /I "..\..\lib\net" /I "..\..\lib\synergy" /I "..\..\lib\platform" /I "..\..\lib\server" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /Fd"..\..\gen\debug\synergys.pdb" /FD /GZ /c
# SUBTRACT CPP /YX
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 8.3 KiB

View File

@ -73,7 +73,25 @@ BEGIN
POPUP "Synergy"
BEGIN
MENUITEM "Show Status", IDC_TASKBAR_STATUS
MENUITEM "Show Log", IDC_TASKBAR_SHOW_LOG
MENUITEM "Copy Log To Clipboard", IDC_TASKBAR_LOG
POPUP "Set Log Level"
BEGIN
MENUITEM "Error", IDC_TASKBAR_LOG_LEVEL_ERROR
MENUITEM "Warning", IDC_TASKBAR_LOG_LEVEL_WARNING
MENUITEM "Note", IDC_TASKBAR_LOG_LEVEL_NOTE
MENUITEM "Info", IDC_TASKBAR_LOG_LEVEL_INFO
MENUITEM "Debug", IDC_TASKBAR_LOG_LEVEL_DEBUG
MENUITEM "Debug1", IDC_TASKBAR_LOG_LEVEL_DEBUG1
MENUITEM "Debug2", IDC_TASKBAR_LOG_LEVEL_DEBUG2
END
MENUITEM "Reload Configuration", IDC_RELOAD_CONFIG
MENUITEM "Force Reconnect", IDC_FORCE_RECONNECT
MENUITEM SEPARATOR

Binary file not shown.

Before

Width:  |  Height:  |  Size: 318 B

After

Width:  |  Height:  |  Size: 318 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 318 B

After

Width:  |  Height:  |  Size: 318 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 318 B

After

Width:  |  Height:  |  Size: 318 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 318 B

After

Width:  |  Height:  |  Size: 318 B

View File

@ -53,10 +53,19 @@ AM_CONDITIONAL(CARBON, test x$acx_host_winapi = xCARBON)
AM_CONDITIONAL(XWINDOWS, test x$acx_host_winapi = xXWINDOWS)
dnl checks for programs
AC_PROG_CC
AC_PROG_CXX
AC_PROG_RANLIB
AC_CHECK_PROG(HAVE_DOT, dot, YES, NO)
dnl AC_PROG_OBJC doesn't exist. Borrow some ideas from KDE.
dnl AC_MSG_CHECKING(for an Objective-C compiler)
OBJC="${CC}"
OBJCFLAGS="${CFLAGS}"
AC_SUBST(OBJC)
AC_SUBST(OBJCFLAGS)
_AM_DEPENDENCIES(OBJC)
dnl do checks using C++
AC_LANG_CPLUSPLUS
@ -88,7 +97,7 @@ ACX_CHECK_INET_ATON
dnl checks for header files
AC_HEADER_STDC
AC_CHECK_HEADERS([unistd.h sys/time.h sys/types.h wchar.h alloca.h])
AC_CHECK_HEADERS([unistd.h sys/time.h sys/types.h locale.h wchar.h])
AC_CHECK_HEADERS([sys/socket.h sys/select.h])
AC_CHECK_HEADERS([sys/utsname.h])
AC_CHECK_HEADERS([istream ostream sstream])
@ -109,6 +118,33 @@ if test x"$acx_host_winapi" = xXWINDOWS; then
,
AC_MSG_ERROR(You must have the XTest headers to compile synergy))
acx_have_xkb=no
AC_CHECK_LIB(X11,
XkbQueryExtension,
[acx_have_xkb=yes],
[acx_have_xkb=no],
[$X_LIBS $X_EXTRA_LIBS])
if test x"$acx_have_xkb" = xyes; then
AC_CHECK_HEADERS([X11/XKBlib.h X11/extensions/XKBstr.h],
[acx_have_xkb=yes],
[acx_have_xkb=no],
[#include <X11/Xlib.h>])
if test x"$acx_have_xkb" = xyes; then
AC_TRY_COMPILE([
#include <X11/Xlib.h>
#include <X11/XKBlib.h>
],[
XkbQueryExtension(0, 0, 0, 0, 0, 0);
],
[acx_have_xkb=yes],
[acx_have_xkb=no])
fi
fi
if test x"$acx_have_xkb" = xyes; then
AC_DEFINE(HAVE_XKB_EXTENSION, 1,
[Define this if the XKB extension is available.])
fi
acx_have_xinerama=yes
AC_CHECK_LIB(Xinerama,
XineramaQueryExtension,
@ -207,8 +243,25 @@ ACX_CXX_WARNINGS_ARE_ERRORS
dnl adjust compiler and linker variables
CXXFLAGS="$CXXFLAGS $SYNERGY_CXXFLAGS $ARCH_CFLAGS"
OBJCXXFLAGS="$OBJCXXFLAGS $CXXFLAGS $ARCH_CFLAGS"
LIBS="$NANOSLEEP_LIBS $INET_ATON_LIBS $ARCH_LIBS $LIBS"
dnl we need to have an environment variable set when building on OS X.
dnl i'm not sure of the right way to do that. writing 'export ...' to
dnl the makefiles isn't portable. here we'll hijack XXXDEPMODE (where
dnl XXX depends on the language) to insert setting the environment
dnl variable when running the compiler. we'd like to put that in CC,
dnl CXX and OBJC but that breaks depcomp. let's hope this works.
if test x"$acx_host_winapi" = xCARBON; then
MACOSX_DEPLOYMENT_TARGET="10.2"
CCDEPMODE="MACOSX_DEPLOYMENT_TARGET=$MACOSX_DEPLOYMENT_TARGET $CCDEPMODE"
CXXDEPMODE="MACOSX_DEPLOYMENT_TARGET=$MACOSX_DEPLOYMENT_TARGET $CXXDEPMODE"
OBJCDEPMODE="MACOSX_DEPLOYMENT_TARGET=$MACOSX_DEPLOYMENT_TARGET $OBJCDEPMODE"
else
MACOSX_DEPLOYMENT_TARGET="5"
CXXDEPMODE="FOO=$MACOSX_DEPLOYMENT_TARGET $CXXDEPMODE"
fi
AC_OUTPUT([
Makefile
cmd/Makefile

View File

@ -62,20 +62,31 @@ Section "Synergy (required)"
File COPYING.txt
File ChangeLog.txt
File ${DEPTH}\doc\PORTING
File ${DEPTH}\doc\about.html
File ${DEPTH}\doc\authors.html
File ${DEPTH}\doc\autostart.html
File ${DEPTH}\doc\banner.html
File ${DEPTH}\doc\compiling.html
File ${DEPTH}\doc\configuration.html
File ${DEPTH}\doc\contact.html
File ${DEPTH}\doc\developer.html
File ${DEPTH}\doc\faq.html
File ${DEPTH}\doc\history.html
File ${DEPTH}\doc\home.html
File ${DEPTH}\doc\index.html
File ${DEPTH}\doc\license.html
File ${DEPTH}\doc\news.html
File ${DEPTH}\doc\roadmap.html
File ${DEPTH}\doc\running.html
File ${DEPTH}\doc\security.html
File ${DEPTH}\doc\synergy.css
File ${DEPTH}\doc\tips.html
File ${DEPTH}\doc\todo.html
File ${DEPTH}\doc\toc.html
File ${DEPTH}\doc\trouble.html
SetOutPath $INSTDIR\images
File ${DEPTH}\doc\images\logo.gif
File ${DEPTH}\doc\images\warp.gif
; Write the installation path into the registry
WriteRegStr HKLM SOFTWARE\Synergy "Install_Dir" "$INSTDIR"
@ -95,17 +106,25 @@ Section "Start Menu Shortcuts"
CreateDirectory "$SMPROGRAMS\Synergy"
CreateShortCut "$SMPROGRAMS\Synergy\Synergy.lnk" "$INSTDIR\synergy.exe" "" "$INSTDIR\synergy.exe" 0
CreateShortCut "$SMPROGRAMS\Synergy\README.lnk" "$INSTDIR\index.html"
CreateShortCut "$SMPROGRAMS\Synergy\FAQ.lnk" "$INSTDIR\faq.html"
CreateShortCut "$SMPROGRAMS\Synergy\Synergy Folder.lnk" "$INSTDIR"
CreateShortCut "$SMPROGRAMS\Synergy\Uninstall.lnk" "$INSTDIR\uninstall.exe" "" "$INSTDIR\uninstall.exe" 0
SectionEnd
; Optional section (can be disabled by the user)
Section "Desktop Icon"
CreateShortCut "$DESKTOP\Synergy.lnk" "$INSTDIR\synergy.exe" "" "$INSTDIR\synergy.exe" 0
SectionEnd
;--------------------------------
; Uninstaller
Section "Uninstall"
; Stop and uninstall the daemons
ExecWait '"$INSTDIR\synergy.exe" /uninstall'
; Remove autorun registry keys for synergy
DeleteRegKey HKLM "SYSTEM\CurrentControlSet\Services\Synergy Server"
@ -136,6 +155,7 @@ Section "Uninstall"
; Remove shortcuts, if any
Delete "$SMPROGRAMS\Synergy\*.*"
Delete "$DESKTOP\Synergy.lnk"
; Remove directories used
RMDir "$SMPROGRAMS\Synergy"

View File

@ -3,7 +3,7 @@ Name: @PACKAGE@
Version: @VERSION@
Release: 1
License: GPL
Packager: Chris Schoeneman <crs23@bigfoot.com>
Packager: Chris Schoeneman <crs23@users.sourceforge.net>
Group: System Environment/Daemons
Prefixes: /usr/bin
Source: @PACKAGE@-@VERSION@.tar.gz
@ -41,19 +41,26 @@ rm -rf $RPM_BUILD_ROOT
%doc INSTALL
%doc NEWS
%doc README
%doc doc/about.html
%doc doc/authors.html
%doc doc/autostart.html
%doc doc/banner.html
%doc doc/border.html
%doc doc/compiling.html
%doc doc/configuration.html
%doc doc/contact.html
%doc doc/developer.html
%doc doc/faq.html
%doc doc/history.html
%doc doc/home.html
%doc doc/index.html
%doc doc/license.html
%doc doc/news.html
%doc doc/roadmap.html
%doc doc/running.html
%doc doc/security.html
%doc doc/tips.html
%doc doc/todo.html
%doc doc/toc.html
%doc doc/trouble.html
%doc doc/synergy.css
%doc examples/synergy.conf

View File

@ -17,20 +17,29 @@ EXTRA_DIST = \
PORTING \
doxygen.cfg.in \
synergy.css \
about.html \
authors.html \
autostart.html \
banner.html \
border.html \
compiling.html \
configuration.html \
contact.html \
developer.html \
faq.html \
history.html \
home.html \
index.html \
license.html \
news.html \
roadmap.html \
running.html \
security.html \
tips.html \
todo.html \
toc.html \
trouble.html \
images/logo.gif \
images/warp.gif \
$(NULL)
MAINTAINERCLEANFILES = \

55
doc/about.html Normal file
View File

@ -0,0 +1,55 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
<html>
<head>
<meta HTTP-EQUIV="Content-Type" CONTENT="text/html;CHARSET=iso-8859-1">
<meta name="keywords" content="Virtual Screen, Open Source, Software" />
<meta name="description" content="Mouse and Keyboard Sharing" />
<link rel="stylesheet" type="text/css" href="synergy.css" media="screen" />
<title>About Synergy</title>
</head>
<body class="main">
<p>
With synergy, all the computers on your desktop form a single virtual
screen. You use the mouse and keyboard of only one of the computers
while you use all of the monitors on all of the computers.
You tell synergy how many screens you have and their positions relative
to one another. Synergy then detects when the mouse moves off
the edge of a screen and jumps it instantly to the neighboring screen.
The keyboard works normally on each screen; input goes to whichever
screen has the cursor.
</p><p>
In this example, the user is moving the mouse from left to right.
When the cursor reaches the right edge of the left screen it jumps
instantly to the left edge of the right screen.
</p><p>
<center><img src="images/warp.gif"></center>
</p><p>
You can arrange screens side-by-side, above and below one another,
or any combination. You can even have a screen jump to the opposite
edge of itself. Synergy also understands multiple screens attached
to the same computer.
</p><p>
Running a game and don't want synergy to jump screens? No problem.
Just toggle Scroll Lock. Synergy keeps the cursor on the same screen
when Scroll Lock is on. (This can be configured to another hot key.)
</p><p>
Do you wish you could cut and paste between computers? Now you can!
Just copy text, HTML, or an image as you normally would on one screen
then switch to another screen and paste it. It's as if all your
computers shared a single clipboard (and separate primary selection for
you X11 users). It even converts newlines to each computer's native
form so cut and paste between different operating systems works
seamlessly. And it does it all in Unicode so any text can be copied.
</p><p>
</p><p>
Do you use a screen saver? With synergy all your screen savers act in
concert. When one starts they all start. When one stops they all
stop. And, if you require a password to unlock the screen, you'll
only have to enter a password on one screen.
</p><p>
If you regularly use multiple computers on one desk, give synergy a
try. You'll wonder how you ever lived without it.
</p>
</body>
</html>

View File

@ -1,38 +1,65 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
<html>
<head>
<meta HTTP-EQUIV="Content-Type" CONTENT="text/html;CHARSET=iso-8859-1">
<meta name="keywords" content="Virtual Screen, Open Source, Software" />
<meta name="description" content="Mouse and Keyboard Sharing" />
<link rel="stylesheet" type="text/css" href="synergy.css" media="screen" />
<title>Synergy Authors</title>
</head>
<body class="main">
<h3>Synergy Authors</h3>
<p>
</p><h3>Synergy Authors</h3><p>
</p><p>
<table>
<tr>
<td><a href="mailto:crs23@users.sourceforge.net">Chris Schoeneman</a></td>
<td>Chris Schoeneman</td>
<td>&nbsp;</td>
<td><span class="fakelink">crs23@users.sourceforge<span class="hide">.no_spam</span>.net</span></td>
<td>&nbsp;</td>
<td>Creator, owner, primary developer</td>
</tr>
<tr>
<td><a href="mailto:ryan@ryanbreen.com">Ryan Breen</a></td>
<td>Ryan Breen</td>
<td>&nbsp;</td>
<td><span class="fakelink">ryan@ryanbreen<span class="hide">.no_spam</span>.com</span></td>
<td>&nbsp;</td>
<td>Initial Mac OS X port</td>
</tr>
<tr>
<td><a href="mailto:moolder@gmx.net">Guido Poschta</a></td>
<td>Guido Poschta</td>
<td>&nbsp;</td>
<td><span class="fakelink">moolder@gmx<span class="hide">.no_spam</span>.net</span></td>
<td>&nbsp;</td>
<td>Windows installer</td>
</tr>
<tr>
<td><a href="mailto:bertrand@landryhetu.com">Bertrand Landry Hetu</a></td>
<td>Bertrand Landry Hetu</td>
<td>&nbsp;</td>
<td><span class="fakelink">bertrand@landryhetu<span class="hide">.no_spam</span>.com</span></td>
<td>&nbsp;</td>
<td>Mac OS X port</td>
</tr>
<tr>
<td><a href="mailto:vttom@users.sourceforge.net">Tom Chadwick</a></td>
<td>Tom Chadwick</td>
<td>&nbsp;</td>
<td><span class="fakelink">vttom@users.sourceforge<span class="hide">.no_spam</span>.net</span></td>
<td>&nbsp;</td>
<td>PageUp/PageDown on X servers without mouse wheel support</td>
</tr>
<tr>
<td><a href="mailto:toopriddy@users.sourceforge.net">Brent Priddy</a></td>
<td>Brent Priddy</td>
<td>&nbsp;</td>
<td><span class="fakelink">toopriddy@users.sourceforge<span class="hide">.no_spam</span>.net</span></td>
<td>&nbsp;</td>
<td>Re-resolving server hostname on each connection</td>
</tr>
</table>
</p><p>
To avoid spam bots, the above email addresses have ".no_spam"
hidden near the end. If you copy and paste the text be sure to
remove it.
</p>
</body>
</html>

View File

@ -1,41 +1,41 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
<html>
<head>
<meta HTTP-EQUIV="Content-Type" CONTENT="text/html;CHARSET=iso-8859-1">
<meta name="keywords" content="Virtual Screen, Open Source, Software" />
<meta name="description" content="Mouse and Keyboard Sharing" />
<link rel="stylesheet" type="text/css" href="synergy.css" media="screen" />
<title>Synergy Autostart Guide</title>
</head>
<body class="main">
<h3>Starting synergy automatically</h3>
<p>
</p><h3>Starting synergy automatically</h3><p>
</p><p>
You can configure synergy to start automatically when the computer
starts or when you log in. The steps to do that are different on
each platform. Note that changing these configurations doesn't
actually start or stop synergy. The changes take effect the next
time you start your computer or log in.
</p>
<h4>Windows</h4>
<p>
</p><p>
</p><h4>Windows</h4><p>
</p><p>
Start synergy and click the <span class="code">Configure...</span> button
by the text <span class="code">Automatic Startup</span>. The
<span class="code">Auto Start</span> dialog will pop up.
If an error occurs then correct the problem and click
<span class="code">Configure</span> again.
</p>
<p>
</p><p>
On the <span class="code">Auto Start</span> dialog you'll configure
synergy to start or not start automatically when the computer starts
or when you log in. You need Administrator access rights to start
synergy automatically when the computer starts. The dialog will let
you know if you have sufficient permission.
</p>
<p>
</p><p>
If synergy is already configured to automatically start then there
will be two <span class="code">Uninstall</span> buttons, at most one
of which is enabled. Click the enabled button, if any, to tell
synergy to not start automatically.
</p>
<p>
</p><p>
If synergy is not configured to start automatically then there will
be two <span class="code">Install</span> buttons. If you have
sufficient permission to have synergy start automatically when the
@ -46,10 +46,9 @@ In this case, synergy will be available during the login screen.
Otherwise, click the <span class="code">Install</span> button in the
<span class="code">When You Log In</span> box to have synergy
automatically start when you log in.
</p>
<h4>Unix</h4>
<p>
</p><p>
</p><h4>Unix</h4><p>
</p><p>
Synergy requires an X server. That means a server must be
running and synergy must be authorized to connect to that server.
It's best to have the display manager start synergy. You'll need
@ -57,34 +56,33 @@ the necessary (probably root) permission to modify the display
manager configuration files. If you don't have that permission
you can start synergy after logging in via the
<span class="code">.xsession</span> file.
</p>
<p>
</p><p>
Typically, you need to edit three script files. The first file
will start synergy before a user logs in, the second will kill
that copy of synergy, and the third will start it again after
the user logs in.
</p>
<p>
</p><p>
The contents of the scripts varies greatly between systems so
there's no one definite place where you should insert your edits.
However, these scripts often exit before reaching the bottom so
put the edits near the top of the script.
</p>
<p>
</p><p>
The location and names of these files depend on the operating
system and display manager you're using. A good guess for the
location is <span class="code">/etc/X11</span>. Typical file names
are:
</p>
<p class="code">
location is <span class="code">/etc/X11</span>. If you use kdm
then try looking in <span class="code">/etc/kde3</span> or
<span class="code">/usr/kde/<span class="arg">version</span>/share/config</span>.
Typical file names are:
</p><p>
<span class="code">
<table>
<tr><td>&nbsp;&nbsp;</td> <td>&nbsp;&nbsp;</td> <td>xdm</td> <td>&nbsp;&nbsp;</td> <td>gdm</td></tr>
<tr><td>1</td> <td></td> <td>xdm/Xsetup</td> <td></td> <td>gdm/Init/Default (*)</td></tr>
<tr><td>2</td> <td></td> <td>xdm/Xstartup</td> <td></td> <td>gdm/PostLogin/Default (*)</td></tr>
<tr><td>3</td> <td></td> <td>xdm/Xsession</td> <td></td> <td>gdm/Sessions/Default (*, **)</td></tr>
<tr><td>&nbsp;&nbsp;</td> <td>&nbsp;&nbsp;</td> <td>xdm</td> <td>&nbsp;&nbsp;</td> <td>kdm</td> <td>&nbsp;&nbsp;</td> <td>gdm</td></tr>
<tr><td>1</td> <td></td> <td>xdm/Xsetup</td> <td></td> <td>kdm/Xsetup</td> <td></td> <td>gdm/Init/Default (*)</td></tr>
<tr><td>2</td> <td></td> <td>xdm/Xstartup</td> <td></td> <td>kdm/Xstartup</td> <td></td> <td>gdm/PostLogin/Default (*)</td></tr>
<tr><td>3</td> <td></td> <td>xdm/Xsession</td> <td></td> <td>kdm/Xsession</td> <td></td> <td>gdm/Sessions/Default (*, **)</td></tr>
</table>
</p>
<p>
</span>
</p><p>
*) The <span class="code">Default</span> file is used if no other
suitable file is found. <span class="code">gdm</span> will try
<span class="arg">displayname</span> (e.g. <span class="code">:0</span>)
@ -95,8 +93,7 @@ in that order, before and instead of <span class="code">Default</span>.
<span class="code">xdm/Xsession</span> or
<span class="code">dm/Xsession</span> if
<span class="code">gdm/Sessions/Default</span> doesn't exist.
</p>
<p>
</p><p>
For a synergy client, add the following to the first file:
<span class="codeblock">
/usr/bin/killall synergyc
@ -105,15 +102,13 @@ For a synergy client, add the following to the first file:
</span>
Of course, the path to synergyc depends on where you installed it
so adjust as necessary.
</p>
<p>
</p><p>
Add to the second file:
<span class="codeblock">
/usr/bin/killall synergyc
sleep 1
</span>
</p>
<p>
</p><p>
And to the third file:
<span class="codeblock">
/usr/bin/killall synergyc
@ -124,8 +119,7 @@ Note that <a href="running.html#options"><span class="arg">&lt;options&gt;</span
must not include
<span class="code">-f</span> or <span class="code">--no-daemon</span> or
the script will never exit and you won't be able to log in.
</p>
<p>
</p><p>
The changes are the same for the synergy server except replace
<span class="code">synergyc</span> with <span class="code">synergys</span>
and use the appropriate synergys <a href="running.html#options">command
@ -135,38 +129,32 @@ file in root's home directory then in <span class="code">/etc</span>.
Make sure it exists in one of those places or use the
<span class="code">--config <span class="arg">config-pathname</span></span>
option to specify its location.
</p>
<p>
</p><p>
Note that some display managers (xdm and kdm, but not gdm) grab
the keyboard and do not release it until the user logs in for
security reasons. This prevents a synergy server from sharing
the mouse and keyboard until the user logs in. It doesn't
prevent a synergy client from synthesizing mouse and keyboard
input, though.
</p>
<p>
</p><p>
If you're configuring synergy to start only after you log in then edit
your <span class="code">.xsession</span> file. Add just what you
would add to the third file above.
</p>
<h4>Mac OS X</h4>
<p>
</p><p>
</p><h4>Mac OS X</h4><p>
</p><p>
[By Tor Slettnes]
</p>
<p>
</p><p>
There are three different ways to automatically start Synergy
(client or server) on Mac OS X:
</p>
<p>
</p><p>
<ol>
<li>
The first method involves creating a <span class="code">StartupItem</span>
at the system level, which is executed when the machine starts up
or shuts down. This script will run in the background, and
relaunch synergy as needed.
</p>
<p>
</p><p>
<dl>
<dt><b>Pros:</b></dt>
<dd>
@ -180,14 +168,12 @@ There are three different ways to automatically start Synergy
</dd>
</dl>
</li>
</p>
<p>
</p><p>
<li>
The second method will launch Synergy from the
<span class="code">LoginWindow</span> application, once a particular
user has logged in.
</p>
<p>
</p><p>
<dl>
<dt><b>Pros:</b></dt>
<dd>
@ -202,13 +188,11 @@ There are three different ways to automatically start Synergy
</dd>
</dl>
</li>
</p>
<p>
</p><p>
<li>
The third method is to launch a startup script from the
"Startup Items" tab under System Preferences -> Accounts.
</p>
<p>
</p><p>
<dl>
<dt><b>Pros:</b></dt>
<dd>
@ -222,17 +206,14 @@ There are three different ways to automatically start Synergy
</dl>
</li>
</ol>
</p>
<p>
</p><p>
The text below describes how to implement a Synergy client using
the first two methods simultaneously. This way, Synergy is
always running, and the clipboard is available when someone is
logged in. A Mac OS X Synergy server setup will be quite similar.
</p>
<p>
</p><p>
<b>1. Create a System Level Startup Item</b>
</p>
<p>
</p><p>
<ul>
<li>
Open a <span class="code">Terminal</span> window, and become root:
@ -250,8 +231,7 @@ logged in. A Mac OS X Synergy server setup will be quite similar.
In this folder, create a new script file by the same name as
the directory itself, <span class="code">Synergy</span>. This script
should contain the following text:
</p>
<p>
</p><p>
<span class="codeblock">
#!/bin/sh
. /etc/rc.common
@ -291,12 +271,10 @@ RestartService ()
&nbsp;
RunService "$1"
</span>
</p>
<p>
</p><p>
However, replace <span class="arg">synergy-server</span> with the actual
name or IP address of your Synergy server.
</p>
<p>
</p><p>
Note that this scripts takes care <em>not</em> to start
Synergy if another instance is currently running. This
allows it to run in the background even when synergy is also
@ -312,39 +290,32 @@ RunService "$1"
<li>
In the same folder, create a file named
<span class="code">StartupParameters.plist</span> containing:
</p>
<p>
</p><p>
<span class="codeblock">
{
Description = "Synergy Client";
Provides = ("synergy-client");
Requires = "Network";
Provides = ("Synergy");
Requires = ("Network");
OrderPreference = "None";
}
</span>
</li>
</ul>
</p>
<p>
</p><p>
That's it! If you want to test this setup, you can run the
startup script as follow:
</p>
<p>
startup script as follows:
</p><p>
<span class="userinput">
# /Library/StartupItems/Synergy/Synergy start
</span>
</p>
<p>
</p><p>
Any errors, as well as output from Synergy, will be shown in
your terminal window.
</p>
<p>
</p><p>
Next time you reboot, Synergy should start automatically.
</p>
<p>
</p><p>
<b>2. Run Synergy When a User Logs In</b>
</p>
<p>
</p><p>
Each time a user successfully logs in via the console, the
<span class="code">LoginWindow</span> application creates a unique session
cookie and stores it in the environment variable
@ -352,57 +323,48 @@ cookie and stores it in the environment variable
to work, Synergy needs access to this environment variable. In
other words, Synergy needs to be launched (directly or
indirectly) via the <span class="code">LoginWindow</span> application.
</p>
<p>
</p><p>
However, in order to kill any synergy processes started at the
system level (as described above), we need root access. Thus,
launching Synergy within the User's environment (e.g. via the
Startup Items tab in System Preferences -> Accounts) is not an
option that work in conjunction with the method above.
</p>
<p>
</p><p>
Fortunately, the <span class="code">LoginWindow</span> application provides
a "hook" for running a custom program (as root, with the username provided as
the first and only argument) once a user has authenticated, but
before the user is logged in.
</p>
<p>
</p><p>
Unfortunately, only one such hook is available. If you have
already installed a Login Hook, you may need to add the text
from below to your existing script, rather than creating a new
one.
</p>
<p>
</p><p>
<ul>
<li>
Launch a Terminal window, and become root:
<span class="userinput">
$ sudo su -
</span>
</li>
</p>
<p>
</p><p>
<li>
Find out if a LoginHook already exists:
<span class="userinput">
# defaults read /Library/Preferences/com.apple.loginwindow LoginHook
# defaults read com.apple.loginwindow LoginHook
</span>
</p>
<p>
This will either show the full path to a script or
executable file, or the text:
<span class="userinput">
The domain/default pair of (/Library/Preferences/com.apple.loginwindow, LoginHook) does not exist
The domain/default pair of (com.apple.loginwindow, LoginHook) does not exist
</span>
In the former case, you need to modify your existing script,
and/or create a "superscript" which in turn calls your
existing script plus the one we will create here.
</p>
<p>
</p><p>
The rest of this text assumes that this item did not already
exist, and that we will create a new script.
</li>
</p>
<p>
<li>
Create a folder in which we will store our custom startup
script:
@ -410,16 +372,13 @@ one.
# mkdir -p /Library/LoginWindow
</span>
</li>
</p>
<p>
<li>
In this folder, create a new script file (let's name it
<span class="code">LoginHook.sh</span>), containing the following text:
</p>
<p>
</p><p>
<span class="codeblock">
#!/bin/sh
prog=(/usr/local/bin/synergyc -n $(hostname -s) --camp <span class="arg">ip-address-of-server</span>)
prog=(/usr/local/bin/synergyc -n $(hostname -s) <span class="arg">ip-address-of-server</span>)
&nbsp;
### Stop any currently running Synergy client
killall ${prog[0]##*/}
@ -428,19 +387,23 @@ killall ${prog[0]##*/}
exec "${prog[@]}"
</span>
</li>
</p>
<p>
<li>
Make this script executable:
<span class="userinput">
# chmod 755 /Library/LoginWindow/LoginHook.sh
</span>
</li>
<li>
Create a login hook to call the script you just created:
<span class="userinput">
# defaults write /Library/Preferences/com.apple.loginwindow \
LoginHook /Library/LoginWindow/LoginHook.sh
# defaults&nbsp;write&nbsp;com.apple.loginwindow&nbsp;LoginHook&nbsp;/Library/LoginWindow/LoginHook.sh
</span>
You can instead type the above all on one line but remove the backslash.
</li>
</ul>
</p>
<p>
</p><p>
More information on setting up login hooks can be found at
<a target="_top" href="http://docs.info.apple.com/article.html?artnum=301446">Apple</a>.
</p><p>
When running the Synergy client, you may need to use the IP
address of the Synergy server rather than its host name.
Specifically, unless you have listed the server in your
@ -448,21 +411,18 @@ local <span class="code">/etc/hosts</span> file or in your local NetInfo
database, name services (i.e. DNS) may not yet be available by the
time you log in after power-up. <span class="code">synergyc</span> will
quit if it cannot resolve the server name.
</p>
<p>
</p><p>
(This is not an issue with the previous method, because the
<span class="code">StartupItems.plist</span> file specifies that this
<span class="code">StartupParameters.plist</span> file specifies that this
script should not be run until "network" is available).
</p>
<p>
</p><p>
<b>3. Good Luck!</b>
</p>
<p>
</p><p>
Remember to look in your system log on both your server and your
client(s) for clues to any problems you may have
(<span class="code">/var/log/system.log</span> on your OS X box, typically
<span class="code">/var/log/syslog</span> on Linux boxes).
</p>
</body>
</html>

16
doc/banner.html Normal file
View File

@ -0,0 +1,16 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
<html>
<head>
<meta HTTP-EQUIV="Content-Type" CONTENT="text/html;CHARSET=iso-8859-1">
<meta name="keywords" content="Virtual Screen, Open Source, Software" />
<meta name="description" content="Mouse and Keyboard Sharing" />
<link rel="stylesheet" type="text/css" href="synergy.css" media="screen" />
<title>Synergy Header</title>
<base target="_top">
</head>
<body class="banner">
<table border="0" cellspacing="0" cellpadding="0">
<tr><td><a href="index.html"><img src="images/logo.gif" alt="Synergy" border="0"></a></td></tr>
</table>
</body>
</html>

14
doc/border.html Normal file
View File

@ -0,0 +1,14 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
<html>
<head>
<meta HTTP-EQUIV="Content-Type" CONTENT="text/html;CHARSET=iso-8859-1">
<meta name="keywords" content="Virtual Screen, Open Source, Software" />
<meta name="description" content="Mouse and Keyboard Sharing" />
<link rel="stylesheet" type="text/css" href="synergy.css" media="screen" />
<title>Synergy</title>
<base target="_top">
</head>
<body class="bannerb">
<br>
</body>
</html>

View File

@ -1,39 +1,40 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
<html>
<head>
<meta HTTP-EQUIV="Content-Type" CONTENT="text/html;CHARSET=iso-8859-1">
<meta name="keywords" content="Virtual Screen, Open Source, Software" />
<meta name="description" content="Mouse and Keyboard Sharing" />
<link rel="stylesheet" type="text/css" href="synergy.css" media="screen" />
<title>Building and Installing Synergy</title>
</head>
<body class="main">
<h3>Prerequisites for building</h3>
<p>
</p><h3>Prerequisites for building</h3><p>
</p><p>
To build synergy from the sources you'll need the following:
<ul>
<li>Windows
<ul>
<li>VC++ 6.0 or up
</ul>
</p><p>
<li>Unix
<ul>
<li>gcc 2.95 or up
<li>X11R4 or up headers and libraries
</ul>
</p><p>
<li>Mac OS X
<ul>
<li>XCode; or gcc 2.95 or up
<li>Carbon development headers and libraries
</ul>
</ul>
</p>
<h3>Configuring the build</h3>
<p>
</p><p>
</p><h3>Configuring the build</h3><p>
</p><p>
This step is not necessary when using VC++ or XCode.
</p>
<p>
</p><p>
To configure the build for your platform use the configure script:
<pre>
./configure
@ -47,80 +48,73 @@ On Solaris you may need to use:
<nobr>./configure --x-includes=/usr/openwin/include --x-libraries=/usr/openwin/lib</nobr>
</pre>
so synergy can find the X11 includes and libraries.
</p>
<h3>Building</h3>
</p><p>
</p><h3>Building</h3><p>
<ul>
<li>Windows
<p>
</p><p>
Start VC++ and open <span class="code">synergy.dsw</span>. Set the
active configuration (Build &gt; Set Active Configuration) to
<span class="code">All - Debug</span> or <span class="code">All -
Release</span> then build. Binaries are built into
<span class="code">./debug</span> or <span class="code">./build</span>.
</p>
</p><p>
<li>Unix or Mac OS X without XCode
<p>
</p><p>
Simply enter:
<pre>
make
</pre>
This will build the client and server and leave them in their
respective source directories.
</p>
</p><p>
<li>Mac OS X with XCode
<p>
</p><p>
Start XCode and open the <span class="code">synergy.xcode</span>
project. Build the <span class="code">all</span> project using
the <span class="code">Deployment</span> flavor.
</p>
</p><p>
</ul>
<h3>Installing</h3>
</p><p>
</p><h3>Installing</h3><p>
<ul>
<li>Windows
<p>
You'll need <a href="http://nsis.sourceforge.net/">NSIS</a>, the
</p><p>
You'll need <a target="_top" href="http://nsis.sourceforge.net/">NSIS</a>, the
Nullsoft Scriptable Install System. Build <span class="code">All -
Release</span> then build <span class="code">Installer - Release</span>.
This creates <span class="code">SynergyInstaller.exe</span> in the
<span class="code">build</span> directory. Run this to install synergy.
</p>
<p>
</p><p>
Alternatively, you can simply copy the following files from the
<span class="code">debug</span> or <span class="code">build</span>
directory to a directory you choose (perhaps under the
<span class="code">Program Files</span> directory):
<ul class="code">
<li>synergy.exe
<li>synergyc.exe
<li>synergys.exe
<li>synrgyhk.dll
</ul>
</p>
</p><p>
<li>Unix or Mac OS X without XCode
<p>
</p><p>
<pre>
make install
</pre>
will install the client and server into
<span class="code">/usr/local/bin</span> unless you
specified a different directory when you ran configure.
</p>
</p><p>
<li>Mac OS X with XCode
<p>
</p><p>
Copy the following files from ./build to a convenient location:
</p><p>
<ul class="code">
<li>synergyc
<li>synergys
</ul>
</p>
</p>
</body>
</html>

View File

@ -1,27 +1,30 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
<html>
<head>
<meta HTTP-EQUIV="Content-Type" CONTENT="text/html;CHARSET=iso-8859-1">
<meta name="keywords" content="Virtual Screen, Open Source, Software" />
<meta name="description" content="Mouse and Keyboard Sharing" />
<link rel="stylesheet" type="text/css" href="synergy.css" media="screen" />
<title>Synergy Configuration Guide</title>
</head>
<body class="main">
<h3>Synergy Configuration File Format</h3>
<p>
</p><h3>Synergy Configuration File Format</h3><p>
</p><p>
The synergy server requires configuration. It will try certain
pathnames to load the configuration file if you don't specify a
path using the <span class="code">--config</span> command line
option. <span class="code">synergys --help</span> reports those
pathnames.
</p>
<p>
</p><p>
The configuration file is a plain text file. Use any text editor
to create the configuration file. The file is broken into sections
and each section has the form:
<pre>
<span class="codeblock">
section: <span class="arg">name</span>
<span class="arg">args</span>
end
</pre>
</span>
Comments are introduced by <span class="code">#</span> and continue to
the end of the line. <span class="arg">name</span> must be one of the
following:
@ -36,8 +39,7 @@ configuration file is case-sensitive so <span class="code">Section</span>,
<span class="code">SECTION</span>, and <span class="code">section</span>
are all different and only the last is valid. Screen names are the
exception; screen names are case-insensitive.
</p>
<p>
</p><p>
The file is parsed top to bottom and names cannot be used before
they've been defined in the <span class="code">screens</span> or
<span class="code">aliases</span> sections. So the
@ -45,9 +47,9 @@ they've been defined in the <span class="code">screens</span> or
must appear after the <span class="code">screens</span> and links
cannot refer to aliases unless the <span class="code">aliases</span>
appear before the <span class="code">links</span>.
</p>
<h4>screens</h4>
<p>
</p><p>
</p><h4>screens</h4><p>
</p><p>
<span class="arg">args</span> is a list of screen names, one name per
line, each followed by a colon. Names are arbitrary strings but they
must be unique. The hostname of each computer is recommended. (This
@ -60,10 +62,9 @@ screen can specify a number of options. Options have the form
<span class="code"><span class="arg">name</span> =
<span class="arg">value</span></span> and are listed one per line
after the screen name.
</p>
<p>
</p><p>
Example:
<pre>
<span class="codeblock">
section: screens
moe:
larry:
@ -72,18 +73,17 @@ Example:
curly:
meta = alt
end
</pre>
</span>
This declares three screens named <span class="code">moe</span>,
<span class="code">larry</span>, and <span class="code">curly</span>.
Screen <span class="code">larry</span> has half-duplex Caps Lock and
Num Lock keys (see below) and screen <span class="code">curly</span>
converts the meta modifier key to the alt modifier key.
</p>
<p>
</p><p>
A screen can have the following options:
<ul>
<li><span class="code">halfDuplexCapsLock = {true|false}</span>
<p>
</p><p>
This computer has a Caps Lock key that doesn't report a
press and a release event when the user presses it but
instead reports a press event when it's turned on and a
@ -93,22 +93,32 @@ A screen can have the following options:
on the server screen. If it acts strangely on one
screen then that screen may need the option set to
<span class="code">true</span>.
</p>
</p><p>
<li><span class="code">halfDuplexNumLock = {true|false}</span>
<p>
</p><p>
This is identical to <span class="code">halfDuplexCapsLock</span>
except it applies to the Num Lock key.
</p>
</p><p>
<li><span class="code">halfDuplexScrollLock = {true|false}</span>
<p>
</p><p>
This is identical to <span class="code">halfDuplexCapsLock</span>
except it applies to the Scroll Lock key. Note that synergy uses
Scroll Lock to keep the cursor on the current screen. That is,
when Scroll Lock is toggled on, the cursor is locked to the screen
that it's currently on. Use it to prevent accidental switching.
</p>
except it applies to the Scroll Lock key. Note that, by default,
synergy uses Scroll Lock to keep the cursor on the current screen. That
is, when Scroll Lock is toggled on, the cursor is locked to the screen
that it's currently on. You can use that to prevent accidental switching.
You can also configure other hot keys to do that; see <a href="#lockCursor">
lockCursorToScreen</a>.
</p><p>
<li><span class="code">switchCorners = &lt;corners&gt;</span>
</p><p>
See <a href="#corners">switchCorners</a> below.
</p><p>
<li><span class="code">switchCornerSize = N</span>
</p><p>
See <a href="#cornerSize">switchCornerSize</a> below.
</p><p>
<li><span class="code">xtestIsXineramaUnaware = {true|false}</span>
<p>
</p><p>
This option works around a bug in the XTest extension
when used in combination with Xinerama. It affects
X11 clients only. Not all versions of the XTest
@ -118,19 +128,18 @@ A screen can have the following options:
currently <span class="code">true</span> by default. If
you know your XTest extension is Xinerama aware then set
this option to <span class="code">false</span>.
</p>
</p><p>
<li><span class="code">shift = {shift|ctrl|alt|meta|super|none}<br>
ctrl = {shift|ctrl|alt|meta|super|none}<br>
alt = {shift|ctrl|alt|meta|super|none}<br>
meta = {shift|ctrl|alt|meta|super|none}<br>
super = {shift|ctrl|alt|meta|super|none}</span>
<p>
</p><p>
Map a modifier key pressed on the server's keyboard to
a different modifier on this client. This option only
has an effect on a client screen; it's accepted and
ignored on the server screen.
</p>
<p>
</p><p>
You can map, say, the shift key to shift (the default),
ctrl, alt, meta, super or nothing. Normally, you
wouldn't remap shift or ctrl. You might, however, have
@ -139,12 +148,11 @@ A screen can have the following options:
doesn't use meta but uses alt extensively, you'll want
the windows client to map meta to alt (using
<span class="code">meta = alt</span>).
</p>
</p><p>
</ul>
</p>
<h4>aliases</h4>
<p>
</p><p>
</p><a name="aliases"></a><h4>aliases</h4><p>
</p><p>
<span class="arg">args</span> is a list of screen names just like
in the <span class="code">screens</span> section except each screen
is followed by a list of aliases, one per line, <b>not</b> followed
@ -152,102 +160,163 @@ A screen can have the following options:
screen name lookup each alias is equivalent to the screen name it
aliases. So a client can connect using its canonical screen name
or any of its aliases.
</p>
<p>
</p><p>
Example:
<pre>
<span class="codeblock">
section: aliases
larry:
larry.stooges.com
curly:
shemp
end
</pre>
</span>
Screen <span class="code">larry</span> is also known as
<span class="code">larry.stooges.com</span> and can connect as
either name. Screen <span class="code">curly</span> is also
known as <span class="code">shemp</span> (hey, it's just an example).
</p>
<h4>links</h4>
<p>
</p><p>
</p><h4>links</h4><p>
</p><p>
<span class="arg">args</span> is a list of screen names just like
in the <span class="code">screens</span> section except each screen
is followed by a list of links, one per line. Each link has the
form <span class="code">{left|right|up|down}</span> =
<span class="code">name</span>. A link indicates which screen is
adjacent in the given direction.
</p>
<p>
form <span class="code">{left|right|up|down}[&lt;range&gt;]</span> =
<span class="code">name[&lt;range&gt;]</span>. A link indicates which
screen is adjacent in the given direction.
</p><p>
Each side of a link can specify a range which defines a portion
of an edge. A range on the direction is the portion of edge you can
leave from while a range on the screen is the portion of edge you'll
enter into. Ranges are optional and default to the entire edge. All
ranges on a particular direction of a particular screen must not
overlap.
</p><p>
A &lt;range&gt; is written as <span class="code">(&lt;start&gt;,&lt;end&gt;)</span>.
Both <span class="code">start</span> and <span class="code">end</span>
are percentages in the range 0 to 100, inclusive. The start must be
less than the end. 0 is the left or top of an edge and 100 is the
right or bottom.
</p><p>
Example:
<pre>
<span class="codeblock">
section: links
moe:
right = larry
up = curly
up(50,100) = curly(0,50)
larry:
left = moe
up = curly
up(0,50) = curly(50,100)
curly:
down = larry
down(0,50) = moe
down(50,100) = larry(0,50)
end
</pre>
</span>
This indicates that screen <span class="code">larry</span> is to
the right of screen <span class="code">moe</span> (so moving the
cursor off the right edge of <span class="code">moe</span> would
make it appear at the left edge of <span class="code">larry</span>),
<span class="code">curly</span> is above <span class="code">moe</span>,
the left half of
<span class="code">curly</span> is above the right half of
<span class="code">moe</span>,
<span class="code">moe</span> is to the left of
<span class="code">larry</span>, <span class="code">curly</span> is
above <span class="code">larry</span>, and
<span class="code">larry</span> is below
<span class="code">curly</span>. Note that links do not have to be
symmetrical; moving up from <span class="code">moe</span> then down
from <span class="code">curly</span> lands the cursor on
<span class="code">larry</span>.
</p>
<h4>options</h4>
<p>
<span class="code">larry</span> (edges are not necessarily symmetric
so you have to provide both directions), the right half of
<span class="code">curly</span> is above the left half of
<span class="code">larry</span>, all of <span class="code">moe</span>
is below the left half of <span class="code">curly</span>, and the
left half of <span class="code">larry</span> is below the right half of
<span class="code">curly</span>.
</p><p>
<a name="asymmetric"></a>Note that links do not have to be
symmetrical; for instance, here the edge between
<span class="code">moe</span> and <span class="code">curly</span>
maps to different ranges depending on if you're going up or down.
In fact links don't have to be bidirectional. You can configure
the right of <span class="code">moe</span> to go to
<span class="code">larry</span> without a link from the left of
<span class="code">larry</span> to <span class="code">moe</span>.
It's possible to configure a screen with no outgoing links; the
cursor will get stuck on that screen unless you have a hot key
configured to switch off of that screen.
</p><p>
</p><h4>options</h4><p>
</p><p>
<span class="arg">args</span> is a list of lines of the form
<span class="code">name = value</span>. These set the global
options.
</p>
<p>
</p><p>
Example:
<pre>
<span class="codeblock">
section: options
heartbeat = 5000
switchDelay = 500
end
</pre>
</p>
<p>
</span>
</p><p>
You can use the following options:
<ul>
<li><span class="code">heartbeat = N</span>
<p>
</p><p>
The server will expect each client to send a message no
less than every <span class="code">N</span> milliseconds.
If no message arrives from a client within
<span class="code">3N</span> seconds the server forces that
client to disconnect.
</p>
<p>
</p><p>
If synergy fails to detect clients disconnecting while
the server is sleeping or vice versa, try using this
option.
</p>
</p><p>
<li><span class="code"><a name="corners"></a>switchCorners = &lt;corners&gt;</span>
</p><p>
Synergy won't switch screens when the mouse reaches the edge of
the screen if it's in a listed corner. The size of all corners
is given by the <span class="code">switchCornerSize</span>
option.
</p><p>
Corners are specified by a list using the following names:
<ul>
<li><span class="code">none</span> -- no corners
<li><span class="code">top-left</span> -- the top left corner
<li><span class="code">top-right</span> -- the top right corner
<li><span class="code">bottom-left</span> -- the bottom left corner
<li><span class="code">bottom-right</span> -- the bottom right corner
<li><span class="code">left</span> -- top and bottom left corners
<li><span class="code">right</span> -- top and bottom right corners
<li><span class="code">top</span> -- left and right top corners
<li><span class="code">bottom</span> -- left and right bottom corners
<li><span class="code">all</span> -- all corners
</ul>
</p><p>
The first name in the list is one of the above names and defines
the initial set of corners. Subsequent names are prefixed with
+ or - to add the corner to or remove the corner from the set,
respectively. For example:
</p><p>
<span class="code">
all -left +top-left
</span>
</p><p>
starts will all corners, removes the left corners (top and bottom)
then adds the top-left back in, resulting in the top-left,
bottom-left and bottom-right corners.
</p><p>
<li><span class="code"><a name="cornerSize"></a>switchCornerSize = N</span>
</p><p>
Sets the size of all corners in pixels. The cursor must be within
<span class="code">N</span> pixels of the corner to be considered
to be in the corner.
</p><p>
<li><span class="code">switchDelay = N</span>
<p>
</p><p>
Synergy won't switch screens when the mouse reaches the
edge of a screen unless it stays on the edge for
<span class="code">N</span>
milliseconds. This helps prevent unintentional
switching when working near the edge of a screen.
</p>
</p><p>
<li><span class="code">switchDoubleTap = N</span>
<p>
</p><p>
Synergy won't switch screens when the mouse reaches the
edge of a screen unless it's moved away from the edge
and then back to the edge within <span class="code">N</span>
@ -255,29 +324,337 @@ A screen can have the following options:
the option you have to quickly tap the edge twice to
switch. This helps prevent unintentional switching
when working near the edge of a screen.
</p>
</p><p>
<li><span class="code">screenSaverSync = {true|false}</span>
<p>
</p><p>
If set to <span class="code">false</span> then synergy
won't synchronize screen savers. Client screen savers
will start according to their individual configurations.
The server screen saver won't start if there is input,
even if that input is directed toward a client screen.
</p>
</p><p>
<li><span class="code">relativeMouseMoves = {true|false}</span>
<p>
</p><p>
If set to <span class="code">true</span> then secondary
screens move the mouse using relative rather than
absolute mouse moves when and only when Scroll Lock is
toggled on (i.e. the cursor is locked to the screen).
screens move the mouse using relative rather than absolute
mouse moves when and only when the cursor is locked to the
screen (by Scroll Lock or a <a href="#lockCursor">configured
hot key</a>).
This is intended to make synergy work better with certain
games. If set to <span class="code">false</span> or not
set then all mouse moves are absolute.
</p>
</p><p>
<li><span class="code">keystroke(<span class="arg">key</span>) = <span class="arg">actions</span></span>
</p><p>
Binds the key combination <span class="arg">key</span> to the
given <span class="arg">actions</span>. <span class="arg">key</span>
is an optional list of modifiers (<span class="code">shift</span>,
<span class="code">control</span>, <span class="code">alt</span>,
<span class="code">meta</span> or <span class="code">super</span>)
optionally followed by a character or a key name, all separated by
<span class="code">+</span> (plus signs). You must have either
modifiers or a character/key name or both. See below for
<a href="#keynames">valid key names</a>.
</p><p>
Actions are described <a href="#actions">below</a>.
</p><p>
Keyboard hot keys are handled while the cursor is on the primary
screen and secondary screens. Separate actions can be assigned
to press and release.
</p><p>
<li><span class="code">mousebutton(<span class="arg">button</span>) = <span class="arg">actions</span></span>
</p><p>
Binds the modifier and mouse button combination
<span class="arg">button</span> to the given
<span class="arg">actions</span>. <span class="arg">button</span>
is an optional list of modifiers (<span class="code">shift</span>,
<span class="code">control</span>, <span class="code">alt</span>,
<span class="code">meta</span> or <span class="code">super</span>)
followed by a button number. The primary button (the
left button for right handed users) is button 1, the middle button
is 2, etc.
</p><p>
Actions are described <a href="#actions">below</a>.
</p><p>
Mouse button actions are not handled while the cursor is on the
primary screen. You cannot use these to perform an action while
on the primary screen. Separate actions can be assigned to press
and release.
</p><p>
</ul>
You can use both the <span class="code">switchDelay</span> and
<span class="code">switchDoubleTap</span> options at the same
time. Synergy will switch when either requirement is satisfied.
</p><p>
<a name="actions">Actions</a> are two lists of individual actions separated
by commas. The two lists are separated by a semicolon. Either list can be
empty and if the second list is empty then the semicolon is optional. The
first list lists actions to take when the condition becomes true (e.g. the
hot key or mouse button is pressed) and the second lists actions to take
when the condition becomes false (e.g. the hot key or button is released).
The condition becoming true is called activation and becoming false is
called deactivation.
Allowed individual actions are:
<ul>
<li><span class="code">keystroke(<span class="arg">key</span>[,<span class="arg">screens</span>])</span>
<li><span class="code">keyDown(<span class="arg">key</span>[,<span class="arg">screens</span>])</span>
<li><span class="code">keyUp(<span class="arg">key</span>[,<span class="arg">screens</span>])</span>
</p><p>
Synthesizes the modifiers and key given in <span class="arg">key</span>
which has the same form as described in the
<span class="code">keystroke</span> option. If given,
<span class="arg">screens</span> lists the screen or screens to
direct the event to, regardless of the active screen. If not
given then the event is directed to the active screen only.
</p><p>
<span class="code">keyDown</span> synthesizes a key press and
<span class="code">keyUp</span> synthesizes a key release.
<span class="code">keystroke</span> synthesizes a key press on
activation and a release on deactivation and is equivalent to
a <span class="code">keyDown</span> on activation and
<span class="code">keyUp</span> on deactivation.
</p><p>
<span class="arg">screens</span> is either <span class="code">*</span>
to indicate all screens or a colon (:) separated list of screen
names. (Note that the screen name must have already been encountered
in the configuration file so you'll probably want to put actions at
the bottom of the file.)
</p><p>
<li><span class="code">mousebutton(<span class="arg">button</span>)</span>
<li><span class="code">mouseDown(<span class="arg">button</span>)</span>
<li><span class="code">mouseUp(<span class="arg">button</span>)</span>
</p><p>
Synthesizes the modifiers and mouse button given in
<span class="arg">button</span>
which has the same form as described in the
<span class="code">mousebutton</span> option.
</p><p>
<span class="code">mouseDown</span> synthesizes a mouse press and
<span class="code">mouseUp</span> synthesizes a mouse release.
<span class="code">mousebutton</span> synthesizes a mouse press on
activation and a release on deactivation and is equivalent to
a <span class="code">mouseDown</span> on activation and
<span class="code">mouseUp</span> on deactivation.
</p><p>
<li><a name="lockCursor"></a><span class="code">lockCursorToScreen(<span class="arg">mode</span>)</span>
</p><p>
Locks the cursor to or unlocks the cursor from the active screen.
<span class="arg">mode</span> can be <span class="code">off</span>
to unlock the cursor, <span class="code">on</span> to lock the
cursor, or <span class="code">toggle</span> to toggle the current
state. The default is <span class="code">toggle</span>. If the
configuration has no <span class="code">lockCursorToScreen</span>
action and Scroll Lock is not used as a hot key then Scroll Lock
toggles cursor locking.
</p><p>
<li><span class="code">switchToScreen(<span class="arg">screen</span>)</span>
</p><p>
Jump to screen with name or alias <span class="arg">screen</span>.
</p><p>
<li><span class="code">switchInDirection(<span class="arg">dir</span>)</span>
</p><p>
Switch to the screen in the direction <span class="arg">dir</span>,
which may be one of <span class="code">left</span>,
<span class="code">right</span>, <span class="code">up</span> or
<span class="code">down</span>.
</p><p>
</ul>
</p><p>
Examples:
<ul>
<li><span class="code">keystroke(alt+left) = switchInDirection(left)</span>
</p><p>
Switches to the screen to left when the left arrow key is pressed
in combination with the Alt key.
</p><p>
<li><span class="code">keystroke(shift+control+alt+super) = switchToScreen(moe)</span>
</p><p>
Switches to screen <span class="code">moe</span> when all of the
Shift, Control, Alt, and Super modifier keys are pressed together.
</p><p>
<li><span class="code">keystroke(alt+f1) = ; lockCursorToScreen(toggle)</span>
</p><p>
Toggles locking the cursor to the screen when Alt+F1 is released.
</p><p>
<li><span class="code">mousebutton(2) = mouseDown(control+1) ; mouseUp(control+1)</span>
</p><p>
While on a secondary screen clicking the middle mouse button will
become a Control click of the primary button.
</p><p>
<li><span class="code">keystroke(super+f1) = keystroke(super+L,larry), keystroke(control+alt+delete,curly)</span>
</p><p>
Pressing Super+F1 (on any screen) will synthesize Super+L on screen
<span class="code">larry</span> and Control+Alt+Delete on screen
<span class="code">curly</span>.
</p><p>
</ul></span>
</p><p>
<a name="keynames">Valid key names</a> are:
<span class="code"><ul>
<li>AppMail
<li>AppMedia
<li>AppUser1
<li>AppUser2
<li>AudioDown
<li>AudioMute
<li>AudioNext
<li>AudioPlay
<li>AudioPrev
<li>AudioStop
<li>AudioUp
<li>BackSpace
<li>Begin
<li>Break
<li>Cancel
<li>CapsLock
<li>Clear
<li>Delete
<li>Down
<li>Eject
<li>End
<li>Escape
<li>Execute
<li>F1
<li>F2
<li>F3
<li>F4
<li>F5
<li>F6
<li>F7
<li>F8
<li>F9
<li>F10
<li>F11
<li>F12
<li>F13
<li>F14
<li>F15
<li>F16
<li>F17
<li>F18
<li>F19
<li>F20
<li>F21
<li>F22
<li>F23
<li>F24
<li>F25
<li>F26
<li>F27
<li>F28
<li>F29
<li>F30
<li>F31
<li>F32
<li>F33
<li>F34
<li>F35
<li>Find
<li>Help
<li>Home
<li>Insert
<li>KP_0
<li>KP_1
<li>KP_2
<li>KP_3
<li>KP_4
<li>KP_5
<li>KP_6
<li>KP_7
<li>KP_8
<li>KP_9
<li>KP_Add
<li>KP_Begin
<li>KP_Decimal
<li>KP_Delete
<li>KP_Divide
<li>KP_Down
<li>KP_End
<li>KP_Enter
<li>KP_Equal
<li>KP_F1
<li>KP_F2
<li>KP_F3
<li>KP_F4
<li>KP_Home
<li>KP_Insert
<li>KP_Left
<li>KP_Multiply
<li>KP_PageDown
<li>KP_PageUp
<li>KP_Right
<li>KP_Separator
<li>KP_Space
<li>KP_Subtract
<li>KP_Tab
<li>KP_Up
<li>Left
<li>LeftTab
<li>Linefeed
<li>Menu
<li>NumLock
<li>PageDown
<li>PageUp
<li>Pause
<li>Print
<li>Redo
<li>Return
<li>Right
<li>ScrollLock
<li>Select
<li>Sleep
<li>Space
<li>SysReq
<li>Tab
<li>Undo
<li>Up
<li>WWWBack
<li>WWWFavorites
<li>WWWForward
<li>WWWHome
<li>WWWRefresh
<li>WWWSearch
<li>WWWStop
<li>Space
<li>Exclaim
<li>DoubleQuote
<li>Number
<li>Dollar
<li>Percent
<li>Ampersand
<li>Apostrophe
<li>ParenthesisL
<li>ParenthesisR
<li>Asterisk
<li>Plus
<li>Comma
<li>Minus
<li>Period
<li>Slash
<li>Colon
<li>Semicolon
<li>Less
<li>Equal
<li>Greater
<li>Question
<li>At
<li>BracketL
<li>Backslash
<li>BracketR
<li>Circumflex
<li>Underscore
<li>Grave
<li>BraceL
<li>Bar
<li>BraceR
<li>Tilde
</ul></span>
Additionally, a name of the form <span class="code">\uXXXX</span> where
<span class="code">XXXX</span> is a hexadecimal number is interpreted as
a unicode character code.
Key and modifier names are case-insensitive. Keys that don't exist on
the keyboard or in the default keyboard layout will not work.
</p>
</body>
</html>

44
doc/contact.html Normal file
View File

@ -0,0 +1,44 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
<html>
<head>
<meta HTTP-EQUIV="Content-Type" CONTENT="text/html;CHARSET=iso-8859-1">
<meta name="keywords" content="Virtual Screen, Open Source, Software" />
<meta name="description" content="Mouse and Keyboard Sharing" />
<link rel="stylesheet" type="text/css" href="synergy.css" media="screen" />
<title>Synergy Contact Info</title>
</head>
<body class="main">
<p>
Use the following addresses to contact the synergy project:
</p><p>
<table border="0">
<tr>
<td align="right">Bug reports:</td>
<td>&nbsp;</td>
<td><a target="_top" href="http://sourceforge.net/tracker/?func=add&group_id=59275&atid=490467">Add Synergy Bug</a></td>
</tr>
<tr>
<td align="right">Help:</td>
<td>&nbsp;</td>
<td><span class="fakelink">synergy-help@groundhog.pair.<span class="hide">.no_spam</span>com</span></td>
</tr>
<tr>
<td align="right">General:</td>
<td>&nbsp;</td>
<td><span class="fakelink">crs23@users.sourceforge.<span class="hide">.no_spam</span>net</span></td>
</tr>
</table>
</p><p>
To avoid spam bots, the above email addresses have ".no_spam"
hidden near the end. If you copy and paste the text be sure to
remove it.
</p><p>
Please check the
<a target="_top" href="http://sourceforge.net/tracker/?func=browse&group_id=59275&atid=490467">
bug list</a> before reporting a bug. You may also find answers at the
synergy <a target="_top" href="http://sourceforge.net/forum/?group_id=59275">forums</a>.
Emails for help asking questions answered on this site will go unanswered.
</p>
</body>
</html>

View File

@ -1,27 +1,27 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
<html>
<head>
<meta HTTP-EQUIV="Content-Type" CONTENT="text/html;CHARSET=iso-8859-1">
<meta name="keywords" content="Virtual Screen, Open Source, Software" />
<meta name="description" content="Mouse and Keyboard Sharing" />
<link rel="stylesheet" type="text/css" href="synergy.css" media="screen" />
<title>Synergy Developer's Guide</title>
<title>Synergy Developer Documentation</title>
</head>
<body class="main">
<h3>Developer's Guide</h3>
<p>
Synergy is reasonably well commented so reading the source code
should be enough to understand particular pieces. See the
<a href="PORTING"><span class="code">doc/PORTING</span></a>
<span class="code">doc/PORTING</span>
file in the synergy source code for more high-level information.
</p>
<h4>How it works</h4>
<p>
</p><p>
</p><h4>How it works</h4><p>
</p><p>
The theory behind synergy is simple: the server captures mouse,
keyboard, clipboard, and screen saver events and forwards them to
one or more clients. If input is directed to the server itself
then the input is delivered normally. In practice, however, many
complications arise.
</p>
<p>
</p><p>
First, different keyboard mappings can produce different characters.
Synergy attempts to generate the same character on the client as
would've been generated on the server, including appropriate modifier
@ -34,8 +34,7 @@ keyboard. For example, if the client or server can't distinguish
between the left and right shift keys then synergy can't be certain
to synthesize the shift on the same side of the keyboard as the user
pressed.
</p>
<p>
</p><p>
Second, different systems have different clipboards and clipboard
formats. The X window system has a system-wide selection and
clipboard (and yet other buffers) while Microsoft Windows has only
@ -43,15 +42,13 @@ a system-wide clipboard. Synergy has to choose which of these
buffers correspond to one another. Furthermore, different systems
use different text encodings and line breaks. Synergy mediates and
converts between them.
</p>
<p>
</p><p>
Finally, there are no standards across operating systems for some
operations that synergy requires. Among these are: intercepting
and synthesizing events; enabling, disabling, starting and stopping
the screen saver; detecting when the screen saver starts; reading
and writing the clipboard(s).
</p>
<p>
</p><p>
All this means that synergy must be customized to each operating
system (or windowing system in the case of X windows). Synergy
breaks platform differences into two groups. The first includes
@ -60,25 +57,25 @@ multithreading, network I/O, multi-byte and wide character
conversion, time and sleeping, message display and logging, and
running a process detached from a terminal. This code lives in
<span class="code">lib/arch</span>.
</p>
<p>
</p><p>
The second includes screen and window management handling, user
event handling, event synthesis, the clipboards, and the screen
saver. This code lives in <span class="code">lib/platform</span>.
</p>
<p>
</p><p>
For both groups, there are particular classes or interfaces that
must be inherited and implemented for each platform. See the
<a href="PORTING"><span class="code">doc/PORTING</span></a> file in
the synergy source code for more information.
</p>
<h4>Auto-generated Documentation</h4>
<p>
<span class="code">doc/PORTING</span> file in the synergy source
code for more information.
</p><p>
</p><h4>Auto-generated Documentation</h4><p>
</p><p>
Synergy can automatically generate documentation from the comments
in the code using <a href="http://www.doxygen.org/">doxygen</a>.
Use "<span class="code">make doxygen</span>" to build it yourself
in the code using <a target="_top" href="http://www.doxygen.org/">doxygen</a>.
Use <span class="command">make doxygen</span> to build it yourself
from the source code into the <span class="code">doc/doxygen/html</span>
directory.
</p>
</p>
</body>
</html>

View File

@ -1,14 +1,18 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
<html>
<head>
<meta HTTP-EQUIV="Content-Type" CONTENT="text/html;CHARSET=iso-8859-1">
<meta name="keywords" content="Virtual Screen, Open Source, Software" />
<meta name="description" content="Mouse and Keyboard Sharing" />
<link rel="stylesheet" type="text/css" href="synergy.css" media="screen" />
<title>Synergy FAQ</title>
<title>Synergy Frequently Asked Questions</title>
</head>
<body class="main">
<p></p>
<h3>Synergy Frequently Asked Questions</h3>
</p><p>
<h4>Questions</h4>
<ol class="faq">
<ol>
<li><a href="#faq1">Why doesn't ctrl+alt+del work on secondary screens?</a>
<li><a href="#faq2">Can the server and client be using different operating systems?</a>
<li><a href="#faq3">What's the difference between synergy and x2x, x2vnc, etc?</a>
@ -27,27 +31,42 @@
<li><a href="#faq16">I get the error 'Xlib: No protocol specified'. Why?</a>
<li><a href="#faq17">The cursor goes to secondary screen but won't come back. Why?</a>
<li><a href="#faq18">The cursor wraps from one edge of the screen to the opposite. Why?</a>
<li><a href="#faq19">How do I stop my game from minimizing when I leave the screen?</a>
</ol>
<h4>Answers</h4>
<ol class="faq">
<ol>
<li><a name="faq1"></a><span class="fakelink">Why doesn't ctrl+alt+del work on secondary screens?</span>
<p>
Synergy isn't able to capture ctrl+alt+del on PC compatible
systems because it's handled completely differently than
primary screens because it's handled completely differently than
other keystrokes. However, when the mouse is on a client
screen, pressing ctrl+alt+pause will simulate ctrl+alt+del
on the client. (A client running on Windows NT, 2000, or XP
must be running as a service for this to work.)
must be configured to autostart when the computer starts for
this to work.)
</p><p>
On a primary screen running on an OS X system, you can use
ctrl+command+del. Using the pause key isn't necessary since OS X
doesn't treat ctrl+command+del differently. And using the pause
key isn't usually possible because there isn't one on most OS X
systems. Use command instead of option/alt because
the command key, not the option/alt key, maps to alt on windows.
The reason is because the command key is in the same physical
location and performs the same general function (menu shortcuts)
as alt on a windows system. This mapping can be modified in
the configuration.
</p><p>
On mac laptops, the key labeled "delete" is actually backspace
and ctrl+command+delete won't work. However fn+delete really
is delete so fn+ctrl+command+delete will act as ctrl+alt+del
on a windows secondary screen.
</p>
<li><a name="faq2"></a><span class="fakelink">Can the server and client be using different operating systems?</span>
<p>
Yes. The synergy network protocol is platform neutral so
synergy doesn't care what operating systems are running on
the server and clients.
</p>
<li><a name="faq3"></a><span class="fakelink">What's the difference between synergy and
<span class="code">x2x</span>, <span class="code">x2vnc</span>, etc?</span>
<p>
@ -60,7 +79,6 @@
However, the right tool for the job is whatever tool works
best for you.
</p>
<li><a name="faq4"></a><span class="fakelink">What does "Cannot initialize hook library" mean?</span>
<p>
This error can occur on a synergy server running on a
@ -70,7 +88,6 @@
not then try logging off and back on or rebooting then
starting synergy again.
</p>
<li><a name="faq5"></a><span class="fakelink">What security/encryption does synergy provide?</span>
<p>
Synergy provides no built-in encryption or authentication.
@ -78,18 +95,17 @@
network, especially the Internet. It's generally fine for home
networks. Future versions may provide built-in encryption and
authentication.
</p>
<p>
</p><p>
Strong encryption and authentication is available through SSH
(secure shell). Run the SSH daemon (i.e. server) on the same
computer that you run the synergy server. It requires no
special configuration to support synergy. On each synergy
client system, run SSH with port forwarding:
</p>
</p><p>
<pre>
ssh -f -N -L 24800:<span class="arg">server-hostname</span>:24800 <span class="arg">server-hostname</span>
</pre>
<p>
</p><p>
where <span class="arg">server-hostname</span> is the name of the
SSH/synergy server.
Once ssh authenticates itself, start the synergy client
@ -97,14 +113,12 @@
<span class="code">127.0.0.1</span> as the server's
address. SSH will then encrypt all communication on behalf of
synergy. Authentication is handled by the SSH authentication.
</p>
<p>
</p><p>
A free implementation of SSH for Linux and many Unix systems is
<a href="http://www.openssh.com/">OpenSSH</a>. For
<a target="_top" href="http://www.openssh.com/">OpenSSH</a>. For
Windows there's a port of OpenSSH using
<a href="http://www.cygwin.com/">Cygwin<a>.
<a target="_top" href="http://www.cygwin.com/">Cygwin<a>.
</p>
<li><a name="faq6"></a><span class="fakelink">What should I call my screens in the configuration?</span>
<p>
You can use any unique name in the configuration file for each
@ -115,8 +129,7 @@
<span class="code">xyz.foo.com</span>. If you don't use the computer's hostname, you
have to tell synergy the name of the screen using a command line
option, or the startup dialog on Windows.
</p>
<p>
</p><p>
Some systems are configured to report the fully qualified domain
name as the hostname. For those systems it will be easier to use
the FQDN as the screen name. Also note that a Mac OS X system
@ -124,32 +137,29 @@
<span class="code">xyz.local</span>. If that's the case for you
then use <span class="code">xyz.local</span> as the screen name.
</p>
<li><a name="faq7"></a><span class="fakelink">Why do my Caps-Lock, Num-Lock, Scroll-Lock keys act funny?</span>
<p>
Some systems treat the Caps-Lock, Num-Lock, and Scroll-Lock keys
differently than all the others. Whereas most keys report going down
when physically pressed and going up when physically released, on
these systems the keys report going down when being activated and
going up when being deactivated. That is, when you press and release,
say, Caps-Lock to activate it, it only reports going down, and when
you press and release to deactivate it, it only reports going up.
This confuses synergy.
</p>
<p>
these systems the Caps-Lock and Num-Lock keys report going down
when being activated and going up when being deactivated. That
is, when you press and release, say, Caps-Lock to activate it, it
only reports going down, and when you press and release to
deactivate it, it only reports going up. This confuses synergy.
</p><p>
You can solve the problem by changing your configuration file.
In the screens section, following each screen that has the
problem, add any or all of these lines as appropriate:
</p>
problem, any or all of these lines as appropriate:
</p><p>
<pre>
halfDuplexCapsLock = true
halfDuplexNumLock = true
halfDuplexScrollLock = true
</pre>
<p>
</p><p>
Then restart synergy on the server or reload the configuration.
</p>
<li><a name="faq8"></a><span class="fakelink">Can synergy share the display in addition to the mouse and keyboard?</span>
<p>
No. Synergy is a KM solution not a KVM (keyboard, video, mouse)
@ -157,13 +167,11 @@
Hopefully, this will make synergy suitable for managing large
numbers of headless servers.
</p>
<li><a name="faq9"></a><span class="fakelink">Can synergy do drag and drop between computers?</span>
<p>
No. That's a very cool idea and it'll be explored. However, it's
also clearly difficult and may take a long time to implement.
</p>
<li><a name="faq10"></a><span class="fakelink">Does AltGr/Mode-Switch/ISO_Level3_Shift work?</span>
<p>
Yes, as of 1.0.12 synergy has full support for AltGr/Mode-switch.
@ -173,7 +181,6 @@
layout cannot be generated by synergy.) There is experimental
support for ISO_Level3_Shift in 1.1.3.
</p>
<li><a name="faq11"></a><span class="fakelink">Why isn't synergy ported to platform XYZ?</span>
<p>
Probably because the developers don't have access to platform XYZ
@ -181,7 +188,6 @@
inherently non-portable aspects so there's a not insignificant
effort involved in porting.
</p>
<li><a name="faq12"></a><span class="fakelink">My client can't connect. What's wrong?</span>
<p>
A common mistake when starting the client is to give the wrong
@ -192,36 +198,33 @@
socket</span> followed by <span class="code">the attempt to connect was forcefully
rejected</span> or <span class="code">connection refused</span> then the server isn't started,
can't bind the address, or the client is connecting to the wrong
host name/address or port.
host name/address or port. See the
<a href="trouble.html">troublshooting</a> page for more help.
</p>
<li><a name="faq13"></a><span class="fakelink">Linking fails on Solaris. What's wrong?</span>
<p>
Did you add
</p>
</p><p>
<pre>
<nobr>--x-includes=/usr/openwin/include --x-libraries=/usr/openwin/lib</nobr>
</pre>
<p>
</p><p>
to the <span class="code">configure</span> command line? Solaris puts
the X11 includes and libraries in an unusual place and the above lets
synergy find them.
</p>
<li><a name="faq14"></a><span class="fakelink">The screen saver never starts. Why not?</span>
<p>
If the synergy server is on X Windows then the screen saver will
not start while the mouse is on a client screen. This is a
consequence of how X Windows, synergy and xscreensaver work.
</p>
<li><a name="faq15"></a><span class="fakelink">I can't switch screens anymore for no apparent reason. Why?</span>
<p>
This should not happen with 1.1.3 and up. Earlier versions of
synergy would not allow switching screens when a key was down and
sometimes it would believe a key was down when it was not.
</p>
<li><a name="faq16"></a><span class="fakelink">I get the error 'Xlib: No protocol specified'. Why?</span>
<p>
You're running synergy without authorization to connect to the
@ -229,7 +232,6 @@
logged in as non-root. Just run synergy as the same user that's
logged in.
</p>
<li><a name="faq17"></a><span class="fakelink">The cursor goes to secondary screen but won't come back. Why?</span>
<p>
Your configuration is incorrect. You must indicate the neighbors
@ -237,7 +239,6 @@
the left of 'Orange' does not mean that 'Orange' is to the right
of 'Apple'. You must provide both in the configuration.
</p>
<li><a name="faq18"></a><span class="fakelink">The cursor wraps from one edge of the screen to the opposite. Why?</span>
<p>
Because you told it to. If you list 'Orange' to be to the left of
@ -245,6 +246,21 @@
make it jump to the right edge. Remove the offending line from the
configuration if you don't want that behavior.
</p>
<li><a name="faq19"></a><span class="fakelink">How do I stop my game from minimizing when I leave the screen?</span>
<p>
Many full screen applications, particularly games, automatically
minimize when they're no longer the active (foreground) application
on Microsoft Windows. The synergy server normally becomes the foreground
when you switch to another screen in order to more reliably capture all
user input causing those full screen applications to minimize. To
prevent synergy from stealing the foreground just click "Options..."
and check "Don't take foreground window on Windows servers." If you
turn this on then be aware that synergy may not function correctly when
certain programs, particularly the command prompt, are the foreground
when you switch to other screens. Simply make a different program the
foreground before switching to work around that.
</p>
</ol>
</body>
</html>

View File

@ -1,12 +1,16 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
<html>
<head>
<meta HTTP-EQUIV="Content-Type" CONTENT="text/html;CHARSET=iso-8859-1">
<meta name="keywords" content="Virtual Screen, Open Source, Software" />
<meta name="description" content="Mouse and Keyboard Sharing" />
<link rel="stylesheet" type="text/css" href="synergy.css" media="screen" />
<title>Synergy History</title>
</head>
<body class="main">
<h3>Synergy History</h3>
<p>
</p><h3>Synergy History</h3><p>
</p><p>
The first incarnation of synergy was CosmoSynergy, created by
Richard Lee and Adam Feder then at Cosmo Software, Inc., a
subsidiary of SGI (nee Silicon Graphics, Inc.), at the end of
@ -16,11 +20,11 @@ both an Irix and a Windows box on their desks and switchboxes
were expensive and annoying. CosmoSynergy was a great success
but Cosmo Software declined to productize it and the company
was later closed.
</p>
<p>
</p><p>
Synergy is a from-scratch reimplementation of CosmoSynergy.
It provides most of the features of the original and adds a
few improvements.
</p>
</body>
</html>

61
doc/home.html Normal file
View File

@ -0,0 +1,61 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
<html>
<head>
<meta HTTP-EQUIV="Content-Type" CONTENT="text/html;CHARSET=iso-8859-1">
<meta name="keywords" content="Virtual Screen, Open Source, Software" />
<meta name="description" content="Mouse and Keyboard Sharing" />
<link rel="stylesheet" type="text/css" href="synergy.css" media="screen" />
<title>Synergy</title>
</head>
<body class="main">
<p>
</p><h4>Introduction</h4><p>
synergy: [noun] a mutually advantageous conjunction of distinct elements
</p><p>
Synergy lets you easily share a single mouse and keyboard between
multiple computers with different operating systems, each with its
own display, without special hardware. It's intended for users
with multiple computers on their desk since each system uses its
own monitor(s).
</p><p>
Redirecting the mouse and keyboard is as simple as moving the mouse
off the edge of your screen. Synergy also merges the clipboards of
all the systems into one, allowing cut-and-paste between systems.
Furthermore, it synchronizes screen savers so they all start and stop
together and, if screen locking is enabled, only one screen requires
a password to unlock them all. <a href="about.html">Learn more</a>
about how it works.
</p><p>
Synergy is open source and released under the
<a href="license.html#GPL">GNU Public License (GPL)</a>.
</p><p>
</p><h4>System Requirements</h4><p>
</p><p>
<ul>
<li>Microsoft Windows 95, Windows 98, Windows Me (the Windows 95 family)
<li>Microsoft Windows NT, Windows 2000, Windows XP (the Windows NT family)
<li>Mac OS X 10.2 or higher
<li>Unix
<ul>
<li>X Windows version 11 revision 4 or up
<li>XTEST extension<br>
(use "<span class="code">xdpyinfo | grep XTEST</span>" to check for XTEST)
</ul>
</ul>
All systems must support TCP/IP networking.
</p><p>
"Unix" includes Linux, Solaris, Irix and other variants. Synergy has
only been extensively tested on Linux and may not work completely or
at all on other versions of Unix. Patches are welcome (including
patches that package binaries) at the
<a target="_top" href="http://sourceforge.net/tracker/?group_id=59275&atid=490469">patches page</a>.
</p><p>
The Mac OS X port is incomplete. It does not synchronize the screen saver,
only text clipboard data works (i.e. HTML and bitmap data do not work),
the cursor won't hide when not on the screen, and there may be problems
with mouse wheel acceleration. Other problems should be
<a target="_top" href="http://sourceforge.net/tracker/?func=add&group_id=59275&atid=490467">filed as bugs</a>.
</p>
</body>
</html>

View File

@ -1,96 +1,33 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
<html>
<head>
<meta HTTP-EQUIV="Content-Type" CONTENT="text/html;CHARSET=iso-8859-1">
<meta name="keywords" content="Virtual Screen, Open Source, Software" />
<meta name="description" content="Mouse and Keyboard Sharing" />
<link rel="stylesheet" type="text/css" href="synergy.css" media="screen" />
<title>Synergy Introduction</title>
<title>Synergy</title>
</head>
<body class="main">
<h3>Synergy</h3>
<h4>Introduction</h4>
<p>
synergy: [noun] a mutually advantageous conjunction of distinct elements
</p>
<p>
Synergy lets you easily share a single mouse and keyboard between
multiple computers with different operating systems, each with its
own display, without special hardware. It's intended for users
with multiple computers on their desk since each system uses its
own monitor(s).
</p>
<p>
Redirecting the mouse and keyboard is as simple as moving the mouse
off the edge of your screen. Synergy also merges the clipboards of
all the systems into one, allowing cut-and-paste between systems.
Furthermore, it synchronizes screen savers so they all start and stop
together and, if screen locking is enabled, only one screen requires
a password to unlock them all.
</p>
<p>
Synergy is open source and released under the
<a href="license.html#GPL">GNU Public License (GPL)</a>.
</p>
<h4>Links</h4>
<p>
<b>Local</b><br>
Getting started:<br>
<a href="running.html">how to run synergy</a><br>
<a href="compiling.html">how to build synergy</a><br>
<br>
Using synergy:<br>
<a href="faq.html">FAQ</a><br>
<a href="tips.html">tips on using synergy</a><br>
<a href="autostart.html">autostart guide</a><br>
<a href="configuration.html">configuration file format guide</a><br>
<br>
Future directions:<br>
<a href="todo.html">roadmap to future enhancements</a><br>
<br>
For developers:<br>
<a href="developer.html">developer's guide</a><br>
<br>
Security:<br>
<a href="security.html">important note about security with synergy</a><br>
<br>
Miscellaneous documents:<br>
<a href="authors.html">the authors of synergy</a><br>
<a href="history.html">the history of synergy</a><br>
<a href="license.html">the synergy license terms</a><br>
<a href="news.html">news about synergy</a><br>
<br>
<b>Internet</b><br>
<a href="http://synergy2.sourceforge.net/">synergy home page</a><br>
<a href="http://sourceforge.net/projects/synergy2/">synergy project page</a><br>
<a href="http://sourceforge.net/tracker/?func=browse&group_id=59275&atid=490467">synergy bug list</a><br>
<a href="http://sourceforge.net/forum/?group_id=59275">synergy community forums</a><br>
</p>
<h4>System Requirements</h4>
<p>
<ul>
<li>Microsoft Windows 95, Windows 98, Windows Me (the Windows 95 family)
<li>Microsoft Windows NT, Windows 2000, Windows XP (the Windows NT family)
<li>Mac OS X 10.2 or higher
<li>Unix
<ul>
<li>X Windows version 11 revision 4 or up
<li>XTEST extension<br>
(use "<span class="code">xdpyinfo | grep XTEST</span>" to check for XTEST)
</ul>
</ul>
All systems must support TCP/IP networking.
</p>
<p>
"Unix" includes Linux, Solaris, Irix and other variants. Synergy has
only been extensively tested on Linux and may not work completely or
at all on other versions of Unix. Patches are welcome (including
patches that package binaries) at the
<a href="http://sourceforge.net/tracker/?group_id=59275&atid=490469">patches page</a>.
</p>
<p>
The Mac OS X port is incomplete. It does not synchronize the screen saver,
only text clipboard data works (i.e. HTML and bitmap data do not work),
non-US English keyboards are untested and probably don't work, and there
may be problems with mouse pointer and mouse wheel acceleration. Other
problems should be <a href="http://sourceforge.net/tracker/?func=add&group_id=59275&atid=490467">filed as bugs</a>.
</p>
</body>
<script language="JavaScript">
<!--
pageName = (location.search ? location.search.substring(1) + location.hash : "home.html");
document.write('<frameset rows="77,2,*" frameborder="no" framespacing="0" border="0">');
document.write('<frame name="banner" noresize="yes" marginwidth="0" marginheight="0" scrolling="no" src="banner.html">');
document.write('<frame name="border" noresize="yes" marginwidth="0" marginheight="0" scrolling="no" src="border.html">');
document.write('<frameset cols="120,*">');
document.write('<frame name="toc" noresize="yes" marginwidth="0" marginheight="0" scrolling="no" src="toc.html">');
document.write('<frame name="page" noresize="yes" marginwidth="0" marginheight="0" scrolling="yes" src="' + pageName + '">');
document.write('</frameset>');
document.write('</frameset>');
//-->
</script>
<noscript>
<frameset rows="77,2,*" frameborder="no" framespacing="0" border="0">
<frame name="banner" noresize="yes" marginwidth="0" marginheight="0" scrolling="no" src="banner.html">
<frame name="border" noresize="yes" marginwidth="0" marginheight="0" scrolling="no" src="border.html">
<frameset cols="120,*">
<frame name="toc" noresize="yes" marginwidth="0" marginheight="0" scrolling="no" src="toc.html">
<frame name="page" noresize="yes" marginwidth="0" marginheight="0" scrolling="yes" src="home.html">
</frameset>
</frameset>
</noscript>
</html>

View File

@ -1,25 +1,29 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
<html>
<head>
<meta HTTP-EQUIV="Content-Type" CONTENT="text/html;CHARSET=iso-8859-1">
<meta name="keywords" content="Virtual Screen, Open Source, Software" />
<meta name="description" content="Mouse and Keyboard Sharing" />
<link rel="stylesheet" type="text/css" href="synergy.css" media="screen" />
<title>Synergy License and Copyright</title>
</head>
<body class="main">
<h3>Synergy License and Copyright</h3>
<p>
</p><h3>Synergy License and Copyright</h3><p>
</p><p>
Synergy is copyright (C) 2002 Chris Schoeneman.<br>
Synergy is distributed under the GNU GENERAL PUBLIC LICENSE.
</p>
<h4><a name="GPL"></a>GNU GENERAL PUBLIC LICENSE</h4>
</p><p>
</p><h4><a name="GPL"></a>GNU GENERAL PUBLIC LICENSE</h4><p>
<b>Version 2, June 1991</b>
<p>
</p><p>
Copyright (C) 1989, 1991 Free Software Foundation, Inc.<br>
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA<br>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
</p>
<h4>Preamble</h4>
<p>
</p><p>
</p><h4>Preamble</h4><p>
</p><p>
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
@ -29,55 +33,48 @@ Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
</p>
<p>
</p><p>
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
</p>
<p>
</p><p>
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
</p>
<p>
</p><p>
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
</p>
<p>
</p><p>
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
</p>
<p>
</p><p>
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
</p>
<p>
</p><p>
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
</p>
<p>
</p><p>
The precise terms and conditions for copying, distribution and
modification follow.
</p>
<h4>GNU GENERAL PUBLIC LICENSE<br>
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION</h4>
<p>
</p><p>
</p><h4>GNU GENERAL PUBLIC LICENSE<br>
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION</h4><p>
</p><p>
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
@ -87,16 +84,14 @@ that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
</p>
<p>
</p><p>
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
</p>
<p>
</p><p>
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
@ -104,31 +99,26 @@ copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
</p>
<p>
</p><p>
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
</p>
<p>
</p><p>
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
</p>
<p>
</p><p>
<table><tr><td>&nbsp;&nbsp;&nbsp;&nbsp;</td>
<td>
<p>
</p><p>
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
</p>
<p>
</p><p>
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
</p>
<p>
</p><p>
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
@ -139,10 +129,9 @@ above, provided that you also meet all of these conditions:
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
</p>
</p><p>
</td></tr></table>
</p>
<p>
</p><p>
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
@ -152,50 +141,43 @@ distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
</p>
<p>
</p><p>
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
</p>
<p>
</p><p>
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
</p>
<p>
</p><p>
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
</p>
<p>
</p><p>
<table><tr><td>&nbsp;&nbsp;&nbsp;&nbsp;</td>
<td>
<p>
</p><p>
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
</p>
<p>
</p><p>
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
</p>
<p>
</p><p>
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
</p>
</p><p>
</td></tr></table>
</p>
<p>
</p><p>
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
@ -206,15 +188,13 @@ anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
</p>
<p>
</p><p>
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
</p>
<p>
</p><p>
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
@ -222,8 +202,7 @@ void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
</p>
<p>
</p><p>
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
@ -232,8 +211,7 @@ modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
</p>
<p>
</p><p>
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
@ -241,8 +219,7 @@ these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
</p>
<p>
</p><p>
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
@ -255,14 +232,12 @@ license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
</p>
<p>
</p><p>
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
</p>
<p>
</p><p>
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
@ -273,12 +248,10 @@ through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
</p>
<p>
</p><p>
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
</p>
<p>
</p><p>
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
@ -286,14 +259,12 @@ may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
</p>
<p>
</p><p>
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
</p>
<p>
</p><p>
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
@ -301,8 +272,7 @@ either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
</p>
<p>
</p><p>
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
@ -310,11 +280,9 @@ Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
</p>
<p>
</p><p>
<b>NO WARRANTY</b>
</p>
<p>
</p><p>
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE
IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE
@ -325,8 +293,7 @@ OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE
ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
</p>
<p>
</p><p>
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED
TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY
WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED
@ -338,9 +305,9 @@ LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE
PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH
HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
</p>
<p>
</p><p>
<b>END OF TERMS AND CONDITIONS</b>
</p>
</body>
</html>

View File

@ -1,37 +1,179 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
<html>
<head>
<meta HTTP-EQUIV="Content-Type" CONTENT="text/html;CHARSET=iso-8859-1">
<meta name="keywords" content="Virtual Screen, Open Source, Software" />
<meta name="description" content="Mouse and Keyboard Sharing" />
<link rel="stylesheet" type="text/css" href="synergy.css" media="screen" />
<title>Synergy News</title>
</head>
<body class="main">
<h3>Synergy News</h3>
<span class="date">Jan-26-2005</span> - Synergy 1.2.2 released
<p>
<span class="date">Apr-02-2006</span> - Synergy 1.3.1 released
</p><p>
Made following changes:
<ul>
<li>Hot key screen switching now restores last cursor position
<li>Fixed loss of hot keys when reloading configuration
<li>Fixed autorepeating on win32 (no longer sending repeating key releases)
<li>Fixed autorepeating on X11 (non-repeating keys were repeating)
<li>Fixed AltGr issues on X11
<li>Fixed modifier mapping bug on OS X client (caused wrong characters)
<li>Fixed one way for modifiers to get stuck active on all platforms
<li>Fixed bugs in win32 GUI
<li>Removed alloca() from unix code (should fix FreeBSD build)
<li>Added more debugging output for network problems
<li>Fixed failure to detect some errors on X11
</ul>
</p><p>
<span class="date">Mar-22-2006</span> - Synergy 1.3.0 released
</p><p>
Made following additions:
<ul>
<li>Console window on win32 can now be closed (reopened from tray menu)
<li>Can now change logging level on the fly from win32 tray menu
<li>Added client keep alive (lost connections are now detected reliably)
<li>Added support for linking portions of screen edges
<li>Added version number to UI in win32
<li>Added GUI for hot key configuration on win32
<li>Hot keys can now perform actions on press and/or release
<li>Added key down, key up, mouse down, and mouse up hot key actions
<li>Key actions can be directed to particular screens
<li>Hot keys can each perform multiple actions
</ul>
</p><p>
Made following fixes:
<ul>
<li>Fixed AltGr key mappings (again)
<li>Fixed assertion when pasting on X11
<li>Fixed modifier keys in VMware on X11
<li>OS X server now treats sends option/alt as AltGr or super depending on key
<li>Improved handling of AltGr on win32
<li>Fixed not removing client when connection is lost
<li>Clients now detect loss of connection to server and reconnect
<li>Fixed mouse jumping on OS X multimonitor systems
<li>Closing console on win32 no longer quits synergy
<li>Fixed Num Lock breaking certain keys
<li>Fixed Scroll Lock not locking cursor to screen
<li>Fixed mapping of delete key on X11
<li>Fixed loss of clipboard after a particular copy/paste sequence
<li>Fixed compatibility with windows 95/98/Me (ToUnicodeEx)
<li>Fixed bad argument to function on OS X
<li>Fixed error parsing comments in configuration
<li>Fixed autorepeat on win32 servers
<li>Fixed X11 keyboard focus bug when reentering screen
<li>Fixed (suppressed) hot key autorepeating
<li>Fixed mousebutton action when Caps/Num/Scroll Lock were on
<li>Added documentation on firewalls
<li>Fixed documentation formatting on IE6
</ul>
</p><p>
Hot keys support has one known major bug: key actions cannot be directed
to the server (primary) screen. The configuration file syntax has changed
from earlier versions; users will have to modify the configurations by
hand.
</p><p>
<span class="date">Dec-18-2005</span> - Synergy 1.2.7 released
</p><p>
Made following changes:
<ul>
<li>Added preliminary support for configurable hot keys (Lorenz Schori)
<li>Major rewrite of keyboard handling code
<li>Fixed non-US keyboard handling (AltGr and ISO_Level3_Shift)
<li>Now supporting all installed keyboard layouts simultaneously
<li>Fixed bug in handling remapped caps-lock on X11
<li>Fixed control and alt keys getting stuck on on X11
<li>Fixed desktop focus problems requiring extra clicks on win32
<li>Fixed alt key event getting passed to server when on client on win32
<li>Synergy would prevent alt+numpad character entry; this is fixed
<li>Fixed suppression of xscreensaver 2.21 on X11
<li>Fixed middle mouse button dragging on OSX server (Brian Kendall)
<li>Fixed caps/num/scroll lock toggles getting out of sync
<li>Enhanced support for converting clipboard text to the Latin-1 encoding
<li>Added autostart documentation for KDE users
<li>Added more details about using Terminal for OSX users
<li>Fixed crash when using --help on certain platforms
</ul>
</p><p>
The hot key support is known to have bugs. The configuration file
syntax for hot keys is likely to change and the documentation for it
is minimal. The graphical UI on windows does not provide any support
for editing hot keys.
</p><p>
<span class="date">Nov-12-2005</span> - Synergy 1.2.6 released
</p><p>
Made following changes:
<ul>
<li>Fixed permission problem saving autostart configuration in win32 launcher
<li>Disabled buggy fix for loss of clipboard change detection
<li>Restored pthread signal autoconf code
</ul>
</p><p>
<span class="date">Oct-17-2005</span> - Synergy 1.2.5 released
</p><p>
Made following changes:
<ul>
<li>Win32 launcher now saves configuration automatically
<li>Fixed failure to save autostart configuration on win32
<li>Fixed output bottom-right configuration flag
<li>Now properly releasing keys when leaving a client screen
<li>Fixed stuck-Alt on win32
<li>Fixed 64-bit problem with clipboard on X11
<li>Fixed BadAtom bug on X11
<li>Fixed loss of detection of clipboard changes on win32
<li>Added support for the MightyMouse
<li>Added support for buttons 4 and 5 on OSX
<li>Now shutting down win32 services when uninstalling
</ul>
</p><p>
<span class="date">Aug-07-2005</span> - Synergy 1.2.4 released
</p><p>
Made following changes:
<ul>
<li>Fixed gcc 4.0 warnings
<li>Fixed autoconf/automake problems
<li>Fixed scroll-lock on X windows
<li>Added option to suppress foreground window grabbing on win32
<li>Fixed --daemon option on win32 client
<li>Fixed --no-restart on client
<li>Updated OS X autostart documentation
</ul>
</p><p>
<span class="date">Jul-27-2005</span> - Synergy 1.2.3 released
</p><p>
Made following changes:
<ul>
<li>Added OS X screensaver synchronization support (Lorenz Schori)
<li>Added OS X sleep support (Lorenz Schori)
<li>Added OS X fast user switching support (Lorenz Schori)
<li>Fixed international keyboard support on OS X (Lorenz Schori)
<li>Now capturing global hotkeys (e.g. cmd+tab, etc) on OS X (Lorenz Schori)
<li>Added support for SO_REUSEADDR (Don Eisele)
<li>Added "dead" corners feature
<li>Fixed "resource temporarily unavailable" warning when quiting on OS X
<li>Win32 now defaults to WARNING log level to avoid console window
<li>Now disabling foreground window on win32 when leaving server (Brent Priddy)
</ul>
</p><p>
<span class="date">Jan-26-2005</span> - Synergy 1.2.2 released
</p><p>
Made following changes:
</p>
<ul>
<li>Fixed major OS X modifier key handling bug
<li>Fixed handling of ISO_Level3_Shift on X11
</ul>
</p><p>
<span class="date">Jan-04-2005</span> - Synergy 1.2.1 released
<p>
</p><p>
Made following changes:
</p>
<ul>
<li>Fixed major OS X keyboard handling bug
<li>Fixed some minor documentation bugs
</ul>
</p><p>
<span class="date">Dec-30-2004</span> - Synergy 1.2.0 released
<p>
</p><p>
Made following changes:
</p>
<ul>
<li>Improved support for moving laptops between networks (Brent Priddy)
<li>Added ISO_Level3_Shift support on X windows
@ -42,23 +184,19 @@ Made following changes:
<li>Fixed memory leak on OS X
<li>Added OS X autostart documentation (Tor Slettnes)
</ul>
</p><p>
<span class="date">Nov-12-2004</span> - Synergy 1.1.10 released
<p>
</p><p>
Made following changes:
</p>
<ul>
<li>Fixed race in condition variable wrapper; caused synergy to hang randomly
<li>Fixed modifier key and caps-lock handling on OS X
<li>Fixed modifier key and caps-lock handling on OSX
<li>System info log message now filtered like all other messages
</ul>
</p><p>
<span class="date">Nov-07-2004</span> - Synergy 1.1.9 released
<p>
</p><p>
Made following changes:
</p>
<ul>
<li>Fixed compiler error on gcc 3.4 and later
<li>Worked around minor gcc -O3 compiler bug
@ -89,12 +227,10 @@ Made following changes:
<li>Added -display option for X11
<li>Added support for X11 compose key (Multi_key)
</ul>
</p><p>
<span class="date">Aug-05-2004</span> - Synergy 1.1.8 released
<p>
</p><p>
Made following changes:
</p>
<ul>
<li>Removed key event capture on X11 (was breaking terminal keyboard input)
<li>Worked around win32 command prompt stealing shift key events
@ -110,12 +246,10 @@ Made following changes:
<li>Fixed mouse wheel drift on OS X client
<li>Reorganized documentation and converted to HTML
</ul>
</p><p>
<span class="date">Jun-13-2004</span> - Synergy 1.1.7 released
<p>
</p><p>
Made following changes:
</p>
<ul>
<li>Added OS X precompiled header file forgotten in last build
<li>Fixed bug in fix for 'unexpected async reply' on X11
@ -125,12 +259,10 @@ Made following changes:
<li>Fixed error in conversion from multibyte to wide characters
<li>Maybe fixed win32 screen saver detection
</ul>
</p><p>
<span class="date">May-26-2004</span> - Synergy 1.1.6 released
<p>
</p><p>
Made following changes:
</p>
<ul>
<li>Added preliminary Mac OS X support (client and server)
<li>Fixed ctrl+alt+del emulation on win32
@ -141,21 +273,17 @@ Made following changes:
<li>Fixed reference count bug
<li>Keyboard input focus now restored on X11 (fixes loss of input in some games)
</ul>
<p>
</p><p>
The OS X port does not yet support:
</p>
<ul>
<li>HTML and bitmap clipboard data
<li>Screen saver synchronization
<li>Non-US English keyboards
</ul>
</p><p>
<span class="date">May-05-2004</span> - Synergy 1.1.5 released
<p>
</p><p>
Made following changes:
</p>
<ul>
<li>No longer switching screens when a mouse button is down
<li>Worked around win32 mouse hook bug, fixing switch on double tap
@ -171,24 +299,20 @@ Made following changes:
<li>Partial support for MSYS/MinGW builds (NOT COMPLETE)
<li>Partial merge of OS X port (NOT COMPLETE)
</ul>
</p><p>
<span class="date">Mar-31-2004</span> - Synergy 1.1.4 released
<p>
</p><p>
Made following changes:
</p>
<ul>
<li>Fixed lookup of hosts by name of win32
<li>Reverted tray icon code to 1.0.15 version; seems to fix the bugs
<li>Fixed crash when caps, num, or scroll lock not in key map on X11
<li>Fixed double tap and wait to switch features
</ul>
</p><p>
<span class="date">Mar-28-2004</span> - Synergy 1.1.3 released
<p>
</p><p>
Made following changes:
</p>
<ul>
<li>Major code refactoring; reduced use of threads, added event queue
<li>Removed unused HTTP support code
@ -199,17 +323,13 @@ Made following changes:
<li>Improved keyboard handling and bug fixes
<li>Fixed dead key handling
</ul>
<p>
</p><p>
Note: the tray icon on windows is known to not work correctly when
running the synergy server on Windows 95/95/Me.
</p>
</p><p>
<span class="date">Aug-24-2003</span> - Synergy 1.0.14 released
<p>
</p><p>
Made following changes:
</p>
<ul>
<li>Fixed bugs in setting win32 process/thread priority
<li>Fixed resource leak in opening win32 system log
@ -217,20 +337,18 @@ Made following changes:
<li>Synergy log copied to clipboard now transferred to other screens
<li>Hack to work around lesstif clipboard removed (fixes pasting on X)
</ul>
</p><p>
<span class="date">Jul-20-2003</span> - Synergy 1.0.12 released
<p>
</p><p>
Made following changes:
</p><p>
This release finally completes support for non-ASCII characters,
fully supporting most (all?) European keyboard layouts including
dead key composition. This release includes changes from several
experimental versions (1.0.9, 1.0.11, 1.1.0, 1.1.1, 1.1.2, and
1.1.3).
</p>
<p>
</p><p>
Made following changes:
</p>
<ul>
<li>Added non-ASCII support to win32 and X11
<li>Added dead key support to win32 and X11
@ -244,12 +362,11 @@ Made following changes:
<li>Fixed mouse warping on unconnected client
<li>Stopped unconnected client from filling up event logs
</ul>
</p><p>
<span class="date">May-10-2003</span> - Synergy 1.0.8 released
<p>
</p><p>
Made following changes:
</p>
</p><p>
<ul>
<li>Fixed hook forwarding (fixing interaction with objectbar)
<li>Fixed "Windows" key handling and added support Win+E, Win+F, etc
@ -268,12 +385,48 @@ Made following changes:
<li>Added support for "Internet" and "Multimedia" keys
<li>Fixed jumping from client to itself (mouse wrapping)
</ul>
</p><p>
<span class="date">Apr-26-2003</span> - Added roadmap
</p><p>
There's now a <a href="roadmap.html">roadmap</a> for Synergy
describing the plans for further development.
</p><p>
<span class="date">Apr-26-2003</span> - Added Paypal donation page
</p><p>
There's now a <a href="donate.html">donate</a> button for those
who'd like to make a monetary contribution to the further
development of Synergy.
</p><p>
<span class="date">Apr-26-2003</span> - Development update
</p><p>
Synergy 1.0.8 will include fixes for the following problems.
These are already fixed and some are in development version 1.0.7.
</p><p>
<ul>
<li>Mouse events at edge of screen are stolen
<li>Windows key doesn't work on clients
<li>Alt+[Shift+]Tab, Alt+[Shift+]Esc, Ctrl+Esc don't work on Win 95/98/Me
<li>Scroll lock doesn't lock to Windows server screen
<li>Screen flashes every 5 seconds on some X11 systems
<li>Synergy doesn't work properly with Xinerama
<li>Screen names with underscores are not allowed
</ul>
</p><p>
Synergy 1.0.8 will probably include fixes for these problems:
</p><p>
<ul>
<li>AltGr/Mode_switch doesn't work
<li>Non-ASCII keys aren't supported
<li>Synergy performs badly on a busy Windows system
<li>Unexpected key repeats on X11 clients
</ul>
</p><p>
Synergy 1.0.8 should be available in the first half of May.
</p><p>
<span class="date">Mar-27-2003</span> - Synergy 1.0.6 released
<p>
</p><p>
Made following changes:
</p>
</p><p>
<ul>
<li>Added tray icon on win32
<li>Fixed multi-monitor support on win32
@ -285,14 +438,33 @@ Made following changes:
<li>Fixed problem sending the CLIPBOARD to motif/lesstif apps
<li>Win32 launcher now remembers non-config-file state
</ul>
</p><p>
In addition, the version number scheme has been changed. Given a
version number X.Y.Z, release versions will always have Y and Z
even while development versions will have Y and Z odd.
</p><p>
<span class="date">Mar-27-2003</span> - Synergy featured in Linux Journal.
</p><p>
The April 2003 issue of Linux Journal includes an article on Synergy.
Written by Chris Schoeneman, it describes configuring synergy between
two linux systems.
</p><p>
<span class="date">Mar-27-2003</span> - Contributions to Synergy.
</p><p>
Many thanks to Girard Thibaut for providing a version of the win32
launch dialog translated into French. I hope to integrate these
changes into future releases.
</p><p>
Thanks also to &quot;wrhodes&quot; who provided source files for
building an InstallShield installer for Synergy. They'll be
integrated into an upcoming release.
</p><p>
<span class="date">Feb-18-2003</span> - Synergy 1.0.3 released
<p>
</p><p>
Made following changes:
</p>
</p><p>
<ul>
<li>Support for X11 keymaps with only uppercase letters
<li>Added support for X11 keymaps with only uppercase letters
<li>Fixed memory leaks
<li>Added documentation on using synergy with SSH
<li>Fixed unnecessary left-handed mouse button swapping
@ -300,31 +472,28 @@ Made following changes:
<li>Reduced frequency of large cursor jumps when leaving win32 server
<li>Changed cursor motion on win32 multimon to relative moves only
</ul>
</p><p>
<span class="date">Jan-25-2003</span> - Synergy 1.0.2 released
<p>
</p><p>
Made following changes:
</p>
</p><p>
<ul>
<li>Fixed out-of-bounds array lookup in the BSD and Windows network code
<li>Added ability to set screen options from Windows launch dialog
</ul>
</p><p>
<span class="date">Jan-22-2003</span> - Synergy 1.0.1 released
<p>
</p><p>
Made following changes:
</p>
</p><p>
<ul>
<li>Fixed running as a service on Windows NT family
</ul>
</p><p>
<span class="date">Jan-20-2003</span> - Synergy 1.0.0 released
<p>
</p><p>
Made following changes:
</p>
</p><p>
<ul>
<li>Refactored to centralize platform dependent code
<li>Added support for mouse wheel on Windows NT (SP3 and up)
@ -333,19 +502,16 @@ Made following changes:
<li>Fixes for working with xscreensaver
<li>Fixes for circular screen links
</ul>
<p>
</p><p>
This release has been tested on Linux and Windows. It builds and
is believed to run on Solaris and FreeBSD. It is believed to
build and run on Irix and AIX. It builds but does not work on
MacOS X.
</p>
</p><p>
<span class="date">Dec-25-2002</span> - Synergy 0.9.14 released
<p>
</p><p>
Made following changes:
</p>
</p><p>
<ul>
<li>Fixed solaris compile problems (untested)
<li>Fixed irix compile problems (untested)
@ -358,12 +524,11 @@ Made following changes:
<li>Added config options for half-duplex toggle keys on X11
<li>Enabled class diagrams in doxygen documentation
</ul>
</p><p>
<span class="date">Nov-05-2002</span> - Synergy 0.9.13 released
<p>
</p><p>
Made following changes:
</p>
</p><p>
<ul>
<li>Fixed solaris compile problems (untested)
<li>Fixed MacOS X compile problems (semi-functional)
@ -376,12 +541,11 @@ Made following changes:
<li>Unix platforms can now read Win32 configuration files
<li>Minor error reporting fixes
</ul>
</p><p>
<span class="date">Sep-14-2002</span> - Synergy 0.9.12 released
<p>
</p><p>
Made following changes:
</p>
</p><p>
<ul>
<li>Win32 was not reporting log messages properly when run from synergy.exe
<li>Network error messages weren't reporting useful information
@ -389,51 +553,47 @@ Made following changes:
<li>X11 wasn't handling some keys/key combinations correctly
<li>Added option to change logging level when testing from synergy.exe
</ul>
</p><p>
<span class="date">Sep-04-2002</span> - Synergy 0.9.11 released
<p>
</p><p>
Fixed following bugs:
</p>
</p><p>
<ul>
<li>Worked around missing SendInput() on windows 95/NT 4 prior to SP3
<li>Fixed keyboard mapping on X11 synergy client
</ul>
</p><p>
<span class="date">Sep-02-2002</span> - Synergy 0.9.10 released
<p>
</p><p>
Fixed following bugs:
</p>
</p><p>
<ul>
<li>The Pause/Break and KP_Enter buttons were not working correctly on windows
<li>The Pause/Break and keypad Enter buttons were not working correctly on windows
<li>Configuration options were being lost on windows after a reboot
<li>Added support for AltGr/ModeSwitch keys
<li>Added support for auto-start on windows when not administrator
<li>Improved autoconf
<li>Added workaround for lack of sstream header on g++ 2.95.
</ul>
</p><p>
<span class="date">Aug-18-2002</span> - Synergy 0.9.9 released
<p>
</p><p>
Fixed three bugs:
</p>
</p><p>
<ul>
<li>The PrintScrn button was not working correctly on windows
<li>The Win32 server could hang when a client disconnected
<li>Using the mouse wheel could hang the X server
</ul>
</p><p>
<span class="date">Aug-11-2002</span> - Synergy 0.9.8 released
<p>
</p><p>
Supports any number of clients under Linux or Windows 95 or NT4
or later. Includes mouse and keyboard sharing, clipboard
synchronization and screen saver synchronization. Supports ASCII
keystrokes, 5 button mouse with wheel, and Unicode text clipboard
format.
</p>
</body>
</html>

92
doc/roadmap.html Normal file
View File

@ -0,0 +1,92 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
<html>
<head>
<meta HTTP-EQUIV="Content-Type" CONTENT="text/html;CHARSET=iso-8859-1">
<meta name="keywords" content="Virtual Screen, Open Source, Software" />
<meta name="description" content="Mouse and Keyboard Sharing" />
<link rel="stylesheet" type="text/css" href="synergy.css" media="screen" />
<title>Synergy Roadmap</title>
</head>
<body class="main">
<p>
</p><h3>Synergy Roadmap</h3><p>
</p><p>
This page describes the planned development of Synergy. There are
no dates or deadlines. Instead, you'll find the features to come
and the rough order they'll arrive.
</p><p>
</p><h4>Short term</h4><p>
</p><p>
Synergy should work seamlessly. When it works correctly, it works
transparently so you don't even think about it. When it breaks,
you're forced out of the illusion of a unified desktop. The first
priority is fixing those bugs that break the illusion.
</p><p>
Some of these bugs are pretty minor and some people would rather
have new features first. But I'd rather fix the current
foundation before building on it. That's not to say features
won't get added until after bug fixes; sometimes it's just too
tempting to code up a feature.
</p><p>
The highest priority feature is currently splitting synergy into
front-ends and a back-end. The back-end does the real work. The
front-ends are console, GUI, or background applications that
communicate with the back-end, either controlling it or receiving
notifications from it.
</p><p>
On win32, there'd be a front-end for the tray icon and a dialog to
start, stop, and control the back-end. OS X and X11 would have
similar front-ends. Splitting out the front-end has the added
benefit on X11 of keeping the back-end totally independent of
choice of GUI toolkit (KDE, Gnome, etc.)
</p><p>
One can also imagine a front-end that does nothing but put monitors
into power-saving mode when the cursor is not on them. If you have
one monitor auto-senses two inputs, this would automatically switch
the display when you move the cursor to one screen or another.
</p><p>
</p><h4>Medium term</h4><p>
</p><p>
Some features fit well into Synergy's current design and may simply
enhance it's current capabilities.
</p><p>
<ul>
<li>Configurable hot key to pop up a screen switch menu
<li>Configure screen saver synchronization on or off
<li>Graphical interface configuration and control on all platforms
<li>Graphical status feedback on all platforms
<li>More supported clipboard formats (particularly rich text)
</ul>
</p><p>
A popup menu would be new for Synergy, which currently doesn't have
to do any drawing. That opens up many possibilities. Ideally,
front-ends request hot keys from the back-end and then tell the back
end what to do when they're invoked. This keeps the back-end
independent of the user interface.
</p><p>
</p><h4>Long term</h4><p>
</p><p>
Two features stand out as long term goals:
</p><p>
<ul>
<li>Support <span class="arg">N</span> computers on
<span class="arg">M</span> monitors
<li>Drag and drop across computers
</ul>
</p><p>
The first feature means sharing a monitor or monitors the way the
keyboard and mouse are shared. With this, Synergy would be a full
KVM solution. Not only would it support a few computers sharing
one screen (still using the mouse to roll from one screen to
another), but it should also support dozens of computers to provide
a solution for server farm administrators. In this capacity, it
may need to support text (as opposed to bitmap graphics) screens.
</p><p>
The second feature would enhance the unified desktop illusion. It
would make it possible to drag a file and possibly other objects
to another screen. The object would be copied (or moved). I expect
this to be a very tricky feature.
</p>
</body>
</html>

View File

@ -1,69 +1,72 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
<html>
<head>
<meta HTTP-EQUIV="Content-Type" CONTENT="text/html;CHARSET=iso-8859-1">
<meta name="keywords" content="Virtual Screen, Open Source, Software" />
<meta name="description" content="Mouse and Keyboard Sharing" />
<link rel="stylesheet" type="text/css" href="synergy.css" media="screen" />
<title>Guide to Running Synergy</title>
<title>Synergy User Guide</title>
</head>
<body class="main">
<h3>Running Synergy</h3>
<p>
</p><h3>Running Synergy</h3><p>
</p><p>
Synergy lets you use one keyboard and mouse across multiple computers.
To do so it requires that all the computers are connected to each other
via TCP/IP networking. Most systems come with this installed.
</p>
<h4>Step 1 - Choose a server</h4>
<p>
</p><p>
</p><h4>Step 1 - Choose a server</h4><p>
</p><p>
The first step is to pick which keyboard and mouse you want to share.
The computer with that keyboard and mouse is called the "primary
screen" and it runs the synergy server. All of the other computers
are "secondary screens" and run the synergy client.
</p>
<h4>Step 2 - Install the software</h4>
<p>
</p><p>
</p><h4>Step 2 - Install the software</h4><p>
</p><p>
Second, you install the software. Choose the appropriate package
and install it. For example, on Windows you would run
<span class="code">SynergyInstaller</span>. You must install the
software on all the computers that will share the mouse and keyboard.
</p>
<h4>Step 3 - Configure and start the server</h4>
<p>
software on all the computers that will share the mouse and keyboard
(clients and server). On OS X you'll just have a folder with some
documentation and two programs. You can put this folder anywhere.
</p><p>
</p><h4>Step 3 - Configure and start the server</h4><p>
</p><p>
Next you configure the server. You'll tell synergy the name of
the primary and secondary screens, which screens are next to which,
and choose desired options. On Windows there's a dialog box for
setting the configuration. On other systems you'll create a simple
text file.
</p>
<p>
</p><p>
<a name="asymmetric"></a>
Note that when you tell synergy that screen <span class="code">A</span>
is to the left of screen <span class="code">B</span> this does <b>not</b>
imply that <span class="code">B</span> is to the right of
<span class="code">A</span>. You must explicitly indicate both
relations. If you don't do both then when you're running synergy you'll
find you're unable to leave one of the screens.
</p>
<p>
</p><p>
<b>Windows</b><br>
On Windows run synergy by double clicking on the
<span class="code">synergy</span> file. This brings up a dialog.
Configure the server:
<ul>
<li>Click the <span class="code">Server</span> radio button
<li>Click <span class="code">Add</span> to add the server to the
<li>Click the <span class="code">Share this computer's keyboard and mouse (server)</span> radio button
<li>Click the <span class="code">Screens &amp; Links Configure...</span> button
<li>Click the <span class="code">+</span> button to add the server to the
<span class="code">Screens</span> list
<ul>
<li>Enter the name of server (the computer's name is the recommended name)
<li>Optionally enter other names the server is known by
<li>Click <span class="code">OK</span>
</ul>
<li>Use <span class="code">Add</span> to add your other computers
<li>Use the <span class="code">+</span> button to add your other computers
<ul>
<li>Using a computer's name as its screen name is recommended
<li>Choose desired screen options on the <span class="code">Add</span> dialog
<li>Choose desired screen options on the <span class="code">Add Screen</span> dialog
</ul>
<li>Use the controls under <span class="code">Layout</span> to link screens together
<li>Use the controls under <span class="code">Links</span> to link screens together
<ul>
<li>Click (once) on the server's name in the <span class="code">Screens</span> list
<li>Choose the screen to the left of the server; use <span class="code">---</span>
@ -71,6 +74,7 @@ Configure the server:
<li>Choose the screens to the right, above and below the server
<li>Repeat the above steps for all the other screens
</ul>
<li>Click <span class="code">OK</span> to close the <span class="code">Screens &amp; Links</span> dialog
<li>Use <span class="code">Options...</span> to set desired options
<li>If the server's screen name is not the server's computer name:
<ul>
@ -80,16 +84,14 @@ Configure the server:
<li>Click <span class="code">OK</span>
</ul>
</ul>
</p>
<p>
</p><p>
Now click <span class="code">Test</span>. The server will start and
you'll see a console window with log messages telling you about synergy's
progress. If an error occurs you'll get one or more dialog boxes telling
you what the errors are; read the errors to determine the problem then
correct them and try <span class="code">Test</span> again.
</p>
<p>
correct them and try <span class="code">Test</span> again. See Step 5
for typical errors.
</p><p>
<b>Unix or Mac OS X</b><br>
Create a text file named <span class="code">synergy.conf</span> with the
following:
@ -119,34 +121,41 @@ have more than two computers you can add those too: add each computer's host
name in the <span class="code">screens</span> section and add the
appropriate links. See the <a href="configuration.html">configuration
guide</a> for more configuration possibilities.
</p>
<p>
</p><p>
Now start the server. Normally synergy wants to run "in the background."
It detaches from the terminal and doesn't have a visible window, effectively
disappearing from view. Until you're sure your configuration works, you
should start synergy "in the foreground" using the <span class="code">-f</span>
command line option.
</p><p>
On unix type the command below in a shell. If synergys is not in your
PATH then use the full pathname.
<pre>
synergys -f --config synergy.conf
</pre>
On OS X open Terminal in the Utilities folder in the Applications folder.
Drag the synergys program from the synergy folder onto the Terminal window.
The path to the synergys program will appear. Add the following to the
same line, type a space at the end of the line but don't press enter:
<pre>
-f --config
</pre>
Now drag the synergy.conf file onto the Terminal window and press enter.
Check the reported messages for errors. Use ctrl+c to stop synergy if
it didn't stop automatically, correct any problems, and start it again.
</p>
<h4>Step 4 - Start the clients</h4>
<p>
</p><p>
</p><h4>Step 4 - Start the clients</h4><p>
</p><p>
Next you start the client on each computer that will share the server's
keyboard and mouse.
</p>
<p>
</p><p>
<b>Windows</b><br>
On Windows run synergy by double clicking on the
<span class="code">synergy</span> file. This brings up a dialog.
Configure the client:
<ul>
<li>Click the <span class="code">Client</span> radio button
<li>Enter the server's computer name in <span class="code">Server Host Name</span>
<li>Click the <span class="code">Use another computer's shared keyboard and mouse (client)</span> radio button
<li>Enter the server's computer name next to <span class="code">Other Computer's Host Name</span>
<ul>
<li>This is not the server's screen name, unless you made that the
server's host name as recommended
@ -158,45 +167,81 @@ Configure the client:
<li>Click <span class="code">OK</span>
</ul>
</ul>
</p>
<p>
</p><p>
Now click <span class="code">Test</span>.
</p>
<p>
</p><p>
<b>Unix or Mac OS X</b><br>
To start a client, enter the following:
To start a client on unix, enter the following:
<pre>
synergyc -f <span class="arg">server-host-name</span>
</pre>
where <span class="arg">server-host-name</span> is replaced by the host
name of the computer running the synergy server.
</p>
<h4>Step 5 - Test</h4>
<p>
name of the computer running the synergy server. If synergyc is not in
your PATH then use the full pathname.
</p><p>
On OS X open Terminal in the Utilities folder in the Applications folder.
Drag the synergyc program from the synergy folder onto the Terminal window.
The path to the synergys program will appear. Add the following to the
same line and press enter:
<pre>
-f <span class="arg">server-host-name</span>
</pre>
</p><p>
When you added the client to the server's configuration you chose a
name for the client. If that name was not client's host name then
you must tell the client the name you used. Instead of the above
command use this instead:
<pre>
synergyc -f --name <span class="arg">name</span> <span class="arg">server-host-name</span>
</pre>
where <span class="arg">name</span> is the name for the client in
the server's configuration. (On OS X drag the synergyc program to the
Terminal window rather than typing synergyc.)
</p><p>
</p><h4>Step 5 - Test</h4><p>
</p><p>
Clients should immediately report a successful connection or one or
more error messages. Here are the typical problems and possible
solutions:
more error messages. Some typical problems and possible solutions are
below. See the <a href="trouble.html">troubleshooting</a> and the
<a href="faq.html">FAQ</a> pages for more help.
<ul>
<li>failed to open screen (X11 only)
<p>
</p><p>
Check permission to open the X display;<br>
check that the DISPLAY environment variable is set;<br>
check that the DISPLAY environment variable is set<br>
use the <span class="code">--display</span> command line option.
</p>
</p><p>
<li>address already in use
</p><p>
Another program (maybe another copy of synergy) is using the synergy port;
stop the other program or choose a different port in the
<span class="code">Advanced...</span> dialog. If you change the port
you must make the same change on all of the clients, too.
</p><p>
<li>connection forcefully rejected
</p><p>
The synergy client successfully contacted the server but synergy wasn't
running or it's running on a different port. You may also see this if
there's a firewall blocking the host or port. Make sure synergy is
running on the server and check for a firewall.
</p><p>
<li>already connected
<p>
</p><p>
Check that the synergy client isn't already running.
</p>
</p><p>
<li>refused client
<p>
</p><p>
Add the client to the server's configuration file.
</p>
</p><p>
<li>connection timed out
</p><p>
Check that <span class="arg">server-host-name</span> is correct.<br>
Check that you don't have a firewall blocking the server or synergy port.
</p><p>
<li>connection failed
<p>
check that <span class="arg">server-host-name</span> is
correct;<br>the server cannot open the desired port, stop
the program using that port (24800) and restart the server.
</p>
</p><p>
Check that <span class="arg">server-host-name</span> is correct.
</p><p>
</ul>
If you get the error "<span class="code">Xlib: No protocol specified</span>"
you're probably running synergy as root while logged in as another user.
@ -204,33 +249,34 @@ X11 may prevent this for security reasons. Either run synergy as the same
user that's logged in or (not recommended) use
<nobr>"<span class="code">xhost +</span>"</nobr> to allow anyone to connect
to the display.
</p>
<p>
</p><p>
When successful you should be able to move the mouse off the appropriate
edges of your server's screen and have it appear on a client screen.
Try to move the mouse to each screen and check all the configured links.
Check the mouse buttons and wheel and try the keyboard on each client.
You can also cut-and-paste text, HTML, and images across computers (HTML
and images are not supported on OS X yet).
</p>
<h4>Step 6 - Run</h4>
<p>
</p><p>
</p><h4>Step 6 - Run</h4><p>
</p><p>
Once everything works correctly, stop all the clients then the server.
Then start the server with the <span class="code">Start</span> button
on Windows and without the <span class="code">-f</span> option on Unix
and Mac OS X. Finally start the clients similarly.
</p>
<p>
and Mac OS X. Finally start the clients similarly. On Windows before
clicking <span class="code">Start</span> you may want to set the
<span class="code">Logging Level</span> to
<span class="code">Warning</span> so the logging window doesn't pop
up (because you currently can't close it, just minimize it).
</p><p>
You can also configure synergy to start automatically when your computer
starts or when you log in. See the <a href="autostart.html">autostart
guide</a> for more information.
</p>
<h4><a name="options"></a>Command Line Options Guide</h4>
<p>
</p><p>
</p><h4><a name="options"></a>Command Line Options Guide</h4><p>
</p><p>
<b><a name="commonOptions"></a>Common Command Line Options</b><br>
The following options are supported by <span class="code">synergys</span>
and <span class="code">synergyc</span>.
</p>
<table>
<tr>
<td>&nbsp;</td><td><span class="code">-d,</span></td>
@ -242,16 +288,16 @@ and <span class="code">synergyc</span>.
<td><span class="code">--daemon</span></td>
<td></td><td>run as a daemon (Unix) or background (Windows)</td>
</tr>
<tr>
<td>&nbsp;</td><td><span class="code">&nbsp;</span></td>
<td><span class="code">--display <span class="arg">display</span></span></td>
<td>&nbsp;&nbsp;</td><td>connect to X server at <span class="arg">display</span> (X11 only)</td>
</tr>
<tr>
<td>&nbsp;</td><td><span class="code">-f,</span></td>
<td><span class="code">--no-daemon</span></td>
<td></td><td>run in the foreground</td>
</tr>
<tr>
<td>&nbsp;</td><td><span class="code">&nbsp;</span></td>
<td><span class="code">--display <span class="arg">display</span></span></td>
<td>&nbsp;&nbsp;</td><td>connect to X server at <span class="arg">display</span> (X11 only)</td>
</tr>
<tr>
<td>&nbsp;</td><td><span class="code">-n,</span></td>
<td><span class="code">--name <span class="arg">name</span></span></td>
@ -278,8 +324,7 @@ and <span class="code">synergyc</span>.
<td></td><td>print version information and exit</td>
</tr>
</table>
</p>
<p>
</p><p>
Debug levels are from highest to lowest: <span class="code">FATAL</span>,
<span class="code">ERROR</span>, <span class="code">WARNING</span>,
<span class="code">NOTE</span>, <span class="code">INFO</span>,
@ -291,28 +336,24 @@ as a daemon. The Windows NT family logs messages to the event log
when running as a service. The Windows 95 family shows FATAL log
messages in a message box and others in a terminal window when running
as a service.
</p>
<p>
</p><p>
The <span class="code">--name</span> option lets the client or server
use a name other than its hostname for its screen. This name is used
when checking the configuration.
</p>
<p>
</p><p>
Neither the client nor server will automatically restart if an error
occurs that is sure to happen every time. For example, the server
will exit immediately if it can't find itself in the configuration.
On X11 both the client and server will also terminate if the
connection to the X server is lost (usually because it died).
</p>
<p>
</p><p>
<b>Server Command Line Options</b><br>
<p>
</p><p>
<pre>
synergys [options]
</pre>
The server accepts the <a href="#commonOptions">common options</a> and:
</p>
<p>
</p><p>
<table>
<tr>
<td>&nbsp;</td><td><span class="code">-a,</span></td>
@ -325,8 +366,7 @@ The server accepts the <a href="#commonOptions">common options</a> and:
<td>&nbsp;&nbsp;</td><td>read configuration from <span class="arg">pathname</span></td>
</tr>
</table>
</p>
<p>
</p><p>
<span class="arg">address</span> has one of the following forms:
<pre>
<span class="arg">hostname</span>
@ -338,10 +378,9 @@ interface on the server system (e.g. <span class="code">somehost</span>
or <span class="code">192.168.1.100</span>). <span class="arg">port</span>
is a port number from 1 to 65535. <span class="arg">hostname</span> defaults to
the system's hostname and <span class="arg">port</span> defaults to 24800.
</p>
<p>
</p><p>
<b>Client Command Line Options</b><br>
<p>
</p><p>
<pre>
synergyc [options] <span class="arg">address</span>[:<span class="arg">port</span>]
</pre>
@ -351,4 +390,5 @@ port on the server to connect to. The client accepts the
<a href="#commonOptions">common options</a>.
</p>
</body>
</html>

View File

@ -1,39 +1,37 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
<html>
<head>
<meta HTTP-EQUIV="Content-Type" CONTENT="text/html;CHARSET=iso-8859-1">
<meta name="keywords" content="Virtual Screen, Open Source, Software" />
<meta name="description" content="Mouse and Keyboard Sharing" />
<link rel="stylesheet" type="text/css" href="synergy.css" media="screen" />
<title>Synergy Security Guide</title>
<title>Synergy Network Security Guide</title>
</head>
<body class="main">
<h3>Authentication and Encryption</h3>
<p>
</p><h3>Authentication and Encryption</h3><p>
Synergy does not do any authentication or encryption. Any computer
can connect to the synergy server if it provides a screen name known
to the server, and all data is transferred between the server and the
clients unencrypted which means that anyone can, say, extract the
key presses used to type a password. Therefore, synergy should not
be used on untrusted networks.
</p>
<p>
</p><p>
However, there are tools that can add authentication and encryption
to synergy without modifying either those tools or synergy. One
such tool is SSH (which stands for secure shell). A free implementation
of SSH is called <a href="http://www.openssh.com/">OpenSSH</a> and runs
of SSH is called <a target="_top" href="http://www.openssh.com/">OpenSSH</a> and runs
on Linux, many Unixes, and Windows (in combination with
<a href="http://www.cygwin.com/">Cygwin</a>).
</p>
<h3>Configuring the Server</h3>
<p>
<a target="_top" href="http://www.cygwin.com/">Cygwin</a>).
</p><p>
</p><h3>Configuring the Server</h3><p>
Install the OpenSSH server on the same computer as the synergy server.
Configure the OpenSSH server as usual (synergy doesn't demand any
special options in OpenSSH) and start it. Start the synergy server as
usual; the synergy server requires no special options to work with
OpenSSH.
</p>
<h3>Configuring the Clients</h3>
<p>
</p><p>
</p><h3>Configuring the Clients</h3><p>
Install the OpenSSH client on each synergy client computer. Then, on
each client, start the OpenSSH client using port forwarding:
<pre>
@ -53,4 +51,5 @@ Synergy will then run normally except all communication is passed
through OpenSSH which decrypts/encrypts it on behalf of synergy.
</p>
</body>
</html>

View File

@ -53,8 +53,9 @@ pre {
font-variant: small-caps;
font-size: 400%;
width: 100%;
padding: 0px 0px 0px 5px;
border-bottom: solid #6699ff 1px;
padding: 0px;
margin: 0px;
border: 0px;
}
.banner a {
color: #000000;
@ -63,6 +64,15 @@ pre {
text-decoration: none;
color: #000000;
}
.bannerb {
color: #ffffff;
background-color: #ffffff;
width: 100%;
height: 1px;
padding: 0px;
margin: 0px;
border-bottom: solid #6699ff 1px;
}
.nav {
font-size: x-small;
@ -71,6 +81,7 @@ pre {
padding: 2px 0px 2px 0px;
margin: 0px;
border-bottom: solid #d4d4d4 300px;
}
.nav a:hover {
text-decoration: none;
@ -82,7 +93,7 @@ pre {
text-indent: 1em;
}
.nav .section {
width: 100%;
width: 120px;
text-indent: 0em;
border-top: 0px;
border-left: 0px;

View File

@ -1,45 +1,42 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
<html>
<head>
<meta HTTP-EQUIV="Content-Type" CONTENT="text/html;CHARSET=iso-8859-1">
<meta name="keywords" content="Virtual Screen, Open Source, Software" />
<meta name="description" content="Mouse and Keyboard Sharing" />
<link rel="stylesheet" type="text/css" href="synergy.css" media="screen" />
<title>Synergy Tips and Tricks</title>
</head>
<body class="main">
<h3>Tips and Tricks</h3>
<p>
</p><h3>Tips and Tricks</h3><p>
<ul>
<li>
<p>
Be aware that not all keystrokes can be handled by synergy. In
particular, ctrl+alt+del is not handled. However, synergy can
convert ctrl+alt+pause into ctrl+alt+del on the client side.
(Synergy must be installed as a service on the client for this to
work on the Windows NT family.) Some non-standard keys may not
work, especially "multimedia" buttons, though several are
correctly handled.
</p>
(Synergy must be configured to autostart when the computer starts
on the client for this to work on the Windows NT family.) Some
non-standard keys may not work, especially "multimedia" buttons,
though several are correctly handled.
</p><p>
<li>
<p>
A screen can be its own neighbor. That allows a screen to "wrap".
For example, if a configuration linked the left and right sides of
a screen to itself then moving off the left of the screen would put
the mouse at the right of the screen and vice versa.
</p>
</p><p>
<li>
<p>
You cannot switch screens when the Scroll Lock is toggled on. Use
this to prevent unintentional switching.
</p>
this to prevent unintentional switching. You can configure other
hot keys to do this instead; see
<a href="configuration.html#lockCursor">lockCursorToScreen</a>.
</p><p>
<li>
<p>
Turn off mouse driven virtual desktop switching on X windows. It
will interfere with synergy. Use keyboard shortcuts instead.
</p>
</p><p>
<li>
<p>
Synergy's screen saver synchronization works best with xscreensaver
under X windows. Synergy works better with xscreensaver if it is
using one of the screen saver extensions. Prior to xscreensaver 4.0
@ -49,45 +46,36 @@
command line options to enable an extension (assuming your server has
the extension). Starting with 4.0 you must enable the corresponding
option in your <span class="code">.xscreensaver</span> file.
</p>
</p><p>
<li>
<p>
Synergy automatically converts newlines in clipboard text (Unix
expects <span class="code">\n</span> to end each line while Windows
expects <span class="code">\r\n</span>).
</p>
</p><p>
<li>
<p>
Clients can be started and stopped at any time. When a screen is
not connected, the mouse will jump over that screen as if the mouse
had moved all the way across it and jumped to the next screen.
</p>
</p><p>
<li>
<p>
A client's keyboard and mouse are fully functional while synergy is
running. You can use them in case synergy locks up.
</p>
</p><p>
<li>
<p>
Strong authentication and encryption is available by using SSH. See
the <a href="security.html">security guide</a> for more information.
Synergy does not otherwise provide secure communications and it should
not be used on or over untrusted networks.
</p>
</p><p>
<li>
<p>
Synergy doesn't work if a 16-bit Windows application has the focus
on Windows 95/98/Me. This is due to limitations of Windows. One
commonly used 16-bit application is the command prompt
(<span class="code">command.exe</span>)
and this includes synergy's log window when running in test mode.
</p>
</p><p>
</ul>
</p>
</body>
</html>

43
doc/toc.html Normal file
View File

@ -0,0 +1,43 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
<html>
<head>
<meta HTTP-EQUIV="Content-Type" CONTENT="text/html;CHARSET=iso-8859-1">
<meta name="keywords" content="Virtual Screen, Open Source, Software" />
<meta name="description" content="Mouse and Keyboard Sharing" />
<link rel="stylesheet" type="text/css" href="synergy.css" media="screen" />
<title>Synergy TOC</title>
<base target="page">
</head>
<body>
<table class="nav">
<tr><td class="section"><nobr>General</nobr></td></tr>
<tr><td><nobr><a href="home.html">Home</a></nobr></td></tr>
<tr><td><nobr><a href="about.html">About</a></nobr></td></tr>
<tr><td><nobr><a href="news.html">News</a></nobr></td></tr>
<tr><td><nobr><a href="authors.html">Authors</a></nobr></td></tr>
<tr><td><nobr><a href="license.html">License</a></nobr></td></tr>
<tr><td><nobr><a href="history.html">History</a></nobr></td></tr>
<tr><td><nobr><a href="roadmap.html">Future</a></nobr></td></tr>
<tr><td></td></tr>
<tr><td class="section"><nobr>Documentation</nobr></td></tr>
<tr><td><nobr><a href="running.html">Using Synergy</a></nobr></td></tr>
<tr><td><nobr><a href="security.html">Security</a></nobr></td></tr>
<tr><td><nobr><a href="configuration.html">Configuration</a></nobr></td></tr>
<tr><td><nobr><a href="autostart.html">Autostarting</a></nobr></td></tr>
<tr><td><nobr><a href="compiling.html">Compiling</a></nobr></td></tr>
<tr><td><nobr><a href="developer.html">Developer</a></nobr></td></tr>
<tr><td></td></tr>
<tr><td class="section"><nobr>Help</nobr></td></tr>
<tr><td><nobr><a href="faq.html">FAQ</a></nobr></td></tr>
<tr><td><nobr><a href="trouble.html">Troubleshooting</a></nobr></td></tr>
<tr><td><nobr><a href="tips.html">Tips</a></nobr></td></tr>
<tr><td><nobr><a target="_top" href="http://sourceforge.net/tracker/?func=browse&group_id=59275&atid=490467">Known Bugs</a></nobr></td></tr>
<tr><td><nobr><a target="_top" href="http://sourceforge.net/tracker/?func=add&group_id=59275&atid=490467">Report Bug</a></nobr></td></tr>
<tr><td><nobr><a href="contact.html">Contact</a></nobr></td></tr>
<tr><td></td></tr>
<tr><td class="section"><nobr>Community</nobr></td></tr>
<tr><td><nobr><a target="_top" href="http://sourceforge.net/projects/synergy2/">Project Home</a></nobr></td></tr>
<tr><td><nobr><a target="_top" href="http://sourceforge.net/forum/?group_id=59275">Forums</a></nobr></td></tr>
<tr><td><nobr><a target="_top" href="http://sourceforge.net/donate/index.php?group_id=59275">Donate</a></nobr></td></tr>
</table>
</body>

204
doc/trouble.html Normal file
View File

@ -0,0 +1,204 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
<html>
<head>
<meta HTTP-EQUIV="Content-Type" CONTENT="text/html;CHARSET=iso-8859-1">
<meta name="keywords" content="Virtual Screen, Open Source, Software" />
<meta name="description" content="Mouse and Keyboard Sharing" />
<link rel="stylesheet" type="text/css" href="synergy.css" media="screen" />
<title>Synergy Troubleshooting</title>
</head>
<body class="main">
<p> </p>
<h3>Synergy Troubleshooting</h3>
<h4>Problems</h4>
<ol>
<li><a href="#problem1">Cannot read configuration</a>
<li><a href="#problem2">Connection forcefully rejected</a>
<li><a href="#problem3">Connection timed out</a>
<li><a href="#problem4">Cannot listen for clients</a>
<li><a href="#problem5">Unknown screen name "XXX"</a>
<li><a href="#problem6">Server refused client with name "XXX"</a>
<br><a href="#problem6">A client with name "XXX" is not in the map</a>
<li><a href="#problem7">Server already has a connected client with name "XXX"</a>
<br><a href="#problem7">A client with name "XXX" is already connected</a>
<li><a href="#problem8">Server has incompatible version</a>
<li><a href="#problem9">The cursor goes to secondary screen but won't come back</a>
</ol>
<h4>Solutions</h4>
<ol>
<li><a name="problem1"></a><span class="fakelink">Cannot read configuration</span>
<p>
There's an error in the configuration file. This error is always
accompanied by another message describing the problem. Use that
message and the <a href="configuration.html">configuration documentation</a>
to determine the fix.
</p>
<li><a name="problem2"></a><span class="fakelink">Connection forcefully rejected</span>
<p>
The client was able to contact the server computer but the server was
not listening for clients. Possible reasons are:
</p>
<ul>
<li>The client is using the wrong server
<p>
Make sure the client is using the hostname or IP address of the computer
running the synergy server.
</p>
<li>Synergy isn't running on the server
<p>
Make sure the synergy server is running on the server computer. Make
sure the server is ready to accept connections. If another program is
using synergy's port (24800 by default) then synergy can't start unless
you specify a different port.
</p>
<li>The client is using the wrong port
<p>
Synergy uses port 24800 by default but you can specify a different port.
If you do use a different port you must use that port on the server and
all clients.
</p>
</ul>
<li><a name="problem3"></a><span class="fakelink">Connection timed out</span>
<p>
The most likely reasons for this are:
</p>
<ul>
<li>A firewall
<p>
A firewall is a program or device that deliberately blocks network
connections for security reasons. Typically, they'll silently drop
packets they don't want rather than sending a rejection to the sender.
This makes it more difficult for intruders to break in.
</p><p>
When synergy traffic hits a firewall and gets dropped, eventually the
synergy client will give up waiting for a response and time out. To
allow synergy traffic through first find all the firewalls on the
network between and on the synergy client and server computers.
</p><p>
A firewall on the server or any network device between the server and
any client should allow packets to TCP port 24800. (Port 24800 is the
default; use whichever port you've selected.) You'll have to consult
the manual for your operating system, device, or firewall software to
find out how to do this.
</p><p>
Usually you'll won't need to adjust a firewall on client machines.
That's because firewalls normally allow incoming traffic on any port
they've initiated a connection on. The reasoning is, of course, if
you started a conversation you probably want to hear the reply.
</p>
<li>The network is down or busy
<p>
Correct the network problem and try again. You might try
<span class="code">ping</span> to see if the two computers can see
each other on the network.
</p>
<li>The server is frozen
<p>
If the synergy server is running but locked up or very busy then the
client may get this message. If the server is locked up then you'll
probably have to restart it. If it's just very busy then the client
should successfully connect automatically once the server settles down.
</p>
</ul>
<li><a name="problem4"></a><span class="fakelink">Cannot listen for clients</span>
<p>
Synergy tried to start listening for clients but the network port is
unavailable for some reason. Typical reasons are:
</p>
<ul>
<li>No network devices
<p>
You must have a TCP/IP network device installed and enabled to use
synergy.
</p>
<li>A synergy server is already running
<p>
Check that a synergy server isn't already running.
</p>
<li>Another program is using synergy's port
<p>
Only one program at a time can listen for connections on a given port.
If the specific error is that the address is already in use and you've
ruled out the other causes, then it's likely another program is already
using synergy's port. By default synergy uses port 24800. Try having
synergy use a different port number, like 24801 or 24900. Note that
the server and all clients must use the same port number. Alternatively,
find the other program and stop it or have it use another port.
</p>
</ul>
<li><a name="problem5"></a><span class="fakelink">Unknown screen name "XXX"</span>
<p>
This error can be reported when reading the configuration; see
<a href="#problem1">cannot read configuration</a>. If the configuration
was read successfully and you get this error then it means that the
server's screen is not in the configuration. All screens must be listed
in the configuration.
</p><p>
A common reason for this is when you haven't used the system's hostname
as its screen name. By default, synergy uses the hostname as the screen
name. If you used a different screen name in the configuration then you
must tell synergy what that name is. Let's say the hostname is
<span class="code">frederick</span> but the configuration defines a screen
named <span class="code">fred</span>. Then you must tell the server
that its screen name is <span class="code">fred</span> by using the
<span class="code">--name fred</span> command line option or setting
the screen name in the advanced options dialog to
<span class="code">fred</span>.
</p><p>
Alternatively, you can specify one name as an alias of another. See
the <a href="configuration.html#aliases">configuration documentation</a>
for details.
</p><p>
Another common reason for this is a mismatch between what you think the
hostname is and what synergy thinks it is. Typically this is a problem
with fully qualified domain names (FQDN). Perhaps you think your system
is named <span class="code">fred</span> but synergy thinks it's
<span class="code">fred.nowhere.com</span> or
<span class="code">fred.local</span>. You can use either solution above
to fix this.
</p>
<li><a name="problem6"></a><span class="fakelink">Server refused client with name "XXX"</span>
<br><span class="fakelink">A client with name "XXX" is not in the map</span>
<p>
The client is using a screen name not in the server's configuration.
This is essentially the same problem as <a href="#problem5">Unknown
screen name "XXX"</a> and has the same solutions: specify another
screen name or add an alias.
</p>
<li><a name="problem7"></a><span class="fakelink">Server already has a connected client with name "XXX"</span>
<br><span class="fakelink">A client with name "XXX" is already connected</span>
<p>
This happens when:
</p>
<ul>
<li>Two clients try use the same screen name
<p>
Each client must have a unique screen name. Configure at least one
client to use a different screen name.
</p>
<li>One client reconnects without cleanly disconnecting
<p>
It's possible for a client to disconnect without the server knowing,
usually by being disconnected from the network or possibly by going
to sleep or even crashing. The server is left thinking the client is
still connected so when the client reconnects the server will think
this is a different client using the same name. Synergy will usually
detect and correct this problem within a few seconds. If it doesn't
then restart the server.
</p>
</ul>
<li><a name="problem8"></a><span class="fakelink">Server has incompatible version</span>
<p>
You're using different versions of synergy on the client and server.
You should use the same version on all systems.
</p>
<li><a name="problem9"></a><span class="fakelink">The cursor goes to secondary screen but won't come back</span>
<p>
This is <a href="faq.html#faq17">FAQ #17</a> and is also mentioned in
the documentation for <a href="running.html#asymmetric">using synergy</a>
and <a href="configuration.html#asymmetric">configuration</a>.
</p>
</ol>
</body>
</html>

View File

@ -122,7 +122,7 @@ CArch::CArch(ARCH_ARGS* args)
m_sleep = new ARCH_SLEEP;
m_string = new ARCH_STRING;
m_time = new ARCH_TIME;
m_console = new ARCH_CONSOLE;
m_console = new ARCH_CONSOLE(args);
m_daemon = new ARCH_DAEMON;
m_taskbar = new ARCH_TASKBAR(args);
@ -170,6 +170,12 @@ CArch::closeConsole()
m_console->closeConsole();
}
void
CArch::showConsole(bool showIfEmpty)
{
m_console->showConsole(showIfEmpty);
}
void
CArch::writeConsole(const char* str)
{
@ -254,6 +260,12 @@ CArch::closeLog()
m_log->closeLog();
}
void
CArch::showLog(bool showIfEmpty)
{
m_log->showLog(showIfEmpty);
}
void
CArch::writeLog(ELevel level, const char* msg)
{
@ -488,6 +500,12 @@ CArch::setNoDelayOnSocket(CArchSocket s, bool noDelay)
return m_net->setNoDelayOnSocket(s, noDelay);
}
bool
CArch::setReuseAddrOnSocket(CArchSocket s, bool reuse)
{
return m_net->setReuseAddrOnSocket(s, reuse);
}
std::string
CArch::getHostName()
{

View File

@ -74,6 +74,7 @@ public:
// IArchConsole overrides
virtual void openConsole(const char*);
virtual void closeConsole();
virtual void showConsole(bool showIfEmpty);
virtual void writeConsole(const char*);
virtual const char* getNewlineForConsole();
@ -99,6 +100,7 @@ public:
// IArchLog overrides
virtual void openLog(const char*);
virtual void closeLog();
virtual void showLog(bool showIfEmpty);
virtual void writeLog(ELevel, const char*);
// IArchMultithread overrides
@ -143,6 +145,7 @@ public:
const void* buf, size_t len);
virtual void throwErrorOnSocket(CArchSocket);
virtual bool setNoDelayOnSocket(CArchSocket, bool noDelay);
virtual bool setReuseAddrOnSocket(CArchSocket, bool reuse);
virtual std::string getHostName();
virtual CArchNetAddress newAnyAddr(EAddressFamily);
virtual CArchNetAddress copyAddr(CArchNetAddress);

View File

@ -19,7 +19,7 @@
// CArchConsoleUnix
//
CArchConsoleUnix::CArchConsoleUnix()
CArchConsoleUnix::CArchConsoleUnix(void*)
{
// do nothing
}
@ -41,6 +41,12 @@ CArchConsoleUnix::closeConsole()
// do nothing
}
void
CArchConsoleUnix::showConsole(bool)
{
// do nothing
}
void
CArchConsoleUnix::writeConsole(const char* str)
{

View File

@ -22,12 +22,13 @@
//! Unix implementation of IArchConsole
class CArchConsoleUnix : public IArchConsole {
public:
CArchConsoleUnix();
CArchConsoleUnix(void*);
virtual ~CArchConsoleUnix();
// IArchConsole overrides
virtual void openConsole(const char* title);
virtual void closeConsole();
virtual void showConsole(bool);
virtual void writeConsole(const char*);
virtual const char* getNewlineForConsole();
};

View File

@ -15,90 +15,100 @@
#include "CArchConsoleWindows.h"
#include "IArchMultithread.h"
#include "CArch.h"
#include <cstdio>
#include "CArchMiscWindows.h"
#include <richedit.h>
#define SYNERGY_MSG_CONSOLE_OPEN WM_APP + 0x0021
#define SYNERGY_MSG_CONSOLE_CLOSE WM_APP + 0x0022
#define SYNERGY_MSG_CONSOLE_SHOW WM_APP + 0x0023
#define SYNERGY_MSG_CONSOLE_WRITE WM_APP + 0x0024
#define SYNERGY_MSG_CONSOLE_CLEAR WM_APP + 0x0025
//
// CArchConsoleWindows
//
CArchThread CArchConsoleWindows::s_thread = 0;
CArchConsoleWindows* CArchConsoleWindows::s_instance = NULL;
HINSTANCE CArchConsoleWindows::s_appInstance = NULL;
CArchConsoleWindows::CArchConsoleWindows() :
m_output(NULL)
CArchConsoleWindows::CArchConsoleWindows(void* appInstance) :
m_show(false),
m_maxLines(1000),
m_numCharacters(0),
m_maxCharacters(65536)
{
s_thread = ARCH->newCurrentThread();
// save the singleton instance
s_instance = this;
// save app instance
s_appInstance = reinterpret_cast<HINSTANCE>(appInstance);
// we need a mutex
m_mutex = ARCH->newMutex();
// dummy write to stderr to create locks in stdio from the main
// thread. if we open the console from another thread then we
// can deadlock in stdio when trying to write from a 3rd thread.
// writes to stderr without a console don't go anywhere so the
// user won't notice this.
fprintf(stderr, "\n");
// and a condition variable which uses the above mutex
m_ready = false;
m_condVar = ARCH->newCondVar();
// we're going to want to get a result from the thread we're
// about to create to know if it initialized successfully.
// so we lock the condition variable.
ARCH->lockMutex(m_mutex);
// open a window and run an event loop in a separate thread.
// this has to happen in a separate thread because if we
// create a window on the current desktop with the current
// thread then the current thread won't be able to switch
// desktops if it needs to.
m_thread = ARCH->newThread(&CArchConsoleWindows::threadEntry, this);
// wait for child thread
while (!m_ready) {
ARCH->waitCondVar(m_condVar, m_mutex, -1.0);
}
// ready
ARCH->unlockMutex(m_mutex);
}
CArchConsoleWindows::~CArchConsoleWindows()
{
if (m_thread != NULL) {
PostMessage(m_hwnd, WM_QUIT, 0, 0);
ARCH->wait(m_thread, -1.0);
ARCH->closeThread(m_thread);
}
ARCH->closeCondVar(m_condVar);
ARCH->closeMutex(m_mutex);
ARCH->closeThread(s_thread);
s_instance = NULL;
}
void
CArchConsoleWindows::openConsole(const char* title)
{
ARCH->lockMutex(m_mutex);
if (m_output == NULL) {
if (AllocConsole()) {
// get console output handle
m_output = GetStdHandle(STD_ERROR_HANDLE);
// set console title
if (title != NULL) {
SetConsoleTitle(title);
}
// prep console. windows 95 and its ilk have braindead
// consoles that can't even resize independently of the
// buffer size. use a 25 line buffer for those systems.
OSVERSIONINFO osInfo;
COORD size = { 80, 1000 };
osInfo.dwOSVersionInfoSize = sizeof(osInfo);
if (GetVersionEx(&osInfo) &&
osInfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
size.Y = 25;
SetConsoleScreenBufferSize(m_output, size);
SetConsoleTextAttribute(m_output,
FOREGROUND_RED |
FOREGROUND_GREEN |
FOREGROUND_BLUE);
// catch console signals
SetConsoleCtrlHandler(&CArchConsoleWindows::signalHandler, TRUE);
// reopen stderr to point at console
freopen("con", "w", stderr);
}
}
ARCH->unlockMutex(m_mutex);
SetWindowText(m_frame, title);
SendMessage(m_frame, SYNERGY_MSG_CONSOLE_OPEN, 0, 0);
}
void
CArchConsoleWindows::closeConsole()
{
ARCH->lockMutex(m_mutex);
if (m_output != NULL) {
if (FreeConsole()) {
m_output = NULL;
}
}
ARCH->unlockMutex(m_mutex);
SendMessage(m_frame, SYNERGY_MSG_CONSOLE_CLOSE, 0, 0);
SendMessage(m_frame, SYNERGY_MSG_CONSOLE_CLEAR, 0, 0);
}
void
CArchConsoleWindows::showConsole(bool showIfEmpty)
{
SendMessage(m_frame, SYNERGY_MSG_CONSOLE_SHOW, showIfEmpty ? 1 : 0, 0);
}
void
CArchConsoleWindows::writeConsole(const char* str)
{
fprintf(stderr, "%s", str);
SendMessage(m_frame, SYNERGY_MSG_CONSOLE_WRITE,
reinterpret_cast<WPARAM>(str), 0);
}
const char*
@ -107,21 +117,322 @@ CArchConsoleWindows::getNewlineForConsole()
return "\r\n";
}
BOOL WINAPI
CArchConsoleWindows::signalHandler(DWORD ctrlType)
void
CArchConsoleWindows::clearBuffer()
{
// terminate app and skip remaining handlers
switch (ctrlType) {
case CTRL_C_EVENT:
ARCH->raiseSignal(CArch::kINTERRUPT);
return TRUE;
m_buffer.clear();
m_numCharacters = 0;
SetWindowText(m_hwnd, "");
}
case CTRL_BREAK_EVENT:
ARCH->raiseSignal(CArch::kTERMINATE);
return TRUE;
void
CArchConsoleWindows::appendBuffer(const char* msg)
{
bool wasEmpty = m_buffer.empty();
default:
ARCH->raiseSignal(CArch::kINTERRUPT);
// get current selection
CHARRANGE selection;
SendMessage(m_hwnd, EM_EXGETSEL, 0, reinterpret_cast<LPARAM>(&selection));
// remove tail of buffer
size_t removedCharacters = 0;
while (m_buffer.size() >= m_maxLines) {
removedCharacters += m_buffer.front().size();
m_buffer.pop_front();
}
// remove lines from top of control
if (removedCharacters > 0) {
CHARRANGE range;
range.cpMin = 0;
range.cpMax = static_cast<LONG>(removedCharacters);
SendMessage(m_hwnd, EM_EXSETSEL, 0, reinterpret_cast<LPARAM>(&range));
SendMessage(m_hwnd, EM_REPLACESEL, FALSE, reinterpret_cast<LPARAM>(""));
// adjust selection
if (selection.cpMin < static_cast<LONG>(removedCharacters) ||
selection.cpMax < static_cast<LONG>(removedCharacters)) {
selection.cpMin = 0;
selection.cpMax = 0;
}
else {
selection.cpMin -= static_cast<LONG>(removedCharacters);
selection.cpMax -= static_cast<LONG>(removedCharacters);
}
m_numCharacters -= removedCharacters;
}
// append message
m_buffer.push_back(msg);
size_t newNumCharacters = m_numCharacters + m_buffer.back().size();
// add line to bottom of control
if (newNumCharacters > m_maxCharacters) {
m_maxCharacters = newNumCharacters;
SendMessage(m_hwnd, EM_EXLIMITTEXT, 0, m_maxCharacters);
}
CHARRANGE range;
range.cpMin = m_numCharacters;
range.cpMax = m_numCharacters;
SendMessage(m_hwnd, EM_EXSETSEL, 0, reinterpret_cast<LPARAM>(&range));
SendMessage(m_hwnd, EM_REPLACESEL, FALSE,
reinterpret_cast<LPARAM>(m_buffer.back().c_str()));
// adjust selection
bool atEnd = false;
if (selection.cpMax == static_cast<LONG>(m_numCharacters)) {
selection.cpMin = static_cast<LONG>(newNumCharacters);
selection.cpMax = static_cast<LONG>(newNumCharacters);
atEnd = true;
}
// restore the selection
SendMessage(m_hwnd, EM_EXSETSEL, 0, reinterpret_cast<LPARAM>(&selection));
if (atEnd) {
SendMessage(m_hwnd, EM_SCROLLCARET, 0, 0);
}
if (wasEmpty && m_show) {
ShowWindow(m_frame, TRUE);
}
m_numCharacters = newNumCharacters;
}
void
CArchConsoleWindows::setSize(int width, int height)
{
DWORD style = GetWindowLong(m_frame, GWL_STYLE);
DWORD exStyle = GetWindowLong(m_frame, GWL_EXSTYLE);
RECT rect;
rect.left = 100;
rect.top = 100;
rect.right = rect.left + width * m_wChar;
rect.bottom = rect.top + height * m_hChar;
AdjustWindowRectEx(&rect, style, FALSE, exStyle);
SetWindowPos(m_frame, NULL, 0, 0, rect.right - rect.left,
rect.bottom - rect.top,
SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOZORDER);
}
LRESULT
CArchConsoleWindows::wndProc(HWND hwnd,
UINT msg, WPARAM wParam, LPARAM lParam)
{
switch (msg) {
case WM_CLOSE:
ShowWindow(m_frame, FALSE);
m_show = false;
return 0;
case SYNERGY_MSG_CONSOLE_OPEN:
return 0;
case SYNERGY_MSG_CONSOLE_CLOSE:
SendMessage(m_frame, WM_CLOSE, 0, 0);
m_show = false;
return 0;
case SYNERGY_MSG_CONSOLE_SHOW:
m_show = true;
if (wParam != 0 || !m_buffer.empty()) {
ShowWindow(m_frame, TRUE);
}
return 0;
case SYNERGY_MSG_CONSOLE_WRITE:
appendBuffer(reinterpret_cast<const char*>(wParam));
return 0;
case SYNERGY_MSG_CONSOLE_CLEAR:
clearBuffer();
return 0;
case WM_SIZE:
if (hwnd == m_frame) {
MoveWindow(m_hwnd, 0, 0, LOWORD(lParam), HIWORD(lParam), TRUE);
}
break;
case WM_SIZING:
if (hwnd == m_frame) {
// get window vs client area info
int wBase = 40 * m_wChar;
int hBase = 40 * m_hChar;
DWORD style = GetWindowLong(m_frame, GWL_STYLE);
DWORD exStyle = GetWindowLong(m_frame, GWL_EXSTYLE);
RECT rect;
rect.left = 100;
rect.top = 100;
rect.right = rect.left + wBase;
rect.bottom = rect.top + hBase;
AdjustWindowRectEx(&rect, style, FALSE, exStyle);
wBase = rect.right - rect.left - wBase;
hBase = rect.bottom - rect.top - hBase;
// get closest size that's a multiple of the character size
RECT* newRect = (RECT*)lParam;
int width = (newRect->right - newRect->left - wBase) / m_wChar;
int height = (newRect->bottom - newRect->top - hBase) / m_hChar;
width = width * m_wChar + wBase;
height = height * m_hChar + hBase;
// adjust sizing rect
switch (wParam) {
case WMSZ_LEFT:
case WMSZ_TOPLEFT:
case WMSZ_BOTTOMLEFT:
newRect->left = newRect->right - width;
break;
case WMSZ_RIGHT:
case WMSZ_TOPRIGHT:
case WMSZ_BOTTOMRIGHT:
newRect->right = newRect->left + width;
break;
}
switch (wParam) {
case WMSZ_TOP:
case WMSZ_TOPLEFT:
case WMSZ_TOPRIGHT:
newRect->top = newRect->bottom - height;
break;
case WMSZ_BOTTOM:
case WMSZ_BOTTOMLEFT:
case WMSZ_BOTTOMRIGHT:
newRect->bottom = newRect->top + height;
break;
}
return TRUE;
}
break;
default:
break;
}
return DefWindowProc(hwnd, msg, wParam, lParam);
}
LRESULT CALLBACK
CArchConsoleWindows::staticWndProc(HWND hwnd, UINT msg,
WPARAM wParam, LPARAM lParam)
{
// forward the message
if (s_instance != NULL) {
return s_instance->wndProc(hwnd, msg, wParam, lParam);
}
else {
return DefWindowProc(hwnd, msg, wParam, lParam);
}
}
void
CArchConsoleWindows::threadMainLoop()
{
LoadLibrary("RICHED32.DLL");
// get the app icons
HICON largeIcon, smallIcon;
CArchMiscWindows::getIcons(largeIcon, smallIcon);
// register a window class
WNDCLASSEX classInfo;
classInfo.cbSize = sizeof(classInfo);
classInfo.style = 0;
classInfo.lpfnWndProc = &CArchConsoleWindows::staticWndProc;
classInfo.cbClsExtra = 0;
classInfo.cbWndExtra = sizeof(CArchConsoleWindows*);
classInfo.hInstance = s_appInstance;
classInfo.hIcon = largeIcon;
classInfo.hCursor = NULL;
classInfo.hbrBackground = NULL;
classInfo.lpszMenuName = NULL;
classInfo.lpszClassName = TEXT("SynergyConsole");
classInfo.hIconSm = smallIcon;
ATOM windowClass = RegisterClassEx(&classInfo);
// create frame window
m_frame = CreateWindowEx(0,
reinterpret_cast<LPCTSTR>(windowClass),
TEXT("Synergy Log"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT, 100, 100,
NULL,
NULL,
s_appInstance,
NULL);
// create log window
m_hwnd = CreateWindowEx(0,
"RichEdit",
TEXT(""),
WS_CHILD | WS_VISIBLE | WS_VSCROLL |
ES_MULTILINE | ES_READONLY,
0, 0, 1, 1,
m_frame,
(HMENU)1,
s_appInstance,
NULL);
// select font and get info
HDC hdc = GetDC(m_hwnd);
HGDIOBJ oldFont = SelectObject(hdc, GetStockObject(ANSI_FIXED_FONT));
TEXTMETRIC metrics;
GetTextMetrics(hdc, &metrics);
CHARFORMAT format;
format.cbSize = sizeof(format);
format.dwMask = CFM_CHARSET | CFM_COLOR | CFM_FACE |
CFM_OFFSET | CFM_SIZE | CFM_PROTECTED |
CFM_BOLD | CFM_ITALIC |
CFM_STRIKEOUT | CFM_UNDERLINE;
format.dwEffects = 0;
format.yHeight = metrics.tmHeight;
format.yOffset = 0;
format.crTextColor = RGB(0, 0, 0);
format.bCharSet = DEFAULT_CHARSET;
format.bPitchAndFamily = FIXED_PITCH | FF_MODERN;
GetTextFace(hdc, sizeof(format.szFaceName), format.szFaceName);
SelectObject(hdc, oldFont);
ReleaseDC(m_hwnd, hdc);
// prep window
SendMessage(m_hwnd, EM_EXLIMITTEXT, 0, m_maxCharacters);
SendMessage(m_hwnd, EM_SETCHARFORMAT, 0, reinterpret_cast<LPARAM>(&format));
SendMessage(m_hwnd, EM_SETBKGNDCOLOR, 0, RGB(255, 255, 255));
m_wChar = metrics.tmAveCharWidth;
m_hChar = metrics.tmHeight + metrics.tmExternalLeading;
setSize(80, 25);
// signal ready
ARCH->lockMutex(m_mutex);
m_ready = true;
ARCH->broadcastCondVar(m_condVar);
ARCH->unlockMutex(m_mutex);
// handle failure
if (m_hwnd == NULL) {
UnregisterClass(reinterpret_cast<LPCTSTR>(windowClass), s_appInstance);
return;
}
// main loop
MSG msg;
while (GetMessage(&msg, NULL, 0, 0)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
// clean up
DestroyWindow(m_hwnd);
UnregisterClass(reinterpret_cast<LPCTSTR>(windowClass), s_appInstance);
}
void*
CArchConsoleWindows::threadEntry(void* self)
{
reinterpret_cast<CArchConsoleWindows*>(self)->threadMainLoop();
return NULL;
}

View File

@ -19,6 +19,7 @@
#include "IArchConsole.h"
#include "IArchMultithread.h"
#include "stddeque.h"
#include <windows.h>
#define ARCH_CONSOLE CArchConsoleWindows
@ -26,23 +27,51 @@
//! Win32 implementation of IArchConsole
class CArchConsoleWindows : public IArchConsole {
public:
CArchConsoleWindows();
CArchConsoleWindows(void*);
virtual ~CArchConsoleWindows();
// IArchConsole overrides
virtual void openConsole(const char* title);
virtual void closeConsole();
virtual void showConsole(bool showIfEmpty);
virtual void writeConsole(const char*);
virtual const char* getNewlineForConsole();
private:
static BOOL WINAPI signalHandler(DWORD);
void clearBuffer();
void appendBuffer(const char*);
void setSize(int width, int height);
LRESULT wndProc(HWND, UINT, WPARAM, LPARAM);
static LRESULT CALLBACK
staticWndProc(HWND, UINT, WPARAM, LPARAM);
void threadMainLoop();
static void* threadEntry(void*);
private:
static CArchThread s_thread;
typedef std::deque<std::string> MessageBuffer;
static CArchConsoleWindows* s_instance;
static HINSTANCE s_appInstance;
// multithread data
CArchMutex m_mutex;
HANDLE m_output;
CArchCond m_condVar;
bool m_ready;
CArchThread m_thread;
// child thread data
HWND m_frame;
HWND m_hwnd;
LONG m_wChar;
LONG m_hChar;
bool m_show;
// messages
size_t m_maxLines;
size_t m_maxCharacters;
size_t m_numCharacters;
MessageBuffer m_buffer;
};
#endif

View File

@ -136,11 +136,12 @@ CArchDaemonWindows::installDaemon(const char* name,
NULL);
if (service == NULL) {
// can't create service
// FIXME -- handle ERROR_SERVICE_EXISTS
DWORD err = GetLastError();
if (err != ERROR_SERVICE_EXISTS) {
CloseServiceHandle(mgr);
throw XArchDaemonInstallFailed(new XArchEvalWindows(err));
}
}
// done with service and manager
CloseServiceHandle(service);
@ -148,7 +149,7 @@ CArchDaemonWindows::installDaemon(const char* name,
// open the registry key for this service
HKEY key = openNTServicesKey();
key = CArchMiscWindows::openKey(key, name);
key = CArchMiscWindows::addKey(key, name);
if (key == NULL) {
// can't open key
DWORD err = GetLastError();
@ -165,7 +166,7 @@ CArchDaemonWindows::installDaemon(const char* name,
CArchMiscWindows::setValue(key, _T("Description"), description);
// set command line
key = CArchMiscWindows::openKey(key, _T("Parameters"));
key = CArchMiscWindows::addKey(key, _T("Parameters"));
if (key == NULL) {
// can't open key
DWORD err = GetLastError();
@ -224,7 +225,7 @@ CArchDaemonWindows::uninstallDaemon(const char* name, bool allUsers)
}
// open the service. oddly, you must open a service to delete it.
SC_HANDLE service = OpenService(mgr, name, DELETE);
SC_HANDLE service = OpenService(mgr, name, DELETE | SERVICE_STOP);
if (service == NULL) {
DWORD err = GetLastError();
CloseServiceHandle(mgr);
@ -234,6 +235,10 @@ CArchDaemonWindows::uninstallDaemon(const char* name, bool allUsers)
throw XArchDaemonUninstallNotInstalled(new XArchEvalWindows(err));
}
// stop the service. we don't care if we fail.
SERVICE_STATUS status;
ControlService(service, SERVICE_CONTROL_STOP, &status);
// delete the service
const bool okay = (DeleteService(service) == 0);
const DWORD err = GetLastError();
@ -244,6 +249,10 @@ CArchDaemonWindows::uninstallDaemon(const char* name, bool allUsers)
// handle failure. ignore error if service isn't installed anymore.
if (!okay && isDaemonInstalled(name, allUsers)) {
if (err == ERROR_IO_PENDING) {
// this seems to be a spurious error
return;
}
if (err != ERROR_SERVICE_MARKED_FOR_DELETE) {
throw XArchDaemonUninstallFailed(new XArchEvalWindows(err));
}
@ -317,7 +326,7 @@ CArchDaemonWindows::daemonize(const char* name, DaemonFunc func)
}
bool
CArchDaemonWindows::canInstallDaemon(const char* name, bool allUsers)
CArchDaemonWindows::canInstallDaemon(const char* /*name*/, bool allUsers)
{
// if not for all users then use the user's autostart registry.
// key. if windows 95 family then use windows 95 services key.
@ -338,10 +347,10 @@ CArchDaemonWindows::canInstallDaemon(const char* name, bool allUsers)
}
CloseServiceHandle(mgr);
// check if we can open the registry key for this service
// check if we can open the registry key
HKEY key = openNTServicesKey();
key = CArchMiscWindows::openKey(key, name);
key = CArchMiscWindows::openKey(key, _T("Parameters"));
// key = CArchMiscWindows::addKey(key, name);
// key = CArchMiscWindows::addKey(key, _T("Parameters"));
CArchMiscWindows::closeKey(key);
return (key != NULL);
@ -415,7 +424,7 @@ CArchDaemonWindows::openNTServicesKey()
NULL
};
return CArchMiscWindows::openKey(HKEY_LOCAL_MACHINE, s_keyNames);
return CArchMiscWindows::addKey(HKEY_LOCAL_MACHINE, s_keyNames);
}
HKEY
@ -430,7 +439,7 @@ CArchDaemonWindows::open95ServicesKey()
NULL
};
return CArchMiscWindows::openKey(HKEY_LOCAL_MACHINE, s_keyNames);
return CArchMiscWindows::addKey(HKEY_LOCAL_MACHINE, s_keyNames);
}
HKEY
@ -445,7 +454,7 @@ CArchDaemonWindows::openUserStartupKey()
NULL
};
return CArchMiscWindows::openKey(HKEY_CURRENT_USER, s_keyNames);
return CArchMiscWindows::addKey(HKEY_CURRENT_USER, s_keyNames);
}
bool

View File

@ -41,6 +41,12 @@ CArchLogUnix::closeLog()
closelog();
}
void
CArchLogUnix::showLog(bool)
{
// do nothing
}
void
CArchLogUnix::writeLog(ELevel level, const char* msg)
{

View File

@ -28,6 +28,7 @@ public:
// IArchLog overrides
virtual void openLog(const char* name);
virtual void closeLog();
virtual void showLog(bool);
virtual void writeLog(ELevel, const char*);
};

View File

@ -47,6 +47,12 @@ CArchLogWindows::closeLog()
}
}
void
CArchLogWindows::showLog(bool)
{
// do nothing
}
void
CArchLogWindows::writeLog(ELevel level, const char* msg)
{

View File

@ -31,6 +31,7 @@ public:
// IArchLog overrides
virtual void openLog(const char* name);
virtual void closeLog();
virtual void showLog(bool showIfEmpty);
virtual void writeLog(ELevel, const char*);
private:

View File

@ -33,6 +33,8 @@ typedef DWORD EXECUTION_STATE;
CArchMiscWindows::CDialogs* CArchMiscWindows::s_dialogs = NULL;
DWORD CArchMiscWindows::s_busyState = 0;
CArchMiscWindows::STES_t CArchMiscWindows::s_stes = NULL;
HICON CArchMiscWindows::s_largeIcon = NULL;
HICON CArchMiscWindows::s_smallIcon = NULL;
void
CArchMiscWindows::init()
@ -87,6 +89,20 @@ CArchMiscWindows::isWindowsModern()
return result;
}
void
CArchMiscWindows::setIcons(HICON largeIcon, HICON smallIcon)
{
s_largeIcon = largeIcon;
s_smallIcon = smallIcon;
}
void
CArchMiscWindows::getIcons(HICON& largeIcon, HICON& smallIcon)
{
largeIcon = s_largeIcon;
smallIcon = s_smallIcon;
}
int
CArchMiscWindows::runDaemon(RunFunc runFunc)
{
@ -113,6 +129,30 @@ CArchMiscWindows::getDaemonQuitMessage()
HKEY
CArchMiscWindows::openKey(HKEY key, const TCHAR* keyName)
{
return openKey(key, keyName, false);
}
HKEY
CArchMiscWindows::openKey(HKEY key, const TCHAR* const* keyNames)
{
return openKey(key, keyNames, false);
}
HKEY
CArchMiscWindows::addKey(HKEY key, const TCHAR* keyName)
{
return openKey(key, keyName, true);
}
HKEY
CArchMiscWindows::addKey(HKEY key, const TCHAR* const* keyNames)
{
return openKey(key, keyNames, true);
}
HKEY
CArchMiscWindows::openKey(HKEY key, const TCHAR* keyName, bool create)
{
// ignore if parent is NULL
if (key == NULL) {
@ -123,7 +163,7 @@ CArchMiscWindows::openKey(HKEY key, const TCHAR* keyName)
HKEY newKey;
LONG result = RegOpenKeyEx(key, keyName, 0,
KEY_WRITE | KEY_QUERY_VALUE, &newKey);
if (result != ERROR_SUCCESS) {
if (result != ERROR_SUCCESS && create) {
DWORD disp;
result = RegCreateKeyEx(key, keyName, 0, TEXT(""),
0, KEY_WRITE | KEY_QUERY_VALUE,
@ -140,11 +180,11 @@ CArchMiscWindows::openKey(HKEY key, const TCHAR* keyName)
}
HKEY
CArchMiscWindows::openKey(HKEY key, const TCHAR* const* keyNames)
CArchMiscWindows::openKey(HKEY key, const TCHAR* const* keyNames, bool create)
{
for (size_t i = 0; key != NULL && keyNames[i] != NULL; ++i) {
// open next key
key = openKey(key, keyNames[i]);
key = openKey(key, keyNames[i], create);
}
return key;
}

View File

@ -56,6 +56,18 @@ public:
*/
static bool isWindowsModern();
//! Set the application icons
/*!
Set the application icons.
*/
static void setIcons(HICON largeIcon, HICON smallIcon);
//! Get the application icons
/*!
Get the application icons.
*/
static void getIcons(HICON& largeIcon, HICON& smallIcon);
//! Run the daemon
/*!
Delegates to CArchDaemonWindows.
@ -86,6 +98,12 @@ public:
//! Open and return a registry key, closing the parent key
static HKEY openKey(HKEY parent, const TCHAR* const* keyPath);
//! Open/create and return a registry key, closing the parent key
static HKEY addKey(HKEY parent, const TCHAR* child);
//! Open/create and return a registry key, closing the parent key
static HKEY addKey(HKEY parent, const TCHAR* const* keyPath);
//! Close a key
static void closeKey(HKEY);
@ -144,6 +162,13 @@ public:
static void removeBusyState(DWORD busyModes);
private:
//! Open and return a registry key, closing the parent key
static HKEY openKey(HKEY parent, const TCHAR* child, bool create);
//! Open and return a registry key, closing the parent key
static HKEY openKey(HKEY parent, const TCHAR* const* keyPath,
bool create);
//! Read a string value from the registry
static std::string readBinaryOrString(HKEY, const TCHAR* name, DWORD type);
@ -159,6 +184,8 @@ private:
static CDialogs* s_dialogs;
static DWORD s_busyState;
static STES_t s_stes;
static HICON s_largeIcon;
static HICON s_smallIcon;
};
#endif

View File

@ -49,6 +49,7 @@ setSignalSet(sigset_t* sigset)
sigaddset(sigset, SIGHUP);
sigaddset(sigset, SIGINT);
sigaddset(sigset, SIGTERM);
sigaddset(sigset, SIGUSR2);
}
//
@ -771,7 +772,7 @@ CArchMultithreadPosix::threadSignalHandler(void*)
for (;;) {
// wait
#if HAVE_POSIX_SIGWAIT
int signal;
int signal = 0;
sigwait(&sigset, &signal);
#else
sigwait(&sigset);
@ -791,6 +792,10 @@ CArchMultithreadPosix::threadSignalHandler(void*)
ARCH->raiseSignal(kHANGUP);
break;
case SIGUSR2:
ARCH->raiseSignal(kUSER);
break;
default:
// ignore
break;

View File

@ -31,9 +31,6 @@
#if HAVE_POLL
# include <poll.h>
# if HAVE_ALLOCA_H
# include <alloca.h>
# endif
#else
# if HAVE_SYS_SELECT_H
# include <sys/select.h>
@ -47,13 +44,6 @@
# include <stdio.h>
#endif
#if HAVE_ALLOCA_H
# define freea(x_)
#else
# define alloca(x_) malloc(x_)
# define freea(x_) free(x_)
#endif
static const int s_family[] = {
PF_UNSPEC,
PF_INET
@ -291,8 +281,7 @@ CArchNetworkBSD::pollSocket(CPollEntry pe[], int num, double timeout)
}
// allocate space for translated query
struct pollfd* pfd = reinterpret_cast<struct pollfd*>(
alloca((1 + num) * sizeof(struct pollfd)));
struct pollfd* pfd = new struct pollfd[1 + num];
// translate query
for (int i = 0; i < num; ++i) {
@ -322,7 +311,7 @@ CArchNetworkBSD::pollSocket(CPollEntry pe[], int num, double timeout)
n = poll(pfd, n, t);
// reset the unblock pipe
if (unblockPipe != NULL && (pfd[num].revents & POLLIN) != 0) {
if (n > 0 && unblockPipe != NULL && (pfd[num].revents & POLLIN) != 0) {
// the unblock event was signalled. flush the pipe.
char dummy[100];
do {
@ -338,10 +327,10 @@ CArchNetworkBSD::pollSocket(CPollEntry pe[], int num, double timeout)
if (errno == EINTR) {
// interrupted system call
ARCH->testCancelThread();
freea(pfd);
delete[] pfd;
return 0;
}
freea(pfd);
delete[] pfd;
throwError(errno);
}
@ -362,7 +351,7 @@ CArchNetworkBSD::pollSocket(CPollEntry pe[], int num, double timeout)
}
}
freea(pfd);
delete[] pfd;
return n;
}
@ -452,7 +441,7 @@ CArchNetworkBSD::pollSocket(CPollEntry pe[], int num, double timeout)
SELECT_TYPE_ARG5 timeout2P);
// reset the unblock pipe
if (unblockPipe != NULL && FD_ISSET(unblockPipe[0], &readSet)) {
if (n > 0 && unblockPipe != NULL && FD_ISSET(unblockPipe[0], &readSet)) {
// the unblock event was signalled. flush the pipe.
char dummy[100];
do {
@ -594,6 +583,29 @@ CArchNetworkBSD::setNoDelayOnSocket(CArchSocket s, bool noDelay)
return (oflag != 0);
}
bool
CArchNetworkBSD::setReuseAddrOnSocket(CArchSocket s, bool reuse)
{
assert(s != NULL);
// get old state
int oflag;
socklen_t size = sizeof(oflag);
if (getsockopt(s->m_fd, SOL_SOCKET, SO_REUSEADDR,
(optval_t*)&oflag, &size) == -1) {
throwError(errno);
}
int flag = reuse ? 1 : 0;
size = sizeof(flag);
if (setsockopt(s->m_fd, SOL_SOCKET, SO_REUSEADDR,
(optval_t*)&flag, size) == -1) {
throwError(errno);
}
return (oflag != 0);
}
std::string
CArchNetworkBSD::getHostName()
{

View File

@ -73,6 +73,7 @@ public:
const void* buf, size_t len);
virtual void throwErrorOnSocket(CArchSocket);
virtual bool setNoDelayOnSocket(CArchSocket, bool noDelay);
virtual bool setReuseAddrOnSocket(CArchSocket, bool reuse);
virtual std::string getHostName();
virtual CArchNetAddress newAnyAddr(EAddressFamily);
virtual CArchNetAddress copyAddr(CArchNetAddress);

View File

@ -612,6 +612,30 @@ CArchNetworkWinsock::setNoDelayOnSocket(CArchSocket s, bool noDelay)
return (oflag != 0);
}
bool
CArchNetworkWinsock::setReuseAddrOnSocket(CArchSocket s, bool reuse)
{
assert(s != NULL);
// get old state
BOOL oflag;
int size = sizeof(oflag);
if (getsockopt_winsock(s->m_socket, SOL_SOCKET,
SO_REUSEADDR, &oflag, &size) == SOCKET_ERROR) {
throwError(getsockerror_winsock());
}
// set new state
BOOL flag = reuse ? 1 : 0;
size = sizeof(flag);
if (setsockopt_winsock(s->m_socket, SOL_SOCKET,
SO_REUSEADDR, &flag, size) == SOCKET_ERROR) {
throwError(getsockerror_winsock());
}
return (oflag != 0);
}
std::string
CArchNetworkWinsock::getHostName()
{

View File

@ -70,6 +70,7 @@ public:
const void* buf, size_t len);
virtual void throwErrorOnSocket(CArchSocket);
virtual bool setNoDelayOnSocket(CArchSocket, bool noDelay);
virtual bool setReuseAddrOnSocket(CArchSocket, bool reuse);
virtual std::string getHostName();
virtual CArchNetAddress newAnyAddr(EAddressFamily);
virtual CArchNetAddress copyAddr(CArchNetAddress);

View File

@ -19,6 +19,9 @@
#include "CArch.h"
#include <limits.h>
#include <string.h>
#if HAVE_LOCALE_H
# include <locale.h>
#endif
#if HAVE_WCHAR_H || defined(_MSC_VER)
# include <wchar.h>
#elif __APPLE__
@ -56,6 +59,15 @@ static CArchMutex s_mutex = NULL;
ARCH_STRING::ARCH_STRING()
{
s_mutex = ARCH->newMutex();
#if HAVE_LOCALE_H
// see if we can convert a Latin-1 character
char mb[MB_LEN_MAX];
if (wctomb(mb, 0xe3) == -1) {
// can't convert. try another locale so we can convert latin-1.
setlocale(LC_CTYPE, "en_US");
}
#endif
}
ARCH_STRING::~ARCH_STRING()

View File

@ -43,6 +43,15 @@ public:
*/
virtual void closeConsole() = 0;
//! Show the console
/*!
Causes the console to become visible. This generally only makes sense
for a console in a graphical user interface. Other implementations
will do nothing. Iff \p showIfEmpty is \c false then the implementation
may optionally only show the console if it's not empty.
*/
virtual void showConsole(bool showIfEmpty) = 0;
//! Write to the console
/*!
Writes the given string to the console, opening it if necessary.

View File

@ -52,6 +52,15 @@ public:
*/
virtual void closeLog() = 0;
//! Show the log
/*!
Causes the log to become visible. This generally only makes sense
for a log in a graphical user interface. Other implementations
will do nothing. Iff \p showIfEmpty is \c false then the implementation
may optionally only show the log if it's not empty.
*/
virtual void showLog(bool showIfEmpty) = 0;
//! Write to the log
/*!
Writes the given string to the log with the given level.

View File

@ -80,6 +80,7 @@ public:
kINTERRUPT, //!< Interrupt (e.g. Ctrl+C)
kTERMINATE, //!< Terminate (e.g. Ctrl+Break)
kHANGUP, //!< Hangup (SIGHUP)
kUSER, //!< User (SIGUSR2)
kNUM_SIGNALS
};
//! Type of signal handler function

View File

@ -226,6 +226,13 @@ public:
*/
virtual bool setNoDelayOnSocket(CArchSocket, bool noDelay) = 0;
//! Turn address reuse on or off on socket
/*!
Allows the address this socket is bound to to be reused while in the
TIME_WAIT state. Returns the previous state.
*/
virtual bool setReuseAddrOnSocket(CArchSocket, bool reuse) = 0;
//! Return local host's name
virtual std::string getHostName() = 0;

View File

@ -41,7 +41,7 @@ RSC=rc.exe
# PROP Intermediate_Dir "..\..\gen\build"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c
# ADD CPP /nologo /MT /W4 /GX /O2 /I "..\common" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /Fd"..\..\gen\build\arch.pdb" /FD /c
# ADD CPP /nologo /MT /W4 /GR /GX /O2 /I "..\common" /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /Fd"..\..\gen\build\arch.pdb" /FD /c
# SUBTRACT CPP /YX
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
@ -65,7 +65,7 @@ LIB32=link.exe -lib
# PROP Intermediate_Dir "..\..\gen\debug"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c
# ADD CPP /nologo /MTd /W4 /Gm /GX /ZI /Od /I "..\base" /I "..\mt" /I "..\common" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /Fd"..\..\gen\debug\arch.pdb" /FD /GZ /c
# ADD CPP /nologo /MTd /W4 /Gm /GR /GX /ZI /Od /I "..\base" /I "..\mt" /I "..\common" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /Fd"..\..\gen\debug\arch.pdb" /FD /GZ /c
# SUBTRACT CPP /YX
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"

View File

@ -22,15 +22,17 @@
CEvent::CEvent() :
m_type(kUnknown),
m_target(NULL),
m_data(NULL)
m_data(NULL),
m_flags(0)
{
// do nothing
}
CEvent::CEvent(Type type, void* target, void* data) :
CEvent::CEvent(Type type, void* target, void* data, Flags flags) :
m_type(type),
m_target(target),
m_data(data)
m_data(data),
m_flags(flags)
{
// do nothing
}
@ -53,6 +55,12 @@ CEvent::getData() const
return m_data;
}
CEvent::Flags
CEvent::getFlags() const
{
return m_flags;
}
CEvent::Type
CEvent::registerType(const char* name)
{
@ -82,7 +90,9 @@ CEvent::deleteData(const CEvent& event)
break;
default:
if ((event.getFlags() & kDontFreeData) == 0) {
free(event.getData());
}
break;
}
}

View File

@ -33,6 +33,13 @@ public:
kLast //!< Must be last
};
typedef UInt32 Flags;
enum {
kNone = 0x00, //!< No flags
kDeliverImmediately = 0x01, //!< Dispatch and free event immediately
kDontFreeData = 0x02 //!< Don't free data in deleteData
};
CEvent();
//! Create \c CEvent with data
@ -41,9 +48,10 @@ public:
The \p data must be POD (plain old data) allocated by malloc(),
which means it cannot have a constructor, destructor or be
composed of any types that do. \p target is the intended
recipient of the event.
recipient of the event. \p flags is any combination of \c Flags.
*/
CEvent(Type type, void* target = NULL, void* data = NULL);
CEvent(Type type, void* target = NULL, void* data = NULL,
UInt32 flags = kNone);
//! @name manipulators
//@{
@ -97,12 +105,19 @@ public:
*/
void* getData() const;
//! Get event flags
/*!
Returns the event flags.
*/
Flags getFlags() const;
//@}
private:
Type m_type;
void* m_target;
void* m_data;
Flags m_flags;
};
#endif

View File

@ -207,6 +207,11 @@ CEventQueue::addEvent(const CEvent& event)
break;
}
if ((event.getFlags() & CEvent::kDeliverImmediately) != 0) {
dispatchEvent(event);
CEvent::deleteData(event);
}
else {
CArchMutexLock lock(m_mutex);
// store the event's data locally
@ -218,6 +223,7 @@ CEventQueue::addEvent(const CEvent& event)
removeEvent(eventID);
CEvent::deleteData(event);
}
}
}
CEventQueueTimer*

Some files were not shown because too many files have changed in this diff Show More