diff --git a/common/core/desktop/.gitignore b/common/core/desktop/.gitignore index 40a3439fe8..90ca8c2bb1 100644 --- a/common/core/desktop/.gitignore +++ b/common/core/desktop/.gitignore @@ -9,3 +9,5 @@ wasm.build TIER.md VERSION.md shellHelperFunctions.sh + +src/rust/keyman_keyboard_processor/target/ diff --git a/common/core/desktop/include/keyman/keyboardprocessor.h.in b/common/core/desktop/include/keyman/keyboardprocessor.h.in index 430dc0b455..6bb681f672 100644 --- a/common/core/desktop/include/keyman/keyboardprocessor.h.in +++ b/common/core/desktop/include/keyman/keyboardprocessor.h.in @@ -478,6 +478,7 @@ typedef struct { uintptr_t marker; // MARKER type km_kbp_option_item const * option; // OPT types km_kbp_usv character; // CHAR type + uint8_t capsLock; // CAPSLOCK type, 1 to turn on, 0 to turn off }; } km_kbp_action_item; @@ -494,6 +495,7 @@ enum km_kbp_action_type { // for applications where context is cached, this clears the context; // for applications where context is read from the focused text store, // the context is just re-read and markers flushed. + KM_KBP_IT_CAPSLOCK = 8, // Enable or disable capsLock KM_KBP_IT_MAX_TYPE_ID }; @@ -940,7 +942,8 @@ KMN_API km_kbp_status km_kbp_process_event(km_kbp_state *state, km_kbp_virtual_key vk, - uint16_t modifier_state); + uint16_t modifier_state, + uint8_t is_key_down); #if defined(__cplusplus) } // extern "C" diff --git a/common/core/desktop/src/km_kbp_processevent_api.cpp b/common/core/desktop/src/km_kbp_processevent_api.cpp index 698ae7b2f2..747ee2858c 100644 --- a/common/core/desktop/src/km_kbp_processevent_api.cpp +++ b/common/core/desktop/src/km_kbp_processevent_api.cpp @@ -12,15 +12,15 @@ #include "processor.hpp" #include "state.hpp" -km_kbp_status +km_kbp_status km_kbp_process_event(km_kbp_state *state, - km_kbp_virtual_key vk, uint16_t modifier_state) -{ - return state->processor().process_event(state, vk, modifier_state); + km_kbp_virtual_key vk, + uint16_t modifier_state, + uint8_t is_key_down) { + return state->processor().process_event(state, vk, modifier_state, is_key_down); } - -km_kbp_attr const * +km_kbp_attr const * km_kbp_get_engine_attrs(km_kbp_state const *state) { return &state->processor().attributes(); diff --git a/common/core/desktop/src/kmx/kmx_capslock.cpp b/common/core/desktop/src/kmx/kmx_capslock.cpp index cd11290af7..9db0fab0a0 100644 --- a/common/core/desktop/src/kmx/kmx_capslock.cpp +++ b/common/core/desktop/src/kmx/kmx_capslock.cpp @@ -2,57 +2,80 @@ Copyright: Copyright (C) 2003-2018 SIL International. Authors: mcdurdin */ +#include #include using namespace km::kbp; using namespace kmx; -void KMX_ProcessEvent::ResetCapsLock(void) -{ - DebugLog("ResetCapsLock: enter"); +/** + * Set caps lock state. + * Called by ProcessEvent. + * May update `modifiers` to add or remove `CAPITALFLAG` according to capsLockOn + * parameter. May queue actions to set caps lock state. + * + * @param[in,out] modifiers The modifier key bitmap + * @param capsLockOn The desired caps lock state + */ +void KMX_ProcessEvent::SetCapsLock(KMX_DWORD &modifiers, KMX_BOOL capsLockOn) { + KMX_BOOL capsLockCurrentlyOn = IsCapsLockOn(modifiers); + if (capsLockCurrentlyOn == capsLockOn) { + return; + } - if (m_keyboard.Keyboard->dwFlags & KF_CAPSALWAYSOFF) - { + DebugLog("Caps lock is %s, switching %s", capsLockCurrentlyOn ? "on" : "off", capsLockOn ? "on" : "off"); + + m_actions.QueueAction(QIT_CAPSLOCK, capsLockOn); + if (capsLockOn) { + modifiers |= CAPITALFLAG; + } else { + modifiers &= ~CAPITALFLAG; + } +} + +/** + * Deal with CapsAlwaysOff store option and turns caps lock off if necessary. + * Called by ProcessEvent. + * May update `modifiers` to add or remove `CAPITALFLAG` according to keyboard + * requirements. May queue actions to set caps lock state. + * + * @param[in,out] modifiers The modifier key bitmap + */ +void KMX_ProcessEvent::ResetCapsLock(KMX_DWORD &modifiers) { + if (m_keyboard.Keyboard->dwFlags & KF_CAPSALWAYSOFF) { DebugLog("ResetCapsLock: caps lock should be always off"); - if (m_environment.capsLock()) - { - DebugLog("ResetCapsLock: caps lock is on, switching off caps lock"); - m_actions.QueueAction(QIT_CAPSLOCK, 0); - } - } - DebugLog("ResetCapsLock: exit"); -} - - -void KMX_ProcessEvent::KeyCapsLockPress(KMX_BOOL FIsUp) -{ - if (m_keyboard.Keyboard->dwFlags & KF_CAPSONONLY) - { - if(FIsUp && !m_environment.capsLock()) - { - m_actions.QueueAction(QIT_CAPSLOCK, 1); - } - } - else if (m_keyboard.Keyboard->dwFlags & KF_CAPSALWAYSOFF) - { - if(!FIsUp && m_environment.capsLock()) - { - m_actions.QueueAction(QIT_CAPSLOCK, 0); - } + SetCapsLock(modifiers, FALSE); } } - -void KMX_ProcessEvent::KeyShiftPress(KMX_BOOL FIsUp) -{ - if(!m_environment.capsLock()) return; - - if (m_keyboard.Keyboard->dwFlags & KF_SHIFTFREESCAPS) - { - if(!FIsUp) - { - m_actions.QueueAction(QIT_CAPSLOCK, 0); - } +/** + * Deal with CapsLock store options on CapsLock key press. Called by ProcessEvent. + * May update `modifiers` to add or remove `CAPITALFLAG` according to keyboard + * requirements. May queue actions to set caps lock state. + * + * @param[in,out] modifiers The modifier key bitmap + * @param isKeyDown TRUE if this is called on KeyDown event, FALSE if + * called on KeyUp event + */ +void KMX_ProcessEvent::KeyCapsLockPress(KMX_DWORD &modifiers, KMX_BOOL isKeyDown) { + if (m_keyboard.Keyboard->dwFlags & KF_CAPSONONLY && !isKeyDown) { + SetCapsLock(modifiers, TRUE); + } else if (m_keyboard.Keyboard->dwFlags & KF_CAPSALWAYSOFF && isKeyDown) { + SetCapsLock(modifiers, FALSE); } } +/** + * Deal with CapsLock store options on Shift key press. Called by ProcessEvent. + * May update `modifiers` to remove `CAPITALFLAG` according to keyboard + * requirements. May queue actions to reset caps lock state. + * + * @param[in,out] modifiers The modifier key bitmap + * @param isKeyDown TRUE if this is called on KeyDown event, FALSE if + * called on KeyUp event + */ +void KMX_ProcessEvent::KeyShiftPress(KMX_DWORD &modifiers, KMX_BOOL isKeyDown) { + if (m_keyboard.Keyboard->dwFlags & KF_SHIFTFREESCAPS && isKeyDown) { + SetCapsLock(modifiers, FALSE); + } +} diff --git a/common/core/desktop/src/kmx/kmx_environment.cpp b/common/core/desktop/src/kmx/kmx_environment.cpp index 1e166225c1..4d3d3c5490 100644 --- a/common/core/desktop/src/kmx/kmx_environment.cpp +++ b/common/core/desktop/src/kmx/kmx_environment.cpp @@ -16,7 +16,6 @@ namespace { *DEFAULT_BASELAYOUT = u"kbdus.dll", *DEFAULT_BASELAYOUTALT = u"en-US", *DEFAULT_SIMULATEALTGR = u"0", - *DEFAULT_CAPSLOCK = u"0", *DEFAULT_BASELAYOUTGIVESCTRLRALTFORRALT = u"0"; } @@ -25,7 +24,6 @@ KMX_Environment::KMX_Environment() { Set(KM_KBP_KMX_ENV_BASELAYOUT, DEFAULT_BASELAYOUT); Set(KM_KBP_KMX_ENV_BASELAYOUTALT, DEFAULT_BASELAYOUTALT); Set(KM_KBP_KMX_ENV_SIMULATEALTGR, DEFAULT_SIMULATEALTGR); - Set(KM_KBP_KMX_ENV_CAPSLOCK, DEFAULT_CAPSLOCK); Set(KM_KBP_KMX_ENV_BASELAYOUTGIVESCTRLRALTFORRALT, DEFAULT_BASELAYOUTGIVESCTRLRALTFORRALT); } @@ -46,9 +44,6 @@ char16_t const * KMX_Environment::LookUp(std::u16string const & key) const { else if (!u16icmp(key.c_str(), KM_KBP_KMX_ENV_SIMULATEALTGR)) { return _simulateAltGr ? u"1" : u"0"; } - else if (!u16icmp(key.c_str(), KM_KBP_KMX_ENV_CAPSLOCK)) { - return _capsLock ? u"1" : u"0"; - } else if (!u16icmp(key.c_str(), KM_KBP_KMX_ENV_BASELAYOUTGIVESCTRLRALTFORRALT)) { return _baseLayoutGivesCtrlRAltForRAlt ? u"1" : u"0"; } @@ -74,9 +69,6 @@ void KMX_Environment::Set(std::u16string const & key, std::u16string const & val else if (!u16icmp(key.c_str(), KM_KBP_KMX_ENV_SIMULATEALTGR)) { _simulateAltGr = value == u"1"; } - else if (!u16icmp(key.c_str(), KM_KBP_KMX_ENV_CAPSLOCK)) { - _capsLock = value == u"1"; - } else if (!u16icmp(key.c_str(), KM_KBP_KMX_ENV_BASELAYOUTGIVESCTRLRALTFORRALT)) { _baseLayoutGivesCtrlRAltForRAlt = value == u"1"; } diff --git a/common/core/desktop/src/kmx/kmx_environment.h b/common/core/desktop/src/kmx/kmx_environment.h index f1ee70faf6..4d934e0d10 100644 --- a/common/core/desktop/src/kmx/kmx_environment.h +++ b/common/core/desktop/src/kmx/kmx_environment.h @@ -12,7 +12,6 @@ class KMX_Environment { private: KMX_BOOL _simulateAltGr, _baseLayoutGivesCtrlRAltForRAlt; std::u16string _baseLayout, _baseLayoutAlt; - KMX_BOOL _capsLock; std::u16string _platform; void InitOption( std::vector