refs #453 Refactor CInputManger and low level input handlers

This commit is contained in:
Roland Winklmeier
2015-08-14 20:21:27 +02:00
committed by Mathew Sutcliffe
parent 63c7c6be0d
commit 199a1e5fcb
31 changed files with 609 additions and 1086 deletions

View File

@@ -28,11 +28,6 @@ namespace BlackCore
// this->m_dBusInterface = new CGenericDBusInterface(serviceName, IContextApplication::ObjectPath(), IContextApplication::InterfaceName(), connection, this);
this->relaySignals(serviceName, connection);
// Enable event forwarding from GUI process to core
CInputManager *inputManager = CInputManager::getInstance();
connect(inputManager, &CInputManager::hotkeyFuncEvent, this, &CContextApplicationProxy::processHotkeyFuncEvent);
inputManager->setEventForwarding(true);
connect(this, &IContextApplication::messageLogged, this, [](const CStatusMessage & message, const CIdentifier & origin)
{
if (!origin.isFromSameProcess())

View File

@@ -26,7 +26,7 @@
using namespace BlackMisc;
using namespace BlackMisc::Aviation;
using namespace BlackMisc::Audio;
using namespace BlackMisc::Hardware;
using namespace BlackMisc::Input;
using namespace BlackSound;
namespace BlackCore
@@ -42,10 +42,6 @@ namespace BlackCore
// own aircraft may or may not be available
const CCallsign ownCallsign = (this->getIContextOwnAircraft()) ? getIContextOwnAircraft()->getOwnAircraft().getCallsign() : CCallsign();
// Register PTT hotkey function
m_inputManager = CInputManager::getInstance();
m_handlePtt = m_inputManager->registerHotkeyFunc(CHotkeyFunction::Ptt(), this, &CContextAudio::ps_setVoiceTransmission);
m_channel1 = m_voice->createVoiceChannel();
m_channel1->setOwnAircraftCallsign(ownCallsign);
connect(m_channel1.data(), &IVoiceChannel::connectionStatusChanged, this, &CContextAudio::ps_connectionStatusChanged);

View File

@@ -21,7 +21,6 @@
#include "voice_channel.h"
#include "audio_device.h"
#include "audio_mixer.h"
#include "input_manager.h"
#include "blackinput/keyboard.h"
#include "blackmisc/audio/voiceroomlist.h"
@@ -154,8 +153,6 @@ namespace BlackCore
QSharedPointer<IVoiceChannel> getVoiceChannelBy(const BlackMisc::Audio::CVoiceRoom &voiceRoom);
CInputManager *m_inputManager = nullptr;
CInputManager::RegistrationHandle m_handlePtt;
std::unique_ptr<IVoice> m_voice; //!< underlying voice lib
std::unique_ptr<IAudioMixer> m_audioMixer;

View File

@@ -4,107 +4,152 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "input_manager.h"
#include "blackmisc/input/keyboardkeylist.h"
using namespace BlackInput;
using namespace BlackMisc;
using namespace BlackMisc::Hardware;
using namespace BlackMisc::Input;
namespace BlackCore
{
CInputManager *CInputManager::m_instance = nullptr;
CInputManager::CInputManager(QObject *parent) :
QObject(parent),
m_keyboard(IKeyboard::getInstance()),
m_joystick(IJoystick::getInstance())
m_keyboard(std::move(IKeyboard::create(this))),
m_joystick(std::move(IJoystick::create(this)))
{
connect(m_keyboard, &IKeyboard::keyUp, this, &CInputManager::ps_processKeyboardKeyUp);
connect(m_keyboard, &IKeyboard::keyDown, this, &CInputManager::ps_processKeyboardKeyDown);
connect(m_joystick, &IJoystick::buttonUp, this, &CInputManager::ps_processJoystickButtonUp);
connect(m_joystick, &IJoystick::buttonDown, this, &CInputManager::ps_processJoystickButtonDown);
connect(m_keyboard.get(), &IKeyboard::keyCombinationChanged, this, &CInputManager::ps_processKeyCombinationChanged);
connect(m_joystick.get(), &IJoystick::buttonCombinationChanged, this, &CInputManager::ps_processButtonCombinationChanged);
}
CInputManager *CInputManager::getInstance()
CInputManager *CInputManager::instance()
{
if (!m_instance)
static CInputManager instance;
return &instance;
}
void CInputManager::registerAction(const QString &action)
{
if (!m_availableActions.contains(action))
{
m_instance = new CInputManager();
m_availableActions.push_back(action);
emit hotkeyActionRegistered( { action } );
}
return m_instance;
}
void CInputManager::changeHotkeySettings(Settings::CSettingKeyboardHotkeyList hotkeys)
void CInputManager::registerRemoteActions(const QStringList &actions)
{
CKeyboardKeyList keyList;
for (Settings::CSettingKeyboardHotkey settingHotkey : hotkeys)
for (const auto &action : actions)
{
CKeyboardKey key = settingHotkey.getKey();
if (key.isEmpty()) continue;
m_hashKeyboardKeyFunctions.insert(key, settingHotkey.getFunction());
keyList.push_back(key);
if (!m_availableActions.contains(action))
{
m_availableActions.push_back(action);
emit hotkeyActionRegistered( { action } );
}
}
m_keyboard->setKeysToMonitor(keyList);
}
void CInputManager::ps_processKeyboardKeyDown(const CKeyboardKey &key)
void CInputManager::unbind(int index)
{
if (!m_hashKeyboardKeyFunctions.contains(key)) return;
// Get configured hotkey function
CHotkeyFunction hotkeyFunc = m_hashKeyboardKeyFunctions.value(key);
callFunctionsBy(hotkeyFunc, true);
auto info = std::find_if (m_boundActions.begin(), m_boundActions.end(), [index] (const BindInfo &info) { return info.m_index == index; });
if (info != m_boundActions.end())
{
m_boundActions.erase(info);
}
}
void CInputManager::ps_processKeyboardKeyUp(const CKeyboardKey &key)
void CInputManager::ps_changeHotkeySettings()
{
if (!m_hashKeyboardKeyFunctions.contains(key)) return;
m_configuredActions.clear();
for (CActionHotkey actionHotkey : m_actionHotkeys.get())
{
CHotkeyCombination combination = actionHotkey.getCombination();
if (combination.isEmpty()) continue;
// Get configured hotkey function
CHotkeyFunction hotkeyFunc = m_hashKeyboardKeyFunctions.value(key);
callFunctionsBy(hotkeyFunc, false);
m_configuredActions.insert(combination, actionHotkey.getAction());
}
}
void CInputManager::ps_processJoystickButtonDown(const CJoystickButton &button)
void CInputManager::ps_processKeyCombinationChanged(const CHotkeyCombination &combination)
{
qDebug() << "Pressed Button" << button.getButtonIndex();
if (!m_hashJoystickKeyFunctions.contains(button)) return;
// Get configured hotkey function
CHotkeyFunction hotkeyFunc = m_hashJoystickKeyFunctions.value(button);
callFunctionsBy(hotkeyFunc, true);
// Merge in the joystick part
CHotkeyCombination copy(combination);
copy.setJoystickButtons(m_lastCombination.getJoystickButtons());
processCombination(copy);
}
void CInputManager::ps_processJoystickButtonUp(const CJoystickButton &button)
void CInputManager::ps_processButtonCombinationChanged(const CHotkeyCombination &combination)
{
qDebug() << "Released Button" << button.getButtonIndex();
if (!m_hashJoystickKeyFunctions.contains(button)) return;
// Get configured hotkey function
CHotkeyFunction hotkeyFunc = m_hashJoystickKeyFunctions.value(button);
callFunctionsBy(hotkeyFunc, false);
// Merge in the keyboard keys
CHotkeyCombination copy(combination);
copy.setKeyboardKeys(m_lastCombination.getKeyboardKeys());
processCombination(copy);
}
void CInputManager::callFunctionsBy(const CHotkeyFunction &hotkeyFunction, bool isKeyDown)
void CInputManager::startCapture()
{
BlackMisc::Event::CEventHotkeyFunction hotkeyEvent(hotkeyFunction, isKeyDown);
if(m_eventForwardingEnabled) emit hotkeyFuncEvent(hotkeyEvent);
if (!m_hashRegisteredFunctions.contains(hotkeyFunction)) return;
auto func = m_hashRegisteredFunctions.value(hotkeyFunction);
func(isKeyDown);
m_captureActive = true;
m_capturedCombination = {};
}
CInputManager::RegistrationHandle CInputManager::registerHotkeyFuncImpl(const BlackMisc::CHotkeyFunction &hotkeyFunction,
QObject *receiver,
std::function<void (bool)> function)
void CInputManager::callFunctionsBy(const QString &action, bool isKeyDown)
{
m_hashRegisteredFunctions.insert(hotkeyFunction, function);
if (action.isEmpty()) { return; }
if(m_actionRelayingEnabled) emit remoteActionFromLocal(action, isKeyDown);
RegistrationHandle handle;
handle.function = function;
handle.hotkeyFunction = hotkeyFunction;
handle.m_receiver = receiver;
return handle;
for (const auto &boundAction : m_boundActions)
{
if (boundAction.m_action == action)
{
boundAction.m_function(isKeyDown);
}
}
}
void CInputManager::triggerKey(const CHotkeyCombination &combination, bool isPressed)
{
Q_UNUSED(isPressed)
QString previousAction = m_configuredActions.value(m_lastCombination);
QString action = m_configuredActions.value(combination);
callFunctionsBy(previousAction, false);
callFunctionsBy(action, true);
m_lastCombination = combination;
}
int CInputManager::bindImpl(const QString &action, QObject *receiver, std::function<void (bool)> function)
{
static int index = 0;
Q_ASSERT(index < INT_MAX);
BindInfo info;
info.m_index = index;
++index;
info.m_function = function;
info.m_action = action;
info.m_receiver = receiver;
m_boundActions.push_back(info);
return info.m_index;
}
void CInputManager::processCombination(const CHotkeyCombination &combination)
{
if (m_captureActive)
{
if (combination.size() < m_capturedCombination.size())
{
emit combinationSelectionFinished(m_capturedCombination);
m_captureActive = false;
}
else
{
emit combinationSelectionChanged(combination);
m_capturedCombination = combination;
}
}
QString previousAction = m_configuredActions.value(m_lastCombination);
QString action = m_configuredActions.value(combination);
m_lastCombination = combination;
callFunctionsBy(previousAction, false);
callFunctionsBy(action, true);
}
}

View File

@@ -7,15 +7,13 @@
#define BLACKCORE_INPUTMANAGER_H
#include "blackcoreexport.h"
#include "blackcore/settings/application.h"
#include "blackinput/keyboard.h"
#include "blackinput/joystick.h"
#include "blackmisc/hardware/keyboardkeylist.h"
#include "blackmisc/hardware/joystickbutton.h"
#include "blackmisc/hotkeyfunction.h"
#include "blackmisc/setkeyboardhotkeylist.h"
#include "blackmisc/eveventhotkeyfunction.h"
#include "blackmisc/input/hotkeycombination.h"
#include <QObject>
#include <QHash>
#include <QVector>
#include <type_traits>
#include <functional>
@@ -29,62 +27,67 @@ namespace BlackCore
Q_OBJECT
public:
//! Register new action
void registerAction(const QString &action);
//! \brief Handle to a registered hotkey function
struct RegistrationHandle
{
//! \brief Constructor
RegistrationHandle() {}
BlackMisc::CHotkeyFunction hotkeyFunction; //!< Registered hotkey function
QPointer<QObject> m_receiver; //!< Registered receiver
std::function<void(bool)> function; //!< Registered function
};
//! Register remote actions
void registerRemoteActions(const QStringList &actions);
//! Register a new hotkey function
RegistrationHandle registerHotkeyFunc(const BlackMisc::CHotkeyFunction &hotkeyFunction, QObject *receiver, const QByteArray &slotName)
{
auto function = [=](bool isKeyDown){ QMetaObject::invokeMethod(receiver, slotName, Q_ARG(bool, isKeyDown)); };
return registerHotkeyFuncImpl(hotkeyFunction, receiver, function);
}
//! Register a new hotkey function
template <class RecvObj>
RegistrationHandle registerHotkeyFunc(const BlackMisc::CHotkeyFunction &hotkeyFunction, RecvObj *receiver, void (RecvObj:: *slotPointer)(bool))
template <typename RecvObj>
int bind(const QString &action, RecvObj *receiver, void (RecvObj:: *slotPointer)(bool))
{
using namespace std::placeholders;
auto function = std::bind(slotPointer, receiver, _1);
return registerHotkeyFuncImpl(hotkeyFunction, receiver, function);
return bindImpl(action, receiver, function);
}
//! Register a new hotkey function
template <class Func>
RegistrationHandle registerHotkeyFunc(const BlackMisc::CHotkeyFunction &hotkeyFunction, QObject *receiver, Func functionObject)
template <typename Func>
int bind(const QString &action, QObject *receiver, Func functionObject)
{
return registerHotkeyFuncImpl(hotkeyFunction, receiver, functionObject);
return bindImpl(action, receiver, functionObject);
}
//! Unbind a slot
void unbind(int index);
//!
//! Select a key combination as hotkey. This method returns immediatly.
//! Listen for signals combinationSelectionChanged and combinationSelectionFinished
//! to retrieve the user input.
void startCapture();
//! Deletes all registered hotkeys. Be careful with this method!
void resetAllHotkeyFuncs() { m_hashRegisteredFunctions.clear(); }
void resetAllActions() { m_configuredActions.clear(); }
//! Get all available and known actions
QStringList allAvailableActions() const { return m_availableActions; }
//! Enable event forwarding to core
void setEventForwarding(bool enabled) { m_eventForwardingEnabled = enabled; }
//! Creates a native keyboard handler object
static CInputManager *getInstance();
public slots:
//! Change hotkey settings
void changeHotkeySettings(BlackMisc::Settings::CSettingKeyboardHotkeyList hotkeys);
void setForwarding(bool enabled) { m_actionRelayingEnabled = enabled; }
//! Call functions by hotkeyfunction
void callFunctionsBy(const BlackMisc::CHotkeyFunction &hotkeyFunction, bool isKeyDown);
void callFunctionsBy(const QString &action, bool isKeyDown);
//! Triggers a key event manually and calls the registered functions.
void triggerKey(const BlackMisc::Input::CHotkeyCombination &combination, bool isPressed);
//! Creates a native keyboard handler object
static CInputManager *instance();
signals:
//! Event hotkeyfunction occured
void hotkeyFuncEvent(const BlackMisc::Event::CEventHotkeyFunction &event);
void remoteActionFromLocal(const QString &action, bool argument);
//! Selected combination has changed
void combinationSelectionChanged(const BlackMisc::Input::CHotkeyCombination &combination);
//! Combination selection has finished
void combinationSelectionFinished(const BlackMisc::Input::CHotkeyCombination &combination);
//! New hotkey action is registered
void hotkeyActionRegistered(const QStringList &actions);
protected:
//! Constructor
@@ -92,28 +95,43 @@ namespace BlackCore
private slots:
void ps_processKeyboardKeyDown(const BlackMisc::Hardware::CKeyboardKey &);
void ps_processKeyCombinationChanged(const BlackMisc::Input::CHotkeyCombination &combination);
void ps_processKeyboardKeyUp(const BlackMisc::Hardware::CKeyboardKey &);
void ps_processButtonCombinationChanged(const BlackMisc::Input::CHotkeyCombination &combination);
void ps_processJoystickButtonDown(const BlackMisc::Hardware::CJoystickButton &button);
void ps_processJoystickButtonUp(const BlackMisc::Hardware::CJoystickButton &button);
//! Change hotkey settings
void ps_changeHotkeySettings();
private:
//! Handle to a bound action
struct BindInfo
{
// Using unique int intex for identification because std::function does not have a operator==
int m_index = 0;
QString m_action;
QPointer<QObject> m_receiver;
std::function<void(bool)> m_function;
};
RegistrationHandle registerHotkeyFuncImpl(const BlackMisc::CHotkeyFunction &hotkeyFunction, QObject *receiver, std::function<void(bool)> function);
int bindImpl(const QString &action, QObject *receiver, std::function<void(bool)> function);
void processCombination(const BlackMisc::Input::CHotkeyCombination &combination);
static CInputManager *m_instance;
BlackInput::IKeyboard *m_keyboard = nullptr;
BlackInput::IJoystick *m_joystick = nullptr;
std::unique_ptr<BlackInput::IKeyboard> m_keyboard;
std::unique_ptr<BlackInput::IJoystick> m_joystick;
QHash<BlackMisc::CHotkeyFunction, std::function<void(bool)> > m_hashRegisteredFunctions;
QHash<BlackMisc::Hardware::CKeyboardKey, BlackMisc::CHotkeyFunction> m_hashKeyboardKeyFunctions;
QHash<BlackMisc::Hardware::CJoystickButton, BlackMisc::CHotkeyFunction> m_hashJoystickKeyFunctions;
QStringList m_availableActions;
QHash<BlackMisc::Input::CHotkeyCombination, QString> m_configuredActions;
QVector<BindInfo> m_boundActions;
bool m_eventForwardingEnabled = false;
bool m_actionRelayingEnabled = false;
bool m_captureActive = false;
BlackMisc::Input::CHotkeyCombination m_lastCombination;
BlackMisc::Input::CHotkeyCombination m_capturedCombination;
BlackCore::CSetting<BlackCore::Settings::Application::ActionHotkeys> m_actionHotkeys { this, &CInputManager::ps_changeHotkeySettings };
};
}

