mirror of
https://github.com/debauchee/barrier.git
synced 2026-05-11 00:58:14 +08:00
Merged Win32 updates. Added full warnings on g++. Fixed bug in
client when handling server rejection.
This commit is contained in:
@@ -14,6 +14,7 @@
|
||||
|
||||
#include "CConfig.h"
|
||||
#include "LaunchUtil.h"
|
||||
#include "CMSWindowsUtil.h"
|
||||
#include "CArch.h"
|
||||
#include "resource.h"
|
||||
#include "stdfstream.h"
|
||||
@@ -23,32 +24,13 @@
|
||||
CString
|
||||
getString(DWORD id)
|
||||
{
|
||||
char buffer[1024];
|
||||
buffer[0] = '\0';
|
||||
LoadString(s_instance, id, buffer, sizeof(buffer) / sizeof(buffer[0]));
|
||||
return buffer;
|
||||
return CMSWindowsUtil::getString(s_instance, id);
|
||||
}
|
||||
|
||||
CString
|
||||
getErrorString(DWORD error)
|
||||
{
|
||||
char* buffer;
|
||||
if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||
FORMAT_MESSAGE_IGNORE_INSERTS |
|
||||
FORMAT_MESSAGE_FROM_SYSTEM,
|
||||
0,
|
||||
error,
|
||||
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||
(LPTSTR)&buffer,
|
||||
0,
|
||||
NULL) == 0) {
|
||||
return getString(IDS_ERROR);
|
||||
}
|
||||
else {
|
||||
CString result(buffer);
|
||||
LocalFree(buffer);
|
||||
return result;
|
||||
}
|
||||
return CMSWindowsUtil::getErrorString(s_instance, error, IDS_ERROR);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -332,8 +332,8 @@ BEGIN
|
||||
"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_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 now automatically start each time you start your computer."
|
||||
IDS_INSTALLED_USER "Installed auto-start. Synergy will now automatically start each time you log in."
|
||||
@@ -348,6 +348,7 @@ BEGIN
|
||||
IDS_SERVER_IS_CLIENT "Please enter the computer name of the synergy server, not\nthe name of this computer, in the Server Host Name field."
|
||||
IDS_ADD_SCREEN "Add Screen"
|
||||
IDS_EDIT_SCREEN "Edit Screen %{1}"
|
||||
IDS_ERROR_CODE "Error code: %{1}"
|
||||
END
|
||||
|
||||
#endif // English (U.S.) resources
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#define IDS_ADD_SCREEN 37
|
||||
#define IDS_EDIT_SCREEN 38
|
||||
#define IDS_INVALID_TIME 39
|
||||
#define IDS_ERROR_CODE 39
|
||||
#define IDD_MAIN 101
|
||||
#define IDD_ADD 102
|
||||
#define IDD_WAIT 103
|
||||
|
||||
@@ -21,18 +21,19 @@
|
||||
#include "CArchTaskBarWindows.h"
|
||||
#include "resource.h"
|
||||
|
||||
static const UINT g_stateToIconID[CMSWindowsClientTaskBarReceiver::kMaxState] =
|
||||
//
|
||||
// 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::CMSWindowsClientTaskBarReceiver(
|
||||
HINSTANCE appInstance, const CBufferedLogOutputter* logBuffer) :
|
||||
CClientTaskBarReceiver(),
|
||||
@@ -41,7 +42,7 @@ CMSWindowsClientTaskBarReceiver::CMSWindowsClientTaskBarReceiver(
|
||||
m_logBuffer(logBuffer)
|
||||
{
|
||||
for (UInt32 i = 0; i < kMaxState; ++i) {
|
||||
m_icon[i] = loadIcon(g_stateToIconID[i]);
|
||||
m_icon[i] = loadIcon(s_stateToIconID[i]);
|
||||
}
|
||||
m_menu = LoadMenu(m_appInstance, MAKEINTRESOURCE(IDR_TASKBAR));
|
||||
|
||||
@@ -171,7 +172,7 @@ CMSWindowsClientTaskBarReceiver::primaryAction()
|
||||
const IArchTaskBarReceiver::Icon
|
||||
CMSWindowsClientTaskBarReceiver::getIcon() const
|
||||
{
|
||||
return reinterpret_cast<Icon>(m_icon[getState()]);
|
||||
return reinterpret_cast<Icon>(m_icon[getStatus()]);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -58,6 +58,7 @@ private:
|
||||
HMENU m_menu;
|
||||
HICON m_icon[kMaxState];
|
||||
const CBufferedLogOutputter* m_logBuffer;
|
||||
static const UINT s_stateToIconID[];
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -19,7 +19,8 @@
|
||||
// CXWindowsClientTaskBarReceiver
|
||||
//
|
||||
|
||||
CXWindowsClientTaskBarReceiver::CXWindowsClientTaskBarReceiver()
|
||||
CXWindowsClientTaskBarReceiver::CXWindowsClientTaskBarReceiver(
|
||||
const CBufferedLogOutputter*)
|
||||
{
|
||||
// add ourself to the task bar
|
||||
ARCH->addReceiver(this);
|
||||
|
||||
@@ -17,10 +17,12 @@
|
||||
|
||||
#include "CClientTaskBarReceiver.h"
|
||||
|
||||
class CBufferedLogOutputter;
|
||||
|
||||
//! Implementation of CClientTaskBarReceiver for X Windows
|
||||
class CXWindowsClientTaskBarReceiver : public CClientTaskBarReceiver {
|
||||
public:
|
||||
CXWindowsClientTaskBarReceiver();
|
||||
CXWindowsClientTaskBarReceiver(const CBufferedLogOutputter*);
|
||||
virtual ~CXWindowsClientTaskBarReceiver();
|
||||
|
||||
// IArchTaskBarReceiver overrides
|
||||
|
||||
@@ -48,6 +48,7 @@ synergyc_LDADD = \
|
||||
$(DEPTH)/lib/io/libio.a \
|
||||
$(DEPTH)/lib/mt/libmt.a \
|
||||
$(DEPTH)/lib/base/libbase.a \
|
||||
$(DEPTH)/lib/common/libcommon.a \
|
||||
$(DEPTH)/lib/arch/libarch.a \
|
||||
$(X_LIBS) \
|
||||
$(X_PRE_LIBS) \
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
// 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
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "CFunctionEventJob.h"
|
||||
#include "CLog.h"
|
||||
#include "CString.h"
|
||||
#include "CStringUtil.h"
|
||||
#include "LogOutputters.h"
|
||||
#include "CArch.h"
|
||||
#include "XArch.h"
|
||||
@@ -33,8 +34,9 @@
|
||||
|
||||
#define DAEMON_RUNNING(running_)
|
||||
#if WINDOWS_LIKE
|
||||
#include "CMSWindowsScreen.h"
|
||||
#include "CArchMiscWindows.h"
|
||||
#include "CMSWindowsScreen.h"
|
||||
#include "CMSWindowsUtil.h"
|
||||
#include "CMSWindowsClientTaskBarReceiver.h"
|
||||
#include "resource.h"
|
||||
#undef DAEMON_RUNNING
|
||||
@@ -51,6 +53,9 @@
|
||||
#define DAEMON_NAME "synergyc"
|
||||
#endif
|
||||
|
||||
typedef int (*StartupFunc)(int, char**);
|
||||
static void parse(int argc, const char* const* argv);
|
||||
|
||||
//
|
||||
// program arguments
|
||||
//
|
||||
@@ -64,7 +69,8 @@ public:
|
||||
m_backend(false),
|
||||
m_restartable(true),
|
||||
m_daemon(true),
|
||||
m_logFilter(NULL)
|
||||
m_logFilter(NULL),
|
||||
m_serverAddress(NULL)
|
||||
{ s_instance = this; }
|
||||
~CArgs() { s_instance = NULL; }
|
||||
|
||||
@@ -76,7 +82,7 @@ public:
|
||||
bool m_daemon;
|
||||
const char* m_logFilter;
|
||||
CString m_name;
|
||||
CNetworkAddress m_serverAddress;
|
||||
CNetworkAddress* m_serverAddress;
|
||||
};
|
||||
|
||||
CArgs* CArgs::s_instance = NULL;
|
||||
@@ -97,6 +103,18 @@ createScreen()
|
||||
#endif
|
||||
}
|
||||
|
||||
static
|
||||
CClientTaskBarReceiver*
|
||||
createTaskBarReceiver(const CBufferedLogOutputter* logBuffer)
|
||||
{
|
||||
#if WINDOWS_LIKE
|
||||
return new CMSWindowsClientTaskBarReceiver(
|
||||
CMSWindowsScreen::getInstance(), logBuffer);
|
||||
#elif UNIX_LIKE
|
||||
return new CXWindowsClientTaskBarReceiver(logBuffer);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// platform independent main
|
||||
@@ -292,7 +310,7 @@ startClient()
|
||||
try {
|
||||
clientScreen = openClientScreen();
|
||||
s_client = openClient(ARG->m_name,
|
||||
ARG->m_serverAddress, clientScreen);
|
||||
*ARG->m_serverAddress, clientScreen);
|
||||
s_clientScreen = clientScreen;
|
||||
LOG((CLOG_NOTE "started client"));
|
||||
s_client->connect();
|
||||
@@ -338,7 +356,7 @@ stopClient()
|
||||
|
||||
static
|
||||
int
|
||||
realMain()
|
||||
mainLoop()
|
||||
{
|
||||
// start the client. if this return false then we've failed and
|
||||
// we shouldn't retry.
|
||||
@@ -350,8 +368,8 @@ realMain()
|
||||
// run event loop. if startClient() failed we're supposed to retry
|
||||
// later. the timer installed by startClient() will take care of
|
||||
// that.
|
||||
DAEMON_RUNNING(true);
|
||||
CEvent event;
|
||||
DAEMON_RUNNING(true);
|
||||
EVENTQUEUE->getEvent(event);
|
||||
while (event.getType() != CEvent::kQuit) {
|
||||
EVENTQUEUE->dispatchEvent(event);
|
||||
@@ -369,45 +387,65 @@ realMain()
|
||||
return kExitSuccess;
|
||||
}
|
||||
|
||||
/*
|
||||
static
|
||||
void
|
||||
realMainEntry(void* vresult)
|
||||
int
|
||||
daemonMainLoop(int, const char**)
|
||||
{
|
||||
*reinterpret_cast<int*>(vresult) = realMain();
|
||||
CSystemLogger sysLogger(DAEMON_NAME);
|
||||
return mainLoop();
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
runMainInThread(void)
|
||||
standardStartup(int argc, char** argv)
|
||||
{
|
||||
int result = 0;
|
||||
CThread appThread(new CFunctionJob(&realMainEntry, &result));
|
||||
try {
|
||||
#if WINDOWS_LIKE
|
||||
MSG msg;
|
||||
while (appThread.waitForEvent(-1.0) == CThread::kEvent) {
|
||||
// check for a quit event
|
||||
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
|
||||
if (msg.message == WM_QUIT) {
|
||||
CThread::getCurrentThread().cancel();
|
||||
}
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
}
|
||||
#else
|
||||
appThread.wait(-1.0);
|
||||
#endif
|
||||
return result;
|
||||
// parse command line
|
||||
parse(argc, argv);
|
||||
|
||||
// daemonize if requested
|
||||
if (ARG->m_daemon) {
|
||||
return ARCH->daemonize(DAEMON_NAME, &daemonMainLoop);
|
||||
}
|
||||
catch (XThread&) {
|
||||
appThread.cancel();
|
||||
appThread.wait(-1.0);
|
||||
throw;
|
||||
else {
|
||||
return mainLoop();
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
static
|
||||
int
|
||||
run(int argc, char** argv, ILogOutputter* outputter, StartupFunc startup)
|
||||
{
|
||||
// general initialization
|
||||
CSocketMultiplexer multiplexer;
|
||||
CEventQueue eventQueue;
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
@@ -588,7 +626,7 @@ parse(int argc, const char* const* argv)
|
||||
|
||||
// save server address
|
||||
try {
|
||||
ARG->m_serverAddress = CNetworkAddress(argv[i], kDefaultPort);
|
||||
*ARG->m_serverAddress = CNetworkAddress(argv[i], kDefaultPort);
|
||||
}
|
||||
catch (XSocketAddress& e) {
|
||||
LOG((CLOG_PRINT "%s: %s" BYE,
|
||||
@@ -676,192 +714,106 @@ byeThrow(int x)
|
||||
|
||||
static
|
||||
int
|
||||
daemonStartup(int argc, const char** argv)
|
||||
daemonNTMainLoop(int argc, const char** argv)
|
||||
{
|
||||
CSystemLogger sysLogger(DAEMON_NAME);
|
||||
|
||||
// have to cancel this thread to quit
|
||||
s_taskBarReceiver->setQuitJob(new CQuitJob(CThread::getCurrentThread()));
|
||||
|
||||
// catch errors that would normally exit
|
||||
bye = &byeThrow;
|
||||
|
||||
// parse command line
|
||||
parse(argc, argv);
|
||||
|
||||
// cannot run as backend if running as a service
|
||||
ARG->m_backend = false;
|
||||
|
||||
// run as a service
|
||||
return CArchMiscWindows::runDaemon(realMain);
|
||||
return CArchMiscWindows::runDaemon(mainLoop);
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
daemonStartup95(int, const char**)
|
||||
daemonNTStartup(int, char**)
|
||||
{
|
||||
CSystemLogger sysLogger(DAEMON_NAME);
|
||||
return runMainInThread();
|
||||
bye = &byeThrow;
|
||||
return ARCH->daemonize(DAEMON_NAME, &daemonNTMainLoop);
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
run(int argc, char** argv)
|
||||
void
|
||||
showError(HINSTANCE instance, const char* title, UINT id, const char* arg)
|
||||
{
|
||||
// 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.
|
||||
if (argc <= 1 && !CArchMiscWindows::isWindows95Family()) {
|
||||
try {
|
||||
return ARCH->daemonize(DAEMON_NAME, &daemonStartup);
|
||||
}
|
||||
catch (XArchDaemon& e) {
|
||||
LOG((CLOG_CRIT "failed to start as a service: %s" BYE, e.what().c_str(), ARG->m_pname));
|
||||
}
|
||||
return kExitFailed;
|
||||
}
|
||||
|
||||
// parse command line
|
||||
parse(argc, argv);
|
||||
|
||||
// daemonize if requested
|
||||
if (ARG->m_daemon) {
|
||||
// start as a daemon
|
||||
if (CArchMiscWindows::isWindows95Family()) {
|
||||
try {
|
||||
return ARCH->daemonize(DAEMON_NAME, &daemonStartup95);
|
||||
}
|
||||
catch (XArchDaemon& e) {
|
||||
LOG((CLOG_CRIT "failed to start as a service: %s" BYE, e.what().c_str(), ARG->m_pname));
|
||||
}
|
||||
return kExitFailed;
|
||||
}
|
||||
else {
|
||||
// cannot start a service from the command line so just
|
||||
// run normally (except with log messages redirected).
|
||||
CSystemLogger sysLogger(DAEMON_NAME);
|
||||
return runMainInThread();
|
||||
}
|
||||
}
|
||||
else {
|
||||
// run
|
||||
return runMainInThread();
|
||||
}
|
||||
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)
|
||||
{
|
||||
CArch arch(instance);
|
||||
CLOG;
|
||||
CArgs args;
|
||||
|
||||
// save instance
|
||||
CMSWindowsScreen::init(instance);
|
||||
|
||||
// get program name
|
||||
ARG->m_pname = ARCH->getBasename(__argv[0]);
|
||||
|
||||
// send PRINT and FATAL output to a message box
|
||||
CLOG->insert(new CMessageBoxOutputter);
|
||||
|
||||
// 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 = new CMSWindowsClientTaskBarReceiver(instance,
|
||||
&logBuffer);
|
||||
s_taskBarReceiver->setQuitJob(new CQuitJob(CThread::getCurrentThread()));
|
||||
|
||||
int result;
|
||||
try {
|
||||
// run in foreground or as a daemon
|
||||
result = run(__argc, __argv);
|
||||
CArch arch(instance);
|
||||
CMSWindowsScreen::init(instance);
|
||||
CLOG;
|
||||
// FIXME
|
||||
// CThread::getCurrentThread().setPriority(-14);
|
||||
CArgs args;
|
||||
|
||||
// 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 (__argc <= 1 && !CArchMiscWindows::isWindows95Family()) {
|
||||
startup = &daemonNTStartup;
|
||||
}
|
||||
|
||||
// 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());
|
||||
return kExitFailed;
|
||||
}
|
||||
catch (...) {
|
||||
// note that we don't rethrow thread cancellation. we'll
|
||||
// be exiting soon so it doesn't matter. what we'd like
|
||||
// is for everything after this try/catch to be in a
|
||||
// finally block.
|
||||
result = kExitFailed;
|
||||
showError(instance, __argv[0], IDS_UNCAUGHT_EXCEPTION, "<unknown>");
|
||||
throw;
|
||||
}
|
||||
|
||||
// done with task bar receiver
|
||||
delete s_taskBarReceiver;
|
||||
|
||||
// done with log buffer
|
||||
CLOG->remove(&logBuffer);
|
||||
|
||||
// let user examine any messages if we're running as a backend
|
||||
// by putting up a dialog box before exiting.
|
||||
if (ARG->m_backend && s_hasImportantLogMessages) {
|
||||
char msg[1024];
|
||||
msg[0] = '\0';
|
||||
LoadString(instance, IDS_FAILED, msg, sizeof(msg) / sizeof(msg[0]));
|
||||
MessageBox(NULL, msg, ARG->m_pname, MB_OK | MB_ICONWARNING);
|
||||
}
|
||||
|
||||
delete CLOG;
|
||||
return result;
|
||||
}
|
||||
|
||||
#elif UNIX_LIKE
|
||||
|
||||
static
|
||||
int
|
||||
daemonStartup(int, const char**)
|
||||
{
|
||||
CSystemLogger sysLogger(DAEMON_NAME);
|
||||
return realMain();
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char** argv)
|
||||
{
|
||||
CArch arch;
|
||||
CLOG;
|
||||
|
||||
// go really fast
|
||||
CThread::getCurrentThread().setPriority(-14);
|
||||
|
||||
CSocketMultiplexer multiplexer;
|
||||
CEventQueue eventQueue;
|
||||
|
||||
// get program name
|
||||
CArgs args;
|
||||
ARG->m_pname = ARCH->getBasename(argv[0]);
|
||||
|
||||
// make the task bar receiver. the user can control this app
|
||||
// through the task bar.
|
||||
s_taskBarReceiver = new CXWindowsClientTaskBarReceiver;
|
||||
|
||||
// parse command line
|
||||
parse(argc, argv);
|
||||
|
||||
// daemonize if requested
|
||||
int result;
|
||||
if (ARG->m_daemon) {
|
||||
try {
|
||||
result = ARCH->daemonize(DAEMON_NAME, &daemonStartup);
|
||||
}
|
||||
catch (XArchDaemon&) {
|
||||
LOG((CLOG_CRIT "failed to daemonize"));
|
||||
result = kExitFailed;
|
||||
}
|
||||
try {
|
||||
int result;
|
||||
CArch arch;
|
||||
CLOG;
|
||||
CArgs args;
|
||||
result = run(argc, argv, NULL, &standardStartup);
|
||||
delete CLOG;
|
||||
return result;
|
||||
}
|
||||
else {
|
||||
result = realMain();
|
||||
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;
|
||||
}
|
||||
|
||||
// done with task bar receiver
|
||||
delete s_taskBarReceiver;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
@@ -99,6 +99,8 @@ END
|
||||
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
|
||||
|
||||
@@ -21,7 +21,11 @@
|
||||
#include "CArchTaskBarWindows.h"
|
||||
#include "resource.h"
|
||||
|
||||
static const UINT g_stateToIconID[CMSWindowsServerTaskBarReceiver::kMaxState] =
|
||||
//
|
||||
// CMSWindowsServerTaskBarReceiver
|
||||
//
|
||||
|
||||
const UINT CMSWindowsServerTaskBarReceiver::s_stateToIconID[kMaxState] =
|
||||
{
|
||||
IDI_TASKBAR_NOT_RUNNING,
|
||||
IDI_TASKBAR_NOT_WORKING,
|
||||
@@ -29,10 +33,6 @@ static const UINT g_stateToIconID[CMSWindowsServerTaskBarReceiver::kMaxState] =
|
||||
IDI_TASKBAR_CONNECTED
|
||||
};
|
||||
|
||||
//
|
||||
// CMSWindowsServerTaskBarReceiver
|
||||
//
|
||||
|
||||
CMSWindowsServerTaskBarReceiver::CMSWindowsServerTaskBarReceiver(
|
||||
HINSTANCE appInstance, const CBufferedLogOutputter* logBuffer) :
|
||||
CServerTaskBarReceiver(),
|
||||
@@ -41,7 +41,7 @@ CMSWindowsServerTaskBarReceiver::CMSWindowsServerTaskBarReceiver(
|
||||
m_logBuffer(logBuffer)
|
||||
{
|
||||
for (UInt32 i = 0; i < kMaxState; ++i) {
|
||||
m_icon[i] = loadIcon(g_stateToIconID[i]);
|
||||
m_icon[i] = loadIcon(s_stateToIconID[i]);
|
||||
}
|
||||
m_menu = LoadMenu(m_appInstance, MAKEINTRESOURCE(IDR_TASKBAR));
|
||||
|
||||
@@ -77,12 +77,7 @@ CMSWindowsServerTaskBarReceiver::showStatus()
|
||||
std::string status = getToolTip();
|
||||
|
||||
// get the connect clients, if any
|
||||
typedef std::vector<CString> CClientList;
|
||||
CClientList clients;
|
||||
CServer* server = getServer();
|
||||
if (server != NULL) {
|
||||
server->getClients(clients);
|
||||
}
|
||||
const CClients& clients = getClients();
|
||||
|
||||
// done getting status
|
||||
unlock();
|
||||
@@ -92,7 +87,7 @@ CMSWindowsServerTaskBarReceiver::showStatus()
|
||||
SendMessage(child, WM_SETTEXT, 0, (LPARAM)status.c_str());
|
||||
child = GetDlgItem(m_window, IDC_TASKBAR_STATUS_CLIENTS);
|
||||
SendMessage(child, LB_RESETCONTENT, 0, 0);
|
||||
for (CClientList::const_iterator index = clients.begin();
|
||||
for (CClients::const_iterator index = clients.begin();
|
||||
index != clients.end(); ) {
|
||||
const char* client = index->c_str();
|
||||
if (++index == clients.end()) {
|
||||
@@ -191,7 +186,7 @@ CMSWindowsServerTaskBarReceiver::primaryAction()
|
||||
const IArchTaskBarReceiver::Icon
|
||||
CMSWindowsServerTaskBarReceiver::getIcon() const
|
||||
{
|
||||
return reinterpret_cast<Icon>(m_icon[getState()]);
|
||||
return reinterpret_cast<Icon>(m_icon[getStatus()]);
|
||||
}
|
||||
|
||||
void
|
||||
|
||||
@@ -58,6 +58,7 @@ private:
|
||||
HMENU m_menu;
|
||||
HICON m_icon[kMaxState];
|
||||
const CBufferedLogOutputter* m_logBuffer;
|
||||
static const UINT s_stateToIconID[];
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -19,7 +19,8 @@
|
||||
// CXWindowsServerTaskBarReceiver
|
||||
//
|
||||
|
||||
CXWindowsServerTaskBarReceiver::CXWindowsServerTaskBarReceiver()
|
||||
CXWindowsServerTaskBarReceiver::CXWindowsServerTaskBarReceiver(
|
||||
const CBufferedLogOutputter*)
|
||||
{
|
||||
// add ourself to the task bar
|
||||
ARCH->addReceiver(this);
|
||||
|
||||
@@ -17,10 +17,12 @@
|
||||
|
||||
#include "CServerTaskBarReceiver.h"
|
||||
|
||||
class CBufferedLogOutputter;
|
||||
|
||||
//! Implementation of CServerTaskBarReceiver for X Windows
|
||||
class CXWindowsServerTaskBarReceiver : public CServerTaskBarReceiver {
|
||||
public:
|
||||
CXWindowsServerTaskBarReceiver();
|
||||
CXWindowsServerTaskBarReceiver(const CBufferedLogOutputter*);
|
||||
virtual ~CXWindowsServerTaskBarReceiver();
|
||||
|
||||
// IArchTaskBarReceiver overrides
|
||||
|
||||
@@ -48,6 +48,7 @@ synergys_LDADD = \
|
||||
$(DEPTH)/lib/io/libio.a \
|
||||
$(DEPTH)/lib/mt/libmt.a \
|
||||
$(DEPTH)/lib/base/libbase.a \
|
||||
$(DEPTH)/lib/common/libcommon.a \
|
||||
$(DEPTH)/lib/arch/libarch.a \
|
||||
$(X_LIBS) \
|
||||
$(X_PRE_LIBS) \
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
// 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
|
||||
|
||||
@@ -28,6 +28,8 @@
|
||||
#include "CEventQueue.h"
|
||||
#include "CFunctionEventJob.h"
|
||||
#include "CLog.h"
|
||||
#include "CString.h"
|
||||
#include "CStringUtil.h"
|
||||
#include "LogOutputters.h"
|
||||
#include "CArch.h"
|
||||
#include "XArch.h"
|
||||
@@ -36,8 +38,9 @@
|
||||
|
||||
#define DAEMON_RUNNING(running_)
|
||||
#if WINDOWS_LIKE
|
||||
#include "CMSWindowsScreen.h"
|
||||
#include "CArchMiscWindows.h"
|
||||
#include "CMSWindowsScreen.h"
|
||||
#include "CMSWindowsUtil.h"
|
||||
#include "CMSWindowsServerTaskBarReceiver.h"
|
||||
#include "resource.h"
|
||||
#undef DAEMON_RUNNING
|
||||
@@ -63,6 +66,10 @@
|
||||
#define SYS_CONFIG_NAME "synergy.conf"
|
||||
#endif
|
||||
|
||||
typedef int (*StartupFunc)(int, char**);
|
||||
static void parse(int argc, const char* const* argv);
|
||||
static void loadConfig();
|
||||
|
||||
//
|
||||
// program arguments
|
||||
//
|
||||
@@ -90,8 +97,8 @@ public:
|
||||
const char* m_configFile;
|
||||
const char* m_logFilter;
|
||||
CString m_name;
|
||||
CNetworkAddress m_synergyAddress;
|
||||
CConfig m_config;
|
||||
CNetworkAddress* m_synergyAddress;
|
||||
CConfig* m_config;
|
||||
};
|
||||
|
||||
CArgs* CArgs::s_instance = NULL;
|
||||
@@ -112,6 +119,18 @@ createScreen()
|
||||
#endif
|
||||
}
|
||||
|
||||
static
|
||||
CServerTaskBarReceiver*
|
||||
createTaskBarReceiver(const CBufferedLogOutputter* logBuffer)
|
||||
{
|
||||
#if WINDOWS_LIKE
|
||||
return new CMSWindowsServerTaskBarReceiver(
|
||||
CMSWindowsScreen::getInstance(), logBuffer);
|
||||
#elif UNIX_LIKE
|
||||
return new CXWindowsServerTaskBarReceiver(logBuffer);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// platform independent main
|
||||
@@ -299,11 +318,11 @@ startServer()
|
||||
CPrimaryClient* primaryClient = NULL;
|
||||
CClientListener* listener = NULL;
|
||||
try {
|
||||
CString name = ARG->m_config.getCanonicalName(ARG->m_name);
|
||||
CString name = ARG->m_config->getCanonicalName(ARG->m_name);
|
||||
serverScreen = openServerScreen();
|
||||
primaryClient = openPrimaryClient(name, serverScreen);
|
||||
listener = openClientListener(ARG->m_config.getSynergyAddress());
|
||||
s_server = openServer(ARG->m_config, primaryClient);
|
||||
listener = openClientListener(ARG->m_config->getSynergyAddress());
|
||||
s_server = openServer(*ARG->m_config, primaryClient);
|
||||
s_serverScreen = serverScreen;
|
||||
s_primaryClient = primaryClient;
|
||||
s_listener = listener;
|
||||
@@ -372,26 +391,26 @@ stopServer()
|
||||
|
||||
static
|
||||
int
|
||||
realMain()
|
||||
mainLoop()
|
||||
{
|
||||
// if configuration has no screens then add this system
|
||||
// as the default
|
||||
if (ARG->m_config.begin() == ARG->m_config.end()) {
|
||||
ARG->m_config.addScreen(ARG->m_name);
|
||||
if (ARG->m_config->begin() == ARG->m_config->end()) {
|
||||
ARG->m_config->addScreen(ARG->m_name);
|
||||
}
|
||||
|
||||
// set the contact address, if provided, in the config.
|
||||
// otherwise, if the config doesn't have an address, use
|
||||
// the default.
|
||||
if (ARG->m_synergyAddress.isValid()) {
|
||||
ARG->m_config.setSynergyAddress(ARG->m_synergyAddress);
|
||||
if (ARG->m_synergyAddress->isValid()) {
|
||||
ARG->m_config->setSynergyAddress(*ARG->m_synergyAddress);
|
||||
}
|
||||
else if (!ARG->m_config.getSynergyAddress().isValid()) {
|
||||
ARG->m_config.setSynergyAddress(CNetworkAddress(kDefaultPort));
|
||||
else if (!ARG->m_config->getSynergyAddress().isValid()) {
|
||||
ARG->m_config->setSynergyAddress(CNetworkAddress(kDefaultPort));
|
||||
}
|
||||
|
||||
// canonicalize the primary screen name
|
||||
CString primaryName = ARG->m_config.getCanonicalName(ARG->m_name);
|
||||
CString primaryName = ARG->m_config->getCanonicalName(ARG->m_name);
|
||||
if (primaryName.empty()) {
|
||||
LOG((CLOG_CRIT "unknown screen name `%s'", ARG->m_name.c_str()));
|
||||
return kExitFailed;
|
||||
@@ -407,8 +426,8 @@ realMain()
|
||||
// run event loop. if startServer() failed we're supposed to retry
|
||||
// later. the timer installed by startServer() will take care of
|
||||
// that.
|
||||
DAEMON_RUNNING(true);
|
||||
CEvent event;
|
||||
DAEMON_RUNNING(true);
|
||||
EVENTQUEUE->getEvent(event);
|
||||
while (event.getType() != CEvent::kQuit) {
|
||||
EVENTQUEUE->dispatchEvent(event);
|
||||
@@ -426,43 +445,71 @@ realMain()
|
||||
return kExitSuccess;
|
||||
}
|
||||
|
||||
/* XXX
|
||||
static
|
||||
void
|
||||
realMainEntry(void* vresult)
|
||||
int
|
||||
daemonMainLoop(int, const char**)
|
||||
{
|
||||
*reinterpret_cast<int*>(vresult) = realMain();
|
||||
CSystemLogger sysLogger(DAEMON_NAME);
|
||||
return mainLoop();
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
runMainInThread(void)
|
||||
standardStartup(int argc, char** argv)
|
||||
{
|
||||
int result = 0;
|
||||
CThread appThread(new CFunctionJob(&realMainEntry, &result));
|
||||
try {
|
||||
#if WINDOWS_LIKE
|
||||
MSG msg;
|
||||
while (appThread.waitForEvent(-1.0) == CThread::kEvent) {
|
||||
// check for a quit event
|
||||
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
|
||||
if (msg.message == WM_QUIT) {
|
||||
CThread::getCurrentThread().cancel();
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
appThread.wait(-1.0);
|
||||
#endif
|
||||
return result;
|
||||
// parse command line
|
||||
parse(argc, argv);
|
||||
|
||||
// load configuration
|
||||
loadConfig();
|
||||
|
||||
// daemonize if requested
|
||||
if (ARG->m_daemon) {
|
||||
return ARCH->daemonize(DAEMON_NAME, &daemonMainLoop);
|
||||
}
|
||||
catch (XThread&) {
|
||||
appThread.cancel();
|
||||
appThread.wait(-1.0);
|
||||
throw;
|
||||
else {
|
||||
return mainLoop();
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
static
|
||||
int
|
||||
run(int argc, char** argv, ILogOutputter* outputter, StartupFunc startup)
|
||||
{
|
||||
// general initialization
|
||||
CSocketMultiplexer multiplexer;
|
||||
CEventQueue eventQueue;
|
||||
ARG->m_synergyAddress = new CNetworkAddress;
|
||||
ARG->m_config = new CConfig;
|
||||
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_config;
|
||||
delete ARG->m_synergyAddress;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// command line parsing
|
||||
@@ -606,7 +653,7 @@ parse(int argc, const char* const* argv)
|
||||
else if (isArg(i, argc, argv, "-a", "--address", 1)) {
|
||||
// save listen address
|
||||
try {
|
||||
ARG->m_synergyAddress = CNetworkAddress(argv[i + 1],
|
||||
*ARG->m_synergyAddress = CNetworkAddress(argv[i + 1],
|
||||
kDefaultPort);
|
||||
}
|
||||
catch (XSocketAddress& e) {
|
||||
@@ -723,7 +770,7 @@ loadConfig(const char* pathname)
|
||||
if (!configStream) {
|
||||
throw XConfigRead("cannot open file");
|
||||
}
|
||||
configStream >> ARG->m_config;
|
||||
configStream >> *ARG->m_config;
|
||||
LOG((CLOG_DEBUG "configuration read successfully"));
|
||||
return true;
|
||||
}
|
||||
@@ -828,197 +875,107 @@ byeThrow(int x)
|
||||
|
||||
static
|
||||
int
|
||||
daemonStartup(int argc, const char** argv)
|
||||
daemonNTMainLoop(int argc, const char** argv)
|
||||
{
|
||||
CSystemLogger sysLogger(DAEMON_NAME);
|
||||
|
||||
// catch errors that would normally exit
|
||||
bye = &byeThrow;
|
||||
|
||||
// parse command line
|
||||
parse(argc, argv);
|
||||
|
||||
// cannot run as backend if running as a service
|
||||
ARG->m_backend = false;
|
||||
|
||||
// load configuration
|
||||
loadConfig();
|
||||
|
||||
// run as a service
|
||||
return CArchMiscWindows::runDaemon(realMain);
|
||||
return CArchMiscWindows::runDaemon(mainLoop);
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
daemonStartup95(int, const char**)
|
||||
daemonNTStartup(int, char**)
|
||||
{
|
||||
CSystemLogger sysLogger(DAEMON_NAME);
|
||||
return runMainInThread();
|
||||
bye = &byeThrow;
|
||||
return ARCH->daemonize(DAEMON_NAME, &daemonNTMainLoop);
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
run(int argc, char** argv)
|
||||
void
|
||||
showError(HINSTANCE instance, const char* title, UINT id, const char* arg)
|
||||
{
|
||||
// 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.
|
||||
if (argc <= 1 && !CArchMiscWindows::isWindows95Family()) {
|
||||
try {
|
||||
return ARCH->daemonize(DAEMON_NAME, &daemonStartup);
|
||||
}
|
||||
catch (XArchDaemon& e) {
|
||||
LOG((CLOG_CRIT "failed to start as a service: %s" BYE, e.what().c_str(), ARG->m_pname));
|
||||
}
|
||||
return kExitFailed;
|
||||
}
|
||||
|
||||
// parse command line
|
||||
parse(argc, argv);
|
||||
|
||||
// load configuration
|
||||
loadConfig();
|
||||
|
||||
// daemonize if requested
|
||||
if (ARG->m_daemon) {
|
||||
// start as a daemon
|
||||
if (CArchMiscWindows::isWindows95Family()) {
|
||||
try {
|
||||
return ARCH->daemonize(DAEMON_NAME, &daemonStartup95);
|
||||
}
|
||||
catch (XArchDaemon& e) {
|
||||
LOG((CLOG_CRIT "failed to start as a service: %s" BYE, e.what().c_str(), ARG->m_pname));
|
||||
}
|
||||
return kExitFailed;
|
||||
}
|
||||
else {
|
||||
// cannot start a service from the command line so just
|
||||
// run normally (except with log messages redirected).
|
||||
CSystemLogger sysLogger(DAEMON_NAME);
|
||||
return runMainInThread();
|
||||
}
|
||||
}
|
||||
else {
|
||||
// run
|
||||
return runMainInThread();
|
||||
}
|
||||
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)
|
||||
{
|
||||
CArch arch(instance);
|
||||
CLOG;
|
||||
CArgs args;
|
||||
|
||||
// save instance
|
||||
CMSWindowsScreen::init(instance);
|
||||
|
||||
// get program name
|
||||
ARG->m_pname = ARCH->getBasename(__argv[0]);
|
||||
|
||||
// send PRINT and FATAL output to a message box
|
||||
CLOG->insert(new CMessageBoxOutputter);
|
||||
|
||||
// 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 = new CMSWindowsServerTaskBarReceiver(instance,
|
||||
&logBuffer);
|
||||
|
||||
int result;
|
||||
try {
|
||||
// run in foreground or as a daemon
|
||||
result = run(__argc, __argv);
|
||||
CArch arch(instance);
|
||||
CMSWindowsScreen::init(instance);
|
||||
CLOG;
|
||||
// FIXME
|
||||
// CThread::getCurrentThread().setPriority(-14);
|
||||
CArgs args;
|
||||
|
||||
// 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 (__argc <= 1 && !CArchMiscWindows::isWindows95Family()) {
|
||||
startup = &daemonNTStartup;
|
||||
}
|
||||
|
||||
// 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());
|
||||
return kExitFailed;
|
||||
}
|
||||
catch (...) {
|
||||
// note that we don't rethrow thread cancellation. we'll
|
||||
// be exiting soon so it doesn't matter. what we'd like
|
||||
// is for everything after this try/catch to be in a
|
||||
// finally block.
|
||||
result = kExitFailed;
|
||||
showError(instance, __argv[0], IDS_UNCAUGHT_EXCEPTION, "<unknown>");
|
||||
throw;
|
||||
}
|
||||
|
||||
// done with task bar receiver
|
||||
delete s_taskBarReceiver;
|
||||
|
||||
// done with log buffer
|
||||
CLOG->remove(&logBuffer);
|
||||
|
||||
// let user examine any messages if we're running as a backend
|
||||
// by putting up a dialog box before exiting.
|
||||
if (ARG->m_backend && s_hasImportantLogMessages) {
|
||||
char msg[1024];
|
||||
msg[0] = '\0';
|
||||
LoadString(instance, IDS_FAILED, msg, sizeof(msg) / sizeof(msg[0]));
|
||||
MessageBox(NULL, msg, ARG->m_pname, MB_OK | MB_ICONWARNING);
|
||||
}
|
||||
|
||||
delete CLOG;
|
||||
return result;
|
||||
}
|
||||
|
||||
#elif UNIX_LIKE
|
||||
|
||||
static
|
||||
int
|
||||
daemonStartup(int, const char**)
|
||||
{
|
||||
CSystemLogger sysLogger(DAEMON_NAME);
|
||||
return realMain();
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char** argv)
|
||||
{
|
||||
CArch arch;
|
||||
CLOG;
|
||||
|
||||
// go really fast
|
||||
CThread::getCurrentThread().setPriority(-14);
|
||||
|
||||
CSocketMultiplexer multiplexer;
|
||||
CEventQueue eventQueue;
|
||||
|
||||
// get program name
|
||||
CArgs args;
|
||||
ARG->m_pname = ARCH->getBasename(argv[0]);
|
||||
|
||||
// make the task bar receiver. the user can control this app
|
||||
// through the task bar.
|
||||
s_taskBarReceiver = new CXWindowsServerTaskBarReceiver;
|
||||
|
||||
// parse command line
|
||||
parse(argc, argv);
|
||||
|
||||
// load configuration
|
||||
loadConfig();
|
||||
|
||||
// daemonize if requested
|
||||
int result;
|
||||
if (ARG->m_daemon) {
|
||||
try {
|
||||
result = ARCH->daemonize(DAEMON_NAME, &daemonStartup);
|
||||
}
|
||||
catch (XArchDaemon&) {
|
||||
LOG((CLOG_CRIT "failed to daemonize"));
|
||||
result = kExitFailed;
|
||||
}
|
||||
try {
|
||||
int result;
|
||||
CArch arch;
|
||||
CLOG;
|
||||
CArgs args;
|
||||
result = run(argc, argv, NULL, &standardStartup);
|
||||
delete CLOG;
|
||||
return result;
|
||||
}
|
||||
else {
|
||||
result = realMain();
|
||||
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;
|
||||
}
|
||||
|
||||
// done with task bar receiver
|
||||
delete s_taskBarReceiver;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
@@ -102,6 +102,8 @@ END
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user