From a55eac5c202fe95015add932c8dadc26e37ec9c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Tue, 22 Aug 2023 10:58:54 +0200 Subject: [PATCH 01/11] silence compiler warnings --- src/input/BBQ10Keyboard.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/input/BBQ10Keyboard.cpp b/src/input/BBQ10Keyboard.cpp index f0459d8f7..fa663d9b9 100644 --- a/src/input/BBQ10Keyboard.cpp +++ b/src/input/BBQ10Keyboard.cpp @@ -33,7 +33,7 @@ #define KEY_NUMLOCK (1 << 6) #define KEY_COUNT_MASK (0x1F) -BBQ10Keyboard::BBQ10Keyboard() : m_wire(nullptr), m_addr(NULL), writeCallback(nullptr), readCallback(nullptr) {} +BBQ10Keyboard::BBQ10Keyboard() : m_wire(nullptr), m_addr(0), readCallback(nullptr), writeCallback(nullptr) {} void BBQ10Keyboard::begin(uint8_t addr, TwoWire *wire) { From 0fcaaf39b0ad3ce6d9a46ecd79726f56c9c84bde Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Tue, 22 Aug 2023 11:23:19 +0200 Subject: [PATCH 02/11] Try manual scancode for SYM --- src/input/BBQ10Keyboard.cpp | 4 +++ src/input/BBQ10Keyboard.h | 5 ++++ src/input/kbI2cBase.cpp | 51 ++++++++++++++++++++++++++++--------- src/input/kbI2cBase.h | 1 + 4 files changed, 49 insertions(+), 12 deletions(-) diff --git a/src/input/BBQ10Keyboard.cpp b/src/input/BBQ10Keyboard.cpp index fa663d9b9..8f8399aef 100644 --- a/src/input/BBQ10Keyboard.cpp +++ b/src/input/BBQ10Keyboard.cpp @@ -22,6 +22,8 @@ #define CFG_NUMLOCK_INT (1 << 3) #define CFG_KEY_INT (1 << 4) #define CFG_PANIC_INT (1 << 5) +#define CFG_REPORT_MODS (1 << 6) +#define CFG_USE_MODS (1 << 7) #define INT_OVERFLOW (1 << 0) #define INT_CAPSLOCK (1 << 1) @@ -66,6 +68,8 @@ void BBQ10Keyboard::reset() writeCallback(m_addr, _REG_RST, &data, 0); } delay(100); + writeRegister(_REG_CFG, readRegister8(_REG_CFG) | CFG_REPORT_MODS); + delay(100); } void BBQ10Keyboard::attachInterrupt(uint8_t pin, void (*func)(void)) const diff --git a/src/input/BBQ10Keyboard.h b/src/input/BBQ10Keyboard.h index da6de71d7..07d02308f 100644 --- a/src/input/BBQ10Keyboard.h +++ b/src/input/BBQ10Keyboard.h @@ -3,6 +3,11 @@ #include "configuration.h" #include +#define KEY_MOD_ALT (0x1A) +#define KEY_MOD_SHL (0x1B) +#define KEY_MOD_SHR (0x1C) +#define KEY_MOD_SYM (0x1D) + class BBQ10Keyboard { public: diff --git a/src/input/kbI2cBase.cpp b/src/input/kbI2cBase.cpp index 3289a665c..56d065070 100644 --- a/src/input/kbI2cBase.cpp +++ b/src/input/kbI2cBase.cpp @@ -78,21 +78,48 @@ int32_t KbI2cBase::runOnce() e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_BACK; e.kbchar = key.key; break; - case 0x12: // sym shift+2 - e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_UP; - e.kbchar = 0xb5; + case 'e': // sym e + case '2': // sym shift+2 + if (is_sym) { + e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_UP; + e.kbchar = 0xb5; + } else { + e.inputEvent = ANYKEY; + e.kbchar = key.key; + } break; - case 0x18: // sym shift+8 - e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_DOWN; - e.kbchar = 0xb6; + case 'x': // sym x + case '8': // sym shift+8 + if (is_sym) { + e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_DOWN; + e.kbchar = 0xb6; + } else { + e.inputEvent = ANYKEY; + e.kbchar = key.key; + } break; - case 0x14: // Left (sym shift+4) - e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT; - e.kbchar = 0x00; // tweak for destSelect + case 's': // sym s + case '4': // Left (sym shift+4) + if (is_sym) { + e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT; + e.kbchar = 0x00; // tweak for destSelect + } else { + e.inputEvent = ANYKEY; + e.kbchar = key.key; + } break; - case 0x16: // Right (sym shift+6) - e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT; - e.kbchar = 0x00; // tweak for destSelect + case 'f': // sym f + case '6': // Right (sym shift+6) + if (is_sym) { + e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT; + e.kbchar = 0x00; // tweak for destSelect + } else { + e.inputEvent = ANYKEY; + e.kbchar = key.key; + } + break; + case KEY_MOD_SYM: // toggle SYM Key + is_sym = !is_sym; break; case 0x0d: // Enter case 0x0a: // apparently Enter on Q10 is a line feed instead of carriage return diff --git a/src/input/kbI2cBase.h b/src/input/kbI2cBase.h index 59c26e16d..35b9b0901 100644 --- a/src/input/kbI2cBase.h +++ b/src/input/kbI2cBase.h @@ -19,4 +19,5 @@ class KbI2cBase : public Observable, public concurrency::OST TwoWire *i2cBus = 0; BBQ10Keyboard Q10keyboard; + bool is_sym = false; }; From 8cfe130df3e62128458e7036bd9f1b841ac7717f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Tue, 22 Aug 2023 21:11:19 +0200 Subject: [PATCH 03/11] update SYM Scancode --- src/input/kbI2cBase.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/input/kbI2cBase.cpp b/src/input/kbI2cBase.cpp index 56d065070..2e8d04933 100644 --- a/src/input/kbI2cBase.cpp +++ b/src/input/kbI2cBase.cpp @@ -119,6 +119,7 @@ int32_t KbI2cBase::runOnce() } break; case KEY_MOD_SYM: // toggle SYM Key + case 0x13: // Code scanner says the SYM key ias 0x13 is_sym = !is_sym; break; case 0x0d: // Enter From 5c7c1cd25337d3e5d2f5f57790015632b281d279 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Tue, 22 Aug 2023 10:58:54 +0200 Subject: [PATCH 04/11] silence compiler warnings --- src/input/BBQ10Keyboard.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/input/BBQ10Keyboard.cpp b/src/input/BBQ10Keyboard.cpp index f0459d8f7..fa663d9b9 100644 --- a/src/input/BBQ10Keyboard.cpp +++ b/src/input/BBQ10Keyboard.cpp @@ -33,7 +33,7 @@ #define KEY_NUMLOCK (1 << 6) #define KEY_COUNT_MASK (0x1F) -BBQ10Keyboard::BBQ10Keyboard() : m_wire(nullptr), m_addr(NULL), writeCallback(nullptr), readCallback(nullptr) {} +BBQ10Keyboard::BBQ10Keyboard() : m_wire(nullptr), m_addr(0), readCallback(nullptr), writeCallback(nullptr) {} void BBQ10Keyboard::begin(uint8_t addr, TwoWire *wire) { From 7b1aeb60cd68f04f0ff82966acc729aef082acbe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Tue, 22 Aug 2023 11:23:19 +0200 Subject: [PATCH 05/11] Try manual scancode for SYM --- src/input/BBQ10Keyboard.cpp | 4 +++ src/input/BBQ10Keyboard.h | 5 ++++ src/input/kbI2cBase.cpp | 51 ++++++++++++++++++++++++++++--------- src/input/kbI2cBase.h | 1 + 4 files changed, 49 insertions(+), 12 deletions(-) diff --git a/src/input/BBQ10Keyboard.cpp b/src/input/BBQ10Keyboard.cpp index fa663d9b9..8f8399aef 100644 --- a/src/input/BBQ10Keyboard.cpp +++ b/src/input/BBQ10Keyboard.cpp @@ -22,6 +22,8 @@ #define CFG_NUMLOCK_INT (1 << 3) #define CFG_KEY_INT (1 << 4) #define CFG_PANIC_INT (1 << 5) +#define CFG_REPORT_MODS (1 << 6) +#define CFG_USE_MODS (1 << 7) #define INT_OVERFLOW (1 << 0) #define INT_CAPSLOCK (1 << 1) @@ -66,6 +68,8 @@ void BBQ10Keyboard::reset() writeCallback(m_addr, _REG_RST, &data, 0); } delay(100); + writeRegister(_REG_CFG, readRegister8(_REG_CFG) | CFG_REPORT_MODS); + delay(100); } void BBQ10Keyboard::attachInterrupt(uint8_t pin, void (*func)(void)) const diff --git a/src/input/BBQ10Keyboard.h b/src/input/BBQ10Keyboard.h index da6de71d7..07d02308f 100644 --- a/src/input/BBQ10Keyboard.h +++ b/src/input/BBQ10Keyboard.h @@ -3,6 +3,11 @@ #include "configuration.h" #include +#define KEY_MOD_ALT (0x1A) +#define KEY_MOD_SHL (0x1B) +#define KEY_MOD_SHR (0x1C) +#define KEY_MOD_SYM (0x1D) + class BBQ10Keyboard { public: diff --git a/src/input/kbI2cBase.cpp b/src/input/kbI2cBase.cpp index 3289a665c..56d065070 100644 --- a/src/input/kbI2cBase.cpp +++ b/src/input/kbI2cBase.cpp @@ -78,21 +78,48 @@ int32_t KbI2cBase::runOnce() e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_BACK; e.kbchar = key.key; break; - case 0x12: // sym shift+2 - e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_UP; - e.kbchar = 0xb5; + case 'e': // sym e + case '2': // sym shift+2 + if (is_sym) { + e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_UP; + e.kbchar = 0xb5; + } else { + e.inputEvent = ANYKEY; + e.kbchar = key.key; + } break; - case 0x18: // sym shift+8 - e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_DOWN; - e.kbchar = 0xb6; + case 'x': // sym x + case '8': // sym shift+8 + if (is_sym) { + e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_DOWN; + e.kbchar = 0xb6; + } else { + e.inputEvent = ANYKEY; + e.kbchar = key.key; + } break; - case 0x14: // Left (sym shift+4) - e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT; - e.kbchar = 0x00; // tweak for destSelect + case 's': // sym s + case '4': // Left (sym shift+4) + if (is_sym) { + e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT; + e.kbchar = 0x00; // tweak for destSelect + } else { + e.inputEvent = ANYKEY; + e.kbchar = key.key; + } break; - case 0x16: // Right (sym shift+6) - e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT; - e.kbchar = 0x00; // tweak for destSelect + case 'f': // sym f + case '6': // Right (sym shift+6) + if (is_sym) { + e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT; + e.kbchar = 0x00; // tweak for destSelect + } else { + e.inputEvent = ANYKEY; + e.kbchar = key.key; + } + break; + case KEY_MOD_SYM: // toggle SYM Key + is_sym = !is_sym; break; case 0x0d: // Enter case 0x0a: // apparently Enter on Q10 is a line feed instead of carriage return diff --git a/src/input/kbI2cBase.h b/src/input/kbI2cBase.h index 59c26e16d..35b9b0901 100644 --- a/src/input/kbI2cBase.h +++ b/src/input/kbI2cBase.h @@ -19,4 +19,5 @@ class KbI2cBase : public Observable, public concurrency::OST TwoWire *i2cBus = 0; BBQ10Keyboard Q10keyboard; + bool is_sym = false; }; From d6b629ae04694de4203487220c89df0688909d46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Tue, 22 Aug 2023 21:11:19 +0200 Subject: [PATCH 06/11] update SYM Scancode --- src/input/kbI2cBase.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/input/kbI2cBase.cpp b/src/input/kbI2cBase.cpp index 56d065070..2e8d04933 100644 --- a/src/input/kbI2cBase.cpp +++ b/src/input/kbI2cBase.cpp @@ -119,6 +119,7 @@ int32_t KbI2cBase::runOnce() } break; case KEY_MOD_SYM: // toggle SYM Key + case 0x13: // Code scanner says the SYM key ias 0x13 is_sym = !is_sym; break; case 0x0d: // Enter From 7f1b58a222d79e86d2415cbb33d95e28937e625f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Tue, 22 Aug 2023 21:23:37 +0200 Subject: [PATCH 07/11] trunk fmt --- src/input/kbI2cBase.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/input/kbI2cBase.cpp b/src/input/kbI2cBase.cpp index 2e8d04933..fd7bee074 100644 --- a/src/input/kbI2cBase.cpp +++ b/src/input/kbI2cBase.cpp @@ -119,7 +119,7 @@ int32_t KbI2cBase::runOnce() } break; case KEY_MOD_SYM: // toggle SYM Key - case 0x13: // Code scanner says the SYM key ias 0x13 + case 0x13: // Code scanner says the SYM key ias 0x13 is_sym = !is_sym; break; case 0x0d: // Enter From 5bb207d88be146aa1778ebcabe254968a30f6b9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Wed, 23 Aug 2023 09:44:20 +0200 Subject: [PATCH 08/11] reset sym after second keypress also remove debug print and non-working scancodes. --- src/input/kbI2cBase.cpp | 18 +++++++++++------- src/modules/CannedMessageModule.cpp | 4 ++-- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/src/input/kbI2cBase.cpp b/src/input/kbI2cBase.cpp index fd7bee074..106eed3a2 100644 --- a/src/input/kbI2cBase.cpp +++ b/src/input/kbI2cBase.cpp @@ -79,50 +79,53 @@ int32_t KbI2cBase::runOnce() e.kbchar = key.key; break; case 'e': // sym e - case '2': // sym shift+2 + if (is_sym) { e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_UP; e.kbchar = 0xb5; + is_sym = false; // reset sym state after second keypress } else { e.inputEvent = ANYKEY; e.kbchar = key.key; } break; case 'x': // sym x - case '8': // sym shift+8 + if (is_sym) { e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_DOWN; e.kbchar = 0xb6; + is_sym = false; // reset sym state after second keypress } else { e.inputEvent = ANYKEY; e.kbchar = key.key; } break; case 's': // sym s - case '4': // Left (sym shift+4) + if (is_sym) { e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT; e.kbchar = 0x00; // tweak for destSelect + is_sym = false; // reset sym state after second keypress } else { e.inputEvent = ANYKEY; e.kbchar = key.key; } break; case 'f': // sym f - case '6': // Right (sym shift+6) + if (is_sym) { e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT; e.kbchar = 0x00; // tweak for destSelect + is_sym = false; // reset sym state after second keypress } else { e.inputEvent = ANYKEY; e.kbchar = key.key; } break; - case KEY_MOD_SYM: // toggle SYM Key - case 0x13: // Code scanner says the SYM key ias 0x13 + + case 0x13: // Code scanner says the SYM key is 0x13 is_sym = !is_sym; break; - case 0x0d: // Enter case 0x0a: // apparently Enter on Q10 is a line feed instead of carriage return e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_SELECT; break; @@ -132,6 +135,7 @@ int32_t KbI2cBase::runOnce() default: // all other keys e.inputEvent = ANYKEY; e.kbchar = key.key; + is_sym = false; // reset sym state after second keypress break; } diff --git a/src/modules/CannedMessageModule.cpp b/src/modules/CannedMessageModule.cpp index 8f59848d8..ade9d0e5a 100644 --- a/src/modules/CannedMessageModule.cpp +++ b/src/modules/CannedMessageModule.cpp @@ -171,7 +171,7 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event) (event->inputEvent == static_cast(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT)) || (event->inputEvent == static_cast(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT))) { // LOG_DEBUG("Canned message event (%x)\n", event->kbchar); - // tweak for left/right events generated via trackball/touch with empty kbchar + // tweak for left/right events generated via trackball/touch with empty kbchar if (!event->kbchar) { if (event->inputEvent == static_cast(meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT)) { this->payload = 0xb4; @@ -195,7 +195,7 @@ int CannedMessageModule::handleInputEvent(const InputEvent *event) this->runState = CANNED_MESSAGE_RUN_STATE_FREETEXT; } // pass the pressed key - LOG_DEBUG("Canned message ANYKEY (%x)\n", event->kbchar); + // LOG_DEBUG("Canned message ANYKEY (%x)\n", event->kbchar); this->payload = event->kbchar; this->lastTouchMillis = millis(); validEvent = true; From 2a1d8c40b4eb29f61a81f7ac8585180847ec3218 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Thu, 24 Aug 2023 14:24:26 +0200 Subject: [PATCH 09/11] add TAB and ESC handling --- src/input/kbI2cBase.cpp | 25 ++++++++++++++++++------- 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/src/input/kbI2cBase.cpp b/src/input/kbI2cBase.cpp index 106eed3a2..cb94bed51 100644 --- a/src/input/kbI2cBase.cpp +++ b/src/input/kbI2cBase.cpp @@ -71,15 +71,30 @@ int32_t KbI2cBase::runOnce() e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_NONE; e.source = this->_originName; switch (key.key) { - case 0x1b: // ESC - e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_CANCEL; + case 'p': // TAB + if (is_sym) { + e.kbchar = 0x09; // TAB Scancode + is_sym = false; // reset sym state after second keypress + } else { + e.inputEvent = ANYKEY; + e.kbchar = key.key; + } + break; + case 'q': // ESC + if (is_sym) { + e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_CANCEL; + e.kbchar = 0x1b; + is_sym = false; // reset sym state after second keypress + } else { + e.inputEvent = ANYKEY; + e.kbchar = key.key; + } break; case 0x08: // Back e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_BACK; e.kbchar = key.key; break; case 'e': // sym e - if (is_sym) { e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_UP; e.kbchar = 0xb5; @@ -90,7 +105,6 @@ int32_t KbI2cBase::runOnce() } break; case 'x': // sym x - if (is_sym) { e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_DOWN; e.kbchar = 0xb6; @@ -101,7 +115,6 @@ int32_t KbI2cBase::runOnce() } break; case 's': // sym s - if (is_sym) { e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_LEFT; e.kbchar = 0x00; // tweak for destSelect @@ -112,7 +125,6 @@ int32_t KbI2cBase::runOnce() } break; case 'f': // sym f - if (is_sym) { e.inputEvent = meshtastic_ModuleConfig_CannedMessageConfig_InputEventChar_RIGHT; e.kbchar = 0x00; // tweak for destSelect @@ -122,7 +134,6 @@ int32_t KbI2cBase::runOnce() e.kbchar = key.key; } break; - case 0x13: // Code scanner says the SYM key is 0x13 is_sym = !is_sym; break; From 312028b16136acfd4d85448e7cfee2625aaa1479 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Fri, 25 Aug 2023 09:27:09 +0200 Subject: [PATCH 10/11] Possble fix ESC --- src/input/kbI2cBase.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/input/kbI2cBase.cpp b/src/input/kbI2cBase.cpp index cb94bed51..5cc829bac 100644 --- a/src/input/kbI2cBase.cpp +++ b/src/input/kbI2cBase.cpp @@ -73,6 +73,7 @@ int32_t KbI2cBase::runOnce() switch (key.key) { case 'p': // TAB if (is_sym) { + e.inputEvent = ANYKEY; e.kbchar = 0x09; // TAB Scancode is_sym = false; // reset sym state after second keypress } else { From 4ab67f36684d3275f2efbe4ca5b1c0efff3e9429 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Fri, 25 Aug 2023 16:44:39 +0200 Subject: [PATCH 11/11] IGOR! Fetch me the brain! --- src/input/kbI2cBase.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/input/kbI2cBase.cpp b/src/input/kbI2cBase.cpp index 5cc829bac..366e7fbb1 100644 --- a/src/input/kbI2cBase.cpp +++ b/src/input/kbI2cBase.cpp @@ -72,6 +72,7 @@ int32_t KbI2cBase::runOnce() e.source = this->_originName; switch (key.key) { case 'p': // TAB + case 't': // TAB as well if (is_sym) { e.inputEvent = ANYKEY; e.kbchar = 0x09; // TAB Scancode