diff --git a/src/lib/barrier/App.cpp b/src/lib/barrier/App.cpp index f4293b63..91238779 100644 --- a/src/lib/barrier/App.cpp +++ b/src/lib/barrier/App.cpp @@ -64,7 +64,8 @@ App::App(IEventQueue* events, CreateTaskBarReceiverFunc createTaskBarReceiver, A m_createTaskBarReceiver(createTaskBarReceiver), m_appUtil(events), m_ipcClient(nullptr), - m_socketMultiplexer(nullptr) + m_socketMultiplexer(nullptr), + m_stdin(nullptr) { assert(s_instance == nullptr); s_instance = this; @@ -74,6 +75,10 @@ App::~App() { s_instance = nullptr; delete m_args; + + if (m_stdin) { + delete(m_stdin); + } } void @@ -216,6 +221,14 @@ App::cleanupIpcClient() delete m_ipcClient; } +void +App::initStdinListen() +{ +#if !defined(_WIN32) + m_stdin = new StdinListen(m_events); +#endif +} + void App::handleIpcMessage(const Event& e, void*) { diff --git a/src/lib/barrier/App.h b/src/lib/barrier/App.h index b7c77a00..5ceaf6a0 100644 --- a/src/lib/barrier/App.h +++ b/src/lib/barrier/App.h @@ -23,6 +23,7 @@ #include "base/String.h" #include "base/Log.h" #include "base/EventQueue.h" +#include "base/StdinListen.h" #include "common/common.h" #if SYSAPI_WIN32 @@ -106,6 +107,7 @@ private: protected: void initIpcClient(); void cleanupIpcClient(); + void initStdinListen(); void runEventsLoop(void*); IArchTaskBarReceiver* m_taskBarReceiver; @@ -120,6 +122,7 @@ private: ARCH_APP_UTIL m_appUtil; IpcClient* m_ipcClient; SocketMultiplexer* m_socketMultiplexer; + StdinListen* m_stdin; }; class MinimalApp : public App { diff --git a/src/lib/base/StdinListen.cpp b/src/lib/base/StdinListen.cpp new file mode 100644 index 00000000..3612319d --- /dev/null +++ b/src/lib/base/StdinListen.cpp @@ -0,0 +1,63 @@ +/* + * barrier -- mouse and keyboard sharing utility + * Copyright (C) 2008 Debauchee Open Source Group + * + * 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 LICENSE 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. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#if !defined(_WIN32) + +#include "base/StdinListen.h" +#include "../gui/src/ShutdownCh.h" + +#include // tcgetattr/tcsetattr, read +#include // tcgetattr/tcsetattr + +StdinListen::StdinListen(IEventQueue* events) : + m_events(events), + m_thread(NULL) +{ + // disable ICANON & ECHO so we don't have to wait for a newline + // before we get data (and to keep it from being echoed back out) + termios ta; + tcgetattr(STDIN_FILENO, &ta); + _p_ta_previous = new termios(ta); + ta.c_lflag &= ~(ICANON | ECHO); + tcsetattr(STDIN_FILENO, TCSANOW, &ta); + + m_thread = new Thread(new TMethodJob( + this, &StdinListen::stdinThread)); +} + +StdinListen::~StdinListen() +{ + tcsetattr(STDIN_FILENO, TCSANOW, _p_ta_previous); + delete _p_ta_previous; +} + +void +StdinListen::stdinThread(void *) +{ + char ch; + + while (1) { + if (read(STDIN_FILENO, &ch, 1) == 1) { + if (ch == ShutdownCh) { + m_events->addEvent(Event(Event::kQuit)); + break; + } + } + } +} + +#endif // !defined(_WIN32) \ No newline at end of file diff --git a/src/lib/base/StdinListen.h b/src/lib/base/StdinListen.h new file mode 100644 index 00000000..8491ba59 --- /dev/null +++ b/src/lib/base/StdinListen.h @@ -0,0 +1,50 @@ +/* + * barrier -- mouse and keyboard sharing utility + * Copyright (C) 2008 Debauchee Open Source Group + * + * 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 LICENSE 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. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#if defined(_WIN32) + +class StdinListen +{ +public: + void stdinThread(void*) {}; +}; + +#else + +#include "base/IEventQueue.h" +#include "base/TMethodJob.h" +#include "mt/Thread.h" + +struct termios; + +class StdinListen +{ +public: + explicit StdinListen(IEventQueue* events); + ~StdinListen(); + +private: + void stdinThread(void*); + + IEventQueue* m_events; + Thread* m_thread; + termios* _p_ta_previous; +}; + +#endif \ No newline at end of file