diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c9149c9..029b33f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,13 +1,14 @@ # Copyright (C) 2018 Intevation GmbH # # This file is Free Software under the GNU GPL (v>=2) # and comes with ABSOLUTELY NO WARRANTY! # See LICENSE.txt for details. include_directories(${Qt5Core_INCLUDE_DIRS}) include_directories(${CMAKE_CURRENT_SOURCE_DIR}) include_directories(util) add_subdirectory(resolver) +add_subdirectory(overlayer) diff --git a/src/overlayer/CMakeLists.txt b/src/overlayer/CMakeLists.txt new file mode 100644 index 0000000..73928ca --- /dev/null +++ b/src/overlayer/CMakeLists.txt @@ -0,0 +1,31 @@ +# Copyright (C) 2018 Intevation GmbH +# +# This file is Free Software under the GNU GPL (v>=2) +# and comes with ABSOLUTELY NO WARRANTY! +# See LICENSE.txt for details. + +set(EXECUTABLE_NAME "overlayer") + +set(EXECUTABLE_SRC + main.cpp + quitter.cpp + ${CMAKE_SOURCE_DIR}/src/img/icon.rc + ${CMAKE_SOURCE_DIR}/src/util/overlay.cpp + ${CMAKE_SOURCE_DIR}/src/util/strhelp.c +) + +add_executable(${EXECUTABLE_NAME} + ${_add_executable_params} + ${EXECUTABLE_SRC} +) + +target_link_libraries(${EXECUTABLE_NAME} + Qt5::Widgets +) + +if (WIN32) + set_target_properties(${EXECUTABLE_NAME} PROPERTIES LINK_FLAGS "-municode") +endif(WIN32) + + +install(TARGETS ${EXECUTABLE_NAME} DESTINATION bin) diff --git a/src/overlayer/main.cpp b/src/overlayer/main.cpp new file mode 100644 index 0000000..bb528c8 --- /dev/null +++ b/src/overlayer/main.cpp @@ -0,0 +1,149 @@ +/* Copyright (C) 2018 by Intevation GmbH + * + * This file is Free Software under the GNU GPL (v>=2) + * and comes with ABSOLUTELY NO WARRANTY! + * See LICENSE.txt for details. + */ + +/** @file Main entry point for the application. + */ +#include "strhelp.h" +#include "overlayer-options.h" + +#include "quitter.h" +#include "util/overlay.h" + +#include + +#include +#include +#include +#include +#include + +#ifdef Q_OS_WIN + #include + #include +#endif + +#ifndef APPNAME +#define APPNAME "Overlayer" +#endif + +#ifndef VERSION +#define VERSION "0.0" +#endif + +bool g_debug = false; + +QtMessageHandler g_default_msg_handler = NULL; + +void filterDebugOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg) +{ + if (!g_debug && type == QtDebugMsg) { + return; + } + + if (g_default_msg_handler) { + (*g_default_msg_handler)(type, context, msg); + } +} + +int realMain(int argc, char **argv); + +#if defined(WIN32) && defined(UNICODE) + +/** @brief Unicode entry point. + * + * Converts arguments to UTF-8 and executes the real + * entry point realMain. + */ +int wmain(int argc, wchar_t **argv, wchar_t **envp) +{ + char **utf8args = NULL; + + utf8args = (char**) xmalloc0 ((argc + 1) * sizeof(char*)); + + for (int i = 0; i < argc; i++) { + utf8args[i] = wchar_to_utf8(argv[i], wcslen(argv[i])); + if (utf8args[i] == NULL) { + printf ("Fatal: could not convert arguments to UTF-8.\n"); + exit(-1); + } + } + int ret = realMain(argc, utf8args); + strv_free(utf8args); + + return ret; +} +#else +int main(int argc, char **argv) +{ + return realMain(argc, argv); +} +#endif + +/** @brief The real entry point to the application. + * + * @param [in] argc the count of the arguments. + * @param [in] argv On GNU/Linux this function expects argv to be in the + * native system encoding. On Windows the arguments + * shall be UTF-8 + * + * @returns 0 on success an error code otherwise. */ +int realMain(int argc, char **argv) +{ + /* QApplication setup */ + QApplication app(argc, argv); + QApplication::setOrganizationName(QStringLiteral(APPNAME)); + QApplication::setApplicationName(QStringLiteral(APPNAME)); + QApplication::setApplicationVersion(QStringLiteral(VERSION)); + +#if 0 + /* Setup translations */ + QTranslator translator; + if (QLocale::system().name() == "C") { + /* Useful for testing / development as the primary target is german */ + translator.load(":/l10n/main_de_DE"); + } else { + translator.load(":/l10n/main_" + QLocale::system().name()); + } + app.installTranslator(&translator); +#endif + + /* Parse the command line */ + QCommandLineParser parser; + options(parser); + +#ifdef Q_OS_WIN + auto oldCodec = QTextCodec::codecForLocale(); + QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8")); +#endif + parser.process(app); +#ifdef Q_OS_WIN + QTextCodec::setCodecForLocale(oldCodec); +#endif + + g_debug = parser.isSet("debug"); + g_default_msg_handler = qInstallMessageHandler(filterDebugOutput); + + // Let's go + Quitter quitter; + Overlay *overlay; + + const auto hwnd = parser.value(QStringLiteral("hwnd")); + if (!hwnd.isEmpty()) { + bool ok; + WId id = (WId) hwnd.toInt(&ok); + if (!ok) { + std::cerr << "invalid hwnd value" << std::endl; + qApp->exit(EXIT_FAILURE); + } + overlay = new Overlay(id, parser.value(QStringLiteral("overlayText"))); + } else { + std::cerr << "no hwnd value" << std::endl; + qApp->exit(EXIT_FAILURE); + } + + return app.exec(); +} diff --git a/src/overlayer/overlayer-options.h b/src/overlayer/overlayer-options.h new file mode 100644 index 0000000..6cb448d --- /dev/null +++ b/src/overlayer/overlayer-options.h @@ -0,0 +1,34 @@ +#ifndef OVERLAYER_OPTIONS +#define OVERLAYER_OPTIONS +/* Copyright (C) 2018 by Intevation GmbH + * + * This file is Free Software under the GNU GPL (v>=2) + * and comes with ABSOLUTELY NO WARRANTY! + * See LICENSE.txt for details. + */ + +#include +#include + +/** @file Commandline options*/ +static void options(QCommandLineParser &parser) +{ + QList options; + + options + << QCommandLineOption(QStringList() << QStringLiteral("debug"), + QStringLiteral("Print debug output.")) + << QCommandLineOption(QStringLiteral("hwnd"), + QStringLiteral("Parent Window"), + QStringLiteral("windows window handle")) + << QCommandLineOption(QStringLiteral("overlayText"), + QStringLiteral("Overlay Text"), + QStringLiteral("text to overlay over hwnd")); + + for (const auto &opt: options) { + parser.addOption(opt); + } + parser.addVersionOption(); + parser.addHelpOption(); +} +#endif // OVERLAYER_OPTIONS diff --git a/src/overlayer/quitter.cpp b/src/overlayer/quitter.cpp new file mode 100644 index 0000000..be19442 --- /dev/null +++ b/src/overlayer/quitter.cpp @@ -0,0 +1,29 @@ +/* Copyright (C) 2018 by Intevation GmbH + * + * This file is Free Software under the GNU GPL (v>=2) + * and comes with ABSOLUTELY NO WARRANTY! + * See LICENSE.txt for details. + */ + + +#include +#include "quitter.h" + +#include + +void Quitter::readQuit() +{ + std::string line; + std::getline(std::cin, line); + if (std::cin.eof() || line == "quit") { + qApp->quit(); + } +} + +Quitter::Quitter() +{ + m_notifier = new QSocketNotifier(fileno(stdin), QSocketNotifier::Read, this); + connect(m_notifier, &QSocketNotifier::activated, this, [this] () { + readQuit(); + }); +} diff --git a/src/overlayer/quitter.h b/src/overlayer/quitter.h new file mode 100644 index 0000000..a983b1b --- /dev/null +++ b/src/overlayer/quitter.h @@ -0,0 +1,28 @@ +#ifndef QUITTER_H +#define QUITTER_H +/* Copyright (C) 2018 by Intevation GmbH + * + * This file is Free Software under the GNU GPL (v>=2) + * and comes with ABSOLUTELY NO WARRANTY! + * See LICENSE.txt for details. + */ + + +#include +#include +#include + +class Quitter: public QObject +{ + Q_OBJECT; + +public: + Quitter(); + +private: + QSocketNotifier *m_notifier; + + void readQuit(); +}; + +#endif // QUITTER_H