From 4ae75259233a45583b6a0d73f1f7224cb50e0398 Mon Sep 17 00:00:00 2001 From: Felix Kuehling <67731127+fxkuehl@users.noreply.github.com> Date: Mon, 28 Nov 2022 03:16:38 -0500 Subject: Bug17281 - Retain momentary layers until the end of tapping (#17282) * Make process_tapping more readable Move most #ifdefs into conditionally defined macros to make the logic easier to follow. * Retain momentary layers until the end of tapping This allows mod-tap and layer-tap keys on layers to behave as expected. Bug: https://github.com/qmk/qmk_firmware/issues/17281 * Add tests for delayed mod/layer release while tapping Mods and layer key release is delayed while tapping is in progress to ensure that the tap is registered with the modifier state and on the layer where the key was first pressed. Signed-off-by: Felix Kuehling --- quantum/action_tapping.c | 161 ++++++++++++++++++++++++----------------------- 1 file changed, 84 insertions(+), 77 deletions(-) (limited to 'quantum') diff --git a/quantum/action_tapping.c b/quantum/action_tapping.c index df3317ac05..b5386a5e17 100644 --- a/quantum/action_tapping.c +++ b/quantum/action_tapping.c @@ -117,6 +117,66 @@ void action_tapping_process(keyrecord_t record) { } } +/* Some conditionally defined helper macros to keep process_tapping more + * readable. The conditional definition of tapping_keycode and all the + * conditional uses of it are hidden inside macros named TAP_... + */ +# if (defined(AUTO_SHIFT_ENABLE) && defined(RETRO_SHIFT)) || defined(PERMISSIVE_HOLD_PER_KEY) || defined(TAPPING_FORCE_HOLD_PER_KEY) || defined(HOLD_ON_OTHER_KEY_PRESS_PER_KEY) +# define TAP_DEFINE_KEYCODE uint16_t tapping_keycode = get_record_keycode(&tapping_key, false) +# else +# define TAP_DEFINE_KEYCODE +# endif + +# if defined(AUTO_SHIFT_ENABLE) && defined(RETRO_SHIFT) +# ifdef RETRO_TAPPING_PER_KEY +# define TAP_GET_RETRO_TAPPING get_retro_tapping(tapping_keycode, &tapping_key) +# else +# define TAP_GET_RETRO_TAPPING true +# endif +# define MAYBE_RETRO_SHIFTING(ev) (TAP_GET_RETRO_TAPPING && (RETRO_SHIFT + 0) != 0 && TIMER_DIFF_16((ev).time, tapping_key.event.time) < (RETRO_SHIFT + 0)) +# define TAP_IS_LT IS_LT(tapping_keycode) +# define TAP_IS_MT IS_MT(tapping_keycode) +# define TAP_IS_RETRO IS_RETRO(tapping_keycode) +# else +# define TAP_GET_RETRO_TAPPING false +# define MAYBE_RETRO_SHIFTING(ev) false +# define TAP_IS_LT false +# define TAP_IS_MT false +# define TAP_IS_RETRO false +# endif + +# ifdef PERMISSIVE_HOLD_PER_KEY +# define TAP_GET_PERMISSIVE_HOLD get_permissive_hold(tapping_keycode, &tapping_key) +# elif defined(PERMISSIVE_HOLD) +# define TAP_GET_PERMISSIVE_HOLD true +# else +# define TAP_GET_PERMISSIVE_HOLD false +# endif + +# ifdef HOLD_ON_OTHER_KEY_PRESS_PER_KEY +# define TAP_GET_HOLD_ON_OTHER_KEY_PRESS get_hold_on_other_key_press(tapping_keycode, &tapping_key) +# elif defined(HOLD_ON_OTHER_KEY_PRESS) +# define TAP_GET_HOLD_ON_OTHER_KEY_PRESS true +# else +# define TAP_GET_HOLD_ON_OTHER_KEY_PRESS false +# endif + +# ifdef IGNORE_MOD_TAP_INTERRUPT_PER_KEY +# define TAP_GET_IGNORE_MOD_TAP_INTERRUPT get_ignore_mod_tap_interrupt(tapping_keycode, &tapping_key) +# elif defined(IGNORE_MOD_TAP_INTERRUPT) +# define TAP_GET_IGNORE_MOD_TAP_INTERRUPT true +# else +# define TAP_GET_IGNORE_MOD_TAP_INTERRUPT false +# endif + +# ifdef TAPPING_FORCE_HOLD_PER_KEY +# define TAP_GET_TAPPING_FORCE_HOLD get_tapping_force_hold(tapping_keycode, &tapping_key) +# elif defined(TAPPING_FORCE_HOLD) +# define TAP_GET_TAPPING_FORCE_HOLD true +# else +# define TAP_GET_TAPPING_FORCE_HOLD false +# endif + /** \brief Tapping * * Rule: Tap key is typed(pressed and released) within TAPPING_TERM. @@ -125,24 +185,11 @@ void action_tapping_process(keyrecord_t record) { /* return true when key event is processed or consumed. */ bool process_tapping(keyrecord_t *keyp) { keyevent_t event = keyp->event; -# if (defined(AUTO_SHIFT_ENABLE) && defined(RETRO_SHIFT)) || defined(PERMISSIVE_HOLD_PER_KEY) || defined(TAPPING_FORCE_HOLD_PER_KEY) || defined(HOLD_ON_OTHER_KEY_PRESS_PER_KEY) - uint16_t tapping_keycode = get_record_keycode(&tapping_key, false); -# endif + TAP_DEFINE_KEYCODE; // if tapping if (IS_TAPPING_PRESSED()) { - // clang-format off - if (WITHIN_TAPPING_TERM(event) -# if defined(AUTO_SHIFT_ENABLE) && defined(RETRO_SHIFT) - || ( -# ifdef RETRO_TAPPING_PER_KEY - get_retro_tapping(tapping_keycode, &tapping_key) && -# endif - (RETRO_SHIFT + 0) != 0 && TIMER_DIFF_16(event.time, tapping_key.event.time) < (RETRO_SHIFT + 0) - ) -# endif - ) { - // clang-format on + if (WITHIN_TAPPING_TERM(event) || MAYBE_RETRO_SHIFTING(event)) { if (tapping_key.tap.count == 0) { if (IS_TAPPING_RECORD(keyp) && !event.pressed) { # if defined(AUTO_SHIFT_ENABLE) && defined(RETRO_SHIFT) @@ -164,57 +211,31 @@ bool process_tapping(keyrecord_t *keyp) { * useful for long TAPPING_TERM but may prevent fast typing. */ // clang-format off -# if defined(PERMISSIVE_HOLD) || defined(PERMISSIVE_HOLD_PER_KEY) || (defined(AUTO_SHIFT_ENABLE) && defined(RETRO_SHIFT)) else if ( ( - IS_RELEASED(event) && waiting_buffer_typed(event) -# ifdef PERMISSIVE_HOLD_PER_KEY - && get_permissive_hold(tapping_keycode, &tapping_key) -# elif defined(PERMISSIVE_HOLD) - && true -# endif + IS_RELEASED(event) && waiting_buffer_typed(event) && + TAP_GET_PERMISSIVE_HOLD ) // Causes nested taps to not wait past TAPPING_TERM/RETRO_SHIFT // unnecessarily and fixes them for Layer Taps. -# if defined(AUTO_SHIFT_ENABLE) && defined(RETRO_SHIFT) - || ( -# ifdef RETRO_TAPPING_PER_KEY - get_retro_tapping(tapping_keycode, &tapping_key) && -# endif + || (TAP_GET_RETRO_TAPPING && ( // Rolled over the two keys. - ( - ( - false -# if defined(HOLD_ON_OTHER_KEY_PRESS) || defined(HOLD_ON_OTHER_KEY_PRESS_PER_KEY) - || ( - IS_LT(tapping_keycode) -# ifdef HOLD_ON_OTHER_KEY_PRESS_PER_KEY - && get_hold_on_other_key_press(tapping_keycode, &tapping_key) -# endif - ) -# endif -# if !defined(IGNORE_MOD_TAP_INTERRUPT) || defined(IGNORE_MOD_TAP_INTERRUPT_PER_KEY) - || ( - IS_MT(tapping_keycode) -# ifdef IGNORE_MOD_TAP_INTERRUPT_PER_KEY - && !get_ignore_mod_tap_interrupt(tapping_keycode, &tapping_key) -# endif - ) -# endif - ) && tapping_key.tap.interrupted == true + (tapping_key.tap.interrupted == true && ( + (TAP_IS_LT && TAP_GET_HOLD_ON_OTHER_KEY_PRESS) || + (TAP_IS_MT && !TAP_GET_IGNORE_MOD_TAP_INTERRUPT) + ) ) // Makes Retro Shift ignore [IGNORE_MOD_TAP_INTERRUPT's // effects on nested taps for MTs and the default // behavior of LTs] below TAPPING_TERM or RETRO_SHIFT. || ( - IS_RETRO(tapping_keycode) + TAP_IS_RETRO && (event.key.col != tapping_key.event.key.col || event.key.row != tapping_key.event.key.row) && IS_RELEASED(event) && waiting_buffer_typed(event) ) ) ) -# endif ) { // clang-format on debug("Tapping: End. No tap. Interfered by typing key\n"); @@ -224,13 +245,12 @@ bool process_tapping(keyrecord_t *keyp) { // enqueue return false; } -# endif /* Process release event of a key pressed before tapping starts * Without this unexpected repeating will occur with having fast repeating setting * https://github.com/tmk/tmk_keyboard/issues/60 */ else if (IS_RELEASED(event) && !waiting_buffer_typed(event)) { - // Modifier should be retained till end of this tapping. + // Modifier/Layer should be retained till end of this tapping. action_t action = layer_switch_get_action(event.key); switch (action.kind.id) { case ACT_LMODS: @@ -243,6 +263,16 @@ bool process_tapping(keyrecord_t *keyp) { if (action.key.mods && keyp->tap.count == 0) return false; if (IS_MOD(action.key.code)) return false; break; + case ACT_LAYER_TAP: + case ACT_LAYER_TAP_EXT: + switch (action.layer_tap.code) { + case 0 ...(OP_TAP_TOGGLE - 1): + case OP_ON_OFF: + case OP_OFF_ON: + case OP_SET_CLEAR: + return false; + } + break; } // Release of key should be process immediately. debug("Tapping: release event of a key pressed before tapping\n"); @@ -252,11 +282,7 @@ bool process_tapping(keyrecord_t *keyp) { // set interrupted flag when other key preesed during tapping if (event.pressed) { tapping_key.tap.interrupted = true; -# if defined(HOLD_ON_OTHER_KEY_PRESS) || defined(HOLD_ON_OTHER_KEY_PRESS_PER_KEY) -# if defined(HOLD_ON_OTHER_KEY_PRESS_PER_KEY) - if (get_hold_on_other_key_press(tapping_keycode, &tapping_key)) -# endif - { + if (TAP_GET_HOLD_ON_OTHER_KEY_PRESS) { debug("Tapping: End. No tap. Interfered by pressed key\n"); process_record(&tapping_key); tapping_key = (keyrecord_t){}; @@ -264,7 +290,6 @@ bool process_tapping(keyrecord_t *keyp) { // enqueue return false; } -# endif } // enqueue return false; @@ -357,27 +382,10 @@ bool process_tapping(keyrecord_t *keyp) { } } } else if (IS_TAPPING_RELEASED()) { - // clang-format off - if (WITHIN_TAPPING_TERM(event) -# if defined(AUTO_SHIFT_ENABLE) && defined(RETRO_SHIFT) - || ( -# ifdef RETRO_TAPPING_PER_KEY - get_retro_tapping(tapping_keycode, &tapping_key) && -# endif - (RETRO_SHIFT + 0) != 0 && TIMER_DIFF_16(event.time, tapping_key.event.time) < (RETRO_SHIFT + 0) - ) -# endif - ) { - // clang-format on + if (WITHIN_TAPPING_TERM(event) || MAYBE_RETRO_SHIFTING(event)) { if (event.pressed) { if (IS_TAPPING_RECORD(keyp)) { -//# ifndef TAPPING_FORCE_HOLD -# if !defined(TAPPING_FORCE_HOLD) || defined(TAPPING_FORCE_HOLD_PER_KEY) - if ( -# ifdef TAPPING_FORCE_HOLD_PER_KEY - !get_tapping_force_hold(tapping_keycode, &tapping_key) && -# endif - !tapping_key.tap.interrupted && tapping_key.tap.count > 0) { + if (!TAP_GET_TAPPING_FORCE_HOLD && !tapping_key.tap.interrupted && tapping_key.tap.count > 0) { // sequential tap. keyp->tap = tapping_key.tap; if (keyp->tap.count < 15) keyp->tap.count += 1; @@ -389,7 +397,6 @@ bool process_tapping(keyrecord_t *keyp) { debug_tapping_key(); return true; } -# endif // FIX: start new tap again tapping_key = *keyp; return true; -- cgit v1.2.3 From 50661ab65cc04c6400cd20037181dabba1872c86 Mon Sep 17 00:00:00 2001 From: Drashna Jaelre Date: Thu, 1 Dec 2022 13:06:45 -0800 Subject: Remove RGBLIGHT_ANIMATIONS from core (+cleanup) (#19216) --- quantum/rgblight/rgblight.h | 17 ----------------- 1 file changed, 17 deletions(-) (limited to 'quantum') diff --git a/quantum/rgblight/rgblight.h b/quantum/rgblight/rgblight.h index 46e8e07212..7693888462 100644 --- a/quantum/rgblight/rgblight.h +++ b/quantum/rgblight/rgblight.h @@ -68,23 +68,6 @@ |-----------------|-----------------------------------| *****/ -#ifdef RGBLIGHT_ANIMATIONS -// for backward compatibility -# define RGBLIGHT_EFFECT_BREATHING -# define RGBLIGHT_EFFECT_RAINBOW_MOOD -# define RGBLIGHT_EFFECT_RAINBOW_SWIRL -# define RGBLIGHT_EFFECT_SNAKE -# define RGBLIGHT_EFFECT_KNIGHT -# define RGBLIGHT_EFFECT_CHRISTMAS -# define RGBLIGHT_EFFECT_STATIC_GRADIENT -# define RGBLIGHT_EFFECT_RGB_TEST -# define RGBLIGHT_EFFECT_ALTERNATING -#endif - -#ifdef RGBLIGHT_STATIC_PATTERNS -# define RGBLIGHT_EFFECT_STATIC_GRADIENT -#endif - // clang-format off // check dynamic animation effects chose ? -- cgit v1.2.3 From f2a8a13dbad220cfb0dfbd72a90492a15a2e58bb Mon Sep 17 00:00:00 2001 From: dexter93 Date: Thu, 8 Dec 2022 18:09:01 +0200 Subject: Core: Support inverted scan logic for optical switches (#19053) --- quantum/matrix.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'quantum') diff --git a/quantum/matrix.c b/quantum/matrix.c index db683104ed..0de65c6cdd 100644 --- a/quantum/matrix.c +++ b/quantum/matrix.c @@ -46,6 +46,10 @@ along with this program. If not, see . # define SPLIT_MUTABLE_COL const #endif +#ifndef MATRIX_INPUT_PRESSED_STATE +# define MATRIX_INPUT_PRESSED_STATE 0 +#endif + #ifdef DIRECT_PINS static SPLIT_MUTABLE pin_t direct_pins[ROWS_PER_HAND][MATRIX_COLS] = DIRECT_PINS; #elif (DIODE_DIRECTION == ROW2COL) || (DIODE_DIRECTION == COL2ROW) @@ -93,7 +97,7 @@ static inline void setPinInputHigh_atomic(pin_t pin) { static inline uint8_t readMatrixPin(pin_t pin) { if (pin != NO_PIN) { - return readPin(pin); + return (readPin(pin) == MATRIX_INPUT_PRESSED_STATE) ? 0 : 1; } else { return 1; } @@ -121,9 +125,7 @@ __attribute__((weak)) void matrix_read_cols_on_row(matrix_row_t current_matrix[] matrix_row_t row_shifter = MATRIX_ROW_SHIFTER; for (uint8_t col_index = 0; col_index < MATRIX_COLS; col_index++, row_shifter <<= 1) { pin_t pin = direct_pins[current_row][col_index]; - if (pin != NO_PIN) { - current_row_value |= readPin(pin) ? 0 : row_shifter; - } + current_row_value |= readMatrixPin(pin) ? 0 : row_shifter; } // Update the matrix -- cgit v1.2.3 From 85ee55ff3becd29e1590376c3462c6a99c976fa0 Mon Sep 17 00:00:00 2001 From: Ruslan Sayfutdinov Date: Thu, 8 Dec 2022 16:45:30 +0000 Subject: Detect host OS based on USB fingerprint (#18463) Co-authored-by: Drashna Jaelre Co-authored-by: Nick Brassel --- quantum/os_detection.c | 129 ++++++++++++++++++++++ quantum/os_detection.h | 38 +++++++ quantum/os_detection/tests/os_detection.cpp | 164 ++++++++++++++++++++++++++++ quantum/os_detection/tests/rules.mk | 5 + quantum/os_detection/tests/testlist.mk | 1 + 5 files changed, 337 insertions(+) create mode 100644 quantum/os_detection.c create mode 100644 quantum/os_detection.h create mode 100644 quantum/os_detection/tests/os_detection.cpp create mode 100644 quantum/os_detection/tests/rules.mk create mode 100644 quantum/os_detection/tests/testlist.mk (limited to 'quantum') diff --git a/quantum/os_detection.c b/quantum/os_detection.c new file mode 100644 index 0000000000..b1511afb14 --- /dev/null +++ b/quantum/os_detection.c @@ -0,0 +1,129 @@ +/* Copyright 2022 Ruslan Sayfutdinov (@KapJI) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "os_detection.h" + +#include + +#ifdef OS_DETECTION_DEBUG_ENABLE +# include "eeconfig.h" +# include "eeprom.h" +# include "print.h" + +# define STORED_USB_SETUPS 50 +# define EEPROM_USER_OFFSET (uint8_t*)EECONFIG_SIZE + +uint16_t usb_setups[STORED_USB_SETUPS]; +#endif + +#ifdef OS_DETECTION_ENABLE +struct setups_data_t { + uint8_t count; + uint8_t cnt_02; + uint8_t cnt_04; + uint8_t cnt_ff; + uint16_t last_wlength; + os_variant_t detected_os; +}; + +struct setups_data_t setups_data = { + .count = 0, + .cnt_02 = 0, + .cnt_04 = 0, + .cnt_ff = 0, + .detected_os = OS_UNSURE, +}; + +// Some collected sequences of wLength can be found in tests. +void make_guess(void) { + if (setups_data.count < 3) { + return; + } + if (setups_data.cnt_ff >= 2 && setups_data.cnt_04 >= 1) { + setups_data.detected_os = OS_WINDOWS; + return; + } + if (setups_data.count == setups_data.cnt_ff) { + // Linux has 3 packets with 0xFF. + setups_data.detected_os = OS_LINUX; + return; + } + if (setups_data.count == 5 && setups_data.last_wlength == 0xFF && setups_data.cnt_ff == 1 && setups_data.cnt_02 == 2) { + setups_data.detected_os = OS_MACOS; + return; + } + if (setups_data.count == 4 && setups_data.cnt_ff == 0 && setups_data.cnt_02 == 2) { + // iOS and iPadOS don't have the last 0xFF packet. + setups_data.detected_os = OS_IOS; + return; + } + if (setups_data.cnt_ff == 0 && setups_data.cnt_02 == 3 && setups_data.cnt_04 == 1) { + // This is actually PS5. + setups_data.detected_os = OS_LINUX; + return; + } + if (setups_data.cnt_ff >= 1 && setups_data.cnt_02 == 0 && setups_data.cnt_04 == 0) { + // This is actually Quest 2 or Nintendo Switch. + setups_data.detected_os = OS_LINUX; + return; + } +} + +void process_wlength(const uint16_t w_length) { +# ifdef OS_DETECTION_DEBUG_ENABLE + usb_setups[setups_data.count] = w_length; +# endif + setups_data.count++; + setups_data.last_wlength = w_length; + if (w_length == 0x2) { + setups_data.cnt_02++; + } else if (w_length == 0x4) { + setups_data.cnt_04++; + } else if (w_length == 0xFF) { + setups_data.cnt_ff++; + } + make_guess(); +} + +os_variant_t detected_host_os(void) { + return setups_data.detected_os; +} + +void erase_wlength_data(void) { + memset(&setups_data, 0, sizeof(setups_data)); +} +#endif // OS_DETECTION_ENABLE + +#ifdef OS_DETECTION_DEBUG_ENABLE +void print_stored_setups(void) { +# ifdef CONSOLE_ENABLE + uint8_t cnt = eeprom_read_byte(EEPROM_USER_OFFSET); + for (uint16_t i = 0; i < cnt; ++i) { + uint16_t* addr = (uint16_t*)EEPROM_USER_OFFSET + i * sizeof(uint16_t) + sizeof(uint8_t); + xprintf("i: %d, wLength: 0x%02X\n", i, eeprom_read_word(addr)); + } +# endif +} + +void store_setups_in_eeprom(void) { + eeprom_update_byte(EEPROM_USER_OFFSET, setups_data.count); + for (uint16_t i = 0; i < setups_data.count; ++i) { + uint16_t* addr = (uint16_t*)EEPROM_USER_OFFSET + i * sizeof(uint16_t) + sizeof(uint8_t); + eeprom_update_word(addr, usb_setups[i]); + } +} + +#endif // OS_DETECTION_DEBUG_ENABLE diff --git a/quantum/os_detection.h b/quantum/os_detection.h new file mode 100644 index 0000000000..e643dcd27f --- /dev/null +++ b/quantum/os_detection.h @@ -0,0 +1,38 @@ +/* Copyright 2022 Ruslan Sayfutdinov (@KapJI) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#pragma once + +#include + +#ifdef OS_DETECTION_ENABLE +typedef enum { + OS_UNSURE, + OS_LINUX, + OS_WINDOWS, + OS_MACOS, + OS_IOS, +} os_variant_t; + +void process_wlength(const uint16_t w_length); +os_variant_t detected_host_os(void); +void erase_wlength_data(void); +#endif + +#ifdef OS_DETECTION_DEBUG_ENABLE +void print_stored_setups(void); +void store_setups_in_eeprom(void); +#endif diff --git a/quantum/os_detection/tests/os_detection.cpp b/quantum/os_detection/tests/os_detection.cpp new file mode 100644 index 0000000000..102349852e --- /dev/null +++ b/quantum/os_detection/tests/os_detection.cpp @@ -0,0 +1,164 @@ +/* Copyright 2022 Ruslan Sayfutdinov (@KapJI) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "gtest/gtest.h" + +extern "C" { +#include "os_detection.h" +} + +class OsDetectionTest : public ::testing::Test { + protected: + void SetUp() override { + erase_wlength_data(); + } +}; + +os_variant_t check_sequence(const std::vector &w_lengths) { + for (auto &w_length : w_lengths) { + process_wlength(w_length); + } + return detected_host_os(); +} + +/* Some collected data. + +ChibiOS: +Windows 10: [FF, FF, 4, 24, 4, 24, 4, FF, 24, FF, 4, FF, 24, 4, 24, 20A, 20A, 20A, 20A, 20A, 20A, 20A, 20A, 20A, 20A, 20A, 20A, 20A, 20A, 20A, 20A, 20A, 20A, 20A, 20A, 20A, 20A, 20A, 20A] +Windows 10 (another host): [FF, FF, 4, 24, 4, 24, 4, 24, 4, 24, 4, 24] +macOS 12.5: [2, 24, 2, 28, FF] +iOS/iPadOS 15.6: [2, 24, 2, 28] +Linux (including Android, Raspberry Pi and WebOS TV): [FF, FF, FF] +PS5: [2, 4, 2, 28, 2, 24] +Nintendo Switch: [82, FF, 40, 40, FF, 40, 40, FF, 40, 40, FF, 40, 40, FF, 40, 40] +Quest 2: [FF, FF, FF, FE, FF, FE, FF, FE, FF, FE, FF] + +LUFA: +Windows 10 (first connect): [12, FF, FF, 4, 10, FF, FF, FF, 4, 10, 20A, 20A, 20A, 20A, 20A, 20A] +Windows 10 (subsequent connect): [FF, FF, 4, 10, FF, 4, FF, 10, FF, 20A, 20A, 20A, 20A, 20A, 20A] +Windows 10 (another host): [FF, FF, 4, 10, 4, 10] +macOS: [2, 10, 2, E, FF] +iOS/iPadOS: [2, 10, 2, E] +Linux: [FF, FF, FF] +PS5: [2, 4, 2, E, 2, 10] +Nintendo Switch: [82, FF, 40, 40, FF, 40, 40] + +V-USB: +Windows 10: [FF, FF, 4, E, FF] +Windows 10 (another host): [FF, FF, 4, E, 4] +macOS: [2, E, 2, E, FF] +iOS/iPadOS: [2, E, 2, E] +Linux: [FF, FF, FF] +PS5: [2, 4, 2, E, 2] +Nintendo Switch: [82, FF, 40, 40] +Quest 2: [FF, FF, FF, FE] + +Common parts: +Windows: [..., FF, FF, 4, ...] +macOS: [2, _, 2, _, FF] +iOS/iPadOS: [2, _, 2, _] +Linux: [FF, FF, FF] +PS5: [2, 4, 2, _, 2, ...] +Nintendo Switch: [82, FF, 40, 40, ...] +Quest 2: [FF, FF, FF, FE, ...] +*/ +TEST_F(OsDetectionTest, TestLinux) { + EXPECT_EQ(check_sequence({0xFF, 0xFF, 0xFF}), OS_LINUX); +} + +TEST_F(OsDetectionTest, TestChibiosMacos) { + EXPECT_EQ(check_sequence({0x2, 0x24, 0x2, 0x28, 0xFF}), OS_MACOS); +} + +TEST_F(OsDetectionTest, TestLufaMacos) { + EXPECT_EQ(check_sequence({0x2, 0x10, 0x2, 0xE, 0xFF}), OS_MACOS); +} + +TEST_F(OsDetectionTest, TestVusbMacos) { + EXPECT_EQ(check_sequence({0x2, 0xE, 0x2, 0xE, 0xFF}), OS_MACOS); +} + +TEST_F(OsDetectionTest, TestChibiosIos) { + EXPECT_EQ(check_sequence({0x2, 0x24, 0x2, 0x28}), OS_IOS); +} + +TEST_F(OsDetectionTest, TestLufaIos) { + EXPECT_EQ(check_sequence({0x2, 0x10, 0x2, 0xE}), OS_IOS); +} + +TEST_F(OsDetectionTest, TestVusbIos) { + EXPECT_EQ(check_sequence({0x2, 0xE, 0x2, 0xE}), OS_IOS); +} + +TEST_F(OsDetectionTest, TestChibiosWindows10) { + EXPECT_EQ(check_sequence({0xFF, 0xFF, 0x4, 0x24, 0x4, 0x24, 0x4, 0xFF, 0x24, 0xFF, 0x4, 0xFF, 0x24, 0x4, 0x24, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A}), OS_WINDOWS); +} + +TEST_F(OsDetectionTest, TestChibiosWindows10_2) { + EXPECT_EQ(check_sequence({0xFF, 0xFF, 0x4, 0x24, 0x4, 0x24, 0x4, 0x24, 0x4, 0x24, 0x4, 0x24}), OS_WINDOWS); +} + +TEST_F(OsDetectionTest, TestLufaWindows10) { + EXPECT_EQ(check_sequence({0x12, 0xFF, 0xFF, 0x4, 0x10, 0xFF, 0xFF, 0xFF, 0x4, 0x10, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A}), OS_WINDOWS); +} + +TEST_F(OsDetectionTest, TestLufaWindows10_2) { + EXPECT_EQ(check_sequence({0xFF, 0xFF, 0x4, 0x10, 0xFF, 0x4, 0xFF, 0x10, 0xFF, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A, 0x20A}), OS_WINDOWS); +} + +TEST_F(OsDetectionTest, TestLufaWindows10_3) { + EXPECT_EQ(check_sequence({0xFF, 0xFF, 0x4, 0x10, 0x4, 0x10}), OS_WINDOWS); +} + +TEST_F(OsDetectionTest, TestVusbWindows10) { + EXPECT_EQ(check_sequence({0xFF, 0xFF, 0x4, 0xE, 0xFF}), OS_WINDOWS); +} + +TEST_F(OsDetectionTest, TestVusbWindows10_2) { + EXPECT_EQ(check_sequence({0xFF, 0xFF, 0x4, 0xE, 0x4}), OS_WINDOWS); +} + +TEST_F(OsDetectionTest, TestChibiosPs5) { + EXPECT_EQ(check_sequence({0x2, 0x4, 0x2, 0x28, 0x2, 0x24}), OS_LINUX); +} + +TEST_F(OsDetectionTest, TestLufaPs5) { + EXPECT_EQ(check_sequence({0x2, 0x4, 0x2, 0xE, 0x2, 0x10}), OS_LINUX); +} + +TEST_F(OsDetectionTest, TestVusbPs5) { + EXPECT_EQ(check_sequence({0x2, 0x4, 0x2, 0xE, 0x2}), OS_LINUX); +} + +TEST_F(OsDetectionTest, TestChibiosNintendoSwitch) { + EXPECT_EQ(check_sequence({0x82, 0xFF, 0x40, 0x40, 0xFF, 0x40, 0x40, 0xFF, 0x40, 0x40, 0xFF, 0x40, 0x40, 0xFF, 0x40, 0x40}), OS_LINUX); +} + +TEST_F(OsDetectionTest, TestLufaNintendoSwitch) { + EXPECT_EQ(check_sequence({0x82, 0xFF, 0x40, 0x40, 0xFF, 0x40, 0x40}), OS_LINUX); +} + +TEST_F(OsDetectionTest, TestVusbNintendoSwitch) { + EXPECT_EQ(check_sequence({0x82, 0xFF, 0x40, 0x40}), OS_LINUX); +} + +TEST_F(OsDetectionTest, TestChibiosQuest2) { + EXPECT_EQ(check_sequence({0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFE, 0xFF, 0xFE, 0xFF, 0xFE, 0xFF}), OS_LINUX); +} + +TEST_F(OsDetectionTest, TestVusbQuest2) { + EXPECT_EQ(check_sequence({0xFF, 0xFF, 0xFF, 0xFE}), OS_LINUX); +} diff --git a/quantum/os_detection/tests/rules.mk b/quantum/os_detection/tests/rules.mk new file mode 100644 index 0000000000..9bfe373f46 --- /dev/null +++ b/quantum/os_detection/tests/rules.mk @@ -0,0 +1,5 @@ +os_detection_DEFS := -DOS_DETECTION_ENABLE + +os_detection_SRC := \ + $(QUANTUM_PATH)/os_detection/tests/os_detection.cpp \ + $(QUANTUM_PATH)/os_detection.c diff --git a/quantum/os_detection/tests/testlist.mk b/quantum/os_detection/tests/testlist.mk new file mode 100644 index 0000000000..405a7b82d5 --- /dev/null +++ b/quantum/os_detection/tests/testlist.mk @@ -0,0 +1 @@ +TEST_LIST += os_detection -- cgit v1.2.3 From 9bc7e9afbd32e3ed34580f1be9a79e6040158de5 Mon Sep 17 00:00:00 2001 From: Joel Challis Date: Fri, 9 Dec 2022 00:54:52 +0000 Subject: Initial uk+us DD keymap_extras migration (#19031) --- quantum/keymap_extras/keymap_uk.h | 96 +++++++++++---------------------------- quantum/keymap_extras/keymap_us.h | 75 +++++++++++++++--------------- 2 files changed, 65 insertions(+), 106 deletions(-) (limited to 'quantum') diff --git a/quantum/keymap_extras/keymap_uk.h b/quantum/keymap_extras/keymap_uk.h index 03fe8149f0..a6c42eafbf 100644 --- a/quantum/keymap_extras/keymap_uk.h +++ b/quantum/keymap_extras/keymap_uk.h @@ -1,39 +1,33 @@ -/* Copyright 2015-2016 Jack Humbert - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * 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. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ +// Copyright 2022 QMK +// SPDX-License-Identifier: GPL-2.0-or-later -#pragma once +/******************************************************************************* + 88888888888 888 d8b .d888 d8b 888 d8b + 888 888 Y8P d88P" Y8P 888 Y8P + 888 888 888 888 + 888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b + 888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K + 888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b. + 888 888 888 888 X88 888 888 888 Y8b. 888 X88 + 888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P' + 888 888 + 888 888 + 888 888 + .d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888 + d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888 + 888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888 + Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888 + "Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888 + 888 + Y8b d88P + "Y88P" +*******************************************************************************/ +#pragma once #include "keymap.h" - // clang-format off -/* - * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐ - * │ ` │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 0 │ - │ = │ │ - * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤ - * │ │ Q │ W │ E │ R │ T │ Y │ U │ I │ O │ P │ [ │ ] │ │ - * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐ │ - * │ │ A │ S │ D │ F │ G │ H │ J │ K │ L │ ; │ ' │ # │ │ - * ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴────┤ - * │ │ \ │ Z │ X │ C │ V │ B │ N │ M │ , │ . │ / │ │ - * ├────┼───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤ - * │ │ │ │ │ │ │ │ │ - * └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘ - */ -// Row 1 +// Aliases #define UK_GRV KC_GRV // ` #define UK_1 KC_1 // 1 #define UK_2 KC_2 // 2 @@ -47,7 +41,6 @@ #define UK_0 KC_0 // 0 #define UK_MINS KC_MINS // - #define UK_EQL KC_EQL // = -// Row 2 #define UK_Q KC_Q // Q #define UK_W KC_W // W #define UK_E KC_E // E @@ -60,7 +53,6 @@ #define UK_P KC_P // P #define UK_LBRC KC_LBRC // [ #define UK_RBRC KC_RBRC // ] -// Row 3 #define UK_A KC_A // A #define UK_S KC_S // S #define UK_D KC_D // D @@ -73,7 +65,6 @@ #define UK_SCLN KC_SCLN // ; #define UK_QUOT KC_QUOT // ' #define UK_HASH KC_NUHS // # -// Row 4 #define UK_BSLS KC_NUBS // (backslash) #define UK_Z KC_Z // Z #define UK_X KC_X // X @@ -85,21 +76,6 @@ #define UK_COMM KC_COMM // , #define UK_DOT KC_DOT // . #define UK_SLSH KC_SLSH // / - -/* Shifted symbols - * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐ - * │ ¬ │ ! │ " │ £ │ $ │ % │ ^ │ & │ * │ ( │ ) │ _ │ + │ │ - * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤ - * │ │ │ │ │ │ │ │ │ │ │ │ { │ } │ │ - * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐ │ - * │ │ │ │ │ │ │ │ │ │ │ : │ @ │ ~ │ │ - * ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴────┤ - * │ │ | │ │ │ │ │ │ │ │ < │ > │ ? │ │ - * ├────┼───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤ - * │ │ │ │ │ │ │ │ │ - * └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘ - */ -// Row 1 #define UK_NOT S(UK_GRV) // ¬ #define UK_EXLM S(UK_1) // ! #define UK_DQUO S(UK_2) // " @@ -113,39 +89,21 @@ #define UK_RPRN S(UK_0) // ) #define UK_UNDS S(UK_MINS) // _ #define UK_PLUS S(UK_EQL) // + -// Row 2 #define UK_LCBR S(UK_LBRC) // { #define UK_RCBR S(UK_RBRC) // } -// Row 3 #define UK_COLN S(UK_SCLN) // : #define UK_AT S(UK_QUOT) // @ #define UK_TILD S(UK_HASH) // ~ -// Row 4 #define UK_PIPE S(UK_BSLS) // | #define UK_LABK S(UK_COMM) // < #define UK_RABK S(UK_DOT) // > #define UK_QUES S(UK_SLSH) // ? - -/* AltGr symbols - * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐ - * │ ¦ │ │ │ │ € │ │ │ │ │ │ │ │ │ │ - * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤ - * │ │ │ │ É │ │ │ │ Ú │ Í │ Ó │ │ │ │ │ - * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┐ │ - * │ │ Á │ │ │ │ │ │ │ │ │ │ │ │ │ - * ├────┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴───┴────┤ - * │ │ │ │ │ │ │ │ │ │ │ │ │ │ - * ├────┼───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤ - * │ │ │ │ │ │ │ │ │ - * └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘ - */ -// Row 1 #define UK_BRKP ALGR(UK_GRV) // ¦ #define UK_EURO ALGR(UK_4) // € -// Row 2 #define UK_EACU ALGR(KC_E) // É #define UK_UACU ALGR(KC_U) // Ú #define UK_IACU ALGR(KC_I) // Í #define UK_OACU ALGR(KC_O) // Ó -// Row 3 #define UK_AACU ALGR(KC_A) // Á + + diff --git a/quantum/keymap_extras/keymap_us.h b/quantum/keymap_extras/keymap_us.h index b18c701679..c5c5285848 100644 --- a/quantum/keymap_extras/keymap_us.h +++ b/quantum/keymap_extras/keymap_us.h @@ -1,52 +1,55 @@ // Copyright 2022 QMK // SPDX-License-Identifier: GPL-2.0-or-later -#pragma once +/******************************************************************************* + 88888888888 888 d8b .d888 d8b 888 d8b + 888 888 Y8P d88P" Y8P 888 Y8P + 888 888 888 888 + 888 88888b. 888 .d8888b 888888 888 888 .d88b. 888 .d8888b + 888 888 "88b 888 88K 888 888 888 d8P Y8b 888 88K + 888 888 888 888 "Y8888b. 888 888 888 88888888 888 "Y8888b. + 888 888 888 888 X88 888 888 888 Y8b. 888 X88 + 888 888 888 888 88888P' 888 888 888 "Y8888 888 88888P' + 888 888 + 888 888 + 888 888 + .d88b. .d88b. 88888b. .d88b. 888d888 8888b. 888888 .d88b. .d88888 + d88P"88b d8P Y8b 888 "88b d8P Y8b 888P" "88b 888 d8P Y8b d88" 888 + 888 888 88888888 888 888 88888888 888 .d888888 888 88888888 888 888 + Y88b 888 Y8b. 888 888 Y8b. 888 888 888 Y88b. Y8b. Y88b 888 + "Y88888 "Y8888 888 888 "Y8888 888 "Y888888 "Y888 "Y8888 "Y88888 + 888 + Y8b d88P + "Y88P" +*******************************************************************************/ +#pragma once #include "keymap.h" - // clang-format off -/* Shifted symbols - * ┌───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬───────┐ - * │ ~ │ ! │ @ │ # │ $ │ % │ ^ │ & │ * │ ( │ ) │ _ │ + │ │ - * ├───┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─────┤ - * │ │ │ │ │ │ │ │ │ │ │ │ { │ } │ | │ - * ├─────┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴┬──┴─────┤ - * │ │ │ │ │ │ │ │ │ │ │ : │ " │ │ - * ├──────┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴─┬─┴────────┤ - * │ │ │ │ │ │ │ │ │ < │ > │ ? │ │ - * ├────┬───┴┬──┴─┬─┴───┴───┴───┴───┴───┴──┬┴───┼───┴┬────┬────┤ - * │ │ │ │ │ │ │ │ │ - * └────┴────┴────┴────────────────────────┴────┴────┴────┴────┘ - */ -// Row 1 +// Aliases #define KC_TILD S(KC_GRAVE) // ~ -#define KC_EXLM S(KC_1) // ! -#define KC_AT S(KC_2) // @ -#define KC_HASH S(KC_3) // # -#define KC_DLR S(KC_4) // $ -#define KC_PERC S(KC_5) // % -#define KC_CIRC S(KC_6) // ^ -#define KC_AMPR S(KC_7) // & -#define KC_ASTR S(KC_8) // * -#define KC_LPRN S(KC_9) // ( -#define KC_RPRN S(KC_0) // ) +#define KC_EXLM S(KC_1) // ! +#define KC_AT S(KC_2) // @ +#define KC_HASH S(KC_3) // # +#define KC_DLR S(KC_4) // $ +#define KC_PERC S(KC_5) // % +#define KC_CIRC S(KC_6) // ^ +#define KC_AMPR S(KC_7) // & +#define KC_ASTR S(KC_8) // * +#define KC_LPRN S(KC_9) // ( +#define KC_RPRN S(KC_0) // ) #define KC_UNDS S(KC_MINUS) // _ #define KC_PLUS S(KC_EQUAL) // + -// Row 2 -#define KC_LCBR S(KC_LEFT_BRACKET) // { +#define KC_LCBR S(KC_LEFT_BRACKET) // { #define KC_RCBR S(KC_RIGHT_BRACKET) // } -#define KC_PIPE S(KC_BACKSLASH) // | -// Row 3 +#define KC_PIPE S(KC_BACKSLASH) // | #define KC_COLN S(KC_SEMICOLON) // : -#define KC_DQUO S(KC_QUOTE) // " -// Row 4 +#define KC_DQUO S(KC_QUOTE) // " #define KC_LABK S(KC_COMMA) // < -#define KC_RABK S(KC_DOT) // > +#define KC_RABK S(KC_DOT) // > #define KC_QUES S(KC_SLASH) // ? -// alias stuff #define KC_TILDE KC_TILD #define KC_EXCLAIM KC_EXLM #define KC_DOLLAR KC_DLR @@ -57,16 +60,14 @@ #define KC_LEFT_PAREN KC_LPRN #define KC_RIGHT_PAREN KC_RPRN #define KC_UNDERSCORE KC_UNDS - #define KC_LEFT_CURLY_BRACE KC_LCBR #define KC_RIGHT_CURLY_BRACE KC_RCBR - #define KC_COLON KC_COLN #define KC_DOUBLE_QUOTE KC_DQUO #define KC_DQT KC_DQUO - #define KC_LEFT_ANGLE_BRACKET KC_LABK #define KC_LT KC_LABK #define KC_RIGHT_ANGLE_BRACKET KC_RABK #define KC_GT KC_RABK #define KC_QUESTION KC_QUES + -- cgit v1.2.3 From cbabc8dbe6a8476d3082e8bc649d330f87e7b904 Mon Sep 17 00:00:00 2001 From: Albert Y <76888457+filterpaper@users.noreply.github.com> Date: Mon, 12 Dec 2022 23:52:22 +0800 Subject: [Core] Replace Tapping Force Hold feature with Quick Tap Term (#17007) * Replace Tapping Force Hold feature with Quick Tap Term * Replace keyboard level TAPPING_FORCE_HOLD with QUICK_TAP_TERM 0 * Deprecate force hold in info_config.json * Before and after quick tap term unit tests * Quick tap unit tests iteration * Keymap config.h correction * Remove TAPPING_FORCE_HOLD_PER_KEY macros that were missed * Add two more test cases for quick tap * Replace TAPPING_FORCE_HOLD with QUICK_TAP_TERM in configs #2 * Replace TAPPING_FORCE_HOLD_PER_KEY with QUICK_TAP_TERM_PER_KEY in configs #2 * Add function declaration for get_quick_tap_term Co-authored-by: Stefan Kerkmann --- quantum/action_tapping.c | 19 ++++++------------- quantum/action_tapping.h | 13 ++++++++++++- 2 files changed, 18 insertions(+), 14 deletions(-) (limited to 'quantum') diff --git a/quantum/action_tapping.c b/quantum/action_tapping.c index b5386a5e17..0350495ae5 100644 --- a/quantum/action_tapping.c +++ b/quantum/action_tapping.c @@ -25,6 +25,7 @@ # define IS_TAPPING_RECORD(r) (IS_TAPPING() && KEYEQ(tapping_key.event.key, (r->event.key)) && tapping_key.keycode == r->keycode) # endif # define WITHIN_TAPPING_TERM(e) (TIMER_DIFF_16(e.time, tapping_key.event.time) < GET_TAPPING_TERM(get_record_keycode(&tapping_key, false), &tapping_key)) +# define WITHIN_QUICK_TAP_TERM(e) (TIMER_DIFF_16(e.time, tapping_key.event.time) < GET_QUICK_TAP_TERM(get_record_keycode(&tapping_key, false), &tapping_key)) # ifdef DYNAMIC_TAPPING_TERM_ENABLE uint16_t g_tapping_term = TAPPING_TERM; @@ -40,9 +41,9 @@ __attribute__((weak)) uint16_t get_tapping_term(uint16_t keycode, keyrecord_t *r } # endif -# ifdef TAPPING_FORCE_HOLD_PER_KEY -__attribute__((weak)) bool get_tapping_force_hold(uint16_t keycode, keyrecord_t *record) { - return false; +# ifdef QUICK_TAP_TERM_PER_KEY +__attribute__((weak)) uint16_t get_quick_tap_term(uint16_t keycode, keyrecord_t *record) { + return QUICK_TAP_TERM; } # endif @@ -121,7 +122,7 @@ void action_tapping_process(keyrecord_t record) { * readable. The conditional definition of tapping_keycode and all the * conditional uses of it are hidden inside macros named TAP_... */ -# if (defined(AUTO_SHIFT_ENABLE) && defined(RETRO_SHIFT)) || defined(PERMISSIVE_HOLD_PER_KEY) || defined(TAPPING_FORCE_HOLD_PER_KEY) || defined(HOLD_ON_OTHER_KEY_PRESS_PER_KEY) +# if (defined(AUTO_SHIFT_ENABLE) && defined(RETRO_SHIFT)) || defined(PERMISSIVE_HOLD_PER_KEY) || defined(QUICK_TAP_TERM_PER_KEY) || defined(HOLD_ON_OTHER_KEY_PRESS_PER_KEY) # define TAP_DEFINE_KEYCODE uint16_t tapping_keycode = get_record_keycode(&tapping_key, false) # else # define TAP_DEFINE_KEYCODE @@ -169,14 +170,6 @@ void action_tapping_process(keyrecord_t record) { # define TAP_GET_IGNORE_MOD_TAP_INTERRUPT false # endif -# ifdef TAPPING_FORCE_HOLD_PER_KEY -# define TAP_GET_TAPPING_FORCE_HOLD get_tapping_force_hold(tapping_keycode, &tapping_key) -# elif defined(TAPPING_FORCE_HOLD) -# define TAP_GET_TAPPING_FORCE_HOLD true -# else -# define TAP_GET_TAPPING_FORCE_HOLD false -# endif - /** \brief Tapping * * Rule: Tap key is typed(pressed and released) within TAPPING_TERM. @@ -385,7 +378,7 @@ bool process_tapping(keyrecord_t *keyp) { if (WITHIN_TAPPING_TERM(event) || MAYBE_RETRO_SHIFTING(event)) { if (event.pressed) { if (IS_TAPPING_RECORD(keyp)) { - if (!TAP_GET_TAPPING_FORCE_HOLD && !tapping_key.tap.interrupted && tapping_key.tap.count > 0) { + if (WITHIN_QUICK_TAP_TERM(event) && !tapping_key.tap.interrupted && tapping_key.tap.count > 0) { // sequential tap. keyp->tap = tapping_key.tap; if (keyp->tap.count < 15) keyp->tap.count += 1; diff --git a/quantum/action_tapping.h b/quantum/action_tapping.h index bcccc7ac45..c078488c04 100644 --- a/quantum/action_tapping.h +++ b/quantum/action_tapping.h @@ -22,6 +22,11 @@ along with this program. If not, see . # define TAPPING_TERM 200 #endif +/* period of quick tap(ms) */ +#if !defined(QUICK_TAP_TERM) || QUICK_TAP_TERM > TAPPING_TERM +# define QUICK_TAP_TERM TAPPING_TERM +#endif + /* tap count needed for toggling a feature */ #ifndef TAPPING_TOGGLE # define TAPPING_TOGGLE 5 @@ -36,9 +41,9 @@ void action_tapping_process(keyrecord_t record); #endif uint16_t get_tapping_term(uint16_t keycode, keyrecord_t *record); +uint16_t get_quick_tap_term(uint16_t keycode, keyrecord_t *record); bool get_permissive_hold(uint16_t keycode, keyrecord_t *record); bool get_ignore_mod_tap_interrupt(uint16_t keycode, keyrecord_t *record); -bool get_tapping_force_hold(uint16_t keycode, keyrecord_t *record); bool get_retro_tapping(uint16_t keycode, keyrecord_t *record); bool get_hold_on_other_key_press(uint16_t keycode, keyrecord_t *record); @@ -53,3 +58,9 @@ extern uint16_t g_tapping_term; #else # define GET_TAPPING_TERM(keycode, record) (TAPPING_TERM) #endif + +#ifdef QUICK_TAP_TERM_PER_KEY +# define GET_QUICK_TAP_TERM(keycode, record) get_quick_tap_term(keycode, record) +#else +# define GET_QUICK_TAP_TERM(keycode, record) (QUICK_TAP_TERM) +#endif -- cgit v1.2.3 From 102f22f7e99d87989cd95e10370863c3f96ba7e2 Mon Sep 17 00:00:00 2001 From: jpe230 Date: Mon, 12 Dec 2022 14:51:14 -0600 Subject: [Core] Quantum Painter - LVGL Integration (#18499) Co-authored-by: Nick Brassel --- quantum/main.c | 6 +- quantum/painter/lvgl/qp_lvgl.c | 144 ++++++++++++++++++++++++++++++++++++++++ quantum/painter/lvgl/qp_lvgl.h | 25 +++++++ quantum/painter/lvgl/rules.mk | 24 +++++++ quantum/painter/qp.h | 7 ++ quantum/painter/qp_draw_image.c | 12 ++++ quantum/painter/rules.mk | 6 ++ 7 files changed, 221 insertions(+), 3 deletions(-) create mode 100644 quantum/painter/lvgl/qp_lvgl.c create mode 100644 quantum/painter/lvgl/qp_lvgl.h create mode 100644 quantum/painter/lvgl/rules.mk (limited to 'quantum') diff --git a/quantum/main.c b/quantum/main.c index 2d5911b708..3b101c522c 100644 --- a/quantum/main.c +++ b/quantum/main.c @@ -60,9 +60,9 @@ int main(void) { protocol_task(); #ifdef QUANTUM_PAINTER_ENABLE - // Run Quantum Painter animations - void qp_internal_animation_tick(void); - qp_internal_animation_tick(); + // Run Quantum Painter task + void qp_internal_task(void); + qp_internal_task(); #endif #ifdef DEFERRED_EXEC_ENABLE diff --git a/quantum/painter/lvgl/qp_lvgl.c b/quantum/painter/lvgl/qp_lvgl.c new file mode 100644 index 0000000000..41ca3f98c2 --- /dev/null +++ b/quantum/painter/lvgl/qp_lvgl.c @@ -0,0 +1,144 @@ +// Copyright 2022 Jose Pablo Ramirez (@jpe230) +// Copyright 2022 Nick Brassel (@tzarc) +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "qp_lvgl.h" +#include "timer.h" +#include "deferred_exec.h" +#include "lvgl.h" + +typedef struct lvgl_state_t { + uint8_t fnc_id; // Ideally this should be the pointer of the function to run + uint16_t delay_ms; + deferred_token defer_token; +} lvgl_state_t; + +static deferred_executor_t lvgl_executors[2] = {0}; // For lv_tick_inc and lv_task_handler +static lvgl_state_t lvgl_states[2] = {0}; // For lv_tick_inc and lv_task_handler + +painter_device_t selected_display = NULL; +void * color_buffer = NULL; + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Quantum Painter LVGL Integration Internal: qp_lvgl_flush + +void qp_lvgl_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p) { + if (selected_display) { + uint32_t number_pixels = (area->x2 - area->x1 + 1) * (area->y2 - area->y1 + 1); + qp_viewport(selected_display, area->x1, area->y1, area->x2, area->y2); + qp_pixdata(selected_display, (void *)color_p, number_pixels); + qp_flush(selected_display); + lv_disp_flush_ready(disp); + } +} + +static uint32_t tick_task_callback(uint32_t trigger_time, void *cb_arg) { + lvgl_state_t * state = (lvgl_state_t *)cb_arg; + static uint32_t last_tick = 0; + switch (state->fnc_id) { + case 0: { + uint32_t now = timer_read32(); + lv_tick_inc(TIMER_DIFF_32(now, last_tick)); + last_tick = now; + } break; + case 1: + lv_task_handler(); + break; + + default: + break; + } + + // The tasks should run indefinitely + return state->delay_ms; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Quantum Painter LVGL Integration API: qp_lvgl_attach + +bool qp_lvgl_attach(painter_device_t device) { + qp_dprintf("qp_lvgl_start: entry\n"); + qp_lvgl_detach(); + + struct painter_driver_t *driver = (struct painter_driver_t *)device; + if (!driver->validate_ok) { + qp_dprintf("qp_lvgl_attach: fail (validation_ok == false)\n"); + qp_lvgl_detach(); + return false; + } + + // Setting up the tasks + lvgl_state_t *lv_tick_inc_state = &lvgl_states[0]; + lv_tick_inc_state->fnc_id = 0; + lv_tick_inc_state->delay_ms = 1; + lv_tick_inc_state->defer_token = defer_exec_advanced(lvgl_executors, 2, 1, tick_task_callback, lv_tick_inc_state); + + if (lv_tick_inc_state->defer_token == INVALID_DEFERRED_TOKEN) { + qp_dprintf("qp_lvgl_attach: fail (could not set up qp_lvgl executor)\n"); + qp_lvgl_detach(); + return false; + } + + lvgl_state_t *lv_task_handler_state = &lvgl_states[1]; + lv_task_handler_state->fnc_id = 1; + lv_task_handler_state->delay_ms = 5; + lv_task_handler_state->defer_token = defer_exec_advanced(lvgl_executors, 2, 5, tick_task_callback, lv_task_handler_state); + + if (lv_task_handler_state->defer_token == INVALID_DEFERRED_TOKEN) { + qp_dprintf("qp_lvgl_attach: fail (could not set up qp_lvgl executor)\n"); + qp_lvgl_detach(); + return false; + } + + // Init LVGL + lv_init(); + + // Set up lvgl display buffer + static lv_disp_draw_buf_t draw_buf; + // Allocate a buffer for 1/10 screen size + const size_t count_required = driver->panel_width * driver->panel_height / 10; + color_buffer = color_buffer ? realloc(color_buffer, sizeof(lv_color_t) * count_required) : malloc(sizeof(lv_color_t) * count_required); + if (!color_buffer) { + qp_dprintf("qp_lvgl_attach: fail (could not set up memory buffer)\n"); + qp_lvgl_detach(); + return false; + } + memset(color_buffer, 0, sizeof(lv_color_t) * count_required); + // Initialize the display buffer. + lv_disp_draw_buf_init(&draw_buf, color_buffer, NULL, count_required); + + selected_display = device; + + // Setting up display driver + static lv_disp_drv_t disp_drv; /*Descriptor of a display driver*/ + lv_disp_drv_init(&disp_drv); /*Basic initialization*/ + disp_drv.flush_cb = qp_lvgl_flush; /*Set your driver function*/ + disp_drv.draw_buf = &draw_buf; /*Assign the buffer to the display*/ + disp_drv.hor_res = driver->panel_width; /*Set the horizontal resolution of the display*/ + disp_drv.ver_res = driver->panel_height; /*Set the vertical resolution of the display*/ + lv_disp_drv_register(&disp_drv); /*Finally register the driver*/ + + return true; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Quantum Painter LVGL Integration API: qp_lvgl_detach + +void qp_lvgl_detach(void) { + for (int i = 0; i < 2; ++i) { + cancel_deferred_exec_advanced(lvgl_executors, 2, lvgl_states[i].defer_token); + } + if (color_buffer) { + free(color_buffer); + color_buffer = NULL; + } + selected_display = NULL; +} + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Quantum Painter LVGL Integration Internal: qp_lvgl_internal_tick + +void qp_lvgl_internal_tick(void) { + static uint32_t last_lvgl_exec = 0; + deferred_exec_advanced_task(lvgl_executors, 2, &last_lvgl_exec); +} diff --git a/quantum/painter/lvgl/qp_lvgl.h b/quantum/painter/lvgl/qp_lvgl.h new file mode 100644 index 0000000000..d9ad5e8df1 --- /dev/null +++ b/quantum/painter/lvgl/qp_lvgl.h @@ -0,0 +1,25 @@ +// Copyright 2022 Jose Pablo Ramirez (@jpe230) +// Copyright 2022 Nick Brassel (@tzarc) +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "qp.h" +#include "lvgl.h" + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Quantum Painter - LVGL External API + +/** + * Sets up LVGL with the supplied display. + * + * @param device[in] the handle of the device to control + * @return true if init. of LVGL succeeded + * @return false if init. of LVGL failed + */ +bool qp_lvgl_attach(painter_device_t device); + +/** + * Disconnects LVGL from any attached display + */ +void qp_lvgl_detach(void); diff --git a/quantum/painter/lvgl/rules.mk b/quantum/painter/lvgl/rules.mk new file mode 100644 index 0000000000..50226941b3 --- /dev/null +++ b/quantum/painter/lvgl/rules.mk @@ -0,0 +1,24 @@ +# LVGL Integration + +OPT_DEFS += -DQUANTUM_PAINTER_LVGL_INTEGRATION_ENABLE -DLV_CONF_INCLUDE_SIMPLE +DEFERRED_EXEC_ENABLE := yes + +LVGL_DIR_NAME = lvgl +LVGL_DIR = $(LIB_DIR) +LVGL_PATH = $(LVGL_DIR)/$(LVGL_DIR_NAME) + +COMMON_VPATH += $(PLATFORM_PATH) \ + $(QUANTUM_DIR)/painter/$(LVGL_DIR_NAME) \ + $(LVGL_PATH) + +include $(LVGL_PATH)/src/extra/extra.mk +include $(LVGL_PATH)/src/core/lv_core.mk +include $(LVGL_PATH)/src/draw/lv_draw.mk +include $(LVGL_PATH)/src/draw/sw/lv_draw_sw.mk +include $(LVGL_PATH)/src/font/lv_font.mk +include $(LVGL_PATH)/src/hal/lv_hal.mk +include $(LVGL_PATH)/src/misc/lv_misc.mk +include $(LVGL_PATH)/src/widgets/lv_widgets.mk + +SRC += qp_lvgl.c \ + $(CSRCS) diff --git a/quantum/painter/qp.h b/quantum/painter/qp.h index 69bc435961..e5f595d71d 100644 --- a/quantum/painter/qp.h +++ b/quantum/painter/qp.h @@ -463,3 +463,10 @@ int16_t qp_drawtext_recolor(painter_device_t device, uint16_t x, uint16_t y, pai #ifdef QUANTUM_PAINTER_SSD1351_ENABLE # include "qp_ssd1351.h" #endif // QUANTUM_PAINTER_SSD1351_ENABLE + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Quantum Painter Extras + +#ifdef QUANTUM_PAINTER_LVGL_INTEGRATION_ENABLE +# include "qp_lvgl.h" +#endif // QUANTUM_PAINTER_LVGL_INTEGRATION_ENABLE diff --git a/quantum/painter/qp_draw_image.c b/quantum/painter/qp_draw_image.c index e9b975f23a..943cbfef5b 100644 --- a/quantum/painter/qp_draw_image.c +++ b/quantum/painter/qp_draw_image.c @@ -399,3 +399,15 @@ void qp_internal_animation_tick(void) { static uint32_t last_anim_exec = 0; deferred_exec_advanced_task(animation_executors, QUANTUM_PAINTER_CONCURRENT_ANIMATIONS, &last_anim_exec); } + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// Quantum Painter Core API: qp_internal_task + +void qp_internal_task(void) { + qp_internal_animation_tick(); +#ifdef QUANTUM_PAINTER_LVGL_INTEGRATION_ENABLE + // Run LVGL ticks + void qp_lvgl_internal_tick(void); + qp_lvgl_internal_tick(); +#endif +} diff --git a/quantum/painter/rules.mk b/quantum/painter/rules.mk index 5ac374a96e..199e406dd6 100644 --- a/quantum/painter/rules.mk +++ b/quantum/painter/rules.mk @@ -2,6 +2,8 @@ QUANTUM_PAINTER_DRIVERS ?= QUANTUM_PAINTER_ANIMATIONS_ENABLE ?= yes +QUANTUM_PAINTER_LVGL_INTEGRATION ?= no + # The list of permissible drivers that can be listed in QUANTUM_PAINTER_DRIVERS VALID_QUANTUM_PAINTER_DRIVERS := \ rgb565_surface \ @@ -152,3 +154,7 @@ ifeq ($(strip $(QUANTUM_PAINTER_NEEDS_COMMS_SPI)), yes) endif endif +# Check if LVGL needs to be enabled +ifeq ($(strip $(QUANTUM_PAINTER_LVGL_INTEGRATION)), yes) + include $(QUANTUM_DIR)/painter/lvgl/rules.mk +endif -- cgit v1.2.3 From 515dd18c2801663bbac0e59f683c2a93e4bd9b1a Mon Sep 17 00:00:00 2001 From: precondition <57645186+precondition@users.noreply.github.com> Date: Tue, 13 Dec 2022 12:20:07 +0100 Subject: Remove IGNORE_MOD_TAP_INTERRUPT_PER_KEY in favour of HOLD_ON_OTHER_KEY_PRESS_PER_KEY (#15741) --- quantum/action.c | 10 +++---- quantum/action_tapping.c | 14 +++++++--- quantum/process_keycode/process_auto_shift.c | 41 ++++++++++------------------ 3 files changed, 30 insertions(+), 35 deletions(-) (limited to 'quantum') diff --git a/quantum/action.c b/quantum/action.c index abf9834d2f..ea6a24ea5c 100644 --- a/quantum/action.c +++ b/quantum/action.c @@ -55,8 +55,8 @@ int retro_tapping_counter = 0; # include "process_auto_shift.h" #endif -#ifdef IGNORE_MOD_TAP_INTERRUPT_PER_KEY -__attribute__((weak)) bool get_ignore_mod_tap_interrupt(uint16_t keycode, keyrecord_t *record) { +#ifdef HOLD_ON_OTHER_KEY_PRESS_PER_KEY +__attribute__((weak)) bool get_hold_on_other_key_press(uint16_t keycode, keyrecord_t *record) { return false; } #endif @@ -484,10 +484,10 @@ void process_action(keyrecord_t *record, action_t action) { default: if (event.pressed) { if (tap_count > 0) { -# if !defined(IGNORE_MOD_TAP_INTERRUPT) || defined(IGNORE_MOD_TAP_INTERRUPT_PER_KEY) +# if !defined(IGNORE_MOD_TAP_INTERRUPT) || defined(HOLD_ON_OTHER_KEY_PRESS_PER_KEY) if ( -# ifdef IGNORE_MOD_TAP_INTERRUPT_PER_KEY - !get_ignore_mod_tap_interrupt(get_event_keycode(record->event, false), record) && +# ifdef HOLD_ON_OTHER_KEY_PRESS_PER_KEY + get_hold_on_other_key_press(get_event_keycode(record->event, false), record) && # endif record->tap.interrupted) { dprint("mods_tap: tap: cancel: add_mods\n"); diff --git a/quantum/action_tapping.c b/quantum/action_tapping.c index 0350495ae5..ca0f31f12e 100644 --- a/quantum/action_tapping.c +++ b/quantum/action_tapping.c @@ -15,6 +15,14 @@ #ifndef NO_ACTION_TAPPING +# if defined(IGNORE_MOD_TAP_INTERRUPT_PER_KEY) +# error "IGNORE_MOD_TAP_INTERRUPT_PER_KEY has been removed; the code needs to be ported to use HOLD_ON_OTHER_KEY_PRESS_PER_KEY instead." +# elif !defined(IGNORE_MOD_TAP_INTERRUPT) +# if !defined(PERMISSIVE_HOLD) && !defined(PERMISSIVE_HOLD_PER_KEY) && !defined(HOLD_ON_OTHER_KEY_PRESS) && !defined(HOLD_ON_OTHER_KEY_PRESS_PER_KEY) +# pragma message "The default behavior of mod-taps will change to mimic IGNORE_MOD_TAP_INTERRUPT in the future.\nIf you wish to keep the old default behavior of mod-taps, please use HOLD_ON_OTHER_KEY_PRESS." +# endif +# endif + # define IS_TAPPING() !IS_NOEVENT(tapping_key.event) # define IS_TAPPING_PRESSED() (IS_TAPPING() && tapping_key.event.pressed) # define IS_TAPPING_RELEASED() (IS_TAPPING() && !tapping_key.event.pressed) @@ -162,9 +170,7 @@ void action_tapping_process(keyrecord_t record) { # define TAP_GET_HOLD_ON_OTHER_KEY_PRESS false # endif -# ifdef IGNORE_MOD_TAP_INTERRUPT_PER_KEY -# define TAP_GET_IGNORE_MOD_TAP_INTERRUPT get_ignore_mod_tap_interrupt(tapping_keycode, &tapping_key) -# elif defined(IGNORE_MOD_TAP_INTERRUPT) +# if defined(IGNORE_MOD_TAP_INTERRUPT) # define TAP_GET_IGNORE_MOD_TAP_INTERRUPT true # else # define TAP_GET_IGNORE_MOD_TAP_INTERRUPT false @@ -216,7 +222,7 @@ bool process_tapping(keyrecord_t *keyp) { // Rolled over the two keys. (tapping_key.tap.interrupted == true && ( (TAP_IS_LT && TAP_GET_HOLD_ON_OTHER_KEY_PRESS) || - (TAP_IS_MT && !TAP_GET_IGNORE_MOD_TAP_INTERRUPT) + (TAP_IS_MT && TAP_GET_HOLD_ON_OTHER_KEY_PRESS) ) ) // Makes Retro Shift ignore [IGNORE_MOD_TAP_INTERRUPT's diff --git a/quantum/process_keycode/process_auto_shift.c b/quantum/process_keycode/process_auto_shift.c index 35d4851ee5..b7ac449198 100644 --- a/quantum/process_keycode/process_auto_shift.c +++ b/quantum/process_keycode/process_