diff options
| author | 2018-04-25 18:07:30 -0400 | |
|---|---|---|
| committer | 2018-04-25 18:07:30 -0400 | |
| commit | 9b1b081cfdb1c0fb6457278775e0823f8bc10f62 (patch) | |
| tree | ce8840148d8445055ba9e4f12263b2208f234c16 /src/lib/barrier/App.cpp | |
Import Upstream version 2.0.0+dfsgupstream/2.0.0+dfsg
Diffstat (limited to 'src/lib/barrier/App.cpp')
| -rw-r--r-- | src/lib/barrier/App.cpp | 329 |
1 files changed, 329 insertions, 0 deletions
diff --git a/src/lib/barrier/App.cpp b/src/lib/barrier/App.cpp new file mode 100644 index 0000000..1f4eda3 --- /dev/null +++ b/src/lib/barrier/App.cpp @@ -0,0 +1,329 @@ +/* + * barrier -- mouse and keyboard sharing utility + * Copyright (C) 2012-2016 Symless Ltd. + * 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 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 <http://www.gnu.org/licenses/>. + */ + +#include "barrier/App.h" + +#include "base/Log.h" +#include "common/Version.h" +#include "barrier/protocol_types.h" +#include "arch/Arch.h" +#include "base/XBase.h" +#include "arch/XArch.h" +#include "base/log_outputters.h" +#include "barrier/XBarrier.h" +#include "barrier/ArgsBase.h" +#include "ipc/IpcServerProxy.h" +#include "base/TMethodEventJob.h" +#include "ipc/IpcMessage.h" +#include "ipc/Ipc.h" +#include "base/EventQueue.h" + +#if SYSAPI_WIN32 +#include "arch/win32/ArchMiscWindows.h" +#include "base/IEventQueue.h" +#include "base/TMethodJob.h" +#endif + +#include <iostream> +#include <stdio.h> + +#if WINAPI_CARBON +#include <ApplicationServices/ApplicationServices.h> +#endif + +#if defined(__APPLE__) +#include "platform/OSXDragSimulator.h" +#endif + +App* App::s_instance = nullptr; + +// +// App +// + +App::App(IEventQueue* events, CreateTaskBarReceiverFunc createTaskBarReceiver, ArgsBase* args) : + m_bye(&exit), + m_taskBarReceiver(NULL), + m_suspended(false), + m_events(events), + m_args(args), + m_fileLog(nullptr), + m_createTaskBarReceiver(createTaskBarReceiver), + m_appUtil(events), + m_ipcClient(nullptr), + m_socketMultiplexer(nullptr) +{ + assert(s_instance == nullptr); + s_instance = this; +} + +App::~App() +{ + s_instance = nullptr; + delete m_args; +} + +void +App::version() +{ + char buffer[500]; + sprintf( + buffer, + "%s %s, protocol version %d.%d\n%s", + argsBase().m_pname, + kVersion, + kProtocolMajorVersion, + kProtocolMinorVersion, + kCopyright + ); + + std::cout << buffer << std::endl; +} + +int +App::run(int argc, char** argv) +{ +#if MAC_OS_X_VERSION_10_7 + // dock hide only supported on lion :( + ProcessSerialNumber psn = { 0, kCurrentProcess }; + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" + GetCurrentProcess(&psn); +#pragma GCC diagnostic pop + + TransformProcessType(&psn, kProcessTransformToBackgroundApplication); +#endif + + // install application in to arch + appUtil().adoptApp(this); + + // HACK: fail by default (saves us setting result in each catch) + int result = kExitFailed; + + try { + result = appUtil().run(argc, argv); + } + catch (XExitApp& e) { + // instead of showing a nasty error, just exit with the error code. + // not sure if i like this behaviour, but it's probably better than + // using the exit(int) function! + result = e.getCode(); + } + catch (std::exception& e) { + LOG((CLOG_CRIT "An error occurred: %s\n", e.what())); + } + catch (...) { + LOG((CLOG_CRIT "An unknown error occurred.\n")); + } + + appUtil().beforeAppExit(); + + return result; +} + +int +App::daemonMainLoop(int, const char**) +{ +#if SYSAPI_WIN32 + SystemLogger sysLogger(daemonName(), false); +#else + SystemLogger sysLogger(daemonName(), true); +#endif + return mainLoop(); +} + +void +App::setupFileLogging() +{ + if (argsBase().m_logFile != NULL) { + m_fileLog = new FileLogOutputter(argsBase().m_logFile); + CLOG->insert(m_fileLog); + LOG((CLOG_DEBUG1 "logging to file (%s) enabled", argsBase().m_logFile)); + } +} + +void +App::loggingFilterWarning() +{ + if (CLOG->getFilter() > CLOG->getConsoleMaxLevel()) { + if (argsBase().m_logFile == NULL) { + LOG((CLOG_WARN "log messages above %s are NOT sent to console (use file logging)", + CLOG->getFilterName(CLOG->getConsoleMaxLevel()))); + } + } +} + +void +App::initApp(int argc, const char** argv) +{ + // parse command line + parseArgs(argc, argv); + + ARCH->setProfileDirectory(argsBase().m_profileDirectory); + ARCH->setPluginDirectory(argsBase().m_pluginDirectory); + + // set log filter + if (!CLOG->setFilter(argsBase().m_logFilter)) { + LOG((CLOG_PRINT "%s: unrecognized log level `%s'" BYE, + argsBase().m_pname, argsBase().m_logFilter, argsBase().m_pname)); + m_bye(kExitArgs); + } + loggingFilterWarning(); + + if (argsBase().m_enableDragDrop) { + LOG((CLOG_INFO "drag and drop enabled")); + } + + // setup file logging after parsing args + setupFileLogging(); + + // load configuration + loadConfig(); + + if (!argsBase().m_disableTray) { + + // create a log buffer so we can show the latest message + // as a tray icon tooltip + BufferedLogOutputter* logBuffer = new BufferedLogOutputter(1000); + CLOG->insert(logBuffer, true); + + // make the task bar receiver. the user can control this app + // through the task bar. + m_taskBarReceiver = m_createTaskBarReceiver(logBuffer, m_events); + } +} + +void +App::initIpcClient() +{ + m_ipcClient = new IpcClient(m_events, m_socketMultiplexer); + m_ipcClient->connect(); + + m_events->adoptHandler( + m_events->forIpcClient().messageReceived(), m_ipcClient, + new TMethodEventJob<App>(this, &App::handleIpcMessage)); +} + +void +App::cleanupIpcClient() +{ + m_ipcClient->disconnect(); + m_events->removeHandler(m_events->forIpcClient().messageReceived(), m_ipcClient); + delete m_ipcClient; +} + +void +App::handleIpcMessage(const Event& e, void*) +{ + IpcMessage* m = static_cast<IpcMessage*>(e.getDataObject()); + if (m->type() == kIpcShutdown) { + LOG((CLOG_INFO "got ipc shutdown message")); + m_events->addEvent(Event(Event::kQuit)); + } +} + +void +App::runEventsLoop(void*) +{ + m_events->loop(); + +#if defined(MAC_OS_X_VERSION_10_7) + + stopCocoaLoop(); + +#endif +} + +// +// MinimalApp +// + +MinimalApp::MinimalApp() : + App(NULL, NULL, new ArgsBase()) +{ + m_arch.init(); + setEvents(m_events); +} + +MinimalApp::~MinimalApp() +{ +} + +int +MinimalApp::standardStartup(int argc, char** argv) +{ + return 0; +} + +int +MinimalApp::runInner(int argc, char** argv, ILogOutputter* outputter, StartupFunc startup) +{ + return 0; +} + +void +MinimalApp::startNode() +{ +} + +int +MinimalApp::mainLoop() +{ + return 0; +} + +int +MinimalApp::foregroundStartup(int argc, char** argv) +{ + return 0; +} + +barrier::Screen* +MinimalApp::createScreen() +{ + return NULL; +} + +void +MinimalApp::loadConfig() +{ +} + +bool +MinimalApp::loadConfig(const String& pathname) +{ + return false; +} + +const char* +MinimalApp::daemonInfo() const +{ + return ""; +} + +const char* +MinimalApp::daemonName() const +{ + return ""; +} + +void +MinimalApp::parseArgs(int argc, const char* const* argv) +{ +} |
