Merge 7ac22c31cb
into fce7615e42
This commit is contained in:
commit
6917c58b49
|
@ -26,7 +26,8 @@ const char* Action::m_ActionTypeNames[] =
|
||||||
"keyDown", "keyUp", "keystroke",
|
"keyDown", "keyUp", "keystroke",
|
||||||
"switchToScreen", "toggleScreen",
|
"switchToScreen", "toggleScreen",
|
||||||
"switchInDirection", "lockCursorToScreen",
|
"switchInDirection", "lockCursorToScreen",
|
||||||
"mouseDown", "mouseUp", "mousebutton"
|
"userScript",
|
||||||
|
"mouseDown", "mouseUp", "mousebutton",
|
||||||
};
|
};
|
||||||
|
|
||||||
const char* Action::m_SwitchDirectionNames[] = { "left", "right", "up", "down" };
|
const char* Action::m_SwitchDirectionNames[] = { "left", "right", "up", "down" };
|
||||||
|
@ -37,6 +38,7 @@ Action::Action() :
|
||||||
m_Type(keystroke),
|
m_Type(keystroke),
|
||||||
m_TypeScreenNames(),
|
m_TypeScreenNames(),
|
||||||
m_SwitchScreenName(),
|
m_SwitchScreenName(),
|
||||||
|
m_UserScriptCommand(),
|
||||||
m_SwitchDirection(switchLeft),
|
m_SwitchDirection(switchLeft),
|
||||||
m_LockCursorMode(lockCursorToggle),
|
m_LockCursorMode(lockCursorToggle),
|
||||||
m_ActiveOnRelease(false),
|
m_ActiveOnRelease(false),
|
||||||
|
@ -105,6 +107,11 @@ QString Action::text() const
|
||||||
text += ")";
|
text += ")";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case userScript:
|
||||||
|
text += "(";
|
||||||
|
text += userScriptCommand();
|
||||||
|
text += ")";
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
Q_ASSERT(0);
|
Q_ASSERT(0);
|
||||||
break;
|
break;
|
||||||
|
@ -133,6 +140,7 @@ void Action::loadSettings(QSettings& settings)
|
||||||
setLockCursorMode(settings.value("lockCursorToScreen", lockCursorToggle).toInt());
|
setLockCursorMode(settings.value("lockCursorToScreen", lockCursorToggle).toInt());
|
||||||
setActiveOnRelease(settings.value("activeOnRelease", false).toBool());
|
setActiveOnRelease(settings.value("activeOnRelease", false).toBool());
|
||||||
setHaveScreens(settings.value("hasScreens", false).toBool());
|
setHaveScreens(settings.value("hasScreens", false).toBool());
|
||||||
|
setUserScriptCommand(settings.value("userScriptCommand").toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Action::saveSettings(QSettings& settings) const
|
void Action::saveSettings(QSettings& settings) const
|
||||||
|
@ -153,6 +161,7 @@ void Action::saveSettings(QSettings& settings) const
|
||||||
settings.setValue("lockCursorToScreen", lockCursorMode());
|
settings.setValue("lockCursorToScreen", lockCursorMode());
|
||||||
settings.setValue("activeOnRelease", activeOnRelease());
|
settings.setValue("activeOnRelease", activeOnRelease());
|
||||||
settings.setValue("hasScreens", haveScreens());
|
settings.setValue("hasScreens", haveScreens());
|
||||||
|
settings.setValue("userScriptCommand", userScriptCommand());
|
||||||
}
|
}
|
||||||
|
|
||||||
QTextStream& operator<<(QTextStream& outStream, const Action& action)
|
QTextStream& operator<<(QTextStream& outStream, const Action& action)
|
||||||
|
|
|
@ -35,7 +35,8 @@ class Action
|
||||||
public:
|
public:
|
||||||
enum ActionType { keyDown, keyUp, keystroke,
|
enum ActionType { keyDown, keyUp, keystroke,
|
||||||
switchToScreen, toggleScreen, switchInDirection,
|
switchToScreen, toggleScreen, switchInDirection,
|
||||||
lockCursorToScreen, mouseDown, mouseUp, mousebutton };
|
lockCursorToScreen, userScript,
|
||||||
|
mouseDown, mouseUp, mousebutton };
|
||||||
enum SwitchDirection { switchLeft, switchRight, switchUp, switchDown };
|
enum SwitchDirection { switchLeft, switchRight, switchUp, switchDown };
|
||||||
enum LockCursorMode { lockCursorToggle, lockCursonOn, lockCursorOff };
|
enum LockCursorMode { lockCursorToggle, lockCursonOn, lockCursorOff };
|
||||||
|
|
||||||
|
@ -72,11 +73,15 @@ class Action
|
||||||
bool haveScreens() const { return m_HasScreens; }
|
bool haveScreens() const { return m_HasScreens; }
|
||||||
void setHaveScreens(bool b) { m_HasScreens = b; }
|
void setHaveScreens(bool b) { m_HasScreens = b; }
|
||||||
|
|
||||||
|
const QString& userScriptCommand() const { return m_UserScriptCommand; }
|
||||||
|
void setUserScriptCommand(const QString& n) { m_UserScriptCommand = n; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
KeySequence m_KeySequence;
|
KeySequence m_KeySequence;
|
||||||
int m_Type;
|
int m_Type;
|
||||||
QStringList m_TypeScreenNames;
|
QStringList m_TypeScreenNames;
|
||||||
QString m_SwitchScreenName;
|
QString m_SwitchScreenName;
|
||||||
|
QString m_UserScriptCommand;
|
||||||
int m_SwitchDirection;
|
int m_SwitchDirection;
|
||||||
int m_LockCursorMode;
|
int m_LockCursorMode;
|
||||||
bool m_ActiveOnRelease;
|
bool m_ActiveOnRelease;
|
||||||
|
|
|
@ -39,7 +39,7 @@ ActionDialog::ActionDialog(QWidget* parent, ServerConfig& config, Hotkey& hotkey
|
||||||
|
|
||||||
// work around Qt Designer's lack of a QButtonGroup; we need it to get
|
// work around Qt Designer's lack of a QButtonGroup; we need it to get
|
||||||
// at the button id of the checked radio button
|
// at the button id of the checked radio button
|
||||||
QRadioButton* const typeButtons[] = { m_pRadioPress, m_pRadioRelease, m_pRadioPressAndRelease, m_pRadioSwitchToScreen, m_pRadioToggleScreen, m_pRadioSwitchInDirection, m_pRadioLockCursorToScreen };
|
QRadioButton* const typeButtons[] = { m_pRadioPress, m_pRadioRelease, m_pRadioPressAndRelease, m_pRadioSwitchToScreen, m_pRadioToggleScreen, m_pRadioSwitchInDirection, m_pRadioLockCursorToScreen, m_pRadioUserScript };
|
||||||
|
|
||||||
for (unsigned int i = 0; i < sizeof(typeButtons) / sizeof(typeButtons[0]); i++)
|
for (unsigned int i = 0; i < sizeof(typeButtons) / sizeof(typeButtons[0]); i++)
|
||||||
m_pButtonGroupType->addButton(typeButtons[i], i);
|
m_pButtonGroupType->addButton(typeButtons[i], i);
|
||||||
|
@ -49,6 +49,7 @@ ActionDialog::ActionDialog(QWidget* parent, ServerConfig& config, Hotkey& hotkey
|
||||||
m_pButtonGroupType->button(m_Action.type())->setChecked(true);
|
m_pButtonGroupType->button(m_Action.type())->setChecked(true);
|
||||||
m_pComboSwitchInDirection->setCurrentIndex(m_Action.switchDirection());
|
m_pComboSwitchInDirection->setCurrentIndex(m_Action.switchDirection());
|
||||||
m_pComboLockCursorToScreen->setCurrentIndex(m_Action.lockCursorMode());
|
m_pComboLockCursorToScreen->setCurrentIndex(m_Action.lockCursorMode());
|
||||||
|
m_pUserScriptCommand->setText(m_Action.userScriptCommand());
|
||||||
|
|
||||||
if (m_Action.activeOnRelease())
|
if (m_Action.activeOnRelease())
|
||||||
m_pRadioHotkeyReleased->setChecked(true);
|
m_pRadioHotkeyReleased->setChecked(true);
|
||||||
|
@ -93,6 +94,7 @@ void ActionDialog::accept()
|
||||||
m_Action.setSwitchDirection(m_pComboSwitchInDirection->currentIndex());
|
m_Action.setSwitchDirection(m_pComboSwitchInDirection->currentIndex());
|
||||||
m_Action.setLockCursorMode(m_pComboLockCursorToScreen->currentIndex());
|
m_Action.setLockCursorMode(m_pComboLockCursorToScreen->currentIndex());
|
||||||
m_Action.setActiveOnRelease(m_pRadioHotkeyReleased->isChecked());
|
m_Action.setActiveOnRelease(m_pRadioHotkeyReleased->isChecked());
|
||||||
|
m_Action.setUserScriptCommand(m_pUserScriptCommand->text());
|
||||||
|
|
||||||
QDialog::accept();
|
QDialog::accept();
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>372</width>
|
<width>372</width>
|
||||||
<height>484</height>
|
<height>508</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
|
@ -250,6 +250,37 @@
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="QRadioButton" name="m_pRadioUserScript">
|
||||||
|
<property name="text">
|
||||||
|
<string>User Script</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<spacer name="horizontalSpacer">
|
||||||
|
<property name="orientation">
|
||||||
|
<enum>Qt::Horizontal</enum>
|
||||||
|
</property>
|
||||||
|
<property name="sizeHint" stdset="0">
|
||||||
|
<size>
|
||||||
|
<width>40</width>
|
||||||
|
<height>20</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
|
</spacer>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QLineEdit" name="m_pUserScriptCommand">
|
||||||
|
<property name="text">
|
||||||
|
<string>script1</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
@ -588,5 +619,53 @@
|
||||||
</hint>
|
</hint>
|
||||||
</hints>
|
</hints>
|
||||||
</connection>
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>m_pRadioUserScript</sender>
|
||||||
|
<signal>toggled(bool)</signal>
|
||||||
|
<receiver>m_pUserScriptCommand</receiver>
|
||||||
|
<slot>setEnabled(bool)</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>63</x>
|
||||||
|
<y>385</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>291</x>
|
||||||
|
<y>385</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>m_pRadioUserScript</sender>
|
||||||
|
<signal>toggled(bool)</signal>
|
||||||
|
<receiver>m_pKeySequenceWidgetHotkey</receiver>
|
||||||
|
<slot>setDisabled(bool)</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>63</x>
|
||||||
|
<y>385</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>185</x>
|
||||||
|
<y>118</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>m_pRadioUserScript</sender>
|
||||||
|
<signal>toggled(bool)</signal>
|
||||||
|
<receiver>m_pGroupBoxScreens</receiver>
|
||||||
|
<slot>setDisabled(bool)</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>63</x>
|
||||||
|
<y>385</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>185</x>
|
||||||
|
<y>189</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
</connections>
|
</connections>
|
||||||
</ui>
|
</ui>
|
||||||
|
|
|
@ -61,7 +61,8 @@ AppConfig::AppConfig(QSettings* settings) :
|
||||||
m_CryptoEnabled(false),
|
m_CryptoEnabled(false),
|
||||||
m_AutoHide(false),
|
m_AutoHide(false),
|
||||||
m_AutoStart(false),
|
m_AutoStart(false),
|
||||||
m_MinimizeToTray(false)
|
m_MinimizeToTray(false),
|
||||||
|
m_HeadlessMode(false)
|
||||||
{
|
{
|
||||||
Q_ASSERT(m_pSettings);
|
Q_ASSERT(m_pSettings);
|
||||||
|
|
||||||
|
@ -161,6 +162,7 @@ void AppConfig::loadSettings()
|
||||||
m_AutoHide = settings().value("autoHide", false).toBool();
|
m_AutoHide = settings().value("autoHide", false).toBool();
|
||||||
m_AutoStart = settings().value("autoStart", false).toBool();
|
m_AutoStart = settings().value("autoStart", false).toBool();
|
||||||
m_MinimizeToTray = settings().value("minimizeToTray", false).toBool();
|
m_MinimizeToTray = settings().value("minimizeToTray", false).toBool();
|
||||||
|
m_HeadlessMode = settings().value("headlessMode", false).toBool();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AppConfig::saveSettings()
|
void AppConfig::saveSettings()
|
||||||
|
@ -184,6 +186,7 @@ void AppConfig::saveSettings()
|
||||||
settings().setValue("autoHide", m_AutoHide);
|
settings().setValue("autoHide", m_AutoHide);
|
||||||
settings().setValue("autoStart", m_AutoStart);
|
settings().setValue("autoStart", m_AutoStart);
|
||||||
settings().setValue("minimizeToTray", m_MinimizeToTray);
|
settings().setValue("minimizeToTray", m_MinimizeToTray);
|
||||||
|
settings().setValue("headlessMode", m_HeadlessMode);
|
||||||
settings().sync();
|
settings().sync();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -236,3 +239,7 @@ bool AppConfig::getAutoStart() { return m_AutoStart; }
|
||||||
void AppConfig::setMinimizeToTray(bool b) { m_MinimizeToTray = b; }
|
void AppConfig::setMinimizeToTray(bool b) { m_MinimizeToTray = b; }
|
||||||
|
|
||||||
bool AppConfig::getMinimizeToTray() { return m_MinimizeToTray; }
|
bool AppConfig::getMinimizeToTray() { return m_MinimizeToTray; }
|
||||||
|
|
||||||
|
void AppConfig::setHeadlessMode(bool b) { m_HeadlessMode = b; }
|
||||||
|
|
||||||
|
bool AppConfig::getHeadlessMode() { return m_HeadlessMode; }
|
||||||
|
|
|
@ -100,6 +100,9 @@ class AppConfig: public QObject
|
||||||
void setMinimizeToTray(bool b);
|
void setMinimizeToTray(bool b);
|
||||||
bool getMinimizeToTray();
|
bool getMinimizeToTray();
|
||||||
|
|
||||||
|
void setHeadlessMode(bool b);
|
||||||
|
bool getHeadlessMode();
|
||||||
|
|
||||||
void saveSettings();
|
void saveSettings();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -135,6 +138,7 @@ protected:
|
||||||
bool m_AutoHide;
|
bool m_AutoHide;
|
||||||
bool m_AutoStart;
|
bool m_AutoStart;
|
||||||
bool m_MinimizeToTray;
|
bool m_MinimizeToTray;
|
||||||
|
bool m_HeadlessMode;
|
||||||
|
|
||||||
static const char m_BarriersName[];
|
static const char m_BarriersName[];
|
||||||
static const char m_BarriercName[];
|
static const char m_BarriercName[];
|
||||||
|
|
|
@ -520,6 +520,9 @@ void MainWindow::startBarrier()
|
||||||
args << "--enable-crypto";
|
args << "--enable-crypto";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (m_AppConfig->getHeadlessMode()) {
|
||||||
|
args << "--headless-mode";
|
||||||
|
}
|
||||||
#if defined(Q_OS_WIN)
|
#if defined(Q_OS_WIN)
|
||||||
// on windows, the profile directory changes depending on the user that
|
// on windows, the profile directory changes depending on the user that
|
||||||
// launched the process (e.g. when launched with elevation). setting the
|
// launched the process (e.g. when launched with elevation). setting the
|
||||||
|
|
|
@ -51,6 +51,7 @@ SettingsDialog::SettingsDialog(QWidget* parent, AppConfig& config) :
|
||||||
m_pCheckBoxAutoStart->setChecked(appConfig().getAutoStart());
|
m_pCheckBoxAutoStart->setChecked(appConfig().getAutoStart());
|
||||||
m_pCheckBoxMinimizeToTray->setChecked(appConfig().getMinimizeToTray());
|
m_pCheckBoxMinimizeToTray->setChecked(appConfig().getMinimizeToTray());
|
||||||
m_pCheckBoxEnableCrypto->setChecked(m_appConfig.getCryptoEnabled());
|
m_pCheckBoxEnableCrypto->setChecked(m_appConfig.getCryptoEnabled());
|
||||||
|
m_pCheckBoxHeadlessMode->setChecked(m_appConfig.getHeadlessMode());
|
||||||
|
|
||||||
#if defined(Q_OS_WIN)
|
#if defined(Q_OS_WIN)
|
||||||
m_pComboElevate->setCurrentIndex(static_cast<int>(appConfig().elevateMode()));
|
m_pComboElevate->setCurrentIndex(static_cast<int>(appConfig().elevateMode()));
|
||||||
|
@ -75,6 +76,7 @@ void SettingsDialog::accept()
|
||||||
m_appConfig.setAutoHide(m_pCheckBoxAutoHide->isChecked());
|
m_appConfig.setAutoHide(m_pCheckBoxAutoHide->isChecked());
|
||||||
m_appConfig.setAutoStart(m_pCheckBoxAutoStart->isChecked());
|
m_appConfig.setAutoStart(m_pCheckBoxAutoStart->isChecked());
|
||||||
m_appConfig.setMinimizeToTray(m_pCheckBoxMinimizeToTray->isChecked());
|
m_appConfig.setMinimizeToTray(m_pCheckBoxMinimizeToTray->isChecked());
|
||||||
|
m_appConfig.setHeadlessMode(m_pCheckBoxHeadlessMode->isChecked());
|
||||||
m_appConfig.saveSettings();
|
m_appConfig.saveSettings();
|
||||||
QDialog::accept();
|
QDialog::accept();
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>368</width>
|
<width>368</width>
|
||||||
<height>428</height>
|
<height>454</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
|
@ -133,6 +133,13 @@
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="3" column="1">
|
||||||
|
<widget class="QCheckBox" name="m_pCheckBoxHeadlessMode">
|
||||||
|
<property name="text">
|
||||||
|
<string>Headless &mode</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
|
|
@ -114,6 +114,9 @@ App::run(int argc, char** argv)
|
||||||
// using the exit(int) function!
|
// using the exit(int) function!
|
||||||
result = e.getCode();
|
result = e.getCode();
|
||||||
}
|
}
|
||||||
|
catch (std::runtime_error& re) {
|
||||||
|
LOG((CLOG_CRIT "A runtime error occurred: %s\n", re.what()));
|
||||||
|
}
|
||||||
catch (std::exception& e) {
|
catch (std::exception& e) {
|
||||||
LOG((CLOG_CRIT "An error occurred: %s\n", e.what()));
|
LOG((CLOG_CRIT "An error occurred: %s\n", e.what()));
|
||||||
}
|
}
|
||||||
|
|
|
@ -168,7 +168,10 @@ private:
|
||||||
" --enable-drag-drop enable file drag & drop.\n" \
|
" --enable-drag-drop enable file drag & drop.\n" \
|
||||||
" --enable-crypto enable the crypto (ssl) plugin.\n" \
|
" --enable-crypto enable the crypto (ssl) plugin.\n" \
|
||||||
" --profile-dir <path> use named profile directory instead.\n" \
|
" --profile-dir <path> use named profile directory instead.\n" \
|
||||||
" --drop-dir <path> use named drop target directory instead.\n"
|
" --drop-dir <path> use named drop target directory instead.\n" \
|
||||||
|
" --headless-mode when any client connected, if server screen is\n" \
|
||||||
|
" holding the input focus, server will actively\n" \
|
||||||
|
" switch input focus to the client.\n"
|
||||||
|
|
||||||
#define HELP_COMMON_INFO_2 \
|
#define HELP_COMMON_INFO_2 \
|
||||||
" -h, --help display this help and exit.\n" \
|
" -h, --help display this help and exit.\n" \
|
||||||
|
|
|
@ -290,6 +290,9 @@ ArgParser::parseGenericArgs(int argc, const char* const* argv, int& i)
|
||||||
else if (isArg(i, argc, argv, NULL, "--plugin-dir", 1)) {
|
else if (isArg(i, argc, argv, NULL, "--plugin-dir", 1)) {
|
||||||
argsBase().m_pluginDirectory = argv[++i];
|
argsBase().m_pluginDirectory = argv[++i];
|
||||||
}
|
}
|
||||||
|
else if (isArg(i, argc, argv, NULL, "--headless-mode")) {
|
||||||
|
argsBase().m_headlessMode = true;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
// option not supported here
|
// option not supported here
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -44,7 +44,8 @@ m_shouldExit(false),
|
||||||
m_barrierAddress(),
|
m_barrierAddress(),
|
||||||
m_enableCrypto(false),
|
m_enableCrypto(false),
|
||||||
m_profileDirectory(""),
|
m_profileDirectory(""),
|
||||||
m_pluginDirectory("")
|
m_pluginDirectory(""),
|
||||||
|
m_headlessMode(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -52,4 +52,5 @@ public:
|
||||||
bool m_enableCrypto;
|
bool m_enableCrypto;
|
||||||
String m_profileDirectory;
|
String m_profileDirectory;
|
||||||
String m_pluginDirectory;
|
String m_pluginDirectory;
|
||||||
|
bool m_headlessMode;
|
||||||
};
|
};
|
||||||
|
|
|
@ -164,7 +164,7 @@ ClientApp::createScreen()
|
||||||
{
|
{
|
||||||
#if WINAPI_MSWINDOWS
|
#if WINAPI_MSWINDOWS
|
||||||
return new barrier::Screen(new MSWindowsScreen(
|
return new barrier::Screen(new MSWindowsScreen(
|
||||||
false, args().m_noHooks, args().m_stopOnDeskSwitch, m_events), m_events);
|
false, args().m_noHooks, args().m_stopOnDeskSwitch, args().m_headlessMode, m_events), m_events);
|
||||||
#elif WINAPI_XWINDOWS
|
#elif WINAPI_XWINDOWS
|
||||||
return new barrier::Screen(new XWindowsScreen(
|
return new barrier::Screen(new XWindowsScreen(
|
||||||
new XWindowsImpl(),
|
new XWindowsImpl(),
|
||||||
|
|
|
@ -62,21 +62,21 @@ IKeyState::KeyInfo::alloc(KeyID id,
|
||||||
info->m_button = button;
|
info->m_button = button;
|
||||||
info->m_count = count;
|
info->m_count = count;
|
||||||
info->m_screens = info->m_screensBuffer;
|
info->m_screens = info->m_screensBuffer;
|
||||||
strcpy(info->m_screensBuffer, screens.c_str());
|
strcpy(info->m_screensBuffer, screens.c_str()); // Compliant: String type is safe
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
IKeyState::KeyInfo*
|
IKeyState::KeyInfo*
|
||||||
IKeyState::KeyInfo::alloc(const KeyInfo& x)
|
IKeyState::KeyInfo::alloc(const KeyInfo& x)
|
||||||
{
|
{
|
||||||
KeyInfo* info = (KeyInfo*)malloc(sizeof(KeyInfo) +
|
auto bufferLen = strnlen(x.m_screensBuffer, SIZE_MAX);
|
||||||
strlen(x.m_screensBuffer));
|
auto info = (KeyInfo*)malloc(sizeof(KeyInfo) + bufferLen);
|
||||||
info->m_key = x.m_key;
|
info->m_key = x.m_key;
|
||||||
info->m_mask = x.m_mask;
|
info->m_mask = x.m_mask;
|
||||||
info->m_button = x.m_button;
|
info->m_button = x.m_button;
|
||||||
info->m_count = x.m_count;
|
info->m_count = x.m_count;
|
||||||
info->m_screens = x.m_screens ? info->m_screensBuffer : NULL;
|
info->m_screens = x.m_screens ? info->m_screensBuffer : NULL;
|
||||||
strcpy(info->m_screensBuffer, x.m_screensBuffer);
|
memcpy(info->m_screensBuffer, x.m_screensBuffer, bufferLen + 1);
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -62,6 +62,9 @@ ProtocolUtil::readf(barrier::IStream* stream, const char* fmt, ...)
|
||||||
catch (XIO&) {
|
catch (XIO&) {
|
||||||
result = false;
|
result = false;
|
||||||
}
|
}
|
||||||
|
catch (const std::bad_alloc&) {
|
||||||
|
result = false;
|
||||||
|
}
|
||||||
va_end(args);
|
va_end(args);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -79,18 +82,17 @@ ProtocolUtil::vwritef(barrier::IStream* stream,
|
||||||
}
|
}
|
||||||
|
|
||||||
// fill buffer
|
// fill buffer
|
||||||
UInt8* buffer = new UInt8[size];
|
std::vector<UInt8> buffer;
|
||||||
writef_void(buffer, fmt, args);
|
buffer.reserve(size);
|
||||||
|
writef_void(buffer.data(), fmt, args);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// write buffer
|
// write buffer
|
||||||
stream->write(buffer, size);
|
stream->write(buffer.data(), size);
|
||||||
LOG((CLOG_DEBUG2 "wrote %d bytes", size));
|
LOG((CLOG_DEBUG2 "wrote %d bytes", size));
|
||||||
|
|
||||||
delete[] buffer;
|
|
||||||
}
|
}
|
||||||
catch (XBase&) {
|
catch (const XBase& exception) {
|
||||||
delete[] buffer;
|
LOG((CLOG_DEBUG2 "Exception <%s> during wrote %d bytes into stream", exception.what(), size));
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -267,6 +267,18 @@ ServerApp::handleClientConnected(const Event&, void* vlistener)
|
||||||
if (client != NULL) {
|
if (client != NULL) {
|
||||||
m_server->adoptClient(client);
|
m_server->adoptClient(client);
|
||||||
updateStatus();
|
updateStatus();
|
||||||
|
if( args().m_headlessMode && m_server->isServerHoldFocus() ) {
|
||||||
|
std::string screen = args().m_config->getCanonicalName(client->getName());
|
||||||
|
if (screen.empty()) {
|
||||||
|
screen = client->getName();
|
||||||
|
}
|
||||||
|
if(screen.empty()) return;
|
||||||
|
// send event
|
||||||
|
Server::SwitchToScreenInfo* info =
|
||||||
|
Server::SwitchToScreenInfo::alloc(screen);
|
||||||
|
m_events->addEvent(Event(m_events->forServer().switchToScreen(),
|
||||||
|
args().m_config->getInputFilter(), info));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -604,7 +616,7 @@ ServerApp::createScreen()
|
||||||
{
|
{
|
||||||
#if WINAPI_MSWINDOWS
|
#if WINAPI_MSWINDOWS
|
||||||
return new barrier::Screen(new MSWindowsScreen(
|
return new barrier::Screen(new MSWindowsScreen(
|
||||||
true, args().m_noHooks, args().m_stopOnDeskSwitch, m_events), m_events);
|
true, args().m_noHooks, args().m_stopOnDeskSwitch, args().m_headlessMode, m_events), m_events);
|
||||||
#elif WINAPI_XWINDOWS
|
#elif WINAPI_XWINDOWS
|
||||||
return new barrier::Screen(new XWindowsScreen(
|
return new barrier::Screen(new XWindowsScreen(
|
||||||
new XWindowsImpl(),
|
new XWindowsImpl(),
|
||||||
|
|
|
@ -240,7 +240,8 @@ void
|
||||||
Client::enter(SInt32 xAbs, SInt32 yAbs, UInt32, KeyModifierMask mask, bool)
|
Client::enter(SInt32 xAbs, SInt32 yAbs, UInt32, KeyModifierMask mask, bool)
|
||||||
{
|
{
|
||||||
m_active = true;
|
m_active = true;
|
||||||
m_screen->mouseMove(xAbs, yAbs);
|
if (!m_args.m_headlessMode)
|
||||||
|
m_screen->mouseMove(xAbs, yAbs);
|
||||||
m_screen->enter(mask);
|
m_screen->enter(mask);
|
||||||
|
|
||||||
if (m_sendFileThread != NULL) {
|
if (m_sendFileThread != NULL) {
|
||||||
|
@ -515,7 +516,7 @@ Client::setupTimer()
|
||||||
{
|
{
|
||||||
assert(m_timer == NULL);
|
assert(m_timer == NULL);
|
||||||
|
|
||||||
m_timer = m_events->newOneShotTimer(15.0, NULL);
|
m_timer = m_events->newOneShotTimer(2.0, NULL);
|
||||||
m_events->adoptHandler(Event::kTimer, m_timer,
|
m_events->adoptHandler(Event::kTimer, m_timer,
|
||||||
new TMethodEventJob<Client>(this,
|
new TMethodEventJob<Client>(this,
|
||||||
&Client::handleConnectTimeout));
|
&Client::handleConnectTimeout));
|
||||||
|
|
|
@ -100,7 +100,7 @@
|
||||||
MSWindowsDesks::MSWindowsDesks(
|
MSWindowsDesks::MSWindowsDesks(
|
||||||
bool isPrimary, bool noHooks,
|
bool isPrimary, bool noHooks,
|
||||||
const IScreenSaver* screensaver, IEventQueue* events,
|
const IScreenSaver* screensaver, IEventQueue* events,
|
||||||
IJob* updateKeys, bool stopOnDeskSwitch) :
|
IJob* updateKeys, bool stopOnDeskSwitch, bool headlessMode) :
|
||||||
m_isPrimary(isPrimary),
|
m_isPrimary(isPrimary),
|
||||||
m_noHooks(noHooks),
|
m_noHooks(noHooks),
|
||||||
m_isOnScreen(m_isPrimary),
|
m_isOnScreen(m_isPrimary),
|
||||||
|
@ -117,7 +117,8 @@ MSWindowsDesks::MSWindowsDesks(
|
||||||
m_deskReady(&m_mutex, false),
|
m_deskReady(&m_mutex, false),
|
||||||
m_updateKeys(updateKeys),
|
m_updateKeys(updateKeys),
|
||||||
m_events(events),
|
m_events(events),
|
||||||
m_stopOnDeskSwitch(stopOnDeskSwitch)
|
m_stopOnDeskSwitch(stopOnDeskSwitch),
|
||||||
|
m_headlessMode(headlessMode)
|
||||||
{
|
{
|
||||||
m_cursor = createBlankCursor();
|
m_cursor = createBlankCursor();
|
||||||
m_deskClass = createDeskWindowClass(m_isPrimary);
|
m_deskClass = createDeskWindowClass(m_isPrimary);
|
||||||
|
@ -596,9 +597,11 @@ MSWindowsDesks::deskLeave(Desk* desk, HKL keyLayout)
|
||||||
// we aren't notified when the mouse leaves our window.
|
// we aren't notified when the mouse leaves our window.
|
||||||
SetCapture(desk->m_window);
|
SetCapture(desk->m_window);
|
||||||
|
|
||||||
// warp the mouse to the cursor center
|
if (!m_headlessMode) {
|
||||||
LOG((CLOG_DEBUG2 "warping cursor to center: %+d,%+d", m_xCenter, m_yCenter));
|
// warp the mouse to the cursor center
|
||||||
deskMouseMove(m_xCenter, m_yCenter);
|
LOG((CLOG_DEBUG2 "warping cursor to center: %+d,%+d", m_xCenter, m_yCenter));
|
||||||
|
deskMouseMove(m_xCenter, m_yCenter);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -68,7 +68,7 @@ public:
|
||||||
MSWindowsDesks(
|
MSWindowsDesks(
|
||||||
bool isPrimary, bool noHooks,
|
bool isPrimary, bool noHooks,
|
||||||
const IScreenSaver* screensaver, IEventQueue* events,
|
const IScreenSaver* screensaver, IEventQueue* events,
|
||||||
IJob* updateKeys, bool stopOnDeskSwitch);
|
IJob* updateKeys, bool stopOnDeskSwitch, bool headlessMode);
|
||||||
~MSWindowsDesks();
|
~MSWindowsDesks();
|
||||||
|
|
||||||
//! @name manipulators
|
//! @name manipulators
|
||||||
|
@ -294,4 +294,6 @@ private:
|
||||||
|
|
||||||
// true if program should stop on desk switch.
|
// true if program should stop on desk switch.
|
||||||
bool m_stopOnDeskSwitch;
|
bool m_stopOnDeskSwitch;
|
||||||
|
|
||||||
|
bool m_headlessMode;
|
||||||
};
|
};
|
||||||
|
|
|
@ -93,6 +93,7 @@ MSWindowsScreen::MSWindowsScreen(
|
||||||
bool isPrimary,
|
bool isPrimary,
|
||||||
bool noHooks,
|
bool noHooks,
|
||||||
bool stopOnDeskSwitch,
|
bool stopOnDeskSwitch,
|
||||||
|
bool headlessMode,
|
||||||
IEventQueue* events) :
|
IEventQueue* events) :
|
||||||
PlatformScreen(events),
|
PlatformScreen(events),
|
||||||
m_isPrimary(isPrimary),
|
m_isPrimary(isPrimary),
|
||||||
|
@ -136,7 +137,8 @@ MSWindowsScreen::MSWindowsScreen(
|
||||||
m_events,
|
m_events,
|
||||||
new TMethodJob<MSWindowsScreen>(
|
new TMethodJob<MSWindowsScreen>(
|
||||||
this, &MSWindowsScreen::updateKeysCB),
|
this, &MSWindowsScreen::updateKeysCB),
|
||||||
stopOnDeskSwitch);
|
stopOnDeskSwitch,
|
||||||
|
headlessMode);
|
||||||
m_keyState = new MSWindowsKeyState(m_desks, getEventTarget(), m_events);
|
m_keyState = new MSWindowsKeyState(m_desks, getEventTarget(), m_events);
|
||||||
|
|
||||||
updateScreenShape();
|
updateScreenShape();
|
||||||
|
@ -311,6 +313,13 @@ MSWindowsScreen::enter()
|
||||||
bool
|
bool
|
||||||
MSWindowsScreen::leave()
|
MSWindowsScreen::leave()
|
||||||
{
|
{
|
||||||
|
POINT pos;
|
||||||
|
if (!getThisCursorPos(&pos))
|
||||||
|
{
|
||||||
|
LOG((CLOG_DEBUG "Unable to leave screen as Windows security has disabled critical functions required to let barrier work"));
|
||||||
|
//unable to get position this means barrier will break if the cursor leaves the screen
|
||||||
|
return false;
|
||||||
|
}
|
||||||
// get keyboard layout of foreground window. we'll use this
|
// get keyboard layout of foreground window. we'll use this
|
||||||
// keyboard layout for translating keys sent to clients.
|
// keyboard layout for translating keys sent to clients.
|
||||||
HWND window = GetForegroundWindow();
|
HWND window = GetForegroundWindow();
|
||||||
|
@ -521,6 +530,60 @@ MSWindowsScreen::getCursorPos(SInt32& x, SInt32& y) const
|
||||||
m_desks->getCursorPos(x, y);
|
m_desks->getCursorPos(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* getThisCursorPos and setThisCursorPos will attempt to negotiate with the system
|
||||||
|
* to try get the and set the mouse position, however on the logon screen due to
|
||||||
|
* hooks this process has it may unable to work around the problem. Although these
|
||||||
|
* functions did not fix the issue at hand (#5294) its worth keeping them here anyway.
|
||||||
|
*/
|
||||||
|
bool MSWindowsScreen::getThisCursorPos(LPPOINT pos)
|
||||||
|
{
|
||||||
|
auto result = GetCursorPos(pos);
|
||||||
|
auto error = GetLastError();
|
||||||
|
LOG((CLOG_DEBUG3 "%s Attempt: 1 , status %d, code: %d Pos {%d, %d}", __func__, result, error, pos->x, pos->y));
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
result = GetCursorPos(pos);
|
||||||
|
error = GetLastError();
|
||||||
|
LOG((CLOG_DEBUG3 "%s Attempt: 2, status %d, code: %d Pos {%d, %d}", __func__, result, error, pos->x, pos->y));
|
||||||
|
updateDesktopThread();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MSWindowsScreen::setThisCursorPos(int x, int y)
|
||||||
|
{
|
||||||
|
auto result = SetCursorPos(x, y);
|
||||||
|
auto error = GetLastError();
|
||||||
|
LOG((CLOG_DEBUG3 "%s Attempt: 1, status %d, code: %d", __func__, result, error));
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
result = SetCursorPos(x, y);
|
||||||
|
error = GetLastError();
|
||||||
|
LOG((CLOG_DEBUG3 "%s Attempt: 2, status %d, code: %d", __func__, result, error));
|
||||||
|
updateDesktopThread();
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MSWindowsScreen::updateDesktopThread()
|
||||||
|
{
|
||||||
|
|
||||||
|
LOG((CLOG_DEBUG3 "Failed to set cursor Attempting to switch desktop"));
|
||||||
|
SetLastError(0);
|
||||||
|
HDESK cur_hdesk = OpenInputDesktop(0, true, GENERIC_ALL);
|
||||||
|
|
||||||
|
auto error = GetLastError();
|
||||||
|
LOG((CLOG_DEBUG3 "\tGetting desktop Handle: %p Status code: %d", cur_hdesk, error));
|
||||||
|
|
||||||
|
error = GetLastError();
|
||||||
|
LOG((CLOG_DEBUG3 "\tSetting desktop return: %d Status code: %d", SetThreadDesktop(cur_hdesk), GetLastError()));
|
||||||
|
|
||||||
|
CloseDesktop(cur_hdesk);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
MSWindowsScreen::reconfigure(UInt32 activeSides)
|
MSWindowsScreen::reconfigure(UInt32 activeSides)
|
||||||
{
|
{
|
||||||
|
@ -1505,11 +1568,11 @@ MSWindowsScreen::warpCursorNoFlush(SInt32 x, SInt32 y)
|
||||||
|
|
||||||
// warp mouse. hopefully this inserts a mouse motion event
|
// warp mouse. hopefully this inserts a mouse motion event
|
||||||
// between the previous message and the following message.
|
// between the previous message and the following message.
|
||||||
SetCursorPos(x, y);
|
setThisCursorPos(x, y);
|
||||||
|
|
||||||
// check to see if the mouse pos was set correctly
|
// check to see if the mouse pos was set correctly
|
||||||
POINT cursorPos;
|
POINT cursorPos;
|
||||||
GetCursorPos(&cursorPos);
|
getThisCursorPos(&cursorPos);
|
||||||
|
|
||||||
// there is a bug or round error in SetCursorPos and GetCursorPos on
|
// there is a bug or round error in SetCursorPos and GetCursorPos on
|
||||||
// a high DPI setting. The check here is for Vista/7 login screen.
|
// a high DPI setting. The check here is for Vista/7 login screen.
|
||||||
|
|
|
@ -44,6 +44,7 @@ public:
|
||||||
bool isPrimary,
|
bool isPrimary,
|
||||||
bool noHooks,
|
bool noHooks,
|
||||||
bool stopOnDeskSwitch,
|
bool stopOnDeskSwitch,
|
||||||
|
bool headlessMode,
|
||||||
IEventQueue* events);
|
IEventQueue* events);
|
||||||
virtual ~MSWindowsScreen();
|
virtual ~MSWindowsScreen();
|
||||||
|
|
||||||
|
@ -76,6 +77,25 @@ public:
|
||||||
SInt32& width, SInt32& height) const;
|
SInt32& width, SInt32& height) const;
|
||||||
virtual void getCursorPos(SInt32& x, SInt32& y) const;
|
virtual void getCursorPos(SInt32& x, SInt32& y) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Get the position of the cursor on the current machine
|
||||||
|
* \param pos the object that the function will use to store the position of the cursor
|
||||||
|
* \return true if the function was successful
|
||||||
|
*/
|
||||||
|
virtual bool getThisCursorPos(LPPOINT pos);
|
||||||
|
/**
|
||||||
|
* \brief Sets the cursor position on the current machine
|
||||||
|
* \param x The x coordinate of the cursor
|
||||||
|
* \param y The Y coordinate of the cursor
|
||||||
|
* \return True is successful
|
||||||
|
*/
|
||||||
|
virtual bool setThisCursorPos(int x, int y);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief This function will attempt to switch to the current desktop the mouse is located on
|
||||||
|
*/
|
||||||
|
virtual void updateDesktopThread();
|
||||||
|
|
||||||
// IPrimaryScreen overrides
|
// IPrimaryScreen overrides
|
||||||
virtual void reconfigure(UInt32 activeSides);
|
virtual void reconfigure(UInt32 activeSides);
|
||||||
virtual void warpCursor(SInt32 x, SInt32 y);
|
virtual void warpCursor(SInt32 x, SInt32 y);
|
||||||
|
|
|
@ -1244,6 +1244,20 @@ void Config::parseAction(ConfigReadContext& s, const std::string& name,
|
||||||
action = new InputFilter::KeyboardBroadcastAction(m_events, mode, screens);
|
action = new InputFilter::KeyboardBroadcastAction(m_events, mode, screens);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if (name == "userScript") {
|
||||||
|
if (args.size() != 1) {
|
||||||
|
throw XConfigRead(s, "syntax for action: userScript(scriptCommand)");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string scriptCommand = args[0];
|
||||||
|
|
||||||
|
if (scriptCommand.empty()) {
|
||||||
|
throw XConfigRead(s, "bad script command in userScript");
|
||||||
|
}
|
||||||
|
|
||||||
|
action = new InputFilter::UserScriptAction(m_events, scriptCommand);
|
||||||
|
}
|
||||||
|
|
||||||
else {
|
else {
|
||||||
throw XConfigRead(s, "unknown action argument \"%{1}\"", name);
|
throw XConfigRead(s, "unknown action argument \"%{1}\"", name);
|
||||||
}
|
}
|
||||||
|
|
|
@ -558,7 +558,7 @@ std::string InputFilter::KeystrokeAction::format() const
|
||||||
return barrier::string::sprintf("%s(%s,%.*s)", type,
|
return barrier::string::sprintf("%s(%s,%.*s)", type,
|
||||||
barrier::KeyMap::formatKey(m_keyInfo->m_key,
|
barrier::KeyMap::formatKey(m_keyInfo->m_key,
|
||||||
m_keyInfo->m_mask).c_str(),
|
m_keyInfo->m_mask).c_str(),
|
||||||
strlen(m_keyInfo->m_screens + 1) - 1,
|
strnlen(m_keyInfo->m_screens + 1, SIZE_MAX) - 1,
|
||||||
m_keyInfo->m_screens + 1);
|
m_keyInfo->m_screens + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -660,6 +660,53 @@ InputFilter::MouseButtonAction::formatName() const
|
||||||
return (m_press ? "mouseDown" : "mouseUp");
|
return (m_press ? "mouseDown" : "mouseUp");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
InputFilter::UserScriptAction::UserScriptAction(IEventQueue* events,
|
||||||
|
const std::string& scriptCommand) :
|
||||||
|
m_scriptCommand(scriptCommand),
|
||||||
|
m_events(events)
|
||||||
|
{
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string InputFilter::UserScriptAction::getScriptCommand() const
|
||||||
|
{
|
||||||
|
return m_scriptCommand;
|
||||||
|
}
|
||||||
|
|
||||||
|
InputFilter::Action*
|
||||||
|
InputFilter::UserScriptAction::clone() const
|
||||||
|
{
|
||||||
|
return new UserScriptAction(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string InputFilter::UserScriptAction::format() const
|
||||||
|
{
|
||||||
|
return barrier::string::sprintf("userScript(%s)", m_scriptCommand.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
InputFilter::UserScriptAction::perform(const Event& event)
|
||||||
|
{
|
||||||
|
// pick screen name. if m_screen is empty then use the screen from
|
||||||
|
// event if it has one.
|
||||||
|
std::string scriptCommand = m_scriptCommand;
|
||||||
|
if (scriptCommand.empty()) {
|
||||||
|
LOG((CLOG_ERR "script ID empty"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// exec script
|
||||||
|
#if !defined(_WIN32)
|
||||||
|
std::string s = barrier::string::sprintf(R"(sh -c '%s')", scriptCommand.c_str());
|
||||||
|
#else
|
||||||
|
std::string s = barrier::string::sprintf(R"(cmd.exe /C "%s")", scriptCommand.c_str());
|
||||||
|
|
||||||
|
#endif
|
||||||
|
LOG((CLOG_DEBUG "%s",s.c_str()));
|
||||||
|
system(s.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// InputFilter::Rule
|
// InputFilter::Rule
|
||||||
//
|
//
|
||||||
|
|
|
@ -270,6 +270,23 @@ public:
|
||||||
IEventQueue* m_events;
|
IEventQueue* m_events;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// UserScriptAction
|
||||||
|
class UserScriptAction : public Action {
|
||||||
|
public:
|
||||||
|
UserScriptAction(IEventQueue* events, const std::string& scriptCommand);
|
||||||
|
|
||||||
|
std::string getScriptCommand() const;
|
||||||
|
|
||||||
|
// Action overrides
|
||||||
|
virtual Action* clone() const;
|
||||||
|
virtual String format() const;
|
||||||
|
virtual void perform(const Event&);
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string m_scriptCommand;
|
||||||
|
IEventQueue* m_events;
|
||||||
|
};
|
||||||
|
|
||||||
class Rule {
|
class Rule {
|
||||||
public:
|
public:
|
||||||
Rule();
|
Rule();
|
||||||
|
|
|
@ -2338,7 +2338,7 @@ Server::SwitchToScreenInfo::alloc(const std::string& screen)
|
||||||
SwitchToScreenInfo* info =
|
SwitchToScreenInfo* info =
|
||||||
(SwitchToScreenInfo*)malloc(sizeof(SwitchToScreenInfo) +
|
(SwitchToScreenInfo*)malloc(sizeof(SwitchToScreenInfo) +
|
||||||
screen.size());
|
screen.size());
|
||||||
strcpy(info->m_screen, screen.c_str());
|
strcpy(info->m_screen, screen.c_str()); // Compliant: we made sure the buffer is large enough
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2377,7 +2377,7 @@ Server::KeyboardBroadcastInfo::alloc(State state, const std::string& screens)
|
||||||
(KeyboardBroadcastInfo*)malloc(sizeof(KeyboardBroadcastInfo) +
|
(KeyboardBroadcastInfo*)malloc(sizeof(KeyboardBroadcastInfo) +
|
||||||
screens.size());
|
screens.size());
|
||||||
info->m_state = state;
|
info->m_state = state;
|
||||||
strcpy(info->m_screens, screens.c_str());
|
strcpy(info->m_screens, screens.c_str()); // Compliant: we made sure that screens variable ended with null
|
||||||
return info;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -179,6 +179,10 @@ public:
|
||||||
//! Return fake drag file list
|
//! Return fake drag file list
|
||||||
DragFileList getFakeDragFileList() { return m_fakeDragFileList; }
|
DragFileList getFakeDragFileList() { return m_fakeDragFileList; }
|
||||||
|
|
||||||
|
//! Return true if fucus in primary clinet
|
||||||
|
bool isServerHoldFocus() { return (m_active ==
|
||||||
|
(BaseClientProxy*) m_primaryClient); }
|
||||||
|
|
||||||
//@}
|
//@}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -53,7 +53,7 @@ protected:
|
||||||
return new MSWindowsDesks(
|
return new MSWindowsDesks(
|
||||||
true, false, m_screensaver, eventQueue,
|
true, false, m_screensaver, eventQueue,
|
||||||
new TMethodJob<MSWindowsKeyStateTests>(
|
new TMethodJob<MSWindowsKeyStateTests>(
|
||||||
this, &MSWindowsKeyStateTests::updateKeysCB), false);
|
this, &MSWindowsKeyStateTests::updateKeysCB), false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void* getEventTarget() const
|
void* getEventTarget() const
|
||||||
|
|
Loading…
Reference in New Issue