View File

@@ -0,0 +1,46 @@
/* Copyright (C) 2015
* swift project Community / Contributors
*
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
* directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project,
* including this file, may be copied, modified, propagated, or distributed except according to the terms
* contained in the LICENSE file.
*/
//! \file
#ifndef BLACKCORE_SETTINGS_APPLICATION_H
#define BLACKCORE_SETTINGS_APPLICATION_H
#include "blackcore/settingscache.h"
#include "blackmisc/input/actionhotkeylist.h"
namespace BlackCore
{
namespace Settings
{
namespace Application
{
//! User configured hotkeys
struct ActionHotkeys : public CSettingTrait<BlackMisc::Input::CActionHotkeyList>
{
//! \copydoc BlackCore::CSetting::key
static const char *key() { return "application/actionhotkeys"; }
//! \copydoc BlackCore::CSetting::isValid
static bool isValid(const BlackMisc::Input::CActionHotkeyList &value)
{
for (const auto &actionHotkey : value)
{
if (actionHotkey.getApplicableMachine().getMachineName().isEmpty() ||
actionHotkey.getAction().isEmpty() ||
actionHotkey.getCombination().isEmpty()) { return false; }
}
return true;
}
};
}
}
}
#endif

View File

@@ -21,27 +21,23 @@
namespace BlackInput
{
IJoystick *IJoystick::m_instance = nullptr;
IJoystick::IJoystick(QObject *parent) :
QObject(parent)
{
}
IJoystick *IJoystick::getInstance()
std::unique_ptr<IJoystick> IJoystick::create(QObject *parent)
{
if (!m_instance)
{
#if defined(Q_OS_WIN)
m_instance = new CJoystickWindows;
std::unique_ptr<IJoystick> ptr(new CJoystickWindows(parent));
#elif defined(Q_OS_LINUX)
m_instance = new CJoystickLinux;
std::unique_ptr<IJoystick> ptr(new CJoystickLinux(parent));
#elif defined(Q_OS_OSX)
m_instance = new CJoystickMac;
std::unique_ptr<IJoystick> ptr(new CJoystickMac(parent));
#endif
Q_ASSERT_X(m_instance, "IJoystick::getInstance", "Pointer to IJoystick is nullptr!");
}
return m_instance;
return ptr;
}
} // BlackInput

View File

