Initial commit of the synergy trunk sources from sf.net
27
cmd/Makefile.am
Normal file
@@ -0,0 +1,27 @@
|
||||
# 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.
|
||||
|
||||
## Process this file with automake to produce Makefile.in
|
||||
NULL =
|
||||
|
||||
SUBDIRS = \
|
||||
launcher \
|
||||
synergyc \
|
||||
synergys \
|
||||
$(NULL)
|
||||
|
||||
EXTRA_DIST = \
|
||||
$(NULL)
|
||||
|
||||
MAINTAINERCLEANFILES = \
|
||||
Makefile.in \
|
||||
$(NULL)
|
||||
427
cmd/launcher/CAddScreen.cpp
Normal 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)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
@@ -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
|
||||
269
cmd/launcher/CAdvancedOptions.cpp
Normal file
@@ -0,0 +1,269 @@
|
||||
/*
|
||||
* 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 "CArchMiscWindows.h"
|
||||
#include "CAdvancedOptions.h"
|
||||
#include "LaunchUtil.h"
|
||||
#include "XArch.h"
|
||||
#include "resource.h"
|
||||
|
||||
//
|
||||
// CAdvancedOptions
|
||||
//
|
||||
|
||||
CAdvancedOptions* CAdvancedOptions::s_singleton = NULL;
|
||||
|
||||
CAdvancedOptions::CAdvancedOptions(HWND parent, CConfig* config) :
|
||||
m_parent(parent),
|
||||
m_config(config),
|
||||
m_isClient(false),
|
||||
m_screenName(ARCH->getHostName()),
|
||||
m_port(kDefaultPort),
|
||||
m_interface()
|
||||
{
|
||||
assert(s_singleton == NULL);
|
||||
s_singleton = this;
|
||||
init();
|
||||
}
|
||||
|
||||
CAdvancedOptions::~CAdvancedOptions()
|
||||
{
|
||||
s_singleton = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
CAdvancedOptions::doModal(bool isClient)
|
||||
{
|
||||
// save state
|
||||
m_isClient = isClient;
|
||||
|
||||
// do dialog
|
||||
DialogBoxParam(s_instance, MAKEINTRESOURCE(IDD_ADVANCED_OPTIONS),
|
||||
m_parent, (DLGPROC)dlgProc, (LPARAM)this);
|
||||
}
|
||||
|
||||
CString
|
||||
CAdvancedOptions::getScreenName() const
|
||||
{
|
||||
return m_screenName;
|
||||
}
|
||||
|
||||
int
|
||||
CAdvancedOptions::getPort() const
|
||||
{
|
||||
return m_port;
|
||||
}
|
||||
|
||||
CString
|
||||
CAdvancedOptions::getInterface() const
|
||||
{
|
||||
return m_interface;
|
||||
}
|
||||
|
||||
CString
|
||||
CAdvancedOptions::getCommandLine(bool isClient, const CString& serverName) const
|
||||
{
|
||||
CString cmdLine;
|
||||
|
||||
// screen name
|
||||
if (!m_screenName.empty()) {
|
||||
cmdLine += " --name ";
|
||||
cmdLine += m_screenName;
|
||||
}
|
||||
|
||||
// port
|
||||
char portString[20];
|
||||
sprintf(portString, "%d", m_port);
|
||||
if (isClient) {
|
||||
cmdLine += " ";
|
||||
cmdLine += serverName;
|
||||
cmdLine += ":";
|
||||
cmdLine += portString;
|
||||
}
|
||||
else {
|
||||
cmdLine += " --address ";
|
||||
if (!m_interface.empty()) {
|
||||
cmdLine += m_interface;
|
||||
}
|
||||
cmdLine += ":";
|
||||
cmdLine += portString;
|
||||
}
|
||||
|
||||
return cmdLine;
|
||||
}
|
||||
|
||||
void
|
||||
CAdvancedOptions::init()
|
||||
{
|
||||
// get values from registry
|
||||
HKEY key = CArchMiscWindows::openKey(HKEY_CURRENT_USER, getSettingsPath());
|
||||
if (key != NULL) {
|
||||
DWORD newPort = CArchMiscWindows::readValueInt(key, "port");
|
||||
CString newName = CArchMiscWindows::readValueString(key, "name");
|
||||
CString newInterface =
|
||||
CArchMiscWindows::readValueString(key, "interface");
|
||||
if (newPort != 0) {
|
||||
m_port = static_cast<int>(newPort);
|
||||
}
|
||||
if (!newName.empty()) {
|
||||
m_screenName = newName;
|
||||
}
|
||||
if (!newInterface.empty()) {
|
||||
m_interface = newInterface;
|
||||
}
|
||||
CArchMiscWindows::closeKey(key);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CAdvancedOptions::doInit(HWND hwnd)
|
||||
{
|
||||
// set values in GUI
|
||||
HWND child;
|
||||
char buffer[20];
|
||||
sprintf(buffer, "%d", m_port);
|
||||
child = getItem(hwnd, IDC_ADVANCED_PORT_EDIT);
|
||||
SendMessage(child, WM_SETTEXT, 0, (LPARAM)buffer);
|
||||
|
||||
child = getItem(hwnd, IDC_ADVANCED_NAME_EDIT);
|
||||
SendMessage(child, WM_SETTEXT, 0, (LPARAM)m_screenName.c_str());
|
||||
|
||||
child = getItem(hwnd, IDC_ADVANCED_INTERFACE_EDIT);
|
||||
SendMessage(child, WM_SETTEXT, 0, (LPARAM)m_interface.c_str());
|
||||
}
|
||||
|
||||
bool
|
||||
CAdvancedOptions::save(HWND hwnd)
|
||||
{
|
||||
SetCursor(LoadCursor(NULL, IDC_WAIT));
|
||||
|
||||
HWND child = getItem(hwnd, IDC_ADVANCED_NAME_EDIT);
|
||||
CString name = getWindowText(child);
|
||||
if (!m_config->isValidScreenName(name)) {
|
||||
showError(hwnd, CStringUtil::format(
|
||||
getString(IDS_INVALID_SCREEN_NAME).c_str(),
|
||||
name.c_str()));
|
||||
SetFocus(child);
|
||||
return false;
|
||||
}
|
||||
if (!m_isClient && !m_config->isScreen(name)) {
|
||||
showError(hwnd, CStringUtil::format(
|
||||
getString(IDS_UNKNOWN_SCREEN_NAME).c_str(),
|
||||
name.c_str()));
|
||||
SetFocus(child);
|
||||
return false;
|
||||
}
|
||||
|
||||
child = getItem(hwnd, IDC_ADVANCED_INTERFACE_EDIT);
|
||||
CString iface = getWindowText(child);
|
||||
if (!m_isClient) {
|
||||
try {
|
||||
if (!iface.empty()) {
|
||||
ARCH->nameToAddr(iface);
|
||||
}
|
||||
}
|
||||
catch (XArchNetworkName& e) {
|
||||
showError(hwnd, CStringUtil::format(
|
||||
getString(IDS_INVALID_INTERFACE_NAME).c_str(),
|
||||
iface.c_str(), e.what().c_str()));
|
||||
SetFocus(child);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// get and verify port
|
||||
child = getItem(hwnd, IDC_ADVANCED_PORT_EDIT);
|
||||
CString portString = getWindowText(child);
|
||||
int port = atoi(portString.c_str());
|
||||
if (port < 1 || port > 65535) {
|
||||
CString defaultPortString = CStringUtil::print("%d", kDefaultPort);
|
||||
showError(hwnd, CStringUtil::format(
|
||||
getString(IDS_INVALID_PORT).c_str(),
|
||||
portString.c_str(),
|
||||
defaultPortString.c_str()));
|
||||
SetFocus(child);
|
||||
return false;
|
||||
}
|
||||
|
||||
// save state
|
||||
m_screenName = name;
|
||||
m_port = port;
|
||||
m_interface = iface;
|
||||
|
||||
// save values to registry
|
||||
HKEY key = CArchMiscWindows::addKey(HKEY_CURRENT_USER, getSettingsPath());
|
||||
if (key != NULL) {
|
||||
CArchMiscWindows::setValue(key, "port", m_port);
|
||||
CArchMiscWindows::setValue(key, "name", m_screenName);
|
||||
CArchMiscWindows::setValue(key, "interface", m_interface);
|
||||
CArchMiscWindows::closeKey(key);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
CAdvancedOptions::setDefaults(HWND hwnd)
|
||||
{
|
||||
// restore defaults
|
||||
m_screenName = ARCH->getHostName();
|
||||
m_port = kDefaultPort;
|
||||
m_interface = "";
|
||||
|
||||
// update GUI
|
||||
doInit(hwnd);
|
||||
}
|
||||
|
||||
BOOL
|
||||
CAdvancedOptions::doDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM)
|
||||
{
|
||||
switch (message) {
|
||||
case WM_INITDIALOG:
|
||||
doInit(hwnd);
|
||||
return TRUE;
|
||||
|
||||
case WM_COMMAND:
|
||||
switch (LOWORD(wParam)) {
|
||||
case IDOK:
|
||||
if (save(hwnd)) {
|
||||
EndDialog(hwnd, 0);
|
||||
}
|
||||
return TRUE;
|
||||
|
||||
case IDCANCEL:
|
||||
EndDialog(hwnd, 0);
|
||||
return TRUE;
|
||||
|
||||
case IDC_ADVANCED_DEFAULTS:
|
||||
setDefaults(hwnd);
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL CALLBACK
|
||||
CAdvancedOptions::dlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
return s_singleton->doDlgProc(hwnd, message, wParam, lParam);
|
||||
}
|
||||
80
cmd/launcher/CAdvancedOptions.h
Normal file
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* 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 CADVANCEDOPTIONS_H
|
||||
#define CADVANCEDOPTIONS_H
|
||||
|
||||
#include "CString.h"
|
||||
|
||||
#define WINDOWS_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
class CConfig;
|
||||
|
||||
//! Advanced options dialog for Microsoft Windows launcher
|
||||
class CAdvancedOptions {
|
||||
public:
|
||||
CAdvancedOptions(HWND parent, CConfig*);
|
||||
~CAdvancedOptions();
|
||||
|
||||
//! @name manipulators
|
||||
//@{
|
||||
|
||||
//! Run dialog
|
||||
/*!
|
||||
Display and handle the dialog until closed by the user.
|
||||
*/
|
||||
void doModal(bool isClient);
|
||||
|
||||
//@}
|
||||
//! @name accessors
|
||||
//@{
|
||||
|
||||
//! Get the screen name
|
||||
CString getScreenName() const;
|
||||
|
||||
//! Get the port
|
||||
int getPort() const;
|
||||
|
||||
//! Get the interface
|
||||
CString getInterface() const;
|
||||
|
||||
//! Convert options to command line string
|
||||
CString getCommandLine(bool isClient,
|
||||
const CString& serverName) const;
|
||||
|
||||
//@}
|
||||
|
||||
private:
|
||||
void init();
|
||||
void doInit(HWND hwnd);
|
||||
bool save(HWND hwnd);
|
||||
void setDefaults(HWND hwnd);
|
||||
|
||||
// message handling
|
||||
BOOL doDlgProc(HWND, UINT, WPARAM, LPARAM);
|
||||
static BOOL CALLBACK dlgProc(HWND, UINT, WPARAM, LPARAM);
|
||||
|
||||
private:
|
||||
static CAdvancedOptions* s_singleton;
|
||||
|
||||
HWND m_parent;
|
||||
CConfig* m_config;
|
||||
bool m_isClient;
|
||||
CString m_screenName;
|
||||
int m_port;
|
||||
CString m_interface;
|
||||
};
|
||||
|
||||
#endif
|
||||
361
cmd/launcher/CAutoStart.cpp
Normal file
@@ -0,0 +1,361 @@
|
||||
/*
|
||||
* 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 "CLog.h"
|
||||
#include "ILogOutputter.h"
|
||||
#include "CArch.h"
|
||||
#include "CStringUtil.h"
|
||||
#include "XArch.h"
|
||||
#include "CAutoStart.h"
|
||||
#include "LaunchUtil.h"
|
||||
#include "resource.h"
|
||||
|
||||
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
|
||||
//
|
||||
// This class detects a message above a certain level and saves it
|
||||
//
|
||||
|
||||
class CAutoStartOutputter : public ILogOutputter {
|
||||
public:
|
||||
CAutoStartOutputter(CString* msg) : m_msg(msg) { }
|
||||
virtual ~CAutoStartOutputter() { }
|
||||
|
||||
// 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 ""; }
|
||||
|
||||
private:
|
||||
CString* m_msg;
|
||||
};
|
||||
|
||||
bool
|
||||
CAutoStartOutputter::write(ELevel level, const char* message)
|
||||
{
|
||||
if (level <= CLog::kERROR) {
|
||||
*m_msg = message;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// CAutoStart
|
||||
//
|
||||
|
||||
CAutoStart* CAutoStart::s_singleton = NULL;
|
||||
|
||||
CAutoStart::CAutoStart(HWND parent, bool isServer, const CString& cmdLine) :
|
||||
m_parent(parent),
|
||||
m_isServer(isServer),
|
||||
m_cmdLine(cmdLine),
|
||||
m_name(isServer ? SERVER_DAEMON_NAME : CLIENT_DAEMON_NAME)
|
||||
{
|
||||
assert(s_singleton == NULL);
|
||||
s_singleton = this;
|
||||
}
|
||||
|
||||
CAutoStart::~CAutoStart()
|
||||
{
|
||||
s_singleton = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
CAutoStart::doModal()
|
||||
{
|
||||
// install our log outputter
|
||||
CLOG->insert(new CAutoStartOutputter(&m_errorMessage));
|
||||
|
||||
// do dialog
|
||||
DialogBoxParam(s_instance, MAKEINTRESOURCE(IDD_AUTOSTART),
|
||||
m_parent, (DLGPROC)dlgProc, (LPARAM)this);
|
||||
|
||||
// remove log outputter
|
||||
CLOG->pop_front();
|
||||
}
|
||||
|
||||
void
|
||||
CAutoStart::reinstallDaemon(bool isClient, const CString& cmdLine)
|
||||
{
|
||||
// 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
|
||||
CAutoStart::update()
|
||||
{
|
||||
// get installation state
|
||||
const bool installedSystem = ARCH->isDaemonInstalled(
|
||||
m_name.c_str(), true);
|
||||
const bool installedUser = ARCH->isDaemonInstalled(
|
||||
m_name.c_str(), false);
|
||||
|
||||
// get user's permissions
|
||||
const bool canInstallSystem = ARCH->canInstallDaemon(
|
||||
m_name.c_str(), true);
|
||||
const bool canInstallUser = ARCH->canInstallDaemon(
|
||||
m_name.c_str(), false);
|
||||
|
||||
// update messages
|
||||
CString msg, label;
|
||||
if (canInstallSystem) {
|
||||
if (canInstallUser) {
|
||||
msg = getString(IDS_AUTOSTART_PERMISSION_ALL);
|
||||
}
|
||||
else {
|
||||
msg = getString(IDS_AUTOSTART_PERMISSION_SYSTEM);
|
||||
}
|
||||
}
|
||||
else if (canInstallUser) {
|
||||
msg = getString(IDS_AUTOSTART_PERMISSION_USER);
|
||||
}
|
||||
else {
|
||||
msg = getString(IDS_AUTOSTART_PERMISSION_NONE);
|
||||
}
|
||||
setWindowText(getItem(m_hwnd, IDC_AUTOSTART_PERMISSION_MSG), msg);
|
||||
if (installedSystem) {
|
||||
msg = getString(IDS_AUTOSTART_INSTALLED_SYSTEM);
|
||||
label = getString(IDS_UNINSTALL_LABEL);
|
||||
}
|
||||
else if (installedUser) {
|
||||
msg = getString(IDS_AUTOSTART_INSTALLED_USER);
|
||||
label = getString(IDS_UNINSTALL_LABEL);
|
||||
}
|
||||
else {
|
||||
msg = getString(IDS_AUTOSTART_INSTALLED_NONE);
|
||||
label = getString(IDS_INSTALL_LABEL);
|
||||
}
|
||||
setWindowText(getItem(m_hwnd, IDC_AUTOSTART_INSTALLED_MSG), msg);
|
||||
|
||||
// update buttons
|
||||
setWindowText(getItem(m_hwnd, IDC_AUTOSTART_INSTALL_SYSTEM), label);
|
||||
setWindowText(getItem(m_hwnd, IDC_AUTOSTART_INSTALL_USER), label);
|
||||
if (installedSystem) {
|
||||
enableItem(m_hwnd, IDC_AUTOSTART_INSTALL_SYSTEM, canInstallSystem);
|
||||
enableItem(m_hwnd, IDC_AUTOSTART_INSTALL_USER, false);
|
||||
m_install = false;
|
||||
}
|
||||
else if (installedUser) {
|
||||
enableItem(m_hwnd, IDC_AUTOSTART_INSTALL_SYSTEM, false);
|
||||
enableItem(m_hwnd, IDC_AUTOSTART_INSTALL_USER, canInstallUser);
|
||||
m_install = false;
|
||||
}
|
||||
else {
|
||||
enableItem(m_hwnd, IDC_AUTOSTART_INSTALL_SYSTEM, canInstallSystem);
|
||||
enableItem(m_hwnd, IDC_AUTOSTART_INSTALL_USER, canInstallUser);
|
||||
m_install = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
CAutoStart::onInstall(bool allUsers)
|
||||
{
|
||||
if (!m_install) {
|
||||
return onUninstall(allUsers);
|
||||
}
|
||||
|
||||
// get the app path
|
||||
CString appPath = getAppPath(m_isServer ? SERVER_APP : CLIENT_APP);
|
||||
|
||||
// clear error message
|
||||
m_errorMessage = "";
|
||||
|
||||
// install
|
||||
try {
|
||||
ARCH->installDaemon(m_name.c_str(),
|
||||
m_isServer ? SERVER_DAEMON_INFO : CLIENT_DAEMON_INFO,
|
||||
appPath.c_str(), m_cmdLine.c_str(),
|
||||
NULL, allUsers);
|
||||
askOkay(m_hwnd, getString(IDS_INSTALL_TITLE),
|
||||
getString(allUsers ?
|
||||
IDS_INSTALLED_SYSTEM :
|
||||
IDS_INSTALLED_USER));
|
||||
return true;
|
||||
}
|
||||
catch (XArchDaemon& e) {
|
||||
if (m_errorMessage.empty()) {
|
||||
m_errorMessage = CStringUtil::format(
|
||||
getString(IDS_INSTALL_GENERIC_ERROR).c_str(),
|
||||
e.what().c_str());
|
||||
}
|
||||
showError(m_hwnd, m_errorMessage);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
CAutoStart::onUninstall(bool allUsers)
|
||||
{
|
||||
// clear error message
|
||||
m_errorMessage = "";
|
||||
|
||||
// uninstall
|
||||
try {
|
||||
ARCH->uninstallDaemon(m_name.c_str(), allUsers);
|
||||
askOkay(m_hwnd, getString(IDS_UNINSTALL_TITLE),
|
||||
getString(allUsers ?
|
||||
IDS_UNINSTALLED_SYSTEM :
|
||||
IDS_UNINSTALLED_USER));
|
||||
return true;
|
||||
}
|
||||
catch (XArchDaemon& e) {
|
||||
if (m_errorMessage.empty()) {
|
||||
m_errorMessage = CStringUtil::format(
|
||||
getString(IDS_UNINSTALL_GENERIC_ERROR).c_str(),
|
||||
e.what().c_str());
|
||||
}
|
||||
showError(m_hwnd, m_errorMessage);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
BOOL
|
||||
CAutoStart::doDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM)
|
||||
{
|
||||
switch (message) {
|
||||
case WM_INITDIALOG:
|
||||
// save our hwnd
|
||||
m_hwnd = hwnd;
|
||||
|
||||
// update the controls
|
||||
update();
|
||||
|
||||
return TRUE;
|
||||
|
||||
case WM_COMMAND:
|
||||
switch (LOWORD(wParam)) {
|
||||
case IDC_AUTOSTART_INSTALL_SYSTEM:
|
||||
onInstall(true);
|
||||
update();
|
||||
return TRUE;
|
||||
|
||||
case IDC_AUTOSTART_INSTALL_USER:
|
||||
onInstall(false);
|
||||
update();
|
||||
return TRUE;
|
||||
|
||||
case IDCANCEL:
|
||||
EndDialog(hwnd, 0);
|
||||
m_hwnd = NULL;
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL CALLBACK
|
||||
CAutoStart::dlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
return s_singleton->doDlgProc(hwnd, message, wParam, lParam);
|
||||
}
|
||||
90
cmd/launcher/CAutoStart.h
Normal file
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef CAUTOSTART_H
|
||||
#define CAUTOSTART_H
|
||||
|
||||
#include "CString.h"
|
||||
|
||||
#define WINDOWS_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
//! Auto start dialog for Microsoft Windows launcher
|
||||
class CAutoStart {
|
||||
public:
|
||||
CAutoStart(HWND parent, bool isServer, const CString& cmdLine);
|
||||
~CAutoStart();
|
||||
|
||||
//! @name manipulators
|
||||
//@{
|
||||
|
||||
//! Run dialog
|
||||
/*!
|
||||
Display and handle the dialog until closed by the user.
|
||||
*/
|
||||
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
|
||||
//@{
|
||||
|
||||
//! Tests if any daemons are installed
|
||||
/*!
|
||||
Returns \c true if any daemons are installed.
|
||||
*/
|
||||
static bool isDaemonInstalled();
|
||||
|
||||
//@}
|
||||
|
||||
private:
|
||||
void update();
|
||||
bool onInstall(bool allUsers);
|
||||
bool onUninstall(bool allUsers);
|
||||
|
||||
// message handling
|
||||
BOOL doDlgProc(HWND, UINT, WPARAM, LPARAM);
|
||||
static BOOL CALLBACK dlgProc(HWND, UINT, WPARAM, LPARAM);
|
||||
|
||||
private:
|
||||
static CAutoStart* s_singleton;
|
||||
|
||||
HWND m_parent;
|
||||
bool m_isServer;
|
||||
CString m_cmdLine;
|
||||
CString m_name;
|
||||
HWND m_hwnd;
|
||||
bool m_install;
|
||||
CString m_errorMessage;
|
||||
};
|
||||
|
||||
#endif
|
||||
281
cmd/launcher/CGlobalOptions.cpp
Normal file
@@ -0,0 +1,281 @@
|
||||
/*
|
||||
* 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 "CGlobalOptions.h"
|
||||
#include "LaunchUtil.h"
|
||||
#include "resource.h"
|
||||
|
||||
static const int s_defaultDelay = 250;
|
||||
static const int s_defaultHeartbeat = 5000;
|
||||
|
||||
//
|
||||
// CGlobalOptions
|
||||
//
|
||||
|
||||
CGlobalOptions* CGlobalOptions::s_singleton = NULL;
|
||||
|
||||
CGlobalOptions::CGlobalOptions(HWND parent, CConfig* config) :
|
||||
m_parent(parent),
|
||||
m_config(config),
|
||||
m_delayTime(s_defaultDelay),
|
||||
m_twoTapTime(s_defaultDelay),
|
||||
m_heartbeatTime(s_defaultHeartbeat)
|
||||
{
|
||||
assert(s_singleton == NULL);
|
||||
s_singleton = this;
|
||||
}
|
||||
|
||||
CGlobalOptions::~CGlobalOptions()
|
||||
{
|
||||
s_singleton = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
CGlobalOptions::doModal()
|
||||
{
|
||||
// do dialog
|
||||
DialogBoxParam(s_instance, MAKEINTRESOURCE(IDD_GLOBAL_OPTIONS),
|
||||
m_parent, (DLGPROC)dlgProc, (LPARAM)this);
|
||||
}
|
||||
|
||||
void
|
||||
CGlobalOptions::init(HWND hwnd)
|
||||
{
|
||||
HWND child;
|
||||
char buffer[30];
|
||||
|
||||
// reset options
|
||||
sprintf(buffer, "%d", m_delayTime);
|
||||
child = getItem(hwnd, IDC_GLOBAL_DELAY_CHECK);
|
||||
setItemChecked(child, false);
|
||||
child = getItem(hwnd, IDC_GLOBAL_DELAY_TIME);
|
||||
setWindowText(child, buffer);
|
||||
sprintf(buffer, "%d", m_twoTapTime);
|
||||
child = getItem(hwnd, IDC_GLOBAL_TWO_TAP_CHECK);
|
||||
setItemChecked(child, false);
|
||||
child = getItem(hwnd, IDC_GLOBAL_TWO_TAP_TIME);
|
||||
setWindowText(child, buffer);
|
||||
sprintf(buffer, "%d", m_heartbeatTime);
|
||||
child = getItem(hwnd, IDC_GLOBAL_HEARTBEAT_CHECK);
|
||||
setItemChecked(child, false);
|
||||
child = getItem(hwnd, IDC_GLOBAL_HEARTBEAT_TIME);
|
||||
setWindowText(child, buffer);
|
||||
child = getItem(hwnd, IDC_GLOBAL_SCREENSAVER_SYNC);
|
||||
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("");
|
||||
if (options != NULL) {
|
||||
for (CConfig::CScreenOptions::const_iterator index = options->begin();
|
||||
index != options->end(); ++index) {
|
||||
const OptionID id = index->first;
|
||||
const OptionValue value = index->second;
|
||||
if (id == kOptionScreenSwitchDelay) {
|
||||
if (value > 0) {
|
||||
sprintf(buffer, "%d", value);
|
||||
child = getItem(hwnd, IDC_GLOBAL_DELAY_CHECK);
|
||||
setItemChecked(child, true);
|
||||
child = getItem(hwnd, IDC_GLOBAL_DELAY_TIME);
|
||||
setWindowText(child, buffer);
|
||||
}
|
||||
}
|
||||
else if (id == kOptionScreenSwitchTwoTap) {
|
||||
if (value > 0) {
|
||||
sprintf(buffer, "%d", value);
|
||||
child = getItem(hwnd, IDC_GLOBAL_TWO_TAP_CHECK);
|
||||
setItemChecked(child, true);
|
||||
child = getItem(hwnd, IDC_GLOBAL_TWO_TAP_TIME);
|
||||
setWindowText(child, buffer);
|
||||
}
|
||||
}
|
||||
else if (id == kOptionHeartbeat) {
|
||||
if (value > 0) {
|
||||
sprintf(buffer, "%d", value);
|
||||
child = getItem(hwnd, IDC_GLOBAL_HEARTBEAT_CHECK);
|
||||
setItemChecked(child, true);
|
||||
child = getItem(hwnd, IDC_GLOBAL_HEARTBEAT_TIME);
|
||||
setWindowText(child, buffer);
|
||||
}
|
||||
}
|
||||
else if (id == kOptionScreenSaverSync) {
|
||||
child = getItem(hwnd, IDC_GLOBAL_SCREENSAVER_SYNC);
|
||||
setItemChecked(child, (value != 0));
|
||||
}
|
||||
else if (id == kOptionRelativeMouseMoves) {
|
||||
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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
CGlobalOptions::save(HWND hwnd)
|
||||
{
|
||||
HWND child;
|
||||
int newDelayTime = 0;
|
||||
int newTwoTapTime = 0;
|
||||
int newHeartbeatTime = 0;
|
||||
|
||||
// get requested options
|
||||
child = getItem(hwnd, IDC_GLOBAL_DELAY_CHECK);
|
||||
if (isItemChecked(child)) {
|
||||
child = getItem(hwnd, IDC_GLOBAL_DELAY_TIME);
|
||||
newDelayTime = getTime(hwnd, child, true);
|
||||
if (newDelayTime == 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
child = getItem(hwnd, IDC_GLOBAL_DELAY_TIME);
|
||||
newDelayTime = getTime(hwnd, child, false);
|
||||
if (newDelayTime == 0) {
|
||||
newDelayTime = s_defaultDelay;
|
||||
}
|
||||
}
|
||||
child = getItem(hwnd, IDC_GLOBAL_TWO_TAP_CHECK);
|
||||
if (isItemChecked(child)) {
|
||||
child = getItem(hwnd, IDC_GLOBAL_TWO_TAP_TIME);
|
||||
newTwoTapTime = getTime(hwnd, child, true);
|
||||
if (newTwoTapTime == 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
child = getItem(hwnd, IDC_GLOBAL_TWO_TAP_TIME);
|
||||
newTwoTapTime = getTime(hwnd, child, false);
|
||||
if (newTwoTapTime == 0) {
|
||||
newTwoTapTime = s_defaultDelay;
|
||||
}
|
||||
}
|
||||
child = getItem(hwnd, IDC_GLOBAL_HEARTBEAT_CHECK);
|
||||
if (isItemChecked(child)) {
|
||||
child = getItem(hwnd, IDC_GLOBAL_HEARTBEAT_TIME);
|
||||
newHeartbeatTime = getTime(hwnd, child, true);
|
||||
if (newHeartbeatTime == 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
child = getItem(hwnd, IDC_GLOBAL_HEARTBEAT_TIME);
|
||||
newHeartbeatTime = getTime(hwnd, child, false);
|
||||
if (newHeartbeatTime == 0) {
|
||||
newHeartbeatTime = s_defaultHeartbeat;
|
||||
}
|
||||
}
|
||||
|
||||
// remove existing config options
|
||||
m_config->removeOption("", kOptionScreenSwitchDelay);
|
||||
m_config->removeOption("", kOptionScreenSwitchTwoTap);
|
||||
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);
|
||||
if (isItemChecked(child)) {
|
||||
m_config->addOption("", kOptionScreenSwitchDelay, newDelayTime);
|
||||
}
|
||||
child = getItem(hwnd, IDC_GLOBAL_TWO_TAP_CHECK);
|
||||
if (isItemChecked(child)) {
|
||||
m_config->addOption("", kOptionScreenSwitchTwoTap, newTwoTapTime);
|
||||
}
|
||||
child = getItem(hwnd, IDC_GLOBAL_HEARTBEAT_CHECK);
|
||||
if (isItemChecked(child)) {
|
||||
m_config->addOption("", kOptionHeartbeat, newHeartbeatTime);
|
||||
}
|
||||
child = getItem(hwnd, IDC_GLOBAL_SCREENSAVER_SYNC);
|
||||
if (!isItemChecked(child)) {
|
||||
m_config->addOption("", kOptionScreenSaverSync, 0);
|
||||
}
|
||||
child = getItem(hwnd, IDC_GLOBAL_RELATIVE_MOVES);
|
||||
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;
|
||||
m_twoTapTime = newTwoTapTime;
|
||||
m_heartbeatTime = newHeartbeatTime;
|
||||
return true;
|
||||
}
|
||||
|
||||
int
|
||||
CGlobalOptions::getTime(HWND hwnd, HWND child, bool reportError)
|
||||
{
|
||||
CString valueString = getWindowText(child);
|
||||
int value = atoi(valueString.c_str());
|
||||
if (value < 1) {
|
||||
if (reportError) {
|
||||
showError(hwnd, CStringUtil::format(
|
||||
getString(IDS_INVALID_TIME).c_str(),
|
||||
valueString.c_str()));
|
||||
SetFocus(child);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
BOOL
|
||||
CGlobalOptions::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, 0);
|
||||
}
|
||||
return TRUE;
|
||||
|
||||
case IDCANCEL:
|
||||
EndDialog(hwnd, 0);
|
||||
return TRUE;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL CALLBACK
|
||||
CGlobalOptions::dlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
return s_singleton->doDlgProc(hwnd, message, wParam, lParam);
|
||||
}
|
||||
67
cmd/launcher/CGlobalOptions.h
Normal file
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* 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 CGLOBALOPTIONS_H
|
||||
#define CGLOBALOPTIONS_H
|
||||
|
||||
#include "CString.h"
|
||||
|
||||
#define WINDOWS_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
||||
class CConfig;
|
||||
|
||||
//! Global options dialog for Microsoft Windows launcher
|
||||
class CGlobalOptions {
|
||||
public:
|
||||
CGlobalOptions(HWND parent, CConfig*);
|
||||
~CGlobalOptions();
|
||||
|
||||
//! @name manipulators
|
||||
//@{
|
||||
|
||||
//! Run dialog
|
||||
/*!
|
||||
Display and handle the dialog until closed by the user.
|
||||
*/
|
||||
void doModal();
|
||||
|
||||
//@}
|
||||
//! @name accessors
|
||||
//@{
|
||||
|
||||
|
||||
//@}
|
||||
|
||||
private:
|
||||
void init(HWND hwnd);
|
||||
bool save(HWND hwnd);
|
||||
|
||||
int getTime(HWND hwnd, HWND child, bool reportError);
|
||||
|
||||
// message handling
|
||||
BOOL doDlgProc(HWND, UINT, WPARAM, LPARAM);
|
||||
static BOOL CALLBACK dlgProc(HWND, UINT, WPARAM, LPARAM);
|
||||
|
||||
private:
|
||||
static CGlobalOptions* s_singleton;
|
||||
|
||||
HWND m_parent;
|
||||
CConfig* m_config;
|
||||
int m_delayTime;
|
||||
int m_twoTapTime;
|
||||
int m_heartbeatTime;
|
||||
};
|
||||
|
||||
#endif
|
||||
1938
cmd/launcher/CHotkeyOptions.cpp
Normal file
227
cmd/launcher/CHotkeyOptions.h
Normal file
@@ -0,0 +1,227 @@
|
||||
/*
|
||||
* 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 void onKeyboardBroadcastAction(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 std::set<CString> s_screens;
|
||||
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
@@ -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)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
@@ -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
|
||||
855
cmd/launcher/CScreensLinks.cpp
Normal 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)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);
|
||||
}
|
||||
138
cmd/launcher/CScreensLinks.h
Normal 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
|
||||
261
cmd/launcher/LaunchUtil.cpp
Normal file
@@ -0,0 +1,261 @@
|
||||
/*
|
||||
* 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 "LaunchUtil.h"
|
||||
#include "CMSWindowsUtil.h"
|
||||
#include "CArch.h"
|
||||
#include "resource.h"
|
||||
#include "stdfstream.h"
|
||||
|
||||
size_t s_showingDialog = 0;
|
||||
|
||||
CString
|
||||
getString(DWORD id)
|
||||
{
|
||||
return CMSWindowsUtil::getString(s_instance, id);
|
||||
}
|
||||
|
||||
CString
|
||||
getErrorString(DWORD error)
|
||||
{
|
||||
return CMSWindowsUtil::getErrorString(s_instance, error, IDS_ERROR);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
SendMessage(hwnd, WM_SETTEXT, 0, (LPARAM)msg.c_str());
|
||||
}
|
||||
|
||||
CString
|
||||
getWindowText(HWND hwnd)
|
||||
{
|
||||
LRESULT size = SendMessage(hwnd, WM_GETTEXTLENGTH, 0, 0);
|
||||
char* buffer = new char[size + 1];
|
||||
SendMessage(hwnd, WM_GETTEXT, size + 1, (LPARAM)buffer);
|
||||
buffer[size] = '\0';
|
||||
CString result(buffer);
|
||||
delete[] buffer;
|
||||
return result;
|
||||
}
|
||||
|
||||
HWND
|
||||
getItem(HWND hwnd, int id)
|
||||
{
|
||||
return GetDlgItem(hwnd, id);
|
||||
}
|
||||
|
||||
void
|
||||
enableItem(HWND hwnd, int id, bool enabled)
|
||||
{
|
||||
EnableWindow(GetDlgItem(hwnd, id), enabled);
|
||||
}
|
||||
|
||||
void
|
||||
setItemChecked(HWND hwnd, bool checked)
|
||||
{
|
||||
SendMessage(hwnd, BM_SETCHECK, checked ? BST_CHECKED : BST_UNCHECKED, 0);
|
||||
}
|
||||
|
||||
bool
|
||||
isItemChecked(HWND hwnd)
|
||||
{
|
||||
return (SendMessage(hwnd, BM_GETCHECK, 0, 0) == BST_CHECKED);
|
||||
}
|
||||
|
||||
CString
|
||||
getAppPath(const CString& appName)
|
||||
{
|
||||
// prepare path to app
|
||||
char myPathname[MAX_PATH];
|
||||
GetModuleFileName(s_instance, myPathname, MAX_PATH);
|
||||
const char* myBasename = ARCH->getBasename(myPathname);
|
||||
CString appPath = CString(myPathname, myBasename - myPathname);
|
||||
appPath += 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)
|
||||
{
|
||||
try {
|
||||
std::ifstream stream(pathname.c_str());
|
||||
if (stream) {
|
||||
stream >> config;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (...) {
|
||||
// ignore
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
loadConfig(CConfig& config, time_t& t, bool& userConfig)
|
||||
{
|
||||
// load configuration
|
||||
bool configLoaded = false;
|
||||
CString path = ARCH->getUserDirectory();
|
||||
if (!path.empty()) {
|
||||
// try loading the user's configuration
|
||||
path = ARCH->concatPath(path, CONFIG_NAME);
|
||||
if (loadConfig(path, config)) {
|
||||
configLoaded = true;
|
||||
userConfig = true;
|
||||
getFileTime(path, t);
|
||||
}
|
||||
else {
|
||||
// try the system-wide config file
|
||||
path = ARCH->getSystemDirectory();
|
||||
if (!path.empty()) {
|
||||
path = ARCH->concatPath(path, CONFIG_NAME);
|
||||
if (loadConfig(path, config)) {
|
||||
configLoaded = true;
|
||||
userConfig = false;
|
||||
getFileTime(path, t);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return configLoaded;
|
||||
}
|
||||
|
||||
static
|
||||
bool
|
||||
saveConfig(const CString& pathname, const CConfig& config)
|
||||
{
|
||||
try {
|
||||
std::ofstream stream(pathname.c_str());
|
||||
if (stream) {
|
||||
stream << config;
|
||||
return !!stream;
|
||||
}
|
||||
}
|
||||
catch (...) {
|
||||
// ignore
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
saveConfig(const CConfig& config, bool sysOnly, time_t& t)
|
||||
{
|
||||
// try saving the user's configuration
|
||||
if (!sysOnly) {
|
||||
CString path = ARCH->getUserDirectory();
|
||||
if (!path.empty()) {
|
||||
path = ARCH->concatPath(path, CONFIG_NAME);
|
||||
if (saveConfig(path, config)) {
|
||||
getFileTime(path, t);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// try the system-wide config file
|
||||
else {
|
||||
CString path = ARCH->getSystemDirectory();
|
||||
if (!path.empty()) {
|
||||
path = ARCH->concatPath(path, CONFIG_NAME);
|
||||
if (saveConfig(path, config)) {
|
||||
getFileTime(path, t);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
const TCHAR* const*
|
||||
getSettingsPath()
|
||||
{
|
||||
static const TCHAR* s_keyNames[] = {
|
||||
TEXT("Software"),
|
||||
TEXT("Synergy"),
|
||||
TEXT("Synergy"),
|
||||
NULL
|
||||
};
|
||||
return s_keyNames;
|
||||
}
|
||||
61
cmd/launcher/LaunchUtil.h
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef LAUNCHUTIL_H
|
||||
#define LAUNCHUTIL_H
|
||||
|
||||
#include "CString.h"
|
||||
|
||||
#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;
|
||||
|
||||
// client must define this and set it before calling any function here
|
||||
extern HINSTANCE s_instance;
|
||||
|
||||
CString getString(DWORD id);
|
||||
CString getErrorString(DWORD error);
|
||||
|
||||
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);
|
||||
|
||||
HWND getItem(HWND hwnd, int id);
|
||||
void enableItem(HWND hwnd, int id, bool enabled);
|
||||
|
||||
void setItemChecked(HWND, bool);
|
||||
bool isItemChecked(HWND);
|
||||
|
||||
CString getAppPath(const CString& appName);
|
||||
|
||||
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();
|
||||
|
||||
#endif
|
||||
75
cmd/launcher/Makefile.am
Normal file
@@ -0,0 +1,75 @@
|
||||
# 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.
|
||||
|
||||
## Process this file with automake to produce Makefile.in
|
||||
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 \
|
||||
$(NULL)
|
||||
|
||||
EXTRA_DIST = \
|
||||
Makefile.win \
|
||||
synergy.ico \
|
||||
$(MSWINDOWS_SOURCE_FILES) \
|
||||
$(NULL)
|
||||
|
||||
MAINTAINERCLEANFILES = \
|
||||
Makefile.in \
|
||||
$(NULL)
|
||||
|
||||
if MSWINDOWS
|
||||
bin_PROGRAMS = synergy
|
||||
synergy_SOURCES = \
|
||||
$(MSWINDOWS_SOURCE_FILES) \
|
||||
$(NULL)
|
||||
endif
|
||||
synergy_LDADD = \
|
||||
$(top_builddir)/lib/server/libserver.a \
|
||||
$(top_builddir)/lib/platform/libplatform.a \
|
||||
$(top_builddir)/lib/synergy/libsynergy.a \
|
||||
$(top_builddir)/lib/net/libnet.a \
|
||||
$(top_builddir)/lib/io/libio.a \
|
||||
$(top_builddir)/lib/mt/libmt.a \
|
||||
$(top_builddir)/lib/base/libbase.a \
|
||||
$(top_builddir)/lib/common/libcommon.a \
|
||||
$(top_builddir)/lib/arch/libarch.a \
|
||||
$(NULL)
|
||||
INCLUDES = \
|
||||
-I$(top_srcdir)/lib/common \
|
||||
-I$(top_srcdir)/lib/arch \
|
||||
-I$(top_srcdir)/lib/base \
|
||||
-I$(top_srcdir)/lib/mt \
|
||||
-I$(top_srcdir)/lib/io \
|
||||
-I$(top_srcdir)/lib/net \
|
||||
-I$(top_srcdir)/lib/synergy \
|
||||
-I$(top_srcdir)/lib/platform \
|
||||
-I$(top_srcdir)/lib/server \
|
||||
$(NULL)
|
||||
101
cmd/launcher/Makefile.win
Normal file
@@ -0,0 +1,101 @@
|
||||
# synergy -- mouse and keyboard sharing utility
|
||||
# Copyright (C) 2007 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.
|
||||
|
||||
BIN_LAUNCHER_SRC = cmd\launcher
|
||||
BIN_LAUNCHER_DST = $(BUILD_DST)\$(BIN_LAUNCHER_SRC)
|
||||
BIN_LAUNCHER_EXE = "$(BUILD_DST)\synergy.exe"
|
||||
BIN_LAUNCHER_CPP = \
|
||||
"CAddScreen.cpp" \
|
||||
"CAdvancedOptions.cpp" \
|
||||
"CAutoStart.cpp" \
|
||||
"CGlobalOptions.cpp" \
|
||||
"CHotkeyOptions.cpp" \
|
||||
"CInfo.cpp" \
|
||||
"CScreensLinks.cpp" \
|
||||
"LaunchUtil.cpp" \
|
||||
"launcher.cpp" \
|
||||
$(NULL)
|
||||
BIN_LAUNCHER_OBJ = \
|
||||
"$(BIN_LAUNCHER_DST)\CAddScreen.obj" \
|
||||
"$(BIN_LAUNCHER_DST)\CAdvancedOptions.obj" \
|
||||
"$(BIN_LAUNCHER_DST)\CAutoStart.obj" \
|
||||
"$(BIN_LAUNCHER_DST)\CGlobalOptions.obj" \
|
||||
"$(BIN_LAUNCHER_DST)\CHotkeyOptions.obj" \
|
||||
"$(BIN_LAUNCHER_DST)\CInfo.obj" \
|
||||
"$(BIN_LAUNCHER_DST)\CScreensLinks.obj" \
|
||||
"$(BIN_LAUNCHER_DST)\LaunchUtil.obj" \
|
||||
"$(BIN_LAUNCHER_DST)\launcher.obj" \
|
||||
$(NULL)
|
||||
BIN_LAUNCHER_RC = "$(BIN_LAUNCHER_SRC)\launcher.rc"
|
||||
BIN_LAUNCHER_RES = "$(BIN_LAUNCHER_DST)\launcher.res"
|
||||
BIN_LAUNCHER_INC = \
|
||||
/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" \
|
||||
$(NULL)
|
||||
BIN_LAUNCHER_LIB = \
|
||||
$(LIB_SERVER_LIB) \
|
||||
$(LIB_PLATFORM_LIB) \
|
||||
$(LIB_SYNERGY_LIB) \
|
||||
$(LIB_NET_LIB) \
|
||||
$(LIB_IO_LIB) \
|
||||
$(LIB_MT_LIB) \
|
||||
$(LIB_BASE_LIB) \
|
||||
$(LIB_ARCH_LIB) \
|
||||
$(LIB_COMMON_LIB) \
|
||||
$(NULL)
|
||||
|
||||
CPP_FILES = $(CPP_FILES) $(BIN_LAUNCHER_CPP)
|
||||
OBJ_FILES = $(OBJ_FILES) $(BIN_LAUNCHER_OBJ)
|
||||
PROGRAMS = $(PROGRAMS) $(BIN_LAUNCHER_EXE)
|
||||
|
||||
# Need shell functions.
|
||||
guilibs = $(guilibs) shell32.lib
|
||||
|
||||
# Dependency rules
|
||||
$(BIN_LAUNCHER_OBJ): $(AUTODEP)
|
||||
!if EXIST($(BIN_LAUNCHER_DST)\deps.mak)
|
||||
!include $(BIN_LAUNCHER_DST)\deps.mak
|
||||
!endif
|
||||
|
||||
# Build rules. Use batch-mode rules if possible.
|
||||
!if DEFINED(_NMAKE_VER)
|
||||
{$(BIN_LAUNCHER_SRC)\}.cpp{$(BIN_LAUNCHER_DST)\}.obj::
|
||||
!else
|
||||
{$(BIN_LAUNCHER_SRC)\}.cpp{$(BIN_LAUNCHER_DST)\}.obj:
|
||||
!endif
|
||||
@$(ECHO) Compile in $(BIN_LAUNCHER_SRC)
|
||||
-@$(MKDIR) $(BIN_LAUNCHER_DST) 2>NUL:
|
||||
$(cpp) $(cppdebug) $(cppflags) $(cppvarsmt) /showIncludes \
|
||||
$(BIN_LAUNCHER_INC) \
|
||||
/Fo$(BIN_LAUNCHER_DST)\ \
|
||||
/Fd$(BIN_LAUNCHER_DST)\src.pdb \
|
||||
$< | $(AUTODEP) $(BIN_LAUNCHER_SRC) $(BIN_LAUNCHER_DST)
|
||||
$(BIN_LAUNCHER_RES): $(BIN_LAUNCHER_RC)
|
||||
@$(ECHO) Compile $(**F)
|
||||
-@$(MKDIR) $(BIN_LAUNCHER_DST) 2>NUL:
|
||||
$(rc) $(rcflags) $(rcvars) \
|
||||
/fo$@ \
|
||||
$**
|
||||
$(BIN_LAUNCHER_EXE): $(BIN_LAUNCHER_OBJ) $(BIN_LAUNCHER_RES) $(BIN_LAUNCHER_LIB)
|
||||
@$(ECHO) Link $(@F)
|
||||
$(link) $(ldebug) $(guilflags) $(guilibsmt) \
|
||||
/out:$@ \
|
||||
$**
|
||||
$(AUTODEP) $(BIN_LAUNCHER_SRC) $(BIN_LAUNCHER_DST) \
|
||||
$(BIN_LAUNCHER_OBJ:.obj=.d)
|
||||
755
cmd/launcher/launcher.cpp
Normal file
@@ -0,0 +1,755 @@
|
||||
/*
|
||||
* 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 "CLog.h"
|
||||
#include "CStringUtil.h"
|
||||
#include "CArch.h"
|
||||
#include "CArchMiscWindows.h"
|
||||
#include "XArch.h"
|
||||
#include "Version.h"
|
||||
#include "stdvector.h"
|
||||
#include "resource.h"
|
||||
|
||||
// these must come after the above because it includes windows.h
|
||||
#include "LaunchUtil.h"
|
||||
#include "CAddScreen.h"
|
||||
#include "CAdvancedOptions.h"
|
||||
#include "CAutoStart.h"
|
||||
#include "CGlobalOptions.h"
|
||||
#include "CHotkeyOptions.h"
|
||||
#include "CInfo.h"
|
||||
#include "CScreensLinks.h"
|
||||
|
||||
typedef std::vector<CString> CStringList;
|
||||
|
||||
class CChildWaitInfo {
|
||||
public:
|
||||
HWND m_dialog;
|
||||
HANDLE m_child;
|
||||
DWORD m_childID;
|
||||
HANDLE m_ready;
|
||||
HANDLE m_stop;
|
||||
};
|
||||
|
||||
static const char* s_debugName[][2] = {
|
||||
{ TEXT("Error"), "ERROR" },
|
||||
{ TEXT("Warning"), "WARNING" },
|
||||
{ TEXT("Note"), "NOTE" },
|
||||
{ TEXT("Info"), "INFO" },
|
||||
{ TEXT("Debug"), "DEBUG" },
|
||||
{ TEXT("Debug1"), "DEBUG1" },
|
||||
{ TEXT("Debug2"), "DEBUG2" }
|
||||
};
|
||||
static const int s_defaultDebug = 1; // WARNING
|
||||
static const int s_minTestDebug = 3; // INFO
|
||||
|
||||
HINSTANCE s_instance = NULL;
|
||||
|
||||
static CGlobalOptions* s_globalOptions = NULL;
|
||||
static CAdvancedOptions* s_advancedOptions = NULL;
|
||||
static CHotkeyOptions* s_hotkeyOptions = NULL;
|
||||
static CScreensLinks* s_screensLinks = NULL;
|
||||
static CInfo* s_info = NULL;
|
||||
|
||||
static bool s_userConfig = true;
|
||||
static time_t s_configTime = 0;
|
||||
static CConfig s_lastConfig;
|
||||
|
||||
static const TCHAR* s_mainClass = TEXT("GoSynergy");
|
||||
static const TCHAR* s_layoutClass = TEXT("SynergyLayout");
|
||||
|
||||
enum SaveMode {
|
||||
SAVE_QUITING,
|
||||
SAVE_NORMAL,
|
||||
SAVE_QUIET
|
||||
};
|
||||
|
||||
//
|
||||
// program arguments
|
||||
//
|
||||
|
||||
#define ARG CArgs::s_instance
|
||||
|
||||
class CArgs {
|
||||
public:
|
||||
CArgs() { s_instance = this; }
|
||||
~CArgs() { s_instance = NULL; }
|
||||
|
||||
public:
|
||||
static CArgs* s_instance;
|
||||
CConfig m_config;
|
||||
CStringList m_screens;
|
||||
};
|
||||
|
||||
CArgs* CArgs::s_instance = NULL;
|
||||
|
||||
|
||||
static
|
||||
BOOL CALLBACK
|
||||
addDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
static
|
||||
bool
|
||||
isClientChecked(HWND hwnd)
|
||||
{
|
||||
HWND child = getItem(hwnd, IDC_MAIN_CLIENT_RADIO);
|
||||
return isItemChecked(child);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
enableMainWindowControls(HWND hwnd)
|
||||
{
|
||||
bool client = isClientChecked(hwnd);
|
||||
enableItem(hwnd, IDC_MAIN_CLIENT_SERVER_NAME_LABEL, client);
|
||||
enableItem(hwnd, IDC_MAIN_CLIENT_SERVER_NAME_EDIT, client);
|
||||
enableItem(hwnd, IDC_MAIN_SERVER_SCREENS_LABEL, !client);
|
||||
enableItem(hwnd, IDC_MAIN_SCREENS, !client);
|
||||
enableItem(hwnd, IDC_MAIN_OPTIONS, !client);
|
||||
enableItem(hwnd, IDC_MAIN_HOTKEYS, !client);
|
||||
}
|
||||
|
||||
static
|
||||
bool
|
||||
execApp(const char* app, const CString& cmdLine, PROCESS_INFORMATION* procInfo)
|
||||
{
|
||||
// prepare startup info
|
||||
STARTUPINFO startup;
|
||||
startup.cb = sizeof(startup);
|
||||
startup.lpReserved = NULL;
|
||||
startup.lpDesktop = NULL;
|
||||
startup.lpTitle = NULL;
|
||||
startup.dwX = (DWORD)CW_USEDEFAULT;
|
||||
startup.dwY = (DWORD)CW_USEDEFAULT;
|
||||
startup.dwXSize = (DWORD)CW_USEDEFAULT;
|
||||
startup.dwYSize = (DWORD)CW_USEDEFAULT;
|
||||
startup.dwXCountChars = 0;
|
||||
startup.dwYCountChars = 0;
|
||||
startup.dwFillAttribute = 0;
|
||||
startup.dwFlags = STARTF_FORCEONFEEDBACK;
|
||||
startup.wShowWindow = SW_SHOWDEFAULT;
|
||||
startup.cbReserved2 = 0;
|
||||
startup.lpReserved2 = NULL;
|
||||
startup.hStdInput = NULL;
|
||||
startup.hStdOutput = NULL;
|
||||
startup.hStdError = NULL;
|
||||
|
||||
// prepare path to app
|
||||
CString appPath = getAppPath(app);
|
||||
|
||||
// put path to app in command line
|
||||
CString commandLine = "\"";
|
||||
commandLine += appPath;
|
||||
commandLine += "\" ";
|
||||
commandLine += cmdLine;
|
||||
|
||||
// start child
|
||||
if (CreateProcess(NULL, (char*)commandLine.c_str(),
|
||||
NULL,
|
||||
NULL,
|
||||
FALSE,
|
||||
CREATE_DEFAULT_ERROR_MODE |
|
||||
CREATE_NEW_PROCESS_GROUP |
|
||||
NORMAL_PRIORITY_CLASS,
|
||||
NULL,
|
||||
NULL,
|
||||
&startup,
|
||||
procInfo) == 0) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
CString
|
||||
getCommandLine(HWND hwnd, bool testing, bool silent)
|
||||
{
|
||||
CString cmdLine;
|
||||
|
||||
// add constant testing args
|
||||
if (testing) {
|
||||
cmdLine += " -z --no-restart --no-daemon";
|
||||
}
|
||||
|
||||
// can't start as service on NT
|
||||
else if (!CArchMiscWindows::isWindows95Family()) {
|
||||
cmdLine += " --no-daemon";
|
||||
}
|
||||
|
||||
// get the server name
|
||||
CString server;
|
||||
bool isClient = isClientChecked(hwnd);
|
||||
if (isClient) {
|
||||
// check server name
|
||||
HWND child = getItem(hwnd, IDC_MAIN_CLIENT_SERVER_NAME_EDIT);
|
||||
server = getWindowText(child);
|
||||
if (!ARG->m_config.isValidScreenName(server)) {
|
||||
if (!silent) {
|
||||
showError(hwnd, CStringUtil::format(
|
||||
getString(IDS_INVALID_SERVER_NAME).c_str(),
|
||||
server.c_str()));
|
||||
}
|
||||
SetFocus(child);
|
||||
return CString();
|
||||
}
|
||||
|
||||
// compare server name to local host. a common error
|
||||
// is to provide the client's name for the server. we
|
||||
// don't bother to check the addresses though that'd be
|
||||
// more accurate.
|
||||
if (CStringUtil::CaselessCmp::equal(ARCH->getHostName(), server)) {
|
||||
if (!silent) {
|
||||
showError(hwnd, CStringUtil::format(
|
||||
getString(IDS_SERVER_IS_CLIENT).c_str(),
|
||||
server.c_str()));
|
||||
}
|
||||
SetFocus(child);
|
||||
return CString();
|
||||
}
|
||||
}
|
||||
|
||||
// debug level. always include this.
|
||||
if (true) {
|
||||
HWND child = getItem(hwnd, IDC_MAIN_DEBUG);
|
||||
int debug = (int)SendMessage(child, CB_GETCURSEL, 0, 0);
|
||||
|
||||
// if testing then we force the debug level to be no less than
|
||||
// s_minTestDebug. what's the point of testing if you can't
|
||||
// see the debugging info?
|
||||
if (testing && debug < s_minTestDebug) {
|
||||
debug = s_minTestDebug;
|
||||
}
|
||||
|
||||
cmdLine += " --debug ";
|
||||
cmdLine += s_debugName[debug][1];
|
||||
}
|
||||
|
||||
// add advanced options
|
||||
cmdLine += s_advancedOptions->getCommandLine(isClient, server);
|
||||
|
||||
return cmdLine;
|
||||
}
|
||||
|
||||
static
|
||||
bool
|
||||
launchApp(HWND hwnd, bool testing, HANDLE* thread, DWORD* threadID)
|
||||
{
|
||||
if (thread != NULL) {
|
||||
*thread = NULL;
|
||||
}
|
||||
if (threadID != NULL) {
|
||||
*threadID = 0;
|
||||
}
|
||||
|
||||
// start daemon if it's installed and we're not testing
|
||||
if (!testing && CAutoStart::startDaemon()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// decide if client or server
|
||||
const bool isClient = isClientChecked(hwnd);
|
||||
const char* app = isClient ? CLIENT_APP : SERVER_APP;
|
||||
|
||||
// prepare command line
|
||||
CString cmdLine = getCommandLine(hwnd, testing, false);
|
||||
if (cmdLine.empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// start child
|
||||
PROCESS_INFORMATION procInfo;
|
||||
if (!execApp(app, cmdLine, &procInfo)) {
|
||||
showError(hwnd, CStringUtil::format(
|
||||
getString(IDS_STARTUP_FAILED).c_str(),
|
||||
getErrorString(GetLastError()).c_str()));
|
||||
return false;
|
||||
}
|
||||
|
||||
// don't need process handle
|
||||
CloseHandle(procInfo.hProcess);
|
||||
|
||||
// save thread handle and thread ID if desired
|
||||
if (thread != NULL) {
|
||||
*thread = procInfo.hThread;
|
||||
}
|
||||
if (threadID != NULL) {
|
||||
*threadID = procInfo.dwThreadId;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static
|
||||
BOOL CALLBACK
|
||||
waitDlgProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
// only one wait dialog at a time!
|
||||
static CChildWaitInfo* info = NULL;
|
||||
|
||||
switch (message) {
|
||||
case WM_INITDIALOG:
|
||||
// save info pointer
|
||||
info = reinterpret_cast<CChildWaitInfo*>(lParam);
|
||||
|
||||
// save hwnd
|
||||
info->m_dialog = hwnd;
|
||||
|
||||
// signal ready
|
||||
SetEvent(info->m_ready);
|
||||
|
||||
return TRUE;
|
||||
|
||||
case WM_COMMAND:
|
||||
switch (LOWORD(wParam)) {
|
||||
case IDCANCEL:
|
||||
case IDOK:
|
||||
// signal stop
|
||||
SetEvent(info->m_stop);
|
||||
|
||||
// done
|
||||
EndDialog(hwnd, 0);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static
|
||||
DWORD WINAPI
|
||||
waitForChildThread(LPVOID vinfo)
|
||||
{
|
||||
CChildWaitInfo* info = reinterpret_cast<CChildWaitInfo*>(vinfo);
|
||||
|
||||
// wait for ready
|
||||
WaitForSingleObject(info->m_ready, INFINITE);
|
||||
|
||||
// wait for thread to complete or stop event
|
||||
HANDLE handles[2];
|
||||
handles[0] = info->m_child;
|
||||
handles[1] = info->m_stop;
|
||||
DWORD n = WaitForMultipleObjects(2, handles, FALSE, INFINITE);
|
||||
|
||||
// if stop was raised then terminate child and wait for it
|
||||
if (n == WAIT_OBJECT_0 + 1) {
|
||||
PostThreadMessage(info->m_childID, WM_QUIT, 0, 0);
|
||||
WaitForSingleObject(info->m_child, INFINITE);
|
||||
}
|
||||
|
||||
// otherwise post IDOK to dialog box
|
||||
else {
|
||||
PostMessage(info->m_dialog, WM_COMMAND, MAKEWPARAM(IDOK, 0), 0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
waitForChild(HWND hwnd, HANDLE thread, DWORD threadID)
|
||||
{
|
||||
// prepare info for child wait dialog and thread
|
||||
CChildWaitInfo info;
|
||||
info.m_dialog = NULL;
|
||||
info.m_child = thread;
|
||||
info.m_childID = threadID;
|
||||
info.m_ready = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
info.m_stop = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
|
||||
// create a thread to wait on the child thread and event
|
||||
DWORD id;
|
||||
HANDLE waiter = CreateThread(NULL, 0, &waitForChildThread, &info,0, &id);
|
||||
|
||||
// do dialog that let's the user terminate the test
|
||||
DialogBoxParam(s_instance, MAKEINTRESOURCE(IDD_WAIT), hwnd,
|
||||
(DLGPROC)waitDlgProc, (LPARAM)&info);
|
||||
|
||||
// force the waiter thread to finish and wait for it
|
||||
SetEvent(info.m_ready);
|
||||
SetEvent(info.m_stop);
|
||||
WaitForSingleObject(waiter, INFINITE);
|
||||
|
||||
// clean up
|
||||
CloseHandle(waiter);
|
||||
CloseHandle(info.m_ready);
|
||||
CloseHandle(info.m_stop);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
initMainWindow(HWND hwnd)
|
||||
{
|
||||
// append version number to title
|
||||
CString titleFormat = getString(IDS_TITLE);
|
||||
setWindowText(hwnd, CStringUtil::format(titleFormat.c_str(), VERSION));
|
||||
|
||||
// load configuration
|
||||
bool configLoaded =
|
||||
loadConfig(ARG->m_config, s_configTime, s_userConfig);
|
||||
if (configLoaded) {
|
||||
s_lastConfig = ARG->m_config;
|
||||
}
|
||||
|
||||
// get settings from registry
|
||||
bool isServer = configLoaded;
|
||||
int debugLevel = s_defaultDebug;
|
||||
CString server;
|
||||
HKEY key = CArchMiscWindows::openKey(HKEY_CURRENT_USER, getSettingsPath());
|
||||
if (key != NULL) {
|
||||
if (isServer && CArchMiscWindows::hasValue(key, "isServer")) {
|
||||
isServer = (CArchMiscWindows::readValueInt(key, "isServer") != 0);
|
||||
}
|
||||
if (CArchMiscWindows::hasValue(key, "debug")) {
|
||||
debugLevel = static_cast<int>(
|
||||
CArchMiscWindows::readValueInt(key, "debug"));
|
||||
if (debugLevel < 0) {
|
||||
debugLevel = 0;
|
||||
}
|
||||
else if (debugLevel > CLog::kDEBUG2) {
|
||||
debugLevel = CLog::kDEBUG2;
|
||||
}
|
||||
}
|
||||
server = CArchMiscWindows::readValueString(key, "server");
|
||||
CArchMiscWindows::closeKey(key);
|
||||
}
|
||||
|
||||
// choose client/server radio buttons
|
||||
HWND child;
|
||||
child = getItem(hwnd, IDC_MAIN_CLIENT_RADIO);
|
||||
setItemChecked(child, !isServer);
|
||||
child = getItem(hwnd, IDC_MAIN_SERVER_RADIO);
|
||||
setItemChecked(child, isServer);
|
||||
|
||||
// set server name
|
||||
child = getItem(hwnd, IDC_MAIN_CLIENT_SERVER_NAME_EDIT);
|
||||
setWindowText(child, server);
|
||||
|
||||
// debug level
|
||||
child = getItem(hwnd, IDC_MAIN_DEBUG);
|
||||
for (unsigned int i = 0; i < sizeof(s_debugName) /
|
||||
sizeof(s_debugName[0]); ++i) {
|
||||
SendMessage(child, CB_ADDSTRING, 0, (LPARAM)s_debugName[i][0]);
|
||||
}
|
||||
SendMessage(child, CB_SETCURSEL, debugLevel, 0);
|
||||
|
||||
// update controls
|
||||
enableMainWindowControls(hwnd);
|
||||
}
|
||||
|
||||
static
|
||||
bool
|
||||
saveMainWindow(HWND hwnd, SaveMode mode, CString* cmdLineOut = NULL)
|
||||
{
|
||||
DWORD errorID = 0;
|
||||
CString arg;
|
||||
CString cmdLine;
|
||||
|
||||
// save dialog state
|
||||
bool isClient = isClientChecked(hwnd);
|
||||
HKEY key = CArchMiscWindows::addKey(HKEY_CURRENT_USER, getSettingsPath());
|
||||
if (key != NULL) {
|
||||
HWND child;
|
||||
child = getItem(hwnd, IDC_MAIN_CLIENT_SERVER_NAME_EDIT);
|
||||
CArchMiscWindows::setValue(key, "server", getWindowText(child));
|
||||
child = getItem(hwnd, IDC_MAIN_DEBUG);
|
||||
CArchMiscWindows::setValue(key, "debug",
|
||||
SendMessage(child, CB_GETCURSEL, 0, 0));
|
||||
CArchMiscWindows::setValue(key, "isServer", isClient ? 0 : 1);
|
||||
CArchMiscWindows::closeKey(key);
|
||||
}
|
||||
|
||||
// save user's configuration
|
||||
if (!s_userConfig || ARG->m_config != s_lastConfig) {
|
||||
time_t t;
|
||||
if (!saveConfig(ARG->m_config, false, t)) {
|
||||
errorID = IDS_SAVE_FAILED;
|
||||
arg = getErrorString(GetLastError());
|
||||
goto failed;
|
||||
}
|
||||
if (s_userConfig) {
|
||||
s_configTime = t;
|
||||
s_lastConfig = ARG->m_config;
|
||||
}
|
||||
}
|
||||
|
||||
// save autostart configuration
|
||||
if (CAutoStart::isDaemonInstalled()) {
|
||||
if (s_userConfig || ARG->m_config != s_lastConfig) {
|
||||
time_t t;
|
||||
if (!saveConfig(ARG->m_config, true, t)) {
|
||||
errorID = IDS_AUTOSTART_SAVE_FAILED;
|
||||
arg = getErrorString(GetLastError());
|
||||
goto failed;
|
||||
}
|
||||
if (!s_userConfig) {
|
||||
s_configTime = t;
|
||||
s_lastConfig = ARG->m_config;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// get autostart command
|
||||
cmdLine = getCommandLine(hwnd, false, mode == SAVE_QUITING);
|
||||
if (cmdLineOut != NULL) {
|
||||
*cmdLineOut = cmdLine;
|
||||
}
|
||||
if (cmdLine.empty()) {
|
||||
return (mode == SAVE_QUITING);
|
||||
}
|
||||
|
||||
// save autostart command
|
||||
if (CAutoStart::isDaemonInstalled()) {
|
||||
try {
|
||||
CAutoStart::reinstallDaemon(isClient, cmdLine);
|
||||
CAutoStart::uninstallDaemons(!isClient);
|
||||
}
|
||||
catch (XArchDaemon& e) {
|
||||
errorID = IDS_INSTALL_GENERIC_ERROR;
|
||||
arg = e.what();
|
||||
goto failed;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
failed:
|
||||
CString errorMessage =
|
||||
CStringUtil::format(getString(errorID).c_str(), arg.c_str());
|
||||
if (mode == SAVE_QUITING) {
|
||||
errorMessage += "\n";
|
||||
errorMessage += getString(IDS_UNSAVED_DATA_REALLY_QUIT);
|
||||
if (askVerify(hwnd, errorMessage)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (mode == SAVE_NORMAL) {
|
||||
showError(hwnd, errorMessage);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static
|
||||
LRESULT CALLBACK
|
||||
mainWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch (message) {
|
||||
case WM_ACTIVATE:
|
||||
if (LOWORD(wParam) != WA_INACTIVE) {
|
||||
// activated
|
||||
|
||||
// see if the configuration changed
|
||||
if (isConfigNewer(s_configTime, s_userConfig)) {
|
||||
CString message = getString(IDS_CONFIG_CHANGED);
|
||||
if (askVerify(hwnd, message)) {
|
||||
time_t configTime;
|
||||
bool userConfig;
|
||||
CConfig newConfig;
|
||||
if (loadConfig(newConfig, configTime, userConfig) &&
|
||||
userConfig == s_userConfig) {
|
||||
ARG->m_config = newConfig;
|
||||
s_lastConfig = ARG->m_config;
|
||||
}
|
||||
else {
|
||||
message = getString(IDS_LOAD_FAILED);
|
||||
showError(hwnd, message);
|
||||
s_lastConfig = CConfig();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// deactivated; write configuration
|
||||
if (!isShowingDialog()) {
|
||||
saveMainWindow(hwnd, SAVE_QUIET);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_COMMAND:
|
||||
switch (LOWORD(wParam)) {
|
||||
case IDCANCEL:
|
||||
// save data
|
||||
if (saveMainWindow(hwnd, SAVE_QUITING)) {
|
||||
// quit
|
||||
PostQuitMessage(0);
|
||||
}
|
||||
return 0;
|
||||
|
||||
case IDOK:
|
||||
case IDC_MAIN_TEST: {
|
||||
// note if testing
|
||||
const bool testing = (LOWORD(wParam) == IDC_MAIN_TEST);
|
||||
|
||||
// save data
|
||||
if (saveMainWindow(hwnd, SAVE_NORMAL)) {
|
||||
// launch child app
|
||||
DWORD threadID;
|
||||
HANDLE thread;
|
||||
if (!launchApp(hwnd, testing, &thread, &threadID)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// handle child program
|
||||
if (testing) {
|
||||
// wait for process to stop, allowing the user to kill it
|
||||
waitForChild(hwnd, thread, threadID);
|
||||
|
||||
// clean up
|
||||
CloseHandle(thread);
|
||||
}
|
||||
else {
|
||||
// don't need thread handle
|
||||
if (thread != NULL) {
|
||||
CloseHandle(thread);
|
||||
}
|
||||
|
||||
// notify of success
|
||||
askOkay(hwnd, getString(IDS_STARTED_TITLE),
|
||||
getString(IDS_STARTED));
|
||||
|
||||
// quit
|
||||
PostQuitMessage(0);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
case IDC_MAIN_AUTOSTART: {
|
||||
CString cmdLine;
|
||||
if (saveMainWindow(hwnd, SAVE_NORMAL, &cmdLine)) {
|
||||
// run dialog
|
||||
CAutoStart autoStart(hwnd, !isClientChecked(hwnd), cmdLine);
|
||||
autoStart.doModal();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
case IDC_MAIN_CLIENT_RADIO:
|
||||
case IDC_MAIN_SERVER_RADIO:
|
||||
enableMainWindowControls(hwnd);
|
||||
return 0;
|
||||
|
||||
case IDC_MAIN_SCREENS:
|
||||
s_screensLinks->doModal();
|
||||
break;
|
||||
|
||||
case IDC_MAIN_OPTIONS:
|
||||
s_globalOptions->doModal();
|
||||
break;
|
||||
|
||||
case IDC_MAIN_ADVANCED:
|
||||
s_advancedOptions->doModal(isClientChecked(hwnd));
|
||||
break;
|
||||
|
||||
case IDC_MAIN_HOTKEYS:
|
||||
s_hotkeyOptions->doModal();
|
||||
break;
|
||||
|
||||
case IDC_MAIN_INFO:
|
||||
s_info->doModal();
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return DefDlgProc(hwnd, message, wParam, lParam);
|
||||
}
|
||||
|
||||
int WINAPI
|
||||
WinMain(HINSTANCE instance, HINSTANCE, LPSTR cmdLine, int nCmdShow)
|
||||
{
|
||||
CArch arch(instance);
|
||||
CLOG;
|
||||
CArgs args;
|
||||
|
||||
s_instance = instance;
|
||||
|
||||
// if "/uninstall" is on the command line then just stop and
|
||||
// uninstall the service and quit. this is the only option
|
||||
// but we ignore any others.
|
||||
if (CString(cmdLine).find("/uninstall") != CString::npos) {
|
||||
CAutoStart::uninstallDaemons(false);
|
||||
CAutoStart::uninstallDaemons(true);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// register main window (dialog) class
|
||||
WNDCLASSEX classInfo;
|
||||
classInfo.cbSize = sizeof(classInfo);
|
||||
classInfo.style = CS_HREDRAW | CS_VREDRAW;
|
||||
classInfo.lpfnWndProc = &mainWndProc;
|
||||
classInfo.cbClsExtra = 0;
|
||||
classInfo.cbWndExtra = DLGWINDOWEXTRA;
|
||||
classInfo.hInstance = instance;
|
||||
classInfo.hIcon = (HICON)LoadImage(instance,
|
||||
MAKEINTRESOURCE(IDI_SYNERGY),
|
||||
IMAGE_ICON,
|
||||
32, 32, LR_SHARED);
|
||||
classInfo.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||
classInfo.hbrBackground = reinterpret_cast<HBRUSH>(COLOR_3DFACE + 1);
|
||||
classInfo.lpszMenuName = NULL;
|
||||
classInfo.lpszClassName = s_mainClass;
|
||||
classInfo.hIconSm = (HICON)LoadImage(instance,
|
||||
MAKEINTRESOURCE(IDI_SYNERGY),
|
||||
IMAGE_ICON,
|
||||
16, 16, LR_SHARED);
|
||||
RegisterClassEx(&classInfo);
|
||||
|
||||
// create main window
|
||||
HWND mainWindow = CreateDialog(s_instance,
|
||||
MAKEINTRESOURCE(IDD_MAIN), 0, NULL);
|
||||
|
||||
// prep windows
|
||||
initMainWindow(mainWindow);
|
||||
s_globalOptions = new CGlobalOptions(mainWindow, &ARG->m_config);
|
||||
s_advancedOptions = new CAdvancedOptions(mainWindow, &ARG->m_config);
|
||||
s_hotkeyOptions = new CHotkeyOptions(mainWindow, &ARG->m_config);
|
||||
s_screensLinks = new CScreensLinks(mainWindow, &ARG->m_config);
|
||||
s_info = new CInfo(mainWindow);
|
||||
|
||||
// show window
|
||||
ShowWindow(mainWindow, nCmdShow);
|
||||
|
||||
// main loop
|
||||
MSG msg;
|
||||
bool done = false;
|
||||
do {
|
||||
switch (GetMessage(&msg, NULL, 0, 0)) {
|
||||
case -1:
|
||||
// error
|
||||
break;
|
||||
|
||||
case 0:
|
||||
// quit
|
||||
done = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (!IsDialogMessage(mainWindow, &msg)) {
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
break;
|
||||
}
|
||||
} while (!done);
|
||||
|
||||
return msg.wParam;
|
||||
}
|
||||
617
cmd/launcher/launcher.rc
Normal file
@@ -0,0 +1,617 @@
|
||||
//Microsoft Developer Studio generated resource script.
|
||||
//
|
||||
#include "resource.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#include <winresrc.h>
|
||||
#if !defined(IDC_STATIC)
|
||||
#define IDC_STATIC (-1)
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// English (U.S.) resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
||||
#ifdef _WIN32
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
#pragma code_page(1252)
|
||||
#endif //_WIN32
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEXTINCLUDE
|
||||
//
|
||||
|
||||
1 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"resource.h\0"
|
||||
END
|
||||
|
||||
2 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"#include <winresrc.h>\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
3 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Dialog
|
||||
//
|
||||
|
||||
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 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,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 && 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 "&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
|
||||
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION
|
||||
CAPTION "Add Screen"
|
||||
FONT 8, "MS Sans Serif"
|
||||
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,24,ES_MULTILINE |
|
||||
ES_AUTOVSCROLL | ES_AUTOHSCROLL | ES_WANTRETURN
|
||||
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,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,144,11,8
|
||||
COMBOBOX IDC_ADD_MOD_CTRL,37,142,48,60,CBS_DROPDOWNLIST |
|
||||
WS_VSCROLL | WS_TABSTOP
|
||||
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,128,17,8
|
||||
COMBOBOX IDC_ADD_MOD_META,125,126,48,60,CBS_DROPDOWNLIST |
|
||||
WS_VSCROLL | WS_TABSTOP
|
||||
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
|
||||
|
||||
IDD_WAIT DIALOG DISCARDABLE 0, 0, 186, 54
|
||||
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION
|
||||
CAPTION "Running Test..."
|
||||
FONT 8, "MS Sans Serif"
|
||||
BEGIN
|
||||
DEFPUSHBUTTON "Stop",IDOK,129,33,50,14
|
||||
LTEXT "Running synergy. Press Stop to end the test.",
|
||||
IDC_STATIC,7,7,172,15
|
||||
END
|
||||
|
||||
IDD_AUTOSTART DIALOG DISCARDABLE 0, 0, 195, 189
|
||||
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "Auto Start"
|
||||
FONT 8, "MS Sans Serif"
|
||||
BEGIN
|
||||
DEFPUSHBUTTON "Close",IDCANCEL,138,168,50,14
|
||||
LTEXT "Synergy can be configured to start automatically when you log in. If you have sufficient access rights, you can instead configure synergy to start automatically when your computer starts.",
|
||||
IDC_STATIC,7,7,181,33
|
||||
LTEXT "You have sufficient access rights to install and uninstall Auto Start for all users or for just yourself.",
|
||||
IDC_AUTOSTART_PERMISSION_MSG,7,69,181,17
|
||||
LTEXT "Synergy is configured to start automatically when the system starts.",
|
||||
IDC_AUTOSTART_INSTALLED_MSG,7,93,181,17
|
||||
GROUPBOX "When &You Log In",IDC_STATIC,7,119,84,40
|
||||
PUSHBUTTON "Install",IDC_AUTOSTART_INSTALL_USER,23,133,50,14
|
||||
GROUPBOX "When &Computer Starts",IDC_STATIC,104,119,84,40
|
||||
PUSHBUTTON "Install",IDC_AUTOSTART_INSTALL_SYSTEM,119,134,50,14
|
||||
LTEXT "Synergy can be configured to start automatically when the computer starts or when you log in but not both.",
|
||||
IDC_STATIC,7,43,181,17
|
||||
END
|
||||
|
||||
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"
|
||||
BEGIN
|
||||
LTEXT "It's easy to unintentionally switch screens when the pointer is near a screen's edge. Synergy can prevent switching until certain conditions are met to reduce unintentional switching.",
|
||||
IDC_STATIC,7,7,191,26
|
||||
LTEXT "Synergy can wait to switch until the cursor has been at a screen's edge for some amount of time.",
|
||||
IDC_STATIC,7,37,193,16
|
||||
CONTROL "Switch after waiting",IDC_GLOBAL_DELAY_CHECK,"Button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP,7,59,77,10
|
||||
EDITTEXT IDC_GLOBAL_DELAY_TIME,112,58,45,12,ES_AUTOHSCROLL |
|
||||
ES_NUMBER
|
||||
LTEXT "ms",IDC_STATIC,159,60,10,8
|
||||
LTEXT "Synergy can switch only when the cursor hits a screen edge twice within some amount of time.",
|
||||
IDC_STATIC,7,77,193,16
|
||||
CONTROL "Switch on double tap within",IDC_GLOBAL_TWO_TAP_CHECK,
|
||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,99,103,10
|
||||
EDITTEXT IDC_GLOBAL_TWO_TAP_TIME,112,98,45,12,ES_AUTOHSCROLL |
|
||||
ES_NUMBER
|
||||
LTEXT "ms",IDC_STATIC,159,100,10,8
|
||||
LTEXT "Synergy can periodically check that clients are still alive and connected. Use this only if synergy doesn't detect when clients disconnect.",
|
||||
IDC_STATIC,7,122,193,24
|
||||
CONTROL "Check clients every",IDC_GLOBAL_HEARTBEAT_CHECK,"Button",
|
||||
BS_AUTOCHECKBOX | WS_TABSTOP,7,153,78,10
|
||||
EDITTEXT IDC_GLOBAL_HEARTBEAT_TIME,112,152,45,12,ES_AUTOHSCROLL |
|
||||
ES_NUMBER
|
||||
LTEXT "ms",IDC_STATIC,159,154,10,8
|
||||
LTEXT "Synergy can synchronize screen savers across all screens.",
|
||||
IDC_STATIC,7,176,193,8
|
||||
CONTROL "Synchronize screen savers",IDC_GLOBAL_SCREENSAVER_SYNC,
|
||||
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,192,101,10
|
||||
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
|
||||
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
|
||||
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
|
||||
CAPTION "Advanced Options"
|
||||
FONT 8, "MS Sans Serif"
|
||||
BEGIN
|
||||
LTEXT "Synergy normally uses this computer's name as its screen name. Enter another name here if you want to use a different screen name.",
|
||||
IDC_STATIC,7,7,216,19
|
||||
LTEXT "Screen &Name:",IDC_STATIC,7,34,46,8
|
||||
EDITTEXT IDC_ADVANCED_NAME_EDIT,63,32,106,12,ES_AUTOHSCROLL
|
||||
LTEXT "Synergy normally uses a particular network port number. Enter an alternative port here. (The server and all clients must use the same port number.)",
|
||||
IDC_STATIC,7,56,216,26
|
||||
LTEXT "&Port:",IDC_STATIC,7,90,16,8
|
||||
EDITTEXT IDC_ADVANCED_PORT_EDIT,63,88,40,12,ES_AUTOHSCROLL |
|
||||
ES_NUMBER
|
||||
LTEXT "The server normally listens for client connections on all network interfaces. Enter the address of a particular interface to listen on just that interface.",
|
||||
IDC_STATIC,7,110,216,26
|
||||
LTEXT "&Interface:",IDC_STATIC,7,144,31,8
|
||||
EDITTEXT IDC_ADVANCED_INTERFACE_EDIT,63,142,81,12,ES_AUTOHSCROLL
|
||||
PUSHBUTTON "&Defaults",IDC_ADVANCED_DEFAULTS,7,165,50,14
|
||||
DEFPUSHBUTTON "OK",IDOK,118,165,50,14
|
||||
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, 218
|
||||
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
|
||||
CONTROL "Keyboard broadcasting:",
|
||||
IDC_HOTKEY_ACTION_KEYBOARD_BROADCAST,"Button",
|
||||
BS_AUTORADIOBUTTON,7,133,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
|
||||
COMBOBOX IDC_HOTKEY_ACTION_KEYBOARD_BROADCAST_LIST,106,131,53,58,
|
||||
CBS_DROPDOWNLIST | WS_VSCROLL | WS_TABSTOP
|
||||
PUSHBUTTON "...",IDC_HOTKEY_ACTION_KEYBOARD_BROADCAST_SCREENS,
|
||||
162,131,14,12
|
||||
LTEXT "Action takes place &when:",IDC_STATIC,7,153,81,8
|
||||
CONTROL "Hot key is pressed",IDC_HOTKEY_ACTION_ON_ACTIVATE,
|
||||
"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,7,165,74,10
|
||||
CONTROL "Hot key is released",IDC_HOTKEY_ACTION_ON_DEACTIVATE,
|
||||
"Button",BS_AUTORADIOBUTTON,7,177,76,10
|
||||
DEFPUSHBUTTON "OK",IDOK,70,197,50,14
|
||||
PUSHBUTTON "Cancel",IDCANCEL,126,197,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
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// DESIGNINFO
|
||||
//
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
GUIDELINES DESIGNINFO DISCARDABLE
|
||||
BEGIN
|
||||
IDD_MAIN, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 293
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 192
|
||||
END
|
||||
|
||||
IDD_ADD, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 185
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 247
|
||||
END
|
||||
|
||||
IDD_WAIT, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 179
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 47
|
||||
END
|
||||
|
||||
IDD_AUTOSTART, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 188
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 182
|
||||
END
|
||||
|
||||
IDD_GLOBAL_OPTIONS, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 200
|
||||
TOPMARGIN, 7
|
||||
BOTTOMMARGIN, 283
|
||||
END
|
||||
|
||||
IDD_ADVANCED_OPTIONS, DIALOG
|
||||
BEGIN
|
||||
LEFTMARGIN, 7
|
||||
RIGHTMARGIN, 223
|
||||
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
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Icon
|
||||
//
|
||||
|
||||
// Icon with lowest ID value placed first to ensure application icon
|
||||
// remains consistent on all systems.
|
||||
IDI_SYNERGY ICON DISCARDABLE "synergy.ico"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// String Table
|
||||
//
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
BEGIN
|
||||
IDS_ERROR "Error"
|
||||
IDS_INVALID_SCREEN_NAME "Screen name `%{1}' is invalid."
|
||||
IDS_DUPLICATE_SCREEN_NAME "The screen name `%{1}' is already being used."
|
||||
IDS_SCREEN_NAME_IS_ALIAS "A name may not be an alias of itself."
|
||||
IDS_VERIFY "Confirm"
|
||||
IDS_UNSAVED_DATA_REALLY_QUIT "You have unsaved changes. Really quit?"
|
||||
IDS_UNKNOWN_SCREEN_NAME "The screen name `%{1}' is not in the layout."
|
||||
IDS_INVALID_PORT "The port `%{1}' is invalid. It must be between 1 and 65535 inclusive. %{2} is the standard port."
|
||||
IDS_SAVE_FAILED "Failed to save configuration: %{1}"
|
||||
IDS_STARTUP_FAILED "Failed to start synergy: %{1}"
|
||||
IDS_STARTED_TITLE "Started"
|
||||
IDS_STARTED "Synergy was successfully started. Use the task manager or tray icon to terminate it."
|
||||
IDS_UNINSTALL_TITLE "Removed Auto-Start"
|
||||
END
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
BEGIN
|
||||
IDS_AUTOSTART_PERMISSION_SYSTEM
|
||||
"You have sufficient access rights to install and uninstall Auto Start for all users."
|
||||
IDS_AUTOSTART_PERMISSION_USER
|
||||
"You have sufficient access rights to install and uninstall Auto Start for just yourself."
|
||||
IDS_AUTOSTART_PERMISSION_NONE
|
||||
"You do not have sufficient access rights to install or uninstall Auto Start."
|
||||
IDS_AUTOSTART_INSTALLED_SYSTEM
|
||||
"Synergy is configured to start automatically when the system starts."
|
||||
IDS_AUTOSTART_INSTALLED_USER
|
||||
"Synergy is configured to start automatically when you log in."
|
||||
IDS_AUTOSTART_INSTALLED_NONE
|
||||
"Synergy is not configured to start automatically."
|
||||
IDS_INSTALL_LABEL "Install"
|
||||
IDS_UNINSTALL_LABEL "Uninstall"
|
||||
IDS_INSTALL_GENERIC_ERROR "Install failed: %{1}"
|
||||
IDS_UNINSTALL_GENERIC_ERROR "Uninstall failed: %{1}"
|
||||
IDS_INSTALL_TITLE "Installed Auto-Start"
|
||||
IDS_INSTALLED_SYSTEM "Installed auto-start. Synergy will automatically start each time you start your computer."
|
||||
IDS_INSTALLED_USER "Installed auto-start. Synergy will automatically start each time you log in."
|
||||
END
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
BEGIN
|
||||
IDS_UNINSTALLED_SYSTEM "Removed auto-start. Synergy will not automatically start each time you start or reboot your computer."
|
||||
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 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_MODE_OFF "off"
|
||||
IDS_MODE_ON "on"
|
||||
IDS_MODE_TOGGLE "toggle"
|
||||
IDS_ALL_SCREENS "All Screens"
|
||||
IDS_ACTIVE_SCREEN "Active Screen"
|
||||
END
|
||||
|
||||
#endif // English (U.S.) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 3 resource.
|
||||
//
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
|
||||
186
cmd/launcher/resource.h
Normal file
@@ -0,0 +1,186 @@
|
||||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Developer Studio generated include file.
|
||||
// Used by launcher.rc
|
||||
//
|
||||
#define IDS_ERROR 1
|
||||
#define IDS_INVALID_SCREEN_NAME 2
|
||||
#define IDS_DUPLICATE_SCREEN_NAME 3
|
||||
#define IDS_SCREEN_NAME_IS_ALIAS 4
|
||||
#define IDS_VERIFY 5
|
||||
#define IDS_UNSAVED_DATA_REALLY_QUIT 6
|
||||
#define IDS_UNKNOWN_SCREEN_NAME 7
|
||||
#define IDS_INVALID_PORT 8
|
||||
#define IDS_SAVE_FAILED 9
|
||||
#define IDS_STARTUP_FAILED 10
|
||||
#define IDS_STARTED_TITLE 11
|
||||
#define IDS_STARTED 12
|
||||
#define IDS_INSTALL_FAILED 13
|
||||
#define IDS_UNINSTALL_TITLE 14
|
||||
#define IDS_UNINSTALLED 15
|
||||
#define IDS_UNINSTALL_FAILED 16
|
||||
#define IDS_CLIENT 17
|
||||
#define IDS_SERVER 18
|
||||
#define IDS_AUTOSTART_PERMISSION_SYSTEM 19
|
||||
#define IDS_AUTOSTART_PERMISSION_USER 20
|
||||
#define IDS_AUTOSTART_PERMISSION_NONE 21
|
||||
#define IDS_AUTOSTART_INSTALLED_SYSTEM 22
|
||||
#define IDS_AUTOSTART_INSTALLED_USER 23
|
||||
#define IDS_AUTOSTART_INSTALLED_NONE 24
|
||||
#define IDS_INSTALL_LABEL 25
|
||||
#define IDS_UNINSTALL_LABEL 26
|
||||
#define IDS_INSTALL_GENERIC_ERROR 27
|
||||
#define IDS_UNINSTALL_GENERIC_ERROR 28
|
||||
#define IDS_INSTALL_TITLE 29
|
||||
#define IDS_INSTALLED_SYSTEM 30
|
||||
#define IDS_INSTALLED_USER 31
|
||||
#define IDS_UNINSTALLED_SYSTEM 32
|
||||
#define IDS_UNINSTALLED_USER 33
|
||||
#define IDS_INVALID_SERVER_NAME 34
|
||||
#define IDS_TITLE 35
|
||||
#define IDS_SERVER_IS_CLIENT 36
|
||||
#define IDS_ADD_SCREEN 37
|
||||
#define IDS_EDIT_SCREEN 38
|
||||
#define IDS_INVALID_TIME 39
|
||||
#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_MODE_OFF 57
|
||||
#define IDS_MODE_ON 58
|
||||
#define IDS_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
|
||||
#define IDI_SYNERGY 104
|
||||
#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_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_HOTKEYS 1010
|
||||
#define IDC_MAIN_DEBUG 1011
|
||||
#define IDC_ADD_SCREEN_NAME_EDIT 1020
|
||||
#define IDC_ADD_ALIASES_EDIT 1021
|
||||
#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_ADD_HD_CAPS_CHECK 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_ADVANCED_INTERFACE_EDIT 1040
|
||||
#define IDC_GLOBAL_DELAY_CHECK 1041
|
||||
#define IDC_GLOBAL_DELAY_TIME 1042
|
||||
#define IDC_GLOBAL_TWO_TAP_CHECK 1043
|
||||
#define IDC_ADD_MOD_SHIFT 1043
|
||||
#define IDC_GLOBAL_TWO_TAP_TIME 1044
|
||||
#define IDC_ADD_MOD_CTRL 1044
|
||||
#define IDC_ADD_MOD_ALT 1045
|
||||
#define IDC_GLOBAL_HEARTBEAT_CHECK 1045
|
||||
#define IDC_ADD_MOD_META 1046
|
||||
#define IDC_GLOBAL_HEARTBEAT_TIME 1046
|
||||
#define IDC_ADD_MOD_SUPER 1047
|
||||
#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
|
||||
#define IDC_HOTKEY_ACTION_KEYBOARD_BROADCAST 1099
|
||||
#define IDC_HOTKEY_ACTION_KEYBOARD_BROADCAST_LIST 1100
|
||||
#define IDC_HOTKEY_ACTION_KEYBOARD_BROADCAST_SCREENS 1101
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NO_MFC 1
|
||||
#define _APS_NEXT_RESOURCE_VALUE 116
|
||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||
#define _APS_NEXT_CONTROL_VALUE 1102
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
||||
BIN
cmd/launcher/synergy.ico
Normal file
|
After Width: | Height: | Size: 8.3 KiB |
136
cmd/synergyc/CClientTaskBarReceiver.cpp
Normal file
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "CClientTaskBarReceiver.h"
|
||||
#include "CClient.h"
|
||||
#include "CLock.h"
|
||||
#include "CStringUtil.h"
|
||||
#include "IEventQueue.h"
|
||||
#include "CArch.h"
|
||||
#include "Version.h"
|
||||
|
||||
//
|
||||
// CClientTaskBarReceiver
|
||||
//
|
||||
|
||||
CClientTaskBarReceiver::CClientTaskBarReceiver() :
|
||||
m_state(kNotRunning)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
CClientTaskBarReceiver::~CClientTaskBarReceiver()
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
void
|
||||
CClientTaskBarReceiver::updateStatus(CClient* client, const CString& errorMsg)
|
||||
{
|
||||
{
|
||||
// update our status
|
||||
m_errorMessage = errorMsg;
|
||||
if (client == NULL) {
|
||||
if (m_errorMessage.empty()) {
|
||||
m_state = kNotRunning;
|
||||
}
|
||||
else {
|
||||
m_state = kNotWorking;
|
||||
}
|
||||
}
|
||||
else {
|
||||
m_server = client->getServerAddress().getHostname();
|
||||
|
||||
if (client->isConnected()) {
|
||||
m_state = kConnected;
|
||||
}
|
||||
else if (client->isConnecting()) {
|
||||
m_state = kConnecting;
|
||||
}
|
||||
else {
|
||||
m_state = kNotConnected;
|
||||
}
|
||||
}
|
||||
|
||||
// let subclasses have a go
|
||||
onStatusChanged(client);
|
||||
}
|
||||
|
||||
// tell task bar
|
||||
ARCH->updateReceiver(this);
|
||||
}
|
||||
|
||||
CClientTaskBarReceiver::EState
|
||||
CClientTaskBarReceiver::getStatus() const
|
||||
{
|
||||
return m_state;
|
||||
}
|
||||
|
||||
const CString&
|
||||
CClientTaskBarReceiver::getErrorMessage() const
|
||||
{
|
||||
return m_errorMessage;
|
||||
}
|
||||
|
||||
void
|
||||
CClientTaskBarReceiver::quit()
|
||||
{
|
||||
EVENTQUEUE->addEvent(CEvent(CEvent::kQuit));
|
||||
}
|
||||
|
||||
void
|
||||
CClientTaskBarReceiver::onStatusChanged(CClient*)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
void
|
||||
CClientTaskBarReceiver::lock() const
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
void
|
||||
CClientTaskBarReceiver::unlock() const
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
std::string
|
||||
CClientTaskBarReceiver::getToolTip() const
|
||||
{
|
||||
switch (m_state) {
|
||||
case kNotRunning:
|
||||
return CStringUtil::print("%s: Not running", kAppVersion);
|
||||
|
||||
case kNotWorking:
|
||||
return CStringUtil::print("%s: %s",
|
||||
kAppVersion, m_errorMessage.c_str());
|
||||
|
||||
case kNotConnected:
|
||||
return CStringUtil::print("%s: Not connected: %s",
|
||||
kAppVersion, m_errorMessage.c_str());
|
||||
|
||||
case kConnecting:
|
||||
return CStringUtil::print("%s: Connecting to %s...",
|
||||
kAppVersion, m_server.c_str());
|
||||
|
||||
case kConnected:
|
||||
return CStringUtil::print("%s: Connected to %s",
|
||||
kAppVersion, m_server.c_str());
|
||||
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
83
cmd/synergyc/CClientTaskBarReceiver.h
Normal file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* 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 CCLIENTTASKBARRECEIVER_H
|
||||
#define CCLIENTTASKBARRECEIVER_H
|
||||
|
||||
#include "CString.h"
|
||||
#include "IArchTaskBarReceiver.h"
|
||||
|
||||
class CClient;
|
||||
|
||||
//! Implementation of IArchTaskBarReceiver for the synergy server
|
||||
class CClientTaskBarReceiver : public IArchTaskBarReceiver {
|
||||
public:
|
||||
CClientTaskBarReceiver();
|
||||
virtual ~CClientTaskBarReceiver();
|
||||
|
||||
//! @name manipulators
|
||||
//@{
|
||||
|
||||
//! Update status
|
||||
/*!
|
||||
Determine the status and query required information from the client.
|
||||
*/
|
||||
void updateStatus(CClient*, const CString& errorMsg);
|
||||
|
||||
//@}
|
||||
|
||||
// IArchTaskBarReceiver overrides
|
||||
virtual void showStatus() = 0;
|
||||
virtual void runMenu(int x, int y) = 0;
|
||||
virtual void primaryAction() = 0;
|
||||
virtual void lock() const;
|
||||
virtual void unlock() const;
|
||||
virtual const Icon getIcon() const = 0;
|
||||
virtual std::string getToolTip() const;
|
||||
|
||||
protected:
|
||||
enum EState {
|
||||
kNotRunning,
|
||||
kNotWorking,
|
||||
kNotConnected,
|
||||
kConnecting,
|
||||
kConnected,
|
||||
kMaxState
|
||||
};
|
||||
|
||||
//! Get status
|
||||
EState getStatus() const;
|
||||
|
||||
//! Get error message
|
||||
const CString& getErrorMessage() const;
|
||||
|
||||
//! Quit app
|
||||
/*!
|
||||
Causes the application to quit gracefully
|
||||
*/
|
||||
void quit();
|
||||
|
||||
//! Status change notification
|
||||
/*!
|
||||
Called when status changes. The default implementation does nothing.
|
||||
*/
|
||||
virtual void onStatusChanged(CClient* client);
|
||||
|
||||
private:
|
||||
EState m_state;
|
||||
CString m_errorMessage;
|
||||
CString m_server;
|
||||
};
|
||||
|
||||
#endif
|
||||
346
cmd/synergyc/CMSWindowsClientTaskBarReceiver.cpp
Normal file
@@ -0,0 +1,346 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "CMSWindowsClientTaskBarReceiver.h"
|
||||
#include "CClient.h"
|
||||
#include "CMSWindowsClipboard.h"
|
||||
#include "LogOutputters.h"
|
||||
#include "BasicTypes.h"
|
||||
#include "CArch.h"
|
||||
#include "CArchTaskBarWindows.h"
|
||||
#include "resource.h"
|
||||
|
||||
//
|
||||
// CMSWindowsClientTaskBarReceiver
|
||||
//
|
||||
|
||||
const UINT CMSWindowsClientTaskBarReceiver::s_stateToIconID[kMaxState] =
|
||||
{
|
||||
IDI_TASKBAR_NOT_RUNNING,
|
||||
IDI_TASKBAR_NOT_WORKING,
|
||||
IDI_TASKBAR_NOT_CONNECTED,
|
||||
IDI_TASKBAR_NOT_CONNECTED,
|
||||
IDI_TASKBAR_CONNECTED
|
||||
};
|
||||
|
||||
CMSWindowsClientTaskBarReceiver::CMSWindowsClientTaskBarReceiver(
|
||||
HINSTANCE appInstance, const CBufferedLogOutputter* logBuffer) :
|
||||
CClientTaskBarReceiver(),
|
||||
m_appInstance(appInstance),
|
||||
m_window(NULL),
|
||||
m_logBuffer(logBuffer)
|
||||
{
|
||||
for (UInt32 i = 0; i < kMaxState; ++i) {
|
||||
m_icon[i] = loadIcon(s_stateToIconID[i]);
|
||||
}
|
||||
m_menu = LoadMenu(m_appInstance, MAKEINTRESOURCE(IDR_TASKBAR));
|
||||
|
||||
// don't create the window yet. we'll create it on demand. this
|
||||
// has the side benefit of being created in the thread used for
|
||||
// the task bar. that's good because it means the existence of
|
||||
// the window won't prevent changing the main thread's desktop.
|
||||
|
||||
// add ourself to the task bar
|
||||
ARCH->addReceiver(this);
|
||||
}
|
||||
|
||||
CMSWindowsClientTaskBarReceiver::~CMSWindowsClientTaskBarReceiver()
|
||||
{
|
||||
ARCH->removeReceiver(this);
|
||||
for (UInt32 i = 0; i < kMaxState; ++i) {
|
||||
deleteIcon(m_icon[i]);
|
||||
}
|
||||
DestroyMenu(m_menu);
|
||||
destroyWindow();
|
||||
}
|
||||
|
||||
void
|
||||
CMSWindowsClientTaskBarReceiver::showStatus()
|
||||
{
|
||||
// create the window
|
||||
createWindow();
|
||||
|
||||
// lock self while getting status
|
||||
lock();
|
||||
|
||||
// get the current status
|
||||
std::string status = getToolTip();
|
||||
|
||||
// done getting status
|
||||
unlock();
|
||||
|
||||
// update dialog
|
||||
HWND child = GetDlgItem(m_window, IDC_TASKBAR_STATUS_STATUS);
|
||||
SendMessage(child, WM_SETTEXT, 0, (LPARAM)status.c_str());
|
||||
|
||||
if (!IsWindowVisible(m_window)) {
|
||||
// position it by the mouse
|
||||
POINT cursorPos;
|
||||
GetCursorPos(&cursorPos);
|
||||
RECT windowRect;
|
||||
GetWindowRect(m_window, &windowRect);
|
||||
int x = cursorPos.x;
|
||||
int y = cursorPos.y;
|
||||
int fw = GetSystemMetrics(SM_CXDLGFRAME);
|
||||
int fh = GetSystemMetrics(SM_CYDLGFRAME);
|
||||
int ww = windowRect.right - windowRect.left;
|
||||
int wh = windowRect.bottom - windowRect.top;
|
||||
int sw = GetSystemMetrics(SM_CXFULLSCREEN);
|
||||
int sh = GetSystemMetrics(SM_CYFULLSCREEN);
|
||||
if (fw < 1) {
|
||||
fw = 1;
|
||||
}
|
||||
if (fh < 1) {
|
||||
fh = 1;
|
||||
}
|
||||
if (x + ww - fw > sw) {
|
||||
x -= ww - fw;
|
||||
}
|
||||
else {
|
||||
x -= fw;
|
||||
}
|
||||
if (x < 0) {
|
||||
x = 0;
|
||||
}
|
||||
if (y + wh - fh > sh) {
|
||||
y -= wh - fh;
|
||||
}
|
||||
else {
|
||||
y -= fh;
|
||||
}
|
||||
if (y < 0) {
|
||||
y = 0;
|
||||
}
|
||||
SetWindowPos(m_window, HWND_TOPMOST, x, y, ww, wh,
|
||||
SWP_SHOWWINDOW);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CMSWindowsClientTaskBarReceiver::runMenu(int x, int y)
|
||||
{
|
||||
// do popup menu. we need a window to pass to TrackPopupMenu().
|
||||
// the SetForegroundWindow() and SendMessage() calls around
|
||||
// TrackPopupMenu() are to get the menu to be dismissed when
|
||||
// another window gets activated and are just one of those
|
||||
// win32 weirdnesses.
|
||||
createWindow();
|
||||
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 |
|
||||
TPM_LEFTBUTTON |
|
||||
TPM_RIGHTBUTTON,
|
||||
x, y, 0, m_window, NULL);
|
||||
SendMessage(m_window, WM_NULL, 0, 0);
|
||||
|
||||
// perform the requested operation
|
||||
switch (n) {
|
||||
case IDC_TASKBAR_STATUS:
|
||||
showStatus();
|
||||
break;
|
||||
|
||||
case IDC_TASKBAR_LOG:
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CMSWindowsClientTaskBarReceiver::primaryAction()
|
||||
{
|
||||
showStatus();
|
||||
}
|
||||
|
||||
const IArchTaskBarReceiver::Icon
|
||||
CMSWindowsClientTaskBarReceiver::getIcon() const
|
||||
{
|
||||
return reinterpret_cast<Icon>(m_icon[getStatus()]);
|
||||
}
|
||||
|
||||
void
|
||||
CMSWindowsClientTaskBarReceiver::copyLog() const
|
||||
{
|
||||
if (m_logBuffer != NULL) {
|
||||
// collect log buffer
|
||||
CString data;
|
||||
for (CBufferedLogOutputter::const_iterator index = m_logBuffer->begin();
|
||||
index != m_logBuffer->end(); ++index) {
|
||||
data += *index;
|
||||
data += "\n";
|
||||
}
|
||||
|
||||
// copy log to clipboard
|
||||
if (!data.empty()) {
|
||||
CMSWindowsClipboard clipboard(m_window);
|
||||
clipboard.open(0);
|
||||
clipboard.emptyUnowned();
|
||||
clipboard.add(IClipboard::kText, data);
|
||||
clipboard.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CMSWindowsClientTaskBarReceiver::onStatusChanged()
|
||||
{
|
||||
if (IsWindowVisible(m_window)) {
|
||||
showStatus();
|
||||
}
|
||||
}
|
||||
|
||||
HICON
|
||||
CMSWindowsClientTaskBarReceiver::loadIcon(UINT id)
|
||||
{
|
||||
HANDLE icon = LoadImage(m_appInstance,
|
||||
MAKEINTRESOURCE(id),
|
||||
IMAGE_ICON,
|
||||
0, 0,
|
||||
LR_DEFAULTCOLOR);
|
||||
return reinterpret_cast<HICON>(icon);
|
||||
}
|
||||
|
||||
void
|
||||
CMSWindowsClientTaskBarReceiver::deleteIcon(HICON icon)
|
||||
{
|
||||
if (icon != NULL) {
|
||||
DestroyIcon(icon);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CMSWindowsClientTaskBarReceiver::createWindow()
|
||||
{
|
||||
// ignore if already created
|
||||
if (m_window != NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
// get the status dialog
|
||||
m_window = CreateDialogParam(m_appInstance,
|
||||
MAKEINTRESOURCE(IDD_TASKBAR_STATUS),
|
||||
NULL,
|
||||
(DLGPROC)&CMSWindowsClientTaskBarReceiver::staticDlgProc,
|
||||
reinterpret_cast<LPARAM>(
|
||||
reinterpret_cast<void*>(this)));
|
||||
|
||||
// window should appear on top of everything, including (especially)
|
||||
// the task bar.
|
||||
LONG_PTR style = GetWindowLongPtr(m_window, GWL_EXSTYLE);
|
||||
style |= WS_EX_TOOLWINDOW | WS_EX_TOPMOST;
|
||||
SetWindowLongPtr(m_window, GWL_EXSTYLE, style);
|
||||
|
||||
// tell the task bar about this dialog
|
||||
CArchTaskBarWindows::addDialog(m_window);
|
||||
}
|
||||
|
||||
void
|
||||
CMSWindowsClientTaskBarReceiver::destroyWindow()
|
||||
{
|
||||
if (m_window != NULL) {
|
||||
CArchTaskBarWindows::removeDialog(m_window);
|
||||
DestroyWindow(m_window);
|
||||
m_window = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
BOOL
|
||||
CMSWindowsClientTaskBarReceiver::dlgProc(HWND hwnd,
|
||||
UINT msg, WPARAM wParam, LPARAM)
|
||||
{
|
||||
switch (msg) {
|
||||
case WM_INITDIALOG:
|
||||
// use default focus
|
||||
return TRUE;
|
||||
|
||||
case WM_ACTIVATE:
|
||||
// hide when another window is activated
|
||||
if (LOWORD(wParam) == WA_INACTIVE) {
|
||||
ShowWindow(hwnd, SW_HIDE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL CALLBACK
|
||||
CMSWindowsClientTaskBarReceiver::staticDlgProc(HWND hwnd,
|
||||
UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
// if msg is WM_INITDIALOG, extract the CMSWindowsClientTaskBarReceiver*
|
||||
// and put it in the extra window data then forward the call.
|
||||
CMSWindowsClientTaskBarReceiver* self = NULL;
|
||||
if (msg == WM_INITDIALOG) {
|
||||
self = reinterpret_cast<CMSWindowsClientTaskBarReceiver*>(
|
||||
reinterpret_cast<void*>(lParam));
|
||||
SetWindowLong(hwnd, GWL_USERDATA, lParam);
|
||||
}
|
||||
else {
|
||||
// get the extra window data and forward the call
|
||||
LONG data = GetWindowLong(hwnd, GWL_USERDATA);
|
||||
if (data != 0) {
|
||||
self = reinterpret_cast<CMSWindowsClientTaskBarReceiver*>(
|
||||
reinterpret_cast<void*>(data));
|
||||
}
|
||||
}
|
||||
|
||||
// forward the message
|
||||
if (self != NULL) {
|
||||
return self->dlgProc(hwnd, msg, wParam, lParam);
|
||||
}
|
||||
else {
|
||||
return (msg == WM_INITDIALOG) ? TRUE : FALSE;
|
||||
}
|
||||
}
|
||||
64
cmd/synergyc/CMSWindowsClientTaskBarReceiver.h
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* 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 CMSWINDOWSCLIENTTASKBARRECEIVER_H
|
||||
#define CMSWINDOWSCLIENTTASKBARRECEIVER_H
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
|
||||
#include "CClientTaskBarReceiver.h"
|
||||
#include <windows.h>
|
||||
|
||||
class CBufferedLogOutputter;
|
||||
|
||||
//! Implementation of CClientTaskBarReceiver for Microsoft Windows
|
||||
class CMSWindowsClientTaskBarReceiver : public CClientTaskBarReceiver {
|
||||
public:
|
||||
CMSWindowsClientTaskBarReceiver(HINSTANCE, const CBufferedLogOutputter*);
|
||||
virtual ~CMSWindowsClientTaskBarReceiver();
|
||||
|
||||
// IArchTaskBarReceiver overrides
|
||||
virtual void showStatus();
|
||||
virtual void runMenu(int x, int y);
|
||||
virtual void primaryAction();
|
||||
virtual const Icon getIcon() const;
|
||||
|
||||
protected:
|
||||
void copyLog() const;
|
||||
|
||||
// CClientTaskBarReceiver overrides
|
||||
virtual void onStatusChanged();
|
||||
|
||||
private:
|
||||
HICON loadIcon(UINT);
|
||||
void deleteIcon(HICON);
|
||||
void createWindow();
|
||||
void destroyWindow();
|
||||
|
||||
BOOL dlgProc(HWND hwnd,
|
||||
UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
static BOOL CALLBACK
|
||||
staticDlgProc(HWND hwnd,
|
||||
UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
private:
|
||||
HINSTANCE m_appInstance;
|
||||
HWND m_window;
|
||||
HMENU m_menu;
|
||||
HICON m_icon[kMaxState];
|
||||
const CBufferedLogOutputter* m_logBuffer;
|
||||
static const UINT s_stateToIconID[];
|
||||
};
|
||||
|
||||
#endif
|
||||
56
cmd/synergyc/COSXClientTaskBarReceiver.cpp
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2004 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 "COSXClientTaskBarReceiver.h"
|
||||
#include "CArch.h"
|
||||
|
||||
//
|
||||
// COSXClientTaskBarReceiver
|
||||
//
|
||||
|
||||
COSXClientTaskBarReceiver::COSXClientTaskBarReceiver(
|
||||
const CBufferedLogOutputter*)
|
||||
{
|
||||
// add ourself to the task bar
|
||||
ARCH->addReceiver(this);
|
||||
}
|
||||
|
||||
COSXClientTaskBarReceiver::~COSXClientTaskBarReceiver()
|
||||
{
|
||||
ARCH->removeReceiver(this);
|
||||
}
|
||||
|
||||
void
|
||||
COSXClientTaskBarReceiver::showStatus()
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
void
|
||||
COSXClientTaskBarReceiver::runMenu(int, int)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
void
|
||||
COSXClientTaskBarReceiver::primaryAction()
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
const IArchTaskBarReceiver::Icon
|
||||
COSXClientTaskBarReceiver::getIcon() const
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
35
cmd/synergyc/COSXClientTaskBarReceiver.h
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2004 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 COSXCLIENTTASKBARRECEIVER_H
|
||||
#define COSXCLIENTTASKBARRECEIVER_H
|
||||
|
||||
#include "CClientTaskBarReceiver.h"
|
||||
|
||||
class CBufferedLogOutputter;
|
||||
|
||||
//! Implementation of CClientTaskBarReceiver for OS X
|
||||
class COSXClientTaskBarReceiver : public CClientTaskBarReceiver {
|
||||
public:
|
||||
COSXClientTaskBarReceiver(const CBufferedLogOutputter*);
|
||||
virtual ~COSXClientTaskBarReceiver();
|
||||
|
||||
// IArchTaskBarReceiver overrides
|
||||
virtual void showStatus();
|
||||
virtual void runMenu(int x, int y);
|
||||
virtual void primaryAction();
|
||||
virtual const Icon getIcon() const;
|
||||
};
|
||||
|
||||
#endif
|
||||
56
cmd/synergyc/CXWindowsClientTaskBarReceiver.cpp
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "CXWindowsClientTaskBarReceiver.h"
|
||||
#include "CArch.h"
|
||||
|
||||
//
|
||||
// CXWindowsClientTaskBarReceiver
|
||||
//
|
||||
|
||||
CXWindowsClientTaskBarReceiver::CXWindowsClientTaskBarReceiver(
|
||||
const CBufferedLogOutputter*)
|
||||
{
|
||||
// add ourself to the task bar
|
||||
ARCH->addReceiver(this);
|
||||
}
|
||||
|
||||
CXWindowsClientTaskBarReceiver::~CXWindowsClientTaskBarReceiver()
|
||||
{
|
||||
ARCH->removeReceiver(this);
|
||||
}
|
||||
|
||||
void
|
||||
CXWindowsClientTaskBarReceiver::showStatus()
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
void
|
||||
CXWindowsClientTaskBarReceiver::runMenu(int, int)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
void
|
||||
CXWindowsClientTaskBarReceiver::primaryAction()
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
const IArchTaskBarReceiver::Icon
|
||||
CXWindowsClientTaskBarReceiver::getIcon() const
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
35
cmd/synergyc/CXWindowsClientTaskBarReceiver.h
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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 CXWINDOWSCLIENTTASKBARRECEIVER_H
|
||||
#define CXWINDOWSCLIENTTASKBARRECEIVER_H
|
||||
|
||||
#include "CClientTaskBarReceiver.h"
|
||||
|
||||
class CBufferedLogOutputter;
|
||||
|
||||
//! Implementation of CClientTaskBarReceiver for X Windows
|
||||
class CXWindowsClientTaskBarReceiver : public CClientTaskBarReceiver {
|
||||
public:
|
||||
CXWindowsClientTaskBarReceiver(const CBufferedLogOutputter*);
|
||||
virtual ~CXWindowsClientTaskBarReceiver();
|
||||
|
||||
// IArchTaskBarReceiver overrides
|
||||
virtual void showStatus();
|
||||
virtual void runMenu(int x, int y);
|
||||
virtual void primaryAction();
|
||||
virtual const Icon getIcon() const;
|
||||
};
|
||||
|
||||
#endif
|
||||
98
cmd/synergyc/Makefile.am
Normal file
@@ -0,0 +1,98 @@
|
||||
# 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.
|
||||
|
||||
## Process this file with automake to produce Makefile.in
|
||||
NULL =
|
||||
|
||||
COMMON_SOURCE_FILES = \
|
||||
CClientTaskBarReceiver.cpp \
|
||||
CClientTaskBarReceiver.h \
|
||||
synergyc.cpp \
|
||||
$(NULL)
|
||||
XWINDOWS_SOURCE_FILES = \
|
||||
CXWindowsClientTaskBarReceiver.cpp \
|
||||
CXWindowsClientTaskBarReceiver.h \
|
||||
$(NULL)
|
||||
MSWINDOWS_SOURCE_FILES = \
|
||||
CMSWindowsClientTaskBarReceiver.cpp \
|
||||
CMSWindowsClientTaskBarReceiver.h \
|
||||
resource.h \
|
||||
synergyc.rc \
|
||||
$(NULL)
|
||||
CARBON_SOURCE_FILES = \
|
||||
COSXClientTaskBarReceiver.cpp \
|
||||
COSXClientTaskBarReceiver.h \
|
||||
$(NULL)
|
||||
|
||||
EXTRA_DIST = \
|
||||
Makefile.win \
|
||||
synergyc.ico \
|
||||
tb_error.ico \
|
||||
tb_idle.ico \
|
||||
tb_run.ico \
|
||||
tb_wait.ico \
|
||||
$(XWINDOWS_SOURCE_FILES) \
|
||||
$(MSWINDOWS_SOURCE_FILES) \
|
||||
$(CARBON_SOURCE_FILES) \
|
||||
$(NULL)
|
||||
|
||||
MAINTAINERCLEANFILES = \
|
||||
Makefile.in \
|
||||
$(NULL)
|
||||
|
||||
bin_PROGRAMS = synergyc
|
||||
if XWINDOWS
|
||||
synergyc_SOURCES = \
|
||||
$(COMMON_SOURCE_FILES) \
|
||||
$(XWINDOWS_SOURCE_FILES) \
|
||||
$(NULL)
|
||||
endif
|
||||
if MSWINDOWS
|
||||
synergyc_SOURCES = \
|
||||
$(COMMON_SOURCE_FILES) \
|
||||
$(MSWINDOWS_SOURCE_FILES) \
|
||||
$(NULL)
|
||||
endif
|
||||
if CARBON
|
||||
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 \
|
||||
$(top_builddir)/lib/platform/libplatform.a \
|
||||
$(top_builddir)/lib/synergy/libsynergy.a \
|
||||
$(top_builddir)/lib/net/libnet.a \
|
||||
$(top_builddir)/lib/io/libio.a \
|
||||
$(top_builddir)/lib/mt/libmt.a \
|
||||
$(top_builddir)/lib/base/libbase.a \
|
||||
$(top_builddir)/lib/common/libcommon.a \
|
||||
$(top_builddir)/lib/arch/libarch.a \
|
||||
$(NULL)
|
||||
INCLUDES = \
|
||||
-I$(top_srcdir)/lib/common \
|
||||
-I$(top_srcdir)/lib/arch \
|
||||
-I$(top_srcdir)/lib/base \
|
||||
-I$(top_srcdir)/lib/mt \
|
||||
-I$(top_srcdir)/lib/io \
|
||||
-I$(top_srcdir)/lib/net \
|
||||
-I$(top_srcdir)/lib/synergy \
|
||||
-I$(top_srcdir)/lib/platform \
|
||||
-I$(top_srcdir)/lib/client \
|
||||
$(NULL)
|
||||
89
cmd/synergyc/Makefile.win
Normal file
@@ -0,0 +1,89 @@
|
||||
# synergy -- mouse and keyboard sharing utility
|
||||
# Copyright (C) 2007 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.
|
||||
|
||||
BIN_SYNERGYC_SRC = cmd\synergyc
|
||||
BIN_SYNERGYC_DST = $(BUILD_DST)\$(BIN_SYNERGYC_SRC)
|
||||
BIN_SYNERGYC_EXE = "$(BUILD_DST)\synergyc.exe"
|
||||
BIN_SYNERGYC_CPP = \
|
||||
"CClientTaskBarReceiver.cpp" \
|
||||
"CMSWindowsClientTaskBarReceiver.cpp" \
|
||||
"synergyc.cpp" \
|
||||
$(NULL)
|
||||
BIN_SYNERGYC_OBJ = \
|
||||
"$(BIN_SYNERGYC_DST)\CClientTaskBarReceiver.obj" \
|
||||
"$(BIN_SYNERGYC_DST)\CMSWindowsClientTaskBarReceiver.obj" \
|
||||
"$(BIN_SYNERGYC_DST)\synergyc.obj" \
|
||||
$(NULL)
|
||||
BIN_SYNERGYC_RC = "$(BIN_SYNERGYC_SRC)\synergyc.rc"
|
||||
BIN_SYNERGYC_RES = "$(BIN_SYNERGYC_DST)\synergyc.res"
|
||||
BIN_SYNERGYC_INC = \
|
||||
/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\client" \
|
||||
$(NULL)
|
||||
BIN_SYNERGYC_LIB = \
|
||||
$(LIB_CLIENT_LIB) \
|
||||
$(LIB_PLATFORM_LIB) \
|
||||
$(LIB_SYNERGY_LIB) \
|
||||
$(LIB_NET_LIB) \
|
||||
$(LIB_IO_LIB) \
|
||||
$(LIB_MT_LIB) \
|
||||
$(LIB_BASE_LIB) \
|
||||
$(LIB_ARCH_LIB) \
|
||||
$(LIB_COMMON_LIB) \
|
||||
$(NULL)
|
||||
|
||||
CPP_FILES = $(CPP_FILES) $(BIN_SYNERGYC_CPP)
|
||||
OBJ_FILES = $(OBJ_FILES) $(BIN_SYNERGYC_OBJ)
|
||||
PROGRAMS = $(PROGRAMS) $(BIN_SYNERGYC_EXE)
|
||||
|
||||
# Need shell functions.
|
||||
guilibs = $(guilibs) shell32.lib
|
||||
|
||||
# Dependency rules
|
||||
$(BIN_SYNERGYC_OBJ): $(AUTODEP)
|
||||
!if EXIST($(BIN_SYNERGYC_DST)\deps.mak)
|
||||
!include $(BIN_SYNERGYC_DST)\deps.mak
|
||||
!endif
|
||||
|
||||
# Build rules. Use batch-mode rules if possible.
|
||||
!if DEFINED(_NMAKE_VER)
|
||||
{$(BIN_SYNERGYC_SRC)\}.cpp{$(BIN_SYNERGYC_DST)\}.obj::
|
||||
!else
|
||||
{$(BIN_SYNERGYC_SRC)\}.cpp{$(BIN_SYNERGYC_DST)\}.obj:
|
||||
!endif
|
||||
@$(ECHO) Compile in $(BIN_SYNERGYC_SRC)
|
||||
-@$(MKDIR) $(BIN_SYNERGYC_DST) 2>NUL:
|
||||
$(cpp) $(cppdebug) $(cppflags) $(cppvarsmt) /showIncludes \
|
||||
$(BIN_SYNERGYC_INC) \
|
||||
/Fo$(BIN_SYNERGYC_DST)\ \
|
||||
/Fd$(BIN_SYNERGYC_DST)\src.pdb \
|
||||
$< | $(AUTODEP) $(BIN_SYNERGYC_SRC) $(BIN_SYNERGYC_DST)
|
||||
$(BIN_SYNERGYC_RES): $(BIN_SYNERGYC_RC)
|
||||
@$(ECHO) Compile $(**F)
|
||||
-@$(MKDIR) $(BIN_SYNERGYC_DST) 2>NUL:
|
||||
$(rc) $(rcflags) $(rcvars) \
|
||||
/fo$@ \
|
||||
$**
|
||||
$(BIN_SYNERGYC_EXE): $(BIN_SYNERGYC_OBJ) $(BIN_SYNERGYC_RES) $(BIN_SYNERGYC_LIB)
|
||||
@$(ECHO) Link $(@F)
|
||||
$(link) $(ldebug) $(guilflags) $(guilibsmt) \
|
||||
/out:$@ \
|
||||
$**
|
||||
$(AUTODEP) $(BIN_SYNERGYC_SRC) $(BIN_SYNERGYC_DST) \
|
||||
$(BIN_SYNERGYC_OBJ:.obj=.d)
|
||||
37
cmd/synergyc/resource.h
Normal file
@@ -0,0 +1,37 @@
|
||||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Developer Studio generated include file.
|
||||
// Used by synergyc.rc
|
||||
//
|
||||
#define IDS_FAILED 1
|
||||
#define IDS_INIT_FAILED 2
|
||||
#define IDS_UNCAUGHT_EXCEPTION 3
|
||||
#define IDI_SYNERGY 101
|
||||
#define IDI_TASKBAR_NOT_RUNNING 102
|
||||
#define IDI_TASKBAR_NOT_WORKING 103
|
||||
#define IDI_TASKBAR_NOT_CONNECTED 104
|
||||
#define IDI_TASKBAR_CONNECTED 105
|
||||
#define IDR_TASKBAR 107
|
||||
#define IDD_TASKBAR_STATUS 108
|
||||
#define IDC_TASKBAR_STATUS_STATUS 1000
|
||||
#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 40016
|
||||
#define _APS_NEXT_CONTROL_VALUE 1001
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
||||
910
cmd/synergyc/synergyc.cpp
Normal file
@@ -0,0 +1,910 @@
|
||||
/*
|
||||
* 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 "CClient.h"
|
||||
#include "CScreen.h"
|
||||
#include "ProtocolTypes.h"
|
||||
#include "Version.h"
|
||||
#include "XScreen.h"
|
||||
#include "CNetworkAddress.h"
|
||||
#include "CSocketMultiplexer.h"
|
||||
#include "CTCPSocketFactory.h"
|
||||
#include "XSocket.h"
|
||||
#include "CThread.h"
|
||||
#include "CEventQueue.h"
|
||||
#include "CFunctionEventJob.h"
|
||||
#include "CFunctionJob.h"
|
||||
#include "CLog.h"
|
||||
#include "CString.h"
|
||||
#include "CStringUtil.h"
|
||||
#include "LogOutputters.h"
|
||||
#include "CArch.h"
|
||||
#include "XArch.h"
|
||||
#include <cstring>
|
||||
|
||||
#define DAEMON_RUNNING(running_)
|
||||
#if WINAPI_MSWINDOWS
|
||||
#include "CArchMiscWindows.h"
|
||||
#include "CMSWindowsScreen.h"
|
||||
#include "CMSWindowsUtil.h"
|
||||
#include "CMSWindowsClientTaskBarReceiver.h"
|
||||
#include "resource.h"
|
||||
#undef DAEMON_RUNNING
|
||||
#define DAEMON_RUNNING(running_) CArchMiscWindows::daemonRunning(running_)
|
||||
#elif WINAPI_XWINDOWS
|
||||
#include "CXWindowsScreen.h"
|
||||
#include "CXWindowsClientTaskBarReceiver.h"
|
||||
#elif WINAPI_CARBON
|
||||
#include "COSXScreen.h"
|
||||
#include "COSXClientTaskBarReceiver.h"
|
||||
#endif
|
||||
|
||||
// platform dependent name of a daemon
|
||||
#if SYSAPI_WIN32
|
||||
#define DAEMON_NAME "Synergy Client"
|
||||
#elif SYSAPI_UNIX
|
||||
#define DAEMON_NAME "synergyc"
|
||||
#endif
|
||||
|
||||
typedef int (*StartupFunc)(int, char**);
|
||||
static bool startClient();
|
||||
static void parse(int argc, const char* const* argv);
|
||||
|
||||
//
|
||||
// program arguments
|
||||
//
|
||||
|
||||
#define ARG CArgs::s_instance
|
||||
|
||||
class CArgs {
|
||||
public:
|
||||
CArgs() :
|
||||
m_pname(NULL),
|
||||
m_backend(false),
|
||||
m_restartable(true),
|
||||
m_daemon(true),
|
||||
m_logFilter(NULL),
|
||||
m_display(NULL),
|
||||
m_serverAddress(NULL)
|
||||
{ s_instance = this; }
|
||||
~CArgs() { s_instance = NULL; }
|
||||
|
||||
public:
|
||||
static CArgs* s_instance;
|
||||
const char* m_pname;
|
||||
bool m_backend;
|
||||
bool m_restartable;
|
||||
bool m_daemon;
|
||||
const char* m_logFilter;
|
||||
const char* m_display;
|
||||
CString m_name;
|
||||
CNetworkAddress* m_serverAddress;
|
||||
};
|
||||
|
||||
CArgs* CArgs::s_instance = NULL;
|
||||
|
||||
|
||||
//
|
||||
// platform dependent factories
|
||||
//
|
||||
|
||||
static
|
||||
CScreen*
|
||||
createScreen()
|
||||
{
|
||||
#if WINAPI_MSWINDOWS
|
||||
return new CScreen(new CMSWindowsScreen(false));
|
||||
#elif WINAPI_XWINDOWS
|
||||
return new CScreen(new CXWindowsScreen(ARG->m_display, false));
|
||||
#elif WINAPI_CARBON
|
||||
return new CScreen(new COSXScreen(false));
|
||||
#endif
|
||||
}
|
||||
|
||||
static
|
||||
CClientTaskBarReceiver*
|
||||
createTaskBarReceiver(const CBufferedLogOutputter* logBuffer)
|
||||
{
|
||||
#if WINAPI_MSWINDOWS
|
||||
return new CMSWindowsClientTaskBarReceiver(
|
||||
CMSWindowsScreen::getInstance(), logBuffer);
|
||||
#elif WINAPI_XWINDOWS
|
||||
return new CXWindowsClientTaskBarReceiver(logBuffer);
|
||||
#elif WINAPI_CARBON
|
||||
return new COSXClientTaskBarReceiver(logBuffer);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// platform independent main
|
||||
//
|
||||
|
||||
static CClient* s_client = NULL;
|
||||
static CScreen* s_clientScreen = NULL;
|
||||
static CClientTaskBarReceiver* s_taskBarReceiver = NULL;
|
||||
static double s_retryTime = 0.0;
|
||||
static bool s_suspened = false;
|
||||
|
||||
static
|
||||
void
|
||||
updateStatus()
|
||||
{
|
||||
s_taskBarReceiver->updateStatus(s_client, "");
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
updateStatus(const CString& msg)
|
||||
{
|
||||
s_taskBarReceiver->updateStatus(s_client, msg);
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
resetRestartTimeout()
|
||||
{
|
||||
s_retryTime = 0.0;
|
||||
}
|
||||
|
||||
static
|
||||
double
|
||||
nextRestartTimeout()
|
||||
{
|
||||
// choose next restart timeout. we start with rapid retries
|
||||
// then slow down.
|
||||
if (s_retryTime < 1.0) {
|
||||
s_retryTime = 1.0;
|
||||
}
|
||||
else if (s_retryTime < 3.0) {
|
||||
s_retryTime = 3.0;
|
||||
}
|
||||
else if (s_retryTime < 5.0) {
|
||||
s_retryTime = 5.0;
|
||||
}
|
||||
else if (s_retryTime < 15.0) {
|
||||
s_retryTime = 15.0;
|
||||
}
|
||||
else if (s_retryTime < 30.0) {
|
||||
s_retryTime = 30.0;
|
||||
}
|
||||
else {
|
||||
s_retryTime = 60.0;
|
||||
}
|
||||
return s_retryTime;
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
handleScreenError(const CEvent&, void*)
|
||||
{
|
||||
LOG((CLOG_CRIT "error on screen"));
|
||||
EVENTQUEUE->addEvent(CEvent(CEvent::kQuit));
|
||||
}
|
||||
|
||||
static
|
||||
CScreen*
|
||||
openClientScreen()
|
||||
{
|
||||
CScreen* screen = createScreen();
|
||||
EVENTQUEUE->adoptHandler(IScreen::getErrorEvent(),
|
||||
screen->getEventTarget(),
|
||||
new CFunctionEventJob(
|
||||
&handleScreenError));
|
||||
return screen;
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
closeClientScreen(CScreen* screen)
|
||||
{
|
||||
if (screen != NULL) {
|
||||
EVENTQUEUE->removeHandler(IScreen::getErrorEvent(),
|
||||
screen->getEventTarget());
|
||||
delete screen;
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
handleClientRestart(const CEvent&, void* vtimer)
|
||||
{
|
||||
// discard old timer
|
||||
CEventQueueTimer* timer = reinterpret_cast<CEventQueueTimer*>(vtimer);
|
||||
EVENTQUEUE->deleteTimer(timer);
|
||||
EVENTQUEUE->removeHandler(CEvent::kTimer, timer);
|
||||
|
||||
// reconnect
|
||||
startClient();
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
scheduleClientRestart(double retryTime)
|
||||
{
|
||||
// install a timer and handler to retry later
|
||||
LOG((CLOG_DEBUG "retry in %.0f seconds", retryTime));
|
||||
CEventQueueTimer* timer = EVENTQUEUE->newOneShotTimer(retryTime, NULL);
|
||||
EVENTQUEUE->adoptHandler(CEvent::kTimer, timer,
|
||||
new CFunctionEventJob(&handleClientRestart, timer));
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
handleClientConnected(const CEvent&, void*)
|
||||
{
|
||||
LOG((CLOG_NOTE "connected to server"));
|
||||
resetRestartTimeout();
|
||||
updateStatus();
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
handleClientFailed(const CEvent& e, void*)
|
||||
{
|
||||
CClient::CFailInfo* info =
|
||||
reinterpret_cast<CClient::CFailInfo*>(e.getData());
|
||||
|
||||
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));
|
||||
if (!s_suspened) {
|
||||
scheduleClientRestart(nextRestartTimeout());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
handleClientDisconnected(const CEvent&, void*)
|
||||
{
|
||||
LOG((CLOG_NOTE "disconnected from server"));
|
||||
if (!ARG->m_restartable) {
|
||||
EVENTQUEUE->addEvent(CEvent(CEvent::kQuit));
|
||||
}
|
||||
else if (!s_suspened) {
|
||||
s_client->connect();
|
||||
}
|
||||
updateStatus();
|
||||
}
|
||||
|
||||
static
|
||||
CClient*
|
||||
openClient(const CString& name, const CNetworkAddress& address, CScreen* screen)
|
||||
{
|
||||
CClient* client = new CClient(name, address,
|
||||
new CTCPSocketFactory, NULL, screen);
|
||||
EVENTQUEUE->adoptHandler(CClient::getConnectedEvent(),
|
||||
client->getEventTarget(),
|
||||
new CFunctionEventJob(handleClientConnected));
|
||||
EVENTQUEUE->adoptHandler(CClient::getConnectionFailedEvent(),
|
||||
client->getEventTarget(),
|
||||
new CFunctionEventJob(handleClientFailed));
|
||||
EVENTQUEUE->adoptHandler(CClient::getDisconnectedEvent(),
|
||||
client->getEventTarget(),
|
||||
new CFunctionEventJob(handleClientDisconnected));
|
||||
return client;
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
closeClient(CClient* client)
|
||||
{
|
||||
if (client == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
EVENTQUEUE->removeHandler(CClient::getConnectedEvent(), client);
|
||||
EVENTQUEUE->removeHandler(CClient::getConnectionFailedEvent(), client);
|
||||
EVENTQUEUE->removeHandler(CClient::getDisconnectedEvent(), client);
|
||||
delete client;
|
||||
}
|
||||
|
||||
static
|
||||
bool
|
||||
startClient()
|
||||
{
|
||||
double retryTime;
|
||||
CScreen* clientScreen = NULL;
|
||||
try {
|
||||
if (s_clientScreen == NULL) {
|
||||
clientScreen = openClientScreen();
|
||||
s_client = openClient(ARG->m_name,
|
||||
*ARG->m_serverAddress, clientScreen);
|
||||
s_clientScreen = clientScreen;
|
||||
LOG((CLOG_NOTE "started client"));
|
||||
}
|
||||
s_client->connect();
|
||||
updateStatus();
|
||||
return true;
|
||||
}
|
||||
catch (XScreenUnavailable& e) {
|
||||
LOG((CLOG_WARN "cannot open secondary screen: %s", e.what()));
|
||||
closeClientScreen(clientScreen);
|
||||
updateStatus(CString("Cannot open secondary screen: ") + e.what());
|
||||
retryTime = e.getRetryTime();
|
||||
}
|
||||
catch (XScreenOpenFailure& e) {
|
||||
LOG((CLOG_CRIT "cannot open secondary screen: %s", e.what()));
|
||||
closeClientScreen(clientScreen);
|
||||
return false;
|
||||
}
|
||||
catch (XBase& e) {
|
||||
LOG((CLOG_CRIT "failed to start client: %s", e.what()));
|
||||
closeClientScreen(clientScreen);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ARG->m_restartable) {
|
||||
scheduleClientRestart(retryTime);
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
// don't try again
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
stopClient()
|
||||
{
|
||||
closeClient(s_client);
|
||||
closeClientScreen(s_clientScreen);
|
||||
s_client = NULL;
|
||||
s_clientScreen = NULL;
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
mainLoop()
|
||||
{
|
||||
// create socket multiplexer. this must happen after daemonization
|
||||
// on unix because threads evaporate across a fork().
|
||||
CSocketMultiplexer multiplexer;
|
||||
|
||||
// create the event queue
|
||||
CEventQueue eventQueue;
|
||||
|
||||
// start the client. if this return false then we've failed and
|
||||
// we shouldn't retry.
|
||||
LOG((CLOG_DEBUG1 "starting client"));
|
||||
if (!startClient()) {
|
||||
return kExitFailed;
|
||||
}
|
||||
|
||||
// run event loop. if startClient() failed we're supposed to retry
|
||||
// later. the timer installed by startClient() will take care of
|
||||
// that.
|
||||
CEvent event;
|
||||
DAEMON_RUNNING(true);
|
||||
EVENTQUEUE->getEvent(event);
|
||||
while (event.getType() != CEvent::kQuit) {
|
||||
EVENTQUEUE->dispatchEvent(event);
|
||||
CEvent::deleteData(event);
|
||||
EVENTQUEUE->getEvent(event);
|
||||
}
|
||||
DAEMON_RUNNING(false);
|
||||
|
||||
// close down
|
||||
LOG((CLOG_DEBUG1 "stopping client"));
|
||||
stopClient();
|
||||
updateStatus();
|
||||
LOG((CLOG_NOTE "stopped client"));
|
||||
|
||||
return kExitSuccess;
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
daemonMainLoop(int, const char**)
|
||||
{
|
||||
#if SYSAPI_WIN32
|
||||
CSystemLogger sysLogger(DAEMON_NAME, false);
|
||||
#else
|
||||
CSystemLogger sysLogger(DAEMON_NAME, true);
|
||||
#endif
|
||||
return mainLoop();
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
standardStartup(int argc, char** argv)
|
||||
{
|
||||
if (!ARG->m_daemon) {
|
||||
ARCH->showConsole(false);
|
||||
}
|
||||
|
||||
// parse command line
|
||||
parse(argc, argv);
|
||||
|
||||
// daemonize if requested
|
||||
if (ARG->m_daemon) {
|
||||
return ARCH->daemonize(DAEMON_NAME, &daemonMainLoop);
|
||||
}
|
||||
else {
|
||||
return mainLoop();
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
run(int argc, char** argv, ILogOutputter* outputter, StartupFunc startup)
|
||||
{
|
||||
// general initialization
|
||||
ARG->m_serverAddress = new CNetworkAddress;
|
||||
ARG->m_pname = ARCH->getBasename(argv[0]);
|
||||
|
||||
// install caller's output filter
|
||||
if (outputter != NULL) {
|
||||
CLOG->insert(outputter);
|
||||
}
|
||||
|
||||
// save log messages
|
||||
CBufferedLogOutputter logBuffer(1000);
|
||||
CLOG->insert(&logBuffer, true);
|
||||
|
||||
// make the task bar receiver. the user can control this app
|
||||
// through the task bar.
|
||||
s_taskBarReceiver = createTaskBarReceiver(&logBuffer);
|
||||
|
||||
// run
|
||||
int result = startup(argc, argv);
|
||||
|
||||
// done with task bar receiver
|
||||
delete s_taskBarReceiver;
|
||||
|
||||
// done with log buffer
|
||||
CLOG->remove(&logBuffer);
|
||||
|
||||
delete ARG->m_serverAddress;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// command line parsing
|
||||
//
|
||||
|
||||
#define BYE "\nTry `%s --help' for more information."
|
||||
|
||||
static void (*bye)(int) = &exit;
|
||||
|
||||
static
|
||||
void
|
||||
version()
|
||||
{
|
||||
LOG((CLOG_PRINT "%s %s, protocol version %d.%d\n%s",
|
||||
ARG->m_pname,
|
||||
kVersion,
|
||||
kProtocolMajorVersion,
|
||||
kProtocolMinorVersion,
|
||||
kCopyright));
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
help()
|
||||
{
|
||||
#if WINAPI_XWINDOWS
|
||||
# define USAGE_DISPLAY_ARG \
|
||||
" [--display <display>]"
|
||||
# define USAGE_DISPLAY_INFO \
|
||||
" --display <display> connect to the X server at <display>\n"
|
||||
#else
|
||||
# define USAGE_DISPLAY_ARG
|
||||
# define USAGE_DISPLAY_INFO
|
||||
#endif
|
||||
|
||||
LOG((CLOG_PRINT
|
||||
"Usage: %s"
|
||||
" [--daemon|--no-daemon]"
|
||||
" [--debug <level>]"
|
||||
USAGE_DISPLAY_ARG
|
||||
" [--name <screen-name>]"
|
||||
" [--restart|--no-restart]"
|
||||
" <server-address>"
|
||||
"\n\n"
|
||||
"Start the synergy mouse/keyboard sharing server.\n"
|
||||
"\n"
|
||||
" -d, --debug <level> filter out log messages with priorty below level.\n"
|
||||
" level may be: FATAL, ERROR, WARNING, NOTE, INFO,\n"
|
||||
" DEBUG, DEBUG1, DEBUG2.\n"
|
||||
USAGE_DISPLAY_INFO
|
||||
" -f, --no-daemon run the client in the foreground.\n"
|
||||
"* --daemon run the client as a daemon.\n"
|
||||
" -n, --name <screen-name> use screen-name instead the hostname to identify\n"
|
||||
" ourself to the server.\n"
|
||||
" -1, --no-restart do not try to restart the client if it fails for\n"
|
||||
" some reason.\n"
|
||||
"* --restart restart the client automatically if it fails.\n"
|
||||
" -h, --help display this help and exit.\n"
|
||||
" --version display version information and exit.\n"
|
||||
"\n"
|
||||
"* marks defaults.\n"
|
||||
"\n"
|
||||
"The server address is of the form: [<hostname>][:<port>]. The hostname\n"
|
||||
"must be the address or hostname of the server. The port overrides the\n"
|
||||
"default port, %d.\n"
|
||||
"\n"
|
||||
"Where log messages go depends on the platform and whether or not the\n"
|
||||
"client is running as a daemon.",
|
||||
ARG->m_pname, kDefaultPort));
|
||||
|
||||
}
|
||||
|
||||
static
|
||||
bool
|
||||
isArg(int argi, int argc, const char* const* argv,
|
||||
const char* name1, const char* name2,
|
||||
int minRequiredParameters = 0)
|
||||
{
|
||||
if ((name1 != NULL && strcmp(argv[argi], name1) == 0) ||
|
||||
(name2 != NULL && strcmp(argv[argi], name2) == 0)) {
|
||||
// match. check args left.
|
||||
if (argi + minRequiredParameters >= argc) {
|
||||
LOG((CLOG_PRINT "%s: missing arguments for `%s'" BYE,
|
||||
ARG->m_pname, argv[argi], ARG->m_pname));
|
||||
bye(kExitArgs);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// no match
|
||||
return false;
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
parse(int argc, const char* const* argv)
|
||||
{
|
||||
assert(ARG->m_pname != NULL);
|
||||
assert(argv != NULL);
|
||||
assert(argc >= 1);
|
||||
|
||||
// set defaults
|
||||
ARG->m_name = ARCH->getHostName();
|
||||
|
||||
// parse options
|
||||
int i;
|
||||
for (i = 1; i < argc; ++i) {
|
||||
if (isArg(i, argc, argv, "-d", "--debug", 1)) {
|
||||
// change logging level
|
||||
ARG->m_logFilter = argv[++i];
|
||||
}
|
||||
|
||||
else if (isArg(i, argc, argv, "-n", "--name", 1)) {
|
||||
// save screen name
|
||||
ARG->m_name = argv[++i];
|
||||
}
|
||||
|
||||
else if (isArg(i, argc, argv, NULL, "--camp")) {
|
||||
// ignore -- included for backwards compatibility
|
||||
}
|
||||
|
||||
else if (isArg(i, argc, argv, NULL, "--no-camp")) {
|
||||
// ignore -- included for backwards compatibility
|
||||
}
|
||||
|
||||
else if (isArg(i, argc, argv, "-f", "--no-daemon")) {
|
||||
// not a daemon
|
||||
ARG->m_daemon = false;
|
||||
}
|
||||
|
||||
else if (isArg(i, argc, argv, NULL, "--daemon")) {
|
||||
// daemonize
|
||||
ARG->m_daemon = true;
|
||||
}
|
||||
|
||||
#if WINAPI_XWINDOWS
|
||||
else if (isArg(i, argc, argv, "-display", "--display", 1)) {
|
||||
// use alternative display
|
||||
ARG->m_display = argv[++i];
|
||||
}
|
||||
#endif
|
||||
|
||||
else if (isArg(i, argc, argv, "-1", "--no-restart")) {
|
||||
// don't try to restart
|
||||
ARG->m_restartable = false;
|
||||
}
|
||||
|
||||
else if (isArg(i, argc, argv, NULL, "--restart")) {
|
||||
// try to restart
|
||||
ARG->m_restartable = true;
|
||||
}
|
||||
|
||||
else if (isArg(i, argc, argv, "-z", NULL)) {
|
||||
ARG->m_backend = true;
|
||||
}
|
||||
|
||||
else if (isArg(i, argc, argv, "-h", "--help")) {
|
||||
help();
|
||||
bye(kExitSuccess);
|
||||
}
|
||||
|
||||
else if (isArg(i, argc, argv, NULL, "--version")) {
|
||||
version();
|
||||
bye(kExitSuccess);
|
||||
}
|
||||
|
||||
else if (isArg(i, argc, argv, "--", NULL)) {
|
||||
// remaining arguments are not options
|
||||
++i;
|
||||
break;
|
||||
}
|
||||
|
||||
else if (argv[i][0] == '-') {
|
||||
LOG((CLOG_PRINT "%s: unrecognized option `%s'" BYE,
|
||||
ARG->m_pname, argv[i], ARG->m_pname));
|
||||
bye(kExitArgs);
|
||||
}
|
||||
|
||||
else {
|
||||
// this and remaining arguments are not options
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// exactly one non-option argument (server-address)
|
||||
if (i == argc) {
|
||||
LOG((CLOG_PRINT "%s: a server address or name is required" BYE,
|
||||
ARG->m_pname, ARG->m_pname));
|
||||
bye(kExitArgs);
|
||||
}
|
||||
if (i + 1 != argc) {
|
||||
LOG((CLOG_PRINT "%s: unrecognized option `%s'" BYE,
|
||||
ARG->m_pname, argv[i], ARG->m_pname));
|
||||
bye(kExitArgs);
|
||||
}
|
||||
|
||||
// save server address
|
||||
try {
|
||||
*ARG->m_serverAddress = CNetworkAddress(argv[i], kDefaultPort);
|
||||
ARG->m_serverAddress->resolve();
|
||||
}
|
||||
catch (XSocketAddress& e) {
|
||||
// allow an address that we can't look up if we're restartable.
|
||||
// we'll try to resolve the address each time we connect to the
|
||||
// server. a bad port will never get better. patch by Brent
|
||||
// Priddy.
|
||||
if (!ARG->m_restartable || e.getError() == XSocketAddress::kBadPort) {
|
||||
LOG((CLOG_PRINT "%s: %s" BYE,
|
||||
ARG->m_pname, e.what(), ARG->m_pname));
|
||||
bye(kExitFailed);
|
||||
}
|
||||
}
|
||||
|
||||
// increase default filter level for daemon. the user must
|
||||
// explicitly request another level for a daemon.
|
||||
if (ARG->m_daemon && ARG->m_logFilter == NULL) {
|
||||
#if SYSAPI_WIN32
|
||||
if (CArchMiscWindows::isWindows95Family()) {
|
||||
// windows 95 has no place for logging so avoid showing
|
||||
// the log console window.
|
||||
ARG->m_logFilter = "FATAL";
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
ARG->m_logFilter = "NOTE";
|
||||
}
|
||||
}
|
||||
|
||||
// set log filter
|
||||
if (!CLOG->setFilter(ARG->m_logFilter)) {
|
||||
LOG((CLOG_PRINT "%s: unrecognized log level `%s'" BYE,
|
||||
ARG->m_pname, ARG->m_logFilter, ARG->m_pname));
|
||||
bye(kExitArgs);
|
||||
}
|
||||
|
||||
// identify system
|
||||
LOG((CLOG_INFO "Synergy client %s on %s", kVersion, ARCH->getOSName().c_str()));
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// platform dependent entry points
|
||||
//
|
||||
|
||||
#if SYSAPI_WIN32
|
||||
|
||||
static bool s_hasImportantLogMessages = false;
|
||||
|
||||
//
|
||||
// CMessageBoxOutputter
|
||||
//
|
||||
// This class writes severe log messages to a message box
|
||||
//
|
||||
|
||||
class CMessageBoxOutputter : public ILogOutputter {
|
||||
public:
|
||||
CMessageBoxOutputter() { }
|
||||
virtual ~CMessageBoxOutputter() { }
|
||||
|
||||
// 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 ""; }
|
||||
};
|
||||
|
||||
bool
|
||||
CMessageBoxOutputter::write(ELevel level, const char* message)
|
||||
{
|
||||
// note any important messages the user may need to know about
|
||||
if (level <= CLog::kWARNING) {
|
||||
s_hasImportantLogMessages = true;
|
||||
}
|
||||
|
||||
// FATAL and PRINT messages get a dialog box if not running as
|
||||
// backend. if we're running as a backend the user will have
|
||||
// a chance to see the messages when we exit.
|
||||
if (!ARG->m_backend && level <= CLog::kFATAL) {
|
||||
MessageBox(NULL, message, ARG->m_pname, MB_OK | MB_ICONWARNING);
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
void
|
||||
byeThrow(int x)
|
||||
{
|
||||
CArchMiscWindows::daemonFailed(x);
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
daemonNTMainLoop(int argc, const char** argv)
|
||||
{
|
||||
parse(argc, argv);
|
||||
ARG->m_backend = false;
|
||||
return CArchMiscWindows::runDaemon(mainLoop);
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
daemonNTStartup(int, char**)
|
||||
{
|
||||
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)
|
||||
{
|
||||
CString fmt = CMSWindowsUtil::getString(instance, id);
|
||||
CString msg = CStringUtil::format(fmt.c_str(), arg);
|
||||
MessageBox(NULL, msg.c_str(), title, MB_OK | MB_ICONWARNING);
|
||||
}
|
||||
|
||||
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
|
||||
// arguments and we're on NT then we're being invoked as a service.
|
||||
// users on NT can use `--daemon' or `--no-daemon' to force us out
|
||||
// of the service code path.
|
||||
StartupFunc startup = &standardStartup;
|
||||
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);
|
||||
|
||||
// let user examine any messages if we're running as a backend
|
||||
// by putting up a dialog box before exiting.
|
||||
if (args.m_backend && s_hasImportantLogMessages) {
|
||||
showError(instance, args.m_pname, IDS_FAILED, "");
|
||||
}
|
||||
|
||||
delete CLOG;
|
||||
return result;
|
||||
}
|
||||
catch (XBase& e) {
|
||||
showError(instance, __argv[0], IDS_UNCAUGHT_EXCEPTION, e.what());
|
||||
//throw;
|
||||
}
|
||||
catch (XArch& e) {
|
||||
showError(instance, __argv[0], IDS_INIT_FAILED, e.what().c_str());
|
||||
}
|
||||
catch (...) {
|
||||
showError(instance, __argv[0], IDS_UNCAUGHT_EXCEPTION, "<unknown>");
|
||||
//throw;
|
||||
}
|
||||
return kExitFailed;
|
||||
}
|
||||
|
||||
#elif SYSAPI_UNIX
|
||||
|
||||
int
|
||||
main(int argc, char** argv)
|
||||
{
|
||||
CArgs args;
|
||||
try {
|
||||
int result;
|
||||
CArch arch;
|
||||
CLOG;
|
||||
CArgs args;
|
||||
result = run(argc, argv, NULL, &standardStartup);
|
||||
delete CLOG;
|
||||
return result;
|
||||
}
|
||||
catch (XBase& e) {
|
||||
LOG((CLOG_CRIT "Uncaught exception: %s\n", e.what()));
|
||||
throw;
|
||||
}
|
||||
catch (XArch& e) {
|
||||
LOG((CLOG_CRIT "Initialization failed: %s" BYE, e.what().c_str()));
|
||||
return kExitFailed;
|
||||
}
|
||||
catch (...) {
|
||||
LOG((CLOG_CRIT "Uncaught exception: <unknown exception>\n"));
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#error no main() for platform
|
||||
|
||||
#endif
|
||||
BIN
cmd/synergyc/synergyc.ico
Normal file
|
After Width: | Height: | Size: 8.3 KiB |
141
cmd/synergyc/synergyc.rc
Normal file
@@ -0,0 +1,141 @@
|
||||
//Microsoft Developer Studio generated resource script.
|
||||
//
|
||||
#include "resource.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#include <winresrc.h>
|
||||
#if !defined(IDC_STATIC)
|
||||
#define IDC_STATIC (-1)
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// English (U.S.) resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
||||
#ifdef _WIN32
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
#pragma code_page(1252)
|
||||
#endif //_WIN32
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEXTINCLUDE
|
||||
//
|
||||
|
||||
1 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"resource.h\0"
|
||||
END
|
||||
|
||||
2 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"#include <winresrc.h>\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
3 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Icon
|
||||
//
|
||||
|
||||
// Icon with lowest ID value placed first to ensure application icon
|
||||
// remains consistent on all systems.
|
||||
IDI_SYNERGY ICON DISCARDABLE "synergyc.ico"
|
||||
IDI_TASKBAR_NOT_RUNNING ICON DISCARDABLE "tb_idle.ico"
|
||||
IDI_TASKBAR_NOT_WORKING ICON DISCARDABLE "tb_error.ico"
|
||||
IDI_TASKBAR_NOT_CONNECTED ICON DISCARDABLE "tb_wait.ico"
|
||||
IDI_TASKBAR_CONNECTED ICON DISCARDABLE "tb_run.ico"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Dialog
|
||||
//
|
||||
|
||||
IDD_TASKBAR_STATUS DIALOG DISCARDABLE 0, 0, 145, 18
|
||||
STYLE DS_MODALFRAME | WS_POPUP
|
||||
FONT 8, "MS Sans Serif"
|
||||
BEGIN
|
||||
EDITTEXT IDC_TASKBAR_STATUS_STATUS,3,3,139,12,ES_AUTOHSCROLL |
|
||||
ES_READONLY | NOT WS_BORDER
|
||||
END
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Menu
|
||||
//
|
||||
|
||||
IDR_TASKBAR MENU DISCARDABLE
|
||||
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
|
||||
END
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// String Table
|
||||
//
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
BEGIN
|
||||
IDS_FAILED "Synergy is about to quit with errors or warnings. Please check the log then click OK."
|
||||
IDS_INIT_FAILED "Synergy failed to initialize: %{1}"
|
||||
IDS_UNCAUGHT_EXCEPTION "Uncaught exception: %{1}"
|
||||
END
|
||||
|
||||
#endif // English (U.S.) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 3 resource.
|
||||
//
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
|
||||
BIN
cmd/synergyc/tb_error.ico
Normal file
|
After Width: | Height: | Size: 318 B |
BIN
cmd/synergyc/tb_idle.ico
Normal file
|
After Width: | Height: | Size: 318 B |
BIN
cmd/synergyc/tb_run.ico
Normal file
|
After Width: | Height: | Size: 318 B |
BIN
cmd/synergyc/tb_wait.ico
Normal file
|
After Width: | Height: | Size: 318 B |
374
cmd/synergys/CMSWindowsServerTaskBarReceiver.cpp
Normal file
@@ -0,0 +1,374 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "CMSWindowsServerTaskBarReceiver.h"
|
||||
#include "CServer.h"
|
||||
#include "CMSWindowsClipboard.h"
|
||||
#include "IEventQueue.h"
|
||||
#include "LogOutputters.h"
|
||||
#include "BasicTypes.h"
|
||||
#include "CArch.h"
|
||||
#include "CArchTaskBarWindows.h"
|
||||
#include "resource.h"
|
||||
|
||||
extern CEvent::Type getReloadConfigEvent();
|
||||
extern CEvent::Type getForceReconnectEvent();
|
||||
|
||||
//
|
||||
// CMSWindowsServerTaskBarReceiver
|
||||
//
|
||||
|
||||
const UINT CMSWindowsServerTaskBarReceiver::s_stateToIconID[kMaxState] =
|
||||
{
|
||||
IDI_TASKBAR_NOT_RUNNING,
|
||||
IDI_TASKBAR_NOT_WORKING,
|
||||
IDI_TASKBAR_NOT_CONNECTED,
|
||||
IDI_TASKBAR_CONNECTED
|
||||
};
|
||||
|
||||
CMSWindowsServerTaskBarReceiver::CMSWindowsServerTaskBarReceiver(
|
||||
HINSTANCE appInstance, const CBufferedLogOutputter* logBuffer) :
|
||||
CServerTaskBarReceiver(),
|
||||
m_appInstance(appInstance),
|
||||
m_window(NULL),
|
||||
m_logBuffer(logBuffer)
|
||||
{
|
||||
for (UInt32 i = 0; i < kMaxState; ++i) {
|
||||
m_icon[i] = loadIcon(s_stateToIconID[i]);
|
||||
}
|
||||
m_menu = LoadMenu(m_appInstance, MAKEINTRESOURCE(IDR_TASKBAR));
|
||||
|
||||
// don't create the window yet. we'll create it on demand. this
|
||||
// has the side benefit of being created in the thread used for
|
||||
// the task bar. that's good because it means the existence of
|
||||
// the window won't prevent changing the main thread's desktop.
|
||||
|
||||
// add ourself to the task bar
|
||||
ARCH->addReceiver(this);
|
||||
}
|
||||
|
||||
CMSWindowsServerTaskBarReceiver::~CMSWindowsServerTaskBarReceiver()
|
||||
{
|
||||
ARCH->removeReceiver(this);
|
||||
for (UInt32 i = 0; i < kMaxState; ++i) {
|
||||
deleteIcon(m_icon[i]);
|
||||
}
|
||||
DestroyMenu(m_menu);
|
||||
destroyWindow();
|
||||
}
|
||||
|
||||
void
|
||||
CMSWindowsServerTaskBarReceiver::showStatus()
|
||||
{
|
||||
// create the window
|
||||
createWindow();
|
||||
|
||||
// lock self while getting status
|
||||
lock();
|
||||
|
||||
// get the current status
|
||||
std::string status = getToolTip();
|
||||
|
||||
// get the connect clients, if any
|
||||
const CClients& clients = getClients();
|
||||
|
||||
// done getting status
|
||||
unlock();
|
||||
|
||||
// update dialog
|
||||
HWND child = GetDlgItem(m_window, IDC_TASKBAR_STATUS_STATUS);
|
||||
SendMessage(child, WM_SETTEXT, 0, (LPARAM)status.c_str());
|
||||
child = GetDlgItem(m_window, IDC_TASKBAR_STATUS_CLIENTS);
|
||||
SendMessage(child, LB_RESETCONTENT, 0, 0);
|
||||
for (CClients::const_iterator index = clients.begin();
|
||||
index != clients.end(); ) {
|
||||
const char* client = index->c_str();
|
||||
if (++index == clients.end()) {
|
||||
SendMessage(child, LB_ADDSTRING, 0, (LPARAM)client);
|
||||
}
|
||||
else {
|
||||
SendMessage(child, LB_INSERTSTRING, (WPARAM)-1, (LPARAM)client);
|
||||
}
|
||||
}
|
||||
|
||||
if (!IsWindowVisible(m_window)) {
|
||||
// position it by the mouse
|
||||
POINT cursorPos;
|
||||
GetCursorPos(&cursorPos);
|
||||
RECT windowRect;
|
||||
GetWindowRect(m_window, &windowRect);
|
||||
int x = cursorPos.x;
|
||||
int y = cursorPos.y;
|
||||
int fw = GetSystemMetrics(SM_CXDLGFRAME);
|
||||
int fh = GetSystemMetrics(SM_CYDLGFRAME);
|
||||
int ww = windowRect.right - windowRect.left;
|
||||
int wh = windowRect.bottom - windowRect.top;
|
||||
int sw = GetSystemMetrics(SM_CXFULLSCREEN);
|
||||
int sh = GetSystemMetrics(SM_CYFULLSCREEN);
|
||||
if (fw < 1) {
|
||||
fw = 1;
|
||||
}
|
||||
if (fh < 1) {
|
||||
fh = 1;
|
||||
}
|
||||
if (x + ww - fw > sw) {
|
||||
x -= ww - fw;
|
||||
}
|
||||
else {
|
||||
x -= fw;
|
||||
}
|
||||
if (x < 0) {
|
||||
x = 0;
|
||||
}
|
||||
if (y + wh - fh > sh) {
|
||||
y -= wh - fh;
|
||||
}
|
||||
else {
|
||||
y -= fh;
|
||||
}
|
||||
if (y < 0) {
|
||||
y = 0;
|
||||
}
|
||||
SetWindowPos(m_window, HWND_TOPMOST, x, y, ww, wh,
|
||||
SWP_SHOWWINDOW);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CMSWindowsServerTaskBarReceiver::runMenu(int x, int y)
|
||||
{
|
||||
// do popup menu. we need a window to pass to TrackPopupMenu().
|
||||
// the SetForegroundWindow() and SendMessage() calls around
|
||||
// TrackPopupMenu() are to get the menu to be dismissed when
|
||||
// another window gets activated and are just one of those
|
||||
// win32 weirdnesses.
|
||||
createWindow();
|
||||
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 |
|
||||
TPM_LEFTBUTTON |
|
||||
TPM_RIGHTBUTTON,
|
||||
x, y, 0, m_window, NULL);
|
||||
SendMessage(m_window, WM_NULL, 0, 0);
|
||||
|
||||
// perform the requested operation
|
||||
switch (n) {
|
||||
case IDC_TASKBAR_STATUS:
|
||||
showStatus();
|
||||
break;
|
||||
|
||||
case IDC_TASKBAR_LOG:
|
||||
copyLog();
|
||||
break;
|
||||
|
||||
case IDC_TASKBAR_SHOW_LOG:
|
||||
ARCH->showConsole(true);
|
||||
break;
|
||||
|
||||
case IDC_RELOAD_CONFIG:
|
||||
EVENTQUEUE->addEvent(CEvent(getReloadConfigEvent(),
|
||||
IEventQueue::getSystemTarget()));
|
||||
break;
|
||||
|
||||
case IDC_FORCE_RECONNECT:
|
||||
EVENTQUEUE->addEvent(CEvent(getForceReconnectEvent(),
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CMSWindowsServerTaskBarReceiver::primaryAction()
|
||||
{
|
||||
showStatus();
|
||||
}
|
||||
|
||||
const IArchTaskBarReceiver::Icon
|
||||
CMSWindowsServerTaskBarReceiver::getIcon() const
|
||||
{
|
||||
return reinterpret_cast<Icon>(m_icon[getStatus()]);
|
||||
}
|
||||
|
||||
void
|
||||
CMSWindowsServerTaskBarReceiver::copyLog() const
|
||||
{
|
||||
if (m_logBuffer != NULL) {
|
||||
// collect log buffer
|
||||
CString data;
|
||||
for (CBufferedLogOutputter::const_iterator index = m_logBuffer->begin();
|
||||
index != m_logBuffer->end(); ++index) {
|
||||
data += *index;
|
||||
data += "\n";
|
||||
}
|
||||
|
||||
// copy log to clipboard
|
||||
if (!data.empty()) {
|
||||
CMSWindowsClipboard clipboard(m_window);
|
||||
clipboard.open(0);
|
||||
clipboard.emptyUnowned();
|
||||
clipboard.add(IClipboard::kText, data);
|
||||
clipboard.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CMSWindowsServerTaskBarReceiver::onStatusChanged()
|
||||
{
|
||||
if (IsWindowVisible(m_window)) {
|
||||
showStatus();
|
||||
}
|
||||
}
|
||||
|
||||
HICON
|
||||
CMSWindowsServerTaskBarReceiver::loadIcon(UINT id)
|
||||
{
|
||||
HANDLE icon = LoadImage(m_appInstance,
|
||||
MAKEINTRESOURCE(id),
|
||||
IMAGE_ICON,
|
||||
0, 0,
|
||||
LR_DEFAULTCOLOR);
|
||||
return reinterpret_cast<HICON>(icon);
|
||||
}
|
||||
|
||||
void
|
||||
CMSWindowsServerTaskBarReceiver::deleteIcon(HICON icon)
|
||||
{
|
||||
if (icon != NULL) {
|
||||
DestroyIcon(icon);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CMSWindowsServerTaskBarReceiver::createWindow()
|
||||
{
|
||||
// ignore if already created
|
||||
if (m_window != NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
// get the status dialog
|
||||
m_window = CreateDialogParam(m_appInstance,
|
||||
MAKEINTRESOURCE(IDD_TASKBAR_STATUS),
|
||||
NULL,
|
||||
(DLGPROC)&CMSWindowsServerTaskBarReceiver::staticDlgProc,
|
||||
reinterpret_cast<LPARAM>(
|
||||
reinterpret_cast<void*>(this)));
|
||||
|
||||
// window should appear on top of everything, including (especially)
|
||||
// the task bar.
|
||||
LONG_PTR style = GetWindowLongPtr(m_window, GWL_EXSTYLE);
|
||||
style |= WS_EX_TOOLWINDOW | WS_EX_TOPMOST;
|
||||
SetWindowLongPtr(m_window, GWL_EXSTYLE, style);
|
||||
|
||||
// tell the task bar about this dialog
|
||||
CArchTaskBarWindows::addDialog(m_window);
|
||||
}
|
||||
|
||||
void
|
||||
CMSWindowsServerTaskBarReceiver::destroyWindow()
|
||||
{
|
||||
if (m_window != NULL) {
|
||||
CArchTaskBarWindows::removeDialog(m_window);
|
||||
DestroyWindow(m_window);
|
||||
m_window = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
BOOL
|
||||
CMSWindowsServerTaskBarReceiver::dlgProc(HWND hwnd,
|
||||
UINT msg, WPARAM wParam, LPARAM)
|
||||
{
|
||||
switch (msg) {
|
||||
case WM_INITDIALOG:
|
||||
// use default focus
|
||||
return TRUE;
|
||||
|
||||
case WM_ACTIVATE:
|
||||
// hide when another window is activated
|
||||
if (LOWORD(wParam) == WA_INACTIVE) {
|
||||
ShowWindow(hwnd, SW_HIDE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL CALLBACK
|
||||
CMSWindowsServerTaskBarReceiver::staticDlgProc(HWND hwnd,
|
||||
UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
// if msg is WM_INITDIALOG, extract the CMSWindowsServerTaskBarReceiver*
|
||||
// and put it in the extra window data then forward the call.
|
||||
CMSWindowsServerTaskBarReceiver* self = NULL;
|
||||
if (msg == WM_INITDIALOG) {
|
||||
self = reinterpret_cast<CMSWindowsServerTaskBarReceiver*>(
|
||||
reinterpret_cast<void*>(lParam));
|
||||
SetWindowLongPtr(hwnd, GWLP_USERDATA, lParam);
|
||||
}
|
||||
else {
|
||||
// get the extra window data and forward the call
|
||||
LONG data = GetWindowLongPtr(hwnd, GWLP_USERDATA);
|
||||
if (data != 0) {
|
||||
self = reinterpret_cast<CMSWindowsServerTaskBarReceiver*>(
|
||||
reinterpret_cast<void*>(data));
|
||||
}
|
||||
}
|
||||
|
||||
// forward the message
|
||||
if (self != NULL) {
|
||||
return self->dlgProc(hwnd, msg, wParam, lParam);
|
||||
}
|
||||
else {
|
||||
return (msg == WM_INITDIALOG) ? TRUE : FALSE;
|
||||
}
|
||||
}
|
||||
64
cmd/synergys/CMSWindowsServerTaskBarReceiver.h
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* 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 CMSWINDOWSSERVERTASKBARRECEIVER_H
|
||||
#define CMSWINDOWSSERVERTASKBARRECEIVER_H
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
|
||||
#include "CServerTaskBarReceiver.h"
|
||||
#include <windows.h>
|
||||
|
||||
class CBufferedLogOutputter;
|
||||
|
||||
//! Implementation of CServerTaskBarReceiver for Microsoft Windows
|
||||
class CMSWindowsServerTaskBarReceiver : public CServerTaskBarReceiver {
|
||||
public:
|
||||
CMSWindowsServerTaskBarReceiver(HINSTANCE, const CBufferedLogOutputter*);
|
||||
virtual ~CMSWindowsServerTaskBarReceiver();
|
||||
|
||||
// IArchTaskBarReceiver overrides
|
||||
virtual void showStatus();
|
||||
virtual void runMenu(int x, int y);
|
||||
virtual void primaryAction();
|
||||
virtual const Icon getIcon() const;
|
||||
|
||||
protected:
|
||||
void copyLog() const;
|
||||
|
||||
// CServerTaskBarReceiver overrides
|
||||
virtual void onStatusChanged();
|
||||
|
||||
private:
|
||||
HICON loadIcon(UINT);
|
||||
void deleteIcon(HICON);
|
||||
void createWindow();
|
||||
void destroyWindow();
|
||||
|
||||
BOOL dlgProc(HWND hwnd,
|
||||
UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
static BOOL CALLBACK
|
||||
staticDlgProc(HWND hwnd,
|
||||
UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
|
||||
private:
|
||||
HINSTANCE m_appInstance;
|
||||
HWND m_window;
|
||||
HMENU m_menu;
|
||||
HICON m_icon[kMaxState];
|
||||
const CBufferedLogOutputter* m_logBuffer;
|
||||
static const UINT s_stateToIconID[];
|
||||
};
|
||||
|
||||
#endif
|
||||
56
cmd/synergys/COSXServerTaskBarReceiver.cpp
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2004 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 "COSXServerTaskBarReceiver.h"
|
||||
#include "CArch.h"
|
||||
|
||||
//
|
||||
// COSXServerTaskBarReceiver
|
||||
//
|
||||
|
||||
COSXServerTaskBarReceiver::COSXServerTaskBarReceiver(
|
||||
const CBufferedLogOutputter*)
|
||||
{
|
||||
// add ourself to the task bar
|
||||
ARCH->addReceiver(this);
|
||||
}
|
||||
|
||||
COSXServerTaskBarReceiver::~COSXServerTaskBarReceiver()
|
||||
{
|
||||
ARCH->removeReceiver(this);
|
||||
}
|
||||
|
||||
void
|
||||
COSXServerTaskBarReceiver::showStatus()
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
void
|
||||
COSXServerTaskBarReceiver::runMenu(int, int)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
void
|
||||
COSXServerTaskBarReceiver::primaryAction()
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
const IArchTaskBarReceiver::Icon
|
||||
COSXServerTaskBarReceiver::getIcon() const
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
35
cmd/synergys/COSXServerTaskBarReceiver.h
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* synergy -- mouse and keyboard sharing utility
|
||||
* Copyright (C) 2004 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 COSXSERVERTASKBARRECEIVER_H
|
||||
#define COSXSERVERTASKBARRECEIVER_H
|
||||
|
||||
#include "CServerTaskBarReceiver.h"
|
||||
|
||||
class CBufferedLogOutputter;
|
||||
|
||||
//! Implementation of CServerTaskBarReceiver for OS X
|
||||
class COSXServerTaskBarReceiver : public CServerTaskBarReceiver {
|
||||
public:
|
||||
COSXServerTaskBarReceiver(const CBufferedLogOutputter*);
|
||||
virtual ~COSXServerTaskBarReceiver();
|
||||
|
||||
// IArchTaskBarReceiver overrides
|
||||
virtual void showStatus();
|
||||
virtual void runMenu(int x, int y);
|
||||
virtual void primaryAction();
|
||||
virtual const Icon getIcon() const;
|
||||
};
|
||||
|
||||
#endif
|
||||
133
cmd/synergys/CServerTaskBarReceiver.cpp
Normal file
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "CServerTaskBarReceiver.h"
|
||||
#include "CServer.h"
|
||||
#include "CLock.h"
|
||||
#include "CStringUtil.h"
|
||||
#include "IEventQueue.h"
|
||||
#include "CArch.h"
|
||||
#include "Version.h"
|
||||
|
||||
//
|
||||
// CServerTaskBarReceiver
|
||||
//
|
||||
|
||||
CServerTaskBarReceiver::CServerTaskBarReceiver() :
|
||||
m_state(kNotRunning)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
CServerTaskBarReceiver::~CServerTaskBarReceiver()
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
void
|
||||
CServerTaskBarReceiver::updateStatus(CServer* server, const CString& errorMsg)
|
||||
{
|
||||
{
|
||||
// update our status
|
||||
m_errorMessage = errorMsg;
|
||||
if (server == NULL) {
|
||||
if (m_errorMessage.empty()) {
|
||||
m_state = kNotRunning;
|
||||
}
|
||||
else {
|
||||
m_state = kNotWorking;
|
||||
}
|
||||
}
|
||||
else {
|
||||
m_clients.clear();
|
||||
server->getClients(m_clients);
|
||||
if (m_clients.size() <= 1) {
|
||||
m_state = kNotConnected;
|
||||
}
|
||||
else {
|
||||
m_state = kConnected;
|
||||
}
|
||||
}
|
||||
|
||||
// let subclasses have a go
|
||||
onStatusChanged(server);
|
||||
}
|
||||
|
||||
// tell task bar
|
||||
ARCH->updateReceiver(this);
|
||||
}
|
||||
|
||||
CServerTaskBarReceiver::EState
|
||||
CServerTaskBarReceiver::getStatus() const
|
||||
{
|
||||
return m_state;
|
||||
}
|
||||
|
||||
const CString&
|
||||
CServerTaskBarReceiver::getErrorMessage() const
|
||||
{
|
||||
return m_errorMessage;
|
||||
}
|
||||
|
||||
const CServerTaskBarReceiver::CClients&
|
||||
CServerTaskBarReceiver::getClients() const
|
||||
{
|
||||
return m_clients;
|
||||
}
|
||||
|
||||
void
|
||||
CServerTaskBarReceiver::quit()
|
||||
{
|
||||
EVENTQUEUE->addEvent(CEvent(CEvent::kQuit));
|
||||
}
|
||||
|
||||
void
|
||||
CServerTaskBarReceiver::onStatusChanged(CServer*)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
void
|
||||
CServerTaskBarReceiver::lock() const
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
void
|
||||
CServerTaskBarReceiver::unlock() const
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
std::string
|
||||
CServerTaskBarReceiver::getToolTip() const
|
||||
{
|
||||
switch (m_state) {
|
||||
case kNotRunning:
|
||||
return CStringUtil::print("%s: Not running", kAppVersion);
|
||||
|
||||
case kNotWorking:
|
||||
return CStringUtil::print("%s: %s",
|
||||
kAppVersion, m_errorMessage.c_str());
|
||||
|
||||
case kNotConnected:
|
||||
return CStringUtil::print("%s: Waiting for clients", kAppVersion);
|
||||
|
||||
case kConnected:
|
||||
return CStringUtil::print("%s: Connected", kAppVersion);
|
||||
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
88
cmd/synergys/CServerTaskBarReceiver.h
Normal file
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* 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 CSERVERTASKBARRECEIVER_H
|
||||
#define CSERVERTASKBARRECEIVER_H
|
||||
|
||||
#include "CString.h"
|
||||
#include "IArchTaskBarReceiver.h"
|
||||
#include "stdvector.h"
|
||||
|
||||
class CServer;
|
||||
|
||||
//! Implementation of IArchTaskBarReceiver for the synergy server
|
||||
class CServerTaskBarReceiver : public IArchTaskBarReceiver {
|
||||
public:
|
||||
CServerTaskBarReceiver();
|
||||
virtual ~CServerTaskBarReceiver();
|
||||
|
||||
//! @name manipulators
|
||||
//@{
|
||||
|
||||
//! Update status
|
||||
/*!
|
||||
Determine the status and query required information from the server.
|
||||
*/
|
||||
void updateStatus(CServer*, const CString& errorMsg);
|
||||
|
||||
//@}
|
||||
|
||||
// IArchTaskBarReceiver overrides
|
||||
virtual void showStatus() = 0;
|
||||
virtual void runMenu(int x, int y) = 0;
|
||||
virtual void primaryAction() = 0;
|
||||
virtual void lock() const;
|
||||
virtual void unlock() const;
|
||||
virtual const Icon getIcon() const = 0;
|
||||
virtual std::string getToolTip() const;
|
||||
|
||||
protected:
|
||||
typedef std::vector<CString> CClients;
|
||||
enum EState {
|
||||
kNotRunning,
|
||||
kNotWorking,
|
||||
kNotConnected,
|
||||
kConnected,
|
||||
kMaxState
|
||||
};
|
||||
|
||||
//! Get status
|
||||
EState getStatus() const;
|
||||
|
||||
//! Get error message
|
||||
const CString& getErrorMessage() const;
|
||||
|
||||
//! Get connected clients
|
||||
const CClients& getClients() const;
|
||||
|
||||
//! Quit app
|
||||
/*!
|
||||
Causes the application to quit gracefully
|
||||
*/
|
||||
void quit();
|
||||
|
||||
//! Status change notification
|
||||
/*!
|
||||
Called when status changes. The default implementation does
|
||||
nothing.
|
||||
*/
|
||||
virtual void onStatusChanged(CServer* server);
|
||||
|
||||
private:
|
||||
EState m_state;
|
||||
CString m_errorMessage;
|
||||
CClients m_clients;
|
||||
};
|
||||
|
||||
#endif
|
||||
56
cmd/synergys/CXWindowsServerTaskBarReceiver.cpp
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "CXWindowsServerTaskBarReceiver.h"
|
||||
#include "CArch.h"
|
||||
|
||||
//
|
||||
// CXWindowsServerTaskBarReceiver
|
||||
//
|
||||
|
||||
CXWindowsServerTaskBarReceiver::CXWindowsServerTaskBarReceiver(
|
||||
const CBufferedLogOutputter*)
|
||||
{
|
||||
// add ourself to the task bar
|
||||
ARCH->addReceiver(this);
|
||||
}
|
||||
|
||||
CXWindowsServerTaskBarReceiver::~CXWindowsServerTaskBarReceiver()
|
||||
{
|
||||
ARCH->removeReceiver(this);
|
||||
}
|
||||
|
||||
void
|
||||
CXWindowsServerTaskBarReceiver::showStatus()
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
void
|
||||
CXWindowsServerTaskBarReceiver::runMenu(int, int)
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
void
|
||||
CXWindowsServerTaskBarReceiver::primaryAction()
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
|
||||
const IArchTaskBarReceiver::Icon
|
||||
CXWindowsServerTaskBarReceiver::getIcon() const
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
35
cmd/synergys/CXWindowsServerTaskBarReceiver.h
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* 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 CXWINDOWSSERVERTASKBARRECEIVER_H
|
||||
#define CXWINDOWSSERVERTASKBARRECEIVER_H
|
||||
|
||||
#include "CServerTaskBarReceiver.h"
|
||||
|
||||
class CBufferedLogOutputter;
|
||||
|
||||
//! Implementation of CServerTaskBarReceiver for X Windows
|
||||
class CXWindowsServerTaskBarReceiver : public CServerTaskBarReceiver {
|
||||
public:
|
||||
CXWindowsServerTaskBarReceiver(const CBufferedLogOutputter*);
|
||||
virtual ~CXWindowsServerTaskBarReceiver();
|
||||
|
||||
// IArchTaskBarReceiver overrides
|
||||
virtual void showStatus();
|
||||
virtual void runMenu(int x, int y);
|
||||
virtual void primaryAction();
|
||||
virtual const Icon getIcon() const;
|
||||
};
|
||||
|
||||
#endif
|
||||
98
cmd/synergys/Makefile.am
Normal file
@@ -0,0 +1,98 @@
|
||||
# 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.
|
||||
|
||||
## Process this file with automake to produce Makefile.in
|
||||
NULL =
|
||||
|
||||
COMMON_SOURCE_FILES = \
|
||||
CServerTaskBarReceiver.cpp \
|
||||
CServerTaskBarReceiver.h \
|
||||
synergys.cpp \
|
||||
$(NULL)
|
||||
XWINDOWS_SOURCE_FILES = \
|
||||
CXWindowsServerTaskBarReceiver.cpp \
|
||||
CXWindowsServerTaskBarReceiver.h \
|
||||
$(NULL)
|
||||
MSWINDOWS_SOURCE_FILES = \
|
||||
CMSWindowsServerTaskBarReceiver.cpp \
|
||||
CMSWindowsServerTaskBarReceiver.h \
|
||||
resource.h \
|
||||
synergys.rc \
|
||||
$(NULL)
|
||||
CARBON_SOURCE_FILES = \
|
||||
COSXServerTaskBarReceiver.cpp \
|
||||
COSXServerTaskBarReceiver.h \
|
||||
$(NULL)
|
||||
|
||||
EXTRA_DIST = \
|
||||
Makefile.win \
|
||||
synergys.ico \
|
||||
tb_error.ico \
|
||||
tb_idle.ico \
|
||||
tb_run.ico \
|
||||
tb_wait.ico \
|
||||
$(XWINDOWS_SOURCE_FILES) \
|
||||
$(MSWINDOWS_SOURCE_FILES) \
|
||||
$(CARBON_SOURCE_FILES) \
|
||||
$(NULL)
|
||||
|
||||
MAINTAINERCLEANFILES = \
|
||||
Makefile.in \
|
||||
$(NULL)
|
||||
|
||||
bin_PROGRAMS = synergys
|
||||
if XWINDOWS
|
||||
synergys_SOURCES = \
|
||||
$(COMMON_SOURCE_FILES) \
|
||||
$(XWINDOWS_SOURCE_FILES) \
|
||||
$(NULL)
|
||||
endif
|
||||
if MSWINDOWS
|
||||
synergys_SOURCES = \
|
||||
$(COMMON_SOURCE_FILES) \
|
||||
$(MSWINDOWS_SOURCE_FILES) \
|
||||
$(NULL)
|
||||
endif
|
||||
if CARBON
|
||||
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 \
|
||||
$(top_builddir)/lib/platform/libplatform.a \
|
||||
$(top_builddir)/lib/synergy/libsynergy.a \
|
||||
$(top_builddir)/lib/net/libnet.a \
|
||||
$(top_builddir)/lib/io/libio.a \
|
||||
$(top_builddir)/lib/mt/libmt.a \
|
||||
$(top_builddir)/lib/base/libbase.a \
|
||||
$(top_builddir)/lib/common/libcommon.a \
|
||||
$(top_builddir)/lib/arch/libarch.a \
|
||||
$(NULL)
|
||||
INCLUDES = \
|
||||
-I$(top_srcdir)/lib/common \
|
||||
-I$(top_srcdir)/lib/arch \
|
||||
-I$(top_srcdir)/lib/base \
|
||||
-I$(top_srcdir)/lib/mt \
|
||||
-I$(top_srcdir)/lib/io \
|
||||
-I$(top_srcdir)/lib/net \
|
||||
-I$(top_srcdir)/lib/synergy \
|
||||
-I$(top_srcdir)/lib/platform \
|
||||
-I$(top_srcdir)/lib/server \
|
||||
$(NULL)
|
||||
89
cmd/synergys/Makefile.win
Normal file
@@ -0,0 +1,89 @@
|
||||
# synergy -- mouse and keyboard sharing utility
|
||||
# Copyright (C) 2007 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.
|
||||
|
||||
BIN_SYNERGYS_SRC = cmd\synergys
|
||||
BIN_SYNERGYS_DST = $(BUILD_DST)\$(BIN_SYNERGYS_SRC)
|
||||
BIN_SYNERGYS_EXE = "$(BUILD_DST)\synergys.exe"
|
||||
BIN_SYNERGYS_CPP = \
|
||||
"CServerTaskBarReceiver.cpp" \
|
||||
"CMSWindowsServerTaskBarReceiver.cpp" \
|
||||
"synergys.cpp" \
|
||||
$(NULL)
|
||||
BIN_SYNERGYS_OBJ = \
|
||||
"$(BIN_SYNERGYS_DST)\CServerTaskBarReceiver.obj" \
|
||||
"$(BIN_SYNERGYS_DST)\CMSWindowsServerTaskBarReceiver.obj" \
|
||||
"$(BIN_SYNERGYS_DST)\synergys.obj" \
|
||||
$(NULL)
|
||||
BIN_SYNERGYS_RC = "$(BIN_SYNERGYS_SRC)\synergys.rc"
|
||||
BIN_SYNERGYS_RES = "$(BIN_SYNERGYS_DST)\synergys.res"
|
||||
BIN_SYNERGYS_INC = \
|
||||
/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" \
|
||||
$(NULL)
|
||||
BIN_SYNERGYS_LIB = \
|
||||
$(LIB_SERVER_LIB) \
|
||||
$(LIB_PLATFORM_LIB) \
|
||||
$(LIB_SYNERGY_LIB) \
|
||||
$(LIB_NET_LIB) \
|
||||
$(LIB_IO_LIB) \
|
||||
$(LIB_MT_LIB) \
|
||||
$(LIB_BASE_LIB) \
|
||||
$(LIB_ARCH_LIB) \
|
||||
$(LIB_COMMON_LIB) \
|
||||
$(NULL)
|
||||
|
||||
CPP_FILES = $(CPP_FILES) $(BIN_SYNERGYS_CPP)
|
||||
OBJ_FILES = $(OBJ_FILES) $(BIN_SYNERGYS_OBJ)
|
||||
PROGRAMS = $(PROGRAMS) $(BIN_SYNERGYS_EXE)
|
||||
|
||||
# Need shell functions.
|
||||
guilibs = $(guilibs) shell32.lib
|
||||
|
||||
# Dependency rules
|
||||
$(BIN_SYNERGYS_OBJ): $(AUTODEP)
|
||||
!if EXIST($(BIN_SYNERGYS_DST)\deps.mak)
|
||||
!include $(BIN_SYNERGYS_DST)\deps.mak
|
||||
!endif
|
||||
|
||||
# Build rules. Use batch-mode rules if possible.
|
||||
!if DEFINED(_NMAKE_VER)
|
||||
{$(BIN_SYNERGYS_SRC)\}.cpp{$(BIN_SYNERGYS_DST)\}.obj::
|
||||
!else
|
||||
{$(BIN_SYNERGYS_SRC)\}.cpp{$(BIN_SYNERGYS_DST)\}.obj:
|
||||
!endif
|
||||
@$(ECHO) Compile in $(BIN_SYNERGYS_SRC)
|
||||
-@$(MKDIR) $(BIN_SYNERGYS_DST) 2>NUL:
|
||||
$(cpp) $(cppdebug) $(cppflags) $(cppvarsmt) /showIncludes \
|
||||
$(BIN_SYNERGYS_INC) \
|
||||
/Fo$(BIN_SYNERGYS_DST)\ \
|
||||
/Fd$(BIN_SYNERGYS_DST)\src.pdb \
|
||||
$< | $(AUTODEP) $(BIN_SYNERGYS_SRC) $(BIN_SYNERGYS_DST)
|
||||
$(BIN_SYNERGYS_RES): $(BIN_SYNERGYS_RC)
|
||||
@$(ECHO) Compile $(**F)
|
||||
-@$(MKDIR) $(BIN_SYNERGYS_DST) 2>NUL:
|
||||
$(rc) $(rcflags) $(rcvars) \
|
||||
/fo$@ \
|
||||
$**
|
||||
$(BIN_SYNERGYS_EXE): $(BIN_SYNERGYS_OBJ) $(BIN_SYNERGYS_RES) $(BIN_SYNERGYS_LIB)
|
||||
@$(ECHO) Link $(@F)
|
||||
$(link) $(ldebug) $(guilflags) $(guilibsmt) \
|
||||
/out:$@ \
|
||||
$**
|
||||
$(AUTODEP) $(BIN_SYNERGYS_SRC) $(BIN_SYNERGYS_DST) \
|
||||
$(BIN_SYNERGYS_OBJ:.obj=.d)
|
||||
40
cmd/synergys/resource.h
Normal file
@@ -0,0 +1,40 @@
|
||||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Developer Studio generated include file.
|
||||
// Used by synergys.rc
|
||||
//
|
||||
#define IDS_FAILED 1
|
||||
#define IDS_INIT_FAILED 2
|
||||
#define IDS_UNCAUGHT_EXCEPTION 3
|
||||
#define IDI_SYNERGY 101
|
||||
#define IDI_TASKBAR_NOT_RUNNING 102
|
||||
#define IDI_TASKBAR_NOT_WORKING 103
|
||||
#define IDI_TASKBAR_NOT_CONNECTED 104
|
||||
#define IDI_TASKBAR_CONNECTED 105
|
||||
#define IDR_TASKBAR 107
|
||||
#define IDD_TASKBAR_STATUS 108
|
||||
#define IDC_TASKBAR_STATUS_STATUS 1000
|
||||
#define IDC_TASKBAR_STATUS_CLIENTS 1001
|
||||
#define IDC_TASKBAR_QUIT 40003
|
||||
#define IDC_TASKBAR_STATUS 40004
|
||||
#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 40016
|
||||
#define _APS_NEXT_CONTROL_VALUE 1003
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
||||
1312
cmd/synergys/synergys.cpp
Normal file
BIN
cmd/synergys/synergys.ico
Normal file
|
After Width: | Height: | Size: 8.3 KiB |
146
cmd/synergys/synergys.rc
Normal file
@@ -0,0 +1,146 @@
|
||||
//Microsoft Developer Studio generated resource script.
|
||||
//
|
||||
#include "resource.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#include <winresrc.h>
|
||||
#if !defined(IDC_STATIC)
|
||||
#define IDC_STATIC (-1)
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// English (U.S.) resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
||||
#ifdef _WIN32
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
#pragma code_page(1252)
|
||||
#endif //_WIN32
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEXTINCLUDE
|
||||
//
|
||||
|
||||
1 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"resource.h\0"
|
||||
END
|
||||
|
||||
2 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"#include <winresrc.h>\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
3 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Icon
|
||||
//
|
||||
|
||||
// Icon with lowest ID value placed first to ensure application icon
|
||||
// remains consistent on all systems.
|
||||
IDI_SYNERGY ICON DISCARDABLE "synergys.ico"
|
||||
IDI_TASKBAR_NOT_RUNNING ICON DISCARDABLE "tb_idle.ico"
|
||||
IDI_TASKBAR_NOT_WORKING ICON DISCARDABLE "tb_error.ico"
|
||||
IDI_TASKBAR_NOT_CONNECTED ICON DISCARDABLE "tb_wait.ico"
|
||||
IDI_TASKBAR_CONNECTED ICON DISCARDABLE "tb_run.ico"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Menu
|
||||
//
|
||||
|
||||
IDR_TASKBAR MENU DISCARDABLE
|
||||
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
|
||||
MENUITEM "Quit", IDC_TASKBAR_QUIT
|
||||
END
|
||||
END
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Dialog
|
||||
//
|
||||
|
||||
IDD_TASKBAR_STATUS DIALOG DISCARDABLE 0, 0, 145, 60
|
||||
STYLE DS_MODALFRAME | WS_POPUP
|
||||
FONT 8, "MS Sans Serif"
|
||||
BEGIN
|
||||
EDITTEXT IDC_TASKBAR_STATUS_STATUS,3,3,139,12,ES_AUTOHSCROLL |
|
||||
ES_READONLY | NOT WS_BORDER
|
||||
LISTBOX IDC_TASKBAR_STATUS_CLIENTS,3,17,139,40,NOT LBS_NOTIFY |
|
||||
LBS_SORT | LBS_NOINTEGRALHEIGHT | LBS_NOSEL | WS_VSCROLL |
|
||||
WS_TABSTOP
|
||||
END
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// String Table
|
||||
//
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
BEGIN
|
||||
IDS_FAILED "Synergy is about to quit with errors or warnings. Please check the log then click OK."
|
||||
IDS_INIT_FAILED "Synergy failed to initialize: %{1}"
|
||||
IDS_UNCAUGHT_EXCEPTION "Uncaught exception: %{1}"
|
||||
END
|
||||
|
||||
#endif // English (U.S.) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 3 resource.
|
||||
//
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
|
||||
BIN
cmd/synergys/tb_error.ico
Normal file
|
After Width: | Height: | Size: 318 B |
BIN
cmd/synergys/tb_idle.ico
Normal file
|
After Width: | Height: | Size: 318 B |
BIN
cmd/synergys/tb_run.ico
Normal file
|
After Width: | Height: | Size: 318 B |
BIN
cmd/synergys/tb_wait.ico
Normal file
|
After Width: | Height: | Size: 318 B |