mirror of
https://github.com/swift-project/pilotclient.git
synced 2026-04-30 05:51:23 +08:00
refs #453 Refactor CInputManger and low level input handlers
This commit is contained in:
committed by
Mathew Sutcliffe
parent
63c7c6be0d
commit
199a1e5fcb
@@ -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())
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 };
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
46
src/blackcore/settings/application.h
Normal file
46
src/blackcore/settings/application.h
Normal 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
|
||||
@@ -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
|
||||
|
||||
@@ -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 &);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user