diff --git a/src/blackcore/blackcore.pro b/src/blackcore/blackcore.pro index 84c4a7a1f..539590ce9 100644 --- a/src/blackcore/blackcore.pro +++ b/src/blackcore/blackcore.pro @@ -30,6 +30,16 @@ win32 { SOURCES += $$PWD/win/*.cpp } +unix:!macx { + HEADERS += $$PWD/linux/*.h + SOURCES += $$PWD/linux/*.cpp +} + +macx { + HEADERS += $$PWD/mac/*.h + SOURCES += $$PWD/mac/*.cpp +} + win32:!win32-g++*: PRE_TARGETDEPS += ../../lib/blackmisc.lib ../../lib/blacksound.lib ../../lib/blacksim.lib else: PRE_TARGETDEPS += ../../lib/libblackmisc.a ../../lib/libblacksound.a ../../lib/libblacksim.a diff --git a/src/blackcore/keyboard.cpp b/src/blackcore/keyboard.cpp index e8b764ae8..a5d118ef9 100644 --- a/src/blackcore/keyboard.cpp +++ b/src/blackcore/keyboard.cpp @@ -7,6 +7,12 @@ #if defined(Q_OS_WIN) #include "blackcore/win/keyboard_windows.h" +#elif defined(Q_OS_LINUX) + #include "blackcore/linux/keyboard_linux.h" +#elif defined(Q_OS_OSX) + #include "blackcore/mac/keyboard_mac.h" +#else + #error "Platform is not supported!" #endif namespace BlackCore @@ -24,8 +30,10 @@ namespace BlackCore { #if defined(Q_OS_WIN) m_instance = new CKeyboardWindows; -#elif defined(Q_OS_OSX) #elif defined(Q_OS_LINUX) + m_instance = new CKeyboardLinux; +#elif defined(Q_OS_OSX) + m_instance = new CKeyboardMac; #endif Q_ASSERT_X(m_instance, "IKeyboard::getInstance", "Pointer to IKeyboard is NULL!"); m_instance->init(); diff --git a/src/blackcore/linux/keyboard_linux.cpp b/src/blackcore/linux/keyboard_linux.cpp new file mode 100644 index 000000000..c12a86053 --- /dev/null +++ b/src/blackcore/linux/keyboard_linux.cpp @@ -0,0 +1,110 @@ +/* Copyright (C) 2013 VATSIM Community / contributors + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "keyboard_linux.h" +#include + +using namespace BlackMisc::Hardware; + +namespace BlackCore +{ + CKeyboardLinux::CKeyboardLinux(QObject *parent) : + IKeyboard(parent), + m_mode(Mode_Nominal) + { + } + + CKeyboardLinux::~CKeyboardLinux() + { + } + + bool CKeyboardLinux::init() + { + return true; + } + + void CKeyboardLinux::startCapture(bool ignoreNextKey) + { + m_mode = Mode_Capture; + m_ignoreNextKey = ignoreNextKey; + m_pressedKey.setKeyObject(CKeyboardKey()); + } + + int CKeyboardLinux::sizeOfRegisteredFunctions() const + { + int size = 0; + foreach (QList functions, m_registeredFunctions) + { + size += functions.size(); + } + return size; + } + + void CKeyboardLinux::triggerKey(const CKeyboardKey key, bool isPressed) + { + callFunctionsBy(key, isPressed); + } + + IKeyboard::RegistrationHandle CKeyboardLinux::registerHotkeyImpl(BlackMisc::Hardware::CKeyboardKey key, QObject *receiver, std::function function) + { + IKeyboard::RegistrationHandle handle; + + // Workaround: Remove key function. Otherwise operator== will not + // work when we create the key value object by pressed keys + key.setFunction(BlackMisc::Hardware::CKeyboardKey::HotkeyNone); + + if (!key.hasModifier() && !key.hasKey()) + { + return handle; + } + + if (receiver == nullptr) + return handle; + + handle.m_key = key; + handle.m_receiver = receiver; + handle.function = function; + + QList functions = m_registeredFunctions.value(key); + + functions.append(handle); + m_registeredFunctions.insert(key, functions); + + return handle; + } + + void CKeyboardLinux::unregisterHotkeyImpl(const IKeyboard::RegistrationHandle &handle) + { + QList functions = m_registeredFunctions.value(handle.m_key); + functions.removeAll(handle); + m_registeredFunctions.insert(handle.m_key, functions); + } + + void CKeyboardLinux::unregisterAllHotkeysImpl() + { + m_registeredFunctions.clear(); + } + + void CKeyboardLinux::sendCaptureNotification(const CKeyboardKey &key, bool isFinished) + { + if (isFinished) + emit keySelectionFinished(key); + else + emit keySelectionChanged(key); + } + + void CKeyboardLinux::callFunctionsBy(const CKeyboardKey &key, bool isPressed) + { + QList functionHandles = m_registeredFunctions.value(key); + foreach (IKeyboard::RegistrationHandle functionHandle, functionHandles) + { + if (functionHandle.m_receiver.isNull()) + { + continue; + } + functionHandle.function(isPressed); + } + } +} diff --git a/src/blackcore/linux/keyboard_linux.h b/src/blackcore/linux/keyboard_linux.h new file mode 100644 index 000000000..dc9c73303 --- /dev/null +++ b/src/blackcore/linux/keyboard_linux.h @@ -0,0 +1,87 @@ +/* Copyright (C) 2013 VATSIM Community / contributors + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/*! + \file +*/ + +#ifndef BLACKCORE_KEYBOARD_LINUX_H +#define BLACKCORE_KEYBOARD_LINUX_H + +#include "blackcore/keyboard.h" +#include "blackmisc/hwkeyboardkey.h" +#include + +namespace BlackCore +{ + //! \brief Linux implemenation of IKeyboard using hook procedure + //! \todo Change QHash to a CCollection object + class CKeyboardLinux : public IKeyboard + { + Q_OBJECT + public: + + //! \brief Destructor + virtual ~CKeyboardLinux(); + + //! \copydoc IKeyboard::selectKey() + virtual void startCapture(bool ignoreNextKey = false) override; + + //! \copydoc IKeyboard::sizeOfRegisteredFunctions() + virtual int sizeOfRegisteredFunctions() const override; + + //! \copydoc IKeyboard::triggerKey() + virtual void triggerKey(const BlackMisc::Hardware::CKeyboardKey key, bool isPressed) override; + + protected: + + friend class IKeyboard; + + //! \brief Constructor + CKeyboardLinux(QObject *parent = nullptr); + + //! \brief Copy Constructor + CKeyboardLinux(CKeyboardLinux const&); + + //! \copydoc IKeyboard::init() + virtual bool init() override; + + //! \brief Assignment operator + void operator=(CKeyboardLinux const&); + + //! \copydoc IKeyboard::registerHotKeyImpl() + virtual IKeyboard::RegistrationHandle registerHotkeyImpl(BlackMisc::Hardware::CKeyboardKey key, QObject *receiver, std::function function) override; + + //! \copydoc IKeyboard::unregisterHotkeyImpl() + virtual void unregisterHotkeyImpl(const IKeyboard::RegistrationHandle &handle) override; + + //! \copydoc IKeyboard::unregisterHotkeyImpl() + virtual void unregisterAllHotkeysImpl() override; + + private: + + /*! + * \brief Constructor + * \param keySet + * \param isFinished + */ + void sendCaptureNotification(const BlackMisc::Hardware::CKeyboardKey &key, bool isFinished); + + /*! + * \brief Calls registered functions on keyboard event + * \param keySet + * \param isPressed + */ + void callFunctionsBy(const BlackMisc::Hardware::CKeyboardKey &keySet, bool isPressed); + + + QHash> m_registeredFunctions; //!< Registered hotkey functions + BlackMisc::Hardware::CKeyboardKey m_pressedKey; //!< Set of virtual keys pressed in the last cycle + bool m_ignoreNextKey; //!< Is true if the next key needs to be ignored + Mode m_mode; //!< Operation mode + }; +} + +#endif // BLACKCORE_KEYBOARD_LINUX_H diff --git a/src/blackcore/mac/keyboard_mac.cpp b/src/blackcore/mac/keyboard_mac.cpp new file mode 100644 index 000000000..81210f4c5 --- /dev/null +++ b/src/blackcore/mac/keyboard_mac.cpp @@ -0,0 +1,110 @@ +/* Copyright (C) 2013 VATSIM Community / contributors + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "keyboard_mac.h" +#include + +using namespace BlackMisc::Hardware; + +namespace BlackCore +{ + CKeyboardMac::CKeyboardMac(QObject *parent) : + IKeyboard(parent), + m_mode(Mode_Nominal) + { + } + + CKeyboardMac::~CKeyboardMac() + { + } + + bool CKeyboardMac::init() + { + return true; + } + + void CKeyboardMac::startCapture(bool ignoreNextKey) + { + m_mode = Mode_Capture; + m_ignoreNextKey = ignoreNextKey; + m_pressedKey.setKeyObject(CKeyboardKey()); + } + + int CKeyboardMac::sizeOfRegisteredFunctions() const + { + int size = 0; + foreach (QList functions, m_registeredFunctions) + { + size += functions.size(); + } + return size; + } + + void CKeyboardMac::triggerKey(const CKeyboardKey key, bool isPressed) + { + callFunctionsBy(key, isPressed); + } + + IKeyboard::RegistrationHandle CKeyboardMac::registerHotkeyImpl(BlackMisc::Hardware::CKeyboardKey key, QObject *receiver, std::function function) + { + IKeyboard::RegistrationHandle handle; + + // Workaround: Remove key function. Otherwise operator== will not + // work when we create the key value object by pressed keys + key.setFunction(BlackMisc::Hardware::CKeyboardKey::HotkeyNone); + + if (!key.hasModifier() && !key.hasKey()) + { + return handle; + } + + if (receiver == nullptr) + return handle; + + handle.m_key = key; + handle.m_receiver = receiver; + handle.function = function; + + QList functions = m_registeredFunctions.value(key); + + functions.append(handle); + m_registeredFunctions.insert(key, functions); + + return handle; + } + + void CKeyboardMac::unregisterHotkeyImpl(const IKeyboard::RegistrationHandle &handle) + { + QList functions = m_registeredFunctions.value(handle.m_key); + functions.removeAll(handle); + m_registeredFunctions.insert(handle.m_key, functions); + } + + void CKeyboardMac::unregisterAllHotkeysImpl() + { + m_registeredFunctions.clear(); + } + + void CKeyboardMac::sendCaptureNotification(const CKeyboardKey &key, bool isFinished) + { + if (isFinished) + emit keySelectionFinished(key); + else + emit keySelectionChanged(key); + } + + void CKeyboardMac::callFunctionsBy(const CKeyboardKey &key, bool isPressed) + { + QList functionHandles = m_registeredFunctions.value(key); + foreach (IKeyboard::RegistrationHandle functionHandle, functionHandles) + { + if (functionHandle.m_receiver.isNull()) + { + continue; + } + functionHandle.function(isPressed); + } + } +} diff --git a/src/blackcore/mac/keyboard_mac.h b/src/blackcore/mac/keyboard_mac.h new file mode 100644 index 000000000..ea4b8373f --- /dev/null +++ b/src/blackcore/mac/keyboard_mac.h @@ -0,0 +1,87 @@ +/* Copyright (C) 2013 VATSIM Community / contributors + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/*! + \file +*/ + +#ifndef BLACKCORE_KEYBOARD_MAC_H +#define BLACKCORE_KEYBOARD_MAC_H + +#include "blackcore/keyboard.h" +#include "blackmisc/hwkeyboardkey.h" +#include + +namespace BlackCore +{ + //! \brief Linux implemenation of IKeyboard using hook procedure + //! \todo Change QHash to a CCollection object + class CKeyboardMac : public IKeyboard + { + Q_OBJECT + public: + + //! \brief Destructor + virtual ~CKeyboardMac(); + + //! \copydoc IKeyboard::selectKey() + virtual void startCapture(bool ignoreNextKey = false) override; + + //! \copydoc IKeyboard::sizeOfRegisteredFunctions() + virtual int sizeOfRegisteredFunctions() const override; + + //! \copydoc IKeyboard::triggerKey() + virtual void triggerKey(const BlackMisc::Hardware::CKeyboardKey key, bool isPressed) override; + + protected: + + friend class IKeyboard; + + //! \brief Constructor + CKeyboardMac(QObject *parent = nullptr); + + //! \brief Copy Constructor + CKeyboardMac(CKeyboardMac const&); + + //! \copydoc IKeyboard::init() + virtual bool init() override; + + //! \brief Assignment operator + void operator=(CKeyboardMac const&); + + //! \copydoc IKeyboard::registerHotKeyImpl() + virtual IKeyboard::RegistrationHandle registerHotkeyImpl(BlackMisc::Hardware::CKeyboardKey key, QObject *receiver, std::function function) override; + + //! \copydoc IKeyboard::unregisterHotkeyImpl() + virtual void unregisterHotkeyImpl(const IKeyboard::RegistrationHandle &handle) override; + + //! \copydoc IKeyboard::unregisterHotkeyImpl() + virtual void unregisterAllHotkeysImpl() override; + + private: + + /*! + * \brief Constructor + * \param keySet + * \param isFinished + */ + void sendCaptureNotification(const BlackMisc::Hardware::CKeyboardKey &key, bool isFinished); + + /*! + * \brief Calls registered functions on keyboard event + * \param keySet + * \param isPressed + */ + void callFunctionsBy(const BlackMisc::Hardware::CKeyboardKey &keySet, bool isPressed); + + + QHash> m_registeredFunctions; //!< Registered hotkey functions + BlackMisc::Hardware::CKeyboardKey m_pressedKey; //!< Set of virtual keys pressed in the last cycle + bool m_ignoreNextKey; //!< Is true if the next key needs to be ignored + Mode m_mode; //!< Operation mode + }; +} + +#endif // BLACKCORE_KEYBOARD_MAC_H