Fixed win32 config saving, keyboard mapping, and AltGr bugs.
Made extensive changes to the launcher to provide more control over setting up auto-start and it now saves configuration to the user's documents directory if auto-starting at login and saves to the system directory if auto-starting at boot. Replaced MapVirtualKey() with table lookup to work around that function's lack of support for extended keyboard scan codes. Added first cut at support for AltGr.
This commit is contained in:
parent
c95e991aeb
commit
a729e33cfb
10
BUGS
10
BUGS
|
@ -1,7 +1,8 @@
|
||||||
Known Bugs in Synergy
|
Known Bugs in Synergy
|
||||||
=====================
|
=====================
|
||||||
|
|
||||||
Report bugs to: synergy@groundhog.pair.com
|
Report bugs at:
|
||||||
|
http://sourceforge.net/tracker/?func=browse&group_id=59275&atid=490467
|
||||||
|
|
||||||
When reporting bugs, please include the version of the operating
|
When reporting bugs, please include the version of the operating
|
||||||
system you're using and what locale you use.
|
system you're using and what locale you use.
|
||||||
|
@ -77,10 +78,9 @@ system you're using and what locale you use.
|
||||||
when toggled on and KeyRelease when toggled off (instead of KeyPress
|
when toggled on and KeyRelease when toggled off (instead of KeyPress
|
||||||
and KeyRelease for each physical press and release).
|
and KeyRelease for each physical press and release).
|
||||||
|
|
||||||
* Not handling mode-switch and shift-lock (X11)
|
* Not handling shift-lock (X11)
|
||||||
|
|
||||||
Synergy neither handles the mode-switch key nor shift-lock behavior
|
Synergy doesn't handle shift-lock behavior (as opposed to caps-lock).
|
||||||
(as opposed to caps-lock).
|
|
||||||
|
|
||||||
* Large Motif clipboard items are truncated (X11)
|
* Large Motif clipboard items are truncated (X11)
|
||||||
|
|
||||||
|
@ -94,4 +94,4 @@ system you're using and what locale you use.
|
||||||
* Automake isn't fully configured (Linux)
|
* Automake isn't fully configured (Linux)
|
||||||
|
|
||||||
The automake configuration isn't complete so synergy won't build
|
The automake configuration isn't complete so synergy won't build
|
||||||
properly on some (many) systems.
|
or fail to build properly on some (many) systems.
|
||||||
|
|
48
INSTALL
48
INSTALL
|
@ -96,9 +96,9 @@ First configure the server. Click the `Server' radio button
|
||||||
* Click `Test'
|
* Click `Test'
|
||||||
|
|
||||||
The server will start and you'll see a console window with log messages
|
The server will start and you'll see a console window with log messages
|
||||||
telling you about synergy's progress. If an error occurs you'll get a
|
telling you about synergy's progress. If an error occurs you'll get one
|
||||||
dialog box telling you synergy is about to quit; read the log messages
|
or more dialog boxes telling you what the errors are; read the errors
|
||||||
to determine the problem then correct it and try `Test' again.
|
to determine the problem then correct them and try `Test' again.
|
||||||
|
|
||||||
Now that the server is running, you'll need to start a client. On any
|
Now that the server is running, you'll need to start a client. On any
|
||||||
client computer, double click `synergy'. Of course, you'll need to
|
client computer, double click `synergy'. Of course, you'll need to
|
||||||
|
@ -115,9 +115,9 @@ client computer. Then configure the client:
|
||||||
* Click `Test'
|
* Click `Test'
|
||||||
|
|
||||||
If all goes well, the client connects to the server successfully and
|
If all goes well, the client connects to the server successfully and
|
||||||
the mouse and keyboard are shared. If an error occurs you'll get a
|
the mouse and keyboard are shared. If an error occurs you'll get one
|
||||||
dialog box telling you synergy is about to quit; read the log messages
|
or more dialog boxes telling you what the errors are; read the errors
|
||||||
to determine the problem then correct it and try `Test' again. When
|
to determine the problem then correct them and try `Test' again. When
|
||||||
everything is working correctly, install the software on the other
|
everything is working correctly, install the software on the other
|
||||||
client computers (if any) and repeat the steps for configuring the
|
client computers (if any) and repeat the steps for configuring the
|
||||||
client on each.
|
client on each.
|
||||||
|
@ -289,17 +289,31 @@ Starting Automatically on Windows
|
||||||
|
|
||||||
When all the clients work you're ready to have synergy start
|
When all the clients work you're ready to have synergy start
|
||||||
automatically each time the system (re)starts. Click `Stop' on all
|
automatically each time the system (re)starts. Click `Stop' on all
|
||||||
the clients then on the server'. Then Click `Start' on the server.
|
the clients then on the server'. Now click the `Configure' button by
|
||||||
If it starts successfully then click `OK' to close the message box
|
the text `Automatic Startup'. The `Auto Start' dialog will pop up.
|
||||||
and the dialog. The synergy server is now running and will be
|
If an error occurs then correct the problem and click `Configure'
|
||||||
automatically started each time the system is started. Click `Start'
|
again.
|
||||||
then `OK' on each of the clients to start the synergy client and
|
|
||||||
automatically have it start each time the computer starts.
|
|
||||||
|
|
||||||
If you ever want to prevent synergy from starting automatically when
|
On the `Auto Start' dialog you'll configure synergy to start
|
||||||
the computer does, double click `synergy', choose `Client' or `Server'
|
automatically when the computer starts or when you log in. You can
|
||||||
(whichever the computer is running as), then click `No Auto-Start'.
|
also configure synergy to not start automatically. You can only
|
||||||
Click `OK' to dismiss the message box then `Quit' to close the dialog.
|
start synergy automatically when the computer starts if you have
|
||||||
|
sufficient access rights. The dialog will let you know if you have
|
||||||
|
sufficient permission.
|
||||||
|
|
||||||
|
If synergy is already configured to automatically start then there
|
||||||
|
will be two `Uninstall' buttons, at most one of which is enabled.
|
||||||
|
Click the enabled button, if any, to configure synergy to not start
|
||||||
|
automatically.
|
||||||
|
|
||||||
|
If synergy is not configured to start automatically then there will
|
||||||
|
be two `Install' buttons. If you have sufficient permission to
|
||||||
|
have synergy start automatically when the computer does then the
|
||||||
|
`Install' button in the `When Computer Starts' box will be enabled.
|
||||||
|
Click it to have synergy start for all users when the computer starts.
|
||||||
|
In this case, synergy will be available during the login screen.
|
||||||
|
Otherwise, click the `Install' button in the `When You Log In' box
|
||||||
|
to have synergy automatically start when you log in.
|
||||||
|
|
||||||
|
|
||||||
Starting Automatically on Linux
|
Starting Automatically on Linux
|
||||||
|
@ -353,8 +367,6 @@ Common Command Line Options
|
||||||
-1, --no-restart do not restart on failure
|
-1, --no-restart do not restart on failure
|
||||||
-h, --help print help and exit
|
-h, --help print help and exit
|
||||||
--version print version information and exit
|
--version print version information and exit
|
||||||
--install install as a service (Windows only)
|
|
||||||
--uninstall uninstall service (Windows only)
|
|
||||||
|
|
||||||
Debug levels are from highest to lowest: FATAL, ERROR, WARNING, NOTE,
|
Debug levels are from highest to lowest: FATAL, ERROR, WARNING, NOTE,
|
||||||
INFO, DEBUG, DEBUG1, and DEBUG2. Only messages at or above the given
|
INFO, DEBUG, DEBUG1, and DEBUG2. Only messages at or above the given
|
||||||
|
|
|
@ -0,0 +1,262 @@
|
||||||
|
/*
|
||||||
|
* 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 "CPlatform.h"
|
||||||
|
#include "CLog.h"
|
||||||
|
#include "CAutoStart.h"
|
||||||
|
#include "LaunchUtil.h"
|
||||||
|
#include "resource.h"
|
||||||
|
|
||||||
|
#define CLIENT_DAEMON_NAME "Synergy Client"
|
||||||
|
#define SERVER_DAEMON_NAME "Synergy Server"
|
||||||
|
#define CLIENT_DAEMON_INFO "Shares this system's mouse and keyboard with others."
|
||||||
|
#define SERVER_DAEMON_INFO "Shares this system's mouse and keyboard with others."
|
||||||
|
|
||||||
|
//
|
||||||
|
// CAutoStart
|
||||||
|
//
|
||||||
|
|
||||||
|
CAutoStart* CAutoStart::s_singleton = NULL;
|
||||||
|
|
||||||
|
CAutoStart::CAutoStart(HWND parent, CConfig* config, const CString& cmdLine) :
|
||||||
|
m_parent(parent),
|
||||||
|
m_config(config),
|
||||||
|
m_isServer(config != NULL),
|
||||||
|
m_cmdLine(cmdLine),
|
||||||
|
m_name((config != NULL) ? SERVER_DAEMON_NAME : CLIENT_DAEMON_NAME),
|
||||||
|
m_userConfigSaved(false)
|
||||||
|
|
||||||
|
{
|
||||||
|
assert(s_singleton == NULL);
|
||||||
|
s_singleton = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
CAutoStart::~CAutoStart()
|
||||||
|
{
|
||||||
|
s_singleton = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CAutoStart::doModal()
|
||||||
|
{
|
||||||
|
// install our log outputter
|
||||||
|
CLog::Outputter oldOutputter = CLog::getOutputter();
|
||||||
|
CLog::setOutputter(&CAutoStart::onLog);
|
||||||
|
|
||||||
|
// reset saved flag
|
||||||
|
m_userConfigSaved = false;
|
||||||
|
|
||||||
|
// do dialog
|
||||||
|
DialogBoxParam(s_instance, MAKEINTRESOURCE(IDD_AUTOSTART),
|
||||||
|
m_parent, dlgProc, (LPARAM)this);
|
||||||
|
|
||||||
|
// restore log outputter
|
||||||
|
CLog::setOutputter(oldOutputter);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
CAutoStart::wasUserConfigSaved() const
|
||||||
|
{
|
||||||
|
return m_userConfigSaved;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
CAutoStart::update()
|
||||||
|
{
|
||||||
|
// need a platform object
|
||||||
|
CPlatform platform;
|
||||||
|
|
||||||
|
// get installation state
|
||||||
|
const bool installedSystem = platform.isDaemonInstalled(
|
||||||
|
m_name.c_str(), true);
|
||||||
|
const bool installedUser = platform.isDaemonInstalled(
|
||||||
|
m_name.c_str(), false);
|
||||||
|
|
||||||
|
// get user's permissions
|
||||||
|
const bool canInstallSystem = platform.canInstallDaemon(
|
||||||
|
m_name.c_str(), true);
|
||||||
|
const bool canInstallUser = platform.canInstallDaemon(
|
||||||
|
m_name.c_str(), false);
|
||||||
|
|
||||||
|
// update messages
|
||||||
|
CString msg, label;
|
||||||
|
if (canInstallSystem) {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
// try saving configuration. if we can't then don't try
|
||||||
|
// installing the daemon.
|
||||||
|
if (m_config != NULL) {
|
||||||
|
if (!saveConfig(*m_config, allUsers)) {
|
||||||
|
showError(m_hwnd, CStringUtil::format(
|
||||||
|
getString(IDS_SAVE_FAILED).c_str(),
|
||||||
|
getErrorString(GetLastError()).c_str()));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// note if we've saved the user's configuration
|
||||||
|
if (!allUsers) {
|
||||||
|
m_userConfigSaved = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// get the app path
|
||||||
|
CString appPath = getAppPath(m_isServer ? SERVER_APP : CLIENT_APP);
|
||||||
|
|
||||||
|
// clear error message
|
||||||
|
m_errorMessage = "";
|
||||||
|
|
||||||
|
// install
|
||||||
|
CPlatform platform;
|
||||||
|
if (!platform.installDaemon(m_name.c_str(),
|
||||||
|
m_isServer ? SERVER_DAEMON_INFO : CLIENT_DAEMON_INFO,
|
||||||
|
appPath.c_str(), m_cmdLine.c_str(), allUsers)) {
|
||||||
|
if (m_errorMessage.empty()) {
|
||||||
|
m_errorMessage = getString(IDS_INSTALL_GENERIC_ERROR);
|
||||||
|
}
|
||||||
|
showError(m_hwnd, m_errorMessage);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
askOkay(m_hwnd, getString(IDS_INSTALL_TITLE),
|
||||||
|
getString(allUsers ?
|
||||||
|
IDS_INSTALLED_SYSTEM :
|
||||||
|
IDS_INSTALLED_USER));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
CAutoStart::onUninstall(bool allUsers)
|
||||||
|
{
|
||||||
|
// clear error message
|
||||||
|
m_errorMessage = "";
|
||||||
|
|
||||||
|
// uninstall
|
||||||
|
CPlatform platform;
|
||||||
|
if (platform.uninstallDaemon(m_name.c_str(), allUsers) !=
|
||||||
|
IPlatform::kSuccess) {
|
||||||
|
if (m_errorMessage.empty()) {
|
||||||
|
m_errorMessage = getString(IDS_UNINSTALL_GENERIC_ERROR);
|
||||||
|
}
|
||||||
|
showError(m_hwnd, m_errorMessage);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
askOkay(m_hwnd, getString(IDS_UNINSTALL_TITLE),
|
||||||
|
getString(allUsers ?
|
||||||
|
IDS_UNINSTALLED_SYSTEM :
|
||||||
|
IDS_UNINSTALLED_USER));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
CAutoStart::onLog(int priority, const char* message)
|
||||||
|
{
|
||||||
|
if (priority <= CLog::kERROR) {
|
||||||
|
s_singleton->m_errorMessage = message;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
|
@ -0,0 +1,81 @@
|
||||||
|
/*
|
||||||
|
* 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>
|
||||||
|
|
||||||
|
class CConfig;
|
||||||
|
|
||||||
|
//! Auto start dialog for Microsoft Windows launcher
|
||||||
|
class CAutoStart {
|
||||||
|
public:
|
||||||
|
// if config == NULL then it's assumed we're installing/uninstalling
|
||||||
|
// the client, otherwise the server.
|
||||||
|
CAutoStart(HWND parent, CConfig* config, const CString& cmdLine);
|
||||||
|
~CAutoStart();
|
||||||
|
|
||||||
|
//! @name manipulators
|
||||||
|
//@{
|
||||||
|
|
||||||
|
//! Run dialog
|
||||||
|
/*!
|
||||||
|
Display and handle the dialog until closed by the user.
|
||||||
|
*/
|
||||||
|
void doModal();
|
||||||
|
|
||||||
|
//@}
|
||||||
|
//! @name accessors
|
||||||
|
//@{
|
||||||
|
|
||||||
|
//! Test if user configuration was saved
|
||||||
|
/*!
|
||||||
|
Returns true if the user's configuration (as opposed to the system-wide
|
||||||
|
configuration) was saved successfully while in doModal().
|
||||||
|
*/
|
||||||
|
bool wasUserConfigSaved() const;
|
||||||
|
|
||||||
|
//@}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void update();
|
||||||
|
bool onInstall(bool allUsers);
|
||||||
|
bool onUninstall(bool allUsers);
|
||||||
|
|
||||||
|
// log handling
|
||||||
|
static bool onLog(int priority, const char* message);
|
||||||
|
|
||||||
|
// message handling
|
||||||
|
BOOL doDlgProc(HWND, UINT, WPARAM, LPARAM);
|
||||||
|
static BOOL CALLBACK dlgProc(HWND, UINT, WPARAM, LPARAM);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static CAutoStart* s_singleton;
|
||||||
|
|
||||||
|
HWND m_parent;
|
||||||
|
CConfig* m_config;
|
||||||
|
bool m_isServer;
|
||||||
|
CString m_cmdLine;
|
||||||
|
CString m_name;
|
||||||
|
HWND m_hwnd;
|
||||||
|
bool m_install;
|
||||||
|
CString m_errorMessage;
|
||||||
|
bool m_userConfigSaved;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,211 @@
|
||||||
|
/*
|
||||||
|
* 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 "CPlatform.h"
|
||||||
|
#include "LaunchUtil.h"
|
||||||
|
#include "resource.h"
|
||||||
|
#include "stdfstream.h"
|
||||||
|
|
||||||
|
#define CONFIG_NAME "synergy.sgc"
|
||||||
|
|
||||||
|
CString
|
||||||
|
getString(DWORD id)
|
||||||
|
{
|
||||||
|
char buffer[1024];
|
||||||
|
buffer[0] = '\0';
|
||||||
|
LoadString(s_instance, id, buffer, sizeof(buffer) / sizeof(buffer[0]));
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
showError(HWND hwnd, const CString& msg)
|
||||||
|
{
|
||||||
|
CString title = getString(IDS_ERROR);
|
||||||
|
MessageBox(hwnd, msg.c_str(), title.c_str(), MB_OK | MB_APPLMODAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
askOkay(HWND hwnd, const CString& title, const CString& msg)
|
||||||
|
{
|
||||||
|
MessageBox(hwnd, msg.c_str(), title.c_str(), MB_OK | MB_APPLMODAL);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
askVerify(HWND hwnd, const CString& msg)
|
||||||
|
{
|
||||||
|
CString title = getString(IDS_VERIFY);
|
||||||
|
int result = MessageBox(hwnd, msg.c_str(),
|
||||||
|
title.c_str(), MB_OKCANCEL | MB_APPLMODAL);
|
||||||
|
return (result == IDOK);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
CString
|
||||||
|
getAppPath(const CString& appName)
|
||||||
|
{
|
||||||
|
// prepare path to app
|
||||||
|
CPlatform platform;
|
||||||
|
char myPathname[MAX_PATH];
|
||||||
|
GetModuleFileName(s_instance, myPathname, MAX_PATH);
|
||||||
|
const char* myBasename = platform.getBasename(myPathname);
|
||||||
|
CString appPath = CString(myPathname, myBasename - myPathname);
|
||||||
|
appPath += appName;
|
||||||
|
return appPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
CPlatform platform;
|
||||||
|
|
||||||
|
// load configuration
|
||||||
|
bool configLoaded = false;
|
||||||
|
CString path = platform.getUserDirectory();
|
||||||
|
if (!path.empty()) {
|
||||||
|
CPlatform platform;
|
||||||
|
|
||||||
|
// try loading the user's configuration
|
||||||
|
path = platform.addPathComponent(path, CONFIG_NAME);
|
||||||
|
if (loadConfig(path, config)) {
|
||||||
|
configLoaded = true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// try the system-wide config file
|
||||||
|
path = platform.getSystemDirectory();
|
||||||
|
if (!path.empty()) {
|
||||||
|
path = platform.addPathComponent(path, CONFIG_NAME);
|
||||||
|
if (loadConfig(path, config)) {
|
||||||
|
configLoaded = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
CPlatform platform;
|
||||||
|
|
||||||
|
// try saving the user's configuration
|
||||||
|
if (!sysOnly) {
|
||||||
|
CString path = platform.getUserDirectory();
|
||||||
|
if (!path.empty()) {
|
||||||
|
path = platform.addPathComponent(path, CONFIG_NAME);
|
||||||
|
if (saveConfig(path, config)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// try the system-wide config file
|
||||||
|
else {
|
||||||
|
CString path = platform.getSystemDirectory();
|
||||||
|
if (!path.empty()) {
|
||||||
|
path = platform.addPathComponent(path, CONFIG_NAME);
|
||||||
|
if (saveConfig(path, config)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
/*
|
||||||
|
* 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>
|
||||||
|
|
||||||
|
#define CLIENT_APP "synergyc.exe"
|
||||||
|
#define SERVER_APP "synergys.exe"
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
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);
|
||||||
|
|
||||||
|
CString getAppPath(const CString& appName);
|
||||||
|
|
||||||
|
bool loadConfig(CConfig& config);
|
||||||
|
bool saveConfig(const CConfig& config, bool sysOnly);
|
||||||
|
|
||||||
|
#endif
|
|
@ -17,12 +17,12 @@
|
||||||
#include "CPlatform.h"
|
#include "CPlatform.h"
|
||||||
#include "CNetwork.h"
|
#include "CNetwork.h"
|
||||||
#include "Version.h"
|
#include "Version.h"
|
||||||
#include "stdfstream.h"
|
|
||||||
#include "stdvector.h"
|
#include "stdvector.h"
|
||||||
#include "resource.h"
|
#include "resource.h"
|
||||||
|
|
||||||
#define WINDOWS_LEAN_AND_MEAN
|
// these must come after the above because it includes windows.h
|
||||||
#include <windows.h>
|
#include "LaunchUtil.h"
|
||||||
|
#include "CAutoStart.h"
|
||||||
|
|
||||||
#define CONFIG_NAME "synergy.sgc"
|
#define CONFIG_NAME "synergy.sgc"
|
||||||
#define CLIENT_APP "synergyc.exe"
|
#define CLIENT_APP "synergyc.exe"
|
||||||
|
@ -45,9 +45,10 @@ public:
|
||||||
HANDLE m_stop;
|
HANDLE m_stop;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
HINSTANCE s_instance = NULL;
|
||||||
|
|
||||||
static const TCHAR* s_mainClass = TEXT("GoSynergy");
|
static const TCHAR* s_mainClass = TEXT("GoSynergy");
|
||||||
static const TCHAR* s_layoutClass = TEXT("SynergyLayout");
|
static const TCHAR* s_layoutClass = TEXT("SynergyLayout");
|
||||||
static HINSTANCE s_instance = NULL;
|
|
||||||
|
|
||||||
static HWND s_mainWindow;
|
static HWND s_mainWindow;
|
||||||
static CConfig s_config;
|
static CConfig s_config;
|
||||||
|
@ -92,84 +93,6 @@ isNameInList(const CStringList& names, const CString& name)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
|
||||||
CString
|
|
||||||
getString(DWORD id)
|
|
||||||
{
|
|
||||||
char buffer[1024];
|
|
||||||
buffer[0] = '\0';
|
|
||||||
LoadString(s_instance, id, buffer, sizeof(buffer) / sizeof(buffer[0]));
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
static
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static
|
|
||||||
void
|
|
||||||
showError(HWND hwnd, const CString& msg)
|
|
||||||
{
|
|
||||||
CString title = getString(IDS_ERROR);
|
|
||||||
MessageBox(hwnd, msg.c_str(), title.c_str(), MB_OK | MB_APPLMODAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static
|
|
||||||
void
|
|
||||||
askOkay(HWND hwnd, const CString& title, const CString& msg)
|
|
||||||
{
|
|
||||||
MessageBox(hwnd, msg.c_str(), title.c_str(), MB_OK | MB_APPLMODAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
static
|
|
||||||
bool
|
|
||||||
askVerify(HWND hwnd, const CString& msg)
|
|
||||||
{
|
|
||||||
CString title = getString(IDS_VERIFY);
|
|
||||||
int result = MessageBox(hwnd, msg.c_str(),
|
|
||||||
title.c_str(), MB_OKCANCEL | MB_APPLMODAL);
|
|
||||||
return (result == IDOK);
|
|
||||||
}
|
|
||||||
|
|
||||||
static
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
static
|
|
||||||
void
|
|
||||||
enableItem(HWND hwnd, int id, bool enabled)
|
|
||||||
{
|
|
||||||
EnableWindow(GetDlgItem(hwnd, id), enabled);
|
|
||||||
}
|
|
||||||
|
|
||||||
static
|
static
|
||||||
bool
|
bool
|
||||||
isClientChecked(HWND hwnd)
|
isClientChecked(HWND hwnd)
|
||||||
|
@ -178,6 +101,13 @@ isClientChecked(HWND hwnd)
|
||||||
return (SendMessage(child, BM_GETCHECK, 0, 0) == BST_CHECKED);
|
return (SendMessage(child, BM_GETCHECK, 0, 0) == BST_CHECKED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static
|
||||||
|
void
|
||||||
|
enableSaveControls(HWND hwnd)
|
||||||
|
{
|
||||||
|
enableItem(hwnd, IDC_MAIN_SAVE, s_config != s_oldConfig);
|
||||||
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
void
|
void
|
||||||
enableScreensControls(HWND hwnd)
|
enableScreensControls(HWND hwnd)
|
||||||
|
@ -217,6 +147,7 @@ enableMainWindowControls(HWND hwnd)
|
||||||
enableItem(hwnd, IDC_MAIN_CLIENT_SERVER_NAME_LABEL, client);
|
enableItem(hwnd, IDC_MAIN_CLIENT_SERVER_NAME_LABEL, client);
|
||||||
enableItem(hwnd, IDC_MAIN_CLIENT_SERVER_NAME_EDIT, client);
|
enableItem(hwnd, IDC_MAIN_CLIENT_SERVER_NAME_EDIT, client);
|
||||||
enableScreensControls(hwnd);
|
enableScreensControls(hwnd);
|
||||||
|
enableSaveControls(hwnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
|
@ -310,6 +241,7 @@ addScreen(HWND hwnd)
|
||||||
// update neighbors
|
// update neighbors
|
||||||
updateNeighbors(hwnd);
|
updateNeighbors(hwnd);
|
||||||
enableScreensControls(hwnd);
|
enableScreensControls(hwnd);
|
||||||
|
enableSaveControls(hwnd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -370,6 +302,7 @@ editScreen(HWND hwnd)
|
||||||
|
|
||||||
// update neighbors
|
// update neighbors
|
||||||
updateNeighbors(hwnd);
|
updateNeighbors(hwnd);
|
||||||
|
enableSaveControls(hwnd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -400,6 +333,7 @@ removeScreen(HWND hwnd)
|
||||||
// update neighbors
|
// update neighbors
|
||||||
updateNeighbors(hwnd);
|
updateNeighbors(hwnd);
|
||||||
enableScreensControls(hwnd);
|
enableScreensControls(hwnd);
|
||||||
|
enableSaveControls(hwnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
|
@ -431,6 +365,8 @@ changeNeighbor(HWND hwnd, HWND combo, EDirection direction)
|
||||||
s_config.connect(screen, direction, CString(neighbor));
|
s_config.connect(screen, direction, CString(neighbor));
|
||||||
delete[] neighbor;
|
delete[] neighbor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enableSaveControls(hwnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
|
@ -459,16 +395,16 @@ execApp(const char* app, const CString& cmdLine, PROCESS_INFORMATION* procInfo)
|
||||||
startup.hStdError = NULL;
|
startup.hStdError = NULL;
|
||||||
|
|
||||||
// prepare path to app
|
// prepare path to app
|
||||||
CPlatform platform;
|
CString appPath = getAppPath(app);
|
||||||
char myPathname[MAX_PATH];
|
|
||||||
GetModuleFileName(s_instance, myPathname, MAX_PATH);
|
// put path to app in command line
|
||||||
const char* myBasename = platform.getBasename(myPathname);
|
CString commandLine = "\"";
|
||||||
CString appPath = CString(myPathname, myBasename - myPathname);
|
commandLine += appPath;
|
||||||
appPath += app;
|
commandLine += "\" ";
|
||||||
|
commandLine += cmdLine;
|
||||||
|
|
||||||
// start child
|
// start child
|
||||||
if (CreateProcess(appPath.c_str(),
|
if (CreateProcess(NULL, (char*)commandLine.c_str(),
|
||||||
(char*)cmdLine.c_str(),
|
|
||||||
NULL,
|
NULL,
|
||||||
NULL,
|
NULL,
|
||||||
FALSE,
|
FALSE,
|
||||||
|
@ -487,30 +423,11 @@ execApp(const char* app, const CString& cmdLine, PROCESS_INFORMATION* procInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
bool
|
CString
|
||||||
uninstallApp(const char* app)
|
getCommandLine(HWND hwnd, bool testing)
|
||||||
{
|
|
||||||
PROCESS_INFORMATION procInfo;
|
|
||||||
|
|
||||||
// uninstall
|
|
||||||
DWORD exitCode = kExitFailed;
|
|
||||||
if (execApp(app, "-z --uninstall", &procInfo)) {
|
|
||||||
WaitForSingleObject(procInfo.hProcess, INFINITE);
|
|
||||||
GetExitCodeProcess(procInfo.hProcess, &exitCode);
|
|
||||||
CloseHandle(procInfo.hProcess);
|
|
||||||
CloseHandle(procInfo.hThread);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (exitCode == kExitSuccess);
|
|
||||||
}
|
|
||||||
|
|
||||||
static
|
|
||||||
HANDLE
|
|
||||||
launchApp(HWND hwnd, bool testing, DWORD* threadID)
|
|
||||||
{
|
{
|
||||||
// decide if client or server
|
// decide if client or server
|
||||||
const bool isClient = isClientChecked(hwnd);
|
const bool isClient = isClientChecked(hwnd);
|
||||||
const char* app = isClient ? CLIENT_APP : SERVER_APP;
|
|
||||||
|
|
||||||
// get and verify screen name
|
// get and verify screen name
|
||||||
HWND child = GetDlgItem(hwnd, IDC_MAIN_ADVANCED_NAME_EDIT);
|
HWND child = GetDlgItem(hwnd, IDC_MAIN_ADVANCED_NAME_EDIT);
|
||||||
|
@ -520,14 +437,14 @@ launchApp(HWND hwnd, bool testing, DWORD* threadID)
|
||||||
getString(IDS_INVALID_SCREEN_NAME).c_str(),
|
getString(IDS_INVALID_SCREEN_NAME).c_str(),
|
||||||
name.c_str()));
|
name.c_str()));
|
||||||
SetFocus(child);
|
SetFocus(child);
|
||||||
return NULL;
|
return CString();
|
||||||
}
|
}
|
||||||
if (!isClient && !s_config.isScreen(name)) {
|
if (!isClient && !s_config.isScreen(name)) {
|
||||||
showError(hwnd, CStringUtil::format(
|
showError(hwnd, CStringUtil::format(
|
||||||
getString(IDS_UNKNOWN_SCREEN_NAME).c_str(),
|
getString(IDS_UNKNOWN_SCREEN_NAME).c_str(),
|
||||||
name.c_str()));
|
name.c_str()));
|
||||||
SetFocus(child);
|
SetFocus(child);
|
||||||
return NULL;
|
return CString();
|
||||||
}
|
}
|
||||||
|
|
||||||
// get and verify port
|
// get and verify port
|
||||||
|
@ -541,7 +458,7 @@ launchApp(HWND hwnd, bool testing, DWORD* threadID)
|
||||||
portString.c_str(),
|
portString.c_str(),
|
||||||
defaultPortString.c_str()));
|
defaultPortString.c_str()));
|
||||||
SetFocus(child);
|
SetFocus(child);
|
||||||
return NULL;
|
return CString();
|
||||||
}
|
}
|
||||||
|
|
||||||
// prepare command line
|
// prepare command line
|
||||||
|
@ -557,10 +474,10 @@ launchApp(HWND hwnd, bool testing, DWORD* threadID)
|
||||||
CString server = getWindowText(child);
|
CString server = getWindowText(child);
|
||||||
if (!s_config.isValidScreenName(server)) {
|
if (!s_config.isValidScreenName(server)) {
|
||||||
showError(hwnd, CStringUtil::format(
|
showError(hwnd, CStringUtil::format(
|
||||||
getString(IDS_INVALID_SCREEN_NAME).c_str(),
|
getString(IDS_INVALID_SERVER_NAME).c_str(),
|
||||||
server.c_str()));
|
server.c_str()));
|
||||||
SetFocus(child);
|
SetFocus(child);
|
||||||
return NULL;
|
return CString();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (testing) {
|
if (testing) {
|
||||||
|
@ -576,27 +493,21 @@ launchApp(HWND hwnd, bool testing, DWORD* threadID)
|
||||||
cmdLine += portString;
|
cmdLine += portString;
|
||||||
}
|
}
|
||||||
|
|
||||||
// uninstall client and server then reinstall one of them
|
return cmdLine;
|
||||||
if (!testing) {
|
}
|
||||||
// uninstall client and server
|
|
||||||
uninstallApp(CLIENT_APP);
|
|
||||||
uninstallApp(SERVER_APP);
|
|
||||||
|
|
||||||
// install client or server
|
static
|
||||||
PROCESS_INFORMATION procInfo;
|
HANDLE
|
||||||
DWORD exitCode = kExitFailed;
|
launchApp(HWND hwnd, bool testing, DWORD* threadID)
|
||||||
if (execApp(app, CString("-z --install") + cmdLine, &procInfo)) {
|
{
|
||||||
WaitForSingleObject(procInfo.hProcess, INFINITE);
|
// decide if client or server
|
||||||
GetExitCodeProcess(procInfo.hProcess, &exitCode);
|
const bool isClient = isClientChecked(hwnd);
|
||||||
CloseHandle(procInfo.hProcess);
|
const char* app = isClient ? CLIENT_APP : SERVER_APP;
|
||||||
CloseHandle(procInfo.hThread);
|
|
||||||
}
|
|
||||||
|
|
||||||
// see if install succeeded
|
// prepare command line
|
||||||
if (exitCode != kExitSuccess) {
|
CString cmdLine = getCommandLine(hwnd, testing);
|
||||||
showError(hwnd, getString(IDS_INSTALL_FAILED).c_str());
|
if (cmdLine.empty()) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// start child
|
// start child
|
||||||
|
@ -716,67 +627,6 @@ waitForChild(HWND hwnd, HANDLE thread, DWORD threadID)
|
||||||
CloseHandle(info.m_stop);
|
CloseHandle(info.m_stop);
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
static
|
|
||||||
bool
|
|
||||||
saveConfig(const CConfig& config)
|
|
||||||
{
|
|
||||||
CPlatform platform;
|
|
||||||
|
|
||||||
CString path = platform.getUserDirectory();
|
|
||||||
if (!path.empty()) {
|
|
||||||
// try loading the user's configuration
|
|
||||||
path = platform.addPathComponent(path, CONFIG_NAME);
|
|
||||||
if (saveConfig(path, config)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// try the system-wide config file
|
|
||||||
path = platform.getSystemDirectory();
|
|
||||||
if (!path.empty()) {
|
|
||||||
path = platform.addPathComponent(path, CONFIG_NAME);
|
|
||||||
if (saveConfig(path, config)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static
|
static
|
||||||
void
|
void
|
||||||
initMainWindow(HWND hwnd)
|
initMainWindow(HWND hwnd)
|
||||||
|
@ -784,26 +634,9 @@ initMainWindow(HWND hwnd)
|
||||||
CPlatform platform;
|
CPlatform platform;
|
||||||
|
|
||||||
// load configuration
|
// load configuration
|
||||||
bool configLoaded = false;
|
bool configLoaded = loadConfig(s_config);
|
||||||
CString path = platform.getUserDirectory();
|
|
||||||
if (!path.empty()) {
|
|
||||||
// try loading the user's configuration
|
|
||||||
path = platform.addPathComponent(path, CONFIG_NAME);
|
|
||||||
if (loadConfig(path, s_config)) {
|
|
||||||
configLoaded = true;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// try the system-wide config file
|
|
||||||
path = platform.getSystemDirectory();
|
|
||||||
if (!path.empty()) {
|
|
||||||
path = platform.addPathComponent(path, CONFIG_NAME);
|
|
||||||
if (loadConfig(path, s_config)) {
|
|
||||||
configLoaded = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
s_oldConfig = s_config;
|
s_oldConfig = s_config;
|
||||||
|
enableSaveControls(hwnd);
|
||||||
|
|
||||||
// choose client/server radio buttons
|
// choose client/server radio buttons
|
||||||
HWND child;
|
HWND child;
|
||||||
|
@ -978,82 +811,81 @@ mainWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||||
PostQuitMessage(0);
|
PostQuitMessage(0);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case IDOK: {
|
case IDOK:
|
||||||
// save data
|
|
||||||
if (s_config != s_oldConfig) {
|
|
||||||
if (!saveConfig(s_config)) {
|
|
||||||
showError(hwnd, CStringUtil::format(
|
|
||||||
getString(IDS_SAVE_FAILED).c_str(),
|
|
||||||
getErrorString(GetLastError()).c_str()));
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
s_oldConfig = s_config;
|
|
||||||
}
|
|
||||||
|
|
||||||
// launch child app
|
|
||||||
HANDLE thread = launchApp(hwnd, false, NULL);
|
|
||||||
if (thread == NULL) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
CloseHandle(thread);
|
|
||||||
|
|
||||||
// notify of success
|
|
||||||
askOkay(hwnd, getString(IDS_STARTED_TITLE),
|
|
||||||
getString(IDS_STARTED));
|
|
||||||
|
|
||||||
// quit
|
|
||||||
PostQuitMessage(0);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
case IDC_MAIN_TEST: {
|
case IDC_MAIN_TEST: {
|
||||||
|
// note if testing
|
||||||
|
const bool testing = (LOWORD(wParam) == IDC_MAIN_TEST);
|
||||||
|
|
||||||
// save data
|
// save data
|
||||||
if (s_config != s_oldConfig) {
|
if (s_config != s_oldConfig) {
|
||||||
if (!saveConfig(s_config)) {
|
if (!saveConfig(s_config, false)) {
|
||||||
showError(hwnd, CStringUtil::format(
|
showError(hwnd, CStringUtil::format(
|
||||||
getString(IDS_SAVE_FAILED).c_str(),
|
getString(IDS_SAVE_FAILED).c_str(),
|
||||||
getErrorString(GetLastError()).c_str()));
|
getErrorString(GetLastError()).c_str()));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
s_oldConfig = s_config;
|
s_oldConfig = s_config;
|
||||||
|
enableSaveControls(hwnd);
|
||||||
}
|
}
|
||||||
|
|
||||||
// launch child app
|
// launch child app
|
||||||
DWORD threadID;
|
DWORD threadID;
|
||||||
HANDLE thread = launchApp(hwnd, true, &threadID);
|
HANDLE thread = launchApp(hwnd, testing, &threadID);
|
||||||
if (thread == NULL) {
|
if (thread == NULL) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// wait for process to stop, allowing the user to kill it
|
// handle child program
|
||||||
waitForChild(hwnd, thread, threadID);
|
if (testing) {
|
||||||
|
// wait for process to stop, allowing the user to kill it
|
||||||
|
waitForChild(hwnd, thread, threadID);
|
||||||
|
|
||||||
// clean up
|
// clean up
|
||||||
CloseHandle(thread);
|
CloseHandle(thread);
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
case IDC_MAIN_UNINSTALL: {
|
|
||||||
// uninstall client and server
|
|
||||||
bool removedClient = uninstallApp(CLIENT_APP);
|
|
||||||
bool removedServer = uninstallApp(SERVER_APP);
|
|
||||||
if (!removedClient) {
|
|
||||||
showError(hwnd, CStringUtil::format(
|
|
||||||
getString(IDS_UNINSTALL_FAILED).c_str(),
|
|
||||||
getString(IDS_CLIENT).c_str()));
|
|
||||||
}
|
|
||||||
else if (!removedServer) {
|
|
||||||
showError(hwnd, CStringUtil::format(
|
|
||||||
getString(IDS_UNINSTALL_FAILED).c_str(),
|
|
||||||
getString(IDS_SERVER).c_str()));
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
askOkay(hwnd, getString(IDS_UNINSTALL_TITLE),
|
// don't need thread handle
|
||||||
getString(IDS_UNINSTALLED));
|
CloseHandle(thread);
|
||||||
|
|
||||||
|
// notify of success
|
||||||
|
askOkay(hwnd, getString(IDS_STARTED_TITLE),
|
||||||
|
getString(IDS_STARTED));
|
||||||
|
|
||||||
|
// quit
|
||||||
|
PostQuitMessage(0);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case IDC_MAIN_AUTOSTART: {
|
||||||
|
// construct command line
|
||||||
|
CString cmdLine = getCommandLine(hwnd, false);
|
||||||
|
if (!cmdLine.empty()) {
|
||||||
|
// run dialog
|
||||||
|
CAutoStart autoStart(hwnd,
|
||||||
|
isClientChecked(hwnd) ? NULL : &s_config,
|
||||||
|
cmdLine);
|
||||||
|
autoStart.doModal();
|
||||||
|
if (autoStart.wasUserConfigSaved()) {
|
||||||
|
s_oldConfig = s_config;
|
||||||
|
enableSaveControls(hwnd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
case IDC_MAIN_SAVE:
|
||||||
|
if (!saveConfig(s_config, false)) {
|
||||||
|
showError(hwnd, CStringUtil::format(
|
||||||
|
getString(IDS_SAVE_FAILED).c_str(),
|
||||||
|
getErrorString(GetLastError()).c_str()));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
s_oldConfig = s_config;
|
||||||
|
enableSaveControls(hwnd);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
|
||||||
case IDC_MAIN_CLIENT_RADIO:
|
case IDC_MAIN_CLIENT_RADIO:
|
||||||
case IDC_MAIN_SERVER_RADIO:
|
case IDC_MAIN_SERVER_RADIO:
|
||||||
enableMainWindowControls(hwnd);
|
enableMainWindowControls(hwnd);
|
||||||
|
|
|
@ -95,18 +95,34 @@ LINK32=link.exe
|
||||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\CAutoStart.cpp
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=.\launcher.cpp
|
SOURCE=.\launcher.cpp
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=.\launcher.rc
|
SOURCE=.\launcher.rc
|
||||||
# End Source File
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\LaunchUtil.cpp
|
||||||
|
# End Source File
|
||||||
# End Group
|
# End Group
|
||||||
# Begin Group "Header Files"
|
# Begin Group "Header Files"
|
||||||
|
|
||||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\CAutoStart.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
|
SOURCE=.\LaunchUtil.h
|
||||||
|
# End Source File
|
||||||
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=.\resource.h
|
SOURCE=.\resource.h
|
||||||
# End Source File
|
# End Source File
|
||||||
# End Group
|
# End Group
|
||||||
|
|
|
@ -52,7 +52,7 @@ END
|
||||||
// Dialog
|
// Dialog
|
||||||
//
|
//
|
||||||
|
|
||||||
IDD_MAIN DIALOG DISCARDABLE 32768, 0, 300, 241
|
IDD_MAIN DIALOG DISCARDABLE 32768, 0, 300, 262
|
||||||
STYLE DS_MODALFRAME | WS_MINIMIZEBOX | WS_CAPTION | WS_SYSMENU
|
STYLE DS_MODALFRAME | WS_MINIMIZEBOX | WS_CAPTION | WS_SYSMENU
|
||||||
CAPTION "Synergy"
|
CAPTION "Synergy"
|
||||||
CLASS "GoSynergy"
|
CLASS "GoSynergy"
|
||||||
|
@ -62,22 +62,22 @@ BEGIN
|
||||||
IDC_STATIC,7,7,286,19
|
IDC_STATIC,7,7,286,19
|
||||||
GROUPBOX "",IDC_STATIC,7,29,286,31
|
GROUPBOX "",IDC_STATIC,7,29,286,31
|
||||||
GROUPBOX "",IDC_STATIC,7,67,286,103
|
GROUPBOX "",IDC_STATIC,7,67,286,103
|
||||||
GROUPBOX "Advanced Options",IDC_STATIC,7,177,286,34
|
GROUPBOX "Advanced Options",IDC_STATIC,7,177,286,56
|
||||||
CONTROL "Client",IDC_MAIN_CLIENT_RADIO,"Button",
|
CONTROL "&Client",IDC_MAIN_CLIENT_RADIO,"Button",
|
||||||
BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,11,29,33,10
|
BS_AUTORADIOBUTTON | WS_GROUP | WS_TABSTOP,11,29,33,10
|
||||||
CONTROL "Server",IDC_MAIN_SERVER_RADIO,"Button",
|
CONTROL "Server",IDC_MAIN_SERVER_RADIO,"Button",
|
||||||
BS_AUTORADIOBUTTON,11,67,37,10
|
BS_AUTORADIOBUTTON,11,67,37,10
|
||||||
LTEXT "Server Host Name:",IDC_MAIN_CLIENT_SERVER_NAME_LABEL,12,
|
LTEXT "Server &Host Name:",IDC_MAIN_CLIENT_SERVER_NAME_LABEL,
|
||||||
41,61,8
|
12,41,61,8
|
||||||
EDITTEXT IDC_MAIN_CLIENT_SERVER_NAME_EDIT,79,39,106,12,
|
EDITTEXT IDC_MAIN_CLIENT_SERVER_NAME_EDIT,79,39,106,12,
|
||||||
ES_AUTOHSCROLL
|
ES_AUTOHSCROLL
|
||||||
LTEXT "Screens:",IDC_MAIN_SERVER_SCREENS_LABEL,12,79,29,8
|
LTEXT "&Screens:",IDC_MAIN_SERVER_SCREENS_LABEL,12,79,29,8
|
||||||
LISTBOX IDC_MAIN_SERVER_SCREENS_LIST,12,91,106,36,
|
LISTBOX IDC_MAIN_SERVER_SCREENS_LIST,12,91,106,36,
|
||||||
LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
|
LBS_NOINTEGRALHEIGHT | WS_VSCROLL | WS_TABSTOP
|
||||||
PUSHBUTTON "Add",IDC_MAIN_SERVER_ADD_BUTTON,12,132,50,14
|
PUSHBUTTON "&Add",IDC_MAIN_SERVER_ADD_BUTTON,12,132,50,14
|
||||||
PUSHBUTTON "Edit",IDC_MAIN_SERVER_EDIT_BUTTON,68,132,50,14
|
PUSHBUTTON "&Edit",IDC_MAIN_SERVER_EDIT_BUTTON,68,132,50,14
|
||||||
PUSHBUTTON "Remove",IDC_MAIN_SERVER_REMOVE_BUTTON,12,150,50,14
|
PUSHBUTTON "&Remove",IDC_MAIN_SERVER_REMOVE_BUTTON,12,150,50,14
|
||||||
LTEXT "Layout:",IDC_MAIN_SERVER_LAYOUT_LABEL,138,79,24,8
|
LTEXT "&Layout:",IDC_MAIN_SERVER_LAYOUT_LABEL,138,79,24,8
|
||||||
LTEXT "Left:",IDC_MAIN_SERVER_LEFT_LABEL,144,93,15,8
|
LTEXT "Left:",IDC_MAIN_SERVER_LEFT_LABEL,144,93,15,8
|
||||||
COMBOBOX IDC_MAIN_SERVER_LEFT_COMBO,175,91,118,46,
|
COMBOBOX IDC_MAIN_SERVER_LEFT_COMBO,175,91,118,46,
|
||||||
CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
|
CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
|
||||||
|
@ -90,15 +90,17 @@ BEGIN
|
||||||
LTEXT "Below:",IDC_MAIN_SERVER_BOTTOM_LABEL,144,141,22,8
|
LTEXT "Below:",IDC_MAIN_SERVER_BOTTOM_LABEL,144,141,22,8
|
||||||
COMBOBOX IDC_MAIN_SERVER_BOTTOM_COMBO,175,139,118,46,
|
COMBOBOX IDC_MAIN_SERVER_BOTTOM_COMBO,175,139,118,46,
|
||||||
CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
|
CBS_DROPDOWNLIST | CBS_SORT | WS_VSCROLL | WS_TABSTOP
|
||||||
LTEXT "Screen Name:",IDC_STATIC,12,192,46,8
|
LTEXT "Screen &Name:",IDC_STATIC,12,192,46,8
|
||||||
EDITTEXT IDC_MAIN_ADVANCED_NAME_EDIT,64,190,106,12,ES_AUTOHSCROLL
|
EDITTEXT IDC_MAIN_ADVANCED_NAME_EDIT,64,190,106,12,ES_AUTOHSCROLL
|
||||||
LTEXT "Port:",IDC_STATIC,194,192,16,8
|
LTEXT "&Port:",IDC_STATIC,194,192,16,8
|
||||||
EDITTEXT IDC_MAIN_ADVANCED_PORT_EDIT,216,190,40,12,ES_AUTOHSCROLL |
|
EDITTEXT IDC_MAIN_ADVANCED_PORT_EDIT,216,190,40,12,ES_AUTOHSCROLL |
|
||||||
ES_NUMBER
|
ES_NUMBER
|
||||||
DEFPUSHBUTTON "Test",IDC_MAIN_TEST,75,220,50,14
|
LTEXT "Automatic Startup:",IDC_STATIC,12,212,59,8
|
||||||
PUSHBUTTON "Start",IDOK,131,220,50,14
|
PUSHBUTTON "Con&figure...",IDC_MAIN_AUTOSTART,78,210,50,14
|
||||||
PUSHBUTTON "No Auto-Start",IDC_MAIN_UNINSTALL,187,220,50,14
|
PUSHBUTTON "Sa&ve",IDC_MAIN_SAVE,75,241,50,14
|
||||||
PUSHBUTTON "Quit",IDCANCEL,243,220,50,14
|
DEFPUSHBUTTON "&Test",IDC_MAIN_TEST,131,241,50,14
|
||||||
|
PUSHBUTTON "Start",IDOK,187,241,50,14
|
||||||
|
PUSHBUTTON "Quit",IDCANCEL,243,241,50,14
|
||||||
END
|
END
|
||||||
|
|
||||||
IDD_ADD DIALOG DISCARDABLE 0, 0, 172, 95
|
IDD_ADD DIALOG DISCARDABLE 0, 0, 172, 95
|
||||||
|
@ -125,6 +127,26 @@ BEGIN
|
||||||
IDC_STATIC,7,7,172,15
|
IDC_STATIC,7,7,172,15
|
||||||
END
|
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
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
|
@ -139,7 +161,7 @@ BEGIN
|
||||||
LEFTMARGIN, 7
|
LEFTMARGIN, 7
|
||||||
RIGHTMARGIN, 293
|
RIGHTMARGIN, 293
|
||||||
TOPMARGIN, 7
|
TOPMARGIN, 7
|
||||||
BOTTOMMARGIN, 234
|
BOTTOMMARGIN, 255
|
||||||
END
|
END
|
||||||
|
|
||||||
IDD_ADD, DIALOG
|
IDD_ADD, DIALOG
|
||||||
|
@ -157,6 +179,14 @@ BEGIN
|
||||||
TOPMARGIN, 7
|
TOPMARGIN, 7
|
||||||
BOTTOMMARGIN, 47
|
BOTTOMMARGIN, 47
|
||||||
END
|
END
|
||||||
|
|
||||||
|
IDD_AUTOSTART, DIALOG
|
||||||
|
BEGIN
|
||||||
|
LEFTMARGIN, 7
|
||||||
|
RIGHTMARGIN, 188
|
||||||
|
TOPMARGIN, 7
|
||||||
|
BOTTOMMARGIN, 182
|
||||||
|
END
|
||||||
END
|
END
|
||||||
#endif // APSTUDIO_INVOKED
|
#endif // APSTUDIO_INVOKED
|
||||||
|
|
||||||
|
@ -189,16 +219,37 @@ BEGIN
|
||||||
IDS_STARTUP_FAILED "Failed to start synergy: %{1}"
|
IDS_STARTUP_FAILED "Failed to start synergy: %{1}"
|
||||||
IDS_STARTED_TITLE "Started"
|
IDS_STARTED_TITLE "Started"
|
||||||
IDS_STARTED "Synergy was successfully started. Use the task manager to terminate it."
|
IDS_STARTED "Synergy was successfully started. Use the task manager to terminate it."
|
||||||
IDS_INSTALL_FAILED "Failed to install synergy auto-starter. Synergy will not be started now and it will not automatically start each time you start or reboot your computer."
|
|
||||||
IDS_UNINSTALL_TITLE "Removed Auto-Start"
|
IDS_UNINSTALL_TITLE "Removed Auto-Start"
|
||||||
IDS_UNINSTALLED "Removed auto-start. Synergy will not automatically start each time you start or reboot your computer."
|
|
||||||
END
|
END
|
||||||
|
|
||||||
STRINGTABLE DISCARDABLE
|
STRINGTABLE DISCARDABLE
|
||||||
BEGIN
|
BEGIN
|
||||||
IDS_UNINSTALL_FAILED "Failed to remove auto-start of %{1}. You might not have permission to remove it or it might be in use.\n\nOn Windows NT, 2000, or XP you should open the Services control panel and stop the synergy %{1} service then try again."
|
IDS_AUTOSTART_PERMISSION_SYSTEM
|
||||||
IDS_CLIENT "client"
|
"You have sufficient access rights to install and uninstall Auto Start for all users or for just yourself."
|
||||||
IDS_SERVER "server"
|
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 for an unknown reason."
|
||||||
|
IDS_UNINSTALL_GENERIC_ERROR "Uninstall failed for an unknown reason."
|
||||||
|
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."
|
||||||
|
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."
|
||||||
END
|
END
|
||||||
|
|
||||||
#endif // English (U.S.) resources
|
#endif // English (U.S.) resources
|
||||||
|
|
|
@ -1,62 +1,85 @@
|
||||||
//{{NO_DEPENDENCIES}}
|
//{{NO_DEPENDENCIES}}
|
||||||
// Microsoft Developer Studio generated include file.
|
// Microsoft Developer Studio generated include file.
|
||||||
// Used by launcher.rc
|
// Used by launcher.rc
|
||||||
//
|
//
|
||||||
#define IDS_ERROR 1
|
#define IDS_ERROR 1
|
||||||
#define IDS_INVALID_SCREEN_NAME 2
|
#define IDS_INVALID_SCREEN_NAME 2
|
||||||
#define IDS_DUPLICATE_SCREEN_NAME 3
|
#define IDS_DUPLICATE_SCREEN_NAME 3
|
||||||
#define IDS_SCREEN_NAME_IS_ALIAS 4
|
#define IDS_SCREEN_NAME_IS_ALIAS 4
|
||||||
#define IDS_VERIFY 5
|
#define IDS_VERIFY 5
|
||||||
#define IDS_UNSAVED_DATA_REALLY_QUIT 6
|
#define IDS_UNSAVED_DATA_REALLY_QUIT 6
|
||||||
#define IDS_UNKNOWN_SCREEN_NAME 7
|
#define IDS_UNKNOWN_SCREEN_NAME 7
|
||||||
#define IDS_INVALID_PORT 8
|
#define IDS_INVALID_PORT 8
|
||||||
#define IDS_SAVE_FAILED 9
|
#define IDS_SAVE_FAILED 9
|
||||||
#define IDS_STARTUP_FAILED 10
|
#define IDS_STARTUP_FAILED 10
|
||||||
#define IDS_STARTED_TITLE 11
|
#define IDS_STARTED_TITLE 11
|
||||||
#define IDS_STARTED 12
|
#define IDS_STARTED 12
|
||||||
#define IDS_INSTALL_FAILED 13
|
#define IDS_INSTALL_FAILED 13
|
||||||
#define IDS_UNINSTALL_TITLE 14
|
#define IDS_UNINSTALL_TITLE 14
|
||||||
#define IDS_UNINSTALLED 15
|
#define IDS_UNINSTALLED 15
|
||||||
#define IDS_UNINSTALL_FAILED 16
|
#define IDS_UNINSTALL_FAILED 16
|
||||||
#define IDS_CLIENT 17
|
#define IDS_CLIENT 17
|
||||||
#define IDS_SERVER 18
|
#define IDS_SERVER 18
|
||||||
#define IDD_MAIN 101
|
#define IDS_AUTOSTART_PERMISSION_SYSTEM 19
|
||||||
#define IDD_ADD 102
|
#define IDS_AUTOSTART_PERMISSION_USER 20
|
||||||
#define IDD_WAIT 103
|
#define IDS_AUTOSTART_PERMISSION_NONE 21
|
||||||
#define IDI_SYNERGY 104
|
#define IDS_AUTOSTART_INSTALLED_SYSTEM 22
|
||||||
#define IDC_MAIN_CLIENT_RADIO 1000
|
#define IDS_AUTOSTART_INSTALLED_USER 23
|
||||||
#define IDC_MAIN_SERVER_RADIO 1001
|
#define IDS_AUTOSTART_INSTALLED_NONE 24
|
||||||
#define IDC_MAIN_CLIENT_SERVER_NAME_EDIT 1002
|
#define IDS_INSTALL_LABEL 25
|
||||||
#define IDC_MAIN_ADVANCED_NAME_EDIT 1006
|
#define IDS_UNINSTALL_LABEL 26
|
||||||
#define IDC_MAIN_ADVANCED_PORT_EDIT 1008
|
#define IDS_INSTALL_GENERIC_ERROR 27
|
||||||
#define IDC_MAIN_TEST 1009
|
#define IDS_UNINSTALL_GENERIC_ERROR 28
|
||||||
#define IDC_MAIN_CLIENT_SERVER_NAME_LABEL 1011
|
#define IDS_INSTALL_TITLE 29
|
||||||
#define IDC_MAIN_SERVER_SCREENS_LIST 1012
|
#define IDS_INSTALLED_SYSTEM 30
|
||||||
#define IDC_MAIN_SERVER_SCREENS_LABEL 1013
|
#define IDS_INSTALLED_USER 31
|
||||||
#define IDC_MAIN_SERVER_LAYOUT_LABEL 1014
|
#define IDS_UNINSTALLED_SYSTEM 32
|
||||||
#define IDC_MAIN_SERVER_ADD_BUTTON 1018
|
#define IDS_UNINSTALLED_USER 33
|
||||||
#define IDC_MAIN_SERVER_EDIT_BUTTON 1019
|
#define IDS_INVALID_SERVER_NAME 34
|
||||||
#define IDC_ADD_SCREEN_NAME_EDIT 1020
|
#define IDD_MAIN 101
|
||||||
#define IDC_MAIN_SERVER_REMOVE_BUTTON 1020
|
#define IDD_ADD 102
|
||||||
#define IDC_ADD_ALIASES_EDIT 1021
|
#define IDD_WAIT 103
|
||||||
#define IDC_MAIN_SERVER_LEFT_COMBO 1022
|
#define IDI_SYNERGY 104
|
||||||
#define IDC_MAIN_SERVER_RIGHT_COMBO 1023
|
#define IDD_AUTOSTART 105
|
||||||
#define IDC_MAIN_SERVER_TOP_COMBO 1024
|
#define IDC_MAIN_CLIENT_RADIO 1000
|
||||||
#define IDC_MAIN_SERVER_BOTTOM_COMBO 1025
|
#define IDC_MAIN_SERVER_RADIO 1001
|
||||||
#define IDC_MAIN_SERVER_LEFT_LABEL 1026
|
#define IDC_MAIN_CLIENT_SERVER_NAME_EDIT 1002
|
||||||
#define IDC_MAIN_SERVER_RIGHT_LABEL 1027
|
#define IDC_MAIN_ADVANCED_NAME_EDIT 1006
|
||||||
#define IDC_MAIN_SERVER_TOP_LABEL 1028
|
#define IDC_MAIN_ADVANCED_PORT_EDIT 1008
|
||||||
#define IDC_MAIN_SERVER_BOTTOM_LABEL 1029
|
#define IDC_MAIN_TEST 1009
|
||||||
#define IDC_MAIN_UNINSTALL 1030
|
#define IDC_MAIN_SAVE 1010
|
||||||
|
#define IDC_MAIN_CLIENT_SERVER_NAME_LABEL 1011
|
||||||
// Next default values for new objects
|
#define IDC_MAIN_SERVER_SCREENS_LIST 1012
|
||||||
//
|
#define IDC_MAIN_SERVER_SCREENS_LABEL 1013
|
||||||
#ifdef APSTUDIO_INVOKED
|
#define IDC_MAIN_SERVER_LAYOUT_LABEL 1014
|
||||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
#define IDC_MAIN_SERVER_ADD_BUTTON 1018
|
||||||
#define _APS_NO_MFC 1
|
#define IDC_MAIN_SERVER_EDIT_BUTTON 1019
|
||||||
#define _APS_NEXT_RESOURCE_VALUE 105
|
#define IDC_ADD_SCREEN_NAME_EDIT 1020
|
||||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
#define IDC_MAIN_SERVER_REMOVE_BUTTON 1020
|
||||||
#define _APS_NEXT_CONTROL_VALUE 1031
|
#define IDC_ADD_ALIASES_EDIT 1021
|
||||||
#define _APS_NEXT_SYMED_VALUE 101
|
#define IDC_MAIN_SERVER_LEFT_COMBO 1022
|
||||||
#endif
|
#define IDC_MAIN_SERVER_RIGHT_COMBO 1023
|
||||||
#endif
|
#define IDC_MAIN_SERVER_TOP_COMBO 1024
|
||||||
|
#define IDC_MAIN_SERVER_BOTTOM_COMBO 1025
|
||||||
|
#define IDC_MAIN_SERVER_LEFT_LABEL 1026
|
||||||
|
#define IDC_MAIN_SERVER_RIGHT_LABEL 1027
|
||||||
|
#define IDC_MAIN_SERVER_TOP_LABEL 1028
|
||||||
|
#define IDC_MAIN_SERVER_BOTTOM_LABEL 1029
|
||||||
|
#define IDC_MAIN_UNINSTALL 1030
|
||||||
|
#define IDC_AUTOSTART_INSTALLED_MSG 1031
|
||||||
|
#define IDC_AUTOSTART_PERMISSION_MSG 1032
|
||||||
|
#define IDC_AUTOSTART_INSTALL_USER 1033
|
||||||
|
#define IDC_AUTOSTART_INSTALL_SYSTEM 1034
|
||||||
|
#define IDC_MAIN_AUTOSTART 1035
|
||||||
|
|
||||||
|
// Next default values for new objects
|
||||||
|
//
|
||||||
|
#ifdef APSTUDIO_INVOKED
|
||||||
|
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||||
|
#define _APS_NO_MFC 1
|
||||||
|
#define _APS_NEXT_RESOURCE_VALUE 106
|
||||||
|
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||||
|
#define _APS_NEXT_CONTROL_VALUE 1036
|
||||||
|
#define _APS_NEXT_SYMED_VALUE 101
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
|
@ -1,19 +1,19 @@
|
||||||
//{{NO_DEPENDENCIES}}
|
//{{NO_DEPENDENCIES}}
|
||||||
// Microsoft Developer Studio generated include file.
|
// Microsoft Developer Studio generated include file.
|
||||||
// Used by synergy.rc
|
// Used by synergyc.rc
|
||||||
//
|
//
|
||||||
#define IDS_FAILED 1
|
#define IDS_FAILED 1
|
||||||
#define IDD_SYNERGY 101
|
#define IDD_SYNERGY 101
|
||||||
#define IDI_SYNERGY 103
|
#define IDI_SYNERGY 103
|
||||||
#define IDC_LOG 1000
|
#define IDC_LOG 1000
|
||||||
|
|
||||||
// Next default values for new objects
|
// Next default values for new objects
|
||||||
//
|
//
|
||||||
#ifdef APSTUDIO_INVOKED
|
#ifdef APSTUDIO_INVOKED
|
||||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||||
#define _APS_NEXT_RESOURCE_VALUE 104
|
#define _APS_NEXT_RESOURCE_VALUE 104
|
||||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||||
#define _APS_NEXT_CONTROL_VALUE 1000
|
#define _APS_NEXT_CONTROL_VALUE 1000
|
||||||
#define _APS_NEXT_SYMED_VALUE 101
|
#define _APS_NEXT_SYMED_VALUE 101
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -54,8 +54,6 @@ static bool s_backend = false;
|
||||||
static bool s_restartable = true;
|
static bool s_restartable = true;
|
||||||
static bool s_daemon = true;
|
static bool s_daemon = true;
|
||||||
static bool s_camp = true;
|
static bool s_camp = true;
|
||||||
static bool s_install = false;
|
|
||||||
static bool s_uninstall = false;
|
|
||||||
static const char* s_logFilter = NULL;
|
static const char* s_logFilter = NULL;
|
||||||
static CString s_name;
|
static CString s_name;
|
||||||
static CNetworkAddress s_serverAddress;
|
static CNetworkAddress s_serverAddress;
|
||||||
|
@ -246,25 +244,6 @@ static
|
||||||
void
|
void
|
||||||
help()
|
help()
|
||||||
{
|
{
|
||||||
#if WINDOWS_LIKE
|
|
||||||
|
|
||||||
# define PLATFORM_ARGS \
|
|
||||||
" [--install]" \
|
|
||||||
" <server-address>\n" \
|
|
||||||
"or\n" \
|
|
||||||
" --uninstall\n"
|
|
||||||
# define PLATFORM_DESC \
|
|
||||||
" --install install server as a service.\n" \
|
|
||||||
" --uninstall uninstall server service.\n"
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
# define PLATFORM_ARGS \
|
|
||||||
" <server-address>\n"
|
|
||||||
# define PLATFORM_DESC
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
log((CLOG_PRINT
|
log((CLOG_PRINT
|
||||||
"Usage: %s"
|
"Usage: %s"
|
||||||
" [--camp|--no-camp]"
|
" [--camp|--no-camp]"
|
||||||
|
@ -272,7 +251,7 @@ help()
|
||||||
" [--debug <level>]"
|
" [--debug <level>]"
|
||||||
" [--name <screen-name>]"
|
" [--name <screen-name>]"
|
||||||
" [--restart|--no-restart]"
|
" [--restart|--no-restart]"
|
||||||
PLATFORM_ARGS
|
" <server-address>\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Start the synergy mouse/keyboard sharing server.\n"
|
"Start the synergy mouse/keyboard sharing server.\n"
|
||||||
"\n"
|
"\n"
|
||||||
|
@ -289,7 +268,6 @@ PLATFORM_ARGS
|
||||||
" -1, --no-restart do not try to restart the client if it fails for\n"
|
" -1, --no-restart do not try to restart the client if it fails for\n"
|
||||||
" some reason.\n"
|
" some reason.\n"
|
||||||
"* --restart restart the client automatically if it fails.\n"
|
"* --restart restart the client automatically if it fails.\n"
|
||||||
PLATFORM_DESC
|
|
||||||
" -h, --help display this help and exit.\n"
|
" -h, --help display this help and exit.\n"
|
||||||
" --version display version information and exit.\n"
|
" --version display version information and exit.\n"
|
||||||
"\n"
|
"\n"
|
||||||
|
@ -397,30 +375,6 @@ parse(int argc, const char** argv)
|
||||||
bye(kExitSuccess);
|
bye(kExitSuccess);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if WINDOWS_LIKE
|
|
||||||
else if (isArg(i, argc, argv, NULL, "--install")) {
|
|
||||||
s_install = true;
|
|
||||||
if (s_uninstall) {
|
|
||||||
log((CLOG_PRINT "%s: `--install' and `--uninstall'"
|
|
||||||
" are mutually exclusive" BYE,
|
|
||||||
pname, argv[i], pname));
|
|
||||||
bye(kExitArgs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if WINDOWS_LIKE
|
|
||||||
else if (isArg(i, argc, argv, NULL, "--uninstall")) {
|
|
||||||
s_uninstall = true;
|
|
||||||
if (s_install) {
|
|
||||||
log((CLOG_PRINT "%s: `--install' and `--uninstall'"
|
|
||||||
" are mutually exclusive" BYE,
|
|
||||||
pname, argv[i], pname));
|
|
||||||
bye(kExitArgs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
else if (isArg(i, argc, argv, "--", NULL)) {
|
else if (isArg(i, argc, argv, "--", NULL)) {
|
||||||
// remaining arguments are not options
|
// remaining arguments are not options
|
||||||
++i;
|
++i;
|
||||||
|
@ -439,37 +393,26 @@ parse(int argc, const char** argv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// exactly one non-option argument (server-address) unless using
|
// exactly one non-option argument (server-address)
|
||||||
// --uninstall.
|
if (i == argc) {
|
||||||
if (s_uninstall) {
|
log((CLOG_PRINT "%s: a server address or name is required" BYE,
|
||||||
if (i != argc) {
|
|
||||||
log((CLOG_PRINT "%s: unrecognized option `%s' to `%s'" BYE,
|
|
||||||
pname, argv[i], pname,
|
|
||||||
s_install ? "--install" : "--uninstall"));
|
|
||||||
bye(kExitArgs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (i == argc) {
|
|
||||||
log((CLOG_PRINT "%s: a server address or name is required" BYE,
|
|
||||||
pname, pname));
|
pname, pname));
|
||||||
bye(kExitArgs);
|
bye(kExitArgs);
|
||||||
}
|
}
|
||||||
if (i + 1 != argc) {
|
if (i + 1 != argc) {
|
||||||
log((CLOG_PRINT "%s: unrecognized option `%s'" BYE,
|
log((CLOG_PRINT "%s: unrecognized option `%s'" BYE,
|
||||||
pname, argv[i], pname));
|
pname, argv[i], pname));
|
||||||
bye(kExitArgs);
|
bye(kExitArgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
// save server address
|
// save server address
|
||||||
try {
|
try {
|
||||||
s_serverAddress = CNetworkAddress(argv[i], kDefaultPort);
|
s_serverAddress = CNetworkAddress(argv[i], kDefaultPort);
|
||||||
}
|
}
|
||||||
catch (XSocketAddress& e) {
|
catch (XSocketAddress& e) {
|
||||||
log((CLOG_PRINT "%s: %s" BYE,
|
log((CLOG_PRINT "%s: %s" BYE,
|
||||||
pname, e.what(), pname));
|
pname, e.what(), pname));
|
||||||
bye(kExitFailed);
|
bye(kExitFailed);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// increase default filter level for daemon. the user must
|
// increase default filter level for daemon. the user must
|
||||||
|
@ -496,7 +439,6 @@ parse(int argc, const char** argv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// platform dependent entry points
|
// platform dependent entry points
|
||||||
//
|
//
|
||||||
|
@ -505,24 +447,16 @@ parse(int argc, const char** argv)
|
||||||
|
|
||||||
#include "CMSWindowsScreen.h"
|
#include "CMSWindowsScreen.h"
|
||||||
|
|
||||||
static bool s_errors = false;
|
|
||||||
|
|
||||||
static
|
static
|
||||||
bool
|
bool
|
||||||
logMessageBox(int priority, const char* msg)
|
logMessageBox(int priority, const char* msg)
|
||||||
{
|
{
|
||||||
if (priority <= CLog::kERROR) {
|
if (priority <= (s_backend ? CLog::kERROR : CLog::kFATAL)) {
|
||||||
s_errors = true;
|
|
||||||
}
|
|
||||||
if (s_backend) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (priority <= CLog::kFATAL) {
|
|
||||||
MessageBox(NULL, msg, pname, MB_OK | MB_ICONWARNING);
|
MessageBox(NULL, msg, pname, MB_OK | MB_ICONWARNING);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return false;
|
return s_backend;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -551,13 +485,7 @@ daemonStartup(IPlatform* iplatform, int argc, const char** argv)
|
||||||
bye = &byeThrow;
|
bye = &byeThrow;
|
||||||
|
|
||||||
// parse command line
|
// parse command line
|
||||||
s_install = false;
|
|
||||||
s_uninstall = false;
|
|
||||||
parse(argc, argv);
|
parse(argc, argv);
|
||||||
if (s_install || s_uninstall) {
|
|
||||||
// not allowed to install/uninstall from service
|
|
||||||
throw CWin32Platform::CDaemonFailed(kExitArgs);
|
|
||||||
}
|
|
||||||
|
|
||||||
// run as a service
|
// run as a service
|
||||||
return platform->runDaemon(realMain, daemonStop);
|
return platform->runDaemon(realMain, daemonStop);
|
||||||
|
@ -605,58 +533,6 @@ WinMain(HINSTANCE instance, HINSTANCE, LPSTR, int)
|
||||||
// parse command line
|
// parse command line
|
||||||
parse(__argc, const_cast<const char**>(__argv));
|
parse(__argc, const_cast<const char**>(__argv));
|
||||||
|
|
||||||
// install/uninstall
|
|
||||||
if (s_install) {
|
|
||||||
// get the full path to this program
|
|
||||||
TCHAR path[MAX_PATH];
|
|
||||||
if (GetModuleFileName(NULL, path,
|
|
||||||
sizeof(path) / sizeof(path[0])) == 0) {
|
|
||||||
log((CLOG_CRIT "cannot determine absolute path to program"));
|
|
||||||
return kExitFailed;
|
|
||||||
}
|
|
||||||
|
|
||||||
// construct the command line to start the service with
|
|
||||||
CString commandLine = "--daemon";
|
|
||||||
if (s_restartable) {
|
|
||||||
commandLine += " --restart";
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
commandLine += " --no-restart";
|
|
||||||
}
|
|
||||||
if (s_logFilter != NULL) {
|
|
||||||
commandLine += " --debug ";
|
|
||||||
commandLine += s_logFilter;
|
|
||||||
}
|
|
||||||
commandLine += " ";
|
|
||||||
commandLine += s_serverAddress.getHostname().c_str();
|
|
||||||
|
|
||||||
// install
|
|
||||||
if (!platform.installDaemon(DAEMON_NAME,
|
|
||||||
"Shares this system's mouse and keyboard with others.",
|
|
||||||
path, commandLine.c_str())) {
|
|
||||||
log((CLOG_CRIT "failed to install service"));
|
|
||||||
return kExitFailed;
|
|
||||||
}
|
|
||||||
log((CLOG_PRINT "installed successfully"));
|
|
||||||
return kExitSuccess;
|
|
||||||
}
|
|
||||||
else if (s_uninstall) {
|
|
||||||
switch (platform.uninstallDaemon(DAEMON_NAME)) {
|
|
||||||
case IPlatform::kSuccess:
|
|
||||||
log((CLOG_PRINT "uninstalled successfully"));
|
|
||||||
return kExitSuccess;
|
|
||||||
|
|
||||||
case IPlatform::kFailed:
|
|
||||||
log((CLOG_CRIT "failed to uninstall service"));
|
|
||||||
return kExitFailed;
|
|
||||||
|
|
||||||
case IPlatform::kAlready:
|
|
||||||
log((CLOG_CRIT "service isn't installed"));
|
|
||||||
// return success since service is uninstalled
|
|
||||||
return kExitSuccess;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// daemonize if requested
|
// daemonize if requested
|
||||||
int result;
|
int result;
|
||||||
if (s_daemon) {
|
if (s_daemon) {
|
||||||
|
@ -684,15 +560,6 @@ WinMain(HINSTANCE instance, HINSTANCE, LPSTR, int)
|
||||||
|
|
||||||
CNetwork::cleanup();
|
CNetwork::cleanup();
|
||||||
|
|
||||||
// if running as a non-daemon backend and there was an error then
|
|
||||||
// wait for the user to click okay so he can see the error messages.
|
|
||||||
if (s_backend && !s_daemon && (result == kExitFailed || s_errors)) {
|
|
||||||
char msg[1024];
|
|
||||||
msg[0] = '\0';
|
|
||||||
LoadString(instance, IDS_FAILED, msg, sizeof(msg) / sizeof(msg[0]));
|
|
||||||
MessageBox(NULL, msg, pname, MB_OK | MB_ICONWARNING);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -89,17 +89,6 @@ END
|
||||||
// Icon with lowest ID value placed first to ensure application icon
|
// Icon with lowest ID value placed first to ensure application icon
|
||||||
// remains consistent on all systems.
|
// remains consistent on all systems.
|
||||||
IDI_SYNERGY ICON DISCARDABLE "synergyc.ico"
|
IDI_SYNERGY ICON DISCARDABLE "synergyc.ico"
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// String Table
|
|
||||||
//
|
|
||||||
|
|
||||||
STRINGTABLE DISCARDABLE
|
|
||||||
BEGIN
|
|
||||||
IDS_FAILED "Synergy is about to quit with an error. Please check the log for error messages then click OK."
|
|
||||||
END
|
|
||||||
|
|
||||||
#endif // English (U.S.) resources
|
#endif // English (U.S.) resources
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
|
@ -1,19 +1,19 @@
|
||||||
//{{NO_DEPENDENCIES}}
|
//{{NO_DEPENDENCIES}}
|
||||||
// Microsoft Developer Studio generated include file.
|
// Microsoft Developer Studio generated include file.
|
||||||
// Used by synergyd.rc
|
// Used by synergyd.rc
|
||||||
//
|
//
|
||||||
#define IDS_FAILED 1
|
#define IDS_FAILED 1
|
||||||
#define IDD_SYNERGY 101
|
#define IDD_SYNERGY 101
|
||||||
#define IDI_SYNERGY 102
|
#define IDI_SYNERGY 102
|
||||||
#define IDC_LOG 1000
|
#define IDC_LOG 1000
|
||||||
|
|
||||||
// Next default values for new objects
|
// Next default values for new objects
|
||||||
//
|
//
|
||||||
#ifdef APSTUDIO_INVOKED
|
#ifdef APSTUDIO_INVOKED
|
||||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||||
#define _APS_NEXT_RESOURCE_VALUE 103
|
#define _APS_NEXT_RESOURCE_VALUE 103
|
||||||
#define _APS_NEXT_COMMAND_VALUE 40001
|
#define _APS_NEXT_COMMAND_VALUE 40001
|
||||||
#define _APS_NEXT_CONTROL_VALUE 1002
|
#define _APS_NEXT_CONTROL_VALUE 1002
|
||||||
#define _APS_NEXT_SYMED_VALUE 101
|
#define _APS_NEXT_SYMED_VALUE 101
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -61,10 +61,6 @@ static const char* pname = NULL;
|
||||||
static bool s_backend = false;
|
static bool s_backend = false;
|
||||||
static bool s_restartable = true;
|
static bool s_restartable = true;
|
||||||
static bool s_daemon = true;
|
static bool s_daemon = true;
|
||||||
#if WINDOWS_LIKE
|
|
||||||
static bool s_install = false;
|
|
||||||
static bool s_uninstall = false;
|
|
||||||
#endif
|
|
||||||
static const char* s_configFile = NULL;
|
static const char* s_configFile = NULL;
|
||||||
static const char* s_logFilter = NULL;
|
static const char* s_logFilter = NULL;
|
||||||
static CString s_name;
|
static CString s_name;
|
||||||
|
@ -275,13 +271,8 @@ help()
|
||||||
#if WINDOWS_LIKE
|
#if WINDOWS_LIKE
|
||||||
|
|
||||||
# define PLATFORM_ARGS \
|
# define PLATFORM_ARGS \
|
||||||
" {--daemon|--no-daemon}" \
|
" {--daemon|--no-daemon}"
|
||||||
" [--install]\n" \
|
# define PLATFORM_DESC
|
||||||
"or\n" \
|
|
||||||
" --uninstall\n"
|
|
||||||
# define PLATFORM_DESC \
|
|
||||||
" --install install server as a daemon.\n" \
|
|
||||||
" --uninstall uninstall server daemon.\n"
|
|
||||||
# define PLATFORM_EXTRA \
|
# define PLATFORM_EXTRA \
|
||||||
"At least one command line argument is required. If you don't otherwise\n" \
|
"At least one command line argument is required. If you don't otherwise\n" \
|
||||||
"need an argument use `--daemon'.\n" \
|
"need an argument use `--daemon'.\n" \
|
||||||
|
@ -334,7 +325,7 @@ PLATFORM_EXTRA
|
||||||
"default port, %d.\n"
|
"default port, %d.\n"
|
||||||
"\n"
|
"\n"
|
||||||
"If no configuration file pathname is provided then the first of the\n"
|
"If no configuration file pathname is provided then the first of the\n"
|
||||||
"following to load sets the configuration:\n"
|
"following to load successfully sets the configuration:\n"
|
||||||
" %s\n"
|
" %s\n"
|
||||||
" %s\n"
|
" %s\n"
|
||||||
"If no configuration file can be loaded then the configuration uses its\n"
|
"If no configuration file can be loaded then the configuration uses its\n"
|
||||||
|
@ -465,30 +456,6 @@ parse(int argc, const char** argv)
|
||||||
bye(kExitSuccess);
|
bye(kExitSuccess);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if WINDOWS_LIKE
|
|
||||||
else if (isArg(i, argc, argv, NULL, "--install")) {
|
|
||||||
s_install = true;
|
|
||||||
if (s_uninstall) {
|
|
||||||
log((CLOG_PRINT "%s: `--install' and `--uninstall'"
|
|
||||||
" are mutually exclusive" BYE,
|
|
||||||
pname, argv[i], pname));
|
|
||||||
bye(kExitArgs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if WINDOWS_LIKE
|
|
||||||
else if (isArg(i, argc, argv, NULL, "--uninstall")) {
|
|
||||||
s_uninstall = true;
|
|
||||||
if (s_install) {
|
|
||||||
log((CLOG_PRINT "%s: `--install' and `--uninstall'"
|
|
||||||
" are mutually exclusive" BYE,
|
|
||||||
pname, argv[i], pname));
|
|
||||||
bye(kExitArgs);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
else if (isArg(i, argc, argv, "--", NULL)) {
|
else if (isArg(i, argc, argv, "--", NULL)) {
|
||||||
// remaining arguments are not options
|
// remaining arguments are not options
|
||||||
++i;
|
++i;
|
||||||
|
@ -612,24 +579,16 @@ loadConfig()
|
||||||
|
|
||||||
#include "CMSWindowsScreen.h"
|
#include "CMSWindowsScreen.h"
|
||||||
|
|
||||||
static bool s_errors = false;
|
|
||||||
|
|
||||||
static
|
static
|
||||||
bool
|
bool
|
||||||
logMessageBox(int priority, const char* msg)
|
logMessageBox(int priority, const char* msg)
|
||||||
{
|
{
|
||||||
if (priority <= CLog::kERROR) {
|
if (priority <= (s_backend ? CLog::kERROR : CLog::kFATAL)) {
|
||||||
s_errors = true;
|
|
||||||
}
|
|
||||||
if (s_backend) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (priority <= CLog::kFATAL) {
|
|
||||||
MessageBox(NULL, msg, pname, MB_OK | MB_ICONWARNING);
|
MessageBox(NULL, msg, pname, MB_OK | MB_ICONWARNING);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return false;
|
return s_backend;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -658,13 +617,7 @@ daemonStartup(IPlatform* iplatform, int argc, const char** argv)
|
||||||
bye = &byeThrow;
|
bye = &byeThrow;
|
||||||
|
|
||||||
// parse command line
|
// parse command line
|
||||||
s_install = false;
|
|
||||||
s_uninstall = false;
|
|
||||||
parse(argc, argv);
|
parse(argc, argv);
|
||||||
if (s_install || s_uninstall) {
|
|
||||||
// not allowed to install/uninstall from service
|
|
||||||
throw CWin32Platform::CDaemonFailed(kExitArgs);
|
|
||||||
}
|
|
||||||
|
|
||||||
// load configuration
|
// load configuration
|
||||||
loadConfig();
|
loadConfig();
|
||||||
|
@ -715,62 +668,6 @@ WinMain(HINSTANCE instance, HINSTANCE, LPSTR, int)
|
||||||
// parse command line
|
// parse command line
|
||||||
parse(__argc, const_cast<const char**>(__argv));
|
parse(__argc, const_cast<const char**>(__argv));
|
||||||
|
|
||||||
// install/uninstall
|
|
||||||
if (s_install) {
|
|
||||||
// get the full path to this program
|
|
||||||
TCHAR path[MAX_PATH];
|
|
||||||
if (GetModuleFileName(NULL, path,
|
|
||||||
sizeof(path) / sizeof(path[0])) == 0) {
|
|
||||||
log((CLOG_CRIT "cannot determine absolute path to program"));
|
|
||||||
return kExitFailed;
|
|
||||||
}
|
|
||||||
|
|
||||||
// construct the command line to start the service with
|
|
||||||
CString commandLine;
|
|
||||||
commandLine += "--daemon";
|
|
||||||
if (s_restartable) {
|
|
||||||
commandLine += " --restart";
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
commandLine += " --no-restart";
|
|
||||||
}
|
|
||||||
if (s_logFilter != NULL) {
|
|
||||||
commandLine += " --debug ";
|
|
||||||
commandLine += s_logFilter;
|
|
||||||
}
|
|
||||||
if (s_configFile != NULL) {
|
|
||||||
commandLine += " --config \"";
|
|
||||||
commandLine += s_configFile;
|
|
||||||
commandLine += "\"";
|
|
||||||
}
|
|
||||||
|
|
||||||
// install
|
|
||||||
if (!platform.installDaemon(DAEMON_NAME,
|
|
||||||
"Shares this system's mouse and keyboard with others.",
|
|
||||||
path, commandLine.c_str())) {
|
|
||||||
log((CLOG_CRIT "failed to install service"));
|
|
||||||
return kExitFailed;
|
|
||||||
}
|
|
||||||
log((CLOG_PRINT "installed successfully"));
|
|
||||||
return kExitSuccess;
|
|
||||||
}
|
|
||||||
else if (s_uninstall) {
|
|
||||||
switch (platform.uninstallDaemon(DAEMON_NAME)) {
|
|
||||||
case IPlatform::kSuccess:
|
|
||||||
log((CLOG_PRINT "uninstalled successfully"));
|
|
||||||
return kExitSuccess;
|
|
||||||
|
|
||||||
case IPlatform::kFailed:
|
|
||||||
log((CLOG_CRIT "failed to uninstall service"));
|
|
||||||
return kExitFailed;
|
|
||||||
|
|
||||||
case IPlatform::kAlready:
|
|
||||||
log((CLOG_CRIT "service isn't installed"));
|
|
||||||
// return success since service is uninstalled
|
|
||||||
return kExitSuccess;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// load configuration
|
// load configuration
|
||||||
loadConfig();
|
loadConfig();
|
||||||
|
|
||||||
|
@ -801,15 +698,6 @@ WinMain(HINSTANCE instance, HINSTANCE, LPSTR, int)
|
||||||
|
|
||||||
CNetwork::cleanup();
|
CNetwork::cleanup();
|
||||||
|
|
||||||
// if running as a non-daemon backend and there was an error then
|
|
||||||
// wait for the user to click okay so he can see the error messages.
|
|
||||||
if (s_backend && !s_daemon && (result == kExitFailed || s_errors)) {
|
|
||||||
char msg[1024];
|
|
||||||
msg[0] = '\0';
|
|
||||||
LoadString(instance, IDS_FAILED, msg, sizeof(msg) / sizeof(msg[0]));
|
|
||||||
MessageBox(NULL, msg, pname, MB_OK | MB_ICONWARNING);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -511,7 +511,7 @@ CClient::runServer()
|
||||||
for (;;) {
|
for (;;) {
|
||||||
try {
|
try {
|
||||||
// allow connect this much time to succeed
|
// allow connect this much time to succeed
|
||||||
CTimerThread timer(m_camp ? -1.0 : 30.0);
|
CTimerThread timer(15.0);
|
||||||
|
|
||||||
// create socket and attempt to connect to server
|
// create socket and attempt to connect to server
|
||||||
log((CLOG_DEBUG1 "connecting to server"));
|
log((CLOG_DEBUG1 "connecting to server"));
|
||||||
|
@ -532,7 +532,7 @@ CClient::runServer()
|
||||||
}
|
}
|
||||||
|
|
||||||
// we're camping. wait a bit before retrying
|
// we're camping. wait a bit before retrying
|
||||||
CThread::sleep(5.0);
|
CThread::sleep(15.0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -459,6 +459,7 @@ CMSWindowsSecondaryScreen::updateKeys()
|
||||||
if ((m_keys[VK_SCROLL] & 0x01) != 0) {
|
if ((m_keys[VK_SCROLL] & 0x01) != 0) {
|
||||||
m_mask |= KeyModifierScrollLock;
|
m_mask |= KeyModifierScrollLock;
|
||||||
}
|
}
|
||||||
|
// note -- do not save KeyModifierModeSwitch in m_mask
|
||||||
log((CLOG_DEBUG2 "modifiers on update: 0x%04x", m_mask));
|
log((CLOG_DEBUG2 "modifiers on update: 0x%04x", m_mask));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -634,6 +635,11 @@ CMSWindowsSecondaryScreen::mapKey(Keystrokes& keys, UINT& virtualKey,
|
||||||
KeyModifierAlt |
|
KeyModifierAlt |
|
||||||
KeyModifierMeta));
|
KeyModifierMeta));
|
||||||
|
|
||||||
|
// set control and alt if mode shift (AltGr) is requested
|
||||||
|
if ((mask & KeyModifierModeSwitch) != 0) {
|
||||||
|
outMask |= KeyModifierControl | KeyModifierAlt;
|
||||||
|
}
|
||||||
|
|
||||||
// extract extended key flag
|
// extract extended key flag
|
||||||
const bool isExtended = ((virtualKey & 0x100) != 0);
|
const bool isExtended = ((virtualKey & 0x100) != 0);
|
||||||
virtualKey &= ~0x100;
|
virtualKey &= ~0x100;
|
||||||
|
|
|
@ -38,14 +38,15 @@ CUnixPlatform::~CUnixPlatform()
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
CUnixPlatform::installDaemon(const char*, const char*, const char*, const char*)
|
CUnixPlatform::installDaemon(const char*, const char*,
|
||||||
|
const char*, const char*, bool)
|
||||||
{
|
{
|
||||||
// daemons don't require special installation
|
// daemons don't require special installation
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
CUnixPlatform::EResult
|
CUnixPlatform::EResult
|
||||||
CUnixPlatform::uninstallDaemon(const char*)
|
CUnixPlatform::uninstallDaemon(const char*, bool)
|
||||||
{
|
{
|
||||||
// daemons don't require special installation
|
// daemons don't require special installation
|
||||||
return kSuccess;
|
return kSuccess;
|
||||||
|
@ -106,6 +107,18 @@ CUnixPlatform::installDaemonLogger(const char* name)
|
||||||
CLog::setOutputter(&CUnixPlatform::deamonLogger);
|
CLog::setOutputter(&CUnixPlatform::deamonLogger);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
CUnixPlatform::canInstallDaemon(const char*, bool) const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
CUnixPlatform::isDaemonInstalled(const char*, bool) const
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
const char*
|
const char*
|
||||||
CUnixPlatform::getBasename(const char* pathname) const
|
CUnixPlatform::getBasename(const char* pathname) const
|
||||||
{
|
{
|
||||||
|
|
|
@ -27,10 +27,15 @@ public:
|
||||||
virtual bool installDaemon(const char* name,
|
virtual bool installDaemon(const char* name,
|
||||||
const char* description,
|
const char* description,
|
||||||
const char* pathname,
|
const char* pathname,
|
||||||
const char* commandLine);
|
const char* commandLine,
|
||||||
virtual EResult uninstallDaemon(const char* name);
|
bool allUsers);
|
||||||
|
virtual EResult uninstallDaemon(const char* name, bool allUsers);
|
||||||
virtual int daemonize(const char* name, DaemonFunc);
|
virtual int daemonize(const char* name, DaemonFunc);
|
||||||
virtual void installDaemonLogger(const char* name);
|
virtual void installDaemonLogger(const char* name);
|
||||||
|
virtual bool canInstallDaemon(const char* name,
|
||||||
|
bool allUsers) const;
|
||||||
|
virtual bool isDaemonInstalled(const char* name,
|
||||||
|
bool allUsers) const;
|
||||||
virtual const char* getBasename(const char* pathname) const;
|
virtual const char* getBasename(const char* pathname) const;
|
||||||
virtual CString getUserDirectory() const;
|
virtual CString getUserDirectory() const;
|
||||||
virtual CString getSystemDirectory() const;
|
virtual CString getSystemDirectory() const;
|
||||||
|
|
|
@ -94,14 +94,16 @@ CWin32Platform::setStatusError(SERVICE_STATUS_HANDLE handle, DWORD error)
|
||||||
|
|
||||||
bool
|
bool
|
||||||
CWin32Platform::installDaemon(const char* name, const char* description,
|
CWin32Platform::installDaemon(const char* name, const char* description,
|
||||||
const char* pathname, const char* commandLine)
|
const char* pathname, const char* commandLine, bool allUsers)
|
||||||
{
|
{
|
||||||
// windows 95 family services
|
// if not for all users then use the user's autostart registry.
|
||||||
if (isWindows95Family()) {
|
// key. if windows 95 family then use windows 95 services key.
|
||||||
|
if (!allUsers || isWindows95Family()) {
|
||||||
// open registry
|
// open registry
|
||||||
HKEY key = open95ServicesKey();
|
HKEY key = isWindows95Family() ? open95ServicesKey() :
|
||||||
|
openUserStartupKey();
|
||||||
if (key == NULL) {
|
if (key == NULL) {
|
||||||
log((CLOG_ERR "cannot open RunServices registry key", GetLastError()));
|
log((CLOG_ERR "cannot open registry key", GetLastError()));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -152,6 +154,8 @@ CWin32Platform::installDaemon(const char* name, const char* description,
|
||||||
CloseServiceHandle(mgr);
|
CloseServiceHandle(mgr);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
// FIXME -- handle ERROR_SERVICE_EXISTS
|
||||||
|
|
||||||
log((CLOG_ERR "CreateService failed with %d", GetLastError()));
|
log((CLOG_ERR "CreateService failed with %d", GetLastError()));
|
||||||
CloseServiceHandle(mgr);
|
CloseServiceHandle(mgr);
|
||||||
return false;
|
return false;
|
||||||
|
@ -162,7 +166,7 @@ CWin32Platform::installDaemon(const char* name, const char* description,
|
||||||
key = openKey(key, name);
|
key = openKey(key, name);
|
||||||
if (key == NULL) {
|
if (key == NULL) {
|
||||||
// can't open key
|
// can't open key
|
||||||
uninstallDaemon(name);
|
uninstallDaemon(name, allUsers);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,7 +177,7 @@ CWin32Platform::installDaemon(const char* name, const char* description,
|
||||||
key = openKey(key, "Parameters");
|
key = openKey(key, "Parameters");
|
||||||
if (key == NULL) {
|
if (key == NULL) {
|
||||||
// can't open key
|
// can't open key
|
||||||
uninstallDaemon(name);
|
uninstallDaemon(name, allUsers);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
setValue(key, "CommandLine", commandLine);
|
setValue(key, "CommandLine", commandLine);
|
||||||
|
@ -186,14 +190,16 @@ CWin32Platform::installDaemon(const char* name, const char* description,
|
||||||
}
|
}
|
||||||
|
|
||||||
IPlatform::EResult
|
IPlatform::EResult
|
||||||
CWin32Platform::uninstallDaemon(const char* name)
|
CWin32Platform::uninstallDaemon(const char* name, bool allUsers)
|
||||||
{
|
{
|
||||||
// windows 95 family services
|
// if not for all users then use the user's autostart registry.
|
||||||
if (isWindows95Family()) {
|
// key. if windows 95 family then use windows 95 services key.
|
||||||
|
if (!allUsers || isWindows95Family()) {
|
||||||
// open registry
|
// open registry
|
||||||
HKEY key = open95ServicesKey();
|
HKEY key = isWindows95Family() ? open95ServicesKey() :
|
||||||
|
openUserStartupKey();
|
||||||
if (key == NULL) {
|
if (key == NULL) {
|
||||||
log((CLOG_ERR "cannot open RunServices registry key", GetLastError()));
|
log((CLOG_ERR "cannot open registry key", GetLastError()));
|
||||||
return kAlready;
|
return kAlready;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -334,6 +340,91 @@ CWin32Platform::installDaemonLogger(const char* name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
CWin32Platform::canInstallDaemon(const char* name, bool allUsers) const
|
||||||
|
{
|
||||||
|
// if not for all users then use the user's autostart registry.
|
||||||
|
// key. if windows 95 family then use windows 95 services key.
|
||||||
|
if (!allUsers || isWindows95Family()) {
|
||||||
|
// check if we can open the registry key
|
||||||
|
HKEY key = isWindows95Family() ? open95ServicesKey() :
|
||||||
|
openUserStartupKey();
|
||||||
|
closeKey(key);
|
||||||
|
return (key != NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
// windows NT family services
|
||||||
|
else {
|
||||||
|
// check if we can open service manager for write
|
||||||
|
SC_HANDLE mgr = OpenSCManager(NULL, NULL, GENERIC_WRITE);
|
||||||
|
if (mgr == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
CloseServiceHandle(mgr);
|
||||||
|
|
||||||
|
// check if we can open the registry key for this service
|
||||||
|
HKEY key = openNTServicesKey();
|
||||||
|
key = openKey(key, name);
|
||||||
|
key = openKey(key, "Parameters");
|
||||||
|
closeKey(key);
|
||||||
|
|
||||||
|
return (key != NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
CWin32Platform::isDaemonInstalled(const char* name, bool allUsers) const
|
||||||
|
{
|
||||||
|
// if not for all users then use the user's autostart registry.
|
||||||
|
// key. if windows 95 family then use windows 95 services key.
|
||||||
|
if (!allUsers || isWindows95Family()) {
|
||||||
|
// check if we can open the registry key
|
||||||
|
HKEY key = isWindows95Family() ? open95ServicesKey() :
|
||||||
|
openUserStartupKey();
|
||||||
|
if (key == NULL) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check for entry
|
||||||
|
const bool installed = !readValueString(key, name).empty();
|
||||||
|
|
||||||
|
// clean up
|
||||||
|
closeKey(key);
|
||||||
|
|
||||||
|
return installed;
|
||||||
|
}
|
||||||
|
|
||||||
|
// windows NT family services
|
||||||
|
else {
|
||||||
|
// check parameters for this service
|
||||||
|
HKEY key = openNTServicesKey();
|
||||||
|
key = openKey(key, name);
|
||||||
|
key = openKey(key, "Parameters");
|
||||||
|
if (key != NULL) {
|
||||||
|
const bool installed = !readValueString(key, "CommandLine").empty();
|
||||||
|
closeKey(key);
|
||||||
|
if (!installed) {
|
||||||
|
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, GENERIC_READ);
|
||||||
|
|
||||||
|
// clean up
|
||||||
|
CloseServiceHandle(service);
|
||||||
|
CloseServiceHandle(mgr);
|
||||||
|
|
||||||
|
return (service != NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const char*
|
const char*
|
||||||
CWin32Platform::getBasename(const char* pathname) const
|
CWin32Platform::getBasename(const char* pathname) const
|
||||||
{
|
{
|
||||||
|
@ -436,6 +527,11 @@ CWin32Platform::addPathComponent(const CString& prefix,
|
||||||
HKEY
|
HKEY
|
||||||
CWin32Platform::openKey(HKEY key, const char* keyName)
|
CWin32Platform::openKey(HKEY key, const char* keyName)
|
||||||
{
|
{
|
||||||
|
// ignore if parent is NULL
|
||||||
|
if (key == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
// open next key
|
// open next key
|
||||||
HKEY newKey;
|
HKEY newKey;
|
||||||
LONG result = RegOpenKeyEx(key, keyName, 0,
|
LONG result = RegOpenKeyEx(key, keyName, 0,
|
||||||
|
@ -555,6 +651,21 @@ CWin32Platform::open95ServicesKey()
|
||||||
return openKey(HKEY_LOCAL_MACHINE, s_keyNames);
|
return openKey(HKEY_LOCAL_MACHINE, s_keyNames);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HKEY
|
||||||
|
CWin32Platform::openUserStartupKey()
|
||||||
|
{
|
||||||
|
static const char* s_keyNames[] = {
|
||||||
|
_T("Software"),
|
||||||
|
_T("Microsoft"),
|
||||||
|
_T("Windows"),
|
||||||
|
_T("CurrentVersion"),
|
||||||
|
_T("Run"),
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
return openKey(HKEY_CURRENT_USER, s_keyNames);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
CWin32Platform::runDaemon(RunFunc run, StopFunc stop)
|
CWin32Platform::runDaemon(RunFunc run, StopFunc stop)
|
||||||
{
|
{
|
||||||
|
|
|
@ -71,10 +71,15 @@ public:
|
||||||
virtual bool installDaemon(const char* name,
|
virtual bool installDaemon(const char* name,
|
||||||
const char* description,
|
const char* description,
|
||||||
const char* pathname,
|
const char* pathname,
|
||||||
const char* commandLine);
|
const char* commandLine,
|
||||||
virtual EResult uninstallDaemon(const char* name);
|
bool allUsers);
|
||||||
|
virtual EResult uninstallDaemon(const char* name, bool allUsers);
|
||||||
virtual int daemonize(const char* name, DaemonFunc);
|
virtual int daemonize(const char* name, DaemonFunc);
|
||||||
virtual void installDaemonLogger(const char* name);
|
virtual void installDaemonLogger(const char* name);
|
||||||
|
virtual bool canInstallDaemon(const char* name,
|
||||||
|
bool allUsers) const;
|
||||||
|
virtual bool isDaemonInstalled(const char* name,
|
||||||
|
bool allUsers) const;
|
||||||
virtual const char* getBasename(const char* pathname) const;
|
virtual const char* getBasename(const char* pathname) const;
|
||||||
virtual CString getUserDirectory() const;
|
virtual CString getUserDirectory() const;
|
||||||
virtual CString getSystemDirectory() const;
|
virtual CString getSystemDirectory() const;
|
||||||
|
@ -93,6 +98,7 @@ private:
|
||||||
static CString readValueString(HKEY, const char* name);
|
static CString readValueString(HKEY, const char* name);
|
||||||
static HKEY openNTServicesKey();
|
static HKEY openNTServicesKey();
|
||||||
static HKEY open95ServicesKey();
|
static HKEY open95ServicesKey();
|
||||||
|
static HKEY openUserStartupKey();
|
||||||
|
|
||||||
void serviceMain(DWORD, LPTSTR*);
|
void serviceMain(DWORD, LPTSTR*);
|
||||||
static void WINAPI serviceMainEntry(DWORD, LPTSTR*);
|
static void WINAPI serviceMainEntry(DWORD, LPTSTR*);
|
||||||
|
|
|
@ -43,18 +43,22 @@ public:
|
||||||
system and \c description is a short human readable description of
|
system and \c description is a short human readable description of
|
||||||
the daemon. \c pathname is the path to the daemon executable.
|
the daemon. \c pathname is the path to the daemon executable.
|
||||||
\c commandLine should \b not include the name of program as the
|
\c commandLine should \b not include the name of program as the
|
||||||
first argument.
|
first argument. If \c allUsers is true then the daemon will be
|
||||||
|
installed to start at boot time, otherwise it will be installed to
|
||||||
|
start when the current user logs in.
|
||||||
*/
|
*/
|
||||||
// FIXME -- throw on error? will get better error messages that way.
|
// FIXME -- throw on error? will get better error messages that way.
|
||||||
virtual bool installDaemon(const char* name,
|
virtual bool installDaemon(const char* name,
|
||||||
const char* description,
|
const char* description,
|
||||||
const char* pathname,
|
const char* pathname,
|
||||||
const char* commandLine) = 0;
|
const char* commandLine,
|
||||||
|
bool allUsers) = 0;
|
||||||
|
|
||||||
//! Uninstall daemon
|
//! Uninstall daemon
|
||||||
/*!
|
/*!
|
||||||
Uninstall a daemon.
|
Uninstall a daemon.
|
||||||
*/
|
*/
|
||||||
virtual EResult uninstallDaemon(const char* name) = 0;
|
virtual EResult uninstallDaemon(const char* name, bool allUsers) = 0;
|
||||||
|
|
||||||
//! Daemonize the process
|
//! Daemonize the process
|
||||||
/*!
|
/*!
|
||||||
|
@ -91,6 +95,24 @@ public:
|
||||||
//! @name accessors
|
//! @name accessors
|
||||||
//@{
|
//@{
|
||||||
|
|
||||||
|
//! Check if user has permission to install the daemon
|
||||||
|
/*!
|
||||||
|
Returns true iff the caller has permission to install or
|
||||||
|
uninstall the daemon. Note that even if this method returns
|
||||||
|
true it's possible that installing/uninstalling the service
|
||||||
|
may still fail. This method ignores whether or not the
|
||||||
|
service is already installed.
|
||||||
|
*/
|
||||||
|
virtual bool canInstallDaemon(const char* name,
|
||||||
|
bool allUsers) const = 0;
|
||||||
|
|
||||||
|
//! Check if the daemon is installed
|
||||||
|
/*!
|
||||||
|
Returns true iff the daemon is installed.
|
||||||
|
*/
|
||||||
|
virtual bool isDaemonInstalled(const char* name,
|
||||||
|
bool allUsers) const = 0;
|
||||||
|
|
||||||
//! Extract base name
|
//! Extract base name
|
||||||
/*!
|
/*!
|
||||||
Find the base name in the given \c pathname.
|
Find the base name in the given \c pathname.
|
||||||
|
|
|
@ -614,264 +614,266 @@ CMSWindowsPrimaryScreen::ignore() const
|
||||||
return (m_mark != m_markReceived);
|
return (m_mark != m_markReceived);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const KeyID g_virtualKey[] =
|
// map virtual keys to synergy key enumeration. use extended keyboard
|
||||||
|
// bit to distinguish some keys.
|
||||||
|
static const KeyID g_virtualKey[][2] =
|
||||||
{
|
{
|
||||||
/* 0x00 */ kKeyNone, // reserved
|
/* 0x00 */ kKeyNone, kKeyNone, // reserved
|
||||||
/* 0x01 */ kKeyNone, // VK_LBUTTON
|
/* 0x01 */ kKeyNone, kKeyNone, // VK_LBUTTON
|
||||||
/* 0x02 */ kKeyNone, // VK_RBUTTON
|
/* 0x02 */ kKeyNone, kKeyNone, // VK_RBUTTON
|
||||||
/* 0x03 */ kKeyBreak, // VK_CANCEL
|
/* 0x03 */ kKeyNone, kKeyBreak, // VK_CANCEL
|
||||||
/* 0x04 */ kKeyNone, // VK_MBUTTON
|
/* 0x04 */ kKeyNone, kKeyNone, // VK_MBUTTON
|
||||||
/* 0x05 */ kKeyNone, // undefined
|
/* 0x05 */ kKeyNone, kKeyNone, // undefined
|
||||||
/* 0x06 */ kKeyNone, // undefined
|
/* 0x06 */ kKeyNone, kKeyNone, // undefined
|
||||||
/* 0x07 */ kKeyNone, // undefined
|
/* 0x07 */ kKeyNone, kKeyNone, // undefined
|
||||||
/* 0x08 */ kKeyBackSpace, // VK_BACK
|
/* 0x08 */ kKeyBackSpace, kKeyNone, // VK_BACK
|
||||||
/* 0x09 */ kKeyTab, // VK_TAB
|
/* 0x09 */ kKeyTab, kKeyNone, // VK_TAB
|
||||||
/* 0x0a */ kKeyNone, // undefined
|
/* 0x0a */ kKeyNone, kKeyNone, // undefined
|
||||||
/* 0x0b */ kKeyNone, // undefined
|
/* 0x0b */ kKeyNone, kKeyNone, // undefined
|
||||||
/* 0x0c */ kKeyClear, // VK_CLEAR
|
/* 0x0c */ kKeyClear, kKeyClear, // VK_CLEAR
|
||||||
/* 0x0d */ kKeyReturn, // VK_RETURN
|
/* 0x0d */ kKeyReturn, kKeyKP_Enter, // VK_RETURN
|
||||||
/* 0x0e */ kKeyNone, // undefined
|
/* 0x0e */ kKeyNone, kKeyNone, // undefined
|
||||||
/* 0x0f */ kKeyNone, // undefined
|
/* 0x0f */ kKeyNone, kKeyNone, // undefined
|
||||||
/* 0x10 */ kKeyShift_L, // VK_SHIFT
|
/* 0x10 */ kKeyShift_L, kKeyShift_R, // VK_SHIFT
|
||||||
/* 0x11 */ kKeyControl_L, // VK_CONTROL
|
/* 0x11 */ kKeyControl_L, kKeyControl_R, // VK_CONTROL
|
||||||
/* 0x12 */ kKeyAlt_L, // VK_MENU
|
/* 0x12 */ kKeyAlt_L, kKeyAlt_R, // VK_MENU
|
||||||
/* 0x13 */ kKeyPause, // VK_PAUSE
|
/* 0x13 */ kKeyPause, kKeyNone, // VK_PAUSE
|
||||||
/* 0x14 */ kKeyCapsLock, // VK_CAPITAL
|
/* 0x14 */ kKeyCapsLock, kKeyNone, // VK_CAPITAL
|
||||||
/* 0x15 */ kKeyNone, // VK_KANA
|
/* 0x15 */ kKeyNone, kKeyNone, // VK_KANA
|
||||||
/* 0x16 */ kKeyNone, // VK_HANGUL
|
/* 0x16 */ kKeyNone, kKeyNone, // VK_HANGUL
|
||||||
/* 0x17 */ kKeyNone, // VK_JUNJA
|
/* 0x17 */ kKeyNone, kKeyNone, // VK_JUNJA
|
||||||
/* 0x18 */ kKeyNone, // VK_FINAL
|
/* 0x18 */ kKeyNone, kKeyNone, // VK_FINAL
|
||||||
/* 0x19 */ kKeyNone, // VK_KANJI
|
/* 0x19 */ kKeyNone, kKeyNone, // VK_KANJI
|
||||||
/* 0x1a */ kKeyNone, // undefined
|
/* 0x1a */ kKeyNone, kKeyNone, // undefined
|
||||||
/* 0x1b */ kKeyEscape, // VK_ESCAPE
|
/* 0x1b */ kKeyEscape, kKeyNone, // VK_ESCAPE
|
||||||
/* 0x1c */ kKeyNone, // VK_CONVERT
|
/* 0x1c */ kKeyNone, kKeyNone, // VK_CONVERT
|
||||||
/* 0x1d */ kKeyNone, // VK_NONCONVERT
|
/* 0x1d */ kKeyNone, kKeyNone, // VK_NONCONVERT
|
||||||
/* 0x1e */ kKeyNone, // VK_ACCEPT
|
/* 0x1e */ kKeyNone, kKeyNone, // VK_ACCEPT
|
||||||
/* 0x1f */ kKeyNone, // VK_MODECHANGE
|
/* 0x1f */ kKeyNone, kKeyNone, // VK_MODECHANGE
|
||||||
/* 0x20 */ 0x0020, // VK_SPACE
|
/* 0x20 */ 0x0020, kKeyNone, // VK_SPACE
|
||||||
/* 0x21 */ kKeyPageUp, // VK_PRIOR
|
/* 0x21 */ kKeyKP_PageUp, kKeyPageUp, // VK_PRIOR
|
||||||
/* 0x22 */ kKeyPageDown, // VK_NEXT
|
/* 0x22 */ kKeyKP_PageDown, kKeyPageDown, // VK_NEXT
|
||||||
/* 0x23 */ kKeyEnd, // VK_END
|
/* 0x23 */ kKeyKP_End, kKeyEnd, // VK_END
|
||||||
/* 0x24 */ kKeyHome, // VK_HOME
|
/* 0x24 */ kKeyKP_Home, kKeyHome, // VK_HOME
|
||||||
/* 0x25 */ kKeyLeft, // VK_LEFT
|
/* 0x25 */ kKeyKP_Left, kKeyLeft, // VK_LEFT
|
||||||
/* 0x26 */ kKeyUp, // VK_UP
|
/* 0x26 */ kKeyKP_Up, kKeyUp, // VK_UP
|
||||||
/* 0x27 */ kKeyRight, // VK_RIGHT
|
/* 0x27 */ kKeyKP_Right, kKeyRight, // VK_RIGHT
|
||||||
/* 0x28 */ kKeyDown, // VK_DOWN
|
/* 0x28 */ kKeyKP_Down, kKeyDown, // VK_DOWN
|
||||||
/* 0x29 */ kKeySelect, // VK_SELECT
|
/* 0x29 */ kKeySelect, kKeySelect, // VK_SELECT
|
||||||
/* 0x2a */ kKeyNone, // VK_PRINT
|
/* 0x2a */ kKeyNone, kKeyNone, // VK_PRINT
|
||||||
/* 0x2b */ kKeyExecute, // VK_EXECUTE
|
/* 0x2b */ kKeyExecute, kKeyExecute, // VK_EXECUTE
|
||||||
/* 0x2c */ kKeyPrint, // VK_SNAPSHOT
|
/* 0x2c */ kKeyPrint, kKeyPrint, // VK_SNAPSHOT
|
||||||
/* 0x2d */ kKeyInsert, // VK_INSERT
|
/* 0x2d */ kKeyKP_Insert, kKeyInsert, // VK_INSERT
|
||||||
/* 0x2e */ kKeyDelete, // VK_DELETE
|
/* 0x2e */ kKeyKP_Delete, kKeyDelete, // VK_DELETE
|
||||||
/* 0x2f */ kKeyHelp, // VK_HELP
|
/* 0x2f */ kKeyHelp, kKeyHelp, // VK_HELP
|
||||||
/* 0x30 */ kKeyNone, // VK_0
|
/* 0x30 */ kKeyNone, kKeyNone, // VK_0
|
||||||
/* 0x31 */ kKeyNone, // VK_1
|
/* 0x31 */ kKeyNone, kKeyNone, // VK_1
|
||||||
/* 0x32 */ kKeyNone, // VK_2
|
/* 0x32 */ kKeyNone, kKeyNone, // VK_2
|
||||||
/* 0x33 */ kKeyNone, // VK_3
|
/* 0x33 */ kKeyNone, kKeyNone, // VK_3
|
||||||
/* 0x34 */ kKeyNone, // VK_4
|
/* 0x34 */ kKeyNone, kKeyNone, // VK_4
|
||||||
/* 0x35 */ kKeyNone, // VK_5
|
/* 0x35 */ kKeyNone, kKeyNone, // VK_5
|
||||||
/* 0x36 */ kKeyNone, // VK_6
|
/* 0x36 */ kKeyNone, kKeyNone, // VK_6
|
||||||
/* 0x37 */ kKeyNone, // VK_7
|
/* 0x37 */ kKeyNone, kKeyNone, // VK_7
|
||||||
/* 0x38 */ kKeyNone, // VK_8
|
/* 0x38 */ kKeyNone, kKeyNone, // VK_8
|
||||||
/* 0x39 */ kKeyNone, // VK_9
|
/* 0x39 */ kKeyNone, kKeyNone, // VK_9
|
||||||
/* 0x3a */ kKeyNone, // undefined
|
/* 0x3a */ kKeyNone, kKeyNone, // undefined
|
||||||
/* 0x3b */ kKeyNone, // undefined
|
/* 0x3b */ kKeyNone, kKeyNone, // undefined
|
||||||
/* 0x3c */ kKeyNone, // undefined
|
/* 0x3c */ kKeyNone, kKeyNone, // undefined
|
||||||
/* 0x3d */ kKeyNone, // undefined
|
/* 0x3d */ kKeyNone, kKeyNone, // undefined
|
||||||
/* 0x3e */ kKeyNone, // undefined
|
/* 0x3e */ kKeyNone, kKeyNone, // undefined
|
||||||
/* 0x3f */ kKeyNone, // undefined
|
/* 0x3f */ kKeyNone, kKeyNone, // undefined
|
||||||
/* 0x40 */ kKeyNone, // undefined
|
/* 0x40 */ kKeyNone, kKeyNone, // undefined
|
||||||
/* 0x41 */ kKeyNone, // VK_A
|
/* 0x41 */ kKeyNone, kKeyNone, // VK_A
|
||||||
/* 0x42 */ kKeyNone, // VK_B
|
/* 0x42 */ kKeyNone, kKeyNone, // VK_B
|
||||||
/* 0x43 */ kKeyNone, // VK_C
|
/* 0x43 */ kKeyNone, kKeyNone, // VK_C
|
||||||
/* 0x44 */ kKeyNone, // VK_D
|
/* 0x44 */ kKeyNone, kKeyNone, // VK_D
|
||||||
/* 0x45 */ kKeyNone, // VK_E
|
/* 0x45 */ kKeyNone, kKeyNone, // VK_E
|
||||||
/* 0x46 */ kKeyNone, // VK_F
|
/* 0x46 */ kKeyNone, kKeyNone, // VK_F
|
||||||
/* 0x47 */ kKeyNone, // VK_G
|
/* 0x47 */ kKeyNone, kKeyNone, // VK_G
|
||||||
/* 0x48 */ kKeyNone, // VK_H
|
/* 0x48 */ kKeyNone, kKeyNone, // VK_H
|
||||||
/* 0x49 */ kKeyNone, // VK_I
|
/* 0x49 */ kKeyNone, kKeyNone, // VK_I
|
||||||
/* 0x4a */ kKeyNone, // VK_J
|
/* 0x4a */ kKeyNone, kKeyNone, // VK_J
|
||||||
/* 0x4b */ kKeyNone, // VK_K
|
/* 0x4b */ kKeyNone, kKeyNone, // VK_K
|
||||||
/* 0x4c */ kKeyNone, // VK_L
|
/* 0x4c */ kKeyNone, kKeyNone, // VK_L
|
||||||
/* 0x4d */ kKeyNone, // VK_M
|
/* 0x4d */ kKeyNone, kKeyNone, // VK_M
|
||||||
/* 0x4e */ kKeyNone, // VK_N
|
/* 0x4e */ kKeyNone, kKeyNone, // VK_N
|
||||||
/* 0x4f */ kKeyNone, // VK_O
|
/* 0x4f */ kKeyNone, kKeyNone, // VK_O
|
||||||
/* 0x50 */ kKeyNone, // VK_P
|
/* 0x50 */ kKeyNone, kKeyNone, // VK_P
|
||||||
/* 0x51 */ kKeyNone, // VK_Q
|
/* 0x51 */ kKeyNone, kKeyNone, // VK_Q
|
||||||
/* 0x52 */ kKeyNone, // VK_R
|
/* 0x52 */ kKeyNone, kKeyNone, // VK_R
|
||||||
/* 0x53 */ kKeyNone, // VK_S
|
/* 0x53 */ kKeyNone, kKeyNone, // VK_S
|
||||||
/* 0x54 */ kKeyNone, // VK_T
|
/* 0x54 */ kKeyNone, kKeyNone, // VK_T
|
||||||
/* 0x55 */ kKeyNone, // VK_U
|
/* 0x55 */ kKeyNone, kKeyNone, // VK_U
|
||||||
/* 0x56 */ kKeyNone, // VK_V
|
/* 0x56 */ kKeyNone, kKeyNone, // VK_V
|
||||||
/* 0x57 */ kKeyNone, // VK_W
|
/* 0x57 */ kKeyNone, kKeyNone, // VK_W
|
||||||
/* 0x58 */ kKeyNone, // VK_X
|
/* 0x58 */ kKeyNone, kKeyNone, // VK_X
|
||||||
/* 0x59 */ kKeyNone, // VK_Y
|
/* 0x59 */ kKeyNone, kKeyNone, // VK_Y
|
||||||
/* 0x5a */ kKeyNone, // VK_Z
|
/* 0x5a */ kKeyNone, kKeyNone, // VK_Z
|
||||||
/* 0x5b */ kKeyMeta_L, // VK_LWIN
|
/* 0x5b */ kKeyNone, kKeyMeta_L, // VK_LWIN
|
||||||
/* 0x5c */ kKeyMeta_R, // VK_RWIN
|
/* 0x5c */ kKeyNone, kKeyMeta_R, // VK_RWIN
|
||||||
/* 0x5d */ kKeyMenu, // VK_APPS
|
/* 0x5d */ kKeyMenu, kKeyMenu, // VK_APPS
|
||||||
/* 0x5e */ kKeyNone, // undefined
|
/* 0x5e */ kKeyNone, kKeyNone, // undefined
|
||||||
/* 0x5f */ kKeyNone, // undefined
|
/* 0x5f */ kKeyNone, kKeyNone, // undefined
|
||||||
/* 0x60 */ kKeyKP_0, // VK_NUMPAD0
|
/* 0x60 */ kKeyKP_0, kKeyNone, // VK_NUMPAD0
|
||||||
/* 0x61 */ kKeyKP_1, // VK_NUMPAD1
|
/* 0x61 */ kKeyKP_1, kKeyNone, // VK_NUMPAD1
|
||||||
/* 0x62 */ kKeyKP_2, // VK_NUMPAD2
|
/* 0x62 */ kKeyKP_2, kKeyNone, // VK_NUMPAD2
|
||||||
/* 0x63 */ kKeyKP_3, // VK_NUMPAD3
|
/* 0x63 */ kKeyKP_3, kKeyNone, // VK_NUMPAD3
|
||||||
/* 0x64 */ kKeyKP_4, // VK_NUMPAD4
|
/* 0x64 */ kKeyKP_4, kKeyNone, // VK_NUMPAD4
|
||||||
/* 0x65 */ kKeyKP_5, // VK_NUMPAD5
|
/* 0x65 */ kKeyKP_5, kKeyNone, // VK_NUMPAD5
|
||||||
/* 0x66 */ kKeyKP_6, // VK_NUMPAD6
|
/* 0x66 */ kKeyKP_6, kKeyNone, // VK_NUMPAD6
|
||||||
/* 0x67 */ kKeyKP_7, // VK_NUMPAD7
|
/* 0x67 */ kKeyKP_7, kKeyNone, // VK_NUMPAD7
|
||||||
/* 0x68 */ kKeyKP_8, // VK_NUMPAD8
|
/* 0x68 */ kKeyKP_8, kKeyNone, // VK_NUMPAD8
|
||||||
/* 0x69 */ kKeyKP_9, // VK_NUMPAD9
|
/* 0x69 */ kKeyKP_9, kKeyNone, // VK_NUMPAD9
|
||||||
/* 0x6a */ kKeyKP_Multiply, // VK_MULTIPLY
|
/* 0x6a */ kKeyKP_Multiply, kKeyNone, // VK_MULTIPLY
|
||||||
/* 0x6b */ kKeyKP_Add, // VK_ADD
|
/* 0x6b */ kKeyKP_Add, kKeyNone, // VK_ADD
|
||||||
/* 0x6c */ kKeyKP_Separator,// VK_SEPARATOR
|
/* 0x6c */ kKeyKP_Separator,kKeyKP_Separator,// VK_SEPARATOR
|
||||||
/* 0x6d */ kKeyKP_Subtract, // VK_SUBTRACT
|
/* 0x6d */ kKeyKP_Subtract, kKeyNone, // VK_SUBTRACT
|
||||||
/* 0x6e */ kKeyKP_Decimal, // VK_DECIMAL
|
/* 0x6e */ kKeyKP_Decimal, kKeyNone, // VK_DECIMAL
|
||||||
/* 0x6f */ kKeyKP_Divide, // VK_DIVIDE
|
/* 0x6f */ kKeyNone, kKeyKP_Divide, // VK_DIVIDE
|
||||||
/* 0x70 */ kKeyF1, // VK_F1
|
/* 0x70 */ kKeyF1, kKeyNone, // VK_F1
|
||||||
/* 0x71 */ kKeyF2, // VK_F2
|
/* 0x71 */ kKeyF2, kKeyNone, // VK_F2
|
||||||
/* 0x72 */ kKeyF3, // VK_F3
|
/* 0x72 */ kKeyF3, kKeyNone, // VK_F3
|
||||||
/* 0x73 */ kKeyF4, // VK_F4
|
/* 0x73 */ kKeyF4, kKeyNone, // VK_F4
|
||||||
/* 0x74 */ kKeyF5, // VK_F5
|
/* 0x74 */ kKeyF5, kKeyNone, // VK_F5
|
||||||
/* 0x75 */ kKeyF6, // VK_F6
|
/* 0x75 */ kKeyF6, kKeyNone, // VK_F6
|
||||||
/* 0x76 */ kKeyF7, // VK_F7
|
/* 0x76 */ kKeyF7, kKeyNone, // VK_F7
|
||||||
/* 0x77 */ kKeyF8, // VK_F8
|
/* 0x77 */ kKeyF8, kKeyNone, // VK_F8
|
||||||
/* 0x78 */ kKeyF9, // VK_F9
|
/* 0x78 */ kKeyF9, kKeyNone, // VK_F9
|
||||||
/* 0x79 */ kKeyF10, // VK_F10
|
/* 0x79 */ kKeyF10, kKeyNone, // VK_F10
|
||||||
/* 0x7a */ kKeyF11, // VK_F11
|
/* 0x7a */ kKeyF11, kKeyNone, // VK_F11
|
||||||
/* 0x7b */ kKeyF12, // VK_F12
|
/* 0x7b */ kKeyF12, kKeyNone, // VK_F12
|
||||||
/* 0x7c */ kKeyF13, // VK_F13
|
/* 0x7c */ kKeyF13, kKeyF13, // VK_F13
|
||||||
/* 0x7d */ kKeyF14, // VK_F14
|
/* 0x7d */ kKeyF14, kKeyF14, // VK_F14
|
||||||
/* 0x7e */ kKeyF15, // VK_F15
|
/* 0x7e */ kKeyF15, kKeyF15, // VK_F15
|
||||||
/* 0x7f */ kKeyF16, // VK_F16
|
/* 0x7f */ kKeyF16, kKeyF16, // VK_F16
|
||||||
/* 0x80 */ kKeyF17, // VK_F17
|
/* 0x80 */ kKeyF17, kKeyF17, // VK_F17
|
||||||
/* 0x81 */ kKeyF18, // VK_F18
|
/* 0x81 */ kKeyF18, kKeyF18, // VK_F18
|
||||||
/* 0x82 */ kKeyF19, // VK_F19
|
/* 0x82 */ kKeyF19, kKeyF19, // VK_F19
|
||||||
/* 0x83 */ kKeyF20, // VK_F20
|
/* 0x83 */ kKeyF20, kKeyF20, // VK_F20
|
||||||
/* 0x84 */ kKeyF21, // VK_F21
|
/* 0x84 */ kKeyF21, kKeyF21, // VK_F21
|
||||||
/* 0x85 */ kKeyF22, // VK_F22
|
/* 0x85 */ kKeyF22, kKeyF22, // VK_F22
|
||||||
/* 0x86 */ kKeyF23, // VK_F23
|
/* 0x86 */ kKeyF23, kKeyF23, // VK_F23
|
||||||
/* 0x87 */ kKeyF24, // VK_F24
|
/* 0x87 */ kKeyF24, kKeyF24, // VK_F24
|
||||||
/* 0x88 */ kKeyNone, // unassigned
|
/* 0x88 */ kKeyNone, kKeyNone, // unassigned
|
||||||
/* 0x89 */ kKeyNone, // unassigned
|
/* 0x89 */ kKeyNone, kKeyNone, // unassigned
|
||||||
/* 0x8a */ kKeyNone, // unassigned
|
/* 0x8a */ kKeyNone, kKeyNone, // unassigned
|
||||||
/* 0x8b */ kKeyNone, // unassigned
|
/* 0x8b */ kKeyNone, kKeyNone, // unassigned
|
||||||
/* 0x8c */ kKeyNone, // unassigned
|
/* 0x8c */ kKeyNone, kKeyNone, // unassigned
|
||||||
/* 0x8d */ kKeyNone, // unassigned
|
/* 0x8d */ kKeyNone, kKeyNone, // unassigned
|
||||||
/* 0x8e */ kKeyNone, // unassigned
|
/* 0x8e */ kKeyNone, kKeyNone, // unassigned
|
||||||
/* 0x8f */ kKeyNone, // unassigned
|
/* 0x8f */ kKeyNone, kKeyNone, // unassigned
|
||||||
/* 0x90 */ kKeyNumLock, // VK_NUMLOCK
|
/* 0x90 */ kKeyNumLock, kKeyNumLock, // VK_NUMLOCK
|
||||||
/* 0x91 */ kKeyScrollLock, // VK_SCROLL
|
/* 0x91 */ kKeyScrollLock, kKeyNone, // VK_SCROLL
|
||||||
/* 0x92 */ kKeyNone, // unassigned
|
/* 0x92 */ kKeyNone, kKeyNone, // unassigned
|
||||||
/* 0x93 */ kKeyNone, // unassigned
|
/* 0x93 */ kKeyNone, kKeyNone, // unassigned
|
||||||
/* 0x94 */ kKeyNone, // unassigned
|
/* 0x94 */ kKeyNone, kKeyNone, // unassigned
|
||||||
/* 0x95 */ kKeyNone, // unassigned
|
/* 0x95 */ kKeyNone, kKeyNone, // unassigned
|
||||||
/* 0x96 */ kKeyNone, // unassigned
|
/* 0x96 */ kKeyNone, kKeyNone, // unassigned
|
||||||
/* 0x97 */ kKeyNone, // unassigned
|
/* 0x97 */ kKeyNone, kKeyNone, // unassigned
|
||||||
/* 0x98 */ kKeyNone, // unassigned
|
/* 0x98 */ kKeyNone, kKeyNone, // unassigned
|
||||||
/* 0x99 */ kKeyNone, // unassigned
|
/* 0x99 */ kKeyNone, kKeyNone, // unassigned
|
||||||
/* 0x9a */ kKeyNone, // unassigned
|
/* 0x9a */ kKeyNone, kKeyNone, // unassigned
|
||||||
/* 0x9b */ kKeyNone, // unassigned
|
/* 0x9b */ kKeyNone, kKeyNone, // unassigned
|
||||||
/* 0x9c */ kKeyNone, // unassigned
|
/* 0x9c */ kKeyNone, kKeyNone, // unassigned
|
||||||
/* 0x9d */ kKeyNone, // unassigned
|
/* 0x9d */ kKeyNone, kKeyNone, // unassigned
|
||||||
/* 0x9e */ kKeyNone, // unassigned
|
/* 0x9e */ kKeyNone, kKeyNone, // unassigned
|
||||||
/* 0x9f */ kKeyNone, // unassigned
|
/* 0x9f */ kKeyNone, kKeyNone, // unassigned
|
||||||
/* 0xa0 */ kKeyShift_L, // VK_LSHIFT
|
/* 0xa0 */ kKeyShift_L, kKeyShift_L, // VK_LSHIFT
|
||||||
/* 0xa1 */ kKeyShift_R, // VK_RSHIFT
|
/* 0xa1 */ kKeyShift_R, kKeyShift_R, // VK_RSHIFT
|
||||||
/* 0xa2 */ kKeyControl_L, // VK_LCONTROL
|
/* 0xa2 */ kKeyControl_L, kKeyControl_L, // VK_LCONTROL
|
||||||
/* 0xa3 */ kKeyControl_R, // VK_RCONTROL
|
/* 0xa3 */ kKeyControl_R, kKeyControl_R, // VK_RCONTROL
|
||||||
/* 0xa4 */ kKeyAlt_L, // VK_LMENU
|
/* 0xa4 */ kKeyAlt_L, kKeyAlt_L, // VK_LMENU
|
||||||
/* 0xa5 */ kKeyAlt_R, // VK_RMENU
|
/* 0xa5 */ kKeyAlt_R, kKeyAlt_R, // VK_RMENU
|
||||||
/* 0xa6 */ kKeyNone, // unassigned
|
/* 0xa6 */ kKeyNone, kKeyNone, // unassigned
|
||||||
/* 0xa7 */ kKeyNone, // unassigned
|
/* 0xa7 */ kKeyNone, kKeyNone, // unassigned
|
||||||
/* 0xa8 */ kKeyNone, // unassigned
|
/* 0xa8 */ kKeyNone, kKeyNone, // unassigned
|
||||||
/* 0xa9 */ kKeyNone, // unassigned
|
/* 0xa9 */ kKeyNone, kKeyNone, // unassigned
|
||||||
/* 0xaa */ kKeyNone, // unassigned
|
/* 0xaa */ kKeyNone, kKeyNone, // unassigned
|
||||||
/* 0xab */ kKeyNone, // unassigned
|
/* 0xab */ kKeyNone, kKeyNone, // unassigned
|
||||||
/* 0xac */ kKeyNone, // unassigned
|
/* 0xac */ kKeyNone, kKeyNone, // unassigned
|
||||||
/* 0xad */ kKeyNone, // unassigned
|
/* 0xad */ kKeyNone, kKeyNone, // unassigned
|
||||||
/* 0xae */ kKeyNone, // unassigned
|
/* 0xae */ kKeyNone, kKeyNone, // unassigned
|
||||||
/* 0xaf */ kKeyNone, // unassigned
|
/* 0xaf */ kKeyNone, kKeyNone, // unassigned
|
||||||
/* 0xb0 */ kKeyNone, // unassigned
|
/* 0xb0 */ kKeyNone, kKeyNone, // unassigned
|
||||||
/* 0xb1 */ kKeyNone, // unassigned
|
/* 0xb1 */ kKeyNone, kKeyNone, // unassigned
|
||||||
/* 0xb2 */ kKeyNone, // unassigned
|
/* 0xb2 */ kKeyNone, kKeyNone, // unassigned
|
||||||
/* 0xb3 */ kKeyNone, // unassigned
|
/* 0xb3 */ kKeyNone, kKeyNone, // unassigned
|
||||||
/* 0xb4 */ kKeyNone, // unassigned
|
/* 0xb4 */ kKeyNone, kKeyNone, // unassigned
|
||||||
/* 0xb5 */ kKeyNone, // unassigned
|
/* 0xb5 */ kKeyNone, kKeyNone, // unassigned
|
||||||
/* 0xb6 */ kKeyNone, // unassigned
|
/* 0xb6 */ kKeyNone, kKeyNone, // unassigned
|
||||||
/* 0xb7 */ kKeyNone, // unassigned
|
/* 0xb7 */ kKeyNone, kKeyNone, // unassigned
|
||||||
/* 0xb8 */ kKeyNone, // unassigned
|
/* 0xb8 */ kKeyNone, kKeyNone, // unassigned
|
||||||
/* 0xb9 */ kKeyNone, // unassigned
|
/* 0xb9 */ kKeyNone, kKeyNone, // unassigned
|
||||||
/* 0xba */ kKeyNone, // OEM specific
|
/* 0xba */ kKeyNone, kKeyNone, // OEM specific
|
||||||
/* 0xbb */ kKeyNone, // OEM specific
|
/* 0xbb */ kKeyNone, kKeyNone, // OEM specific
|
||||||
/* 0xbc */ kKeyNone, // OEM specific
|
/* 0xbc */ kKeyNone, kKeyNone, // OEM specific
|
||||||
/* 0xbd */ kKeyNone, // OEM specific
|
/* 0xbd */ kKeyNone, kKeyNone, // OEM specific
|
||||||
/* 0xbe */ kKeyNone, // OEM specific
|
/* 0xbe */ kKeyNone, kKeyNone, // OEM specific
|
||||||
/* 0xbf */ kKeyNone, // OEM specific
|
/* 0xbf */ kKeyNone, kKeyNone, // OEM specific
|
||||||
/* 0xc0 */ kKeyNone, // OEM specific
|
/* 0xc0 */ kKeyNone, kKeyNone, // OEM specific
|
||||||
/* 0xc1 */ kKeyNone, // unassigned
|
/* 0xc1 */ kKeyNone, kKeyNone, // unassigned
|
||||||
/* 0xc2 */ kKeyNone, // unassigned
|
/* 0xc2 */ kKeyNone, kKeyNone, // unassigned
|
||||||
/* 0xc3 */ kKeyNone, // unassigned
|
/* 0xc3 */ kKeyNone, kKeyNone, // unassigned
|
||||||
/* 0xc4 */ kKeyNone, // unassigned
|
/* 0xc4 */ kKeyNone, kKeyNone, // unassigned
|
||||||
/* 0xc5 */ kKeyNone, // unassigned
|
/* 0xc5 */ kKeyNone, kKeyNone, // unassigned
|
||||||
/* 0xc6 */ kKeyNone, // unassigned
|
/* 0xc6 */ kKeyNone, kKeyNone, // unassigned
|
||||||
/* 0xc7 */ kKeyNone, // unassigned
|
/* 0xc7 */ kKeyNone, kKeyNone, // unassigned
|
||||||
/* 0xc8 */ kKeyNone, // unassigned
|
/* 0xc8 */ kKeyNone, kKeyNone, // unassigned
|
||||||
/* 0xc9 */ kKeyNone, // unassigned
|
/* 0xc9 */ kKeyNone, kKeyNone, // unassigned
|
||||||
/* 0xca */ kKeyNone, // unassigned
|
/* 0xca */ kKeyNone, kKeyNone, // unassigned
|
||||||
/* 0xcb */ kKeyNone, // unassigned
|
/* 0xcb */ kKeyNone, kKeyNone, // unassigned
|
||||||
/* 0xcc */ kKeyNone, // unassigned
|
/* 0xcc */ kKeyNone, kKeyNone, // unassigned
|
||||||
/* 0xcd */ kKeyNone, // unassigned
|
/* 0xcd */ kKeyNone, kKeyNone, // unassigned
|
||||||
/* 0xce */ kKeyNone, // unassigned
|
/* 0xce */ kKeyNone, kKeyNone, // unassigned
|
||||||
/* 0xcf */ kKeyNone, // unassigned
|
/* 0xcf */ kKeyNone, kKeyNone, // unassigned
|
||||||
/* 0xd0 */ kKeyNone, // unassigned
|
/* 0xd0 */ kKeyNone, kKeyNone, // unassigned
|
||||||
/* 0xd1 */ kKeyNone, // unassigned
|
/* 0xd1 */ kKeyNone, kKeyNone, // unassigned
|
||||||
/* 0xd2 */ kKeyNone, // unassigned
|
/* 0xd2 */ kKeyNone, kKeyNone, // unassigned
|
||||||
/* 0xd3 */ kKeyNone, // unassigned
|
/* 0xd3 */ kKeyNone, kKeyNone, // unassigned
|
||||||
/* 0xd4 */ kKeyNone, // unassigned
|
/* 0xd4 */ kKeyNone, kKeyNone, // unassigned
|
||||||
/* 0xd5 */ kKeyNone, // unassigned
|
/* 0xd5 */ kKeyNone, kKeyNone, // unassigned
|
||||||
/* 0xd6 */ kKeyNone, // unassigned
|
/* 0xd6 */ kKeyNone, kKeyNone, // unassigned
|
||||||
/* 0xd7 */ kKeyNone, // unassigned
|
/* 0xd7 */ kKeyNone, kKeyNone, // unassigned
|
||||||
/* 0xd8 */ kKeyNone, // unassigned
|
/* 0xd8 */ kKeyNone, kKeyNone, // unassigned
|
||||||
/* 0xd9 */ kKeyNone, // unassigned
|
/* 0xd9 */ kKeyNone, kKeyNone, // unassigned
|
||||||
/* 0xda */ kKeyNone, // unassigned
|
/* 0xda */ kKeyNone, kKeyNone, // unassigned
|
||||||
/* 0xdb */ kKeyNone, // OEM specific
|
/* 0xdb */ kKeyNone, kKeyNone, // OEM specific
|
||||||
/* 0xdc */ kKeyNone, // OEM specific
|
/* 0xdc */ kKeyNone, kKeyNone, // OEM specific
|
||||||
/* 0xdd */ kKeyNone, // OEM specific
|
/* 0xdd */ kKeyNone, kKeyNone, // OEM specific
|
||||||
/* 0xde */ kKeyNone, // OEM specific
|
/* 0xde */ kKeyNone, kKeyNone, // OEM specific
|
||||||
/* 0xdf */ kKeyNone, // OEM specific
|
/* 0xdf */ kKeyNone, kKeyNone, // OEM specific
|
||||||
/* 0xe0 */ kKeyNone, // OEM specific
|
/* 0xe0 */ kKeyNone, kKeyNone, // OEM specific
|
||||||
/* 0xe1 */ kKeyNone, // OEM specific
|
/* 0xe1 */ kKeyNone, kKeyNone, // OEM specific
|
||||||
/* 0xe2 */ kKeyNone, // OEM specific
|
/* 0xe2 */ kKeyNone, kKeyNone, // OEM specific
|
||||||
/* 0xe3 */ kKeyNone, // OEM specific
|
/* 0xe3 */ kKeyNone, kKeyNone, // OEM specific
|
||||||
/* 0xe4 */ kKeyNone, // OEM specific
|
/* 0xe4 */ kKeyNone, kKeyNone, // OEM specific
|
||||||
/* 0xe5 */ kKeyNone, // unassigned
|
/* 0xe5 */ kKeyNone, kKeyNone, // unassigned
|
||||||
/* 0xe6 */ kKeyNone, // OEM specific
|
/* 0xe6 */ kKeyNone, kKeyNone, // OEM specific
|
||||||
/* 0xe7 */ kKeyNone, // unassigned
|
/* 0xe7 */ kKeyNone, kKeyNone, // unassigned
|
||||||
/* 0xe8 */ kKeyNone, // unassigned
|
/* 0xe8 */ kKeyNone, kKeyNone, // unassigned
|
||||||
/* 0xe9 */ kKeyNone, // OEM specific
|
/* 0xe9 */ kKeyNone, kKeyNone, // OEM specific
|
||||||
/* 0xea */ kKeyNone, // OEM specific
|
/* 0xea */ kKeyNone, kKeyNone, // OEM specific
|
||||||
/* 0xeb */ kKeyNone, // OEM specific
|
/* 0xeb */ kKeyNone, kKeyNone, // OEM specific
|
||||||
/* 0xec */ kKeyNone, // OEM specific
|
/* 0xec */ kKeyNone, kKeyNone, // OEM specific
|
||||||
/* 0xed */ kKeyNone, // OEM specific
|
/* 0xed */ kKeyNone, kKeyNone, // OEM specific
|
||||||
/* 0xee */ kKeyNone, // OEM specific
|
/* 0xee */ kKeyNone, kKeyNone, // OEM specific
|
||||||
/* 0xef */ kKeyNone, // OEM specific
|
/* 0xef */ kKeyNone, kKeyNone, // OEM specific
|
||||||
/* 0xf0 */ kKeyNone, // OEM specific
|
/* 0xf0 */ kKeyNone, kKeyNone, // OEM specific
|
||||||
/* 0xf1 */ kKeyNone, // OEM specific
|
/* 0xf1 */ kKeyNone, kKeyNone, // OEM specific
|
||||||
/* 0xf2 */ kKeyNone, // OEM specific
|
/* 0xf2 */ kKeyNone, kKeyNone, // OEM specific
|
||||||
/* 0xf3 */ kKeyNone, // OEM specific
|
/* 0xf3 */ kKeyNone, kKeyNone, // OEM specific
|
||||||
/* 0xf4 */ kKeyNone, // OEM specific
|
/* 0xf4 */ kKeyNone, kKeyNone, // OEM specific
|
||||||
/* 0xf5 */ kKeyNone, // OEM specific
|
/* 0xf5 */ kKeyNone, kKeyNone, // OEM specific
|
||||||
/* 0xf6 */ kKeyNone, // VK_ATTN
|
/* 0xf6 */ kKeyNone, kKeyNone, // VK_ATTN
|
||||||
/* 0xf7 */ kKeyNone, // VK_CRSEL
|
/* 0xf7 */ kKeyNone, kKeyNone, // VK_CRSEL
|
||||||
/* 0xf8 */ kKeyNone, // VK_EXSEL
|
/* 0xf8 */ kKeyNone, kKeyNone, // VK_EXSEL
|
||||||
/* 0xf9 */ kKeyNone, // VK_EREOF
|
/* 0xf9 */ kKeyNone, kKeyNone, // VK_EREOF
|
||||||
/* 0xfa */ kKeyNone, // VK_PLAY
|
/* 0xfa */ kKeyNone, kKeyNone, // VK_PLAY
|
||||||
/* 0xfb */ kKeyNone, // VK_ZOOM
|
/* 0xfb */ kKeyNone, kKeyNone, // VK_ZOOM
|
||||||
/* 0xfc */ kKeyNone, // reserved
|
/* 0xfc */ kKeyNone, kKeyNone, // reserved
|
||||||
/* 0xfd */ kKeyNone, // VK_PA1
|
/* 0xfd */ kKeyNone, kKeyNone, // VK_PA1
|
||||||
/* 0xfe */ kKeyNone, // VK_OEM_CLEAR
|
/* 0xfe */ kKeyNone, kKeyNone, // VK_OEM_CLEAR
|
||||||
/* 0xff */ kKeyNone // reserved
|
/* 0xff */ kKeyNone, kKeyNone // reserved
|
||||||
};
|
};
|
||||||
|
|
||||||
KeyID
|
KeyID
|
||||||
|
@ -918,68 +920,22 @@ CMSWindowsPrimaryScreen::mapKey(
|
||||||
if ((m_keys[VK_SCROLL] & 0x01) != 0) {
|
if ((m_keys[VK_SCROLL] & 0x01) != 0) {
|
||||||
mask |= KeyModifierScrollLock;
|
mask |= KeyModifierScrollLock;
|
||||||
}
|
}
|
||||||
|
if ((mask & (KeyModifierControl | KeyModifierAlt)) ==
|
||||||
|
(KeyModifierControl | KeyModifierAlt)) {
|
||||||
|
// ctrl+alt => AltGr on windows
|
||||||
|
mask |= KeyModifierModeSwitch;
|
||||||
|
mask &= ~(KeyModifierControl | KeyModifierAlt);
|
||||||
|
}
|
||||||
*maskOut = mask;
|
*maskOut = mask;
|
||||||
log((CLOG_DEBUG2 "key in vk=%d info=0x%08x mask=0x%04x", vkCode, info, mask));
|
log((CLOG_DEBUG2 "key in vk=%d info=0x%08x mask=0x%04x", vkCode, info, mask));
|
||||||
|
|
||||||
// get the scan code
|
// get the scan code and the extended keyboard flag
|
||||||
UINT scanCode = static_cast<UINT>((info & 0xff0000) >> 16);
|
UINT scanCode = static_cast<UINT>((info & 0x00ff0000u) >> 16);
|
||||||
|
int extended = ((info & 0x01000000) == 0) ? 0 : 1;
|
||||||
// convert virtual key to one that distinguishes between left and
|
log((CLOG_DEBUG1 "key vk=%d ext=%d scan=%d", vkCode, extended, scanCode));
|
||||||
// right for keys that have left/right versions. known scan codes
|
|
||||||
// that don't have left/right versions are passed through unchanged.
|
|
||||||
// unknown scan codes return 0.
|
|
||||||
UINT vkCode2 = MapVirtualKey(scanCode, 3);
|
|
||||||
|
|
||||||
// work around bug Q72583 (bad num pad conversion in MapVirtualKey())
|
|
||||||
if (vkCode >= VK_NUMPAD0 && vkCode <= VK_DIVIDE) {
|
|
||||||
vkCode2 = vkCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
// MapVirtualKey() appears to map VK_LWIN, VK_RWIN, VK_APPS to
|
|
||||||
// some other meaningless virtual key. work around that bug.
|
|
||||||
else if (vkCode >= VK_LWIN && vkCode <= VK_APPS) {
|
|
||||||
vkCode2 = vkCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if the original vkCode is VK_SNAPSHOT then use it. oddly enough,
|
|
||||||
// some keyboards use the same scan code for keypad multiply and
|
|
||||||
// print screen. the difference is that the latter has the extended
|
|
||||||
// key flag set. but MapVirtualKey() doesn't seem capable of using
|
|
||||||
// that flag.
|
|
||||||
else if (vkCode == VK_SNAPSHOT) {
|
|
||||||
vkCode2 = vkCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if MapVirtualKey failed then use original virtual key
|
|
||||||
else if (vkCode2 == 0) {
|
|
||||||
vkCode2 = vkCode;
|
|
||||||
}
|
|
||||||
|
|
||||||
// sadly, win32 will not distinguish between the left and right
|
|
||||||
// control and alt keys using the above function. however, we
|
|
||||||
// can check for those: if bit 24 of info is set then the key
|
|
||||||
// is a "extended" key, such as the right control and right alt
|
|
||||||
// keys.
|
|
||||||
if ((info & 0x1000000) != 0) {
|
|
||||||
switch (vkCode2) {
|
|
||||||
case VK_CONTROL:
|
|
||||||
case VK_LCONTROL:
|
|
||||||
vkCode2 = VK_RCONTROL;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case VK_MENU:
|
|
||||||
case VK_LMENU:
|
|
||||||
vkCode2 = VK_RMENU;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// use left/right distinguishing virtual key
|
|
||||||
vkCode = vkCode2;
|
|
||||||
log((CLOG_DEBUG1 "key vk=%d scan=%d", vkCode, scanCode));
|
|
||||||
|
|
||||||
// handle some keys via table lookup
|
// handle some keys via table lookup
|
||||||
KeyID id = g_virtualKey[vkCode];
|
KeyID id = g_virtualKey[vkCode][extended];
|
||||||
if (id != kKeyNone) {
|
if (id != kKeyNone) {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
@ -989,17 +945,19 @@ CMSWindowsPrimaryScreen::mapKey(
|
||||||
return kKeyMultiKey;
|
return kKeyMultiKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToAscii() maps ctrl+letter to the corresponding control code
|
// save the control state then clear it. ToAscii() maps ctrl+letter
|
||||||
// and ctrl+backspace to delete. if we've got a control code or
|
// to the corresponding control code and ctrl+backspace to delete.
|
||||||
// delete then do ToAscii() again but without the control state.
|
// we don't want that translation so we clear the control modifier
|
||||||
// ToAscii() interprets the control modifier state which we don't
|
// state. however, if we want to simulate AltGr (which is ctrl+alt)
|
||||||
// want. so save the control state then clear it.
|
// then we must not clear it.
|
||||||
BYTE lControl = m_keys[VK_LCONTROL];
|
BYTE lControl = m_keys[VK_LCONTROL];
|
||||||
BYTE rControl = m_keys[VK_RCONTROL];
|
BYTE rControl = m_keys[VK_RCONTROL];
|
||||||
BYTE control = m_keys[VK_CONTROL];
|
BYTE control = m_keys[VK_CONTROL];
|
||||||
m_keys[VK_LCONTROL] = 0;
|
if ((mask & KeyModifierModeSwitch) == 0) {
|
||||||
m_keys[VK_RCONTROL] = 0;
|
m_keys[VK_LCONTROL] = 0;
|
||||||
m_keys[VK_CONTROL] = 0;
|
m_keys[VK_RCONTROL] = 0;
|
||||||
|
m_keys[VK_CONTROL] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
// convert to ascii
|
// convert to ascii
|
||||||
// FIXME -- support unicode
|
// FIXME -- support unicode
|
||||||
|
@ -1092,18 +1050,18 @@ CMSWindowsPrimaryScreen::updateKeys()
|
||||||
|
|
||||||
// we only care about the modifier key states. other keys and the
|
// we only care about the modifier key states. other keys and the
|
||||||
// mouse buttons should be up.
|
// mouse buttons should be up.
|
||||||
m_keys[VK_LSHIFT] = static_cast<BYTE>(GetKeyState(VK_LSHIFT));
|
m_keys[VK_LSHIFT] = static_cast<BYTE>(GetKeyState(VK_LSHIFT) & 0x80);
|
||||||
m_keys[VK_RSHIFT] = static_cast<BYTE>(GetKeyState(VK_RSHIFT));
|
m_keys[VK_RSHIFT] = static_cast<BYTE>(GetKeyState(VK_RSHIFT) & 0x80);
|
||||||
m_keys[VK_SHIFT] = static_cast<BYTE>(GetKeyState(VK_SHIFT));
|
m_keys[VK_SHIFT] = static_cast<BYTE>(GetKeyState(VK_SHIFT) & 0x80);
|
||||||
m_keys[VK_LCONTROL] = static_cast<BYTE>(GetKeyState(VK_LCONTROL));
|
m_keys[VK_LCONTROL] = static_cast<BYTE>(GetKeyState(VK_LCONTROL) & 0x80);
|
||||||
m_keys[VK_RCONTROL] = static_cast<BYTE>(GetKeyState(VK_RCONTROL));
|
m_keys[VK_RCONTROL] = static_cast<BYTE>(GetKeyState(VK_RCONTROL) & 0x80);
|
||||||
m_keys[VK_CONTROL] = static_cast<BYTE>(GetKeyState(VK_CONTROL));
|
m_keys[VK_CONTROL] = static_cast<BYTE>(GetKeyState(VK_CONTROL) & 0x80);
|
||||||
m_keys[VK_LMENU] = static_cast<BYTE>(GetKeyState(VK_LMENU));
|
m_keys[VK_LMENU] = static_cast<BYTE>(GetKeyState(VK_LMENU) & 0x80);
|
||||||
m_keys[VK_RMENU] = static_cast<BYTE>(GetKeyState(VK_RMENU));
|
m_keys[VK_RMENU] = static_cast<BYTE>(GetKeyState(VK_RMENU) & 0x80);
|
||||||
m_keys[VK_MENU] = static_cast<BYTE>(GetKeyState(VK_MENU));
|
m_keys[VK_MENU] = static_cast<BYTE>(GetKeyState(VK_MENU) & 0x80);
|
||||||
m_keys[VK_LWIN] = static_cast<BYTE>(GetKeyState(VK_LWIN));
|
m_keys[VK_LWIN] = static_cast<BYTE>(GetKeyState(VK_LWIN) & 0x80);
|
||||||
m_keys[VK_RWIN] = static_cast<BYTE>(GetKeyState(VK_RWIN));
|
m_keys[VK_RWIN] = static_cast<BYTE>(GetKeyState(VK_RWIN) & 0x80);
|
||||||
m_keys[VK_APPS] = static_cast<BYTE>(GetKeyState(VK_APPS));
|
m_keys[VK_APPS] = static_cast<BYTE>(GetKeyState(VK_APPS) & 0x80);
|
||||||
m_keys[VK_CAPITAL] = static_cast<BYTE>(GetKeyState(VK_CAPITAL));
|
m_keys[VK_CAPITAL] = static_cast<BYTE>(GetKeyState(VK_CAPITAL));
|
||||||
m_keys[VK_NUMLOCK] = static_cast<BYTE>(GetKeyState(VK_NUMLOCK));
|
m_keys[VK_NUMLOCK] = static_cast<BYTE>(GetKeyState(VK_NUMLOCK));
|
||||||
m_keys[VK_SCROLL] = static_cast<BYTE>(GetKeyState(VK_SCROLL));
|
m_keys[VK_SCROLL] = static_cast<BYTE>(GetKeyState(VK_SCROLL));
|
||||||
|
|
Loading…
Reference in New Issue