2020-03-24 01:44:02 +08:00
# pragma once
# include "Helpers.h"
2020-04-10 00:20:19 +08:00
# include "LayoutMap.h"
2020-04-09 00:11:58 +08:00
# include "Shortcut.h"
# include "RemapShortcut.h"
2020-03-24 01:44:02 +08:00
# include <interface/lowlevel_keyboard_event_data.h>
2020-04-04 01:57:46 +08:00
# include <mutex>
2020-03-24 01:44:02 +08:00
# include <winrt/Windows.UI.Xaml.Controls.h>
2020-03-31 02:05:29 +08:00
using namespace winrt : : Windows : : UI : : Xaml : : Controls ;
2020-03-24 01:44:02 +08:00
// Enum type to store different states of the UI
enum class KeyboardManagerUIState
{
// If set to this value then there is no keyboard manager window currently active that requires a hook
Deactivated ,
// If set to this value then the detect key window is currently active and it requires a hook
2020-03-27 23:38:58 +08:00
DetectSingleKeyRemapWindowActivated ,
2020-03-24 01:44:02 +08:00
// If set to this value then the detect shortcut window is currently active and it requires a hook
DetectShortcutWindowActivated
} ;
// Class to store the shared state of the keyboard manager between the UI and the hook
class KeyboardManagerState
{
private :
// State variable used to store which UI window is currently active that requires interaction with the hook
KeyboardManagerUIState uiState ;
2020-04-04 01:57:46 +08:00
std : : mutex uiState_mutex ;
2020-03-24 01:44:02 +08:00
// Window handle for the current UI window which is active. Should be set to nullptr if UI is deactivated
HWND currentUIWindow ;
2020-04-04 01:57:46 +08:00
std : : mutex currentUIWindow_mutex ;
2020-03-24 01:44:02 +08:00
2020-04-10 00:20:19 +08:00
// Object to store the shortcut detected in the detect shortcut UI window. Gets cleared on releasing keys. This is used in both the backend and the UI.
2020-04-09 00:11:58 +08:00
Shortcut detectedShortcut ;
2020-04-04 01:57:46 +08:00
std : : mutex detectedShortcut_mutex ;
2020-03-24 01:44:02 +08:00
2020-04-10 00:20:19 +08:00
// Object to store the shortcut state displayed in the UI window. Always stores last displayed shortcut irrespective of releasing keys. This is used in both the backend and the UI.
Shortcut currentShortcut ;
std : : mutex currentShortcut_mutex ;
2020-03-27 23:38:58 +08:00
// Store detected remap key in the remap UI window. This is used in both the backend and the UI.
DWORD detectedRemapKey ;
2020-04-04 01:57:46 +08:00
std : : mutex detectedRemapKey_mutex ;
2020-03-27 23:38:58 +08:00
// Stores the UI element which is to be updated based on the remap key entered.
2020-04-09 05:31:31 +08:00
StackPanel currentSingleKeyUI ;
std : : mutex currentSingleKeyUI_mutex ;
2020-03-27 23:38:58 +08:00
2020-03-24 01:44:02 +08:00
// Stores the UI element which is to be updated based on the shortcut entered
2020-04-09 05:31:31 +08:00
StackPanel currentShortcutUI ;
std : : mutex currentShortcutUI_mutex ;
2020-03-24 01:44:02 +08:00
2020-04-09 05:31:31 +08:00
// Display a key by appending a border Control as a child of the panel.
void AddKeyToLayout ( const StackPanel & panel , const winrt : : hstring & key ) ;
2020-03-24 01:44:02 +08:00
public :
2020-04-04 01:57:46 +08:00
// The map members and their mutexes are left as public since the maps are used extensively in dllmain.cpp.
2020-03-24 01:44:02 +08:00
// Maps which store the remappings for each of the features. The bool fields should be initalised to false. They are used to check the current state of the shortcut (i.e is that particular shortcut currently pressed down or not).
// Stores single key remappings
2020-04-09 00:11:58 +08:00
std : : unordered_map < DWORD , DWORD > singleKeyReMap ;
2020-04-04 01:57:46 +08:00
std : : mutex singleKeyReMap_mutex ;
2020-03-24 01:44:02 +08:00
// Stores keys which need to be changed from toggle behaviour to modifier behaviour. Eg. Caps Lock
std : : unordered_map < DWORD , bool > singleKeyToggleToMod ;
2020-04-04 01:57:46 +08:00
std : : mutex singleKeyToggleToMod_mutex ;
2020-03-24 01:44:02 +08:00
// Stores the os level shortcut remappings
2020-04-09 00:11:58 +08:00
std : : map < Shortcut , RemapShortcut > osLevelShortcutReMap ;
2020-04-04 01:57:46 +08:00
std : : mutex osLevelShortcutReMap_mutex ;
2020-03-24 01:44:02 +08:00
// Stores the app-specific shortcut remappings. Maps application name to the shortcut map
2020-04-09 00:11:58 +08:00
std : : map < std : : wstring , std : : map < Shortcut , RemapShortcut > > appSpecificShortcutReMap ;
2020-04-04 01:57:46 +08:00
std : : mutex appSpecificShortcutReMap_mutex ;
2020-03-24 01:44:02 +08:00
2020-04-10 00:20:19 +08:00
// Stores the keyboard layout
LayoutMap keyboardMap ;
2020-03-24 01:44:02 +08:00
// Constructor
KeyboardManagerState ( ) ;
// Function to reset the UI state members
void ResetUIState ( ) ;
// Function to check the if the UI state matches the argument state. For states with activated windows it also checks if the window is in focus.
bool CheckUIState ( KeyboardManagerUIState state ) ;
// Function to set the window handle of the current UI window that is activated
void SetCurrentUIWindow ( HWND windowHandle ) ;
// Function to set the UI state. When a window is activated, the handle to the window can be passed in the windowHandle argument.
void SetUIState ( KeyboardManagerUIState state , HWND windowHandle = nullptr ) ;
// Function to clear the OS Level shortcut remapping table
void ClearOSLevelShortcuts ( ) ;
2020-03-27 23:38:58 +08:00
// Function to clear the Keys remapping table
void ClearSingleKeyRemaps ( ) ;
// Function to add a new single key remapping
2020-04-09 00:11:58 +08:00
bool AddSingleKeyRemap ( const DWORD & originalKey , const DWORD & newRemapKey ) ;
2020-03-27 23:38:58 +08:00
2020-03-24 01:44:02 +08:00
// Function to add a new OS level shortcut remapping
2020-04-09 00:11:58 +08:00
bool AddOSLevelShortcut ( const Shortcut & originalSC , const Shortcut & newSC ) ;
2020-03-24 01:44:02 +08:00
// Function to set the textblock of the detect shortcut UI so that it can be accessed by the hook
2020-04-09 05:31:31 +08:00
void ConfigureDetectShortcutUI ( const StackPanel & textBlock ) ;
2020-03-27 23:38:58 +08:00
// Function to set the textblock of the detect remap key UI so that it can be accessed by the hook
2020-04-09 05:31:31 +08:00
void ConfigureDetectSingleKeyRemapUI ( const StackPanel & textBlock ) ;
2020-03-24 01:44:02 +08:00
// Function to update the detect shortcut UI based on the entered keys
void UpdateDetectShortcutUI ( ) ;
2020-03-27 23:38:58 +08:00
// Function to update the detect remap key UI based on the entered key.
void UpdateDetectSingleKeyRemapUI ( ) ;
2020-03-24 01:44:02 +08:00
// Function to return the currently detected shortcut which is displayed on the UI
2020-04-09 00:11:58 +08:00
Shortcut GetDetectedShortcut ( ) ;
2020-03-24 01:44:02 +08:00
2020-03-27 23:38:58 +08:00
// Function to return the currently detected remap key which is displayed on the UI
DWORD GetDetectedSingleRemapKey ( ) ;
2020-03-24 01:44:02 +08:00
// Function which can be used in HandleKeyboardHookEvent before the single key remap event to use the UI and suppress events while the remap window is active.
2020-03-27 23:38:58 +08:00
bool DetectSingleRemapKeyUIBackend ( LowlevelKeyboardEvent * data ) ;
2020-03-24 01:44:02 +08:00
// Function which can be used in HandleKeyboardHookEvent before the os level shortcut remap event to use the UI and suppress events while the remap window is active.
bool DetectShortcutUIBackend ( LowlevelKeyboardEvent * data ) ;
} ;