Add skeleton keyboard implementation for Mac and Linux

refs #206
This commit is contained in:
Roland Winklmeier
2014-04-13 18:57:45 +02:00
parent 84f389262c
commit 9e89618b45
6 changed files with 413 additions and 1 deletions

View File

@@ -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

View File

@@ -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();

View File

@@ -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 <QDebug>
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<IKeyboard::RegistrationHandle> 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<void(bool)> 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<IKeyboard::RegistrationHandle> functions = m_registeredFunctions.value(key);
functions.append(handle);
m_registeredFunctions.insert(key, functions);
return handle;
}
void CKeyboardLinux::unregisterHotkeyImpl(const IKeyboard::RegistrationHandle &handle)
{
QList<IKeyboard::RegistrationHandle> 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<IKeyboard::RegistrationHandle> functionHandles = m_registeredFunctions.value(key);
foreach (IKeyboard::RegistrationHandle functionHandle, functionHandles)
{
if (functionHandle.m_receiver.isNull())
{
continue;
}
functionHandle.function(isPressed);
}
}
}

View File

@@ -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 <QHash>
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<void(bool)> 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<BlackMisc::Hardware::CKeyboardKey, QList<IKeyboard::RegistrationHandle>> 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

View File

@@ -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 <QDebug>
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<IKeyboard::RegistrationHandle> 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<void(bool)> 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<IKeyboard::RegistrationHandle> functions = m_registeredFunctions.value(key);
functions.append(handle);
m_registeredFunctions.insert(key, functions);
return handle;
}
void CKeyboardMac::unregisterHotkeyImpl(const IKeyboard::RegistrationHandle &handle)
{
QList<IKeyboard::RegistrationHandle> 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<IKeyboard::RegistrationHandle> functionHandles = m_registeredFunctions.value(key);
foreach (IKeyboard::RegistrationHandle functionHandle, functionHandles)
{
if (functionHandle.m_receiver.isNull())
{
continue;
}
functionHandle.function(isPressed);
}
}
}

View File

@@ -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 <QHash>
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<void(bool)> 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<BlackMisc::Hardware::CKeyboardKey, QList<IKeyboard::RegistrationHandle>> 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