@@ -13,60 +13,32 @@
#define BLACKINPUT_JOYSTICK_H
#include "blackinputexport.h"
#include "blackmisc/hardware/joystickbutton.h"
#include <QMultiMap>
#include "blackmisc/input/hotkeycombination.h"
#include <QObject>
#include <QPointer>
#include <functional>
#include <memory>
namespace BlackInput
{
/*!
* \brief Abstract interface for native joystick handling.
* \todo Add implementation for Linux and OSX.
* Abstract interface for native joystick handling.
*/
class BLACKINPUT_EXPORT IJoystick : public QObject
{
Q_OBJECT
public:
//! Operation mode
enum Mode
{
ModeNominal,
ModeCapture
};
//! Constructor
IJoystick(QObject *parent = nullptr);
//! Destructor
virtual ~IJoystick() {}
//! Start joystick button selection for settings configuration
virtual void startCapture() = 0;
//! Simulating press/release of a joystick button
virtual void triggerButton(const BlackMisc::Hardware::CJoystickButton button, bool isPressed) = 0;
//! Creates a native joystick handler object
static IJoystick *getInstance();
static std::unique_ptr<IJoystick> create(QObject *parent = nullptr);
signals:
//! User has selected a joystick button
void buttonSelectionFinished(const BlackMisc::Hardware::CJoystickButton &button);
//! Button down
void buttonDown(const BlackMisc::Hardware::CJoystickButton &);
//! Button up
void buttonUp(const BlackMisc::Hardware::CJoystickButton &);
private:
static IJoystick *m_instance;
//! Joystick button combination has changed
void buttonCombinationChanged(const BlackMisc::Input::CHotkeyCombination &);
};
}

View File

@@ -17,28 +17,20 @@
namespace BlackInput
{
IKeyboard *IKeyboard::m_instance = nullptr;
IKeyboard::IKeyboard(QObject *parent) :
QObject(parent)
{
}
IKeyboard::IKeyboard(QObject *parent) : QObject(parent) {}
IKeyboard *IKeyboard::getInstance()
std::unique_ptr<IKeyboard> IKeyboard::create(QObject *parent)
{
if (!m_instance)
{
#if defined(Q_OS_WIN)
m_instance = new CKeyboardWindows;
std::unique_ptr<IKeyboard> ptr(new CKeyboardWindows(parent));
#elif defined(Q_OS_LINUX)
m_instance = new CKeyboardLinux;
std::unique_ptr<IKeyboard> ptr(new CKeyboardLinux(parent));
#elif defined(Q_OS_OSX)
m_instance = new CKeyboardMac;
std::unique_ptr<IKeyboard> ptr(new CKeyboardMac(parent));
#endif
Q_ASSERT_X(m_instance, "IKeyboard::getInstance", "Pointer to IKeyboard is NULL!");
m_instance->init();
}
return m_instance;
ptr->init();
return ptr;
}
} // BlackInput

View File

@@ -11,11 +11,10 @@
#define BLACKINPUT_KEYBOARD_H
#include "blackinputexport.h"
#include "blackmisc/hardware/keyboardkeylist.h"
#include <QMultiMap>
#include "blackmisc/input/keyboardkeylist.h"
#include "blackmisc/input/hotkeycombination.h"
#include <QObject>
#include <QPointer>
#include <functional>
#include <memory>
namespace BlackInput
{
@@ -27,62 +26,18 @@ namespace BlackInput
{
Q_OBJECT
public:
//! Operation mode
enum Mode
{
Mode_Nominal,
Mode_Capture
};
//! Constructor
IKeyboard(QObject *parent = nullptr);
//! Destructor
virtual ~IKeyboard() {}
//! Set the list of keys to monitor
virtual void setKeysToMonitor(const BlackMisc::Hardware::CKeyboardKeyList &keylist) = 0;
/*!
* Select a key combination as hotkey. This method returns immediatly.
* Listen for signals keySelectionChanged and keySelectionFinished
* to retrieve the user input.
* \param ignoreNextKey
* Set to true, if you want to ignore the first key,
* e.g. [ENTER] in case you are running from command line.
*/
virtual void startCapture(bool ignoreNextKey) = 0;
/*!
* Triggers a key event manually and calls the registered functions.
* \param key
* \param isPressed
*/
virtual void triggerKey(const BlackMisc::Hardware::CKeyboardKey &key, bool isPressed) = 0;
//! Creates a native keyboard handler object
static IKeyboard *getInstance();
static std::unique_ptr<IKeyboard> create(QObject *parent = nullptr);
signals:
/*!
* Key selection has changed, but is not finished yet.
* \param key
*/
void keySelectionChanged(BlackMisc::Hardware::CKeyboardKey key);
/*!
* Key selection has finished.
* \param key
*/
void keySelectionFinished(BlackMisc::Hardware::CKeyboardKey key);
//! Key down
void keyDown(const BlackMisc::Hardware::CKeyboardKey &);
//! Key up
void keyUp(const BlackMisc::Hardware::CKeyboardKey &);
//! Key combination changed
void keyCombinationChanged(const BlackMisc::Input::CHotkeyCombination &);
protected:
@@ -92,7 +47,6 @@ namespace BlackInput
virtual bool init() = 0;
private:
static IKeyboard *m_instance;
};
}

View File

