Add sending inputs for keyboard_input on Windows
This commit is contained in:
@@ -47,11 +47,13 @@ HEADERS += src/overlaycontroller.h \
|
|||||||
src/utils/setup.h \
|
src/utils/setup.h \
|
||||||
src/utils/paths.h \
|
src/utils/paths.h \
|
||||||
src/openvr/overlay_utils.h \
|
src/openvr/overlay_utils.h \
|
||||||
src/keyboard_input/input_parser.h
|
src/keyboard_input/input_parser.h \
|
||||||
|
src/keyboard_input/input_sender.h
|
||||||
|
|
||||||
win32 {
|
win32 {
|
||||||
SOURCES += src/tabcontrollers/audiomanager/AudioManagerWindows.cpp \
|
SOURCES += src/tabcontrollers/audiomanager/AudioManagerWindows.cpp \
|
||||||
src/tabcontrollers/keyboardinput/KeyboardInputWindows.cpp
|
src/tabcontrollers/keyboardinput/KeyboardInputWindows.cpp \
|
||||||
|
src/keyboard_input/input_sender_win.cpp
|
||||||
HEADERS += src/tabcontrollers/audiomanager/AudioManagerWindows.h
|
HEADERS += src/tabcontrollers/audiomanager/AudioManagerWindows.h
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -289,10 +289,101 @@ std::vector<Token>
|
|||||||
= removeTokenInSameSequence( ctrlRemoved, Token::MODIFIER_ALT );
|
= removeTokenInSameSequence( ctrlRemoved, Token::MODIFIER_ALT );
|
||||||
const auto shiftRemoved
|
const auto shiftRemoved
|
||||||
= removeTokenInSameSequence( altRemoved, Token::MODIFIER_SHIFT );
|
= removeTokenInSameSequence( altRemoved, Token::MODIFIER_SHIFT );
|
||||||
const auto altgrRemoved
|
|
||||||
= removeTokenInSameSequence( shiftRemoved, Token::MODIFIER_ALTGR );
|
|
||||||
const auto superRemoved
|
const auto superRemoved
|
||||||
= removeTokenInSameSequence( altgrRemoved, Token::MODIFIER_SUPER );
|
= removeTokenInSameSequence( shiftRemoved, Token::MODIFIER_SUPER );
|
||||||
|
|
||||||
return superRemoved;
|
return superRemoved;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isModifier( const Token token ) noexcept
|
||||||
|
{
|
||||||
|
switch ( token )
|
||||||
|
{
|
||||||
|
case Token::MODIFIER_CTRL:
|
||||||
|
[[fallthrough]];
|
||||||
|
case Token::MODIFIER_ALT:
|
||||||
|
[[fallthrough]];
|
||||||
|
case Token::MODIFIER_SHIFT:
|
||||||
|
[[fallthrough]];
|
||||||
|
case Token::MODIFIER_SUPER:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isLiteral( const Token token ) noexcept
|
||||||
|
{
|
||||||
|
if ( isalnum( static_cast<int>( token ) ) )
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ( token )
|
||||||
|
{
|
||||||
|
case Token::KEY_F1:
|
||||||
|
return true;
|
||||||
|
case Token::KEY_F2:
|
||||||
|
return true;
|
||||||
|
case Token::KEY_F3:
|
||||||
|
return true;
|
||||||
|
case Token::KEY_F4:
|
||||||
|
return true;
|
||||||
|
case Token::KEY_F5:
|
||||||
|
return true;
|
||||||
|
case Token::KEY_F6:
|
||||||
|
return true;
|
||||||
|
case Token::KEY_F7:
|
||||||
|
return true;
|
||||||
|
case Token::KEY_F8:
|
||||||
|
return true;
|
||||||
|
case Token::KEY_F9:
|
||||||
|
return true;
|
||||||
|
|
||||||
|
case Token::KEY_BACKSPACE:
|
||||||
|
return true;
|
||||||
|
case Token::KEY_SPACE:
|
||||||
|
return true;
|
||||||
|
case Token::KEY_TAB:
|
||||||
|
return true;
|
||||||
|
case Token::KEY_ESC:
|
||||||
|
return true;
|
||||||
|
case Token::KEY_INS:
|
||||||
|
return true;
|
||||||
|
case Token::KEY_DEL:
|
||||||
|
return true;
|
||||||
|
case Token::KEY_END:
|
||||||
|
return true;
|
||||||
|
case Token::KEY_PGDN:
|
||||||
|
return true;
|
||||||
|
case Token::KEY_PGUP:
|
||||||
|
return true;
|
||||||
|
case Token::KEY_CAPS:
|
||||||
|
return true;
|
||||||
|
case Token::KEY_PRNSCRN:
|
||||||
|
return true;
|
||||||
|
case Token::KEY_PAUSE:
|
||||||
|
return true;
|
||||||
|
case Token::KEY_SCRLOCK:
|
||||||
|
return true;
|
||||||
|
case Token::KEY_LEFTARROW:
|
||||||
|
return true;
|
||||||
|
case Token::KEY_RIGHTARROW:
|
||||||
|
return true;
|
||||||
|
case Token::KEY_UPARROW:
|
||||||
|
return true;
|
||||||
|
case Token::KEY_DOWNARROW:
|
||||||
|
return true;
|
||||||
|
case Token::KEY_KPSLASH:
|
||||||
|
return true;
|
||||||
|
case Token::KEY_KPSTAR:
|
||||||
|
return true;
|
||||||
|
case Token::KEY_KPMINUS:
|
||||||
|
return true;
|
||||||
|
case Token::KEY_KPPLUS:
|
||||||
|
return true;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -91,3 +91,6 @@ std::vector<Token>
|
|||||||
ParseKeyboardInputsToTokens( const std::string inputs ) noexcept;
|
ParseKeyboardInputsToTokens( const std::string inputs ) noexcept;
|
||||||
std::vector<Token>
|
std::vector<Token>
|
||||||
removeIncorrectTokens( const std::vector<Token>& tokens ) noexcept;
|
removeIncorrectTokens( const std::vector<Token>& tokens ) noexcept;
|
||||||
|
|
||||||
|
bool isModifier( const Token token ) noexcept;
|
||||||
|
bool isLiteral( const Token token ) noexcept;
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "input_parser.h"
|
||||||
|
#include <easylogging++.h>
|
||||||
|
|
||||||
|
enum class KeyStatus
|
||||||
|
{
|
||||||
|
Up,
|
||||||
|
Down,
|
||||||
|
};
|
||||||
|
|
||||||
|
void sendTokensAsInput( const std::vector<Token> tokens );
|
||||||
@@ -0,0 +1,181 @@
|
|||||||
|
#include "input_sender.h"
|
||||||
|
#include <vector>
|
||||||
|
#include <Windows.h>
|
||||||
|
#include <cctype>
|
||||||
|
|
||||||
|
WORD convertToVirtualKeycode( const Token token )
|
||||||
|
{
|
||||||
|
if ( isalnum( static_cast<int>( token ) ) )
|
||||||
|
{
|
||||||
|
return static_cast<WORD>( VkKeyScan( static_cast<int>( token ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
switch ( token )
|
||||||
|
{
|
||||||
|
case Token::KEY_F1:
|
||||||
|
return VK_F1;
|
||||||
|
case Token::KEY_F2:
|
||||||
|
return VK_F2;
|
||||||
|
case Token::KEY_F3:
|
||||||
|
return VK_F3;
|
||||||
|
case Token::KEY_F4:
|
||||||
|
return VK_F4;
|
||||||
|
case Token::KEY_F5:
|
||||||
|
return VK_F5;
|
||||||
|
case Token::KEY_F6:
|
||||||
|
return VK_F6;
|
||||||
|
case Token::KEY_F7:
|
||||||
|
return VK_F7;
|
||||||
|
case Token::KEY_F8:
|
||||||
|
return VK_F8;
|
||||||
|
case Token::KEY_F9:
|
||||||
|
return VK_F9;
|
||||||
|
|
||||||
|
case Token::KEY_BACKSPACE:
|
||||||
|
return VK_BACK;
|
||||||
|
case Token::KEY_SPACE:
|
||||||
|
return VK_SPACE;
|
||||||
|
case Token::KEY_TAB:
|
||||||
|
return VK_TAB;
|
||||||
|
case Token::KEY_ESC:
|
||||||
|
return VK_ESCAPE;
|
||||||
|
case Token::KEY_INS:
|
||||||
|
return VK_INSERT;
|
||||||
|
case Token::KEY_DEL:
|
||||||
|
return VK_DELETE;
|
||||||
|
case Token::KEY_END:
|
||||||
|
return VK_END;
|
||||||
|
case Token::KEY_PGDN:
|
||||||
|
return VK_NEXT;
|
||||||
|
case Token::KEY_PGUP:
|
||||||
|
return VK_PRIOR;
|
||||||
|
case Token::KEY_CAPS:
|
||||||
|
return VK_CAPITAL;
|
||||||
|
case Token::KEY_PRNSCRN:
|
||||||
|
return VK_SNAPSHOT;
|
||||||
|
case Token::KEY_PAUSE:
|
||||||
|
return VK_PAUSE;
|
||||||
|
case Token::KEY_SCRLOCK:
|
||||||
|
return VK_SCROLL;
|
||||||
|
case Token::KEY_LEFTARROW:
|
||||||
|
return VK_LEFT;
|
||||||
|
case Token::KEY_RIGHTARROW:
|
||||||
|
return VK_RIGHT;
|
||||||
|
case Token::KEY_UPARROW:
|
||||||
|
return VK_UP;
|
||||||
|
case Token::KEY_DOWNARROW:
|
||||||
|
return VK_DOWN;
|
||||||
|
case Token::KEY_KPSLASH:
|
||||||
|
return VK_DIVIDE;
|
||||||
|
case Token::KEY_KPSTAR:
|
||||||
|
return VK_MULTIPLY;
|
||||||
|
case Token::KEY_KPMINUS:
|
||||||
|
return VK_SUBTRACT;
|
||||||
|
case Token::KEY_KPPLUS:
|
||||||
|
return VK_ADD;
|
||||||
|
|
||||||
|
case Token::MODIFIER_CTRL:
|
||||||
|
return VK_CONTROL;
|
||||||
|
case Token::MODIFIER_ALT:
|
||||||
|
return VK_MENU;
|
||||||
|
case Token::MODIFIER_SHIFT:
|
||||||
|
return VK_SHIFT;
|
||||||
|
case Token::MODIFIER_SUPER:
|
||||||
|
return VK_LWIN;
|
||||||
|
|
||||||
|
default:
|
||||||
|
// LOG incorrect symbol
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
INPUT createInputStruct( const WORD virtualKeyCode,
|
||||||
|
const KeyStatus keyStatus ) noexcept
|
||||||
|
{
|
||||||
|
INPUT input = {};
|
||||||
|
|
||||||
|
input.type = INPUT_KEYBOARD;
|
||||||
|
|
||||||
|
input.ki.wVk = virtualKeyCode;
|
||||||
|
|
||||||
|
if ( keyStatus == KeyStatus::Up )
|
||||||
|
{
|
||||||
|
input.ki.dwFlags = KEYEVENTF_KEYUP;
|
||||||
|
}
|
||||||
|
else if ( keyStatus == KeyStatus::Down )
|
||||||
|
{
|
||||||
|
input.ki.dwFlags = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
|
||||||
|
void sendKeyboardInputRaw( std::vector<INPUT> inputs )
|
||||||
|
{
|
||||||
|
const auto success = SendInput( static_cast<unsigned int>( inputs.size() ),
|
||||||
|
inputs.data(),
|
||||||
|
sizeof( INPUT ) );
|
||||||
|
|
||||||
|
if ( ( inputs.size() > 0 ) && !success )
|
||||||
|
{
|
||||||
|
char* err;
|
||||||
|
auto errCode = GetLastError();
|
||||||
|
if ( !FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER
|
||||||
|
| FORMAT_MESSAGE_FROM_SYSTEM,
|
||||||
|
nullptr,
|
||||||
|
errCode,
|
||||||
|
MAKELANGID( LANG_NEUTRAL,
|
||||||
|
SUBLANG_DEFAULT ), // default language
|
||||||
|
reinterpret_cast<LPTSTR>( &err ),
|
||||||
|
0,
|
||||||
|
nullptr ) )
|
||||||
|
{
|
||||||
|
LOG( ERROR )
|
||||||
|
<< "Error calling SendInput(): Could not get error message ("
|
||||||
|
<< errCode << ")";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LOG( ERROR ) << "Error calling SendInput(): " << err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void sendTokenAsInput( const std::vector<Token> tokens )
|
||||||
|
{
|
||||||
|
std::vector<INPUT> inputs = {};
|
||||||
|
std::vector<Token> heldInputs = {};
|
||||||
|
for ( const auto& token : tokens )
|
||||||
|
{
|
||||||
|
if ( isModifier( token ) )
|
||||||
|
{
|
||||||
|
inputs.push_back( createInputStruct(
|
||||||
|
convertToVirtualKeycode( token ), KeyStatus::Down ) );
|
||||||
|
heldInputs.push_back( token );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( token == Token::TOKEN_NEW_SEQUENCE )
|
||||||
|
{
|
||||||
|
for ( const auto& h : heldInputs )
|
||||||
|
{
|
||||||
|
inputs.push_back( createInputStruct(
|
||||||
|
convertToVirtualKeycode( h ), KeyStatus::Up ) );
|
||||||
|
}
|
||||||
|
heldInputs.clear();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( isLiteral( token ) )
|
||||||
|
{
|
||||||
|
inputs.push_back( createInputStruct(
|
||||||
|
convertToVirtualKeycode( token ), KeyStatus::Down ) );
|
||||||
|
inputs.push_back( createInputStruct(
|
||||||
|
convertToVirtualKeycode( token ), KeyStatus::Up ) );
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sendKeyboardInputRaw( inputs );
|
||||||
|
// send inputs
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user