feat(radio): optional key lock feature (#7383)
This commit is contained in:
@@ -978,7 +978,7 @@ bool BoardJson::loadDefinition()
|
||||
if (m_board == Board::BOARD_UNKNOWN)
|
||||
return true;
|
||||
|
||||
if (!loadFile(m_board, m_hwdefn, m_inputs, m_switches, m_keys, m_trims, m_display, m_cfs, m_hardware))
|
||||
if (!loadFile(m_board, m_hwdefn, m_inputs, m_switches, m_keys, m_trims, m_display, m_cfs, m_hardware, m_hasKeyLockCombo))
|
||||
return false;
|
||||
|
||||
afterLoadFixups(m_board, m_inputs, m_switches, m_keys, m_trims);
|
||||
@@ -1015,7 +1015,7 @@ bool BoardJson::loadDefinition()
|
||||
// static
|
||||
bool BoardJson::loadFile(Board::Type board, QString hwdefn, InputsTable * inputs, SwitchesTable * switches,
|
||||
KeysTable * keys, TrimsTable * trims, DisplayDefn & display, CustomSwitchesDefn & cfs,
|
||||
HardwareDefn & hardware)
|
||||
HardwareDefn & hardware, bool & hasKeyLockCombo)
|
||||
{
|
||||
if (board == Board::BOARD_UNKNOWN) {
|
||||
return false;
|
||||
@@ -1202,6 +1202,9 @@ bool BoardJson::loadFile(Board::Type board, QString hwdefn, InputsTable * inputs
|
||||
}
|
||||
}
|
||||
|
||||
hasKeyLockCombo = obj.value("key_lock_combo").isArray() &&
|
||||
obj.value("key_lock_combo").toArray().size() == 2;
|
||||
|
||||
if (obj.value("trims").isArray()) {
|
||||
const QJsonArray &trms = obj.value("trims").toArray();
|
||||
|
||||
@@ -1315,4 +1318,4 @@ const QString BoardJson::getCapabilityStr(const Board::Capability capability) co
|
||||
default:
|
||||
return QString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -167,6 +167,7 @@ class BoardJson
|
||||
|
||||
const Board::KeyInfo getKeyInfo(int index) const;
|
||||
const int getKeyIndex(const QString key) const;
|
||||
bool hasKeyLockCombo() const { return m_hasKeyLockCombo; }
|
||||
|
||||
const int getSwitchIndex(const QString val, Board::LookupValueType lvt) const;
|
||||
const int getCFSIndexForSwitch(int sw) const;
|
||||
@@ -201,6 +202,7 @@ private:
|
||||
DisplayDefn m_display;
|
||||
CustomSwitchesDefn m_cfs;
|
||||
HardwareDefn m_hardware;
|
||||
bool m_hasKeyLockCombo = false;
|
||||
|
||||
struct InputCounts {
|
||||
unsigned int flexGyroAxes;
|
||||
@@ -226,7 +228,7 @@ private:
|
||||
|
||||
static bool loadFile(Board::Type board, QString hwdefn, InputsTable * inputs, SwitchesTable * switches,
|
||||
KeysTable * keys, TrimsTable * trims, DisplayDefn & lcd, CustomSwitchesDefn & cfs,
|
||||
HardwareDefn & hardware);
|
||||
HardwareDefn & hardware, bool & hasKeyLockCombo);
|
||||
static void afterLoadFixups(Board::Type board, InputsTable * inputs, SwitchesTable * switches,
|
||||
KeysTable * keys, TrimsTable * trims);
|
||||
|
||||
|
||||
@@ -417,6 +417,7 @@ Node convert<GeneralSettings>::encode(const GeneralSettings& rhs)
|
||||
}
|
||||
|
||||
node["oneLogPerDay"] = (int)rhs.oneLogPerDay;
|
||||
node["keyLockEnabled"] = (int)rhs.keyLockEnabled;
|
||||
|
||||
return node;
|
||||
}
|
||||
@@ -780,6 +781,7 @@ bool convert<GeneralSettings>::decode(const Node& node, GeneralSettings& rhs)
|
||||
}
|
||||
|
||||
node["oneLogPerDay"] >> rhs.oneLogPerDay;
|
||||
node["keyLockEnabled"] >> rhs.keyLockEnabled;
|
||||
|
||||
// override critical settings after import
|
||||
// TODO: for consistency move up call stack to use existing eeprom and profile conversions
|
||||
|
||||
@@ -459,6 +459,7 @@ class GeneralSettings {
|
||||
unsigned int qmFavorites[MAX_QMFAVOURITES];
|
||||
char* qmFavoritesTools[MAX_QMFAVOURITES];
|
||||
bool oneLogPerDay;
|
||||
bool keyLockEnabled;
|
||||
|
||||
void switchConfigClear();
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "autocombobox.h"
|
||||
#include "namevalidator.h"
|
||||
#include "helpers.h"
|
||||
#include "boardjson.h"
|
||||
|
||||
constexpr char FIM_HATSMODE[] {"Hats Mode"};
|
||||
constexpr char FIM_STICKMODE[] {"Stick Mode"};
|
||||
@@ -474,6 +475,17 @@ void GeneralSetupPanel::setValues()
|
||||
ui->startSoundCB->setChecked(!generalSettings.dontPlayHello);
|
||||
ui->modelQuickSelect_CB->setChecked(generalSettings.modelQuickSelect);
|
||||
ui->chkOneLogPerDay->setChecked(generalSettings.oneLogPerDay);
|
||||
{
|
||||
BoardJson* bj = Boards::getBoardJson(board);
|
||||
bool hasCombo = bj && bj->hasKeyLockCombo();
|
||||
ui->chkKeyLockEnabled->setChecked(hasCombo && generalSettings.keyLockEnabled);
|
||||
ui->chkKeyLockEnabled->setEnabled(hasCombo);
|
||||
ui->label_keyLockEnabled->setEnabled(hasCombo);
|
||||
if (!hasCombo) {
|
||||
ui->chkKeyLockEnabled->setToolTip(tr("Not available on this radio (no key combo defined)"));
|
||||
ui->label_keyLockEnabled->setToolTip(tr("Not available on this radio (no key combo defined)"));
|
||||
}
|
||||
}
|
||||
|
||||
if (Boards::getCapability(board, Board::HasColorLcd)) {
|
||||
ui->modelSelectLayout_CB->setCurrentIndex(generalSettings.modelSelectLayout);
|
||||
@@ -951,3 +963,11 @@ void GeneralSetupPanel::on_chkOneLogPerDay_stateChanged(int)
|
||||
emit modified();
|
||||
}
|
||||
}
|
||||
|
||||
void GeneralSetupPanel::on_chkKeyLockEnabled_stateChanged(int)
|
||||
{
|
||||
if (!lock) {
|
||||
generalSettings.keyLockEnabled = ui->chkKeyLockEnabled->isChecked();
|
||||
emit modified();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,6 +103,7 @@ class GeneralSetupPanel : public GeneralPanel
|
||||
|
||||
void on_pwrOffIfInactiveSB_editingFinished();
|
||||
void on_chkOneLogPerDay_stateChanged(int);
|
||||
void on_chkKeyLockEnabled_stateChanged(int);
|
||||
|
||||
private:
|
||||
Ui::GeneralSetup *ui;
|
||||
|
||||
@@ -1326,6 +1326,20 @@ p, li { white-space: pre-wrap; }
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="30" column="0">
|
||||
<widget class="QLabel" name="label_keyLockEnabled">
|
||||
<property name="text">
|
||||
<string>Key lock</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="30" column="1">
|
||||
<widget class="QCheckBox" name="chkKeyLockEnabled">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
|
||||
@@ -146,9 +146,16 @@ AddHWGenTarget(${HW_DESC_JSON} stm32_pwm_inputs stm32_pwm_inputs.inc)
|
||||
AddHWGenTarget(${HW_DESC_JSON} simu_keys simu_keys.inc)
|
||||
AddHWGenTarget(${HW_DESC_JSON} simu_switches simu_switches.inc)
|
||||
|
||||
AddHWGenTarget(${HW_DESC_JSON} hal_keys_lock hal_keys_lock.h)
|
||||
add_custom_target(hal_keys_lock_hdr DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/hal_keys_lock.h)
|
||||
if(TARGET board)
|
||||
add_dependencies(board hal_keys_lock_hdr)
|
||||
endif()
|
||||
|
||||
add_dependencies(board hal_settings hal_keys hal_adc_inputs stm32_keys stm32_switches stm32_adc_inputs stm32_pwm_inputs yaml_inputs lua_inputs lua_mixsrc lua_keys)
|
||||
add_dependencies(board_bl hal_settings hal_keys stm32_keys)
|
||||
|
||||
|
||||
include(hal/CMakeLists.txt)
|
||||
|
||||
add_subdirectory(bitmaps)
|
||||
|
||||
@@ -24,9 +24,10 @@ set(BOARD_LIB_SRC
|
||||
|
||||
add_library(minimal_board_lib OBJECT EXCLUDE_FROM_ALL ${MINIMAL_BOARD_LIB_SRC})
|
||||
add_dependencies(minimal_board_lib stm32_keys)
|
||||
add_dependencies(minimal_board_lib hal_keys_lock_hdr)
|
||||
|
||||
add_library(board_lib OBJECT EXCLUDE_FROM_ALL ${BOARD_LIB_SRC})
|
||||
add_dependencies(board_lib minimal_board_lib)
|
||||
add_dependencies(board_lib minimal_board_lib hal_keys_lock_hdr)
|
||||
|
||||
if(DEBUG)
|
||||
target_compile_definitions(board_lib PRIVATE DEBUG)
|
||||
|
||||
@@ -354,5 +354,9 @@
|
||||
"haptic_counter_register": "HAPTIC_TIMER->CCR2",
|
||||
"haptic_ccmr1": "TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2M_2",
|
||||
"haptic_ccer": "TIM_CCER_CC2E"
|
||||
}
|
||||
},
|
||||
"key_lock_combo": [
|
||||
"KEY_SYS",
|
||||
"KEY_MODEL"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -425,5 +425,9 @@
|
||||
"haptic_counter_register": "HAPTIC_TIMER->CCR2",
|
||||
"haptic_ccmr1": "TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2M_2",
|
||||
"haptic_ccer": "TIM_CCER_CC2E"
|
||||
}
|
||||
},
|
||||
"key_lock_combo": [
|
||||
"KEY_MENU",
|
||||
"KEY_ENTER"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -376,5 +376,9 @@
|
||||
"mixer_scheduler_timer_freq": "(PERI1_FREQUENCY * TIMER_MULT_APB1)",
|
||||
"mixer_scheduler_timer_irqn": "TIM8_BRK_TIM12_IRQn",
|
||||
"mixer_scheduler_timer_irqhandler": "TIM8_BRK_TIM12_IRQHandler"
|
||||
}
|
||||
},
|
||||
"key_lock_combo": [
|
||||
"KEY_SYS",
|
||||
"KEY_MODEL"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -300,5 +300,9 @@
|
||||
"haptic_counter_register": "HAPTIC_TIMER->CCR1",
|
||||
"haptic_ccmr1": "TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2",
|
||||
"haptic_ccer": "TIM_CCER_CC1E"
|
||||
}
|
||||
},
|
||||
"key_lock_combo": [
|
||||
"KEY_SYS",
|
||||
"KEY_MODEL"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -460,5 +460,9 @@
|
||||
"haptic_timer_output_enable": "TIM_CCER_CC2E",
|
||||
"haptic_timer_mode": "TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2M_2",
|
||||
"haptic_timer_compare_value": "HAPTIC_GPIO_TIMER->CCR2"
|
||||
}
|
||||
},
|
||||
"key_lock_combo": [
|
||||
"KEY_SYS",
|
||||
"KEY_MODEL"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -482,5 +482,9 @@
|
||||
"haptic_counter_register": "HAPTIC_TIMER->CCR2",
|
||||
"haptic_ccmr1": "TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2M_2",
|
||||
"haptic_ccer": "TIM_CCER_CC2E"
|
||||
}
|
||||
},
|
||||
"key_lock_combo": [
|
||||
"KEY_SYS",
|
||||
"KEY_MODEL"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -282,5 +282,9 @@
|
||||
"haptic_counter_register": "HAPTIC_TIMER->CCR1",
|
||||
"haptic_ccmr1": "TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2",
|
||||
"haptic_ccer": "TIM_CCER_CC1E"
|
||||
}
|
||||
},
|
||||
"key_lock_combo": [
|
||||
"KEY_ENTER",
|
||||
"KEY_RIGHT"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -347,5 +347,9 @@
|
||||
"haptic_counter_register": "HAPTIC_TIMER->CCR2",
|
||||
"haptic_ccmr1": "TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2M_2",
|
||||
"haptic_ccer": "TIM_CCER_CC2E"
|
||||
}
|
||||
},
|
||||
"key_lock_combo": [
|
||||
"KEY_SYS",
|
||||
"KEY_MODEL"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -317,5 +317,9 @@
|
||||
"haptic_counter_register": "HAPTIC_TIMER->CCR2",
|
||||
"haptic_ccmr1": "TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2M_2",
|
||||
"haptic_ccer": "TIM_CCER_CC2E"
|
||||
}
|
||||
},
|
||||
"key_lock_combo": [
|
||||
"KEY_SYS",
|
||||
"KEY_MODEL"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -477,5 +477,9 @@
|
||||
"haptic_timer_output_enable": "TIM_CCER_CC2E | TIM_CCER_CC2NE",
|
||||
"haptic_timer_mode": "TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2M_2 | TIM_CCMR1_OC2PE",
|
||||
"haptic_timer_compare_value": "HAPTIC_GPIO_TIMER->CCR2"
|
||||
}
|
||||
},
|
||||
"key_lock_combo": [
|
||||
"KEY_EXIT",
|
||||
"KEY_ENTER"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -356,5 +356,9 @@
|
||||
"haptic_counter_register": "HAPTIC_TIMER->CCR1",
|
||||
"haptic_ccmr1": "TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2",
|
||||
"haptic_ccer": "TIM_CCER_CC1E"
|
||||
}
|
||||
},
|
||||
"key_lock_combo": [
|
||||
"KEY_ENTER",
|
||||
"KEY_RIGHT"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -317,5 +317,9 @@
|
||||
"haptic_counter_register": "HAPTIC_TIMER->CCR2",
|
||||
"haptic_ccmr1": "TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2M_2",
|
||||
"haptic_ccer": "TIM_CCER_CC2E"
|
||||
}
|
||||
},
|
||||
"key_lock_combo": [
|
||||
"KEY_PAGEDN",
|
||||
"KEY_ENTER"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -332,5 +332,9 @@
|
||||
"haptic_counter_register": "HAPTIC_TIMER->CCR2",
|
||||
"haptic_ccmr1": "TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2M_2",
|
||||
"haptic_ccer": "TIM_CCER_CC2E"
|
||||
}
|
||||
},
|
||||
"key_lock_combo": [
|
||||
"KEY_MENU",
|
||||
"KEY_ENTER"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -394,5 +394,9 @@
|
||||
"haptic_timer_output_enable": "TIM_CCER_CC1E | TIM_CCER_CC1NE",
|
||||
"haptic_timer_mode": "TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2 | TIM_CCMR1_OC1PE",
|
||||
"haptic_timer_compare_value": "HAPTIC_GPIO_TIMER->CCR1"
|
||||
}
|
||||
},
|
||||
"key_lock_combo": [
|
||||
"KEY_SYS",
|
||||
"KEY_TELE"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -444,5 +444,9 @@
|
||||
"haptic_timer_output_enable": "TIM_CCER_CC2E | TIM_CCER_CC2NE",
|
||||
"haptic_timer_mode": "TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2M_2 | TIM_CCMR1_OC2PE",
|
||||
"haptic_timer_compare_value": "HAPTIC_GPIO_TIMER->CCR2"
|
||||
}
|
||||
},
|
||||
"key_lock_combo": [
|
||||
"KEY_PAGEDN",
|
||||
"KEY_ENTER"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -474,5 +474,9 @@
|
||||
"haptic_timer_output_enable": "TIM_CCER_CC2E",
|
||||
"haptic_timer_mode": "TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2M_2",
|
||||
"haptic_timer_compare_value": "HAPTIC_GPIO_TIMER->CCR2"
|
||||
}
|
||||
},
|
||||
"key_lock_combo": [
|
||||
"KEY_SYS",
|
||||
"KEY_MODEL"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -475,5 +475,9 @@
|
||||
"haptic_timer_output_enable": "TIM_CCER_CC2E",
|
||||
"haptic_timer_mode": "TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2M_2",
|
||||
"haptic_timer_compare_value": "HAPTIC_GPIO_TIMER->CCR2"
|
||||
}
|
||||
},
|
||||
"key_lock_combo": [
|
||||
"KEY_SYS",
|
||||
"KEY_MODEL"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -555,5 +555,9 @@
|
||||
"haptic_counter_register": "HAPTIC_TIMER->CCR1",
|
||||
"haptic_ccmr1": "TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2",
|
||||
"haptic_ccer": "TIM_CCER_CC1E"
|
||||
}
|
||||
},
|
||||
"key_lock_combo": [
|
||||
"KEY_MENU",
|
||||
"KEY_ENTER"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -558,5 +558,9 @@
|
||||
"haptic_counter_register": "HAPTIC_TIMER->CCR2",
|
||||
"haptic_ccmr1": "TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2M_2",
|
||||
"haptic_ccer": "TIM_CCER_CC2E"
|
||||
}
|
||||
},
|
||||
"key_lock_combo": [
|
||||
"KEY_MENU",
|
||||
"KEY_ENTER"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -545,5 +545,9 @@
|
||||
"haptic_timer_output_enable": "TIM_CCER_CC2E | TIM_CCER_CC2NE",
|
||||
"haptic_timer_mode": "TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2M_2 | TIM_CCMR1_OC2PE",
|
||||
"haptic_timer_compare_value": "HAPTIC_GPIO_TIMER->CCR2"
|
||||
}
|
||||
},
|
||||
"key_lock_combo": [
|
||||
"KEY_PAGEDN",
|
||||
"KEY_ENTER"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -295,5 +295,9 @@
|
||||
"haptic_counter_register": "HAPTIC_TIMER->CCR1",
|
||||
"haptic_ccmr1": "TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2",
|
||||
"haptic_ccer": "TIM_CCER_CC1E"
|
||||
}
|
||||
},
|
||||
"key_lock_combo": [
|
||||
"KEY_SYS",
|
||||
"KEY_MODEL"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -280,5 +280,9 @@
|
||||
"haptic_counter_register": "HAPTIC_TIMER->CCR1",
|
||||
"haptic_ccmr1": "TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2",
|
||||
"haptic_ccer": "TIM_CCER_CC1E"
|
||||
}
|
||||
},
|
||||
"key_lock_combo": [
|
||||
"KEY_ENTER",
|
||||
"KEY_RIGHT"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -386,5 +386,9 @@
|
||||
"haptic_counter_register": "HAPTIC_TIMER->CCR1",
|
||||
"haptic_ccmr1": "TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2",
|
||||
"haptic_ccer": "TIM_CCER_CC1E"
|
||||
}
|
||||
},
|
||||
"key_lock_combo": [
|
||||
"KEY_MENU",
|
||||
"KEY_ENTER"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -319,5 +319,9 @@
|
||||
"haptic_counter_register": "HAPTIC_TIMER->CCR2",
|
||||
"haptic_ccmr1": "TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2M_2",
|
||||
"haptic_ccer": "TIM_CCER_CC2E"
|
||||
}
|
||||
},
|
||||
"key_lock_combo": [
|
||||
"KEY_MENU",
|
||||
"KEY_ENTER"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -416,5 +416,9 @@
|
||||
"haptic_counter_register": "HAPTIC_TIMER->CCR1",
|
||||
"haptic_ccmr1": "TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2",
|
||||
"haptic_ccer": "TIM_CCER_CC1E"
|
||||
}
|
||||
},
|
||||
"key_lock_combo": [
|
||||
"KEY_MENU",
|
||||
"KEY_ENTER"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -366,5 +366,9 @@
|
||||
"haptic_counter_register": "HAPTIC_TIMER->CCR1",
|
||||
"haptic_ccmr1": "TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2",
|
||||
"haptic_ccer": "TIM_CCER_CC1E"
|
||||
}
|
||||
},
|
||||
"key_lock_combo": [
|
||||
"KEY_SYS",
|
||||
"KEY_MODEL"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -346,5 +346,9 @@
|
||||
"haptic_counter_register": "HAPTIC_TIMER->CCR2",
|
||||
"haptic_ccmr1": "TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2M_2",
|
||||
"haptic_ccer": "TIM_CCER_CC2E"
|
||||
}
|
||||
},
|
||||
"key_lock_combo": [
|
||||
"KEY_SYS",
|
||||
"KEY_MODEL"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -430,5 +430,9 @@
|
||||
"haptic_timer_output_enable": "TIM_CCER_CC2E | TIM_CCER_CC2NE",
|
||||
"haptic_timer_mode": "TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2M_2 | TIM_CCMR1_OC2PE",
|
||||
"haptic_timer_compare_value": "HAPTIC_GPIO_TIMER->CCR2"
|
||||
}
|
||||
},
|
||||
"key_lock_combo": [
|
||||
"KEY_SYS",
|
||||
"KEY_MODEL"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -482,5 +482,9 @@
|
||||
"haptic_timer_output_enable": "TIM_CCER_CC2E",
|
||||
"haptic_timer_mode": "TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2M_2",
|
||||
"haptic_timer_compare_value": "HAPTIC_GPIO_TIMER->CCR2"
|
||||
}
|
||||
},
|
||||
"key_lock_combo": [
|
||||
"KEY_SYS",
|
||||
"KEY_MODEL"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -544,5 +544,9 @@
|
||||
"haptic_timer_output_enable": "TIM_CCER_CC2E | TIM_CCER_CC2NE",
|
||||
"haptic_timer_mode": "TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2M_2 | TIM_CCMR1_OC2PE",
|
||||
"haptic_timer_compare_value": "HAPTIC_GPIO_TIMER->CCR2"
|
||||
}
|
||||
},
|
||||
"key_lock_combo": [
|
||||
"KEY_SYS",
|
||||
"KEY_MODEL"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -394,5 +394,9 @@
|
||||
"haptic_counter_register": "HAPTIC_TIMER->CCR2",
|
||||
"haptic_ccmr1": "TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2M_2",
|
||||
"haptic_ccer": "TIM_CCER_CC2E"
|
||||
}
|
||||
},
|
||||
"key_lock_combo": [
|
||||
"KEY_SYS",
|
||||
"KEY_MODEL"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -393,5 +393,9 @@
|
||||
"haptic_counter_register": "HAPTIC_TIMER->CCR2",
|
||||
"haptic_ccmr1": "TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2M_2",
|
||||
"haptic_ccer": "TIM_CCER_CC2E"
|
||||
}
|
||||
},
|
||||
"key_lock_combo": [
|
||||
"KEY_SYS",
|
||||
"KEY_MODEL"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -493,5 +493,9 @@
|
||||
"haptic_timer_output_enable": "TIM_CCER_CC2E",
|
||||
"haptic_timer_mode": "TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2M_2",
|
||||
"haptic_timer_compare_value": "HAPTIC_GPIO_TIMER->CCR2"
|
||||
}
|
||||
},
|
||||
"key_lock_combo": [
|
||||
"KEY_SYS",
|
||||
"KEY_MODEL"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -479,5 +479,9 @@
|
||||
"haptic_timer_output_enable": "TIM_CCER_CC2E",
|
||||
"haptic_timer_mode": "TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2M_2",
|
||||
"haptic_timer_compare_value": "HAPTIC_GPIO_TIMER->CCR2"
|
||||
}
|
||||
},
|
||||
"key_lock_combo": [
|
||||
"KEY_PAGEDN",
|
||||
"KEY_SYS"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -479,5 +479,9 @@
|
||||
"haptic_timer_output_enable": "TIM_CCER_CC2E",
|
||||
"haptic_timer_mode": "TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2M_2",
|
||||
"haptic_timer_compare_value": "HAPTIC_GPIO_TIMER->CCR2"
|
||||
}
|
||||
},
|
||||
"key_lock_combo": [
|
||||
"KEY_SYS",
|
||||
"KEY_MODEL"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -468,5 +468,9 @@
|
||||
"haptic_timer_output_enable": "TIM_CCER_CC1E",
|
||||
"haptic_timer_mode": "TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2",
|
||||
"haptic_timer_compare_value": "HAPTIC_GPIO_TIMER->CCR1"
|
||||
}
|
||||
},
|
||||
"key_lock_combo": [
|
||||
"KEY_PAGEUP",
|
||||
"KEY_ENTER"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -344,5 +344,9 @@
|
||||
"haptic_counter_register": "HAPTIC_TIMER->CCR1",
|
||||
"haptic_ccmr1": "TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2",
|
||||
"haptic_ccer": "TIM_CCER_CC1E"
|
||||
}
|
||||
},
|
||||
"key_lock_combo": [
|
||||
"KEY_MENU",
|
||||
"KEY_ENTER"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -329,5 +329,9 @@
|
||||
"haptic_counter_register": "HAPTIC_TIMER->CCR3",
|
||||
"haptic_ccmr2": "TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3M_2",
|
||||
"haptic_ccer": "TIM_CCER_CC3E"
|
||||
}
|
||||
},
|
||||
"key_lock_combo": [
|
||||
"KEY_MENU",
|
||||
"KEY_ENTER"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -393,5 +393,9 @@
|
||||
"haptic_counter_register": "HAPTIC_TIMER->CCR1",
|
||||
"haptic_ccmr1": "TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2",
|
||||
"haptic_ccer": "TIM_CCER_CC1E"
|
||||
}
|
||||
},
|
||||
"key_lock_combo": [
|
||||
"KEY_MENU",
|
||||
"KEY_EXIT"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -387,5 +387,9 @@
|
||||
"haptic_counter_register": "HAPTIC_TIMER->CCR3",
|
||||
"haptic_ccmr2": "TIM_CCMR2_OC3M_1 | TIM_CCMR2_OC3M_2",
|
||||
"haptic_ccer": "TIM_CCER_CC3E"
|
||||
}
|
||||
},
|
||||
"key_lock_combo": [
|
||||
"KEY_MENU",
|
||||
"KEY_EXIT"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -372,5 +372,9 @@
|
||||
},
|
||||
"haptic": {
|
||||
"haptic_gpio": "GPIO_PIN(GPIOC, 14)"
|
||||
}
|
||||
},
|
||||
"key_lock_combo": [
|
||||
"KEY_MENU",
|
||||
"KEY_EXIT"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -585,5 +585,9 @@
|
||||
"haptic_counter_register": "HAPTIC_TIMER->CCR1",
|
||||
"haptic_ccmr1": "TIM_CCMR1_OC1M_1 | TIM_CCMR1_OC1M_2",
|
||||
"haptic_ccer": "TIM_CCER_CC1E"
|
||||
}
|
||||
},
|
||||
"key_lock_combo": [
|
||||
"KEY_MENU",
|
||||
"KEY_EXIT"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -292,5 +292,9 @@
|
||||
"haptic_counter_register": "HAPTIC_TIMER->CCR2",
|
||||
"haptic_ccmr1": "TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2M_2",
|
||||
"haptic_ccer": "TIM_CCER_CC2E"
|
||||
}
|
||||
},
|
||||
"key_lock_combo": [
|
||||
"KEY_MENU",
|
||||
"KEY_EXIT"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -319,5 +319,9 @@
|
||||
"haptic_counter_register": "HAPTIC_TIMER->CCR2",
|
||||
"haptic_ccmr1": "TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2M_2",
|
||||
"haptic_ccer": "TIM_CCER_CC2E"
|
||||
}
|
||||
},
|
||||
"key_lock_combo": [
|
||||
"KEY_MENU",
|
||||
"KEY_EXIT"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -370,5 +370,9 @@
|
||||
"haptic_counter_register": "HAPTIC_TIMER->CCR2",
|
||||
"haptic_ccmr1": "TIM_CCMR1_OC2M_1 | TIM_CCMR1_OC2M_2",
|
||||
"haptic_ccer": "TIM_CCER_CC2E"
|
||||
}
|
||||
},
|
||||
"key_lock_combo": [
|
||||
"KEY_SYS",
|
||||
"KEY_MODEL"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -79,12 +79,12 @@ static inline void check_struct()
|
||||
#if defined(PCBXLITES)
|
||||
CHKSIZE(RadioData, 951);
|
||||
#elif defined(RADIO_ST16) || defined(PCBPA01) || defined(RADIO_TX15) || defined(RADIO_T15PRO) || defined(RADIO_TX16SMK3) || defined(RADIO_T22)
|
||||
CHKSIZE(RadioData, 1182);
|
||||
CHKSIZE(RadioData, 1183);
|
||||
#elif defined(COLORLCD)
|
||||
#if defined(IMU)
|
||||
CHKSIZE(RadioData, 1062);
|
||||
CHKSIZE(RadioData, 1063);
|
||||
#else
|
||||
CHKSIZE(RadioData, 1061);
|
||||
CHKSIZE(RadioData, 1062);
|
||||
#endif
|
||||
#elif defined(RADIO_GX12)
|
||||
CHKSIZE(RadioData, 1068);
|
||||
|
||||
@@ -1163,13 +1163,16 @@ PACK(struct RadioData {
|
||||
NOBACKUP(uint8_t modelSelectLayout:2);
|
||||
NOBACKUP(uint8_t radioThemesDisabled:1);
|
||||
NOBACKUP(uint8_t oneLogPerDay:1);
|
||||
NOBACKUP(uint8_t keyLockEnabled:1);
|
||||
#elif LCD_W == 128
|
||||
uint8_t invertLCD:1; // Invert B&W LCD display
|
||||
NOBACKUP(uint8_t oneLogPerDay:1);
|
||||
NOBACKUP(uint8_t spare:5 SKIP);
|
||||
NOBACKUP(uint8_t keyLockEnabled:1);
|
||||
NOBACKUP(uint8_t spare:4 SKIP);
|
||||
#else
|
||||
NOBACKUP(uint8_t oneLogPerDay:1);
|
||||
NOBACKUP(uint8_t spare:6 SKIP);
|
||||
NOBACKUP(uint8_t keyLockEnabled:1);
|
||||
NOBACKUP(uint8_t spare:5 SKIP);
|
||||
#endif
|
||||
|
||||
NOBACKUP(uint8_t pwrOffIfInactive);
|
||||
|
||||
@@ -87,6 +87,7 @@ enum {
|
||||
CASE_BACKLIGHT(ITEM_RADIO_SETUP_BACKLIGHT_SOURCE)
|
||||
CASE_BACKLIGHT(ITEM_RADIO_SETUP_BACKLIGHT_SOURCE_OVERRIDE)
|
||||
CASE_BACKLIGHT(ITEM_RADIO_SETUP_FLASH_BEEP)
|
||||
CASE_KEY_LOCK(ITEM_RADIO_SETUP_KEY_LOCK)
|
||||
ITEM_RADIO_ONE_LOG_PER_DAY,
|
||||
CASE_SPLASH_PARAM(ITEM_RADIO_SETUP_DISABLE_SPLASH)
|
||||
CASE_PWR_BUTTON_PRESS(ITEM_RADIO_SETUP_PWR_ON_SPEED)
|
||||
@@ -228,7 +229,6 @@ void menuRadioSetup(event_t event)
|
||||
CASE_BACKLIGHT(0)
|
||||
CASE_BACKLIGHT(BACKLIGHT_WARNING_ROW(LABEL(0)))
|
||||
CASE_BACKLIGHT(0)
|
||||
0,
|
||||
CASE_SPLASH_PARAM(0)
|
||||
CASE_PWR_BUTTON_PRESS(0)
|
||||
CASE_PWR_BUTTON_PRESS(0)
|
||||
@@ -628,6 +628,20 @@ void menuRadioSetup(event_t event)
|
||||
break;
|
||||
}
|
||||
|
||||
#if defined(KEYS_LOCK_KEY1) && defined(KEYS_LOCK_KEY2)
|
||||
case ITEM_RADIO_SETUP_KEY_LOCK: {
|
||||
static char lbl[24];
|
||||
const char* k1 = keysGetLabel((EnumKeys)KEYS_LOCK_KEY1);
|
||||
const char* k2 = keysGetLabel((EnumKeys)KEYS_LOCK_KEY2);
|
||||
snprintf(lbl, sizeof(lbl), STR_KEY_LOCK_FMT,
|
||||
k1 ? k1 : "?", k2 ? k2 : "?");
|
||||
lcdDrawTextAlignedLeft(y, lbl);
|
||||
g_eeGeneral.keyLockEnabled =
|
||||
editCheckBox(g_eeGeneral.keyLockEnabled, LCD_W - 9, y, nullptr, attr, event);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
case ITEM_RADIO_SETUP_DISABLE_SPLASH:
|
||||
{
|
||||
lcdDrawTextAlignedLeft(y, STR_SPLASHSCREEN);
|
||||
|
||||
@@ -90,6 +90,7 @@ enum MenuRadioSetupItems {
|
||||
ITEM_RADIO_SETUP_BACKLIGHT_SOURCE,
|
||||
ITEM_RADIO_SETUP_BACKLIGHT_SOURCE_OVERRIDE,
|
||||
ITEM_RADIO_SETUP_FLASH_BEEP,
|
||||
CASE_KEY_LOCK(ITEM_RADIO_SETUP_KEY_LOCK)
|
||||
ITEM_RADIO_ONE_LOG_PER_DAY,
|
||||
CASE_SPLASH_PARAM(ITEM_RADIO_SETUP_DISABLE_SPLASH)
|
||||
CASE_PWR_BUTTON_PRESS(ITEM_RADIO_SETUP_PWR_ON_SPEED)
|
||||
@@ -235,6 +236,7 @@ void menuRadioSetup(event_t event)
|
||||
BACKLIGHT_WARNING_ROW(LABEL(0)), // backlight control override warning
|
||||
0, // flash beep
|
||||
0,
|
||||
CASE_KEY_LOCK(0) // key lock
|
||||
CASE_SPLASH_PARAM(0) // disable splash
|
||||
CASE_PWR_BUTTON_PRESS(0) // pwr on speed
|
||||
CASE_PWR_BUTTON_PRESS(0) // pwr off speed
|
||||
@@ -619,6 +621,20 @@ void menuRadioSetup(event_t event)
|
||||
break;
|
||||
}
|
||||
|
||||
#if defined(KEYS_LOCK_KEY1) && defined(KEYS_LOCK_KEY2)
|
||||
case ITEM_RADIO_SETUP_KEY_LOCK: {
|
||||
static char lbl[24];
|
||||
const char* k1 = keysGetLabel((EnumKeys)KEYS_LOCK_KEY1);
|
||||
const char* k2 = keysGetLabel((EnumKeys)KEYS_LOCK_KEY2);
|
||||
snprintf(lbl, sizeof(lbl), STR_KEY_LOCK_FMT,
|
||||
k1 ? k1 : "?", k2 ? k2 : "?");
|
||||
lcdDrawTextAlignedLeft(y, lbl);
|
||||
g_eeGeneral.keyLockEnabled =
|
||||
editCheckBox(g_eeGeneral.keyLockEnabled, RADIO_SETUP_2ND_COLUMN, y, nullptr, attr, event);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
case ITEM_RADIO_SETUP_DISABLE_SPLASH:
|
||||
lcdDrawTextAlignedLeft(y, STR_SPLASHSCREEN);
|
||||
if (SPLASH_NEEDED()) {
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "pagegroup.h"
|
||||
#include "qmpagechoice.h"
|
||||
#include "radio_tools.h"
|
||||
#include "toggleswitch.h"
|
||||
|
||||
#define SET_DIRTY() storageDirty(EE_GENERAL)
|
||||
|
||||
@@ -87,6 +88,18 @@ QMKeyShortcutsPage::QMKeyShortcutsPage():
|
||||
{
|
||||
auto qmPages = QuickMenu::menuPageNames(false);
|
||||
|
||||
#if defined(KEYS_LOCK_KEY1) && defined(KEYS_LOCK_KEY2)
|
||||
static char keyLockLabel[45];
|
||||
const char* k1 = keysGetLabel((EnumKeys)KEYS_LOCK_KEY1);
|
||||
const char* k2 = keysGetLabel((EnumKeys)KEYS_LOCK_KEY2);
|
||||
snprintf(keyLockLabel, sizeof(keyLockLabel), STR_KEY_LOCK_FMT,
|
||||
k1 ? k1 : "?", k2 ? k2 : "?");
|
||||
setupLine(keyLockLabel, [=](Window* parent, coord_t x, coord_t y) {
|
||||
new ToggleSwitch(parent, {x, y, 0, 0},
|
||||
GET_SET_DEFAULT(g_eeGeneral.keyLockEnabled));
|
||||
});
|
||||
#endif
|
||||
|
||||
setupLine(STR_SHORT_PRESS, nullptr);
|
||||
addKey(EVT_KEY_BREAK(KEY_SYS), qmPages, "SYS");
|
||||
addKey(EVT_KEY_BREAK(KEY_MODEL), qmPages, "MDL");
|
||||
|
||||
@@ -47,6 +47,12 @@
|
||||
#define CASE_BACKLIGHT(x)
|
||||
#endif
|
||||
|
||||
#if defined(KEYS_LOCK_KEY1) && defined(KEYS_LOCK_KEY2)
|
||||
#define CASE_KEY_LOCK(x) x,
|
||||
#else
|
||||
#define CASE_KEY_LOCK(x)
|
||||
#endif
|
||||
|
||||
#if defined(RTCLOCK)
|
||||
#define CASE_RTCLOCK(x) x,
|
||||
#else
|
||||
|
||||
+58
-1
@@ -28,7 +28,7 @@
|
||||
#include "hal/rotary_encoder.h"
|
||||
#include "dataconstants.h"
|
||||
|
||||
#if !defined(BOOT) && (defined(USE_HATS_AS_KEYS) || defined(PCBXLITE))
|
||||
#if !defined(BOOT)
|
||||
#include "edgetx.h"
|
||||
#endif
|
||||
|
||||
@@ -183,6 +183,26 @@ void Key::killEvents()
|
||||
static Key keys[MAX_KEYS];
|
||||
static Key trim_keys[MAX_TRIMS * 2];
|
||||
|
||||
#if !defined(BOOT)
|
||||
// Per-target key combo (from hal.h KEYS_LOCK_KEY1/KEY2) long-pressed together
|
||||
// toggles a software key lock.
|
||||
static bool s_keys_locked = false;
|
||||
static bool s_keys_lock_notify = false;
|
||||
static uint8_t s_keys_lock_combo_cnt = 0;
|
||||
|
||||
bool areKeysLocked() { return s_keys_locked; }
|
||||
|
||||
bool consumeKeysLockToggleEvent()
|
||||
{
|
||||
if (!s_keys_lock_notify) return false;
|
||||
s_keys_lock_notify = false;
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
bool areKeysLocked() { return false; }
|
||||
bool consumeKeysLockToggleEvent() { return false; }
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief returns true if there is an event waiting.
|
||||
*
|
||||
@@ -494,11 +514,48 @@ bool keysPollingCycle()
|
||||
trims_input = READ_TRIMS();
|
||||
#endif
|
||||
|
||||
#if !defined(BOOT) && defined(KEYS_LOCK_KEY1) && defined(KEYS_LOCK_KEY2)
|
||||
// Combo keys (from hal.h) long-pressed together toggle the key lock; killing
|
||||
// the per-key events while both are held prevents their individual actions
|
||||
// from firing.
|
||||
if (g_eeGeneral.keyLockEnabled &&
|
||||
keyIsSupported(KEYS_LOCK_KEY1) && keyIsSupported(KEYS_LOCK_KEY2)) {
|
||||
bool both = (keys_input & (1u << KEYS_LOCK_KEY1)) &&
|
||||
(keys_input & (1u << KEYS_LOCK_KEY2));
|
||||
if (both) {
|
||||
keys[KEYS_LOCK_KEY1].killEvents();
|
||||
keys[KEYS_LOCK_KEY2].killEvents();
|
||||
if (s_keys_lock_combo_cnt < 0xFF) s_keys_lock_combo_cnt++;
|
||||
if (s_keys_lock_combo_cnt == KEY_LONG_DELAY) {
|
||||
s_keys_locked = !s_keys_locked;
|
||||
s_keys_lock_notify = true;
|
||||
}
|
||||
} else {
|
||||
s_keys_lock_combo_cnt = 0;
|
||||
}
|
||||
} else {
|
||||
// Feature disabled: never leave keys stuck locked.
|
||||
s_keys_locked = false;
|
||||
s_keys_lock_combo_cnt = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
for (int i = 0; i < MAX_KEYS; i++) {
|
||||
event_t evt = keys[i].input(keys_input & (1 << i));
|
||||
if (evt) {
|
||||
evt = keyMapping(evt | i);
|
||||
#if !defined(BOOT)
|
||||
if (evt) {
|
||||
if (!s_keys_locked) {
|
||||
pushEvent(evt);
|
||||
} else if ((evt & _MSK_KEY_FLAGS) == _MSK_KEY_FIRST) {
|
||||
// Re-show the "Keys locked" toast on each new key press while locked.
|
||||
s_keys_lock_notify = true;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (evt) pushEvent(evt);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,9 @@
|
||||
#include "edgetx_types.h"
|
||||
|
||||
#include "hal/key_driver.h"
|
||||
#if !defined(BOOT) && !defined(SIMU)
|
||||
#include "hal_keys_lock.h"
|
||||
#endif
|
||||
|
||||
constexpr event_t EVT_REFRESH = 0x1000;
|
||||
constexpr event_t EVT_ENTRY = 0x1001;
|
||||
@@ -186,6 +189,12 @@ uint8_t keysGetTrimState(uint8_t trim);
|
||||
bool keysPollingCycle();
|
||||
bool rotaryEncoderPollingCycle();
|
||||
|
||||
// Holding the per-target combo (KEYS_LOCK_KEY1 + KEYS_LOCK_KEY2 from hal.h)
|
||||
// for KEY_LONG_DELAY toggles the key lock. While locked, key events are
|
||||
// suppressed; trims/sticks/switches still work.
|
||||
bool areKeysLocked();
|
||||
bool consumeKeysLockToggleEvent();
|
||||
|
||||
#if defined(USE_HATS_AS_KEYS)
|
||||
void setHatsAsKeys(bool val);
|
||||
bool getHatsAsKeys();
|
||||
|
||||
@@ -282,6 +282,54 @@ void checkHatsAsKeys()
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(COLORLCD)
|
||||
// Tick count at which to clear our key-lock message. 0 = no message active.
|
||||
static tmr10ms_t s_keysLockMsgUntil = 0;
|
||||
static const char* s_keysLockMsg = nullptr;
|
||||
#endif
|
||||
|
||||
void checkKeysLock()
|
||||
{
|
||||
if (consumeKeysLockToggleEvent()) {
|
||||
audioKeyPress();
|
||||
const char* lockedMsg = STR_KEYS_LOCKED;
|
||||
#if defined(KEYS_LOCK_KEY1) && defined(KEYS_LOCK_KEY2)
|
||||
static char lockedBuf[45];
|
||||
const char* k1 = keysGetLabel((EnumKeys)KEYS_LOCK_KEY1);
|
||||
const char* k2 = keysGetLabel((EnumKeys)KEYS_LOCK_KEY2);
|
||||
snprintf(lockedBuf, sizeof(lockedBuf), STR_KEYS_LOCKED_FMT,
|
||||
k1 ? k1 : "?", k2 ? k2 : "?");
|
||||
lockedMsg = lockedBuf;
|
||||
#endif
|
||||
#if defined(COLORLCD)
|
||||
POPUP_BUBBLE(areKeysLocked() ? lockedMsg : STR_KEYS_UNLOCKED, 1500);
|
||||
#else
|
||||
// Can't use a modal POPUP_INFORMATION: keys may be locked, so the user
|
||||
// couldn't dismiss it. Keep our own deadline and re-arm POPUP_WAIT every
|
||||
// tick below — that survives other code clearing warningText (e.g. the
|
||||
// GVAR display in view_main.cpp).
|
||||
s_keysLockMsg = areKeysLocked() ? lockedMsg : STR_KEYS_UNLOCKED;
|
||||
s_keysLockMsgUntil = get_tmr10ms() + 150;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !defined(COLORLCD)
|
||||
if (s_keysLockMsgUntil) {
|
||||
if ((int32_t)(get_tmr10ms() - s_keysLockMsgUntil) >= 0) {
|
||||
s_keysLockMsgUntil = 0;
|
||||
// Only clear if our message is still the active one; another popup
|
||||
// may have replaced it in the meantime.
|
||||
if (warningText == s_keysLockMsg) CLEAR_POPUP();
|
||||
s_keysLockMsg = nullptr;
|
||||
} else {
|
||||
// Keep the popup fresh every tick — another path (GVAR, etc.) may
|
||||
// have cleared warningText; just re-arm it.
|
||||
POPUP_WAIT(s_keysLockMsg);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void checkStorageUpdate()
|
||||
{
|
||||
#if defined(RTC_BACKUP_RAM) && !defined(SIMU)
|
||||
@@ -547,6 +595,8 @@ void perMain()
|
||||
checkHatsAsKeys();
|
||||
#endif
|
||||
|
||||
checkKeysLock();
|
||||
|
||||
#if defined(COLORLCD)
|
||||
MainWindow::instance()->run();
|
||||
#endif
|
||||
|
||||
@@ -385,7 +385,8 @@ static const struct YamlNode struct_RadioData[] = {
|
||||
YAML_UNSIGNED( "modelQuickSelect", 1 ),
|
||||
YAML_UNSIGNED( "invertLCD", 1 ),
|
||||
YAML_UNSIGNED( "oneLogPerDay", 1 ),
|
||||
YAML_PADDING( 5 ),
|
||||
YAML_UNSIGNED( "keyLockEnabled", 1 ),
|
||||
YAML_PADDING( 4 ),
|
||||
YAML_UNSIGNED( "pwrOffIfInactive", 8 ),
|
||||
YAML_END
|
||||
};
|
||||
|
||||
@@ -457,6 +457,7 @@ static const struct YamlNode struct_RadioData[] = {
|
||||
YAML_UNSIGNED( "modelSelectLayout", 2 ),
|
||||
YAML_UNSIGNED( "radioThemesDisabled", 1 ),
|
||||
YAML_UNSIGNED( "oneLogPerDay", 1 ),
|
||||
YAML_UNSIGNED( "keyLockEnabled", 1 ),
|
||||
YAML_UNSIGNED( "pwrOffIfInactive", 8 ),
|
||||
YAML_ARRAY("keyShortcuts", 8, 6, struct_KeyShortcut, NULL),
|
||||
YAML_ARRAY("qmFavorites", 8, 12, struct_QMFavorite, NULL),
|
||||
|
||||
@@ -458,6 +458,7 @@ static const struct YamlNode struct_RadioData[] = {
|
||||
YAML_UNSIGNED( "modelSelectLayout", 2 ),
|
||||
YAML_UNSIGNED( "radioThemesDisabled", 1 ),
|
||||
YAML_UNSIGNED( "oneLogPerDay", 1 ),
|
||||
YAML_UNSIGNED( "keyLockEnabled", 1 ),
|
||||
YAML_UNSIGNED( "pwrOffIfInactive", 8 ),
|
||||
YAML_ARRAY("keyShortcuts", 8, 6, struct_KeyShortcut, NULL),
|
||||
YAML_ARRAY("qmFavorites", 8, 12, struct_QMFavorite, NULL),
|
||||
|
||||
@@ -409,7 +409,8 @@ static const struct YamlNode struct_RadioData[] = {
|
||||
YAML_UNSIGNED( "modelQuickSelect", 1 ),
|
||||
YAML_UNSIGNED( "invertLCD", 1 ),
|
||||
YAML_UNSIGNED( "oneLogPerDay", 1 ),
|
||||
YAML_PADDING( 5 ),
|
||||
YAML_UNSIGNED( "keyLockEnabled", 1 ),
|
||||
YAML_PADDING( 4 ),
|
||||
YAML_UNSIGNED( "pwrOffIfInactive", 8 ),
|
||||
YAML_END
|
||||
};
|
||||
|
||||
@@ -448,6 +448,7 @@ static const struct YamlNode struct_RadioData[] = {
|
||||
YAML_UNSIGNED( "modelSelectLayout", 2 ),
|
||||
YAML_UNSIGNED( "radioThemesDisabled", 1 ),
|
||||
YAML_UNSIGNED( "oneLogPerDay", 1 ),
|
||||
YAML_UNSIGNED( "keyLockEnabled", 1 ),
|
||||
YAML_UNSIGNED( "pwrOffIfInactive", 8 ),
|
||||
YAML_ARRAY("keyShortcuts", 8, 6, struct_KeyShortcut, NULL),
|
||||
YAML_ARRAY("qmFavorites", 8, 12, struct_QMFavorite, NULL),
|
||||
|
||||
@@ -455,6 +455,7 @@ static const struct YamlNode struct_RadioData[] = {
|
||||
YAML_UNSIGNED( "modelSelectLayout", 2 ),
|
||||
YAML_UNSIGNED( "radioThemesDisabled", 1 ),
|
||||
YAML_UNSIGNED( "oneLogPerDay", 1 ),
|
||||
YAML_UNSIGNED( "keyLockEnabled", 1 ),
|
||||
YAML_UNSIGNED( "pwrOffIfInactive", 8 ),
|
||||
YAML_ARRAY("keyShortcuts", 8, 6, struct_KeyShortcut, NULL),
|
||||
YAML_ARRAY("qmFavorites", 8, 12, struct_QMFavorite, NULL),
|
||||
|
||||
@@ -481,6 +481,7 @@ static const struct YamlNode struct_RadioData[] = {
|
||||
YAML_UNSIGNED( "modelSelectLayout", 2 ),
|
||||
YAML_UNSIGNED( "radioThemesDisabled", 1 ),
|
||||
YAML_UNSIGNED( "oneLogPerDay", 1 ),
|
||||
YAML_UNSIGNED( "keyLockEnabled", 1 ),
|
||||
YAML_UNSIGNED( "pwrOffIfInactive", 8 ),
|
||||
YAML_ARRAY("keyShortcuts", 8, 6, struct_KeyShortcut, NULL),
|
||||
YAML_ARRAY("qmFavorites", 8, 12, struct_QMFavorite, NULL),
|
||||
|
||||
@@ -455,6 +455,7 @@ static const struct YamlNode struct_RadioData[] = {
|
||||
YAML_UNSIGNED( "modelSelectLayout", 2 ),
|
||||
YAML_UNSIGNED( "radioThemesDisabled", 1 ),
|
||||
YAML_UNSIGNED( "oneLogPerDay", 1 ),
|
||||
YAML_UNSIGNED( "keyLockEnabled", 1 ),
|
||||
YAML_UNSIGNED( "pwrOffIfInactive", 8 ),
|
||||
YAML_ARRAY("keyShortcuts", 8, 6, struct_KeyShortcut, NULL),
|
||||
YAML_ARRAY("qmFavorites", 8, 12, struct_QMFavorite, NULL),
|
||||
|
||||
@@ -448,6 +448,7 @@ static const struct YamlNode struct_RadioData[] = {
|
||||
YAML_UNSIGNED( "modelSelectLayout", 2 ),
|
||||
YAML_UNSIGNED( "radioThemesDisabled", 1 ),
|
||||
YAML_UNSIGNED( "oneLogPerDay", 1 ),
|
||||
YAML_UNSIGNED( "keyLockEnabled", 1 ),
|
||||
YAML_UNSIGNED( "pwrOffIfInactive", 8 ),
|
||||
YAML_ARRAY("keyShortcuts", 8, 6, struct_KeyShortcut, NULL),
|
||||
YAML_ARRAY("qmFavorites", 8, 12, struct_QMFavorite, NULL),
|
||||
|
||||
@@ -481,6 +481,7 @@ static const struct YamlNode struct_RadioData[] = {
|
||||
YAML_UNSIGNED( "modelSelectLayout", 2 ),
|
||||
YAML_UNSIGNED( "radioThemesDisabled", 1 ),
|
||||
YAML_UNSIGNED( "oneLogPerDay", 1 ),
|
||||
YAML_UNSIGNED( "keyLockEnabled", 1 ),
|
||||
YAML_UNSIGNED( "pwrOffIfInactive", 8 ),
|
||||
YAML_ARRAY("keyShortcuts", 8, 6, struct_KeyShortcut, NULL),
|
||||
YAML_ARRAY("qmFavorites", 8, 12, struct_QMFavorite, NULL),
|
||||
|
||||
@@ -466,6 +466,7 @@ static const struct YamlNode struct_RadioData[] = {
|
||||
YAML_UNSIGNED( "modelSelectLayout", 2 ),
|
||||
YAML_UNSIGNED( "radioThemesDisabled", 1 ),
|
||||
YAML_UNSIGNED( "oneLogPerDay", 1 ),
|
||||
YAML_UNSIGNED( "keyLockEnabled", 1 ),
|
||||
YAML_UNSIGNED( "pwrOffIfInactive", 8 ),
|
||||
YAML_ARRAY("keyShortcuts", 8, 6, struct_KeyShortcut, NULL),
|
||||
YAML_ARRAY("qmFavorites", 8, 12, struct_QMFavorite, NULL),
|
||||
|
||||
@@ -481,6 +481,7 @@ static const struct YamlNode struct_RadioData[] = {
|
||||
YAML_UNSIGNED( "modelSelectLayout", 2 ),
|
||||
YAML_UNSIGNED( "radioThemesDisabled", 1 ),
|
||||
YAML_UNSIGNED( "oneLogPerDay", 1 ),
|
||||
YAML_UNSIGNED( "keyLockEnabled", 1 ),
|
||||
YAML_UNSIGNED( "pwrOffIfInactive", 8 ),
|
||||
YAML_ARRAY("keyShortcuts", 8, 6, struct_KeyShortcut, NULL),
|
||||
YAML_ARRAY("qmFavorites", 8, 12, struct_QMFavorite, NULL),
|
||||
|
||||
@@ -394,7 +394,8 @@ static const struct YamlNode struct_RadioData[] = {
|
||||
YAML_UNSIGNED( "modelQuickSelect", 1 ),
|
||||
YAML_UNSIGNED( "invertLCD", 1 ),
|
||||
YAML_UNSIGNED( "oneLogPerDay", 1 ),
|
||||
YAML_PADDING( 5 ),
|
||||
YAML_UNSIGNED( "keyLockEnabled", 1 ),
|
||||
YAML_PADDING( 4 ),
|
||||
YAML_UNSIGNED( "pwrOffIfInactive", 8 ),
|
||||
YAML_END
|
||||
};
|
||||
|
||||
@@ -481,6 +481,7 @@ static const struct YamlNode struct_RadioData[] = {
|
||||
YAML_UNSIGNED( "modelSelectLayout", 2 ),
|
||||
YAML_UNSIGNED( "radioThemesDisabled", 1 ),
|
||||
YAML_UNSIGNED( "oneLogPerDay", 1 ),
|
||||
YAML_UNSIGNED( "keyLockEnabled", 1 ),
|
||||
YAML_UNSIGNED( "pwrOffIfInactive", 8 ),
|
||||
YAML_ARRAY("keyShortcuts", 8, 6, struct_KeyShortcut, NULL),
|
||||
YAML_ARRAY("qmFavorites", 8, 12, struct_QMFavorite, NULL),
|
||||
|
||||
@@ -394,7 +394,8 @@ static const struct YamlNode struct_RadioData[] = {
|
||||
YAML_UNSIGNED( "modelQuickSelect", 1 ),
|
||||
YAML_UNSIGNED( "invertLCD", 1 ),
|
||||
YAML_UNSIGNED( "oneLogPerDay", 1 ),
|
||||
YAML_PADDING( 5 ),
|
||||
YAML_UNSIGNED( "keyLockEnabled", 1 ),
|
||||
YAML_PADDING( 4 ),
|
||||
YAML_UNSIGNED( "pwrOffIfInactive", 8 ),
|
||||
YAML_END
|
||||
};
|
||||
|
||||
@@ -481,6 +481,7 @@ static const struct YamlNode struct_RadioData[] = {
|
||||
YAML_UNSIGNED( "modelSelectLayout", 2 ),
|
||||
YAML_UNSIGNED( "radioThemesDisabled", 1 ),
|
||||
YAML_UNSIGNED( "oneLogPerDay", 1 ),
|
||||
YAML_UNSIGNED( "keyLockEnabled", 1 ),
|
||||
YAML_UNSIGNED( "pwrOffIfInactive", 8 ),
|
||||
YAML_ARRAY("keyShortcuts", 8, 6, struct_KeyShortcut, NULL),
|
||||
YAML_ARRAY("qmFavorites", 8, 12, struct_QMFavorite, NULL),
|
||||
|
||||
@@ -482,6 +482,7 @@ static const struct YamlNode struct_RadioData[] = {
|
||||
YAML_UNSIGNED( "modelSelectLayout", 2 ),
|
||||
YAML_UNSIGNED( "radioThemesDisabled", 1 ),
|
||||
YAML_UNSIGNED( "oneLogPerDay", 1 ),
|
||||
YAML_UNSIGNED( "keyLockEnabled", 1 ),
|
||||
YAML_UNSIGNED( "pwrOffIfInactive", 8 ),
|
||||
YAML_ARRAY("keyShortcuts", 8, 6, struct_KeyShortcut, NULL),
|
||||
YAML_ARRAY("qmFavorites", 8, 12, struct_QMFavorite, NULL),
|
||||
|
||||
@@ -457,6 +457,7 @@ static const struct YamlNode struct_RadioData[] = {
|
||||
YAML_UNSIGNED( "modelSelectLayout", 2 ),
|
||||
YAML_UNSIGNED( "radioThemesDisabled", 1 ),
|
||||
YAML_UNSIGNED( "oneLogPerDay", 1 ),
|
||||
YAML_UNSIGNED( "keyLockEnabled", 1 ),
|
||||
YAML_UNSIGNED( "pwrOffIfInactive", 8 ),
|
||||
YAML_ARRAY("keyShortcuts", 8, 6, struct_KeyShortcut, NULL),
|
||||
YAML_ARRAY("qmFavorites", 8, 12, struct_QMFavorite, NULL),
|
||||
|
||||
@@ -384,7 +384,8 @@ static const struct YamlNode struct_RadioData[] = {
|
||||
YAML_SIGNED( "disablePwrOnOffHaptic", 1 ),
|
||||
YAML_UNSIGNED( "modelQuickSelect", 1 ),
|
||||
YAML_UNSIGNED( "oneLogPerDay", 1 ),
|
||||
YAML_PADDING( 6 ),
|
||||
YAML_UNSIGNED( "keyLockEnabled", 1 ),
|
||||
YAML_PADDING( 5 ),
|
||||
YAML_UNSIGNED( "pwrOffIfInactive", 8 ),
|
||||
YAML_END
|
||||
};
|
||||
|
||||
@@ -384,7 +384,8 @@ static const struct YamlNode struct_RadioData[] = {
|
||||
YAML_SIGNED( "disablePwrOnOffHaptic", 1 ),
|
||||
YAML_UNSIGNED( "modelQuickSelect", 1 ),
|
||||
YAML_UNSIGNED( "oneLogPerDay", 1 ),
|
||||
YAML_PADDING( 6 ),
|
||||
YAML_UNSIGNED( "keyLockEnabled", 1 ),
|
||||
YAML_PADDING( 5 ),
|
||||
YAML_UNSIGNED( "pwrOffIfInactive", 8 ),
|
||||
YAML_END
|
||||
};
|
||||
|
||||
@@ -384,7 +384,8 @@ static const struct YamlNode struct_RadioData[] = {
|
||||
YAML_SIGNED( "disablePwrOnOffHaptic", 1 ),
|
||||
YAML_UNSIGNED( "modelQuickSelect", 1 ),
|
||||
YAML_UNSIGNED( "oneLogPerDay", 1 ),
|
||||
YAML_PADDING( 6 ),
|
||||
YAML_UNSIGNED( "keyLockEnabled", 1 ),
|
||||
YAML_PADDING( 5 ),
|
||||
YAML_UNSIGNED( "pwrOffIfInactive", 8 ),
|
||||
YAML_END
|
||||
};
|
||||
|
||||
@@ -385,7 +385,8 @@ static const struct YamlNode struct_RadioData[] = {
|
||||
YAML_UNSIGNED( "modelQuickSelect", 1 ),
|
||||
YAML_UNSIGNED( "invertLCD", 1 ),
|
||||
YAML_UNSIGNED( "oneLogPerDay", 1 ),
|
||||
YAML_PADDING( 5 ),
|
||||
YAML_UNSIGNED( "keyLockEnabled", 1 ),
|
||||
YAML_PADDING( 4 ),
|
||||
YAML_UNSIGNED( "pwrOffIfInactive", 8 ),
|
||||
YAML_END
|
||||
};
|
||||
|
||||
@@ -390,7 +390,8 @@ static const struct YamlNode struct_RadioData[] = {
|
||||
YAML_UNSIGNED( "modelQuickSelect", 1 ),
|
||||
YAML_UNSIGNED( "invertLCD", 1 ),
|
||||
YAML_UNSIGNED( "oneLogPerDay", 1 ),
|
||||
YAML_PADDING( 5 ),
|
||||
YAML_UNSIGNED( "keyLockEnabled", 1 ),
|
||||
YAML_PADDING( 4 ),
|
||||
YAML_UNSIGNED( "pwrOffIfInactive", 8 ),
|
||||
YAML_END
|
||||
};
|
||||
|
||||
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* Copyright (C) EdgeTX
|
||||
*
|
||||
* License GPLv2: http://www.gnu.org/licenses/gpl-2.0.html
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include "gtests.h"
|
||||
|
||||
#if defined(KEYS_LOCK_KEY1) && defined(KEYS_LOCK_KEY2)
|
||||
|
||||
// keys.cpp local; must match.
|
||||
static constexpr int LOCK_POLL_DELAY = 32;
|
||||
// A few extra polling cycles past the threshold to be safe against off-by-ones.
|
||||
static constexpr int LOCK_POLL_HOLD = LOCK_POLL_DELAY + 4;
|
||||
|
||||
static void releaseAllKeys()
|
||||
{
|
||||
for (int i = 0; i < MAX_KEYS; i++) simuSetKey(i, false);
|
||||
// Drain any pending events from prior tests.
|
||||
while (getEvent()) {}
|
||||
// Two polling cycles to let the Key debouncers see "released".
|
||||
keysPollingCycle();
|
||||
keysPollingCycle();
|
||||
while (getEvent()) {}
|
||||
(void)consumeKeysLockToggleEvent();
|
||||
}
|
||||
|
||||
static void holdComboFor(int cycles)
|
||||
{
|
||||
simuSetKey(KEYS_LOCK_KEY1, true);
|
||||
simuSetKey(KEYS_LOCK_KEY2, true);
|
||||
for (int i = 0; i < cycles; i++) keysPollingCycle();
|
||||
}
|
||||
|
||||
class KeyLockTest : public EdgeTxTest
|
||||
{
|
||||
protected:
|
||||
void SetUp() override
|
||||
{
|
||||
EdgeTxTest::SetUp();
|
||||
g_eeGeneral.keyLockEnabled = 1;
|
||||
releaseAllKeys();
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(KeyLockTest, ComboTogglesLock)
|
||||
{
|
||||
EXPECT_FALSE(areKeysLocked());
|
||||
|
||||
holdComboFor(LOCK_POLL_HOLD);
|
||||
EXPECT_TRUE(areKeysLocked());
|
||||
EXPECT_TRUE(consumeKeysLockToggleEvent());
|
||||
EXPECT_FALSE(consumeKeysLockToggleEvent()); // consumed once
|
||||
|
||||
releaseAllKeys();
|
||||
|
||||
holdComboFor(LOCK_POLL_HOLD);
|
||||
EXPECT_FALSE(areKeysLocked());
|
||||
EXPECT_TRUE(consumeKeysLockToggleEvent());
|
||||
}
|
||||
|
||||
TEST_F(KeyLockTest, BriefComboDoesNotToggle)
|
||||
{
|
||||
// Hold for fewer cycles than the long-press threshold.
|
||||
holdComboFor(LOCK_POLL_DELAY - 2);
|
||||
EXPECT_FALSE(areKeysLocked());
|
||||
EXPECT_FALSE(consumeKeysLockToggleEvent());
|
||||
}
|
||||
|
||||
TEST_F(KeyLockTest, DisabledFlagPreventsLocking)
|
||||
{
|
||||
g_eeGeneral.keyLockEnabled = 0;
|
||||
holdComboFor(LOCK_POLL_HOLD);
|
||||
EXPECT_FALSE(areKeysLocked());
|
||||
EXPECT_FALSE(consumeKeysLockToggleEvent());
|
||||
}
|
||||
|
||||
TEST_F(KeyLockTest, DisablingFlagWhileLockedReleasesLock)
|
||||
{
|
||||
holdComboFor(LOCK_POLL_HOLD);
|
||||
ASSERT_TRUE(areKeysLocked());
|
||||
(void)consumeKeysLockToggleEvent();
|
||||
releaseAllKeys();
|
||||
|
||||
// Turning the feature off must never leave the radio stuck locked.
|
||||
g_eeGeneral.keyLockEnabled = 0;
|
||||
keysPollingCycle();
|
||||
EXPECT_FALSE(areKeysLocked());
|
||||
}
|
||||
|
||||
// Find a key not part of the lock combo to use for input-suppression tests.
|
||||
static int pickProbeKey()
|
||||
{
|
||||
for (int i = 0; i < MAX_KEYS; i++) {
|
||||
if (i == KEYS_LOCK_KEY1 || i == KEYS_LOCK_KEY2) continue;
|
||||
if (keyIsSupported((EnumKeys)i)) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
TEST_F(KeyLockTest, LockedKeyPressIsSuppressed)
|
||||
{
|
||||
int probe = pickProbeKey();
|
||||
if (probe < 0) GTEST_SKIP() << "no spare key to probe with";
|
||||
|
||||
// Sanity check: while unlocked, a key press emits an event.
|
||||
simuSetKey(probe, true);
|
||||
keysPollingCycle();
|
||||
simuSetKey(probe, false);
|
||||
keysPollingCycle();
|
||||
bool sawEvent = false;
|
||||
while (event_t e = getEvent()) { (void)e; sawEvent = true; }
|
||||
EXPECT_TRUE(sawEvent);
|
||||
|
||||
// Lock the keys.
|
||||
holdComboFor(LOCK_POLL_HOLD);
|
||||
ASSERT_TRUE(areKeysLocked());
|
||||
(void)consumeKeysLockToggleEvent();
|
||||
releaseAllKeys();
|
||||
|
||||
// Now key presses must not push any events.
|
||||
simuSetKey(probe, true);
|
||||
keysPollingCycle();
|
||||
simuSetKey(probe, false);
|
||||
keysPollingCycle();
|
||||
EXPECT_EQ(getEvent(), (event_t)0);
|
||||
|
||||
// A key press while locked re-arms the toggle-event notification so the
|
||||
// UI can re-show the "Keys locked" toast.
|
||||
EXPECT_TRUE(consumeKeysLockToggleEvent());
|
||||
}
|
||||
|
||||
#endif // KEYS_LOCK_KEY1 && KEYS_LOCK_KEY2
|
||||
@@ -570,6 +570,10 @@
|
||||
#define TR_KEYS_BACKLIGHT "按键背光"
|
||||
#define TR_BLCOLOR "颜色"
|
||||
#define TR_ONE_LOG_PER_DAY "One log per day"
|
||||
#define TR_KEY_LOCK_FMT "Key lock (%s+%s hold)"
|
||||
#define TR_KEYS_LOCKED "Keys locked"
|
||||
#define TR_KEYS_LOCKED_FMT "Keys locked (%s+%s)"
|
||||
#define TR_KEYS_UNLOCKED "Keys unlocked"
|
||||
#define TR_SPLASHSCREEN "开机图片"
|
||||
#define TR_PLAY_HELLO "开机语音"
|
||||
#define TR_PWR_ON_DELAY "开机延迟"
|
||||
|
||||
@@ -573,6 +573,10 @@
|
||||
#define TR_KEYS_BACKLIGHT "Podsvětlení kláves"
|
||||
#define TR_BLCOLOR "Barva"
|
||||
#define TR_ONE_LOG_PER_DAY "One log per day"
|
||||
#define TR_KEY_LOCK_FMT "Key lock (%s+%s hold)"
|
||||
#define TR_KEYS_LOCKED "Keys locked"
|
||||
#define TR_KEYS_LOCKED_FMT "Keys locked (%s+%s)"
|
||||
#define TR_KEYS_UNLOCKED "Keys unlocked"
|
||||
#define TR_SPLASHSCREEN TR("úvodní logo", "Zobrazit úvodní logo")
|
||||
#define TR_PLAY_HELLO "Zvuk při spuštění"
|
||||
#define TR_PWR_ON_DELAY "Zpoždění zapnutí"
|
||||
|
||||
@@ -575,6 +575,10 @@
|
||||
#define TR_KEYS_BACKLIGHT "Taster klarhed"
|
||||
#define TR_BLCOLOR "Farve"
|
||||
#define TR_ONE_LOG_PER_DAY "One log per day"
|
||||
#define TR_KEY_LOCK_FMT "Key lock (%s+%s hold)"
|
||||
#define TR_KEYS_LOCKED "Keys locked"
|
||||
#define TR_KEYS_LOCKED_FMT "Keys locked (%s+%s)"
|
||||
#define TR_KEYS_UNLOCKED "Keys unlocked"
|
||||
#define TR_SPLASHSCREEN "Start skærm"
|
||||
#define TR_PLAY_HELLO "Startop lyd"
|
||||
#define TR_PWR_ON_DELAY "Forsinkelse ved tænd"
|
||||
|
||||
@@ -571,6 +571,10 @@
|
||||
#define TR_KEYS_BACKLIGHT "Tastenbeleucht."
|
||||
#define TR_BLCOLOR "Farbe"
|
||||
#define TR_ONE_LOG_PER_DAY "One log per day"
|
||||
#define TR_KEY_LOCK_FMT "Key lock (%s+%s hold)"
|
||||
#define TR_KEYS_LOCKED "Keys locked"
|
||||
#define TR_KEYS_LOCKED_FMT "Keys locked (%s+%s)"
|
||||
#define TR_KEYS_UNLOCKED "Keys unlocked"
|
||||
#define TR_SPLASHSCREEN TR("Startbild Ein", "Startbild Anzeigedauer")
|
||||
#define TR_PLAY_HELLO "Startton abspielen"
|
||||
#define TR_PWR_ON_DELAY TR("PWR EIN Verzög.", "Einschaltverzögerung")
|
||||
|
||||
@@ -571,6 +571,10 @@
|
||||
#define TR_KEYS_BACKLIGHT "Keys backlight"
|
||||
#define TR_BLCOLOR "Color"
|
||||
#define TR_ONE_LOG_PER_DAY "One log per day"
|
||||
#define TR_KEY_LOCK_FMT "Key lock (%s+%s hold)"
|
||||
#define TR_KEYS_LOCKED "Keys locked"
|
||||
#define TR_KEYS_LOCKED_FMT "Keys locked (%s+%s)"
|
||||
#define TR_KEYS_UNLOCKED "Keys unlocked"
|
||||
#define TR_SPLASHSCREEN "Splash screen"
|
||||
#define TR_PLAY_HELLO "Startup Sound"
|
||||
#define TR_PWR_ON_DELAY "Pwr On delay"
|
||||
|
||||
@@ -569,6 +569,10 @@
|
||||
#define TR_KEYS_BACKLIGHT "Keys backlight"
|
||||
#define TR_BLCOLOR "Color"
|
||||
#define TR_ONE_LOG_PER_DAY "One log per day"
|
||||
#define TR_KEY_LOCK_FMT "Key lock (%s+%s hold)"
|
||||
#define TR_KEYS_LOCKED "Keys locked"
|
||||
#define TR_KEYS_LOCKED_FMT "Keys locked (%s+%s)"
|
||||
#define TR_KEYS_UNLOCKED "Keys unlocked"
|
||||
#define TR_SPLASHSCREEN "Pantalla inicio"
|
||||
#define TR_PLAY_HELLO "Startup Sound"
|
||||
#define TR_PWR_ON_DELAY TR("Atraso On", "Atraso encendido")
|
||||
|
||||
@@ -570,6 +570,10 @@
|
||||
#define TR_KEYS_BACKLIGHT "Keys backlight"
|
||||
#define TR_BLCOLOR "Color"
|
||||
#define TR_ONE_LOG_PER_DAY "One log per day"
|
||||
#define TR_KEY_LOCK_FMT "Key lock (%s+%s hold)"
|
||||
#define TR_KEYS_LOCKED "Keys locked"
|
||||
#define TR_KEYS_LOCKED_FMT "Keys locked (%s+%s)"
|
||||
#define TR_KEYS_UNLOCKED "Keys unlocked"
|
||||
#define TR_SPLASHSCREEN "Splash screen"
|
||||
#define TR_PLAY_HELLO "Startup Sound"
|
||||
#define TR_PWR_ON_DELAY "Pwr On delay"
|
||||
|
||||
@@ -574,6 +574,10 @@
|
||||
#define TR_KEYS_BACKLIGHT "Rétroéclairage touches"
|
||||
#define TR_BLCOLOR "Couleur"
|
||||
#define TR_ONE_LOG_PER_DAY "Un log par jour"
|
||||
#define TR_KEY_LOCK_FMT "Key lock (%s+%s hold)"
|
||||
#define TR_KEYS_LOCKED "Keys locked"
|
||||
#define TR_KEYS_LOCKED_FMT "Keys locked (%s+%s)"
|
||||
#define TR_KEYS_UNLOCKED "Keys unlocked"
|
||||
#define TR_SPLASHSCREEN "Écran d'accueil"
|
||||
#define TR_PLAY_HELLO "Son de démarrage"
|
||||
#define TR_PWR_ON_DELAY "Délai btn ON"
|
||||
|
||||
@@ -574,6 +574,10 @@
|
||||
#define TR_KEYS_BACKLIGHT "תאורת לחצנים"
|
||||
#define TR_BLCOLOR "צבע"
|
||||
#define TR_ONE_LOG_PER_DAY "One log per day"
|
||||
#define TR_KEY_LOCK_FMT "Key lock (%s+%s hold)"
|
||||
#define TR_KEYS_LOCKED "Keys locked"
|
||||
#define TR_KEYS_LOCKED_FMT "Keys locked (%s+%s)"
|
||||
#define TR_KEYS_UNLOCKED "Keys unlocked"
|
||||
#define TR_SPLASHSCREEN "מסך פתיחה"
|
||||
#define TR_PLAY_HELLO "צליל אתחול"
|
||||
#define TR_PWR_ON_DELAY "השהיית הפעלה פעיל"
|
||||
|
||||
@@ -571,6 +571,10 @@
|
||||
#define TR_KEYS_BACKLIGHT "Luce tasti"
|
||||
#define TR_BLCOLOR "Colore"
|
||||
#define TR_ONE_LOG_PER_DAY "Un log al giorno"
|
||||
#define TR_KEY_LOCK_FMT "Key lock (%s+%s hold)"
|
||||
#define TR_KEYS_LOCKED "Keys locked"
|
||||
#define TR_KEYS_LOCKED_FMT "Keys locked (%s+%s)"
|
||||
#define TR_KEYS_UNLOCKED "Keys unlocked"
|
||||
#define TR_SPLASHSCREEN TR("Sch. avvio", "Schermata d'avvio")
|
||||
#define TR_PLAY_HELLO "Suono all'accensione"
|
||||
#define TR_PWR_ON_DELAY "Rit. accens."
|
||||
|
||||
@@ -570,6 +570,10 @@
|
||||
#define TR_KEYS_BACKLIGHT "キー バックライト"
|
||||
#define TR_BLCOLOR "カラー"
|
||||
#define TR_ONE_LOG_PER_DAY "One log per day"
|
||||
#define TR_KEY_LOCK_FMT "Key lock (%s+%s hold)"
|
||||
#define TR_KEYS_LOCKED "Keys locked"
|
||||
#define TR_KEYS_LOCKED_FMT "Keys locked (%s+%s)"
|
||||
#define TR_KEYS_UNLOCKED "Keys unlocked"
|
||||
#define TR_SPLASHSCREEN "起動イメージ"
|
||||
#define TR_PLAY_HELLO "起動時サウンド"
|
||||
#define TR_PWR_ON_DELAY "電源ON遅延"
|
||||
|
||||
@@ -580,6 +580,10 @@
|
||||
#define TR_KEYS_BACKLIGHT "키 백라이트"
|
||||
#define TR_BLCOLOR "색상"
|
||||
#define TR_ONE_LOG_PER_DAY "One log per day"
|
||||
#define TR_KEY_LOCK_FMT "Key lock (%s+%s hold)"
|
||||
#define TR_KEYS_LOCKED "Keys locked"
|
||||
#define TR_KEYS_LOCKED_FMT "Keys locked (%s+%s)"
|
||||
#define TR_KEYS_UNLOCKED "Keys unlocked"
|
||||
#define TR_SPLASHSCREEN "시작화면"
|
||||
#define TR_PLAY_HELLO "시작 사운드"
|
||||
|
||||
|
||||
@@ -572,6 +572,10 @@
|
||||
#define TR_KEYS_BACKLIGHT "Keys backlight"
|
||||
#define TR_BLCOLOR "Kleur"
|
||||
#define TR_ONE_LOG_PER_DAY "One log per day"
|
||||
#define TR_KEY_LOCK_FMT "Key lock (%s+%s hold)"
|
||||
#define TR_KEYS_LOCKED "Keys locked"
|
||||
#define TR_KEYS_LOCKED_FMT "Keys locked (%s+%s)"
|
||||
#define TR_KEYS_UNLOCKED "Keys unlocked"
|
||||
#define TR_SPLASHSCREEN "Startscherm Aan"
|
||||
#define TR_PLAY_HELLO "Startup Sound"
|
||||
#define TR_PWR_ON_DELAY "Pwr On delay"
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user