@@ -18,7 +18,7 @@
#include <fcntl.h>
using namespace BlackMisc;
using namespace BlackMisc::Hardware;
using namespace BlackMisc::Input;
namespace
{
@@ -42,17 +42,6 @@ namespace BlackInput
ps_directoryChanged(inputDevicesDir());
}
void CJoystickLinux::startCapture()
{
}
void CJoystickLinux::triggerButton(const CJoystickButton button, bool isPressed)
{
if (!isPressed) emit buttonUp(button);
else emit buttonDown(button);
}
void CJoystickLinux::cleanupJoysticks()
{
for (auto it = m_joysticks.begin(); it != m_joysticks.end();)
@@ -123,17 +112,27 @@ namespace BlackInput
QFile *joystick = qobject_cast<QFile *>(object);
Q_ASSERT(joystick);
struct js_event event;
while (joystick->read(reinterpret_cast<char *>(&event), sizeof(event)) == sizeof(event))
{
BlackMisc::Input::CHotkeyCombination oldCombination(m_buttonCombination);
switch (event.type & ~JS_EVENT_INIT)
{
case JS_EVENT_BUTTON:
if (event.value)
emit buttonDown(CJoystickButton(event.number));
{
m_buttonCombination.addJoystickButton(event.number);
}
else
emit buttonUp(CJoystickButton(event.number));
{
m_buttonCombination.removeJoystickButton(event.number);
}
if (oldCombination != m_buttonCombination)
{
emit buttonCombinationChanged(m_buttonCombination);
}
break;
}
}

View File

@@ -13,7 +13,7 @@
//! \file
#include "blackinput/joystick.h"
#include "blackmisc/hardware/joystickbutton.h"
#include "blackmisc/input/joystickbutton.h"
#include "blackmisc/collection.h"
#include <QMap>
#include <QString>
@@ -41,12 +41,6 @@ namespace BlackInput
//! \brief Destructor
virtual ~CJoystickLinux() = default;
//! \copydoc IJoystick::startCapture()
virtual void startCapture() override;
//! \copydoc IJoystick::triggerButton()
virtual void triggerButton(const BlackMisc::Hardware::CJoystickButton button, bool isPressed) override;
private:
friend class IJoystick;
@@ -71,8 +65,7 @@ namespace BlackInput
void ps_readInput(QObject *object);
private:
IJoystick::Mode m_mode = ModeNominal; //!< Current working mode
BlackMisc::Input::CHotkeyCombination m_buttonCombination;
QSignalMapper *m_mapper = nullptr; //!< Maps device handles
QMap<QString, QFile *> m_joysticks; //!< All read joysticks, file path <-> file instance pairs
QFileSystemWatcher *m_inputWatcher = nullptr;

View File

@@ -4,29 +4,79 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "keyboard_linux.h"
#include "keymapping_linux.h"
#include "blackmisc/logmessage.h"
#include <QDebug>
#include <QFileSystemWatcher>
#include <QDir>
#include <QFile>
#include <QHash>
#include <QSocketNotifier>
#include <linux/input.h>
#include <fcntl.h>
#include <X11/keysym.h>
#include <X11/XKBlib.h>
using namespace BlackMisc::Hardware;
using namespace BlackMisc;
using namespace BlackMisc::Input;
namespace BlackInput
{
CKeyboardLinux::CKeyboardLinux(QObject *parent) :
IKeyboard(parent),
m_ignoreNextKey(false),
m_mode(Mode_Nominal)
static QHash<int, Input::KeyCode> keyMapping
{
{ XK_0, Key_0 },
{ XK_1, Key_1 },
{ XK_2, Key_2 },
{ XK_3, Key_3 },
{ XK_4, Key_4 },
{ XK_5, Key_5 },
{ XK_6, Key_6 },
{ XK_7, Key_7 },
{ XK_8, Key_8 },
{ XK_9, Key_9 },
{ XK_a, Key_A },
{ XK_b, Key_B },
{ XK_c, Key_C },
{ XK_d, Key_D },
{ XK_e, Key_E },
{ XK_f, Key_F },
{ XK_g, Key_G },
{ XK_h, Key_H },
{ XK_i, Key_I },
{ XK_j, Key_J },
{ XK_k, Key_K },
{ XK_l, Key_L },
{ XK_m, Key_M },
{ XK_n, Key_N },
{ XK_o, Key_O },
{ XK_p, Key_P },
{ XK_q, Key_Q },
{ XK_r, Key_R },
{ XK_s, Key_S },
{ XK_t, Key_T },
{ XK_u, Key_U },
{ XK_v, Key_V },
{ XK_w, Key_W },
{ XK_x, Key_X },
{ XK_y, Key_Y },
{ XK_z, Key_Z },
{ XK_Shift_L, Key_ShiftLeft },
{ XK_Shift_R, Key_ShiftRight },
{ XK_Control_L, Key_ControlLeft },
{ XK_Control_R, Key_ControlRight },
{ XK_Alt_L, Key_AltLeft },
{ XK_Alt_R, Key_AltRight },
};
CKeyboardLinux::CKeyboardLinux(QObject *parent) :
IKeyboard(parent)
{
m_display = XOpenDisplay(nullptr);
}
CKeyboardLinux::~CKeyboardLinux()
{
if (m_display) XCloseDisplay(m_display);
}
bool CKeyboardLinux::init()
@@ -39,24 +89,6 @@ namespace BlackInput
return true;
}
void CKeyboardLinux::setKeysToMonitor(const CKeyboardKeyList &keylist)
{
m_listMonitoredKeys = keylist;
}
void CKeyboardLinux::startCapture(bool ignoreNextKey)
{
m_mode = Mode_Capture;
m_ignoreNextKey = ignoreNextKey;
m_pressedKey.setKeyObject(CKeyboardKey());
}
void CKeyboardLinux::triggerKey(const CKeyboardKey &key, bool isPressed)
{
if (!isPressed) emit keyUp(key);
else emit keyDown(key);
}
void CKeyboardLinux::deviceDirectoryChanged(const QString &dir)
{
QDir eventFiles(dir, QLatin1String("event*"), 0, QDir::System);
@@ -96,7 +128,9 @@ namespace BlackInput
default:
continue;
}
int keyCode = eventInput.code;
// The + 8 offset is required for XkbKeycodeToKeysym to output the correct Keysym
int keyCode = eventInput.code + 8;
keyEvent(keyCode, isPressed);
}
@@ -112,14 +146,6 @@ namespace BlackInput
}
}
void CKeyboardLinux::sendCaptureNotification(const CKeyboardKey &key, bool isFinished)
{
if (isFinished)
emit keySelectionFinished(key);
else
emit keySelectionChanged(key);
}
void CKeyboardLinux::addRawInputDevice(const QString &filePath)
{
QSharedPointer<QFile> inputFile(new QFile(filePath));
@@ -170,62 +196,73 @@ namespace BlackInput
}
}
void CKeyboardLinux::keyEvent(int virtualKeyCode, bool isPressed)
void CKeyboardLinux::keyEvent(int keyCode, bool isPressed)
{
if (CKeyMappingLinux::isMouseButton(virtualKeyCode))
return;
if (isMouseButton(keyCode)) { return; }
BlackMisc::Hardware::CKeyboardKey lastPressedKey = m_pressedKey;
if (m_ignoreNextKey)
{
m_ignoreNextKey = false;
return;
}
bool isFinished = false;
BlackMisc::Input::CHotkeyCombination oldCombination(m_keyCombination);
if (isPressed)
{
if (CKeyMappingLinux::isModifier(virtualKeyCode))
m_pressedKey.addModifier(CKeyMappingLinux::convertToModifier(virtualKeyCode));
else
{
m_pressedKey.setKey(CKeyMappingLinux::convertToKey(virtualKeyCode));
}
auto key = convertToKey(keyCode);
if (key == Key_Unknown) { return; }
m_keyCombination.addKeyboardKey(key);
}
else
{
if (CKeyMappingLinux::isModifier(virtualKeyCode))
m_pressedKey.removeModifier(CKeyMappingLinux::convertToModifier(virtualKeyCode));
else
{
m_pressedKey.setKey(Qt::Key_unknown);
}
auto key = convertToKey(keyCode);
if (key == Key_Unknown) { return; }
isFinished = true;
m_keyCombination.removeKeyboardKey(key);
}
if (lastPressedKey == m_pressedKey)
return;
#ifdef DEBUG_KEYBOARD
qDebug() << "Virtual key: " << virtualKeyCode;
#endif
if (m_mode == Mode_Capture)
if (oldCombination != m_keyCombination)
{
if (isFinished)
{
sendCaptureNotification(lastPressedKey, true);
m_mode = Mode_Nominal;
}
else
{
sendCaptureNotification(m_pressedKey, false);
}
emit keyCombinationChanged(m_keyCombination);
}
else
}
BlackMisc::Input::KeyCode CKeyboardLinux::convertToKey(int keyCode)
{
// The keycode received from kernel does not take keyboard layouts into account.
// It always defaults to US keyboards. In contrast to kernel devices, X11 is aware
// of user keyboard layouts. The magic below translates the key code
// into the correct symbol via a X11 connection.
// Summary of translations:
// Kernel key code -> X11 key symbol -> swift key code
auto keySym = XkbKeycodeToKeysym(m_display, keyCode, 0, 0);
return keyMapping.value(keySym, Key_Unknown);
}
bool CKeyboardLinux::isModifier(int keyCode)
{
auto keySym = XkbKeycodeToKeysym(m_display, keyCode, 0, 0);
switch (keySym)
{
if (m_listMonitoredKeys.contains(lastPressedKey)) emit keyUp(lastPressedKey);
if (m_listMonitoredKeys.contains(m_pressedKey)) emit keyDown(m_pressedKey);
case XK_Shift_L:
case XK_Shift_R:
case XK_Control_L:
case XK_Control_R:
case XK_Alt_L:
case XK_Alt_R:
return true;
default: return false;
}
return false;
}
bool CKeyboardLinux::isMouseButton(int keyCode)
{
switch (keyCode)
{
case BTN_LEFT:
case BTN_RIGHT:
case BTN_MIDDLE:
return true;
default:
return false;
}
}
}

View File

@@ -11,16 +11,18 @@
#define BLACKINPUT_KEYBOARD_LINUX_H
#include "blackinput/keyboard.h"
#include "blackmisc/hardware/keyboardkeylist.h"
#include "blackmisc/input/hotkeycombination.h"
#include <QHash>
#include <X11/X.h>
#include <X11/Xlib.h>
class QFileSystemWatcher;
class QFile;
namespace BlackInput
{
//! \brief Linux implemenation of IKeyboard using hook procedure
//! \todo Change QHash to a CCollection object
class CKeyboardLinux : public IKeyboard
{
Q_OBJECT
@@ -36,15 +38,6 @@ namespace BlackInput
//! \brief Destructor
virtual ~CKeyboardLinux();
//! Set the list of keys to monitor
virtual void setKeysToMonitor(const BlackMisc::Hardware::CKeyboardKeyList &keylist) override;
//! \copydoc IKeyboard::selectKey()
virtual void startCapture(bool ignoreNextKey = false) override;
//! \copydoc IKeyboard::triggerKey()
virtual void triggerKey(const BlackMisc::Hardware::CKeyboardKey &key, bool isPressed) override;
protected:
//! \copydoc IKeyboard::init()
@@ -65,33 +58,18 @@ namespace BlackInput
//! \brief Constructor
CKeyboardLinux(QObject *parent = nullptr);
/*!
* \brief Constructor
* \param keySet
* \param isFinished
*/
void sendCaptureNotification(const BlackMisc::Hardware::CKeyboardKey &key, bool isFinished);
/*!
* \brief Add new raw input device
* \param filePath Path to device file
*/
void addRawInputDevice(const QString &filePath);
void keyEvent(int keyCode, bool isPressed);
BlackMisc::Input::KeyCode convertToKey(int keyCode);
bool isModifier(int keyCode);
bool isMouseButton(int keyCode);
/*!
* \brief Process new key event
* \param virtualKeyCode
* \param isPressed
*/
void keyEvent(int virtualKeyCode, bool isPressed);
BlackMisc::Hardware::CKeyboardKeyList m_listMonitoredKeys; //!< Registered keys
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
BlackMisc::Input::CHotkeyCombination m_keyCombination; //!< Current status of pressed keys;
QFileSystemWatcher *m_devInputWatcher; //!< Watches the device file system for input devices
QHash<QString, QSharedPointer<QFile>> m_keyboardDevices; //!< All known input devices
Display *m_display;
};
}

View File

@@ -1,100 +0,0 @@
/* 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 "keymapping_linux.h"
#include <QDebug>
#include <linux/input.h>
using namespace BlackMisc::Hardware;
namespace BlackInput
{
Qt::Key CKeyMappingLinux::convertToKey(int virtualKey)
{
switch (virtualKey)
{
case KEY_0: return Qt::Key_0; break;
case KEY_1: return Qt::Key_1; break;
case KEY_2: return Qt::Key_2; break;
case KEY_3: return Qt::Key_3; break;
case KEY_4: return Qt::Key_4; break;
case KEY_5: return Qt::Key_5; break;
case KEY_6: return Qt::Key_6; break;
case KEY_7: return Qt::Key_7; break;
case KEY_8: return Qt::Key_8; break;
case KEY_9: return Qt::Key_9; break;
case KEY_A: return Qt::Key_A; break;
case KEY_B: return Qt::Key_B; break;
case KEY_C: return Qt::Key_C; break;
case KEY_D: return Qt::Key_D; break;
case KEY_E: return Qt::Key_E; break;
case KEY_F: return Qt::Key_F; break;
case KEY_G: return Qt::Key_G; break;
case KEY_H: return Qt::Key_H; break;
case KEY_I: return Qt::Key_I; break;
case KEY_J: return Qt::Key_J; break;
case KEY_K: return Qt::Key_K; break;
case KEY_L: return Qt::Key_L; break;
case KEY_M: return Qt::Key_M; break;
case KEY_N: return Qt::Key_N; break;
case KEY_O: return Qt::Key_O; break;
case KEY_P: return Qt::Key_P; break;
case KEY_Q: return Qt::Key_Q; break;
case KEY_R: return Qt::Key_R; break;
case KEY_S: return Qt::Key_S; break;
case KEY_T: return Qt::Key_T; break;
case KEY_U: return Qt::Key_U; break;
case KEY_V: return Qt::Key_V; break;
case KEY_W: return Qt::Key_W; break;
case KEY_X: return Qt::Key_X; break;
case KEY_Y: return Qt::Key_Y; break;
case KEY_Z: return Qt::Key_Z; break;
default: return Qt::Key_unknown; break;
}
}
CKeyboardKey::Modifier CKeyMappingLinux::convertToModifier(int virtualKey)
{
switch (virtualKey)
{
case KEY_LEFTSHIFT: return CKeyboardKey::ModifierShiftLeft; break;
case KEY_RIGHTSHIFT: return CKeyboardKey::ModifierShiftRight; break;
case KEY_LEFTCTRL: return CKeyboardKey::ModifierCtrlLeft; break;
case KEY_RIGHTCTRL: return CKeyboardKey::ModifierCtrlRight; break;
case KEY_LEFTALT: return CKeyboardKey::ModifierAltLeft; break;
case KEY_RIGHTALT: return CKeyboardKey::ModifierAltRight; break;
default: return CKeyboardKey::ModifierNone; break;
}
}
bool CKeyMappingLinux::isModifier(int virtualKey)
{
switch (virtualKey)
{
case KEY_LEFTSHIFT:
case KEY_RIGHTSHIFT:
case KEY_LEFTCTRL:
case KEY_RIGHTCTRL:
case KEY_LEFTALT:
case KEY_RIGHTALT:
return true;
default: return false;
}
}
bool CKeyMappingLinux::isMouseButton(int virtualKey)
{
switch (virtualKey)
{
case BTN_LEFT:
case BTN_RIGHT:
case BTN_MIDDLE:
return true;
default:
return false;
}
}
} // namespace BlackInput

View File

@@ -1,48 +0,0 @@
/* 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/. */
#ifndef BLACKINPUT_KEYMAPPING_LINUX_H
#define BLACKINPUT_KEYMAPPING_LINUX_H
#include "blackmisc/hardware/keyboardkey.h"
namespace BlackInput
{
//! \brief This class provides methods to map between windows virtual keys and CKeyboardKey
class CKeyMappingLinux
{
public:
/*!
* \brief Converts a set of windows virtual keys to a CKeySet object
* \param virtualKey
* \return
*/
static BlackMisc::Hardware::CKeyboardKey::Modifier convertToModifier(int virtualKey);
/*!
* \brief Convert to Qt key
* \param virtualKey
* \return
*/
static Qt::Key convertToKey(int virtualKey);
/*!
* \brief Checks if its a modifier key
* \param virtualKey
* \return
*/
static bool isModifier(int virtualKey);
/*!
* \brief Checks if its a mouse button
* \param virtualKey
* \return
*/
static bool isMouseButton(int virtualKey);
};
} // namespace BlackInput
#endif // guard

View File

@@ -9,7 +9,7 @@
#include "joystick_mac.h"
using namespace BlackMisc::Hardware;
using namespace BlackMisc::Input;
namespace BlackInput
{
@@ -22,14 +22,4 @@ namespace BlackInput
{
}
void CJoystickMac::startCapture()
{
}
void CJoystickMac::triggerButton(const CJoystickButton button, bool isPressed)
{
if(!isPressed) emit buttonUp(button);
else emit buttonDown(button);
}
} // namespace BlackInput

View File

@@ -13,13 +13,13 @@
//! \file
#include "blackinput/joystick.h"
#include "blackmisc/hardware/joystickbutton.h"
#include "blackmisc/input/joystickbutton.h"
#include "blackmisc/collection.h"
#include <QSet>
namespace BlackInput
{
//! Linux implemenation of IJoystick with DirectInput
//! OSX implemenation of IJoystick
//! \todo Not implmeneted yet
class CJoystickMac : public IJoystick
{
Q_OBJECT
@@ -35,20 +35,11 @@ namespace BlackInput
//! \brief Destructor
virtual ~CJoystickMac();
//! \copydoc IJoystick::startCapture()
virtual void startCapture() override;
//! \copydoc IJoystick::triggerButton()
virtual void triggerButton(const BlackMisc::Hardware::CJoystickButton button, bool isPressed) override;
private:
friend class IJoystick;
//! Destructor
CJoystickMac(QObject *parent = nullptr);
IJoystick::Mode m_mode = ModeNominal; //!< Current working mode
};
} // namespace BlackInput

View File

@@ -13,7 +13,7 @@
#define BLACKINPUT_KEYBOARD_MAC_H
#include "blackinput/keyboard.h"
#include "blackmisc/hardware/keyboardkeylist.h"
#include "blackmisc/input/hotkeycombination.h"
#include <QHash>
class __CGEvent;
@@ -27,13 +27,11 @@ typedef __CGEventTapProxy* CGEventTapProxy; //!< Max event proxy definition
namespace BlackInput
{
//! Mac OSX implemenation of IKeyboard using hook procedure
//! \todo Change QHash to a CCollection object
class CKeyboardMac : public IKeyboard
{
Q_OBJECT
public:
//! Copy Constructor
CKeyboardMac(CKeyboardMac const&) = delete;
@@ -43,15 +41,6 @@ namespace BlackInput
//! Destructor
virtual ~CKeyboardMac();
//! Set the list of keys to monitor
virtual void setKeysToMonitor(const BlackMisc::Hardware::CKeyboardKeyList &keylist) override;
//! \copydoc IKeyboard::selectKey()
virtual void startCapture(bool ignoreNextKey = false) override;
//! \copydoc IKeyboard::triggerKey()
virtual void triggerKey(const BlackMisc::Hardware::CKeyboardKey &key, bool isPressed) override;
//! Process key event
virtual void processKeyEvent(CGEventType type, CGEventRef event);
@@ -66,23 +55,14 @@ namespace BlackInput
//! Constructor
CKeyboardMac(QObject *parent = nullptr);
/*!
* Constructor
* \param keySet
* \param isFinished
*/
void sendCaptureNotification(const BlackMisc::Hardware::CKeyboardKey &key, bool isFinished);
BlackMisc::Input::KeyCode convertToKey(int keyCode);
static CGEventRef myCGEventCallback(CGEventTapProxy proxy,
CGEventType type,
CGEventRef event,
void *refcon);
BlackMisc::Hardware::CKeyboardKeyList m_listMonitoredKeys; //!< Registered keys
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
BlackMisc::Input::CHotkeyCombination m_keyCombination; //!< Current status of pressed keys;
};
}

View File

@@ -8,22 +8,62 @@
*/
#include "keyboard_mac.h"
#include "keymapping_mac.h"
#include <QDebug>
#include <QHash>
#include <QtWidgets/QMessageBox>
#include <CoreFoundation/CoreFoundation.h>
#include <ApplicationServices/ApplicationServices.h>
#include <AppKit/NSEvent.h>
#include <AppKit/NSAlert.h>
#include <Foundation/NSString.h>
#include <Carbon/Carbon.h>
using namespace BlackMisc::Hardware;
using namespace BlackMisc::Input;
namespace BlackInput
{
static QHash<int, KeyCode> keyMapping
{
{ kVK_ANSI_0, Key_0 },
{ kVK_ANSI_1, Key_1 },
{ kVK_ANSI_2, Key_2 },
{ kVK_ANSI_3, Key_3 },
{ kVK_ANSI_4, Key_4 },
{ kVK_ANSI_5, Key_5 },
{ kVK_ANSI_6, Key_6 },
{ kVK_ANSI_7, Key_7 },
{ kVK_ANSI_8, Key_8 },
{ kVK_ANSI_9, Key_9 },
{ kVK_ANSI_A, Key_A },
{ kVK_ANSI_B, Key_B },
{ kVK_ANSI_C, Key_C },
{ kVK_ANSI_D, Key_D },
{ kVK_ANSI_E, Key_E },
{ kVK_ANSI_F, Key_F },
{ kVK_ANSI_G, Key_G },
{ kVK_ANSI_H, Key_H },
{ kVK_ANSI_I, Key_I },
{ kVK_ANSI_J, Key_J },
{ kVK_ANSI_K, Key_K },
{ kVK_ANSI_L, Key_L },
{ kVK_ANSI_M, Key_M },
{ kVK_ANSI_N, Key_N },
{ kVK_ANSI_O, Key_O },
{ kVK_ANSI_P, Key_P },
{ kVK_ANSI_Q, Key_Q },
{ kVK_ANSI_R, Key_R },
{ kVK_ANSI_S, Key_S },
{ kVK_ANSI_T, Key_T },
{ kVK_ANSI_U, Key_U },
{ kVK_ANSI_V, Key_V },
{ kVK_ANSI_W, Key_W },
{ kVK_ANSI_X, Key_X },
{ kVK_ANSI_Y, Key_Y },
{ kVK_ANSI_Z, Key_Z },
};
CKeyboardMac::CKeyboardMac(QObject *parent) :
IKeyboard(parent),
m_mode(Mode_Nominal)
IKeyboard(parent)
{
}
@@ -34,44 +74,47 @@ namespace BlackInput
bool CKeyboardMac::init()
{
bool accessibilityEnabled = false;
if (AXIsProcessTrustedWithOptions != NULL) {
if (AXIsProcessTrustedWithOptions != NULL)
{
// 10.9 and later
const void * keys[] = { kAXTrustedCheckOptionPrompt };
const void * values[] = { kCFBooleanTrue };
const void *keys[] = { kAXTrustedCheckOptionPrompt };
const void *values[] = { kCFBooleanTrue };
CFDictionaryRef options = CFDictionaryCreate(
kCFAllocatorDefault,
keys,
values,
sizeof(keys) / sizeof(*keys),
&kCFCopyStringDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
kCFAllocatorDefault,
keys,
values,
sizeof(keys) / sizeof(*keys),
&kCFCopyStringDictionaryKeyCallBacks,
&kCFTypeDictionaryValueCallBacks);
accessibilityEnabled = AXIsProcessTrustedWithOptions(options);
}
else {
else
{
// 10.8 and older
accessibilityEnabled = AXAPIEnabled();
}
if (!accessibilityEnabled) {
if (!accessibilityEnabled)
{
QMessageBox msgBox;
msgBox.setText("In order to enable hotkeys first add Swift to the list of apps allowed to "
"control your computer in System Preferences / Security & Privacy / Privacy / Accessiblity and then restart Swift.");
"control your computer in System Preferences / Security & Privacy / Privacy / Accessiblity and then restart Swift.");
msgBox.exec();
return false;
}
CGEventMask eventMask = ((1 << kCGEventKeyDown) | (1 << kCGEventKeyUp) | (1 <<kCGEventFlagsChanged));
CGEventMask eventMask = ((1 << kCGEventKeyDown) | (1 << kCGEventKeyUp) | (1 << kCGEventFlagsChanged));
// try creating an event tap just for keypresses. if it fails, we need Universal Access.
CFMachPortRef eventTap = CGEventTapCreate(kCGHIDEventTap, kCGHeadInsertEventTap, 0,
eventMask, myCGEventCallback, NULL);
eventMask, myCGEventCallback, this);
CFRunLoopSourceRef source = CFMachPortCreateRunLoopSource(kCFAllocatorDefault,
eventTap, 0);
eventTap, 0);
CFRunLoopAddSource(CFRunLoopGetCurrent(), source, kCFRunLoopCommonModes);
CGEventTapEnable(eventTap, true);
@@ -79,124 +122,98 @@ namespace BlackInput
return true;
}
void CKeyboardMac::setKeysToMonitor(const CKeyboardKeyList &keylist)
{
m_listMonitoredKeys = keylist;
}
void CKeyboardMac::startCapture(bool ignoreNextKey)
{
m_mode = Mode_Capture;
m_ignoreNextKey = ignoreNextKey;
m_pressedKey.setKeyObject(CKeyboardKey());
}
void CKeyboardMac::triggerKey(const CKeyboardKey &key, bool isPressed)
{
if(!isPressed) emit keyUp(key);
else emit keyDown(key);
}
void CKeyboardMac::processKeyEvent(CGEventType type,
CGEventRef event)
CGEventRef event)
{
BlackMisc::Hardware::CKeyboardKey lastPressedKey = m_pressedKey;
if (m_ignoreNextKey)
{
m_ignoreNextKey = false;
return;
}
BlackMisc::Input::CHotkeyCombination oldCombination(m_keyCombination);
unsigned int vkcode = static_cast<unsigned int>(CGEventGetIntegerValueField(event, kCGKeyboardEventKeycode));
bool isFinished = false;
if (type == kCGEventKeyDown) {
m_pressedKey.setKey(CKeyMappingMac::convertToKey(vkcode));
} else if (type == kCGEventKeyUp) {
m_pressedKey.setKey(Qt::Key_unknown);
isFinished = true;
} else if (type == kCGEventFlagsChanged) {
// m_pressedKey.removeAllModifiers();
CGEventFlags f = CGEventGetFlags(event);
qDebug() << "hier";
if ((f & kCGEventFlagMaskShift) == kCGEventFlagMaskShift) {
qDebug() << "shift";
if (vkcode == 56) {
m_pressedKey.addModifier(CKeyboardKey::ModifierShiftLeft);
} else if (vkcode == 60) {
m_pressedKey.addModifier(CKeyboardKey::ModifierShiftRight);
}
} else {
m_pressedKey.removeModifier(CKeyboardKey::ModifierShiftLeft);
m_pressedKey.removeModifier(CKeyboardKey::ModifierShiftRight);
}
if ((f & kCGEventFlagMaskControl) == kCGEventFlagMaskControl) {
qDebug() << "ctrl";
// at least on the mac wireless keyboard there is no right ctrl key
if (vkcode == 59) {
m_pressedKey.addModifier(CKeyboardKey::ModifierCtrlLeft);
}
} else {
m_pressedKey.removeModifier(CKeyboardKey::ModifierCtrlLeft);
}
if ((f & kCGEventFlagMaskAlternate) == kCGEventFlagMaskAlternate) {
qDebug() << "alt";
if (vkcode == 58) {
m_pressedKey.addModifier(CKeyboardKey::ModifierAltLeft);
} else if (vkcode == 61) {
m_pressedKey.addModifier(CKeyboardKey::ModifierAltRight);
}
} else {
m_pressedKey.removeModifier(CKeyboardKey::ModifierAltLeft);
m_pressedKey.removeModifier(CKeyboardKey::ModifierAltRight);
}
}
if (lastPressedKey == m_pressedKey)
return;
if (m_mode == Mode_Capture)
if (type == kCGEventKeyDown)
{
if (isFinished)
auto key = convertToKey(vkcode);
if (key == Key_Unknown) { return; }
m_keyCombination.addKeyboardKey(key);
}
else if (type == kCGEventKeyUp)
{
auto key = convertToKey(vkcode);
if (key == Key_Unknown) { return; }
m_keyCombination.removeKeyboardKey(key);
}
else if (type == kCGEventFlagsChanged)
{
CGEventFlags f = CGEventGetFlags(event);
if ((f & kCGEventFlagMaskShift) == kCGEventFlagMaskShift)
{
sendCaptureNotification(lastPressedKey, true);
m_mode = Mode_Nominal;
if (vkcode == 56)
{
m_keyCombination.addKeyboardKey(Key_ShiftLeft);
}
else if (vkcode == 60)
{
m_keyCombination.addKeyboardKey(Key_ShiftRight);
}
}
else
{
sendCaptureNotification(m_pressedKey, false);
m_keyCombination.removeKeyboardKey(Key_ShiftLeft);
m_keyCombination.removeKeyboardKey(Key_ShiftRight);
}
if ((f & kCGEventFlagMaskControl) == kCGEventFlagMaskControl)
{
// at least on the mac wireless keyboard there is no right ctrl key
if (vkcode == 59)
{
m_keyCombination.addKeyboardKey(Key_ControlLeft);
}
}
else
{
m_keyCombination.removeKeyboardKey(Key_ControlLeft);
}
if ((f & kCGEventFlagMaskAlternate) == kCGEventFlagMaskAlternate)
{
if (vkcode == 58)
{
m_keyCombination.addKeyboardKey(Key_AltLeft);
}
else if (vkcode == 61)
{
m_keyCombination.addKeyboardKey(Key_AltRight);
}
}
else
{
m_keyCombination.removeKeyboardKey(Key_AltLeft);
m_keyCombination.removeKeyboardKey(Key_AltRight);
}
}
else
if (oldCombination == m_keyCombination)
{
if (m_listMonitoredKeys.contains(lastPressedKey)) emit keyUp(lastPressedKey);
if (m_listMonitoredKeys.contains(m_pressedKey)) emit keyDown(m_pressedKey);
emit keyCombinationChanged(m_keyCombination);
}
}
void CKeyboardMac::sendCaptureNotification(const CKeyboardKey &key, bool isFinished)
KeyCode CKeyboardMac::convertToKey(int keyCode)
{
if (isFinished)
emit keySelectionFinished(key);
else
emit keySelectionChanged(key);
return keyMapping.value(keyCode, Key_Unknown);
}
CGEventRef CKeyboardMac::myCGEventCallback(CGEventTapProxy,
CGEventType type,
CGEventRef event,
void *)
CGEventType type,
CGEventRef event,
void *refcon)
{
CKeyboardMac *keyboardMac = qobject_cast<CKeyboardMac*>(IKeyboard::getInstance());
CKeyboardMac *keyboardMac = static_cast<CKeyboardMac*>(refcon);
keyboardMac->processKeyEvent(type, event);
// send event to next application
return event;
// send event to next application
return event;
}
}

View File

@@ -1,33 +0,0 @@
/* Copyright (C) 2015
* swift project Community / Contributors
*
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
* directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project,
* including this file, may be copied, modified, propagated, or distributed except according to the terms
* contained in the LICENSE file.
*/
//! \file
#ifndef BLACKINPUT_KEYMAPPING_MAC_H
#define BLACKINPUT_KEYMAPPING_MAC_H
#include "blackmisc/hardware/keyboardkey.h"
namespace BlackInput
{
//! \brief This class provides methods to map between Mac OS X virtual keys and CKeyboardKey
class CKeyMappingMac
{
public:
/*!
* \brief Convert to Qt key
* \param virtualKey
* \return
*/
static Qt::Key convertToKey(unsigned int virtualKey);
};
} // namespace BlackInput
#endif // KEYMAPPING_MAC_H

View File

@@ -1,62 +0,0 @@
/* Copyright (C) 2015
* swift project Community / Contributors
*
* This file is part of swift project. It is subject to the license terms in the LICENSE file found in the top-level
* directory of this distribution and at http://www.swift-project.org/license.html. No part of swift project,
* including this file, may be copied, modified, propagated, or distributed except according to the terms
* contained in the LICENSE file.
*/
#include "keymapping_mac.h"
#include <QDebug>
#include <Carbon/Carbon.h>
using namespace BlackMisc::Hardware;
namespace BlackInput
{
Qt::Key CKeyMappingMac::convertToKey(unsigned int virtualKey)
{
switch (virtualKey)
{
case kVK_ANSI_0: return Qt::Key_0;
case kVK_ANSI_1: return Qt::Key_1;
case kVK_ANSI_2: return Qt::Key_2;
case kVK_ANSI_3: return Qt::Key_3;
case kVK_ANSI_4: return Qt::Key_4;
case kVK_ANSI_5: return Qt::Key_5;
case kVK_ANSI_6: return Qt::Key_6;
case kVK_ANSI_7: return Qt::Key_7;
case kVK_ANSI_8: return Qt::Key_8;
case kVK_ANSI_9: return Qt::Key_9;
case kVK_ANSI_A: return Qt::Key_A;
case kVK_ANSI_B: return Qt::Key_B;
case kVK_ANSI_C: return Qt::Key_C;
case kVK_ANSI_D: return Qt::Key_D;
case kVK_ANSI_E: return Qt::Key_E;
case kVK_ANSI_F: return Qt::Key_F;
case kVK_ANSI_G: return Qt::Key_G;
case kVK_ANSI_H: return Qt::Key_H;
case kVK_ANSI_I: return Qt::Key_I;
case kVK_ANSI_J: return Qt::Key_J;
case kVK_ANSI_K: return Qt::Key_K;
case kVK_ANSI_L: return Qt::Key_L;
case kVK_ANSI_M: return Qt::Key_M;
case kVK_ANSI_N: return Qt::Key_N;
case kVK_ANSI_O: return Qt::Key_O;
case kVK_ANSI_P: return Qt::Key_P;
case kVK_ANSI_Q: return Qt::Key_Q;
case kVK_ANSI_R: return Qt::Key_R;
case kVK_ANSI_S: return Qt::Key_S;
case kVK_ANSI_T: return Qt::Key_T;
case kVK_ANSI_U: return Qt::Key_U;
case kVK_ANSI_V: return Qt::Key_V;
case kVK_ANSI_W: return Qt::Key_W;
case kVK_ANSI_X: return Qt::Key_X;
case kVK_ANSI_Y: return Qt::Key_Y;
case kVK_ANSI_Z: return Qt::Key_Z;
default: return Qt::Key_unknown;
}
}
} // namespace BlackInput

View File

@@ -17,13 +17,13 @@
// handling in the second branch.
using namespace BlackMisc;
using namespace BlackMisc::Hardware;
using namespace BlackMisc::Input;
namespace BlackInput
{
const TCHAR *CJoystickWindows::m_helperWindowClassName = TEXT("SDLHelperWindowInputCatcher");
const TCHAR *CJoystickWindows::m_helperWindowName = TEXT("SDLHelperWindowInputMsgWindow");
const TCHAR *CJoystickWindows::m_helperWindowClassName = TEXT("HelperWindow");
const TCHAR *CJoystickWindows::m_helperWindowName = TEXT("JoystickCatcherWindow");
ATOM CJoystickWindows::m_helperWindowClass = 0;
HWND CJoystickWindows::m_helperWindow = nullptr;
@@ -43,17 +43,6 @@ namespace BlackInput
CoUninitialize();
}
void CJoystickWindows::startCapture()
{
// TODO
}
void CJoystickWindows::triggerButton(const CJoystickButton button, bool isPressed)
{
if (!isPressed) emit buttonUp(button);
else emit buttonDown(button);
}
void CJoystickWindows::timerEvent(QTimerEvent * /* event */)
{
pollDeviceState();
@@ -207,23 +196,13 @@ namespace BlackInput
void CJoystickWindows::updateAndSendButtonStatus(qint32 buttonIndex, bool isPressed)
{
if (isPressed)
BlackMisc::Input::CHotkeyCombination oldCombination(m_buttonCombination);
if (isPressed) { m_buttonCombination.addJoystickButton(buttonIndex); }
else { m_buttonCombination.removeJoystickButton(buttonIndex); }
if (oldCombination != m_buttonCombination)
{
if (!m_pressedButtons.contains(buttonIndex))
{
CJoystickButton joystickButton(buttonIndex);
emit buttonDown(joystickButton);
m_pressedButtons.push_back(buttonIndex);
}
}
else
{
if (m_pressedButtons.contains(buttonIndex))
{
CJoystickButton joystickButton(buttonIndex);
emit buttonUp(joystickButton);
m_pressedButtons.remove(buttonIndex);
}
emit buttonCombinationChanged(m_buttonCombination);
}
}
@@ -260,7 +239,7 @@ namespace BlackInput
m_directInputDevice->Acquire();
if (FAILED(hr = m_directInputDevice->Poll()))
{
// FIXME: print error message
CLogMessage(this).warning("DirectInput error code: ") << hr;
return hr;
}
}
@@ -273,7 +252,7 @@ namespace BlackInput
m_directInputDevice->Acquire();
if (FAILED(hr = m_directInputDevice->GetDeviceState(sizeof(DIJOYSTATE2), &state)))
{
// FIXME: print error message
CLogMessage(this).warning("DirectInput error code: ") << hr;
return hr;
}
}

View File

@@ -14,7 +14,7 @@
#include "blackinput/blackinputexport.h"
#include "blackinput/joystick.h"
#include "blackmisc/hardware/joystickbutton.h"
#include "blackmisc/input/joystickbutton.h"
#include "blackmisc/collection.h"
#include <QSet>
@@ -62,12 +62,6 @@ namespace BlackInput
//! \brief Destructor
virtual ~CJoystickWindows();
//! \copydoc IJoystick::startCapture()
virtual void startCapture() override;
//! \copydoc IJoystick::triggerButton()
virtual void triggerButton(const BlackMisc::Hardware::CJoystickButton button, bool isPressed) override;
protected:
//! Timer based updates
@@ -116,9 +110,8 @@ namespace BlackInput
QList<CJoystickDeviceData> m_availableJoystickDevices; //!< List of found and available joystick devices
QList<CJoystickDeviceInput> m_joystickDeviceInputs; //!< List of available device buttons
BlackMisc::CCollection<qint32> m_pressedButtons; //!< Collection of pressed buttons
IJoystick::Mode m_mode = ModeNominal; //!< Current working mode
BlackMisc::Input::CHotkeyCombination m_buttonCombination;
static const WCHAR *m_helperWindowClassName; //!< Helper window class name
static const WCHAR *m_helperWindowName; //!< Helper window name

View File

@@ -4,17 +4,63 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "keyboard_windows.h"
#include "keymapping_windows.h"
#include <QDebug>
using namespace BlackMisc::Hardware;
using namespace BlackMisc::Input;
namespace BlackInput
{
static QHash<int, KeyCode> keyMapping
{
{ '0', Key_0 },
{ '1', Key_1 },
{ '2', Key_2 },
{ '3', Key_3 },
{ '4', Key_4 },
{ '5', Key_5 },
{ '6', Key_6 },
{ '7', Key_7 },
{ '8', Key_8 },
{ '9', Key_9 },
{ 'A', Key_A },
{ 'B', Key_B },
{ 'C', Key_C },
{ 'D', Key_D },
{ 'E', Key_E },
{ 'F', Key_F },
{ 'G', Key_G },
{ 'H', Key_H },
{ 'I', Key_I },
{ 'J', Key_J },
{ 'K', Key_K },
{ 'L', Key_L },
{ 'M', Key_M },
{ 'N', Key_N },
{ 'O', Key_O },
{ 'P', Key_P },
{ 'Q', Key_Q },
{ 'R', Key_R },
{ 'S', Key_S },
{ 'T', Key_T },
{ 'U', Key_U },
{ 'V', Key_V },
{ 'W', Key_W },
{ 'X', Key_X },
{ 'Y', Key_Y },
{ 'Z', Key_Z },
{ VK_LSHIFT, Key_ShiftLeft },
{ VK_RSHIFT, Key_ShiftRight },
{ VK_LCONTROL, Key_ControlLeft },
{ VK_RCONTROL, Key_ControlRight },
{ VK_LMENU, Key_AltLeft },
{ VK_RMENU, Key_AltRight },
};
static CKeyboardWindows *g_keyboardWindows = nullptr;
CKeyboardWindows::CKeyboardWindows(QObject *parent) :
IKeyboard(parent),
m_keyboardHook(nullptr),
m_mode(Mode_Nominal)
m_keyboardHook(nullptr)
{
}
@@ -26,103 +72,42 @@ namespace BlackInput
bool CKeyboardWindows::init()
{
Q_ASSERT_X(g_keyboardWindows == nullptr, "CKeyboardWindows::init", "Windows supports only one keyboard instance. Cannot initialize a second one!");
g_keyboardWindows = this;
m_keyboardHook = SetWindowsHookEx(WH_KEYBOARD_LL, CKeyboardWindows::keyboardProc, GetModuleHandle(NULL), 0);
return true;
}
void CKeyboardWindows::setKeysToMonitor(const CKeyboardKeyList &keylist)
{
m_listMonitoredKeys = keylist;
}
void CKeyboardWindows::startCapture(bool ignoreNextKey)
{
m_mode = Mode_Capture;
m_ignoreNextKey = ignoreNextKey;
m_pressedKey.setKeyObject(CKeyboardKey());
}
void CKeyboardWindows::triggerKey(const CKeyboardKey &key, bool isPressed)
{
if(!isPressed) emit keyUp(key);
else emit keyDown(key);
}
void CKeyboardWindows::processKeyEvent(WPARAM vkcode, uint event)
{
BlackMisc::Hardware::CKeyboardKey lastPressedKey = m_pressedKey;
if (m_ignoreNextKey)
{
m_ignoreNextKey = false;
return;
}
bool isFinished = false;
BlackMisc::Input::CHotkeyCombination oldCombination(m_keyCombination);
if ((event == WM_KEYDOWN) || (event == WM_SYSKEYDOWN))
{
if (CKeyMappingWindows::isModifier(vkcode))
m_pressedKey.addModifier(CKeyMappingWindows::convertToModifier(vkcode));
else
{
m_pressedKey.setKey(CKeyMappingWindows::convertToKey(vkcode));
}
auto key = keyMapping.value(vkcode);
if (key == Key_Unknown) { return; }
m_keyCombination.addKeyboardKey(CKeyboardKey(key));
}
else if ((event == WM_KEYUP) || (event == WM_SYSKEYUP) )
{
if (CKeyMappingWindows::isModifier(vkcode))
m_pressedKey.removeModifier(CKeyMappingWindows::convertToModifier(vkcode));
else
{
m_pressedKey.setKey(Qt::Key_unknown);
}
isFinished = true;
auto key = keyMapping.value(vkcode);
if (key == Key_Unknown) { return; }
m_keyCombination.removeKeyboardKey(CKeyboardKey(key));
}
if (lastPressedKey == m_pressedKey)
return;
#ifdef DEBUG_KEYBOARD_WINDOWS
qDebug() << "Virtual key: " << vkcode;
#endif
if (m_mode == Mode_Capture)
if (oldCombination != m_keyCombination)
{
if (isFinished)
{
sendCaptureNotification(lastPressedKey, true);
m_mode = Mode_Nominal;
}
else
{
sendCaptureNotification(m_pressedKey, false);
}
emit keyCombinationChanged(m_keyCombination);
}
else
{
if (m_listMonitoredKeys.contains(lastPressedKey)) emit keyUp(lastPressedKey);
if (m_listMonitoredKeys.contains(m_pressedKey)) emit keyDown(m_pressedKey);
}
}
void CKeyboardWindows::sendCaptureNotification(const CKeyboardKey &key, bool isFinished)
{
if (isFinished)
emit keySelectionFinished(key);
else
emit keySelectionChanged(key);
}
LRESULT CALLBACK CKeyboardWindows::keyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
// This is the reason why we have to use singleton pattern. We cannot pass a object pointer to
// keyboardProc.
CKeyboardWindows *keyboardWindows = qobject_cast<CKeyboardWindows*>(IKeyboard::getInstance());
if (nCode == HC_ACTION)
{
KBDLLHOOKSTRUCT *keyboardEvent =reinterpret_cast<KBDLLHOOKSTRUCT*>(lParam);
WPARAM vkCode = keyboardEvent->vkCode;
keyboardWindows->processKeyEvent(vkCode, wParam);
g_keyboardWindows->processKeyEvent(vkCode, wParam);
}
return CallNextHookEx(keyboardWindows->keyboardHook(), nCode, wParam, lParam);
return CallNextHookEx(g_keyboardWindows->keyboardHook(), nCode, wParam, lParam);
}
}

View File

@@ -12,8 +12,8 @@
#include "blackinput/blackinputexport.h"
#include "blackinput/keyboard.h"
#include "blackmisc/hardware/keyboardkey.h"
#include "blackmisc/hardware/keyboardkeylist.h"
#include "blackmisc/input/keyboardkey.h"
#include "blackmisc/input/keyboardkeylist.h"
#include <QHash>
#ifndef NOMINMAX
#define NOMINMAX
@@ -23,7 +23,6 @@
namespace BlackInput
{
//! \brief Windows implemenation of IKeyboard using hook procedure
//! \todo Change QHash to a CCollection object
class BLACKINPUT_EXPORT CKeyboardWindows : public IKeyboard
{
Q_OBJECT
@@ -38,15 +37,6 @@ namespace BlackInput
//! \brief Destructor
virtual ~CKeyboardWindows();
//! \copydoc IKeyboard::setKeysToMonitor()
virtual void setKeysToMonitor(const BlackMisc::Hardware::CKeyboardKeyList &keylist) override;
//! \copydoc IKeyboard::selectKey()
virtual void startCapture(bool ignoreNextKey = false) override;
//! \copydoc IKeyboard::triggerKey()
virtual void triggerKey(const BlackMisc::Hardware::CKeyboardKey &key, bool isPressed) override;
//! \brief Keyboard hook handle
HHOOK keyboardHook() const { return m_keyboardHook; }
@@ -65,13 +55,6 @@ namespace BlackInput
//! \brief Constructor
CKeyboardWindows(QObject *parent = nullptr);
/*!
* \brief Constructor
* \param keySet
* \param isFinished
*/
void sendCaptureNotification(const BlackMisc::Hardware::CKeyboardKey &key, bool isFinished);
void addKey(WPARAM vkcode);
void removeKey(WPARAM vkcode);
@@ -85,11 +68,8 @@ namespace BlackInput
static LRESULT CALLBACK keyboardProc(int nCode, WPARAM wParam, LPARAM lParam);
BlackMisc::Hardware::CKeyboardKeyList m_listMonitoredKeys; //!< Registered keys
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
BlackMisc::Input::CHotkeyCombination m_keyCombination; //!< Set of virtual keys pressed in the last cycle
HHOOK m_keyboardHook; //!< Keyboard hook handle
Mode m_mode; //!< Operation mode
};
}

View File

@@ -1,93 +0,0 @@
/* 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 "keymapping_windows.h"
#include <QDebug>
#ifndef NOMINMAX
#define NOMINMAX
#endif
#include <windows.h>
using namespace BlackMisc::Hardware;
namespace BlackInput
{
Qt::Key CKeyMappingWindows::convertToKey(WPARAM virtualKey)
{
switch (virtualKey)
{
case '0': return Qt::Key_0; break;
case '1': return Qt::Key_1; break;
case '2': return Qt::Key_2; break;
case '3': return Qt::Key_3; break;
case '4': return Qt::Key_4; break;
case '5': return Qt::Key_5; break;
case '6': return Qt::Key_6; break;
case '7': return Qt::Key_7; break;
case '8': return Qt::Key_8; break;
case '9': return Qt::Key_9; break;
case 'A': return Qt::Key_A; break;
case 'B': return Qt::Key_B; break;
case 'C': return Qt::Key_C; break;
case 'D': return Qt::Key_D; break;
case 'E': return Qt::Key_E; break;
case 'F': return Qt::Key_F; break;
case 'G': return Qt::Key_G; break;
case 'H': return Qt::Key_H; break;
case 'I': return Qt::Key_I; break;
case 'J': return Qt::Key_J; break;
case 'K': return Qt::Key_K; break;
case 'L': return Qt::Key_L; break;
case 'M': return Qt::Key_M; break;
case 'N': return Qt::Key_N; break;
case 'O': return Qt::Key_O; break;
case 'P': return Qt::Key_P; break;
case 'Q': return Qt::Key_Q; break;
case 'R': return Qt::Key_R; break;
case 'S': return Qt::Key_S; break;
case 'T': return Qt::Key_T; break;
case 'U': return Qt::Key_U; break;
case 'V': return Qt::Key_V; break;
case 'W': return Qt::Key_W; break;
case 'X': return Qt::Key_X; break;
case 'Y': return Qt::Key_Y; break;
case 'Z': return Qt::Key_Z; break;
default: return Qt::Key_unknown; break;
}
}
CKeyboardKey::Modifier CKeyMappingWindows::convertToModifier(WPARAM virtualKey)
{
switch (virtualKey)
{
case VK_LSHIFT: return CKeyboardKey::ModifierShiftLeft; break;
case VK_RSHIFT: return CKeyboardKey::ModifierShiftRight; break;
case VK_LCONTROL: return CKeyboardKey::ModifierCtrlLeft; break;
case VK_RCONTROL: return CKeyboardKey::ModifierCtrlRight; break;
case VK_LMENU: return CKeyboardKey::ModifierAltLeft; break;
case VK_RMENU: return CKeyboardKey::ModifierAltRight; break;
default: return CKeyboardKey::ModifierNone; break;
}
}
bool CKeyMappingWindows::isModifier(WPARAM vkcode)
{
switch (vkcode)
{
case VK_LSHIFT:
case VK_RSHIFT:
case VK_LCONTROL:
case VK_RCONTROL:
case VK_LMENU:
case VK_RMENU:
case VK_LWIN:
case VK_RWIN:
return true;
default: return false;
}
}
} // namespace BlackInput

View File

@@ -1,46 +0,0 @@
/* 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/. */
#ifndef BLACKINPUT_KEYMAPPING_WINDOWS_H
#define BLACKINPUT_KEYMAPPING_WINDOWS_H
#include "blackinput/blackinputexport.h"
#include "blackmisc/hardware/keyboardkey.h"
#ifndef NOMINMAX
#define NOMINMAX
#endif
#include <windows.h>
namespace BlackInput
{
//! \brief This class provides methods to map between windows virtual keys and CKeyboardKey
class BLACKINPUT_EXPORT CKeyMappingWindows
{
public:
/*!
* \brief Converts a set of windows virtual keys to a CKeySet object
* \param virtualKey
* \return
*/
static BlackMisc::Hardware::CKeyboardKey::Modifier convertToModifier(WPARAM virtualKey);
/*!
* \brief Convert to Qt key
* \param virtualKey
* \return
*/
static Qt::Key convertToKey(WPARAM virtualKey);
/*!
* \brief Checks if its a modifier key
* \param vkcode
* \return
*/
static bool isModifier(WPARAM vkcode);
};
} // namespace BlackInput
#endif // guard

View File

@@ -36,7 +36,7 @@ using namespace BlackMisc::PhysicalQuantities;
using namespace BlackMisc::Geo;
using namespace BlackMisc::Settings;
using namespace BlackMisc::Audio;
using namespace BlackMisc::Hardware;
using namespace BlackMisc::Input;
/*
* Constructor
@@ -375,26 +375,6 @@ void SwiftGuiStd::ps_toggleWindowVisibility()
}
}
void SwiftGuiStd::ps_registerHotkeyFunctions()
{
CInputManager *m_inputManager = BlackCore::CInputManager::getInstance();
m_inputManager->registerHotkeyFunc(CHotkeyFunction::Opacity50(), this, [ this ](bool isPressed)
{
if (isPressed) this->ps_onChangedWindowOpacity(50);
});
m_inputManager->registerHotkeyFunc(CHotkeyFunction::Opacity100(), this, [ this ](bool isPressed)
{
if (isPressed) this->ps_onChangedWindowOpacity(100);
});
m_inputManager->registerHotkeyFunc(CHotkeyFunction::ToogleWindowsStayOnTop(), this, [ this ](bool isPressed)
{
if (isPressed) this->ps_toogleWindowStayOnTop();
});
}
void SwiftGuiStd::ps_onStyleSheetsChanged()
{
this->initStyleSheet();

View File

@@ -18,7 +18,6 @@
#include "guimodeenums.h"
#include "blackcore/context_all_interfaces.h"
#include "blackcore/input_manager.h"
#include "blackgui/components/enableforruntime.h"
#include "blackgui/components/infowindowcomponent.h"
#include "blackgui/components/maininfoareacomponent.h"
@@ -113,7 +112,6 @@ private:
bool m_init = false;
BlackGui::Components::CInfoWindowComponent *m_compInfoWindow = nullptr; //!< the info window (popup
BlackGui::CManagedStatusBar m_statusBar;
BlackInput::IKeyboard *m_keyboard = nullptr; //!< hotkeys
BlackMisc::CLogSubscriber m_logSubscriber { this, &SwiftGuiStd::ps_displayStatusMessageInGui };
// contexts
@@ -239,9 +237,6 @@ private slots:
//! Toggle window visibility
void ps_toggleWindowVisibility();
//! Set the hotkey functions
void ps_registerHotkeyFunctions();
//! Style sheet has been changed
void ps_onStyleSheetsChanged();

View File

@@ -125,9 +125,6 @@ void SwiftGuiStd::init(const CRuntimeConfig &runtimeConfig)
this->ui->comp_MainInfoArea->getLogComponent()->appendPlainTextToConsole(CProject::swiftVersionString());
this->ui->comp_MainInfoArea->getLogComponent()->appendPlainTextToConsole(CProject::compiledInfo());
// hotkeys
this->ps_registerHotkeyFunctions();
// update timers
this->startUpdateTimersWhenConnected();